From b2656cae6be78e9cf45571c7e88a2370cd12d67f Mon Sep 17 00:00:00 2001
From: Peter Thienel <thienel@data-quest.de>
Date: Tue, 19 Dec 2023 13:38:32 +0000
Subject: [PATCH] StEP 1800 closes #1800

Closes #1800

Merge request studip/studip!1185
---
 app/controllers/admin/extern.php              |  491 ++++++
 app/controllers/extern.php                    |   48 +
 app/controllers/institute/extern.php          |   77 +
 .../admin/extern/extern_config/persbrowse.php |   51 +
 app/views/institute/extern/_table-header.php  |   16 +
 app/views/institute/extern/_table-row.php     |   57 +
 .../extern/extern_config/_basic_settings.php  |   58 +
 .../extern_config/_institutes_selector.php    |   22 +
 .../extern_config/_sem_types_selector.php     |   22 +
 .../extern_config/_study_areas_selector.php   |   29 +
 .../extern/extern_config/_template.php        |   15 +
 .../extern/extern_config/coursedetails.php    |   35 +
 .../extern/extern_config/courses.php          |   85 +
 .../extern/extern_config/download.php         |   60 +
 .../extern/extern_config/persondetails.php    |  107 ++
 .../extern/extern_config/persons.php          |   71 +
 .../extern/extern_config/timetable.php        |   74 +
 app/views/institute/extern/index.php          |   48 +
 app/views/institute/extern/info.php           |   76 +
 app/views/institute/extern/new.php            |   26 +
 app/views/institute/extern/upload.php         |   29 +
 db/migrations/5.5.12_new_external_pages.php   |  578 +++++++
 lib/bootstrap-autoload.php                    |    2 +-
 lib/bootstrap.php                             |    5 -
 lib/extern/ExternPage.php                     |  491 ++++++
 lib/extern/ExternPageCourseDetails.php        |  293 ++++
 lib/extern/ExternPageCourses.php              |  482 ++++++
 lib/extern/ExternPageDownload.php             |  211 +++
 lib/extern/ExternPagePersBrowse.php           |  392 +++++
 lib/extern/ExternPagePersonDetails.php        |  472 ++++++
 lib/extern/ExternPagePersons.php              |  205 +++
 lib/extern/ExternPageTimetable.php            |  319 ++++
 lib/extern/admin_extern.inc.php               |  438 -----
 .../elements/ExternElementBody.class.php      |   66 -
 .../elements/ExternElementContact.class.php   |  170 --
 .../ExternElementContentNews.class.php        |  117 --
 .../ExternElementLecturesInnerTable.class.php |  189 ---
 .../elements/ExternElementLink.class.php      |   76 -
 .../ExternElementLinkIntern.class.php         |  151 --
 .../ExternElementLinkInternSimple.class.php   |  201 ---
 .../ExternElementLinkInternTemplate.class.php |   91 -
 .../elements/ExternElementList.class.php      |  114 --
 ...ExternElementPersondetailsHeader.class.php |  171 --
 ...ternElementPersondetailsLectures.class.php |  183 --
 ...entPersondetailsLecturesTemplate.class.php |  175 --
 ...ternElementRangeTreeLevelContent.class.php |  101 --
 .../ExternElementRangeTreeLevelName.class.php |  107 --
 .../ExternElementReplaceTextSemType.class.php |  140 --
 .../ExternElementSelectInstitutes.class.php   |  103 --
 .../ExternElementSelectSubjectAreas.class.php |  159 --
 .../ExternElementStudipInfo.class.php         |  128 --
 .../ExternElementStudipLink.class.php         |  165 --
 .../ExternElementTableFooter.class.php        |   59 -
 .../ExternElementTableGroup.class.php         |   84 -
 .../ExternElementTableHeader.class.php        |   68 -
 .../ExternElementTableHeadrow.class.php       |  120 --
 .../ExternElementTableParagraph.class.php     |   65 -
 ...ernElementTableParagraphHeadline.class.php |   72 -
 ...ElementTableParagraphSubHeadline.class.php |  111 --
 .../ExternElementTableParagraphText.class.php |  111 --
 .../elements/ExternElementTableRow.class.php  |  110 --
 .../ExternElementTableRowTwoColumns.class.php |  117 --
 .../ExternElementTemplateGeneric.class.php    |  135 --
 .../ExternElementTreeBackLink.class.php       |   97 --
 .../elements/ExternElementTreeKids.class.php  |   62 -
 .../ExternElementTreeLevelContent.class.php   |   62 -
 .../ExternElementTreeLevelName.class.php      |   62 -
 .../elements/ExternElementTreePath.class.php  |   90 -
 .../main/ExternElementMainDownload.class.php  |  255 ---
 .../main/ExternElementMainGlobal.class.php    |  230 ---
 .../ExternElementMainLecturedetails.class.php |  232 ---
 .../main/ExternElementMainLectures.class.php  |  300 ----
 .../ExternElementMainLecturestable.class.php  |  312 ----
 .../main/ExternElementMainNews.class.php      |  210 ---
 .../ExternElementMainNewsticker.class.php     |  191 ---
 .../ExternElementMainPersondetails.class.php  |  222 ---
 .../main/ExternElementMainPersons.class.php   |  217 ---
 ...xternElementMainRangelecturetree.class.php |  125 --
 .../ExternElementMainSemlecturetree.class.php |  126 --
 ...xternElementMainTemplateDownload.class.php |  219 ---
 ...lementMainTemplateLecturedetails.class.php |  154 --
 ...xternElementMainTemplateLectures.class.php |  253 ---
 .../ExternElementMainTemplateNews.class.php   |  148 --
 ...ernElementMainTemplatePersBrowse.class.php |  169 --
 ...ElementMainTemplatePersondetails.class.php |  159 --
 ...ExternElementMainTemplatePersons.class.php |  170 --
 ...ternElementMainTemplateSemBrowse.class.php |  319 ----
 lib/extern/extern.inc.php                     |  139 --
 lib/extern/extern_config.inc.php              |  135 --
 lib/extern/lib/ExternConfig.class.php         |  680 --------
 lib/extern/lib/ExternConfigDb.class.php       |   95 --
 lib/extern/lib/ExternEdit.class.php           |  270 ---
 lib/extern/lib/ExternElement.class.php        |  529 ------
 lib/extern/lib/ExternElementMain.class.php    |  133 --
 lib/extern/lib/ExternModule.class.php         |  574 -------
 lib/extern/lib/extern_functions.inc.php       |  362 ----
 .../modules/ExternModuleDownload.class.php    |  343 ----
 .../modules/ExternModuleGlobal.class.php      |  226 ---
 .../ExternModuleLecturedetails.class.php      |  606 -------
 .../modules/ExternModuleLectures.class.php    |  104 --
 .../ExternModuleLecturestable.class.php       |  122 --
 lib/extern/modules/ExternModuleNews.class.php |  102 --
 .../modules/ExternModuleNewsticker.class.php  |  169 --
 .../ExternModulePersondetails.class.php       |  132 --
 .../modules/ExternModulePersons.class.php     |  104 --
 .../ExternModuleRangelecturetree.class.php    |   87 -
 .../ExternModuleSemlecturetree.class.php      |   87 -
 .../ExternModuleTemplateDownload.class.php    |  296 ----
 ...ternModuleTemplateLecturedetails.class.php |  567 -------
 .../ExternModuleTemplateLectures.class.php    |  575 -------
 .../ExternModuleTemplateNews.class.php        |  278 ---
 .../ExternModuleTemplatePersBrowse.class.php  |  539 ------
 ...xternModuleTemplatePersondetails.class.php |  774 ---------
 .../ExternModuleTemplatePersons.class.php     |  375 -----
 .../ExternModuleTemplateSemBrowse.class.php   | 1495 -----------------
 .../views/ExternRangeLectureTree.class.php    |  170 --
 .../modules/views/ExternSemBrowse.class.php   |  545 ------
 .../views/ExternSemBrowseTable.class.php      |  476 ------
 .../views/ExternSemLectureTree.class.php      |  124 --
 .../views/lecturedetails_preview.inc.php      |  263 ---
 .../modules/views/lectures_preview.inc.php    |  150 --
 .../views/lecturestable_preview.inc.php       |  124 --
 lib/extern/modules/views/news.inc.php         |  124 --
 lib/extern/modules/views/news_preview.inc.php |  209 ---
 lib/extern/modules/views/newsticker.inc.php   |   76 -
 .../modules/views/newsticker_preview.inc.php  |   60 -
 .../modules/views/persondetails.inc.php       |  707 --------
 .../views/persondetails_preview.inc.php       |  531 ------
 lib/extern/modules/views/persons.inc.php      |  265 ---
 .../modules/views/persons_preview.inc.php     |  202 ---
 lib/extern/sri.inc.php                        |  198 ---
 lib/extern/views/ExternEditGeneric.class.php  |  309 ----
 lib/extern/views/ExternEditHtml.class.php     |  623 -------
 lib/extern/views/ExternEditModule.class.php   |  573 -------
 lib/extern/views/extern_edit_module.inc.php   |  171 --
 .../views/extern_html_templates.inc.php       |  145 --
 lib/extern/views/extern_info_module.inc.php   |   95 --
 lib/models/ExternPageConfig.php               |   61 +
 lib/models/User.class.php                     |    5 +
 lib/navigation/AdminNavigation.php            |    4 +-
 lib/plugins/core/ExternPagePlugin.php         |   52 +
 public/admin_extern.php                       |   65 -
 public/extern.php                             |   48 -
 .../javascripts/bootstrap/external_pages.js   |   15 +
 resources/assets/javascripts/entry-base.js    |    1 +
 templates/extern/upload_form.php              |   35 -
 146 files changed, 5077 insertions(+), 24675 deletions(-)
 create mode 100644 app/controllers/admin/extern.php
 create mode 100644 app/controllers/extern.php
 create mode 100644 app/controllers/institute/extern.php
 create mode 100644 app/views/admin/extern/extern_config/persbrowse.php
 create mode 100644 app/views/institute/extern/_table-header.php
 create mode 100644 app/views/institute/extern/_table-row.php
 create mode 100644 app/views/institute/extern/extern_config/_basic_settings.php
 create mode 100644 app/views/institute/extern/extern_config/_institutes_selector.php
 create mode 100644 app/views/institute/extern/extern_config/_sem_types_selector.php
 create mode 100644 app/views/institute/extern/extern_config/_study_areas_selector.php
 create mode 100644 app/views/institute/extern/extern_config/_template.php
 create mode 100644 app/views/institute/extern/extern_config/coursedetails.php
 create mode 100644 app/views/institute/extern/extern_config/courses.php
 create mode 100644 app/views/institute/extern/extern_config/download.php
 create mode 100644 app/views/institute/extern/extern_config/persondetails.php
 create mode 100644 app/views/institute/extern/extern_config/persons.php
 create mode 100644 app/views/institute/extern/extern_config/timetable.php
 create mode 100644 app/views/institute/extern/index.php
 create mode 100644 app/views/institute/extern/info.php
 create mode 100644 app/views/institute/extern/new.php
 create mode 100644 app/views/institute/extern/upload.php
 create mode 100644 db/migrations/5.5.12_new_external_pages.php
 create mode 100644 lib/extern/ExternPage.php
 create mode 100644 lib/extern/ExternPageCourseDetails.php
 create mode 100644 lib/extern/ExternPageCourses.php
 create mode 100644 lib/extern/ExternPageDownload.php
 create mode 100644 lib/extern/ExternPagePersBrowse.php
 create mode 100644 lib/extern/ExternPagePersonDetails.php
 create mode 100644 lib/extern/ExternPagePersons.php
 create mode 100644 lib/extern/ExternPageTimetable.php
 delete mode 100644 lib/extern/admin_extern.inc.php
 delete mode 100644 lib/extern/elements/ExternElementBody.class.php
 delete mode 100644 lib/extern/elements/ExternElementContact.class.php
 delete mode 100644 lib/extern/elements/ExternElementContentNews.class.php
 delete mode 100644 lib/extern/elements/ExternElementLecturesInnerTable.class.php
 delete mode 100644 lib/extern/elements/ExternElementLink.class.php
 delete mode 100644 lib/extern/elements/ExternElementLinkIntern.class.php
 delete mode 100644 lib/extern/elements/ExternElementLinkInternSimple.class.php
 delete mode 100644 lib/extern/elements/ExternElementLinkInternTemplate.class.php
 delete mode 100644 lib/extern/elements/ExternElementList.class.php
 delete mode 100644 lib/extern/elements/ExternElementPersondetailsHeader.class.php
 delete mode 100644 lib/extern/elements/ExternElementPersondetailsLectures.class.php
 delete mode 100644 lib/extern/elements/ExternElementPersondetailsLecturesTemplate.class.php
 delete mode 100644 lib/extern/elements/ExternElementRangeTreeLevelContent.class.php
 delete mode 100644 lib/extern/elements/ExternElementRangeTreeLevelName.class.php
 delete mode 100644 lib/extern/elements/ExternElementReplaceTextSemType.class.php
 delete mode 100644 lib/extern/elements/ExternElementSelectInstitutes.class.php
 delete mode 100644 lib/extern/elements/ExternElementSelectSubjectAreas.class.php
 delete mode 100644 lib/extern/elements/ExternElementStudipInfo.class.php
 delete mode 100644 lib/extern/elements/ExternElementStudipLink.class.php
 delete mode 100644 lib/extern/elements/ExternElementTableFooter.class.php
 delete mode 100644 lib/extern/elements/ExternElementTableGroup.class.php
 delete mode 100644 lib/extern/elements/ExternElementTableHeader.class.php
 delete mode 100644 lib/extern/elements/ExternElementTableHeadrow.class.php
 delete mode 100644 lib/extern/elements/ExternElementTableParagraph.class.php
 delete mode 100644 lib/extern/elements/ExternElementTableParagraphHeadline.class.php
 delete mode 100644 lib/extern/elements/ExternElementTableParagraphSubHeadline.class.php
 delete mode 100644 lib/extern/elements/ExternElementTableParagraphText.class.php
 delete mode 100644 lib/extern/elements/ExternElementTableRow.class.php
 delete mode 100644 lib/extern/elements/ExternElementTableRowTwoColumns.class.php
 delete mode 100644 lib/extern/elements/ExternElementTemplateGeneric.class.php
 delete mode 100644 lib/extern/elements/ExternElementTreeBackLink.class.php
 delete mode 100644 lib/extern/elements/ExternElementTreeKids.class.php
 delete mode 100644 lib/extern/elements/ExternElementTreeLevelContent.class.php
 delete mode 100644 lib/extern/elements/ExternElementTreeLevelName.class.php
 delete mode 100644 lib/extern/elements/ExternElementTreePath.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainDownload.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainGlobal.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainLecturedetails.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainLectures.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainLecturestable.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainNews.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainNewsticker.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainPersondetails.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainPersons.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainRangelecturetree.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainSemlecturetree.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainTemplateDownload.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainTemplateLecturedetails.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainTemplateLectures.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainTemplateNews.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainTemplatePersBrowse.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainTemplatePersondetails.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainTemplatePersons.class.php
 delete mode 100644 lib/extern/elements/main/ExternElementMainTemplateSemBrowse.class.php
 delete mode 100644 lib/extern/extern.inc.php
 delete mode 100644 lib/extern/extern_config.inc.php
 delete mode 100644 lib/extern/lib/ExternConfig.class.php
 delete mode 100644 lib/extern/lib/ExternConfigDb.class.php
 delete mode 100644 lib/extern/lib/ExternEdit.class.php
 delete mode 100644 lib/extern/lib/ExternElement.class.php
 delete mode 100644 lib/extern/lib/ExternElementMain.class.php
 delete mode 100644 lib/extern/lib/ExternModule.class.php
 delete mode 100644 lib/extern/lib/extern_functions.inc.php
 delete mode 100644 lib/extern/modules/ExternModuleDownload.class.php
 delete mode 100644 lib/extern/modules/ExternModuleGlobal.class.php
 delete mode 100644 lib/extern/modules/ExternModuleLecturedetails.class.php
 delete mode 100644 lib/extern/modules/ExternModuleLectures.class.php
 delete mode 100644 lib/extern/modules/ExternModuleLecturestable.class.php
 delete mode 100644 lib/extern/modules/ExternModuleNews.class.php
 delete mode 100644 lib/extern/modules/ExternModuleNewsticker.class.php
 delete mode 100644 lib/extern/modules/ExternModulePersondetails.class.php
 delete mode 100644 lib/extern/modules/ExternModulePersons.class.php
 delete mode 100644 lib/extern/modules/ExternModuleRangelecturetree.class.php
 delete mode 100644 lib/extern/modules/ExternModuleSemlecturetree.class.php
 delete mode 100644 lib/extern/modules/ExternModuleTemplateDownload.class.php
 delete mode 100644 lib/extern/modules/ExternModuleTemplateLecturedetails.class.php
 delete mode 100644 lib/extern/modules/ExternModuleTemplateLectures.class.php
 delete mode 100644 lib/extern/modules/ExternModuleTemplateNews.class.php
 delete mode 100644 lib/extern/modules/ExternModuleTemplatePersBrowse.class.php
 delete mode 100644 lib/extern/modules/ExternModuleTemplatePersondetails.class.php
 delete mode 100644 lib/extern/modules/ExternModuleTemplatePersons.class.php
 delete mode 100644 lib/extern/modules/ExternModuleTemplateSemBrowse.class.php
 delete mode 100644 lib/extern/modules/views/ExternRangeLectureTree.class.php
 delete mode 100644 lib/extern/modules/views/ExternSemBrowse.class.php
 delete mode 100644 lib/extern/modules/views/ExternSemBrowseTable.class.php
 delete mode 100644 lib/extern/modules/views/ExternSemLectureTree.class.php
 delete mode 100644 lib/extern/modules/views/lecturedetails_preview.inc.php
 delete mode 100644 lib/extern/modules/views/lectures_preview.inc.php
 delete mode 100644 lib/extern/modules/views/lecturestable_preview.inc.php
 delete mode 100644 lib/extern/modules/views/news.inc.php
 delete mode 100644 lib/extern/modules/views/news_preview.inc.php
 delete mode 100644 lib/extern/modules/views/newsticker.inc.php
 delete mode 100644 lib/extern/modules/views/newsticker_preview.inc.php
 delete mode 100644 lib/extern/modules/views/persondetails.inc.php
 delete mode 100644 lib/extern/modules/views/persondetails_preview.inc.php
 delete mode 100644 lib/extern/modules/views/persons.inc.php
 delete mode 100644 lib/extern/modules/views/persons_preview.inc.php
 delete mode 100644 lib/extern/sri.inc.php
 delete mode 100644 lib/extern/views/ExternEditGeneric.class.php
 delete mode 100644 lib/extern/views/ExternEditHtml.class.php
 delete mode 100644 lib/extern/views/ExternEditModule.class.php
 delete mode 100644 lib/extern/views/extern_edit_module.inc.php
 delete mode 100644 lib/extern/views/extern_html_templates.inc.php
 delete mode 100644 lib/extern/views/extern_info_module.inc.php
 create mode 100644 lib/models/ExternPageConfig.php
 create mode 100644 lib/plugins/core/ExternPagePlugin.php
 delete mode 100644 public/admin_extern.php
 delete mode 100644 public/extern.php
 create mode 100644 resources/assets/javascripts/bootstrap/external_pages.js
 delete mode 100644 templates/extern/upload_form.php

diff --git a/app/controllers/admin/extern.php b/app/controllers/admin/extern.php
new file mode 100644
index 00000000000..41833b12dd9
--- /dev/null
+++ b/app/controllers/admin/extern.php
@@ -0,0 +1,491 @@
+<?php
+/**
+ * extern.php - administration controller for system-wide external pages
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @package     extern
+ * @since       5.5
+ */
+
+class Admin_ExternController extends AuthenticatedController
+{
+
+    protected $range;
+    protected $template_path;
+
+    /**
+     * @see PluginController::before_filter()
+     */
+    public function before_filter(&$action, &$args)
+    {
+        parent::before_filter($action, $args);
+
+        $this->checkPerm();
+        $this->init();
+        $this->setSidebar();
+    }
+
+    /**
+     * Initialize the controller.
+     */
+    protected function init()
+    {
+        $this->range = 'studip';
+        $nav = Navigation::getItem('admin/locations/external');
+        if ($nav) {
+            $nav->setActive(true);
+        }
+
+        $this->getSystemWideConfigTypes();
+        $this->config_types['PersBrowse'] = [
+            'name'        => _('Personen-Browser'),
+            'description' => _('Personal der Einrichtungen'),
+            'icon'        => 'person',
+            'template'    => 'admin/extern/extern_config/persbrowse'
+        ];
+
+        $this->fetchPlugins(true);
+
+        PageLayout::setTitle(_('Externe Seiten (Systemweit)'));
+    }
+
+    /**
+     * Action to show index page.
+     */
+    public function index_action()
+    {
+        $configs = [];
+        $count_not_migrated = 0;
+        ExternPageConfig::findEachBySQL(
+            function ($c) use (&$configs, &$count_not_migrated) {
+                $configs[$c->type][] = $c;
+                if (isset($c->conf['not_fixed_after_migration'])) { 
+                    $count_not_migrated++; 
+                }
+            },
+            "range_id = ?", [$this->range]
+        );
+        $this->configs = $configs;
+
+        if ($count_not_migrated > 0) {
+            PageLayout::postInfo(
+                _('Die mit einem Ausrufezeichen versehenen Konfigurationen müssen eventuell überarbeitet werden.'),
+                [
+                    _('Der Aufbau der Templates hat sich in der aktuellen Stud.IP-Version geändert.'),
+                    _('Nach dem Speichern der gekennzeichneten Templates wird die Markierung entfernt.')
+                ]
+            );
+        }
+        $actions_widget = Sidebar::get()->getWidget('actions');
+        $actions_widget->addLink(
+            _('Konfiguration hochladen'),
+            $this->uploadURL(),
+            Icon::create('upload'),
+            ['data-dialog' => 'size=auto']
+        );
+
+        $this->render_template('institute/extern/index', $this->layout);
+    }
+
+    /**
+     * Shows dialog to select a new page configuration
+     */
+    public function new_action()
+    {
+        PageLayout::setTitle(_('Neue externe Seite anlegen'));
+        $this->render_template('institute/extern/new', $this->layout);
+    }
+
+    /**
+     * Create a new configuration or edit an existing one.
+     *
+     * @param string $type_id The type of the configuration.
+     * @param string $config_id The id of the configuration.
+     * @throws AccessDeniedException
+     * @throws InvalidSecurityTokenException
+     * @throws MethodNotAllowedException
+     */
+    public function edit_action(string $type_id, string $config_id = '')
+    {
+        $this->load($type_id, $config_id);
+        $actions_widget = Sidebar::get()->getWidget('actions');
+        $actions_widget->addLink(
+            _('Vorschau anzeigen'),
+            $this->url_for('extern/index', $this->config->id),
+            Icon::create('log'),
+            ['target' => '_blank']
+         );
+        $actions_widget->addLink(
+            _('Informationen anzeigen'),
+            $this->infoURL($this->config->id),
+            Icon::create('infopage'),
+            ['data-dialog' => 'size=auto']
+        );
+        $actions_widget->addLink(
+            _('Konfiguration herunterladen'),
+            $this->downloadURL($this->config->id),
+            Icon::create('download')
+        );
+        $actions_widget->addLink(
+            _('Konfiguration hochladen'),
+            $this->uploadURL($this->config->id),
+            Icon::create('upload'),
+            ['data-dialog' => 'size=auto']
+        );
+
+        $this->render_template($this->config_types[$type_id]['template'], $this->layout);
+    }
+
+    /**
+     * Action to store an external page with configuration.
+     *
+     * @param string $type_id The type of the external page.
+     * @param string $config_id The id of the configuration.
+     * @throws AccessDeniedException
+     * @throws InvalidSecurityTokenException
+     * @throws MethodNotAllowedException
+     */
+    public function store_action(string $type_id, string $config_id = '')
+    {
+        $this->load($type_id, $config_id);
+        if (Request::isPost()) {
+            CSRFProtection::verifyUnsafeRequest();
+            $this->page->conf        = Request::extract(($this->page->getConfigFields()));
+            $this->page->name        = Request::get('name');
+            $this->page->description = Request::get('description');
+            $this->page->template    = Request::get('template');
+            if ($this->page->store()) {
+                if ($this->page->page_config->isNew()) {
+                    PageLayout::postSuccess(sprintf(
+                        _('Eine neue externe Seite "%$1s" vom Typ %$2s wurde angelegt.'),
+                        htmlReady($this->page->name), 
+                        htmlReady($this->page->type)
+                    ));
+                } else {
+                    PageLayout::postSuccess(
+                        sprintf(_('Die Konfiguration der externen Seite "%s" wurde gespeichert.'),
+                        htmlReady($this->page->name)
+                    ));
+                }
+            } else {
+                PageLayout::postInfo(_('Es wurden keine Änderungen vorgenommen'));
+            }
+            if (Request::submitted('store_cancel')) {
+                $this->redirect($this->indexURL(['open_type' => $type_id]));
+                return;
+            }
+        }
+        $this->redirect($this->editURL($type_id, $this->page->id));
+    }
+
+    /**
+     * Loads the configuration to edit or store.
+     *
+     * @param string $type_id The type of the external page.
+     * @param string $config_id The id of the external page.
+     * @throws AccessDeniedException
+     */
+    protected function load(string $type_id, string $config_id = '')
+    {
+        if (!$config_id) {
+            if (!in_array($type_id, array_keys($this->config_types))) {
+                throw new AccessDeniedException();
+            }
+            $this->config = new ExternPageConfig();
+            $this->config->type = $type_id;
+            $this->config->range_id = $this->range;
+        } else {
+            $this->config = ExternPageConfig::find($config_id);
+            if ($this->config->range_id === 'studip') {
+                $GLOBALS['perm']->check('root');
+                $have_perm = true;
+            } else {
+                $have_perm = $GLOBALS['perm']->have_studip_perm('admin', $this->config->range_id);
+            }
+            if (!$this->config || !$have_perm) {
+                throw new AccessDeniedException();
+            }
+        }
+        $this->page = ExternPage::get($this->config);
+    }
+
+    /**
+     * Deletes a configuration.
+     *
+     * @param string $config_id The id of the configuration to delete.
+     * @throws AccessDeniedException
+     * @throws InvalidSecurityTokenException
+     * @throws MethodNotAllowedException
+     */
+    public function delete_action(string $config_id)
+    {
+        $config_type = '';
+        if (Request::isPost()) {
+            CSRFProtection::verifyUnsafeRequest();
+            $config = ExternPageConfig::find($config_id);
+            if ($config->range_id === 'studip') {
+                $GLOBALS['perm']->check('root');
+                $have_perm = true;
+            } else {
+                $have_perm = $GLOBALS['perm']->have_studip_perm('admin', $config->range_id);
+            }
+            if (!$config || !$have_perm) {
+                throw new AccessDeniedException();
+            }
+            if ($config) {
+                $config_name = $config->name;
+                $config_type = $config->type;
+                if ($config->delete()) {
+                    PageLayout::postSuccess(
+                        sprintf(_('Die Konfiguration "%s" wurde gelöscht.'), htmlReady($config_name))
+                    );
+                }
+            }
+        }
+        $this->redirect($this->indexURL(['open_type' => $config_type]));
+    }
+
+    /**
+     * Show dialog with information about the given configuration.
+     *
+     * @param $config_id
+     */
+    public function info_action(string $config_id)
+    {
+        $this->page = ExternPage::get(ExternPageConfig::find($config_id));
+        if ($this->page->author) {
+            $this->author = '<a href="'
+                . URLHelper::getLink('dispatch.php/profile', ['username' => $this->page->author->username])
+                . '">'
+                . htmlReady($this->page->author)
+                . '</a>';
+        } else {
+            $this->author = _('unbekannt');
+        }
+        if ($this->page->editor) {
+            $this->editor = '<a href="'
+                . URLHelper::getLink('dispatch.php/profile', ['username' => $this->page->editor->username])
+                . '">'
+                . htmlReady($this->page->editor)
+                . '</a>';
+        } else {
+            $this->editor = _('unbekannt');
+        }
+        PageLayout::setHelpKeyword('Basis.ExterneSeiten' . $this->page->type);
+        $this->datafields = $this->page->getDataFields();
+        $this->render_template('institute/extern/info', $this->layout);
+    }
+
+    /**
+     * Action to download given configuration.
+     *
+     * @param $config_id
+     */
+    public function download_action(string $config_id)
+    {
+        $config = ExternPageConfig::find($config_id);
+        $perm = $GLOBALS['perm']->have_studip_perm('admin', $config->range_id)
+            || ($GLOBALS['perm']->have_perm('root') && $config->range_id === 'studip');
+        if (!$config || !$perm) {
+            throw new AccessDeniedException();
+        }
+        $this->response->add_header(
+            'Content-Disposition',
+            'attachment; ' . encode_header_parameter('filename', $config->name . '.cfg')
+        );
+        $this->render_json($config->toArray('type name description conf template'));
+    }
+
+    /**
+     * Action to create a new configuration from uploaded file.
+     */
+    public function upload_action()
+    {
+        $this->render_template('institute/extern/upload', $this->layout);
+    }
+
+    /**
+     * Action to import a configuration as json file.
+     *
+     * @return void
+     * @throws InvalidSecurityTokenException
+     * @throws MethodNotAllowedException
+     */
+    public function import_action()
+    {
+        if (Request::submitted('import')) {
+            $this->config_name = Request::get('config_name', '');
+            CSRFProtection::verifyUnsafeRequest();
+            $file = $_FILES['config_file'];
+            if (!$file) {
+                PageLayout::postError(_('Es wurde keine Datei ausgewählt!'));
+                $this->redirect($this->uploadURL());
+                return;
+            }
+            $config_data = json_decode(file_get_contents($file['tmp_name']));
+            if (!$config_data) {
+                PageLayout::postError(_('Die Datei hat ein ungültiges Format!'));
+                $this->redirect($this->uploadURL());
+                return;
+            }
+            $config = new ExternPageConfig();
+            $fields = [
+                'name',
+                'description',
+                'conf',
+                'template',
+                'type',
+            ];
+            foreach ($fields as $field) {
+                if (isset($config_data->$field)) {
+                    $config->$field = $config_data->$field;
+                } else {
+                    PageLayout::postError(_('Die Datei kann nicht importiert werden!'));
+                    $this->redirect($this->uploadURL());
+                    return;
+                }
+            }
+            if (!in_array($config->type, array_keys($this->config_types))) {
+                PageLayout::postError(_('Der Typ der Konfiguration ist ungültig!'));
+                $this->redirect($this->uploadURL());
+                return;
+            }
+            if (trim($this->config_name)) {
+                $config->name = $this->config_name;
+            }
+            $config->range_id = $this->range;
+            $config->author_id = $config->editor_id = $GLOBALS['user']->id;
+            $config->store();
+            PageLayout::postSuccess(
+                sprintf(_('Die Konfiguration "%s" wurde erfolgreich importiert.'), 
+                htmlReady($config->name)
+            ));
+        }
+        $this->relocate($this->indexURL(['open_type' => $config->type]));
+    }
+
+    /**
+     * Action to get study areas by search term.
+     *
+     * @param string $search_term The search term.
+     * @return void
+     */
+    public function search_studyareas_action(string $search_term = '')
+    {
+        $search_term = Request::get('term', $search_term);
+        $paths = [];
+        $study_areas = StudipStudyArea::search($search_term);
+        foreach ((array) $study_areas as $study_area) {
+            if ($study_area->isHidden()) {
+                continue;
+            }
+            $path = $study_area->getPath(' > ');
+            $paths[$path] = [
+                'id'   => $study_area->id,
+                'text' => $path
+            ];
+        }
+        ksort($paths, SORT_LOCALE_STRING);
+
+        $this->render_json([
+            'results' => array_values($paths)
+        ]);
+    }
+
+    /**
+     * Checks for sufficient rights.
+     *
+     * @throws AccessDeniedException
+     */
+    protected function checkPerm()
+    {
+        if (!$GLOBALS['perm']->have_perm('root')) {
+            throw new AccessDeniedException();
+        }
+    }
+
+    /**
+     * Creates the sidebar menu.
+     */
+    protected function setSidebar()
+    {
+        if ($this->range) {
+            $actions_widget = new ActionsWidget();
+            $actions_widget->addLink(
+                _('Neue externe Seite anlegen'),
+                $this->newURL(),
+                Icon::create('settings'),
+                ['data-dialog' => 'size=870x500']
+            );
+            Sidebar::Get()->addWidget($actions_widget);
+        }
+    }
+
+    /**
+     * Retrofits navigation with plugins.
+     *
+     * @param bool $is_system True to fetch system-wide external page plugins.
+     * @return void
+     */
+    protected function fetchPlugins(bool $is_system): void
+    {
+        $plugins = PluginEngine::getPlugins('ExternPagePlugin');
+        foreach ($plugins as $plugin) {
+            if (
+                $is_system === $plugin->isSystemPage()
+                || !$is_system === $plugin->isInstitutePage()
+            ) {
+                $nav = $plugin->getConfigurationFormNavigation();
+                $this->config_types[$nav->name] = [
+                    'name' => $nav->title,
+                    'description' => $nav->description,
+                    'icon' => $nav->image,
+                    'template' => $plugin->getConfigurationFormTemplate(),
+                ];
+            }
+        }
+    }
+
+    /**
+     * Sets data for system-wide external pages.
+     *
+     * @return void
+     */
+    protected function getSystemWideConfigTypes(): void
+    {
+        $this->config_types = [
+            'PersonDetails'  => [
+                'name'        => _('Personen-Details'),
+                'description' => _('Details zu einer Person'),
+                'icon'        => 'person2',
+                'template'    => 'institute/extern/extern_config/persondetails'
+            ],
+            'Courses'       => [
+                'name'        => _('Veranstaltungen'),
+                'description' => _('Liste der Veranstaltungen'),
+                'icon'        => 'seminar',
+                'template'    => 'institute/extern/extern_config/courses'
+            ],
+            'CourseDetails' => [
+                'name'        => _('Veranst.-Details'),
+                'description' => _('Details zu einer Veranstaltung'),
+                'icon'        => 'seminar',
+                'template'    => 'institute/extern/extern_config/coursedetails'
+            ],
+            'Timetable'     => [
+                'name'        => _('Termine'),
+                'description' => _('Zeiten/Termine/Themen der Veranstaltungen'),
+                'icon'        => 'date-cycle',
+                'template'    => 'institute/extern/extern_config/timetable'
+            ]
+        ];
+    }
+
+}
diff --git a/app/controllers/extern.php b/app/controllers/extern.php
new file mode 100644
index 00000000000..6cde6f397e2
--- /dev/null
+++ b/app/controllers/extern.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * extern.php - Controller to provide content to external pages.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @since       5.4
+ */
+
+class ExternController extends StudipController
+{
+    protected $with_session = true;
+
+    /**
+     * Action shows rendered external page.
+     *
+     * @param string $config_id The id of the configuration of the external page to show.
+     * @throws Trails_DoubleRenderError
+     */
+    public function index_action(string $config_id)
+    {
+        $config = ExternPageConfig::find($config_id);
+        if (!$config) {
+            $this->render_text(
+                Config::get()->EXTERN_PAGES_ERROR_MESSAGE
+            );
+            return;
+        }
+        try {
+            $page = ExternPage::get($config);
+            $page->setRequestParams();
+        } catch (Exception $e) {
+            $this->render_text(
+                Config::get()->EXTERN_PAGES_ERROR_MESSAGE . '<br>' . $e->getMessage()
+            );
+            return;
+        }
+
+        $this->render_text($page->toString());
+    }
+
+}
diff --git a/app/controllers/institute/extern.php b/app/controllers/institute/extern.php
new file mode 100644
index 00000000000..66329902c59
--- /dev/null
+++ b/app/controllers/institute/extern.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * extern.php - administration controller for external pages for institutes
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @package     extern
+ * @since       5.4
+ */
+
+require_once 'app/controllers/admin/extern.php';
+
+class Institute_ExternController extends Admin_ExternController
+{
+
+    /**
+     * @see PluginController::before_filter()
+     */
+    public function before_filter(&$action, &$args)
+    {
+        parent::before_filter($action, $args);
+
+        if (!Institute::findCurrent()) {
+            require_once 'lib/admin_search.inc.php';
+
+            // TODO: We don't seem to need this since admin_search will stop the script
+            PageLayout::postInfo(_('Sie müssen zunächst eine Einrichtung auswählen'));
+            $this->redirect('institute/basicdata/index?list=TRUE');
+            return;
+        }
+    }
+
+    /**
+     * Initialize the controller.
+     */
+    protected function init()
+    {
+        $this->range = Context::getId();
+        $this->template_path = 'institute/extern/extern_config/';
+        $nav = Navigation::getItem('admin/institute/external');
+        if ($nav) {
+            $nav->setActive(true);
+        }
+
+        $this->getSystemWideConfigTypes();
+        $this->config_types['Persons'] = [
+            'name'        => _('Personen'),
+            'description' => _('Liste der Personen an einer Einrichtung'),
+            'icon'        => 'persons2',
+            'template'    => 'institute/extern/extern_config/persons',
+        ];
+        $this->config_types['Download'] = [
+            'name'        => _('Dateien'),
+            'description' => _('Liste der Dateien zum Download'),
+            'icon'        => 'files',
+            'template'    => 'institute/extern/extern_config/download',
+        ];
+
+        $this->fetchPlugins(false);
+
+        PageLayout::setTitle(_('Externe Seiten (Einrichtung)'));
+    }
+
+    protected function checkPerm()
+    {
+        if (Context::getId() && !$GLOBALS['perm']->have_studip_perm('admin', Context::getId())) {
+            throw new AccessDeniedException();
+        }
+    }
+
+}
diff --git a/app/views/admin/extern/extern_config/persbrowse.php b/app/views/admin/extern/extern_config/persbrowse.php
new file mode 100644
index 00000000000..ec050f7d406
--- /dev/null
+++ b/app/views/admin/extern/extern_config/persbrowse.php
@@ -0,0 +1,51 @@
+<?php
+/**
+ * @var Admin_ExternController $controller
+ * @var ExternPagePersBrowse $page
+ * @var ExternPageConfig $config
+ */
+?>
+
+<span class="content-title">
+    <?= _('Konfiguration für die Ausgabe von Veranstaltungen') ?>
+</span>
+
+<form method="post" action="<?= $controller->store('PersBrowse', $config->id) ?>" class="default collapsable">
+    <?= CSRFProtection::tokenTag() ?>
+    <?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
+
+    <fieldset>
+        <legend>
+            <?= _('Angaben zum Inhalt') ?>
+        </legend>
+        <label>
+            <?= _('Rechtestufe in Einrichtungen') ?>
+            <select name="instperms[]" class="nested-select" multiple>
+                <? foreach ($page->getInstitutePermissionOptions() as $instperm_id => $instperm_name) : ?>
+                    <option
+                        value="<?= $instperm_id ?>"
+                        <?= in_array($instperm_id, $page->instperms ?? []) ? ' selected' : '' ?>>
+                        <?= htmlReady($instperm_name) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <input type="checkbox" name="onlylecturers" value="1"
+                <?= $page->onlylecturers ? 'checked' : '' ?>>
+            <?= _('Nur Lehrende anzeigen.') ?>
+        </label>
+        <?= $this->render_partial('institute/extern/extern_config/_institutes_selector') ?>
+    </fieldset>
+
+    <?= $this->render_partial('institute/extern/extern_config/_template') ?>
+
+    <footer data-dialog-button>
+        <?= Studip\Button::createAccept(_('Speichern')) ?>
+        <?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
+        <?= Studip\LinkButton::createCancel(
+            _('Abbrechen'), $controller->url_for('institute/extern/index')
+        ) ?>
+    </footer>
+
+</form>
diff --git a/app/views/institute/extern/_table-header.php b/app/views/institute/extern/_table-header.php
new file mode 100644
index 00000000000..9d2ad871ca2
--- /dev/null
+++ b/app/views/institute/extern/_table-header.php
@@ -0,0 +1,16 @@
+<colgroup>
+    <col style="width: 20%">
+    <col>
+    <col style="width: 80px">
+    <col style="width: 25%">
+    <col style="width: 24px">
+</colgroup>
+<thead>
+<tr class="sortable">
+    <th data-sort="text"><?= _('Name') ?></th>
+    <th data-sort="false"><?= _('Beschreibung') ?></th>
+    <th data-sort="htmldata"><?= _('Letzte Änderung') ?></th>
+    <th data-sort="text"><?= _('Erstellt von') ?></th>
+    <th data-sort="false"></th>
+</tr>
+</thead>
diff --git a/app/views/institute/extern/_table-row.php b/app/views/institute/extern/_table-row.php
new file mode 100644
index 00000000000..1568bf95fd2
--- /dev/null
+++ b/app/views/institute/extern/_table-row.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * @var ExternController $controller
+ * @var ExternPageConfig $config
+ */
+?>
+
+<tr>
+    <td>
+        <strong><a href="<?= $controller->link_for('/edit', $config->type, $config->id) ?>">
+            <?= htmlReady($config->name) ?>
+            <?= isset($config->conf['not_fixed_after_migration']) ? '(!)' : '' ?>
+            </a></strong>
+    </td>
+    <td>
+        <small><?= htmlReady($config->description) ?></small>
+    </td>
+    <td data-sort-value="<?= (int) $config->chdate ?>">
+        <?= date('d.m.Y G:H', $config->chdate) ?>
+    </td>
+    <td>
+        <? if ($config->author) : ?>
+            <a href="<?= URLHelper::getLink('dispatch.php/profile', ['username' => $config->author->username]) ?>">
+                <?= htmlReady($config->author->getFullName()) ?>
+            </a>
+        <? else : ?>
+            <?= _('unbekannt') ?>
+        <? endif ?>
+    </td>
+    <td class="actions">
+        <?= ActionMenu::get()->addLink(
+                $controller->editURL($config->type, $config->id),
+                _('Konfiguration bearbeiten'),
+                Icon::create('edit')
+            )->addLink(
+                $controller->infoURL($config->id),
+                _('Informationen anzeigen'),
+                Icon::create('infopage'),
+                ['data-dialog' => '']
+           )->addLink(
+               $controller->downloadURL($config->id),
+               _('Konfiguration herunterladen'),
+               Icon::create('download')
+           )->addButton(
+               'delete',
+               _('Konfiguration löschen'),
+               Icon::create('trash'),
+               [
+                   'formaction'   => $controller->deleteURL($config->id),
+                   'title'        => _('Konfiguration löschen'),
+                   'data-confirm' => sprintf(_('Soll die Konfiguration "%s" gelöscht werden?'), htmlReady($config->name)),
+                   'form'         => 'extern-page-index'
+               ]
+           )->render() 
+       ?>
+    </td>
+</tr>
diff --git a/app/views/institute/extern/extern_config/_basic_settings.php b/app/views/institute/extern/extern_config/_basic_settings.php
new file mode 100644
index 00000000000..5a61f4a0c4c
--- /dev/null
+++ b/app/views/institute/extern/extern_config/_basic_settings.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * @var ExternPageConfig $config
+ * @var ExternPage $page
+ */
+?>
+
+<fieldset>
+    <legend>
+        <?= _('Allgemeine Daten') ?>
+    </legend>
+    <label class="studiprequired" for="external_page_config_name">
+        <span class="textlabel">
+            <?= _('Name der Konfiguration') ?>
+        </span>
+        <span class="asterisk" title="<?= _('Dies ist ein Pflichtfeld') ?>" aria-hidden="true">*</span>
+        <input type="text"
+               id="external_page_config_name"
+               value="<?= htmlReady($config->name) ?>"
+               required
+               name="name"
+               maxlength="255">
+    </label>
+    <label>
+        <?= _('Beschreibung') ?>
+        <textarea name="description"><?= htmlReady($config->description) ?></textarea>
+    </label>
+    <label>
+        <?= _('Ausgabesprache') ?>
+        <select name="language">
+            <? foreach (Config::get()->CONTENT_LANGUAGES as $language_id => $language_data) : ?>
+                <option value="<?= $language_id ?>"
+                    <?= $page->language === $language_id ? ' selected' : '' ?>>
+                    <?= htmlReady($language_data['name']) ?>
+                </option>
+            <? endforeach ?>
+        </select>
+    </label>
+    <label>
+        <?= _('Automatisches Umkodieren der Inhalte') ?>
+        <?
+        $escaping_types = [
+            _('Keine Umkodierung vornehmen') => '',
+            _('html-konform umkodieren')     => 'htmlReady',
+            _('xml-konform umkodieren')      => 'xml',
+            _('json-konform umkodieren')     => 'json'
+        ]
+        ?>
+        <select name="escaping">
+            <? foreach ($escaping_types as $escaping_name => $escaping_type) : ?>
+                <option value="<?= $escaping_type ?>"
+                    <?= $page->escaping === $escaping_type ? ' selected' : '' ?>>
+                    <?= htmlReady($escaping_name) ?>
+                </option>
+            <? endforeach ?>
+        </select>
+    </label>
+</fieldset>
diff --git a/app/views/institute/extern/extern_config/_institutes_selector.php b/app/views/institute/extern/extern_config/_institutes_selector.php
new file mode 100644
index 00000000000..f6bfb757dbf
--- /dev/null
+++ b/app/views/institute/extern/extern_config/_institutes_selector.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * @var ExternPageCourses $page
+ */
+?>
+
+<? $institutes = $page->getInstitutes() ?>
+<? if (count($institutes) > 1) : ?>
+    <label>
+        <?= _('Einrichtungen') ?>
+        <select name="institutes[]" class="nested-select" multiple>
+            <? foreach ($institutes as $institute) : ?>
+                <option
+                    class="<?= $institute['is_fak'] ? 'nested-item-header' : 'nested-item' ?>"
+                    value="<?= htmlReady($institute['Institut_id']) ?>"
+                    <?= in_array($institute['Institut_id'], (array) $page->institutes) ? 'selected' : '' ?>>
+                    <?= htmlReady($institute['Name']) ?>
+                </option>
+            <? endforeach ?>
+        </select>
+    </label>
+<? endif ?>
diff --git a/app/views/institute/extern/extern_config/_sem_types_selector.php b/app/views/institute/extern/extern_config/_sem_types_selector.php
new file mode 100644
index 00000000000..5acc2e21bd2
--- /dev/null
+++ b/app/views/institute/extern/extern_config/_sem_types_selector.php
@@ -0,0 +1,22 @@
+<?php
+/**
+ * @var ExternPageCourses $page
+ */
+?>
+
+<label>
+    <?= _('Veranstaltungstypen') ?>
+    <select name="semtypes[]" class="nested-select" multiple>
+         <? foreach (ExternPage::getGroupedSemTypes() as $class) : ?>
+            <option class="nested-item-header" disabled><?= htmlReady($class['name']) ?></option>
+            <? foreach ($class['types'] as $type) : ?>
+                <option
+                    class="nested-item"
+                    value="<?= htmlReady($type['id']) ?>"
+                    <?= in_array($type['id'], (array) $page->semtypes) ? ' selected' : '' ?>>
+                    <?= htmlReady("{$type['name']} ({$class['name']})") ?>
+                </option>
+            <? endforeach ?>
+        <? endforeach ?>
+    </select>
+</label>
diff --git a/app/views/institute/extern/extern_config/_study_areas_selector.php b/app/views/institute/extern/extern_config/_study_areas_selector.php
new file mode 100644
index 00000000000..a8b87179662
--- /dev/null
+++ b/app/views/institute/extern/extern_config/_study_areas_selector.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * @var ExternPageCourses $page
+ */
+?>
+
+<fieldset>
+    <legend>
+        <?= _('Studienbereiche') ?>
+    </legend>
+    <label>
+        <?= _('Anzuzeigende Studienbereiche') ?>
+        <?= tooltipIcon(_('Wenn keine Studienbereiche ausgewählt werden, werden alle angezeigt.')) ?>
+        <? $study_area_paths = $page->getStudyAreaPaths() ?>
+        <select name="studyareas[]" class="nested-select" id="select-study-areas" multiple>
+            <? foreach ($study_area_paths as $area_id => $path) : ?>
+                <option
+                    value="<?= htmlReady($area_id) ?>"
+                    selected class="nested-item"><?= htmlReady($path) ?>
+                </option>
+            <? endforeach ?>
+        </select>
+    </label>
+    <label>
+        <input type="checkbox" name="scope_kids" value="1"
+            <?= $page->scope_kids ? 'checked' : '' ?>>
+        <?= _('Unterebenen anzeigen.') ?>
+    </label>
+</fieldset>
diff --git a/app/views/institute/extern/extern_config/_template.php b/app/views/institute/extern/extern_config/_template.php
new file mode 100644
index 00000000000..92821a0162d
--- /dev/null
+++ b/app/views/institute/extern/extern_config/_template.php
@@ -0,0 +1,15 @@
+<?php
+/**
+ * @var ExternPage $page
+ */
+?>
+
+<fieldset>
+    <legend>
+        <?= _('Template') ?>
+    </legend>
+    <label>
+        <textarea name="template" placeholder="<?= _('Geben Sie hier das Template ein.') ?>"
+                  cols="80" rows="20"><?= htmlReady($page->template) ?></textarea>
+    </label>
+</fieldset>
diff --git a/app/views/institute/extern/extern_config/coursedetails.php b/app/views/institute/extern/extern_config/coursedetails.php
new file mode 100644
index 00000000000..93a2e6a84f6
--- /dev/null
+++ b/app/views/institute/extern/extern_config/coursedetails.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * @var ExternController $controller
+ * @var ExternPageConfig $config
+ */
+?>
+
+<span class="content-title">
+    <?= _('Konfiguration für die Detailansicht einer Veranstaltung') ?>
+</span>
+
+<form method="post" action="<?= $controller->store('CourseDetails', $config->id) ?>" class="default collapsable">
+    <?= CSRFProtection::tokenTag() ?>
+    <?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
+    <fieldset>
+        <legend>
+            <?= _('Angaben zum Inhalt') ?>
+        </legend>
+        <label>
+            <?= _('Bereichspfad ab Ebene') ?>
+            <?= tooltipIcon(_('Wählen Sie, ab welcher Ebene der Bereichspfad ausgegeben werden soll.')) ?>
+            <input min="1" max="10" type="number" name="rangepathlevel" value="<?= $page->rangepathlevel ?? 1 ?>">
+        </label>
+    </fieldset>
+    <?= $this->render_partial('institute/extern/extern_config/_template') ?>
+
+    <footer data-dialog-button>
+        <?= Studip\Button::createAccept(_('Speichern')) ?>
+        <?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
+        <?= Studip\LinkButton::createCancel(
+            _('Abbrechen'), $controller->indexURL()
+        ) ?>
+    </footer>
+
+</form>
diff --git a/app/views/institute/extern/extern_config/courses.php b/app/views/institute/extern/extern_config/courses.php
new file mode 100644
index 00000000000..2021c10f838
--- /dev/null
+++ b/app/views/institute/extern/extern_config/courses.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ * @var ExternController $controller
+ * @var ExternPageConfig $config
+ * @var ExternPageCourses $page
+ */
+?>
+
+<span class="content-title">
+    <?= _('Konfiguration für die Ausgabe von Veranstaltungen') ?>
+</span>
+<form method="post" action="<?= $controller->store('Courses', $config->id) ?>" class="default collapsable">
+    <?= CSRFProtection::tokenTag() ?>
+    <?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
+    <fieldset>
+        <legend>
+            <?= _('Angaben zum Inhalt') ?>
+        </legend>
+        <label class="col-3">
+            <?= _('Gruppierung') ?>
+            <select name="groupby">
+                <? foreach ($page->getGroupingOptions() as $id => $name) : ?>
+                    <option value="<?= $id ?>"<?= $page->groupby == $id ? ' selected' : '' ?>><?= htmlReady($name) ?></option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <?= _('Startsemester') ?>
+            <?= tooltipIcon(_('Geben Sie das erste anzuzeigende Semester an. '
+                . 'Die Angaben "Vorheriges", "Aktuelles" und "Nächstes" beziehen sich immer auf das laufende Semester '
+                . 'und werden automatisch angepasst.')) ?>
+            <select name="startsem">
+                <? foreach ($page->getSemesterOptions() as $semester) : ?>
+                    <option
+                        value="<?= htmlReady($semester['id']) ?>"
+                        <?= $page->startsem === $semester['id'] ? ' selected' : '' ?>>
+                        <?= htmlReady($semester['name']) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <?= _('Anzahl der anzuzeigenden Semester') ?>
+            <?= tooltipIcon(_('Geben Sie an, wieviele Semester (ab o.a. Startsemester) angezeigt werden sollen.')) ?>
+            <input type="number" min="1" name="semcount" value="<?= htmlReady($page->semcount ?: '1') ?>">
+        </label>
+        <label>
+            <?= _('Umschalten des aktuellen Semesters') ?>
+            <?= tooltipIcon(_('Geben Sie an, wieviele Wochen vor Semesterende automatisch auf das nächste Semester '
+                . 'umgeschaltet werden soll.')) ?>
+            <select name="semswitch">
+                <option value="0"><?= _('Am Semesterende') ?></option>
+                <option value="-1">
+                    <? printf(ngettext('%s Woche vor Semesterende (Systemkonfiguration)',
+                        '%s Wochen vor Semesterende (Systemkonfiguration)',
+                        Config::get()->SEMESTER_TIME_SWITCH),
+                        Config::get()->SEMESTER_TIME_SWITCH) ?>
+                </option>
+                <? foreach (range(1, 12) as $weeks) : ?>
+                    <option value="<? $weeks ?>">
+                        <? printf(ngettext('%s Woche vor Semesterende',
+                            '%s Wochen vor Semesterende', $weeks),
+                            $weeks) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <input type="checkbox" name="participating" value="1"
+                <?= $page->participating ? 'checked' : '' ?>>
+            <?= _('Veranstaltungen beteiligter Institute anzeigen.') ?>
+        </label>
+        <?= $this->render_partial('institute/extern/extern_config/_sem_types_selector') ?>
+        <?= $this->render_partial('institute/extern/extern_config/_institutes_selector') ?>
+    </fieldset>
+    <?= $this->render_partial('institute/extern/extern_config/_study_areas_selector') ?>
+    <?= $this->render_partial('institute/extern/extern_config/_template') ?>
+    <footer data-dialog-button>
+        <?= Studip\Button::createAccept(_('Speichern')) ?>
+        <?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
+        <?= Studip\LinkButton::createCancel(
+            _('Abbrechen'), $controller->indexURL()
+        ) ?>
+    </footer>
+</form>
diff --git a/app/views/institute/extern/extern_config/download.php b/app/views/institute/extern/extern_config/download.php
new file mode 100644
index 00000000000..129accd877b
--- /dev/null
+++ b/app/views/institute/extern/extern_config/download.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * @var ExternController $controller
+ * @var ExternPageDownload $page
+ * @var ExternPageConfig $config
+ */
+?>
+
+<span class="content-title">
+    <?= _('Konfiguration für eine Liste von Dateien (Download)') ?>
+</span>
+
+<form method="post" action="<?= $controller->store('Download', $config->id) ?>" class="default collapsable">
+    <?= CSRFProtection::tokenTag() ?>
+    <?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
+
+    <fieldset>
+        <legend>
+            <?= _('Angaben zum Inhalt') ?>
+        </legend>
+        <label class="col-3">
+            <?= _('Sortierung') ?>
+            <select name="sort" id="data_sort">
+                <? foreach ($page->getSortFields() as $sort_field => $field_name) : ?>
+                    <option value="<?= htmlReady($sort_field) ?>"
+                        <? if ($sort_field === $page->sort) echo 'selected'; ?>>
+                        <?= htmlReady($field_name) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <?= _('Ordnerauswahl') ?>
+            <select class="nested-select" name="folder[]" multiple>
+                <? foreach ($page->get_concatenated_folders() as $folder_id => $folder_name) : ?>
+                    <option value="<?= htmlReady($folder_id) ?>"
+                    <?= in_array($folder_id, (array) $page->folder) ? 'selected' : '' ?>>
+                        <?= htmlReady($folder_name) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <input type="checkbox" name="subfolders" value="1"
+                <?= $page->subfolders ? 'checked' : '' ?>>
+            <?= _('Unterordner der ausgewählten Ordner anzeigen.') ?>
+        </label>
+    </fieldset>
+
+    <?= $this->render_partial('institute/extern/extern_config/_template') ?>
+
+    <footer data-dialog-button>
+        <?= Studip\Button::createAccept(_('Speichern')) ?>
+        <?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
+        <?= Studip\LinkButton::createCancel(
+            _('Abbrechen'), $controller->indexURL()
+        ) ?>
+    </footer>
+
+</form>
diff --git a/app/views/institute/extern/extern_config/persondetails.php b/app/views/institute/extern/extern_config/persondetails.php
new file mode 100644
index 00000000000..311551d53d8
--- /dev/null
+++ b/app/views/institute/extern/extern_config/persondetails.php
@@ -0,0 +1,107 @@
+<?php
+/**
+ * @var ExternController $controller
+ * @var ExternPageConfig $config
+ * @var ExternPagePersonDetails $page
+ */
+?>
+
+<span class="content-title">
+    <?= _('Konfiguration für die Detailansicht von Mitarbeitenden (Personal)') ?>
+</span>
+
+<form method="post" action="<?= $controller->store('PersonDetails', $config->id) ?>" class="default collapsable">
+    <?= CSRFProtection::tokenTag() ?>
+    <?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
+    <fieldset>
+        <legend>
+            <?= _('Angaben zum Inhalt') ?>
+        </legend>
+        <label>
+            <input type="checkbox" name="defaultaddr" value="1"
+                   <?= $page->defaultaddr ? 'checked' : '' ?>>
+            <?= _('Standard-Adresse') ?>
+            <?= tooltipIcon(_('Wenn Sie diese Option wählen, wird die Standard-Adresse ausgegeben, '
+                . 'die jede(r) Mitarbeiter(in) bei seinen universitären Daten auswählen kann. '
+                . 'Wählen Sie diese Option nicht, wenn immer die Adresse der Einrichtung ausgegeben werden soll.')) ?>
+        </label>
+    </fieldset>
+
+    <fieldset>
+        <legend>
+            <?= _('Persönliche Lehrveranstaltungen') ?>
+        </legend>
+        <label>
+            <?= _('Startsemester') ?>
+            <?= tooltipIcon(_('Geben Sie das erste anzuzeigende Semester an. '
+                . 'Die Angaben "vorheriges", "aktuelles" und "nächstes" beziehen sich immer auf das laufende Semester '
+                . 'und werden automatisch angepasst.')) ?>
+            <select name="startsem">
+                <option value="previous"<?= $page->startsem === 'previous' ? ' selected' : '' ?>>
+                    <?= _('vorheriges') ?>
+                </option>
+                <option value="current"<?= $page->startsem === 'current' ? ' selected' : '' ?>>
+                    <?= _('aktuelles') ?>
+                </option>
+                <option value="last"<?= $page->startsem === 'last' ? ' selected' : '' ?>>
+                    <?= _('letztes') ?>
+                </option>
+                <? foreach (array_reverse(Semester::getAll()) as $semester) : ?>
+                    <option value="<?= $semester->id ?>"<?= $page->startsem === $semester->id ? ' selected' : '' ?>>
+                        <?= htmlReady($semester->name) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <?= _('Anzahl der anzuzeigenden Semester') ?>
+            <?= tooltipIcon(_('Geben Sie an, wieviele Semester (ab o.a. Startsemester) angezeigt werden sollen.')) ?>
+            <input type="number" name="semcount" value="<?= (int) $page->semcount ?>">
+        </label>
+        <label>
+            <?= _('Umschalten des aktuellen Semesters') ?>
+            <?= tooltipIcon(_('Geben Sie an, wieviele Wochen vor Semesterende automatisch auf das nächste Semester '
+                . 'umgeschaltet werden soll.')) ?>
+            <select name="semswitch">
+                <option value="0"<?= $page->semswitch === 0 ? ' selected' : '' ?>><?= _('Am Semesterende') ?></option>
+                <option value="-1"<?= $page->semswitch === -1 ? ' selected' : '' ?>>
+                    <? printf(ngettext('%s Woche vor Semesterende (Systemkonfiguration)',
+                            '%s Wochen vor Semesterende (Systemkonfiguration)',
+                            Config::get()->SEMESTER_TIME_SWITCH),
+                        Config::get()->SEMESTER_TIME_SWITCH) ?>
+                </option>
+                <? foreach (range(1, 12) as $weeks) : ?>
+                    <option value="<?= $weeks ?>"<?= $weeks === $page->semswitch ? ' selected' : '' ?>>
+                        <? printf(ngettext('%s Woche vor Semesterende',
+                                '%s Wochen vor Semesterende', $weeks),
+                            $weeks) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <?= _('Veranstaltungskategorien') ?>
+            <?= tooltipIcon(_('Wählen Sie aus, welche Veranstaltungskategorien angezeigt werden sollen.')) ?>
+            <select class="nested-select" name="semclass[]" multiple>
+                <? foreach ($GLOBALS['SEM_CLASS'] as $key => $sem_class) : ?>
+                    <? if ($sem_class['show_browse']) : ?>
+                        <option value="<?= $key ?>"<?= in_array($key, $page->semclass) ? ' selected' : '' ?>>
+                            <?= htmlReady($sem_class['name']) ?>
+                        </option>
+                    <? endif ?>
+                <? endforeach ?>
+            </select>
+        </label>
+    </fieldset>
+
+    <?= $this->render_partial('institute/extern/extern_config/_template') ?>
+
+    <footer data-dialog-button>
+        <?= Studip\Button::createAccept(_('Speichern')) ?>
+        <?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
+        <?= Studip\LinkButton::createCancel(
+            _('Abbrechen'), $controller->indexURL()
+        ) ?>
+    </footer>
+
+</form>
diff --git a/app/views/institute/extern/extern_config/persons.php b/app/views/institute/extern/extern_config/persons.php
new file mode 100644
index 00000000000..e2e17d0201e
--- /dev/null
+++ b/app/views/institute/extern/extern_config/persons.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * @var ExternController $controller
+ * @var ExternPageConfig $config
+ * @var ExternPagePersons $page
+ */
+?>
+
+<span class="content-title">
+    <?= _('Konfiguration für eine Liste der Mitarbeitenden (Personal)') ?>
+</span>
+
+<form method="post" action="<?= $controller->store('Persons', $config->id) ?>" class="default collapsable">
+    <?= CSRFProtection::tokenTag() ?>
+    <?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
+    <fieldset>
+        <legend>
+            <?= _('Angaben zum Inhalt') ?>
+        </legend>
+        <label class="col-3">
+            <?= _('Sortierung') ?>
+            <select name="sort" id="data_sort">
+                <? foreach ($page->getSortFields() as $sort_field => $field_name) : ?>
+                    <option value="<?= htmlReady($sort_field) ?>"
+                        <? if ($sort_field === $page->sort) echo 'selected'; ?>>
+                        <?= htmlReady($field_name) ?>
+                    </option>
+                <? endforeach; ?>
+            </select>
+        </label>
+        <label>
+            <input type="checkbox" name="grouping" value="1"
+                <?= $page->grouping ? 'checked' : '' ?>>
+            <?= _('Gruppierung nach Funktionen/Gruppen') ?>
+        </label>
+    </fieldset>
+    <fieldset>
+        <legend>
+            <?= _('Ausgabe der Funktionen / Gruppen (Sichtbarkeit, alternative Gruppennamen)') ?>
+        </legend>
+        <? $full_group_names = $page->getFullGroupNames() ?>
+        <? if (count($full_group_names)) : ?>
+            <? foreach ($full_group_names as $group_id => $group_name) : ?>
+                <label class="col-5">
+                    <input type="checkbox" name="groupsvisible[<?= $group_id ?>]" value="1"
+                           <?= $page->groupsvisible[$group_id] ? 'checked' : '' ?>>
+                    <?= htmlReady($group_name) ?>
+                </label>
+                <label class="col-5" aria-label="<?= htmlReady($group_name) ?>">
+                    <input type="text" name="groupsalias[<?= $group_id ?>]"
+                           value="<?= htmlReady($page->groupsalias[$group_id]) ?>"
+                           placeholder="<? printf(_('Alternativer Gruppenname (%s)'), htmlReady($group_name)) ?>">
+                </label>
+            <? endforeach ?>
+        <? else : ?>
+            <?= _('Keine Funktionen / Gruppen an dieser Einrichtung vorhanden.') ?>
+        <? endif ?>
+    </fieldset>
+
+    <?= $this->render_partial('institute/extern/extern_config/_template') ?>
+
+    <footer data-dialog-button>
+        <?= Studip\Button::createAccept(_('Speichern')) ?>
+        <?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
+        <?= Studip\LinkButton::createCancel(
+            _('Abbrechen'),
+            $controller->indexURL()
+        ) ?>
+    </footer>
+
+</form>
diff --git a/app/views/institute/extern/extern_config/timetable.php b/app/views/institute/extern/extern_config/timetable.php
new file mode 100644
index 00000000000..a5b5f8c594d
--- /dev/null
+++ b/app/views/institute/extern/extern_config/timetable.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * @var ExternController $controller
+ * @var ExternPageConfig $config
+ * @var ExternPageTimetable $page
+ */
+?>
+
+<span class="content-title">
+    <?= _('Konfiguration für die Ausgabe Veranstaltungsterminen') ?>
+</span>
+<form method="post" action="<?= $controller->store('Timetable', $config->id) ?>" class="default collapsable">
+    <?= CSRFProtection::tokenTag() ?>
+    <?= $this->render_partial('institute/extern/extern_config/_basic_settings') ?>
+    <fieldset>
+        <legend>
+            <?= _('Angaben zum Inhalt') ?>
+        </legend>
+        <label>
+            <?= _('Startdatum') ?>
+            <input type="text" name="date" class="size-s" data-date-picker="" value="<?= htmlReady($page->date) ?>">
+        </label>
+        <label>
+            <select name="date_offset">
+                <? foreach ($page->getDateOffsetOptions() as $offset_key => $offset_name) : ?>
+                    <option value="<?= $offset_key ?>"<?= $offset_key === $page->date_offset ? ' selected' : '' ?>>
+                        <?= htmlReady($offset_name) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <?= _('Anzahl der Zeitbereiche') ?>
+            <?= tooltipIcon(_('Geben Sie an, wie viele der folgenden Zeitbereiche angezeigt werden sollen.')) ?>
+            <input type="number" min="1" name="range_count" value="<?= htmlReady($page->range_count ?: '1') ?>">
+        </label>
+        <label>
+            <?= _('Anzuzeigender Zeitbereich') ?>
+            <select name="time_range">
+                <? foreach ($page->getTimeRangeOptions() as $range_key => $range_name) : ?>
+                    <option value="<?= $range_key ?>"<?= $range_key === $page->time_range ? ' selected' : '' ?>>
+                        <?= htmlReady($range_name) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <?= _('Anzuzeigende Termintypen') ?>
+            <select name="event_types[]" class="nested-select" multiple>
+                <? foreach (Config::get()->TERMIN_TYP as $type_id => $event_typ) : ?>
+                    <option value="<?= $type_id ?>"<?= in_array($type_id, (array) $page->event_types) ? ' selected' : '' ?>>
+                        <?= htmlReady($event_typ['name']) ?>
+                    </option>
+                <? endforeach ?>
+            </select>
+        </label>
+        <label>
+            <input type="checkbox" name="participating" value="1"
+                <?= $page->participating ? 'checked' : '' ?>>
+            <?= _('Veranstaltungen beteiligter Institute anzeigen.') ?>
+        </label>
+        <?= $this->render_partial('institute/extern/extern_config/_sem_types_selector') ?>
+        <?= $this->render_partial('institute/extern/extern_config/_institutes_selector') ?>
+    </fieldset>
+    <?= $this->render_partial('institute/extern/extern_config/_study_areas_selector') ?>
+    <?= $this->render_partial('institute/extern/extern_config/_template') ?>
+    <footer data-dialog-button>
+        <?= Studip\Button::createAccept(_('Speichern')) ?>
+        <?= Studip\Button::createAccept(_('Speichern und zurück'), 'store_cancel') ?>
+        <?= Studip\LinkButton::createCancel(
+            _('Abbrechen'), $controller->indexURL()
+        ) ?>
+    </footer>
+</form>
diff --git a/app/views/institute/extern/index.php b/app/views/institute/extern/index.php
new file mode 100644
index 00000000000..2fdf31eaea3
--- /dev/null
+++ b/app/views/institute/extern/index.php
@@ -0,0 +1,48 @@
+<?php
+/**
+ * @var Institute_ExternController $controller
+ * @var array $config_types
+ * @var ExternPageConfig[] $configs
+ */
+
+if (count($configs) == 0)  :
+    PageLayout::postInfo(_('Es wurde noch keine externe Seite angelegt.'),
+        [
+            sprintf(_('Um eine neue externe Seite anzulegen, klicken sie %shier%s.'),
+                '<a href="' . $controller->new() . '" data-dialog="size=870x500">',
+                '</a>')
+        ]);
+else : ?>
+<form id="extern-page-index" action="#" method="post">
+    <?= CSRFProtection::tokenTag() ?>
+    <section class="contentbox">
+        <header>
+            <h1>
+                <?= _('Externe Seiten') ?>
+            </h1>
+        </header>
+        <? foreach ($config_types as $type_id => $config_type): ?>
+            <? if ($configs[$type_id]) : ?>
+                <article id="<?= $type_id ?>" <? if (Request::option('open_type') === $type_id) echo 'class="open"'; ?>>
+                    <header>
+                        <h1>
+                            <a href="<?= URLHelper::getLink('?#' . $type_id)?>">
+                                <?= htmlReady($config_type['name']) ?>
+                                (<?= count($configs[$type_id]) ?>)
+                            </a>
+                        </h1>
+                    </header>
+                    <section>
+                        <table class="default sortable-table">
+                            <?= $this->render_partial('institute/extern/_table-header.php') ?>
+                            <? foreach ($configs[$type_id] as $config) : ?>
+                                <?= $this->render_partial('institute/extern/_table-row.php', ['config' => $config]) ?>
+                            <? endforeach ?>
+                        </table>
+                    </section>
+                </article>
+            <? endif ?>
+        <? endforeach ?>
+    </section>
+</form>
+<?php endif ?>
diff --git a/app/views/institute/extern/info.php b/app/views/institute/extern/info.php
new file mode 100644
index 00000000000..c33af4ff358
--- /dev/null
+++ b/app/views/institute/extern/info.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * @var ExternPageConfig $page
+ * @var DataField[] $datafields
+ * @var string $author
+ * @var string $editor
+ */
+?>
+
+<section class="contentbox">
+    <header>
+        <h1><?= _('Allgemeine Informationen') ?></h1>
+    </header>
+    <section>
+        <dl>
+            <dt><?= _('Modultyp') ?></dt>
+            <dd><?= htmlReady($page->type) ?></dd>
+            <dt><?= _('Name der Konfiguration') ?></dt>
+            <dd><?= htmlReady($page->name) ?></dd>
+            <dt><?= _('Erstellt am') ?></dt>
+            <dd><?= date('d.m.Y H:m ', $page->mkdate) . sprintf(_('durch %s'), $author) ?></dd>
+            <dt><?= _('Bearbeitet am') ?></dt>
+            <dd><?= date('d.m.Y H:m ', $page->chdate) . sprintf(_('durch %s'), $editor) ?></dd>
+            <dt><?= _('Beschreibung') ?></dt>
+            <dd><?= htmlReady($page->description) ?></dd>
+            <dt><?= _('Zur Hilfeseite') ?></dt>
+            <dd><a class="link-extern" href="<?= htmlReady(format_help_url(PageLayout::getHelpKeyword())) ?>">
+                    <?= sprintf(_('Hilfe zur Konfiguration des Moduls "%s".'), htmlReady($page->type)) ?>
+                </a>
+            </dd>
+        </dl>
+    </section>
+</section>
+<section class="contentbox">
+    <header>
+        <h1><?= _('Informationen zur Verlinkung') ?></h1>
+    </header>
+    <section>
+        <dl>
+            <dt><?= _('Direkter Link') ?></dt>
+            <dd>
+                <blockquote>
+                    <? $link = htmlReady(URLHelper::getLink('dispatch.php/extern/index/' . $page->id, null,true)) ?>
+                    <a href="<?= $link ?>" target="_blank"><?= $link ?></a>
+                </blockquote>
+                <span style="font-size: smaller;">
+                    <?= _('Diese Adresse können Sie in einen Link auf Ihrer Website integrieren, um auf die Ausgabe des Moduls zu verweisen.') ?>
+                </span>
+            </dd>
+            <dt><?= _('Mögliche URL-Parameter') ?></dt>
+            <dd><?= htmlReady(implode(', ', $page->getAllowedRequestParams(true))) ?></dd>
+        </dl>
+    </section>
+</section>
+<? if (count($datafields)) : ?>
+<? $classes = DataField::getDataClass() ?>
+    <section class="contentbox">
+        <header>
+            <h1><?= _('Datenfelder') ?></h1>
+        </header>
+        <section>
+            <dl>
+                <? foreach ($datafields as $class_name => $datafield_class) : ?>
+                    <? foreach ($datafield_class as $datafield) : ?>
+                        <dt><?= htmlReady($classes[$class_name] . ': ' . $datafield->name) ?></dt>
+                        <dd>
+                            <?= 'DATAFIELD_' . $datafield->id ?>
+                            <span style="font-size: smaller;"><?= htmlReady($datafield->description) ?></span>
+                        </dd>
+                    <? endforeach ?>
+                <? endforeach ?>
+            </dl>
+            <p><?= _('Hinweis: Die gelisteten Datenfelder sind eventuell nicht für alle Objekte eines Typs verfügbar.') ?></p>
+        </section>
+    </section>
+<? endif ?>
diff --git a/app/views/institute/extern/new.php b/app/views/institute/extern/new.php
new file mode 100644
index 00000000000..34736a9bb0b
--- /dev/null
+++ b/app/views/institute/extern/new.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ * @var ExternController $controller
+ * @var array $config_types
+ */
+?>
+
+<ul class="content-items" style="padding-top: 10px;">
+    <? foreach ($config_types as $type_id => $config_type) : ?>
+        <li class="content-item">
+            <a class="content-item-link" href="<?= $controller->edit($type_id) ?>">
+                <div class="content-item-img-wrapper">
+                    <?= Icon::create($config_type['icon'])->asImg(64) ?>
+                </div>
+                <div class="content-item-text">
+                    <p class="content-item-title">
+                        <?= htmlReady($config_type['name']) ?>
+                    </p>
+                    <p class="content-item-description">
+                        <?= htmlReady($config_type['description']) ?>
+                    </p>
+                </div>
+            </a>
+        </li>
+    <? endforeach ?>
+</ul>
diff --git a/app/views/institute/extern/upload.php b/app/views/institute/extern/upload.php
new file mode 100644
index 00000000000..92b289419b4
--- /dev/null
+++ b/app/views/institute/extern/upload.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * @var ExternController $controller
+ * @var string $config_name
+ */
+?>
+
+<form class="default" data-dialog="size=auto" method="post"
+      enctype="multipart/form-data"
+      action="<?= $controller->import()?>">
+    <?= CSRFProtection::tokenTag() ?>
+    <fieldset>
+        <legend><?= _('Konfigurationsdatei importieren') ?></legend>
+        <label>
+            <?= _('Name der Konfiguration') ?>
+            <div style="font-size: smaller;">
+                (<?= _('Ohne Angabe wird der Name aus den importierten Daten genommen.') ?>)
+            </div>
+            <input type="text" name="config_name" value="<?= htmlReady($config_name) ?>">
+        </label>
+        <label>
+            <?= _('Konfigurationsdatei') ?>
+            <input type="file" name="config_file" required="required">
+        </label>
+    </fieldset>
+    <div data-dialog-button>
+        <?= \Studip\Button::create(_('Importieren'), 'import') ?>
+    </div>
+</form>
diff --git a/db/migrations/5.5.12_new_external_pages.php b/db/migrations/5.5.12_new_external_pages.php
new file mode 100644
index 00000000000..dec973f5759
--- /dev/null
+++ b/db/migrations/5.5.12_new_external_pages.php
@@ -0,0 +1,578 @@
+<?php
+
+class NewExternalPages extends Migration
+{
+    public function description()
+    {
+        return 'Adds a new table for the configuration and creates a new config entry for error message texts on external pages.';
+    }
+
+    public function up()
+    {
+        $db = \DBManager::get();
+
+        $db->exec("CREATE TABLE `extern_pages_configs` (
+            `config_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+            `range_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+            `type` varchar(50) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+            `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
+            `description` tinytext COLLATE utf8mb4_unicode_ci NOT NULL,
+            `conf` text COLLATE utf8mb4_unicode_ci NOT NULL,
+            `template` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL,
+            `author_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+            `editor_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
+            `mkdate` int(11) UNSIGNED NOT NULL DEFAULT '0',
+            `chdate` int(11) UNSIGNED NOT NULL DEFAULT '0',
+            PRIMARY KEY (`config_id`),
+            KEY `range_id` (`range_id`),
+            KEY `type` (`type`))
+        ");
+
+        $this->migrate_configurations();
+
+        $description = 'Allgemeine Fehlermeldung,die auf der Webseite ausgegeben wird, auf der der Inhalt der '
+            . 'externe Seite angezeigt werden soll. Diese Meldung wird ausgegeben, '
+            . 'wenn z.B. das Template fehlerhaft ist.';
+        $message = 'Ein Fehler ist aufgetreten. Die Inhalte können nicht angezeigt werden.';
+        DBManager::get()->exec(
+            "INSERT IGNORE INTO `config`
+            (`field`, `value`, `type`, `range`,
+            `section`,
+            `mkdate`, `chdate`,
+            `description`)
+            VALUES
+            ('EXTERN_PAGES_ERROR_MESSAGE', '{$message}', 'string', 'global',
+            'external_pages', UNIX_TIMESTAMP(), UNIX_TIMESTAMP(),
+            '{$description}')"
+        );
+
+        $db->exec(
+            "DELETE FROM `config` WHERE `field` = 'EXTERN_ALLOW_ACCESS_WITHOUT_CONFIG'"
+        );
+        $db->exec(
+            "DELETE FROM `config` WHERE `field` = 'EXTERN_SRI_ENABLE'"
+        );
+        $db->exec(
+            "DELETE FROM `config` WHERE `field` = 'EXTERN_SRI_ENABLE_BY_ROOT'"
+        );
+        $db->exec("DROP TABLE `extern_config`");
+
+    }
+
+    public function down()
+    {
+        $db = \DBManager::get();
+
+        $db->exec(
+            "DELETE FROM `config` WHERE `config_id` = 'EXTERN_PAGES_ERROR_MESSAGE'"
+        );
+        $db->exec('DROP TABLE IF EXISTS `extern_pages_configs`');
+
+        $db->exec("CREATE TABLE `extern_config` (
+            `config_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
+            `range_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL DEFAULT '',
+            `config_type` int(4) NOT NULL DEFAULT '0',
+            `name` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '',
+            `is_standard` tinyint(1) UNSIGNED NOT NULL DEFAULT '0',
+            `config` mediumtext COLLATE utf8mb4_unicode_ci NOT NULL,
+            `mkdate` int(11) UNSIGNED NOT NULL DEFAULT '0',
+            `chdate` int(11) UNSIGNED NOT NULL DEFAULT '0',
+            PRIMARY KEY (`config_id`,`range_id`))
+        ");
+
+        $configs = [
+            'EXTERN_ALLOW_ACCESS_WITHOUT_CONFIG' =>
+                'Free access to external pages (without the need of a configuration), independent of SRI settings above',
+            'EXTERN_SRI_ENABLE' =>
+                'Allow the usage of SRI-interface (Stud.IP Remote Include)',
+            'EXTERN_SRI_ENABLE_BY_ROOT' =>
+                'Only root allows the usage of SRI-interface for specific institutes'
+        ];
+        foreach ($configs as $field => $description) {
+            $db->exec(
+                "INSERT IGNORE INTO `config`
+            (`field`, `value`, `type`, `range`,
+            `section`,
+            `mkdate`, `chdate`,
+            `description`)
+            VALUES
+            ({$field}, '0', 'boolean', 'global',
+            'global', UNIX_TIMESTAMP(), UNIX_TIMESTAMP(),
+            '{$description}')"
+            );
+        }
+
+    }
+
+    private function migrate_configurations()
+    {
+        $skip_text = 'Die Konfiguration (ID: %s, TYP: %s, NAME: %s) kann nicht migriert werden. ';
+        $db = DBManager::get();
+        $db->fetchAll('SELECT * FROM `extern_config`', [],
+            function ($config) use ($skip_text)
+            {
+                // skip non template based configs
+                if ($config['config_type'] < 9) {
+                    $this->announce($skip_text . 'Die Seite ist nicht Template-basiert.',
+                        $config['config_id'], $config['config_type'], $config['name']);
+                    return;
+                }
+                $new_conf = new ExternPageConfig($config['config_id']);
+                $new_conf->range_id = $config['range_id'];
+                $new_conf->name = $config['name'];
+                $new_conf->mkdate = $config['mkdate'];
+                $new_conf->chdate = time();
+                $old_data = json_decode($config['config']);
+                $new_data = [
+                    'language' => 'de_DE',
+                    'escaping' => 'htmlReady',
+                    // this is used to show a hint that this configuration has still to be fixed after the migration
+                    'not_fixed_after_migration' => 1
+                ];
+                if (isset($old_data->Main->language) && strlen((string) $old_data->Main->language) < 5) {
+                    $new_data['language'] = $old_data->Main->language;
+                }
+                switch ($config['config_type']) {
+                    // Persons
+                    case 9:
+                        $new_conf->type = 'Persons';
+                        // The new sort fields are different, so match as good as possible.
+                        // Use "nachname" as default.
+                        if (isset($old_data->Main->sort)) {
+                            asort($old_data->Main->sort, SORT_NUMERIC);
+                            if (key($old_data->Main->sort) === '3') {
+                                $new_data['sort'] = 'email';
+                            } else {
+                                $new_data['sort'] = 'nachname';
+                            }
+                        }
+                        if (isset($old_data->Main->grouping) && $old_data->Main->grouping === '1') {
+                            $new_data['grouping'] = true;
+                        }
+                        $new_data['groupsvisible'] = [];
+                        if (isset($old_data->Main->groupsvisible)) {
+                            foreach ($old_data->Main->groupsvisible as $groupsvisible) {
+                                $new_data['groupsvisible'][$groupsvisible] = 1;
+                            }
+                        }
+                        $new_data['groupsalias'] = [];
+                        if (isset($old_data->Main->groupsalias)) {
+                            $new_data['groupsalias'] = $old_data->Main->groupsalias;
+                        }
+                        $replace = [
+                            'PERSONS' => 'GROUPS',
+                            'PERSON'  => 'PERSONS',
+                            'GROUP'   => ''
+                        ];
+                        $template = $this->replaceSubparts(
+                            $replace,
+                            $this->replaceDatafieldMarkers($old_data->TemplateGeneric)
+                        );
+                        $replace = [
+                            'IMAGE-URL-NORMAL' => 'IMAGE_URL_NORMAL',
+                            'IMAGE-URL-MEDIUM' => 'IMAGE_URL_MEDIUM',
+                            'IMAGE-URL-SMALL'  => 'IMAGE_URL_SMALL',
+                            'HOMEPAGE-HREF'    => 'HOMEPAGE_URL'
+                        ];
+                        $template = $this->replaceMarkers($replace, $template);
+                        $replace = [
+                            'PERSONS' => ''
+                        ];
+                        $new_conf->template = $this->replaceAllOldMarkers(
+                            $this->replaceNoMarkerSubparts($replace, $template)
+                        );
+                        break;
+                    // Download
+                    case 10:
+                        $new_conf->type = 'Download';
+                        $sort_fields = [
+                            'filetype',
+                            'name',
+                            '',
+                            'mkdate',
+                            'size',
+                            'author'
+                        ];
+                        if (isset($old_data->Main->sort)) {
+                            arsort($old_data->Main->sort, SORT_NUMERIC);
+                            $new_data['sort'] = $sort_fields[key($old_data->Main->sort)];
+                        }
+                        $new_data['subfolders'] = 1;
+                        $template = $this->replaceDatafieldMarkers($old_data->TemplateGeneric);
+                        $replace = [
+                            'FILE_NAME'        => 'NAME',
+                            'FILE_FILE-NAME'   => 'NAME',
+                            'FILE_SIZE'        => 'SIZE',
+                            'FILE_DESCRIPTION' => 'DESCRIPTION',
+                            'FILE_UPLOAD-DATE' => 'UPLOAD_DATE',
+                            'FILE_HREF'        => 'URL',
+                            'FILE_ICON-HREF'   => 'ICON_URL'
+                        ];
+                        $template = $this->replaceMarkers($replace, $template);
+                        $replace = [
+                            'DOWNLOAD' => '',
+                            'FILE'     => '',
+                            'FILES'    => 'FILES'
+                        ];
+                        $template = $this->replaceSubparts($replace, $template);
+                        $replace = [
+                            'FILES' => ''
+                        ];
+                        $new_conf->template = $this->replaceAllOldMarkers(
+                            $this->replaceNoMarkerSubparts($replace, $template)
+                        );
+                        break;
+                    // news
+                    case 11:
+                        $this->announce($skip_text .
+                            'Die Ausgabe von Ankündigungen an Einrichtungen wird nicht mehr unterstützt.',
+                            $config['config_id'], $config['config_type'], $config['name']);
+                        return;
+                    // courses
+                    case 12:
+                        $new_conf->type = 'Courses';
+                        $new_data['groupby'] = $old_data->Main->grouping;
+                        $new_data['startsem'] = $this->convertSemesters($old_data->Main->semstart);
+                        $new_data['semcount'] = $old_data->Main->semrange;
+                        $new_data['semswitch'] = $old_data->Main->semswitch;
+                        $new_data['participating'] = $old_data->Main->allseminars;
+                        $new_data['semtypes'] = (array) $old_data->ReplaceTextSemType->visibility;
+                        $new_data['studyareas'] = (array) $old_data->SelectSubjectAreas->subjectareasselected;
+                        $replace = [
+                            'START_SEMESTER'                 => 'START_SEMESTER_NAME',
+                            'LECTURES-SUBSTITUTE-GROUPED-BY' => 'GROUPED_BY',
+                            'GROUP'                          => 'NAME',
+                            'SEMTYPE'                        => 'SEMTYPE_NAME',
+                            'UNAME'                          => 'USERNAME'
+                        ];
+                        $template = $this->replaceMarkers(
+                            $replace,
+                            $this->replaceDatafieldMarkers($old_data->TemplateGeneric)
+                        );
+                        $replace = [
+                            'LECTURES'  => '',
+                            'GROUP'     => 'GROUPED_COURSES',
+                            'LECTURE'   => 'COURSES',
+                            'LECTURERS' => 'LECTURERS'
+                        ];
+                        $template = $this->replaceSubparts($replace, $template);
+                        $replace = [
+                            'LECTURES' => 'COURSES'
+                        ];
+                        $new_conf->template = $this->replaceAllOldMarkers(
+                            $this->replaceNoMarkerSubparts($replace, $template)
+                        );
+                        break;
+                    // course details
+                    case 13:
+                        $new_conf->type = 'CourseDetails';
+                        $new_data['rangepathlevel'] = $old_data->Main->rangepathlevel;
+                        // combine templates
+                        $pattern = [
+                            '/(\{%\s+|###)NEWS(###|\s+%})/',
+                            '/(\{%\s+|###)STUDIP-DATA(###|\s+%})/'
+                        ];
+                        $replacement = [
+                            $old_data->TemplateNews->template,
+                            $old_data->TemplateStudipData->template
+                        ];
+                        $template = preg_replace(
+                            $pattern,
+                            $replacement,
+                            $this->replaceDatafieldMarkers($old_data->TemplateLectureData)
+                        );
+                        $replace = [
+                            'MISC'              => 'MISCELLANEOUS',
+                            'LEISTUNGSNACHWEIS' => 'CERTIFICATE',
+                            'UNAME'             => 'USERNAME',
+                            'TUTOR_FULLNAME'    => 'FULLNAME',
+                            'TUTOR_LASTNAME'    => 'LASTNAME',
+                            'TUTOR_FIRSTNAME'   => 'FIRSTNAME',
+                            'TUTOR_TITLEFRONT'  => 'TITLEFRONT',
+                            'TUTOR_TITLEREAR'   => 'TITLEREAR',
+                            'TUTOR_UNAME'       => 'USERNAME',
+                            'NEWS_TOPIC'        => 'TOPIC',
+                            'NEWS_BODY'         => 'BODY',
+                            'NEWS_DATE'         => 'DATE',
+                            'PRELIM-DISCUSSION' => 'PRELIM_DISCUSSION',
+                            'FIRST-MEETING'     => 'FIRST_MEETING',
+                            'HOME-INST-NAME'    => 'HOME_INST_NAME',
+                            'COUNT-USER'        => 'COUNT_USER',
+                            'INVOLVED-INSTITUTE_NAME' => 'NAME'
+                        ];
+                        $template = $this->replaceMarkers($replace, $template);
+                        $replace = [
+                            'LECTUREDETAILS' => '',
+                            'LECTURER'       => '',
+                            'LECTURERS'      => 'LECTURERS',
+                            'TUTOR'          => '',
+                            'TUTORS'         => 'TUTORS',
+                            'NEWS'           => '',
+                            'ALL-NEWS'       => 'NEWS',
+                            'SINGLE-NEWS'    => '',
+                            'STUDIP-DATA'    => '',
+                            'RANGE-PATHES'   => 'RANGE_PATHS',
+                            'RANGE-PATH'     => '',
+                            'MODULES'        => 'MODULES',
+                            'MODULE'         => '',
+                            'INVOLVED-INSTITUTES' => 'INVOLVED_INSTITUTES',
+                            'INVOLVED-INSTITUTE'  => '',
+                        ];
+                        $template = $this->replaceSubparts($replace, $template);
+                        $replace = [
+                            'NEWS' => ''
+                        ];
+                        $new_conf->template = $this->replaceAllOldMarkers(
+                            $this->replaceNoMarkerSubparts($replace, $template)
+                        );
+                        break;
+                    // person details
+                    case 14:
+                        $new_conf->type = 'PersonDetails';
+                        $new_data['defaultaddr'] = $old_data->Main->defaultaddr;
+                        $new_data['startsem'] = $this->convertSemesters($old_data->PersondetailsLectures->semstart);
+                        $new_data['semcount'] = $old_data->PersondetailsLectures->semrange;
+                        $new_data['semswitch'] = $old_data->PersondetailsLectures->semswitch;
+                        $new_data['semclass'] = $old_data->PersondetailsLectures->semclass;
+                        // combine templates
+                        $pattern = [
+                            '/(\{%\s+|###)LECTURES(###|\s+%})/',
+                            '/(\{%\s+|###)NEWS(###|\s+%})/',
+                            '/(\{%\s+|###)APPOINTMENTS(###|\s+%})/',
+                            '/(\{%\s+|###)OWNCATEGORIES(###|\s+%})/'
+                        ];
+                        $replacement = [
+                            $old_data->TemplateLectures->template,
+                            $old_data->TemplateNews->template,
+                            $old_data->TemplateAppointments->template,
+                            $old_data->TemplateOwnCategories->template
+                        ];
+                        $template = preg_replace(
+                            $pattern,
+                            $replacement,
+                            $this->replaceDatafieldMarkers($old_data->TemplateMain)
+                        );
+                        $replace = [
+                            'IMAGE-HREF'               => 'IMAGE_URL_NORMAL',
+                            'INST-NAME'                => 'NAME',
+                            'SINGLE-INST-NAME'         => 'NAME',
+                            'SINGLE-INST-STREET'       => 'STREET',
+                            'SINGLE-INST-ZIPCODE'      => 'ZIPCODE',
+                            'SINGLE-INST-EMAIL'        => 'EMAIL',
+                            'SINGLE-INST-ROOM'         => 'MEMBER_ROOM',
+                            'SINGLE-INST-PHONE'        => 'MEMBER_PHONE',
+                            'SINGLE-INST-FAX'          => 'MEMBER_FAX',
+                            'SINGLE-INST-HREF'         => 'HOMEPAGE',
+                            'SINGLE-INST-OFFICE-HOURS' => 'MEMBER_OFFICEHOURS',
+                            'NEWS_TOPIC'               => 'TOPIC',
+                            'NEWS_BODY'                => 'BODY',
+                            'NEWS_DATE'                => 'DATE',
+                            'LIST-START'               => 'APPOINTMENTS_START',
+                            'LIST-END'                 => 'APPOINTMENTS_END',
+                            'REPETITION'               => 'RECURRENCE',
+                            'BEGIN'                    => 'START',
+                            'OWNCATEGORY_TITLE'        => 'TITLE',
+                            'OWNCATEGORY_CONTENT'      => 'CONTENT',
+                            'OFFICE-HOURS'             => 'OFFICEHOURS',
+                            'HOMEPAGE-HREF'            => 'HOMEPAGE_URL'
+                        ];
+                        $template = $this->replaceMarkers($replace, $template);
+                        $replace = [
+                            'PERSONDETAILS'      => '',
+                            'SINGLE-INST'        => '',
+                            'SEMESTER'           => '',
+                            'NEWS'               => '',
+                            'SINGLE-NEWS'        => '',
+                            'APPOINTMENTS'       => '',
+                            'SINGLE-APPOINTMENT' => '',
+                            'ALL-INST'           => 'INSTITUTES',
+                            'LECTURES'           => 'SEMESTERS',
+                            'LECTURE'            => 'LECTURES',
+                            'ALL-NEWS'           => 'NEWS',
+                            'ALL-APPOINTMENTS'   => 'APPOINTMENTS',
+                            'OWNCATEGORIES'      => 'OWNCATEGORIES',
+                            'OWNCATEGORY'        => ''
+                        ];
+                        $template = $this->replaceSubparts($replace, $template);
+                        $replace = [
+                            'NEWS'         => '',
+                            'APPOINTMENTS' => ''
+                        ];
+                        $new_conf->template = $this->replaceAllOldMarkers(
+                            $this->replaceNoMarkerSubparts($replace, $template)
+                        );
+                        break;
+                    // sembrowser
+                    case 15:
+                        $this->announce($skip_text .
+                            'Der Seminarbrowser wird nicht mehr unterstützt.',
+                            $config['config_id'], $config['config_type'], $config['name']);
+                        return;
+                    // persbrowser
+                    case 16:
+                        $new_conf->type = 'PersBrowse';
+                        $new_data['instperms'] = $old_data->Main->instperms;
+                        $new_data['onlylecturers'] = $old_data->Main->onlylecturers;
+                        $new_data['institutes'] = $old_data->SelectInstitutes->institutesselected;
+                        // combine templates
+                        $pattern = [
+                            '/(\{%\s+|###)LISTCHARACTERS(###|\s+%})/',
+                            '/(\{%\s+|###)LISTINSTITUTES(###|\s+%})/',
+                            '/(\{%\s+|###)LISTPERSONS(###|\s+%})/'
+                        ];
+                        $replacement = [
+                            $old_data->TemplateListCharacters->template,
+                            $old_data->TemplateListInstitutes->template,
+                            $old_data->TemplateListPersons->template
+                        ];
+                        $template = preg_replace(
+                            $pattern,
+                            $replacement,
+                            $old_data->TemplateMain->template
+                        );
+                        $new_data['language'] = $old_data->Main->language;
+                        $replace = [
+                            'CHARACTER_COUNT_USER' => 'CHARACTER_COUNT',
+                            'INSTITUTE_NAME'       => 'NAME',
+                            'INSTITUTE_COUNT_USER' => 'COUNT_USERS'
+                        ];
+                        $template = $this->replaceMarkers($replace, $template);
+
+                        $replace = [
+                            'PERS_BROWSER'    => '',
+                            'CHARACTER'       => '',
+                            'LIST_CHARACTERS' => 'CHARACTERS',
+                            'INSTITUTE'       => '',
+                            'LIST_INSTITUTES' => 'INSTITUTES',
+                            'LIST_PERSONS'    => '',
+                            'PERSON'          => '',
+                            'PERSONS'         => 'PERSONS'
+                        ];
+                        $template = $this->replaceSubparts($replace, $template);
+
+                        $replace = [
+                            'PERSONS' => ''
+                        ];
+                        $new_conf->template = $this->replaceAllOldMarkers(
+                            $this->replaceNoMarkerSubparts($replace, $template)
+                        );
+                }
+                $new_conf->conf = json_encode($new_data);
+                $new_conf->store();
+            });
+    }
+
+    private function replaceMarkers(array $marker_replacements, $template)
+    {
+        foreach ($marker_replacements as $old_marker => $new_marker) {
+            $patterns = [
+                '/###' . $old_marker . '###/',
+                '/\{%(\s.*)' . $old_marker . '(.*\s)%}/'
+            ];
+            $replacements = [
+                '###' . $new_marker . '###',
+                '{%${1}' . $new_marker . '${2}%}'
+            ];
+            $template = preg_replace($patterns, $replacements, $template);
+        };
+        return $template;
+    }
+
+    private function replaceSubparts(array $marker_replacements, $template)
+    {
+        foreach ($marker_replacements as $old_marker => $new_marker) {
+            $patterns = [
+                '/<!--\s+BEGIN\s+' . $old_marker . '\s+-->/',
+                '/\{%\s+foreach.+' . $old_marker . '(\s.+)%}/',
+                '/<!--\s+END\s+' . $old_marker . '\s+-->/'
+            ];
+            if ($new_marker === '') {
+                $replacements = ['', '', ''];
+            } else {
+                $replacements = [
+                    '{% foreach ' . $new_marker . ' %}',
+                    '{% foreach ' . $new_marker . '${1}%}',
+                    '{% endforeach %}'
+                ];
+            }
+            $template = preg_replace($patterns, $replacements, $template);
+        }
+        return $template;
+
+    }
+
+    private function replaceAllOldMarkers($template)
+    {
+        return preg_replace(
+            '/###(([A-Z0-9_-]+)|(DATAFIELD_[0-9a-f]+))###/',
+            '{% ${1} %}',
+            $template);
+    }
+
+    private function replaceNoMarkerSubparts(array $markers, $template)
+    {
+        foreach ($markers as $marker => $replace) {
+            $patterns = [
+                '/<!--\s+BEGIN\s+NO-' . $marker . '\s+-->/',
+                '/<!--\s+END\s+NO-' . $marker . '\s+-->/'
+            ];
+            $new_marker = $replace !== '' ? $replace : $marker;
+            $replacements = [
+                '{% if count(' . $new_marker . ') == 0 %}',
+                '{% endif %}'
+            ];
+            $template = preg_replace($patterns, $replacements, $template);
+        }
+        return $template;
+    }
+
+    /**
+     * Replaces all old datafield markers with new ones.
+     *
+     * @param object $template Array with template and datafield_ids.
+     * @return array|string|string[]
+     */
+    private function replaceDatafieldMarkers($template)
+    {
+        if (isset($template->genericdatafields)) {
+            $search = [];
+            $replace = [];
+            $key = 1;
+            foreach ($template->genericdatafields as $df_id) {
+                $search[]  = 'DATAFIELD_' . $key++;
+                $replace[] = 'DATAFIELD_' . $df_id;
+            }
+            return str_replace($search, $replace, $template->template);
+        }
+        return $template->template;
+    }
+
+    private function convertSemesters($old_semester_config)
+    {
+        $semester_mapping = [
+            'previous' => 'previous',
+            'current'  => 'current',
+            'next'     => 'next'
+        ];
+        $key = 1;
+        foreach (Semester::findAllVisible(false) as $sem) {
+            $semester_mapping[$key++] = $sem['semester_id'];
+        }
+        return $semester_mapping[$old_semester_config] ?? '';
+    }
+
+    private function insertConfig($field, $message, $description)
+    {
+        DBManager::get()->exec(
+            "INSERT IGNORE INTO `config`
+            (`field`, `value`, `type`, `range`,
+            `section`,
+            `mkdate`, `chdate`,
+            `description`)
+            VALUES
+            ({$field}, '{$message}', 'string', 'global',
+            'external_pages', UNIX_TIMESTAMP(), UNIX_TIMESTAMP(),
+            '{$description}')"
+        );
+    }
+}
diff --git a/lib/bootstrap-autoload.php b/lib/bootstrap-autoload.php
index fa6ed7b7a1a..d45ffcdb475 100644
--- a/lib/bootstrap-autoload.php
+++ b/lib/bootstrap-autoload.php
@@ -49,7 +49,7 @@ StudipAutoloader::addAutoloadPath('lib/activities', 'Studip\\Activity');
 StudipAutoloader::addAutoloadPath('lib/evaluation/classes');
 StudipAutoloader::addAutoloadPath('lib/evaluation/classes/db');
 
-StudipAutoloader::addAutoloadPath('lib/extern/lib');
+StudipAutoloader::addAutoloadPath('lib/extern');
 StudipAutoloader::addAutoloadPath('lib/calendar/lib');
 StudipAutoloader::addAutoloadPath('lib/elearning');
 StudipAutoloader::addAutoloadPath('lib/ilias_interface');
diff --git a/lib/bootstrap.php b/lib/bootstrap.php
index 5690a60bd3f..418d6df1b83 100644
--- a/lib/bootstrap.php
+++ b/lib/bootstrap.php
@@ -209,11 +209,6 @@ class DB_Seminar extends DB_Sql
     }
 }
 
-if (Config::get()->EXTERN_ENABLE) {
-    require_once $GLOBALS['STUDIP_BASE_PATH'] . '/lib/extern/extern_config.inc.php';
-    require_once $GLOBALS['STUDIP_BASE_PATH'] . '/lib/extern/lib/extern_functions.inc.php';
-}
-
 if (Config::get()->CALENDAR_ENABLE) {
     require_once 'lib/calendar_functions.inc.php';
 }
diff --git a/lib/extern/ExternPage.php b/lib/extern/ExternPage.php
new file mode 100644
index 00000000000..a70e3f39d0f
--- /dev/null
+++ b/lib/extern/ExternPage.php
@@ -0,0 +1,491 @@
+<?php
+/**
+ * ExternPage.php Abstract class as blueprint for all extern page types.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @since       5.4
+ */
+
+require_once 'vendor/exTpl/Template.php';
+
+abstract class ExternPage
+{
+    /**
+     * @var ExternPageConfig Storage for page configuration.
+     */
+    public $page_config;
+
+    /**
+     * Constructor initialized with page configuration.
+     *
+     * @param ExternPageConfig $config
+     */
+    public function __construct(ExternPageConfig $config)
+    {
+        $this->page_config = $config;
+    }
+
+    /**
+     * Returns an associative array with field names as keys and the spoken name
+     * of fields as value. The output can be sorted by these values.
+     *
+     * @return array Array of field names as keys and spoken names as values.
+     */
+    abstract public function getSortFields(): array;
+
+    /**
+     * Returns an array with all content ready to feed it to the template.
+     *
+     * @return array Array with content of all markers used in template.
+     */
+    abstract public function getMarkersContents(): array;
+
+    /**
+     * Returns all markers with content from datafields related with the given object.
+     * The name of the marker begins with DATFIELD_ followed by the id of the datafield.
+     *
+     * @param SimpleORMap $sorm Sorm-object with datafields.
+     * @return array Markers for datafields.
+     */
+    public function getDatafieldMarkers(SimpleORMap $sorm): array
+    {
+        $datafield_markers = [];
+        foreach ($sorm->datafields as $datafield_entry) {
+            if ($datafield_entry->datafield->view_perms !== 'root' || $this->range_id === 'studip') {
+                $datafield_markers['DATAFIELD_' . $datafield_entry->datafield_id] = $datafield_entry->content;
+            }
+        }
+        return $datafield_markers;
+    }
+
+    /**
+     * Returns an array or csv list of all parameter names and types used in
+     * the form to configure this external page. Used by Request::extract().
+     *
+     * @see Request::extract()
+     * @param false $as_array True to get config fields as array.
+     * @return array|string An array or csv list of all field names and types.
+     */
+    abstract public function getConfigFields(bool $as_array = false);
+
+    /**
+     * Magic method to get a value by given name from configuration.
+     *
+     * @param string $field The name of the field.
+     * @return mixed The value of the field.
+     */
+    public function __get(string $field)
+    {
+        return $this->getValue($field);
+    }
+
+    /**
+     * Magic method to set a field in the configuration by given value.
+     *
+     * @param string $field The field name.
+     * @param mixed $value The value.
+     */
+    public function __set(string $field, $value)
+    {
+        $this->setValue($field, $value);
+    }
+
+    /**
+     * Factory to get ExternPage object from config.
+     *
+     * @param ExternPageConfig $config The page config.
+     * @return ExternPage The module depending on config.
+     * @throw InvalidArgumentException
+     */
+    public static function get(ExternPageConfig $config): ExternPage
+    {
+        if (!$config) {
+            throw new InvalidArgumentException('No configuration found.');
+        }
+        $page_name = 'ExternPage' . $config->type;
+        if (!class_exists($page_name)) {
+            // lookup plugins
+            $plugins = PluginEngine::getPlugins('ExternPagePlugin');
+            foreach ($plugins as $plugin) {
+                if ($config->type === $plugin->getExternPageName()) {
+                    return $plugin->getExternPage($config);
+                }
+            }
+            throw new InvalidArgumentException('Unknown class ' . $page_name);
+        }
+        return new $page_name($config);
+    }
+
+    /**
+     * Convert string with allowed arguments to array with name as key and
+     * type as value.
+     *
+     * @param $args string String with allowed arguments.
+     * @return array Associative array with arguments.
+     */
+    protected static function argsToArray(string $args): array
+    {
+        $extract = [];
+        $return = [];
+        foreach (explode(',', $args) as $one) {
+            $extract[] = array_values(array_filter(array_map('trim', explode(' ', $one))));
+        }
+        foreach ($extract as $one) {
+            $return[$one[0]] = $one[1];
+        }
+        return $return;
+    }
+
+    /**
+     * Returns the processed template with all data from this external page.
+     *
+     * @return string The processed template with content inserted.
+     */
+    public function toString(): string
+    {
+        if (!$language = $this->language) {
+            $language = "de_DE";
+        }
+        init_i18n($language);
+        $template = preg_replace(
+            ['/###([\w-]+)###/', '/<!--\s+BEGIN\s+([\w-]+)\s+-->/', '/<!--\s+END\s+[\w-]+\s+-->/'],
+            ['{% $1 %}', '{% foreach $1 %}', '{% endforeach %}'], $this->template);
+        exTpl\Template::setTagMarkers('{%', '%}');
+        try {
+            $template = new exTpl\Template($template);
+            $escaping_types =
+                [
+                    'htmlReady',
+                    'xml',
+                    'json'
+                ];
+            if (in_array($this->escaping, $escaping_types)) {
+                $template->autoescape($this->escaping);
+            }
+            // php functions used in templates
+            $functions = [
+                'date'    => function($a, $b) { return date($a, $b); },
+                'substr'  => function($a, $b, $c) { return mb_substr($a, $b, $c); },
+                'split'   => function($a, $b) { return mb_split($a, $b); },
+                'implode' => function($a, $b) { return implode($a, $b); },
+                'count'   => function($a) { return count((array) $a); }
+            ];
+            $out = $template->render((array) $this->getMarkersContents() + $functions);
+        } catch (exTpl\TemplateParserException $ex) {
+            $out = Config::get()->EXTERN_PAGES_ERROR_MESSAGE . '<br>' . $ex->getMessage();
+        }
+
+        return $out;
+    }
+
+    /**
+     * Get a value from the configuration of this external page.
+     *
+     * @param string $field The name of the field.
+     * @return mixed The value of the field.
+     */
+    public function getValue(string $field)
+    {
+        $field = $field === 'id' ? 'config_id' : $field;
+        if (isset($this->page_config->$field)) {
+            return $this->page_config->$field;
+        }
+        if ($this->page_config->conf[$field] instanceof JSONArrayObject) {
+            return $this->page_config->conf[$field]->getArrayCopy();
+        }
+        return $this->page_config->conf[$field];
+    }
+
+    /**
+     * Sets a value in the config storage by given field name.
+     *
+     * @param string $field The name of the field.
+     * @param mixed $value The value to set.
+     */
+    public function setValue(string $field, $value)
+    {
+        if ($this->page_config->isField($field)) {
+            $this->page_config->setValue($field, $value);
+        } else {
+            $this->page_config->conf[$field] = $value;
+        }
+    }
+
+    /**
+     * Returns a list (as string or array) with all names of config fields
+     * overridable by request parameters.
+     *
+     * @param false $as_array True to get request params as array.
+     * @return string|string[]|void All allowed request params as array or string.
+     */
+    abstract public function getAllowedRequestParams(bool $as_array = false);
+
+    /**
+     * Extract the allowed request params and overwrites the
+     * values from configuration.
+     */
+    public function setRequestParams()
+    {
+        $allowed_params = $this->getAllowedRequestParams(true);
+        $config_fields = $this->getConfigFields(true);
+        foreach ($allowed_params as $param_name) {
+            $method = $config_fields[$param_name] ?: 'get';
+            $param_value = Request::$method($param_name);
+            if ($param_value) {
+                $this->setValue($param_name, $param_value);
+            }
+        }
+    }
+
+    /**
+     * Stores the configuration.
+     *
+     * @return number|boolean
+     */
+    public function store()
+    {
+        if ($this->page_config->isNew()) {
+            $this->author_id = $GLOBALS['user']->id;
+        }
+        $this->editor_id = $GLOBALS['user']->id;
+        return $this->page_config->store();
+    }
+
+    /**
+     * Retrieves content of all members of given status as content array.
+     *
+     * @param Course $course The course.
+     * @param string $status Status of membership.
+     * @return array Array with content of course members.
+     */
+    protected function getContentMembers(Course $course, $status): array
+    {
+        $content = [];
+        $members = $course->getMembersWithStatus($status);
+        foreach ($members as $member) {
+            $user = $member->user;
+            $content[] = array_merge(
+                [
+                    'FULLNAME'   => $user->getFullname(),
+                    'LASTNAME'   => $user->nachname,
+                    'FIRSTNAME'  => $user->vorname,
+                    'TITLEFRONT' => $user->title_front,
+                    'TITLEREAR'  => $user->title_rear,
+                    'EMAIL'      => $user->email,
+                    'USERNAME'   => $user->username,
+                    'ID'         => $user->id,
+                ],
+                $this->getDatafieldMarkers($member),
+                $this->getDatafieldMarkers($user));
+        }
+        return $content;
+    }
+
+    /**
+     * Returns an array of semester ids depending on config value.
+     *
+     * @return array Array of semester ids.
+     */
+    protected function getSemesters(): array
+    {
+        static $semesters = [];
+
+        if (count($semesters) > 0) {
+            return $semesters;
+        }
+        $sem_time = date_create('now + ' . $this->semswitch . ' weeks');
+        switch ($this->startsem) {
+            case 'next':
+                $start_semester = Semester::findNext($sem_time->getTimestamp());
+                break;
+            case 'current':
+                $start_semester = Semester::findCurrent();
+                break;
+            case 'previous':
+                $start_semester = Semester::findPrevious($sem_time->getTimestamp());
+                break;
+            default:
+                $start_semester = Semester::find($this->startsem) ?: Semester::findCurrent();
+        }
+
+        $semesters = SimpleORMapCollection::createFromArray(
+            Semester::findBySQL('`beginn` >= :sem_start AND `visible` = 1 ORDER BY `beginn` LIMIT :sem_count',
+                [
+                    'sem_start'  => $start_semester->beginn,
+                    'sem_count'  => $this->semcount ?: 1
+                ]
+            )
+        )->pluck('id');
+        return $semesters;
+    }
+
+    /**
+     * Returns SQL snippet to filter by study areas.
+     *
+     * @param array $params Array with query parameters.
+     * @param array $scopes Array with selected scopes.
+     * @param bool $with_kids Returns all descendent ids of the given scopes.
+     * @return string SQL snippet or empty string if no study area is configured.
+     * @throws Exception
+     */
+    protected function getScopesSQL(
+        array &$params,
+        array $scopes,
+        bool $with_kids
+    ): string {
+        if (count($scopes) > 0) {
+            $study_areas = StudipStudyArea::findMany($scopes);
+            $scopes = [];
+            if ($with_kids) {
+                foreach ($study_areas as $study_area) {
+                    $scopes = array_merge($scopes, [$study_area->id], $study_area->getDescendantIds());
+                }
+            } else {
+                $scopes = SimpleORMapCollection::createFromArray($study_areas)->pluck('id');
+            }
+            $params[':sem_tree_ids'] = $scopes;
+            return ' AND `seminar_sem_tree`.`sem_tree_id` IN (:sem_tree_ids) ';
+        }
+        return '';
+    }
+
+    /**
+     * Returns SQL snippet to filter seminars by institutes if institute ids are stored in configuration.
+     * If no institutes stored in configuration it returns an empty string.
+     *
+     * @param array $params Parameters of SQL statement.
+     * @return string SQL snippet or empty string if no institute is configured.
+     */
+    protected function getInstitutesSQL(array &$params): string
+    {
+        $config = $this->page_config->getPristineValue('conf');
+        if ($config['institutes'] instanceof JSONArrayObject) {
+            $config_institutes = $config['institutes']->getArrayCopy();
+        } else {
+            return '';
+        }
+        if ($this->range_id !== 'studip') {
+            $institutes = [$this->range->id];
+            if ($this->range->is_fak && count($this->range->sub_institutes) > 0) {
+                $institutes += $this->range->sub_institutes->pluck('id');
+                if (count($config_institutes) > 0) {
+                    $institutes = array_intersect(
+                        $institutes,
+                        $config_institutes
+                    );
+                }
+            }
+        } else {
+            $institutes = $config_institutes;
+        }
+        // id from request parameter
+        // only accepts institutes defined in config
+        if (count($this->institutes) > 0) {
+            $requested_institutes = array_intersect(
+                $institutes,
+                $this->institutes
+            );
+            if (count($requested_institutes) > 0) {
+                $institutes = $requested_institutes;
+            }
+        }
+        $params[':institute_ids'] = $institutes;
+        $sql = ' AND (`seminare`.`Institut_id` IN (:institute_ids)';
+        if ($this->participating) {
+            $sql .= ' OR `seminar_inst`.`institut_id` IN (:institute_ids)';
+        }
+        return $sql . ') ';
+    }
+
+    /**
+     * Returns an array of institutes names as values and their IDs as keys.
+     *
+     * @throws UnexpectedValueException;
+     * @return array|false
+     */
+    public function getInstitutes()
+    {
+        if ($this->page_config->range_id === 'studip') {
+            return Institute::getMyInstitutes();
+        }
+        $count = Institute::countBySQL("`Institut_id` = ?", [$this->page_config->range_id]);
+        if ($count === 0) {
+            throw new UnexpectedValueException('Unknown institute');
+        }
+        return DBManager::get()->fetchAll("
+            SELECT `fakultaet`.`Institut_id`, `fakultaet`.`Name`, IF(`fakultaet`.`Institut_id` = `Institute`.`fakultaets_id`, 1, 0) AS `is_fak`
+            FROM `Institute`
+            LEFT JOIN `Institute` as `fakultaet` ON (`Institute`.`Institut_id` = `fakultaet`.`fakultaets_id`)
+            WHERE `Institute`.`Institut_id` = ?
+            ORDER BY fakultaet.Name ASC, is_fak DESC, Institute.Name ASC",
+            [$this->page_config->range_id]
+         );
+    }
+
+    /**
+     * Returns an associative array with area ids as keys and the area paths up
+     * to tree root as value.
+     *
+     * @param string $delimiter Delimiter between area names in path.
+     * @return array Array with area id as index and paths as value.
+     * @throws Exception
+     */
+    public function getStudyAreaPaths(string $delimiter = ' > '): array
+    {
+        $paths = [];
+        StudipStudyArea::findAndMapMany(
+            function ($area) use (&$paths, $delimiter) {
+                $paths[$area->id] = $area->getPath($delimiter);
+            },
+            $this->studyareas
+        );
+         asort($paths, SORT_LOCALE_STRING);
+         return $paths;
+    }
+
+    /**
+     * Returns all datafields for the given datafield classes.
+     *
+     * @param array $object_classes Array of datafield class names.
+     * @return DataField[] All datafields for given classes.
+     */
+    public function getDataFields(array $object_classes = []): array
+    {
+        $all_classes = DataField::getDataClass();
+        $data_fields = [];
+        foreach ($object_classes as $class) {
+            if (isset($all_classes[$class])) {
+                $data_fields[$class] = DataField::findBySQL('`object_type` = ? ORDER BY `priority`', [$class]);
+            }
+        }
+        return $data_fields;
+    }
+
+    /**
+     * Returns types of courses grouped by classes.
+     *
+     * @return array The grouped types.
+     */
+    public static function getGroupedSemTypes(): array
+    {
+        $grouped_sem_types = [];
+        foreach ($GLOBALS['SEM_CLASS'] as $class_id => $class) {
+            if ($class['studygroup_mode']) {
+                continue;
+            }
+            $grouped_sem_types[$class_id] = [
+                'name' => $class['name'],
+                'types' => $class->getSemTypes()
+            ];
+        }
+        return $grouped_sem_types;
+    }
+
+}
diff --git a/lib/extern/ExternPageCourseDetails.php b/lib/extern/ExternPageCourseDetails.php
new file mode 100644
index 00000000000..3dd01594d7a
--- /dev/null
+++ b/lib/extern/ExternPageCourseDetails.php
@@ -0,0 +1,293 @@
+<?php
+/**
+ * ExternPageCourseDetails.php - Class to provide course details as extern page.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @since       5.4
+ */
+
+class ExternPageCourseDetails extends ExternPage
+{
+
+    public $institute;
+
+    public function __construct($config)
+    {
+        parent::__construct($config);
+        $this->institute = Institute::find($this->page_config->range_id);
+    }
+
+    /**
+     * @see ExternPage::getSortFields()
+     */
+    public function getSortFields(): array
+    {
+        return [];
+    }
+
+    /**
+     * @see ExternPage::getDataFields()
+     */
+    public function getDataFields(array $object_classes = []): array
+    {
+        return parent::getDataFields(
+            [
+                'sem',
+                'user',
+                'userinstrole'
+            ]
+        );
+    }
+
+    /**
+     * @see ExternPage::getConfigFields()
+     */
+    public function getConfigFields(bool $as_array = false)
+    {
+        $args = '
+            language       option,
+            escaping       option,
+            rangepathlevel int
+        ';
+        return $as_array ? self::argsToArray($args) : $args;
+    }
+
+    /**
+     * @see ExternPage::getAllowedRequestParams()
+     */
+    public function getAllowedRequestParams(bool $as_array = false)
+    {
+        $params = [
+            'language',
+            'course_id',
+        ];
+        return $as_array ? $params : implode(',', $params);
+    }
+
+    /**
+     * @see ExternPage::getMarkersContents()
+     */
+    public function getMarkersContents(): array
+    {
+        return $this->getContent();
+    }
+
+    /**
+     *
+     *
+     * @return array|array[]
+     * @throws Exception
+     */
+    protected function getContent(): array
+    {
+        $course = Course::find($this->course_id);
+
+        if (
+            $this->range_id !== 'studip'
+            && (
+                $course->institut_id !== $this->institute->id
+                || !$course->institutes->find($this->institute->id)
+            )
+        ) {
+            return [];
+        }
+        if (!$course->visible) {
+            return [];
+        }
+
+        $content = $this->getContentCourse($course);
+        $content = array_merge($content, [
+            'LECTURERS' => $this->getContentMembers($course, 'dozent'),
+            'TUTORS'    => $this->getContentMembers($course, 'tutor'),
+        ]);
+        $content += $this->getContentRangePaths($course);
+        $content += $this->getContentModules($course);
+        $content += $this->getContentNews($course);
+        $content += $this->getContentParticipatingInstitutes($course);
+
+        return $content;
+    }
+
+    /**
+     * Retrieves the basic data of current course.
+     *
+     * @param Course $course The current course.
+     * @return array The content with basic data.
+     * @throws Exception
+     */
+    protected function getContentCourse(Course $course): array
+    {
+        $seminar = new Seminar($course);
+        $content = [
+            'TITLE'             => $course->name,
+            'SUBTITLE'          => $course->untertitel,
+            'FULLNAME'          => $course->getFullname(),
+            'SEMESTER'          => $course->getTextualSemester(),
+            'CYCLE'             => $seminar->getDatesExport(),
+            'ROOM'              => $course->ort,
+            'NUMBER'            => $course->veranstaltungsnummer,
+            'PRELIM_DISCUSSION' => vorbesprechung($course->id, 'export'),
+            'SEMTYPE_ID'        => $course->status,
+            'SEMTYPE'           => $GLOBALS['SEM_TYPE'][$course->status]['name'],
+            'SEMCLASS_ID'       => $GLOBALS['SEM_TYPE'][$course->status]['class'],
+            'SEMCLASS'          => $GLOBALS['SEM_CLASS'][$GLOBALS['SEM_TYPE'][$course->status]['class']]['name'],
+            'FORM'              => $course->art,
+            'PARTICIPANTS'      => $course->teilnehmer,
+            'DESCRIPTION'       => $course->beschreibung,
+            'MISCELLANEOUS'     => $course->sonstiges,
+            'REQUIREMENTS'      => $course->vorrausetzungen,
+            'ORGA'              => $course->lernorga,
+            'CERTIFICATE'       => $course->leistungsnachweis,
+            'ECTS'              => $course->ects,
+            'FIRST_MEETING'     => $seminar->getFirstDate('export'),
+            'HOME_INST_NAME'    => $course->home_institut->name,
+            'HOME_INST_ID'      => $course->home_institut->id,
+            'COUNT_USER'        => count($course->members),
+        ];
+        return array_merge(
+            $content,
+            $this->getDatafieldMarkers($course),
+            $this->getContentChildCourses($course));
+    }
+
+    /**
+     * Retrieves all subcourses.
+     *
+     * @param Course $course The parent course.
+     * @return array[] Array of subcourses content.
+     * @throws Exception
+     */
+    protected function getContentChildCourses(Course $course): array
+    {
+        $content = [];
+        foreach ($course->children as $child) {
+            $content[] = $this->getContentCourse($child);
+        }
+        return ['SUBCOURSES' => $content];
+    }
+
+    /**
+     * Retrieves all assignments to study areas as paths.
+     *
+     * @param Course $course The course.
+     * @return array[] Array with full paths of study areas (ranges).
+     */
+    protected function getContentRangePaths(Course $course): array
+    {
+        $content = [];
+        $paths = get_sem_tree_path($course->id, $this->rangepathlevel);
+        if (is_array($paths)) {
+            $content = array_values($paths);
+        }
+        return ['RANGE_PATHS' => $content];
+    }
+
+    /**
+     * Retrieves all module assignments as paths.
+     *
+     * @param Course $course The current course.
+     * @return array[] The paths through mvv.
+     */
+    protected function getContentModules(Course $course): array
+    {
+        $content = [];
+        $sem_class = $course->getSemClass();
+        if ($sem_class['module']) {
+            ModuleManagementModelTreeItem::setObjectFilter('Modul', function ($modul) use ($course) {
+                // check for public status
+                if (!$GLOBALS['MVV_MODUL']['STATUS']['values'][$modul->stat]['public']) {
+                    return false;
+                }
+                $modul_start = Semester::find($modul->start)->beginn ?: 0;
+                $modul_end = Semester::find($modul->end)->beginn ?: PHP_INT_MAX;
+                return ($course->start_time <= $modul_end)
+                    && (
+                        ($course->start_time >= $modul_start)
+                        || $course->isOpenEnded()
+                        || $course->getEndSemester()->ende <= $modul_end
+                        || $course->getEndSemester()->ende >= $modul_start
+                    );
+            });
+            ModuleManagementModelTreeItem::setObjectFilter('StgteilVersion', function ($version) {
+                return $GLOBALS['MVV_STGTEILVERSION']['STATUS']['values'][$version->stat]['public'];
+            });
+            $trail_classes = ['Modulteil', 'StgteilabschnittModul', 'StgteilAbschnitt', 'StgteilVersion'];
+            $mvv_object_paths = MvvCourse::get($this->course_id)->getTrails($trail_classes);
+
+            foreach ($mvv_object_paths as $mvv_object_path) {
+                $modul_id = '';
+                // show only complete paths
+                if (count($mvv_object_path) === 4) {
+                    $mvv_object_names = [];
+                    foreach ($mvv_object_path as $mvv_object) {
+                        $mvv_object_names[] = $mvv_object->getDisplayName();
+                        if ($mvv_object instanceof StgteilabschnittModul) {
+                            $modul_id = $mvv_object->modul_id;
+                        }
+                    }
+                    $content[] = [
+                        'PATH' => implode(' > ', $mvv_object_names),
+                        'ID' => $modul_id,
+                    ];
+                }
+            }
+        }
+
+        return ['MODULES' => $content];
+    }
+
+    /**
+     * Retrieves data of participated institutes as content array.
+     *
+     * @param Course $course The course.
+     * @return array[] Array with data of participated institutes.
+     */
+    protected function getContentParticipatingInstitutes(Course $course): array
+    {
+        $content = [];
+        foreach ($course->institutes as $institute) {
+            if ($institute->id !== $course->home_institut) {
+                $content[] = [
+                    'NAME' => $institute->name,
+                    'ID'   => $institute->id,
+                ];
+            }
+        }
+        return ['INVOLVED_INSTITUTES' => $content];
+    }
+
+    /**
+     * Retrieves content from news for current course.
+     *
+     * @param Course $course The current course.
+     * @return array[] The content with news data.
+     */
+    private function getContentNews(Course $course): array
+    {
+        $news = StudipNews::GetNewsByRange($course->id, true);
+        $content = [];
+        foreach ($news as $news_detail) {
+            $content[] = [
+                'BODY'       => $news_detail->body,
+                'TOPIC'      => $news_detail->topic,
+                'DATE'       => $news_detail->date,
+                'FULLNAME'   => $news_detail->owner->getFullname(),
+                'LASTNAME'   => $news_detail->owner->nachname,
+                'FIRSTNAME'  => $news_detail->owner->vorname,
+                'TITLEFRONT' => $news_detail->owner->title_front,
+                'TITLEREAR'  => $news_detail->owner->title_rear,
+                'USERNAME'   => $news_detail->owner->username,
+                'USERID'     => $news_detail->owner->id,
+            ];
+        }
+        return ['NEWS' => $content];
+    }
+
+}
diff --git a/lib/extern/ExternPageCourses.php b/lib/extern/ExternPageCourses.php
new file mode 100644
index 00000000000..3c6d9cb0b4b
--- /dev/null
+++ b/lib/extern/ExternPageCourses.php
@@ -0,0 +1,482 @@
+<?php
+/**
+ * ExternPageCourses.php - Class to provide a list of courses as extern page.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @since       5.4
+ */
+
+class ExternPageCourses extends ExternPage
+{
+    /**
+     * @see ExternPage::getSortFields()
+     */
+    public function getSortFields(): array
+    {
+        return [];
+    }
+
+    /**
+     * @see ExternPage::getDataFields()
+     */
+    public function getDataFields($object_classes = []): array
+    {
+        return parent::getDataFields(
+            [
+                'sem'
+            ]
+        );
+    }
+
+    /**
+     * @see ExternPage::getConfigFields()
+     */
+    public function getConfigFields($as_array = false)
+    {
+        $fields = '
+            groupby        option,
+            language       option,
+            startsem       option,
+            semcount       int,
+            semswitch      int,
+            participating  int,
+            categories     optionArray,
+            studyareas     optionArray,
+            scope_kids     int,
+            institutes     optionArray,
+            searchtext,
+            sublevels      int,
+            semtypes       optionArray,
+            escaping
+        ';
+        return $as_array ? self::argsToArray($fields) : $fields;
+    }
+
+    /**
+     * @see ExternPage::getAllowedRequestParams()
+     */
+    public function getAllowedRequestParams($as_array = false)
+    {
+        $params = [
+            'groupby',
+            'language',
+            'startsem',
+            'semcount',
+            'semswitch',
+            'participating',
+            'categories',
+            'studyareas',
+            'institutes',
+            'searchtext',
+            'sublevels',
+            'semtypes',
+         ];
+        return $as_array ? $params : implode(',', $params);
+    }
+
+    /**
+     * @see ExternPage::getMarkersContents()
+     */
+    public function getMarkersContents(): array
+    {
+        return $this->getContent();
+    }
+
+    /**
+     * Retries all courses filtered by configuration settings and search term.
+     *
+     * @return SimpleCollection The found courses as course objects.
+     * @throws Exception
+     */
+    private function getCourses(): SimpleCollection
+    {
+        $params = [];
+        $search_sql = $this->getSearchSQL($params);
+        $query = "
+            SELECT
+                DISTINCT `seminare`.*
+            FROM
+                `seminare`
+                LEFT JOIN `seminar_sem_tree`
+                    ON `seminare`.`Seminar_id` = `seminar_sem_tree`.`seminar_id`
+                LEFT JOIN `seminar_inst`
+                    ON `seminare`.`Seminar_id` = `seminar_inst`.`Seminar_id`
+                LEFT JOIN `semester_courses`
+                ON `semester_courses`.`course_id` = `seminare`.`Seminar_id`";
+        if ($search_sql || $this->groupby === '3') {
+            $query .= "
+                LEFT JOIN `seminar_user` ON (`seminare`.`Seminar_id` = `seminar_user`.`seminar_id`
+                    AND `seminar_user`.`status` = 'dozent')";
+        }
+        $query .= "
+            WHERE (`semester_courses`.`semester_id` IN (:semester_ids) OR ISNULL(`semester_id`))
+                AND ISNULL(`seminare`.`parent_course`) "
+            . $this->getScopesSQL($params, $this->studyareas, (bool) $this->scope_kids)
+            . $this->getInstitutesSQL($params)
+            . $this->getSemtypesSQL($params)
+            . $search_sql .
+            " ORDER BY `{$this->getOrderBy()['table']}`.`{$this->getOrderBy()['field']}`" ;
+
+        $params[':semester_ids'] = $this->getSemesters();
+        return SimpleCollection::createFromArray(DBManager::get()->fetchAll(
+            $query, $params, 'Course::buildExisting'));
+    }
+
+    /**
+     * Returns information about possible options to order course table.
+     *
+     * @return array Array with order data selected in configuration.
+     */
+    private function getOrderBy(): array
+    {
+        $order_by = [
+            'semnumber' => ['table' => 'seminare', 'field' => 'VeranstaltungsNummer'],
+            'semname'   => ['table' => 'seminare', 'field' => 'Name'],
+            'semtyp'    => ['table' => 'seminare', 'field' => 'status']
+        ];
+        return isset($order_by[$this->orderby]) ? $order_by[$this->orderby] : $order_by['semname'];
+    }
+
+    public function getSemesterOptions(): array
+    {
+         $semesters = [
+             ['id' => 'previous', 'name' => _('Vorheriges')],
+             ['id' => 'current',  'name' => _('Aktuelles')],
+             ['id' => 'next',     'name' => _('Nächstes')]
+        ];
+        return array_merge($semesters, array_reverse(Semester::getAllAsArray(false)));
+    }
+
+    /**
+     * Returns select-options to group the courses.
+     *
+     * @return array The select-options.
+     */
+    public function getGroupingOptions(): array
+    {
+        return [
+            '0' => _('Keine Gruppierung'),
+            '1' => _('Semester'),
+            '2' => _('Studienbereiche'),
+            '3' => _('Lehrende'),
+            '4' => _('Veranstaltungstypen'),
+            '5' => _('Einrichtungen')
+        ];
+    }
+
+    /**
+     * Returns associative array with content specific for each kind of grouping object.
+     *
+     * @param string $group_id The id of the object to group by.
+     * @return array[] Array with data from grouping objects.
+     * @throws InvalidArgumentException
+     */
+    private function getGroupingData($group_id)
+    {
+        $fields = [
+            'NAME' => '',
+            'ID'   => $group_id
+        ];
+        $order_by = '';
+        switch ($this->groupby) {
+            case 1:
+                // group by semesters
+                $semester = Semester::find($group_id);
+                if ($semester) {
+                    $fields = [
+                        'NAME'        => $semester->name,
+                        'SHORTNAME'   => $semester->semester_token,
+                        'EXTERNAL_ID' => $semester->external_id,
+                        'START'       => $semester->beginn,
+                        'END'         => $semester->ende,
+                        'ID'          => $group_id
+                    ];
+                    $order_by = date('Ymd', $semester->beginn);
+                }
+                break;
+            case 2:
+                // group by study areas
+                $study_area = StudipStudyArea::find($group_id);
+                if ($study_area) {
+                    $fields = [
+                        'NAME' => $study_area->getName(),
+                        'PATH' => $study_area->getPath(),
+                        'INFO' => $study_area->getInfo(),
+                        'ID'   => $group_id
+                    ];
+                    $order_by = implode(' ', $fields['PATH']);
+                }
+                break;
+            case 3:
+                // group by users (lecturers)
+                $user = User::find($group_id);
+                if ($user) {
+                    $fields = [
+                        'NAME'       => $user->getFullName(),
+                        'FIRSTNAME'  => $user->vorname,
+                        'LASTNAME'   => $user->nachname,
+                        'TITLEFRONT' => $user->title_front,
+                        'TITLEREAR'  => $user->title_rear,
+                        'ID'         => $group_id
+                    ];
+                    $order_by = $user->nachname . $user->vorname . $group_id;
+                }
+                break;
+            case 4:
+                // group by semtypes
+                $fields = [
+                    'NAME'     => $GLOBALS['SEM_TYPE'][$group_id]['name'],
+                    'CATEGORY' => $GLOBALS['SEM_CLASS'][$GLOBALS['SEM_TYPE'][$group_id]['class']]['name'],
+                    'ID'       => $group_id
+                ];
+                $order_by = $group_id;
+                break;
+            case 5:
+                // group by institutes
+                $institute = Institute::find($group_id);
+                if ($institute) {
+                    $fields = [
+                        'NAME'    => $institute->name,
+                        'FACULTY' => $institute->faculty->name,
+                        'ID'      => $group_id
+                    ];
+                    $order_by = $institute->name . $group_id;
+                }
+                break;
+            case -1:
+                // not in a group
+                break;
+            default:
+                throw new InvalidArgumentException('Invalid grouping option.');
+        }
+        return [
+            'data'     => $fields,
+            'order_by' => $order_by
+        ];
+    }
+
+    /**
+     * Retrieves all courses grouped and filtered by configuration settings and search term.
+     *
+     * @return Course[] Array of found courses grouped by selected order option.
+     * @throws Exception
+     */
+    private function getGroupedCourses(): array
+    {
+        $group_table_fields = [
+            '1' => '`semester_courses`.`semester_id`',
+            '2' => '`seminar_sem_tree`.`sem_tree_id`',
+            '3' => '`seminar_user`.`user_id`',
+            '4' => '`seminare`.`status`',
+            '5' => '`seminare`.`Institut_id`'
+        ];
+        $grouping = $group_table_fields[$this->groupby];
+        $grouped_courses = [];
+        $semesters = $this->getSemesters();
+        $params = [
+            ':semester_ids' => $semesters
+        ];
+        $search_sql = $this->getSearchSQL($params);
+        $query = "
+            SELECT DISTINCT
+                IFNULL({$grouping}, '-1') AS `group_id`,
+                `seminare`.`Seminar_id` AS `course_id`
+            FROM
+                `seminare`
+                LEFT JOIN `seminar_sem_tree`
+                    ON `seminare`.`Seminar_id` = `seminar_sem_tree`.`seminar_id`
+                LEFT JOIN `seminar_inst`
+                    ON `seminare`.`Seminar_id` = `seminar_inst`.`Seminar_id`
+                LEFT JOIN `semester_courses`
+                ON `semester_courses`.`course_id` = `seminare`.`Seminar_id`";
+        if ($search_sql || $this->groupby === '3') {
+            $query .= "
+                LEFT JOIN `seminar_user` ON (`seminare`.`Seminar_id` = `seminar_user`.`seminar_id`
+                    AND `seminar_user`.`status` = 'dozent')
+                LEFT JOIN `auth_user_md5` USING(`user_id`)";
+        }
+        $query .= "
+            WHERE (`semester_courses`.`semester_id` IN (:semester_ids) OR ISNULL(`semester_id`))
+                AND ISNULL(`seminare`.`parent_course`) "
+                . $this->getScopesSQL($params, $this->studyareas, (bool) $this->scope_kids)
+                . $this->getInstitutesSQL($params)
+                . $this->getSemtypesSQL($params)
+                . $search_sql;
+
+        $grouped_results = DBManager::get()->fetchGroupedPairs($query, $params);
+
+        // handle unlimited courses
+        if ($this->groupby === '1' && isset($grouped_results['-1'])) {
+            foreach ($semesters as $semester_id) {
+                if (isset($grouped_results[$semester_id])) {
+                    $grouped_results[$semester_id] = array_merge($grouped_results[$semester_id], $grouped_results['-1']);
+                } else {
+                    $grouped_results[$semester_id] = $grouped_results['-1'];
+                }
+            }
+            unset($grouped_results['-1']);
+        }
+
+        foreach ($grouped_results as $group_id => $group_result) {
+            $group = $this->getGroupingData($group_id);
+            $grouped_courses[$group['order_by']] = [
+                'group'   => $group['data'],
+                'courses' => SimpleORMapCollection::createFromArray(
+                    Course::findMany($group_result)
+                )->orderBy($this->getOrderBy()['field']),
+            ];
+        }
+        ksort($grouped_courses, SORT_LOCALE_STRING);
+        return $grouped_courses;
+    }
+
+    /**
+     * Return sql snippet to filter courses by search term.
+     *
+     * @param array &$params Array with SQL parameters.
+     * @return string SQL snippet or empty string if no search term is given.
+     */
+    private function getSearchSQL(array &$params): string
+    {
+        if ($this->sword && mb_strlen($this->sword) > 2) {
+            $params[':sword'] = $this->sword;
+            return "
+                    AND (`seminare`.`Name` LIKE '%:sword%'
+                        OR `seminare`.`VeranstaltungsNummer` LIKE '%:sword%'
+                        OR `auth_user_md5`.`Nachname`)";
+        }
+        return '';
+    }
+
+    /**
+     * Returns SQL snippet to filter by course types.
+     *
+     * @param array $params Parameters of SQL statement.
+     * @return string SQL snippet or empty string if no course type is configured.
+     * @throws Exception
+     */
+    private function getSemtypesSQL(array &$params): string
+    {
+        if ($this->semtypes) {
+            $params[':semtypes'] = $this->semtypes;
+            return ' AND `seminare`.`status` IN (:semtypes) ';
+        }
+        return '';
+    }
+
+    /**
+     * Returns all content of courses to render the page template.
+     *
+     * @return array All content to render the template.
+     */
+    protected function getContent(): array
+    {
+        $i = 0;
+        $count = [];
+        $content = [];
+        if ($this->groupby) {
+            $groups_content = [];
+            foreach ($this->getGroupedCourses() as $courses_group) {
+                $courses_content = [];
+                foreach ($courses_group['courses'] as $course) {
+                    $count[$course->id] = true;
+                    $courses_content[] = $this->getCourseContent($course);
+                }
+                $groups_content[$i]['GROUP'] = $courses_group['group'];
+                $groups_content[$i++]['COURSES'] = $courses_content;
+            }
+            $content['GROUPED_COURSES'] = $groups_content;
+            $content['GROUPED_BY']      = $this->groupby;
+        } else {
+            $list_content = [];
+            foreach ($this->getCourses() as $course) {
+                $count[$course->id] = true;
+                $list_content[] = $this->getCourseContent($course);
+            }
+            $content['COURSES'] = $list_content;
+        }
+        $content['COUNT'] = count($count);
+        return $content + $this->getSemesterContent();
+    }
+
+    /**
+     * Returns semester content.
+     *
+     * @return array Content array with semester data.
+     */
+    private function getSemesterContent(): array
+    {
+        $semester_ids = $this->getSemesters();
+        $semesters = [
+            'END_'   => Semester::find(end($semester_ids) ?: ''),
+            'START_' => Semester::find(reset($semester_ids) ?: '')
+        ];
+        $semester_content = [];
+        array_walk($semesters,
+            function ($sem, $index) use (&$semester_content) {
+                if ($index) {
+                    $semester_content += [
+                        $index . 'SEMESTER_NAME'  => $sem->name,
+                        $index . 'SEMESTER_ID'    => $sem->id,
+                        $index . 'SEMESTER_START' => $sem->beginn,
+                        $index . 'SEMESTER_END'   => $sem->ende
+                    ];
+                }
+            });
+        return $semester_content;
+    }
+
+    /**
+     * Returns basic data of a course and of the sub-courses (recursive).
+     *
+     * @param Course $course The course.
+     * @return array Array with basic course data.
+     */
+    private function getCourseContent(Course $course): array
+    {
+        $course_content = [
+            'TITLE'           => $course->name,
+            'FULLTITLE'       => $course->getFullname(),
+            'SUBTITLE'        => $course->untertitel,
+            'NUMBER'          => $course->veranstaltungsnummer,
+            'SEMESTER'        => $course->getFullname('sem-duration-name'),
+            'FORM'            => $course->art,
+            'ROOM'            => $course->ort,
+            'CYCLE'           => Seminar::getInstance($course->id)->getDatesExport(['show_room' => true]),
+            'AVATAR_URL'      => $course->getItemAvatarURL(),
+            'INFO_URL'        => $course->getItemURL(),
+            'LECTURERS'       => $this->getContentMembers($course, 'dozent'),
+            'SEMTYPE_NAME'    => $GLOBALS['SEM_TYPE'][$course->status]['name'],
+            'SEMTYPE_NUMBER'  => $course->status,
+            'SEMCLASS_NAME'   =>
+                $GLOBALS['SEM_CLASS'][$GLOBALS['SEM_TYPE'][$course->status]['class']]['name'],
+            'SEMCLASS_NUMBER' => $GLOBALS['SEM_TYPE'][$course->status]['class'],
+            'ID'              => $course->id,
+            'SUBCOURSES'      => $this->getSubcourses($course)
+        ];
+        return array_merge($course_content, $this->getDatafieldMarkers($course));
+    }
+
+    /**
+     * Retrieves sub-courses of a course.
+     *
+     * @param Course $course The parent course.
+     * @return array All direct sub-courses.
+     */
+    private function getSubcourses(Course $course): array
+    {
+        $subcourses = [];
+        foreach ($course->children as $child) {
+            $subcourses[] = $this->getCourseContent($child);
+        }
+        return $subcourses;
+    }
+
+}
diff --git a/lib/extern/ExternPageDownload.php b/lib/extern/ExternPageDownload.php
new file mode 100644
index 00000000000..6e3a5ad720e
--- /dev/null
+++ b/lib/extern/ExternPageDownload.php
@@ -0,0 +1,211 @@
+<?php
+/**
+ * ExternPageCourseDownload.php - Class to provide a list of files from
+ * an institutes file system.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @since       5.4
+ */
+
+class ExternPageDownload extends ExternPage
+{
+
+    public $institute;
+
+    public function __construct($config)
+    {
+        parent::__construct($config);
+        $this->institute = Institute::find($this->page_config->range_id);
+    }
+
+    /**
+     * @see ExternPage::getSortFields()
+     */
+    public function getSortFields(): array
+    {
+        return [
+            'name'     => _('Dateiname'),
+            'mkdate'   => _('Datum'),
+            'size'     => _('Dateigröße'),
+            'author'   => _('Autor:in'),
+            'filetype' => _('Dateityp')
+        ];
+    }
+
+    /**
+     * @see ExternPage::getDataFields()
+     */
+    public function getDataFields(array $object_classes = []): array
+    {
+        return parent::getDataFields(
+            [
+                'user'
+            ]
+        );
+    }
+
+    /**
+     * @see ExternPage::getConfigFields()
+     */
+    public function getConfigFields($as_array = false)
+    {
+        $args = '
+            sort          option,
+            language      option,
+            folder        optionArray,
+            subfolders    int
+        ';
+        return $as_array ? self::argsToArray($args) : $args;
+    }
+
+    /**
+     * @see ExternPage::getAllowedRequestParams()
+     */
+    public function getAllowedRequestParams(bool $as_array = false)
+    {
+        $params = [
+            'language',
+            'sort',
+            'folder',
+            'subfolders',
+        ];
+        return $as_array ? $params : implode(',', $params);
+    }
+
+    /**
+     * @see ExternPage::getMarkersContents()
+     */
+    public function getMarkersContents(): array
+    {
+        return $this->getContent();
+    }
+
+    /**
+     * Returns all content of downloadable files to render the page template.
+     *
+     * @return array All content to render the template.
+     */
+    protected function getContent(): array
+    {
+        $content = [];
+        $downloadable_file_refs = new SimpleCollection($this->getDownloadableFileRefs($this->page_config->range_id));
+        $downloadable_file_refs->orderBy($this->sort);
+        foreach ($downloadable_file_refs as $file_ref) {
+            $content_file = [
+                'ICON_URL'    => Icon::create(
+                     FileManager::getIconNameForMimeType($file_ref->mime_type)
+                )->asImagePath(),
+                'URL'          => $file_ref->download_url,
+                'NAME'         => $file_ref->name,
+                'DESCRIPTION'  => $file_ref->description,
+                'UPLOAD_DATE'  => $file_ref->mkdate,
+                'SIZE'         => $file_ref->filesize > 1048576
+                    ? round($file_ref->filesize / 1048576, 1) . ' MB'
+                    : round($file_ref->filesize / 1024, 1) . ' KB'
+            ];
+            if ($file_ref->owner) {
+                $content_owner = [
+                    'USERNAME'          => $file_ref->owner->username,
+                    'USERID'            => $file_ref->owner->id,
+                    'FULLNAME'          => $file_ref->owner->getFullname(),
+                    'FIRSTNAME'         => $file_ref->owner->vorname,
+                    'LASTNAME'          => $file_ref->owner->nachname,
+                    'TITLEFRONT'        => $file_ref->owner->title_front,
+                    'TITLEREAR'         => $file_ref->owner->title_rear,
+                ];
+            }
+            $content[] = array_merge(
+                $content_file,
+                $content_owner,
+                $this->getDatafieldMarkers($file_ref->owner));
+        }
+
+        return ['FILES' => $content];
+    }
+
+    /**
+     * Retrieves all file refs of downloadable files.
+     *
+     * @param string $institute_id The id of the institute.
+     * @return array Array with file refs.
+     */
+    protected function getDownloadableFileRefs(string $institute_id): array
+    {
+        $downloadable_file_refs = [];
+
+        $top_folder = Folder::findTopFolder($institute_id);
+        $top_folder = $top_folder->getTypedFolder();
+
+        $files = $folders = [];
+        extract(FileManager::getFolderFilesRecursive($top_folder, 'nobody'));
+
+        foreach ($files as $file) {
+            $folder = $folders[$file->folder_id];
+            if ($folder->isFileDownloadable($file->id, 'nobody')) {
+                $downloadable_file_refs[] = $file;
+            }
+        }
+        return $downloadable_file_refs;
+    }
+
+    public function getFullGroupNames()
+    {
+        $groups = [];
+        foreach ($this->institute->status_groups as $status_group) {
+            $groups[$status_group->id] = $status_group->name;
+            $groups = array_merge($groups, $this->getGroupPaths($status_group));
+        }
+        return $groups;
+    }
+
+    /**
+     * @param $group
+     * @param string $seperator
+     * @param string $pre
+     * @return array
+     */
+    public function getGroupPaths($group, $seperator = ' > ', $pre = ''): array
+    {
+        $name = $pre
+            ? $pre . $seperator . $group->getName()
+            : $group->getName();
+        $result[$group->id] = $name;
+        if ($group->children) {
+            foreach ($group->children as $child) {
+                $result = array_merge($result, $this->getGroupPaths($child, $seperator, $name));
+            }
+        }
+        return $result;
+    }
+
+    /**
+     * Returns an array of paths from top folder to all folders below.
+     *
+     * @return array Array of concatenated folder names.
+     */
+    public function get_concatenated_folders(): array
+    {
+        $top_folder = Folder::findTopFolder($this->page_config->range_id);
+        $top_folder = $top_folder->getTypedFolder();
+        $folders = FileManager::getReadableFolders($top_folder, 'nobody');
+        $folder_names = [];
+        $get_parent_folder_name = function ($folder, $folder_id) use (&$get_parent_folder_name, &$folders, &$folder_names) {
+            $folder_names[$folder_id][] = $folder->name;
+            if ($folder->parent_id) {
+                $get_parent_folder_name($folders[$folder->parent_id], $folder_id);
+            } else {
+                $folder_names[$folder_id] = implode(' > ', array_reverse($folder_names[$folder_id]));
+            }
+        };
+        array_walk($folders, $get_parent_folder_name);
+        return $folder_names;
+    }
+
+}
diff --git a/lib/extern/ExternPagePersBrowse.php b/lib/extern/ExternPagePersBrowse.php
new file mode 100644
index 00000000000..270e99124cd
--- /dev/null
+++ b/lib/extern/ExternPagePersBrowse.php
@@ -0,0 +1,392 @@
+<?php
+/**
+ * ExternPagePersBrowse.php - Class to provide lists of institute members
+ * from all institutes.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @since       5.4
+ */
+
+class ExternPagePersBrowse extends ExternPage
+{
+    public function __construct($config)
+    {
+        parent::__construct($config);
+        $this->institute = Institute::find($this->page_config->range_id);
+    }
+
+    /**
+     * @see ExternPage::getSortFields()
+     */
+    public function getSortFields(): array
+    {
+        return [];
+    }
+
+    /**
+     * @see ExternPage::getDataFields()
+     
+     * @param array $classes
+     * @return array
+     */
+    public function getDataFields($object_classes = []): array
+    {
+        return parent::getDataFields(
+            [
+                'user',
+                'inst'
+            ]
+        );
+    }
+
+    /**
+     * @param false $as_array
+     * @return array|mixed|string
+     */
+    public function getConfigFields($as_array = false)
+    {
+        $args = '
+            language       option,
+            escaping       option,
+            instperms      optionArray,
+            onlylecturers  int,
+            institutes     optionArray
+        ';
+        return $as_array ? self::argsToArray($args) : $args;
+    }
+
+    public function getAllowedRequestParams($as_array = false)
+    {
+        $params = [
+            'language',
+            'initiale',
+            'item_id',
+        ];
+        return $as_array ? $params : implode(',', $params);
+    }
+
+    public function getMarkersContents(): array
+    {
+        return $this->getContent();
+    }
+
+    /**
+     * Returns select-options with institute permissions.
+     *
+     * @return array Array with select-options.
+     */
+    public function getInstitutePermissionOptions(): array
+    {
+        return [
+            'tutor'  => _('Tutoren/Tutorinnen'),
+            'dozent' => _('Dozenten/Dozentinnen'),
+            'admin'  => _('Administratoren/Administratorinnen')
+        ];
+    }
+
+    protected function getContent()
+    {
+        // at least one institute has to be selected in the configuration
+        if (!is_array($this->institutes)) {
+            return [];
+        }
+
+        $content = [
+            'PERSONS'    => $this->getContentListPersons(),
+            'CHARACTERS' => $this->getContentListCharacters(),
+            'INSTITUTES' => $this->getContentListInstitutes(),
+        ];
+
+        return $content;
+    }
+
+    protected function getContentListPersons()
+    {
+        $content = [];
+        if ($this->initiale) {
+            if ($this->onlylecturers) {
+                $current_semester = Semester::findCurrent();
+                $query = "
+                    SELECT
+                        ui.Institut_id, su.user_id
+                    FROM seminar_user su
+                        LEFT JOIN auth_user_md5 aum USING(user_id)
+                        LEFT JOIN seminare s USING (seminar_id)
+                        LEFT JOIN user_inst ui USING(user_id)
+                        LEFT JOIN semester_courses sc ON sc.course_id = su.seminar_id
+                    WHERE LOWER(LEFT(TRIM(aum.Nachname), 1)) = LOWER(?)
+                        AND su.status = 'dozent'
+                        AND s.visible = 1
+                        AND (sc.semester_id = ? OR ISNULL(sc.semester_id))
+                        AND ui.Institut_id IN (?)
+                        AND ui.inst_perms = 'dozent'
+                        AND ui.externdefault = 1
+                        AND " . get_ext_vis_query();
+                $params = [
+                    mb_substr($this->initiale, 0, 1),
+                    $current_semester->id,
+                    $this->institutes,
+                ];
+            } else {
+                // get only users with the given status
+                $query = "
+                    SELECT
+                        ui.Institut_id, ui.user_id
+                    FROM user_inst ui
+                        LEFT JOIN auth_user_md5 aum USING(user_id)
+                    WHERE LOWER(LEFT(TRIM(aum.Nachname), 1)) = LOWER(?)
+                        AND ui.inst_perms IN(?)
+                        AND ui.Institut_id IN (?)
+                        AND ui.externdefault = 1
+                        AND " . get_ext_vis_query();
+                $params = [
+                    mb_substr($this->initiale, 0, 1),
+                    $this->instperms,
+                    $this->institutes,
+                ];
+            }
+        // item_id is given and it is in the list of item_ids selected in the configuration
+        } else if ($this->item_id && in_array($this->item_id, $this->institutes)) {
+            if ($this->onlylecturers) {
+                $current_semester = Semester::findCurrent();
+                // get only users with status dozent in a visible seminar in the current semester
+                $query = "
+                    SELECT
+                        ui.Institut_id, ui.user_id
+                    FROM user_inst ui
+                        INNER JOIN auth_user_md5 aum USING (user_id)
+                        LEFT JOIN seminar_user su USING(user_id)
+                        LEFT JOIN seminare s USING (seminar_id)
+                        LEFT JOIN semester_courses sc ON sc.course_id = s.seminar_id
+                    WHERE ui.Institut_id = ?
+                        AND ui.inst_perms = 'dozent'
+                        AND ui.externdefault = 1
+                        AND " . get_ext_vis_query() . "
+                        AND su.status = 'dozent'
+                        AND s.visible = 1
+                        AND (sc.semester_id = ? OR ISNULL(sc.semester_id)";
+                $params = [
+                    $this->item_id,
+                    $current_semester->id,
+                ];
+            } else {
+                // get only users with the given status
+                $query = '
+                    SELECT
+                        ui.Institut_id, ui.user_id
+                    FROM user_inst ui
+                        INNER JOIN auth_user_md5 aum USING (user_id)
+                    WHERE ui.Institut_id = ?
+                        AND ui.inst_perms IN(?)
+                        AND ui.externdefault = 1
+                        AND ' . get_ext_vis_query();
+                $params = [
+                    $this->item_id,
+                    $this->instperms,
+                ];
+            }
+        } else {
+            return [];
+        }
+        $rows = DBManager::get()->fetchAll($query, $params);
+        $user_list = [];
+        foreach ($rows as $row) {
+            if (!isset($user_list[$row['user_id']])) {
+                $user_list[$row['user_id']] = $row['user_id'] . $row['Institut_id'];
+            }
+        }
+        if (count($user_list) === 0) {
+            return [];
+        }
+
+        $query = '
+            SELECT
+                ui.Institut_id, ui.raum, ui.sprechzeiten, ui.Telefon,
+                inst_perms,  i.Name, aum.user_id, aum.Nachname,
+                aum.Vorname
+            FROM user_inst ui
+                LEFT JOIN Institute i USING(Institut_id)
+                LEFT JOIN auth_user_md5 aum USING(user_id)
+                LEFT JOIN user_info uin USING(user_id)
+            WHERE CONCAT(ui.user_id, ui.Institut_id) IN (?)
+                AND ' . get_ext_vis_query() . '
+            ORDER BY aum.Nachname, aum.Vorname';
+        $rows = DBManager::get()->fetchAll($query, [$user_list]);
+
+        foreach ($rows as $row) {
+            $user = User::find($row['user_id']);
+            $content[] = array_merge(
+                [
+                    'FULLNAME'    => $user->getFullName(),
+                    'LASTNAME'    => $user->nachname,
+                    'FIRSTNAME'   => $user->vorname,
+                    'TITLEFRONT'  => $user->title_front,
+                    'TITLEREAR'   => $user->title_rear,
+                    'USERNAME'    => $user->username,
+                    'USERID'      => $user->id,
+                    'INSTNAME'    => $row['Name'],
+                    'PHONE'       => $row['Telefon'],
+                    'ROOM'        => $row['raum'],
+                    'EMAIL'       => get_visible_email($user->id),
+                    'OFFICEHOURS' => $row['sprechzeiten']
+                ],
+                $this->getDatafieldMarkers($user));
+        }
+        return $content;
+    }
+
+    /**
+     * Returns an array with content to display a list of characters
+     * (initials, the first character of the persons last name).
+     *
+     * @return array The content with a list of initials.
+     */
+    private function getContentListCharacters()
+    {
+        // at least one institute has to be selected in the configuration
+        if (!is_array($this->institutes)) {
+            return [];
+        }
+
+        if ($this->onlylecturers) {
+            $current_semester = Semester::findCurrent();
+            $query = "
+                SELECT COUNT(DISTINCT aum.user_id) as count_user,
+                    UPPER(LEFT(TRIM(aum.Nachname),1)) AS initiale
+                FROM user_inst ui
+                    LEFT JOIN seminar_user su ON ui.user_id = su.user_id
+                    LEFT JOIN seminare s ON su.Seminar_id = s.Seminar_id
+                    LEFT JOIN semester_courses sc ON s.seminar_id = sc.course_id
+                    LEFT JOIN auth_user_md5 aum ON su.user_id = aum.user_id
+                WHERE su.status = 'dozent' AND s.visible = 1
+                    AND (sc.semester_id = ? OR ISNULL(sc.semester_id))
+                    AND TRIM(aum.Nachname) != ''
+                    AND ui.Institut_id IN (?)
+                    AND ui.externdefault = 1
+                    AND " . get_ext_vis_query() . '
+                GROUP BY initiale';
+            $params = [
+                $current_semester->id,
+                $this->institutes,
+            ];
+        } else {
+            $query = "
+                SELECT
+                    COUNT(DISTINCT ui.user_id) as count_user,
+                    UPPER(LEFT(TRIM(aum.Nachname),1)) AS initiale
+                FROM user_inst ui
+                    LEFT JOIN auth_user_md5 aum USING (user_id)
+                WHERE ui.inst_perms IN (?)
+                    AND ui.Institut_id IN (?)
+                    AND ui.externdefault = 1
+                    AND TRIM(aum.Nachname) != ''
+                GROUP BY initiale";
+            $params = [
+                $this->instperms,
+                $this->institutes,
+            ];
+        }
+
+        $rows = DBManager::get()->fetchAll($query, $params);
+        $content = [];
+        foreach ($rows as $row) {
+            $content[] = [
+                'CHARACTER_USER'  => $row['initiale'],
+                'CHARACTER_COUNT' => $row['count_user'],
+            ];
+        }
+        return $content;
+    }
+
+    /**
+     * Returns an array with institute data
+     *
+     * @return array
+     */
+    private function getContentListInstitutes() {
+        // at least one institute has to be selected in the configuration
+        if (!is_array($this->institutes)) {
+            return [];
+        }
+
+        $query = "
+            SELECT
+                Institute.*
+            FROM
+                Institute
+            WHERE Institut_id IN (?)
+                AND fakultaets_id != Institut_id
+            ORDER BY Name ASC";
+        $statement = DBManager::get()->prepare($query);
+        $statement->execute([$this->institutes]);
+
+        $current_semester = Semester::findCurrent();
+        $content = [];
+        while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
+            if ($this->onlylecturers) {
+                // get only users with status dozent in a visible seminar in the current semester
+                $query = "
+                    SELECT
+                        COUNT(DISTINCT(su.user_id)) AS count_user
+                    FROM
+                        user_inst ui
+                        LEFT JOIN seminar_user su USING(user_id)
+                        LEFT JOIN seminare s USING (seminar_id)
+                        LEFT JOIN semester_courses sc ON s.seminar_id = sc.course_id
+                        LEFT JOIN auth_user_md5 aum ON su.user_id = aum.user_id
+                    WHERE ui.Institut_id = ?
+                        AND su.status = 'dozent'
+                        AND ui.externdefault = 1
+                        AND " . get_ext_vis_query() . "
+                        AND ui.inst_perms = 'dozent'
+                        AND (sc.semester_id = ? OR ISNULL(sc.semester_id))";
+                $params = [
+                    $row['Institut_id'],
+                    $current_semester->id,
+                ];
+            } else {
+                // get only users with the given status
+                $query = "
+                    SELECT
+                        COUNT(DISTINCT(ui.user_id)) AS count_user
+                    FROM
+                        user_inst ui
+                        INNER JOIN auth_user_md5 aum USING (user_id)
+                    WHERE ui.Institut_id = ?
+                        AND ui.inst_perms IN(?)
+                        AND ui.externdefault = 1
+                        AND " . get_ext_vis_query();
+                $params = [
+                    $row['Institut_id'],
+                    $this->instperms,
+                ];
+            }
+
+            $state = DBManager::get()->prepare($query);
+            $state->execute($params);
+            while ($row_count = $state->fetch(PDO::FETCH_ASSOC)) {
+                if ($row_count['count_user'] > 0) {
+                    $institute = Institute::build($row, false);
+                    $content[] = array_merge(
+                        [
+                            'NAME'        => $institute->name,
+                            'FULLNAME'    => $institute->getFullname(),
+                            'ID'          => $institute->id,
+                            'COUNT_USERS' => $row_count['count_user'],
+                        ],
+                        $this->getDatafieldMarkers($institute)
+                    );
+                }
+            }
+        }
+        return $content;
+    }
+
+}
diff --git a/lib/extern/ExternPagePersonDetails.php b/lib/extern/ExternPagePersonDetails.php
new file mode 100644
index 00000000000..a71124e0c55
--- /dev/null
+++ b/lib/extern/ExternPagePersonDetails.php
@@ -0,0 +1,472 @@
+<?php
+/**
+ * ExternPagePersonDetails.php - Class to provide detailed data of an
+ * institute member.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @since       5.4
+ */
+
+class ExternPagePersonDetails extends ExternPage
+{
+
+    public $institute;
+
+    public function __construct($config)
+    {
+        parent::__construct($config);
+        $this->institute = Institute::find($this->page_config->range_id);
+    }
+
+    /**
+     * @return array
+     */
+    public function getSortFields() : array
+    {
+        return [];
+    }
+
+    public function getDataFields($object_classes = []) : array
+    {
+        return parent::getDataFields(
+            [
+                'user',
+                'userinstrole'
+            ]
+        );
+    }
+
+    /**
+     * @param false $as_array
+     * @return array|mixed|string
+     */
+    public function getConfigFields($as_array = false)
+    {
+        $args = '
+            language      option,
+            startsem      option,
+            semcount      int,
+            semswitch     int,
+            semclass      optionArray,
+            escaping      option,
+            defaultaddr   int
+        ';
+        return $as_array ? self::argsToArray($args) : $args;
+    }
+
+    public function getAllowedRequestParams($as_array = false)
+    {
+        $params = [
+            'language',
+            'startsem',
+            'semcount',
+            'semswitch',
+            'user_id',
+            'user_name',
+        ];
+        return $as_array ? $params : implode(',', $params);
+    }
+
+    public function getMarkersContents(): array
+    {
+        return $this->getContent();
+    }
+
+    protected function getContent()
+    {
+        if ($this->user_name) {
+            $user = User::findByUsername($this->user_name);
+        } else {
+            $user = User::find($this->user_id);
+        }
+
+        if (!$user) {
+            return [];
+        }
+
+        $memberships = $this->getMemberships($user);
+        if (count($memberships) === 0) {
+            return [];
+        }
+
+        $content = $this->getContentUser($user);
+        $content += $this->getContentInstituteMembers($memberships);
+        $content += $this->getContentSemesterCourses($user);
+        $content += $this->getContentHomepagePlugins($user);
+        $content += $this->getContentNews($user);
+        $content += $this->getContentAppointments($user);
+        $content += $this->getContentOwnCategories($user);
+        return $content;
+    }
+
+    /**
+     * Retrieves all institute memberships of the current user dependent on
+     * home institute of this page configuration.
+     *
+     * @param User $user The current user.
+     * @return InstituteMember[] The memberships of the user.
+     */
+    private function getMemberships(User $user)
+    {
+        return InstituteMember::findBySQL(
+            '`user_id` = ? AND `inst_perms` = ?',
+            [
+                $user->id,
+                'dozent'
+            ]
+        );
+    }
+
+    /**
+     * Retrieves all courses of given user filtered by config values and grouped by semester.
+     *
+     * @param User $user
+     * @return array
+     * @throws Exception
+     */
+    private function getUserCourses(User $user)
+    {
+        $grouped_courses = [];
+        $semesters = $this->getSemesters();
+        $query = "
+            SELECT
+                IFNULL(`semester_courses`.`semester_id`, '-1') AS `group_id`,
+                `seminare`.*
+            FROM
+                `seminare`
+                LEFT JOIN `semester_courses`
+                    ON `semester_courses`.`course_id` = `seminare`.`Seminar_id`
+                LEFT JOIN `seminar_user` USING(`seminar_id`)
+                LEFT JOIN `sem_types`
+                    ON `sem_types`.`id` = `seminare`.`status`
+            WHERE `semester_courses`.`semester_id` IN (:semester_ids) OR ISNULL(`semester_id`)
+                AND `seminar_user`.`user_id` = :user_id
+                AND `seminar_user`.`status` = 'dozent'
+                AND `sem_types`.`class` IN (:semclasses)";
+
+        $grouped_results = DBManager::get()->fetchGrouped($query,
+            [
+                'semester_ids' => $semesters,
+                'semclasses'   => (array) $this->semclass,
+                'user_id'      => $user->id
+            ]);
+
+        // handle unlimited courses
+        if (isset($grouped_results['-1'])) {
+            foreach ($semesters as $semester_id) {
+                if (isset($grouped_results[$semester_id])) {
+                    $grouped_results[$semester_id] = array_merge($grouped_results[$semester_id], $grouped_results['-1']);
+                } else {
+                    $grouped_results[$semester_id] = $grouped_results['-1'];
+                }
+            }
+            unset($grouped_results['-1']);
+        }
+        foreach ($grouped_results as $group_id => $group_result) {
+            $grouped_courses[$group_id] =
+                SimpleORMapCollection::createFromArray(
+                    Course::findMany($group_result));
+        }
+        return $grouped_courses;
+    }
+
+    protected function getAllChildren($group)
+    {
+        $all_groups[] = $group;
+        foreach ($group->getChildren() as $child) {
+            $all_groups = array_merge($all_groups, $this->getAllChildren($child));
+        }
+        return $all_groups;
+    }
+
+    protected function getContentUser(User $user)
+    {
+        if (Visibility::verify('picture', $user->id)) {
+            $avatar = Avatar::getAvatar($user->id);
+        } else {
+            $avatar = Avatar::getNobody();
+        }
+        $content = [
+            'FULLNAME'           => $user->getFullName(),
+            'LASTNAME'           => $user->Nachname,
+            'FIRSTNAME'          => $user->Vorname,
+            'TITLEFRONT'         => $user->title_front,
+            'TITLEREAR'          => $user->title_rear,
+            'USERNAME'           => $user->username,
+            'USERID'             => $user->id,
+            'IMAGE_URL_SMALL'    => $avatar->getURL(Avatar::SMALL),
+            'IMAGE_URL_MEDIUM'   => $avatar->getURL(Avatar::MEDIUM),
+            'IMAGE_URL_NORMAL'   => $avatar->getURL(Avatar::NORMAL),
+            'EMAIL'              => get_visible_email($user->id),
+            'HOMEPAGE_URL'       => Visibility::verify('homepage', $user->id) ? $user->home : '',
+            'CV'                 => Visibility::verify('lebenslauf', $user->id) ? $user->lebenslauf : '',
+            'RESEARCH_INTERESTS' => Visibility::verify('schwerp', $user->id) ? $user->schwerp : '',
+            'PUBLICATIONS'       => Visibility::verify('publi', $user->id) ? $user->publi : '',
+       ];
+        $content += $this->getDatafieldMarkers($user);
+        return $content;
+    }
+
+    protected function getContentInstituteMembers($members)
+    {
+        $content = [];
+        foreach ($members as $member) {
+            if (!$member->visible) {
+                continue;
+            }
+            $content[] = array_merge(
+                [
+                    'ID'                 => $member->institut_id,
+                    'NAME'               => $member->institute->name,
+                    'HOMEPAGE'           => $member->institute->url,
+                    'STREET'             => $member->institute->strasse,
+                    'ZIPCODE'            => $member->institute->plz,
+                    'EMAIL'              => $member->institute->email,
+                    'PHONE'              => $member->institute->telefon,
+                    'FAX'                => $member->institute->fax,
+                    'TYPE'               => $GLOBALS['INST_TYPE'][$member->institute->type]['name'],
+                    'MEMBER_ROOM'        => $member->raum,
+                    'MEMBER_OFFICEHOURS' => $member->sprechzeiten,
+                    'MEMBER_PHONE'       => $member->telefon,
+                    'MEMBER_FAX'         => $member->fax,
+                    'MEMBER_ISSTANDARD'  => $member->externdefault,
+                    'MEMBER_GROUPPATHS' => Statusgruppen::getUserRoles($member->institute->id, $member->user_id)
+                ],
+                $this->getDatafieldMarkers($member));
+        }
+        return ['INSTITUTES' => $content];
+    }
+
+    protected function getUserContent($member)
+    {
+        if (Visibility::verify('picture', $member->user_id)) {
+            $avatar = Avatar::getAvatar($member->user_id);
+        } else {
+            $avatar = Avatar::getNobody();
+        }
+        $inst_member = $this->institute->members->findOneBy('user_id', $member->user_id);
+        $content = [
+            'FULLNAME'         => $member->user->getFullName(),
+            'LASTNAME'         => $member->user->Nachname,
+            'FIRSTNAME'        => $member->user->Vorname,
+            'TITLEFRONT'       => $member->user->title_front,
+            'TITLEREAR'        => $member->user->title_rear,
+            'USERNAME'         => $member->user->username,
+            'IMAGE_URL_SMALL'  => $avatar->getURL(Avatar::SMALL),
+            'IMAGE_URL_MEDIUM' => $avatar->getURL(Avatar::MEDIUM),
+            'IMAGE_URL_NORMAL' => $avatar->getURL(Avatar::NORMAL),
+            'PHONE'            => $inst_member->telefon,
+            'ROOM'             => $inst_member->raum,
+            'EMAIL'            => get_visible_email($member->user_id),
+            'HOMEPAGE_URL'     => Visibility::verify('homepage', $member->user_id) ? $member->user->home : '',
+            'OFFICEHOURS'      => $inst_member->sprechzeiten,
+
+        ];
+        if (Visibility::verify('lebenslauf', $member->user_id)) {
+            $content['CV'] = $member->user->lebenslauf;
+        }
+        if (Visibility::verify('schwerp', $member->user_id)) {
+            $content['RESEARCH_INTERESTS'] = $member->user->schwerp;
+        }
+        if (Visibility::verify('publi', $member->user_id)) {
+            $content['PUBLICATIONS'] = $member->user->publi;
+        }
+        $content = array_merge($content, $this->getContentSemesterCourses($member->user));
+        $content = array_merge($content, $this->getContentHomepagePlugins($member->user));
+        if (Visibility::verify('news', $member->user_id)) {
+            $content['NEWS'] = $this->getContentNews($member->user);
+        }
+        if (Visibility::verify('dates', $member->user_id)) {
+            $content['APPOINTMENTS'] = $this->getContentAppointments($member->user);
+        }
+        $content['OWNCATEGORIES'] = $this->getContentOwnCategories($member->user);
+        return $content;
+    }
+
+    /**
+     * Returns content array with courses grouped by semesters and markers as keys.
+     *
+     * @param User $user The current user object.
+     * @return array[] Array with semester and course data.
+     */
+    private function getContentSemesterCourses(User $user)
+    {
+        $content =  [];
+        $grouped_courses = $this->getUserCourses($user);
+        foreach ($grouped_courses as $semester_id => $courses) {
+            $content[] = array_merge([
+                'COURSES' => $this->getContentCourses($courses)
+            ], $this->getContentSemester($semester_id));
+        }
+        return ['SEMESTERS' => $content];
+    }
+
+    /**
+     * Returns data of given semester as content array.
+     *
+     * @param string $semester_id The id of the semester.
+     * @return array Array with semester data.
+     */
+    private function getContentSemester($semester_id)
+    {
+        $content = [];
+        $semester = Semester::find($semester_id);
+        if ($semester) {
+            $content = [
+                'NAME'        => $semester->name,
+                'SHORTNAME'   => $semester->semester_token,
+            ];
+        }
+        return $content;
+    }
+
+    private function getContentCourses($courses)
+    {
+        foreach ($courses as $course) {
+            $content[] = [
+                'TITLE'    => $course->name,
+                'SUBTITLE' => $course->untertitel,
+                'NUMBER'   => $course->VeranstaltungsNummer,
+                'ID'       => $course->id,
+            ];
+        }
+        return $content;
+    }
+
+    private function getContentNews(User $user)
+    {
+        $news = StudipNews::GetNewsByRange($user->id, true);
+        $content = [];
+        foreach ($news as $news_detail) {
+            $content[] = [
+                'BODY'  => $news_detail->body,
+                'DATE'  => $news_detail->date,
+                'TOPIC' => $news_detail->topic,
+            ];
+        }
+        return ['NEWS' => $content];
+    }
+
+    private function getContentAppointments (User $user)
+    {
+        if (!Config::get()->CALENDAR_ENABLE) {
+            return [];
+        }
+
+        $list_start = new DateTimeImmutable();
+        $list_end = $list_start->modify('+ 7 days');
+        $events = SingleCalendar::getEventList(
+            $user->id,
+            $list_start->getTimestamp(),
+            $list_end->getTimestamp(),
+            null,
+            ['class' => 'PUBLIC'],
+            ['CalendarEvent']
+        );
+
+        $content['APPOINTMENTS_START'] = $list_start->getTimestamp();
+        $content['APPOINTMENTS_END']   = $list_end->getTimestamp();
+        $content_events = [];
+        if (!empty($events)) {
+            foreach ($events as $event) {
+                if ($event->isDayEvent()) {
+                    $date = date('d.m.Y', $event->getStart()) . ' (' . _('ganztägig') . ')';
+                } else {
+                    $date = date('d.m.Y G:H:s', $event->getStart());
+                    if (date('dmY', $event->getStart()) === date('dmY', $event->getEnd())) {
+                        $date .= date('d.m.Y G:H:s', $event->getEnd());
+                    } else {
+                        $date .= ' - ' . date('d.m.Y G:H:s', $event->getEnd());
+                    }
+                }
+                $content_events[] = [
+                    'DATE'            => $date,
+                    'TITLE'           => $event->getTitle(),
+                    'DESCRIPTION'     => $event->getDescription(),
+                    'LOCATION'        => $event->getLocation(),
+                    'RECURRENCE'      => $event->toStringRecurrence(),
+                    'CATEGORY'        => $event->toStringCategories(),
+                    'PRIORITY'        => $event->toStringPriority(),
+                    'START'           => date('d.m.Y G:H:s', $event->getStart()),
+                    'END'             => date('d.m.Y G:H:s', $event->getEnd()),
+                    'TIMESTAMP_START' => $event->getStart(),
+                    'TIMESTAMP_END'   => $event->getEnd(),
+                ];
+            }
+        }
+        return array_merge($content, [
+            'APPOINTMENTS' => $content_events
+        ]);
+    }
+
+    /**
+     * Retrieves all visible homepage categories of the current user.
+     *
+     * @param User $user The current user.
+     * @return array[] The content with categories.
+     */
+    private function getContentOwnCategories(User $user)
+    {
+        $content = [];
+        $categories = Kategorie::findBySQL('`range_id` = ? ORDER BY `priority`', [$user->id]);
+        foreach ($categories as $category) {
+            if (Visibility::verify('kat_' . $category->id, $user->id)) {
+                $content[] = [
+                    'TITLE' => $category->name,
+                    'CONTENT' => $category->content
+                ];
+            }
+        }
+        return ['OWNCATEGORIES' => $content];
+    }
+
+    /**
+     * Returns content from Homepage Plugins.
+     *
+     * @param User $user
+     */
+    private function getContentHomepagePlugins(User $user)
+    {
+        $content = [];
+        $plugins = PluginEngine::getPlugins('HomepagePlugin');
+        foreach ($plugins as $plugin) {
+            $template = $plugin->getHomepageTemplate($user->id);
+            if ($template) {
+                $key_name = 'PLUGIN-' . mb_strtoupper($plugin->getPluginName());
+                $content[$key_name] = $template->render();
+            }
+        }
+        return $content;
+    }
+
+    public function getFullGroupNames()
+    {
+        $groups = [];
+        foreach ($this->institute->status_groups as $status_group) {
+            $groups[$status_group->id] = $status_group->name;
+            $groups = array_merge($groups, $this->getGroupPaths($status_group));
+        }
+        return $groups;
+    }
+
+    public function getGroupPaths($group, $seperator = ' > ', $pre = '')
+    {
+        $name = $pre
+            ? $pre . $seperator . $group->getName()
+            : $group->getName();
+        $result[$group->id] = $name;
+        if ($group->children) {
+            foreach ($group->children as $child) {
+                $result = array_merge($result, $this->getGroupPaths($child, $seperator, $name));
+            }
+        }
+        return $result;
+    }
+}
diff --git a/lib/extern/ExternPagePersons.php b/lib/extern/ExternPagePersons.php
new file mode 100644
index 00000000000..7872a89aa84
--- /dev/null
+++ b/lib/extern/ExternPagePersons.php
@@ -0,0 +1,205 @@
+<?php
+/**
+ * ExternPagePersons.php - Class to provide a list of members of institutes.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @since       5.4
+ */
+
+class ExternPagePersons extends ExternPage
+{
+
+    public $institute;
+
+    public function __construct($config)
+    {
+        parent::__construct($config);
+        $this->institute = Institute::find($this->page_config->range_id);
+    }
+
+    public function getSortFields(): array
+    {
+        return [
+            'vorname'     => _('Vorname'),
+            'nachname'    => _('Nachname'),
+            'email'       => _('E-Mail'),
+            'title_front' => _('Titel vorangestellt'),
+            'title_rear'  => _('Titel nachgestellt')
+        ];
+    }
+
+    public function getDataFields($object_classes = []): array
+    {
+        return parent::getDataFields(
+            [
+                'user',
+                'userinstrole'
+            ]
+        );
+    }
+
+    public function getConfigFields($as_array = false)
+    {
+        $args = '
+            sort          option,
+            grouping      bool,
+            language      option,
+            groupsvisible intArray,
+            groupsalias   getArray,
+            escaping      option
+        ';
+        return $as_array ? self::argsToArray($args) : $args;
+    }
+
+    public function getAllowedRequestParams($as_array = false)
+    {
+        $params = [
+            'grouping',
+            'language',
+            'sort',
+        ];
+        return $as_array ? $params : implode(',', $params);
+    }
+
+    public function getMarkersContents(): array
+    {
+        if ($this->grouping) {
+            return  [
+                'GROUPS' => $this->getGroupedContent()
+            ];
+        } else {
+            return [
+                'PERSONS' => $this->getContentUsers()
+            ];
+        }
+    }
+
+    protected function getContentUsers()
+    {
+        $content = [];
+        foreach ($this->institute->members->orderBy($this->sort) as $member) {
+            $content[] = $this->getUserContent($member);
+        }
+        return $content;
+    }
+
+    /**
+     * Returns all marker content for grouped view.
+     *
+     * @return array The array with all markers.
+     */
+    protected function getGroupedContent()
+    {
+        $content = [];
+        foreach ($this->institute->status_groups->orderBy('position') as $top_group) {
+            foreach ($this->getAllChildren($top_group) as $group) {
+                if ($this->groupsvisible[$group->id]) {
+                    if ($this->groupsalias[$group->id]) {
+                        $grouptitle_substitute = $this->groupsalias[$group->id];
+                    } else {
+                        $grouptitle_substitute = '';
+                    }
+                    $content[] = [
+                        'GROUPTITLE'            => $group->name,
+                        'GROUPTITLE_SUBSTITUTE' => $grouptitle_substitute,
+                        'PERSONS'               => $this->getContentGroupedUsers($group->members),
+                    ];
+                }
+            }
+        }
+        return $content;
+    }
+
+    private function getContentGroupedUsers($members)
+    {
+        $content = [];
+        foreach ($members as $member) {
+            $content[] = $this->getUserContent($member);
+        }
+        return $content;
+    }
+
+    /**
+     * Returns all child groups of a group.
+     *
+     * @param Statusgruppen $group The parent group.
+     * @return Statusgruppen[] All child groups.
+     */
+    protected function getAllChildren(Statusgruppen $group)
+    {
+        $all_groups[] = $group;
+        foreach ($group->getChildren() as $child) {
+            $all_groups = array_merge($all_groups, $this->getAllChildren($child));
+        }
+        return $all_groups;
+    }
+
+    /**
+     * Get content of a single user.
+     *
+     * @param StatusgruppeUser $member
+     * @return array
+     */
+    protected function getUserContent($member)
+    {
+        if (Visibility::verify('picture', $member->user_id) == 5) {
+            $avatar = Avatar::getAvatar($member->user_id);
+        } else {
+            $avatar = Avatar::getNobody();
+        }
+        $inst_member = $this->institute->members->findOneBy('user_id', $member->user_id);
+        $content = array_merge(
+            [
+                'FULLNAME'         => $member->user->getFullName(),
+                'LASTNAME'         => $member->user->Nachname,
+                'FIRSTNAME'        => $member->user->Vorname,
+                'TITLEFRONT'       => $member->user->title_front,
+                'TITLEREAR'        => $member->user->title_rear,
+                'USERNAME'         => $member->user->username,
+                'ID'               => $member->user_id,
+                'IMAGE_URL_SMALL'  => $avatar->getURL(Avatar::SMALL),
+                'IMAGE_URL_MEDIUM' => $avatar->getURL(Avatar::MEDIUM),
+                'IMAGE_URL_NORMAL' => $avatar->getURL(Avatar::NORMAL),
+                'PHONE'            => $inst_member->telefon,
+                'ROOM'             => $inst_member->raum,
+                'EMAIL'            => get_visible_email($member->user->user_id),
+                'HOMEPAGE_URL'     => Visibility::verify('homepage', $member->user_id) ? $member->user->home : '',
+                'OFFICEHOURS'      => $inst_member->sprechzeiten
+            ],
+            $this->getDatafieldMarkers($member->user),
+            $this->getDatafieldMarkers($member));
+        return $content;
+    }
+
+    public function getFullGroupNames()
+    {
+        $groups = [];
+        foreach ($this->institute->status_groups as $status_group) {
+            $groups[$status_group->id] = $status_group->name;
+            $groups = array_merge($groups, $this->getGroupPaths($status_group));
+        }
+        return $groups;
+    }
+
+    public function getGroupPaths($group, $seperator = ' > ', $pre = '')
+    {
+        $name = $pre
+            ? $pre . $seperator . $group->getName()
+            : $group->getName();
+        $result[$group->id] = $name;
+        if ($group->children) {
+            foreach ($group->children as $child) {
+                $result = array_merge($result, $this->getGroupPaths($child, $seperator, $name));
+            }
+        }
+        return $result;
+    }
+
+}
diff --git a/lib/extern/ExternPageTimetable.php b/lib/extern/ExternPageTimetable.php
new file mode 100644
index 00000000000..1035411d33a
--- /dev/null
+++ b/lib/extern/ExternPageTimetable.php
@@ -0,0 +1,319 @@
+<?php
+/**
+ * ExternPageTimetable.php - Class to provide course dates
+ * to show as a timetable.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @since       5.4
+ */
+
+class ExternPageTimetable extends ExternPage
+{
+    /**
+     * @var int The start time
+     */
+    private $start_time = 0;
+
+    /**
+     * @var int The end time
+     */
+    private $end_time = 0;
+
+    /**
+     * @see ExternPage::getSortFields()
+     * @return array Array of field names as keys and spoken names as values.
+     */
+    public function getSortFields() : array
+    {
+        return [];
+    }
+
+    public function getConfigFields(bool $as_array = false)
+    {
+        $fields = '
+            language       option,
+            date,
+            date_offset    option,
+            range_count    int,
+            time_range     option,
+            participating  int,
+            categories     optionArray,
+            studyareas     optionArray,
+            scope_kids     int,
+            institutes     optionArray,
+            sublevels      int,
+            semtypes       optionArray,
+            event_types    optionArray,
+            escaping
+        ';
+        return $as_array ? self::argsToArray($fields) : $fields;
+    }
+
+    public function getAllowedRequestParams(bool $as_array = false)
+    {
+        $params = [
+            'language',
+            'date',
+            'event_types'
+        ];
+        return $as_array ? $params : implode(',', $params);
+    }
+
+    public function getMarkersContents(): array
+    {
+        return $this->getContent();
+    }
+
+    /**
+     * Returns select-options for time ranges.
+     *
+     * @return array Array with select-options.
+     */
+    public function getTimeRangeOptions(): array
+    {
+        return [
+            'days'      => _('Tage'),
+            'weeks'     => _('Wochen'),
+            'months'    => _('Monate'),
+            'years'     => _('Jahre'),
+            'semesters' => _('Semester')
+        ];
+    }
+
+    /**
+     * Returns select-options for date offsets.
+     *
+     * @return array Array with select-options.
+     */
+    public function getDateOffsetOptions(): array
+    {
+        return [
+            'start_date'    => _('Angegebenes Startdatum'),
+            'current_date'  => _('Aktuelles Datum'),
+            'next_semester' => _('Nächstes Semester'),
+            'next_week'     => _('Nächste Woche'),
+            'next_month'    => _('Nächster Monat'),
+            'next_year'     => _('Nächstes Jahr')
+        ];
+    }
+
+    private function getDates(): SimpleCollection
+    {
+        $params = [];
+        $query = "
+            SELECT
+                `termine`.*
+            FROM
+                `termine`
+                LEFT JOIN `seminare`
+                    ON `termine`.`range_id` = `seminare`.`Seminar_id`
+                LEFT JOIN `seminar_sem_tree`
+                    ON `seminare`.`Seminar_id` = `seminar_sem_tree`.`seminar_id`
+                LEFT JOIN `seminar_inst`
+                    ON `seminare`.`Seminar_id` = `seminar_inst`.`Seminar_id`";
+        $query .= "
+            WHERE (`termine`.`date` >= :start AND `termine`.`date` <= :end) "
+            . $this->getEventTypeSQL($params)
+            . $this->getScopesSQL($params, $this->studyareas, (bool) $this->scope_kids)
+            . $this->getInstitutesSQL($params)
+            . $this->getSemtypesSQL($params) .
+            ' GROUP BY `termin_id` ORDER BY `date` ASC';
+        $params[':start'] = $this->getStartTime();
+        $params[':end']   = $this->getEndTime();
+        return SimpleCollection::createFromArray(DBManager::get()->fetchAll(
+            $query, $params, 'CourseDate::buildExisting'));
+    }
+
+    private function getEventTypeSQL(&$params): string
+    {
+        if ($this->event_types) {
+            $params[':event_types'] = $this->event_types;
+            return ' AND `termine`.`date_typ` IN (:event_types) ';
+        }
+        return '';
+    }
+
+    private function getSemtypesSQL(&$params): string
+    {
+        if ($this->semtypes) {
+            $params[':semtypes'] = $this->semtypes;
+            return ' AND `seminare`.`status` IN (:semtypes) ';
+        }
+        return '';
+    }
+
+    /**
+     * Calculates the start time from given config parameters.
+     *
+     * @return int The start time as unix timestamp.
+     */
+    private function getStartTime(): int
+    {
+        if ($this->start_time !== 0) {
+            return $this->start_time;
+        }
+        $time = new DateTime();
+        switch ($this->date_offset) {
+            case 'start_date':
+                $time = DateTime::createFromFormat('d.m.Y', $this->date);
+                break;
+            case 'current_semester':
+                $semester = Semester::findCurrent();
+                $time->setTimestamp($semester->beginn);
+            case 'next_semester':
+                $semester = Semester::findNext();
+                $time->setTimestamp($semester->beginn);
+                break;
+            case 'next_week':
+                $time->modify('monday');
+                break;
+            case 'next_month':
+                $time->modify('first day of next month');
+                break;
+            case 'next_year':
+                $time->modify('first day of next year');
+        }
+        $this->start_time = $time->setTime(0, 0)->getTimestamp();
+        return $this->start_time;
+    }
+
+    /**
+     * Calculates the end time from config parameters.
+     *
+     * @return int The end time as unix timestamp.
+     */
+    private function getEndTime(): int
+    {
+        if ($this->end_time !== 0) {
+            return $this->end_time;
+        }
+        $time = new DateTime();
+        $start_time = $this->getStartTime();
+        if ($this->time_range === 'semester') {
+            $semester = Semester::findByTimestamp($start_time);
+            $i = $this->range_count;
+            while (--$i > 0) {
+                $next_semester = Semester::findNext($semester->beginn);
+                if (!is_null($next_semester)) {
+                    $semester = $next_semester;
+                }
+            }
+            $time->setTimestamp($semester->end);
+        } else {
+            $time->setTimestamp($start_time);
+            $count = $this->range_count - 1;
+            switch ($this->time_range) {
+                case 'days':
+                    $time->modify(sprintf('+%s days', $count));
+                    break;
+                case 'weeks':
+                    $time->modify(sprintf('Sunday +%s weeks', $count));
+                    break;
+                case 'years':
+                    $time->modify('31 dec');
+                    $time->modify(sprintf('+%s years', $count));
+            }
+        }
+        $this->end_time = $time->setTime(23, 59)->getTimestamp();
+        return $this->end_time;
+    }
+
+    protected function getContent()
+    {
+        $count = 0;
+        foreach ($this->getDates() as $date) {
+            $day = new DateTime();
+            $day->setTimestamp($date->date)->setTime(0, 0);
+            $day_timestamp = $day->getTimestamp();
+            $date_content[$day_timestamp]['DAY'] = $day_timestamp;
+            $date_content[$day_timestamp]['DATES'][] = $this->getDateContent($date);
+            $count++;
+        }
+        return [
+            'START'         => $this->start_time,
+            'END'           => $this->end_time,
+            'COUNT_DATES'   => $count,
+            'GROUPED_DATES' => $date_content
+        ];
+    }
+
+    private function getDateContent(CourseDate $date)
+    {
+        $date_content = [
+            'COURSE'      => $this->getCourseContent($date),
+            'START'       => $date->date,
+            'END'         => $date->end_time,
+            'ROOM'        => $date->raum,
+            'TYPE'        => $GLOBALS['TERMIN_TYP'][$date->date_typ]['name'],
+            'LECTURERS'   => $this->getLecturers($date),
+            'TOPICS'      => $this->getTopics($date),
+            'BOOKED_ROOM' => $this->getBookedRoomData($date)
+        ];
+        return $date_content;
+    }
+
+    private function getCourseContent(CourseDate $date): array
+    {
+        return [
+            'TITLE'        => $date->course->name,
+            'FULLTITLE'    => $date->course->getFullname(),
+            'SUBTITLE'     => $date->course->untertitel,
+            'NUMBER'       => $date->course->veranstaltungsnummer,
+            'SEMESTER'     => $date->course->getFullname('sem-duration-name'),
+            'AVATAR_URL'   => $date->course->getItemAvatarURL(),
+            'INFO_URL'     => $date->course->getItemURL(),
+            'SEMTYPENAME'  => $GLOBALS['SEM_TYPE'][$date->course->status]['name'],
+            'SEMCLASSNAME' =>
+                $GLOBALS['SEM_CLASS'][$GLOBALS['SEM_TYPE'][$date->course->status]['class']]['name'],
+            'ID'           => $date->course->id,
+            'LECTURERS'    => $this->getContentMembers($date->course, 'dozent')
+        ];
+    }
+
+    private function getLecturers(CourseDate $date): array
+    {
+        $lecturers_content = [];
+        foreach ($date->dozenten as $lecturer) {
+            $lecturers_content[] = [
+                'LASTNAME'  => $lecturer->nachname,
+                'FIRSTNAME' => $lecturer->vorname,
+                'FULLNAME'  => $lecturer->getFullname(),
+                'ID'        => $lecturer->id,
+                'EMAIL'     => $lecturer->email
+            ];
+
+        }
+        return $lecturers_content;
+    }
+
+    private function getTopics(CourseDate $date): array
+    {
+        $topics_content = [];
+        foreach ($date->topics as $topic) {
+            $topics_content[] = [
+                'TITLE'       => $topic->title,
+                'DESCRIPTION' => $topic->description
+            ];
+        }
+        return $topics_content;
+    }
+
+    private function getBookedRoomData(CourseDate $date): array
+    {
+        if ($date->room_booking) {
+            return [
+                'NAME' => $date->room_booking->resource->name,
+                'ID'   => $date->room_booking->resource->id
+            ];
+        }
+        return [];
+    }
+
+}
diff --git a/lib/extern/admin_extern.inc.php b/lib/extern/admin_extern.inc.php
deleted file mode 100644
index fd436c440d4..00000000000
--- a/lib/extern/admin_extern.inc.php
+++ /dev/null
@@ -1,438 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* admin_extern.inc.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       extern
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// admin_extern.inc.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-use Studip\Button, Studip\LinkButton;
-
-include('lib/seminar_open.php'); // initialise Stud.IP-Session
-
-
-// -- here you have to put initialisations for the current page
-
-if (Request::option('view') == 'extern_global') {
-    $range_id = 'studip';
-    URLHelper::addLinkParam('view', 'extern_global');
-} else {
-    $range_id = Context::getId();
-    URLHelper::addLinkParam('view', 'extern_inst');
-}
-URLHelper::addLinkParam('cid', $range_id);
-$config_id = Request::option('config_id');
-// when downloading a config, do it here and stop afterwards
-if (Request::get('com') == 'download_config') {
-    if ($range_id) {
-        download_config($range_id, $config_id, Request::quoted('module'));
-        page_close();
-        exit;
-    }
-}
-
-PageLayout::setTitle(_("Verwaltung externer Seiten"));
-
-if ($range_id != 'studip') {
-    Navigation::activateItem('/admin/institute/external');
-    require_once 'lib/admin_search.inc.php';
-} else {
-    Navigation::activateItem('/admin/locations/external');
-}
-$mod=Request::quoted('mod');//Change header_line if open object
-if (Context::getId()) {
-    PageLayout::setTitle(Context::getHeaderLine()." - ".PageLayout::getTitle());
-    foreach ($GLOBALS['EXTERN_MODULE_TYPES'] as $key => $type) {
-        if ($type["module"] == $mod) {
-            PageLayout::setTitle(PageLayout::getTitle() . " ({$GLOBALS['EXTERN_MODULE_TYPES'][$key]['name']})");
-            break;
-        }
-    }
-}
-
-// upload of configuration
-if (Request::option('com') == "do_upload_config") {
-    $file_content = file_get_contents($_FILES['the_file']['tmp_name']);
-
-    // revert the changes done by indentJson
-    $file_content_wo_tabs = str_replace("\t", '', str_replace("\n", '', $file_content));
-
-    $jsonconfig = json_decode($file_content_wo_tabs, true);
-
-    if (!check_config($jsonconfig, Request::quoted('check_module'))) {
-        PageLayout::postError(_('Die Konfigurationsdatei hat den falschen Modultyp!'));
-    } else if (!store_config($range_id, $config_id, $jsonconfig)) {
-        PageLayout::postError(_('Die Konfigurationsdatei konnte nicht hochgeladen werden!'));
-    } else {
-        PageLayout::postSuccess(_('Die Datei wurde erfolgreich übertragen!'));
-    }
-}
-
-//Output starts here
-
-ob_start();
-
-// copy existing configuration
-if (Request::option('com') == 'copyconfig') {
-    if (Request::option('copyinstid') && Request::option('copyconfigid')) {
-        $config = ExternConfig::GetInstance(Request::option('copyinstid'), '', Request::option('copyconfigid'));
-        $config_copy = $config->copy($range_id);
-        echo MessageBox::success(sprintf(_("Die Konfiguration wurde als \"%s\" nach Modul \"%s\" kopiert."),
-                htmlReady($config_copy->getConfigName()),
-                htmlReady($GLOBALS['EXTERN_MODULE_TYPES'][$config_copy->getTypeName()]['name'])));
-    } else {
-        Request::set('com','');
-    }
-}
-
-if (Request::option('com') == 'delete') {
-    $config = ExternConfig::GetInstance($range_id, '', $config_id);
-    if ($config->deleteConfiguration()) {
-        echo MessageBox::success(sprintf(_("Konfiguration <strong>\"%s\"</strong> für Modul <strong>\"%s\"</strong> gelöscht!"),
-                htmlReady($config->getConfigName()),
-                htmlReady($GLOBALS['EXTERN_MODULE_TYPES'][$config->getTypeName()]['name'])));
-    } else {
-        echo MessageBox::error(_("Konfiguration konnte nicht gelöscht werden"));
-    }
-}
-
-
-
-if (Request::option('com') == 'delete_sec') {
-    $config = ExternConfig::GetConfigurationMetaData($range_id, $config_id);
-
-    $message = sprintf(_("Wollen Sie die Konfiguration <b>&quot;%s&quot;</b> des Moduls <b>%s</b> wirklich löschen?"), $config["name"], $GLOBALS["EXTERN_MODULE_TYPES"][$config["type"]]["name"]);
-    $message .= '<br><br>';
-    $message .= LinkButton::createAccept("JA", URLHelper::getURL('?com=delete&config_id='.$config_id));
-    $message .= LinkButton::createCancel("NEIN", URLHelper::getURL('?list=TRUE&view=extern_inst'));
-
-    echo MessageBox::info($message);
-
-    $template = $GLOBALS['template_factory']->open('layouts/base.php');
-    $template->content_for_layout = ob_get_clean();
-    echo $template->render();
-    page_close();
-    die;
-}
-
-if (Request::option('com') == 'info') {
-    include 'lib/extern/views/extern_info_module.inc.php';
-
-    $template = $GLOBALS['template_factory']->open('layouts/base.php');
-    $template->content_for_layout = ob_get_clean();
-    echo $template->render();
-    page_close();
-    die;
-}
-
-if (Request::option('com') == 'new' || Request::option('com') == 'edit' || Request::option('com') == 'open' ||
-        Request::option('com') == 'close' || Request::option('com') == 'store') {
-
-    require_once "lib/extern/views/extern_edit_module.inc.php";
-
-    $template = $GLOBALS['template_factory']->open('layouts/base.php');
-    $template->content_for_layout = ob_get_clean();
-    echo $template->render();
-    page_close();
-    die;
-}
-
-// Some browsers don't reload the site by clicking the same link twice again.
-// So it's better to use different commands to do the same job.
-if (Request::option('com') == 'set_default' || Request::option('com') == 'unset_default') {
-    if (!ExternConfig::SetStandardConfiguration($range_id, $config_id)) {
-        page_close();
-        exit;
-    }
-}
-
-if (Config::get()->EXTERN_SRI_ENABLE_BY_ROOT && Request::option('com') == 'enable_sri' && $GLOBALS['perm']->have_perm('root')) {
-    enable_sri($range_id, Request::quoted('sri_enable'));
-}
-
-
-if (Config::get()->EXTERN_SRI_ENABLE_BY_ROOT && $GLOBALS['perm']->have_perm('root')) {
-    echo '<form method="post" action="' . URLHelper::getLink('?com=enable_sri') . '">';
-    echo CSRFProtection::tokenTag();
-    echo '<blockquote>';
-    echo _("SRI-Schnittstelle freigeben");
-    echo ' <input type="checkbox" name="sri_enable" value="1"';
-    if (sri_is_enabled($range_id)) {
-        echo ' checked="checked"';
-    }
-    echo '>';
-
-    echo Button::createAccept();
-
-    echo "</blockquote></form>";
-}
-
-$configurations = ExternConfig::GetAllConfigurations($range_id);
-$module_types_ordered = ExternModule::GetOrderedModuleTypes();
-
-$choose_module_form = '';
-foreach ($module_types_ordered as $i) {
-    if (isset($configurations[$GLOBALS['EXTERN_MODULE_TYPES'][$i]['module']])) {
-        $count = count($configurations[$GLOBALS['EXTERN_MODULE_TYPES'][$i]['module']]);
-        $have_config = TRUE;
-    } else {
-        $count = 0;
-    }
-    if ($i && $count < $EXTERN_MAX_CONFIGURATIONS && ExternModule::HaveAccessModuleType(Request::option('view'), $i)) {
-        $choose_module_form .= "<option value=\"{$GLOBALS['EXTERN_MODULE_TYPES'][$i]['module']}\">"
-                . $GLOBALS['EXTERN_MODULE_TYPES'][$i]['name'] . "</option>\n";
-    }
-}
-
-$sidebar = Sidebar::get();
-
-$widget = new ActionsWidget();
-$widget->addLink(
-    _('Neue globale Konfiguration'),
-    URLHelper::getURL('?com=new&mod=Global'),
-    Icon::create('link-intern', 'clickable')
-);
-
-$sidebar->addWidget($widget);
-
-// cho LinkButton::create(_(" anlegen"), URLHelper::getURL('?com=new&mod=Global'));
-
-if ($choose_module_form != '') {
-    if (Request::option('com') != 'copychoose') {
-        echo '<form method="post" action="' . URLHelper::getLink('?com=new') . '" class="default">';
-        echo CSRFProtection::tokenTag();
-        echo "<fieldset><legend>"
-            ._("Neue Konfiguration für Modul")
-            . "</legend>\n";
-
-        echo "<label>
-                Modul
-            <select name=\"mod\" class=\"size-m\">\n$choose_module_form</select>
-            </label>\n";
-        echo "</fieldset>\n";
-        echo "<footer>" . Button::create(_("Anlegen")) . "</footer>\n";
-        echo "</form><br>\n";
-
-        $conf_institutes = ExternConfig::GetInstitutesWithConfigurations(($GLOBALS['perm']->have_perm('root') && Request::option('view') == 'extern_global') ? 'global' : ['inst', 'fak']);
-        if (is_array($conf_institutes) && count($conf_institutes)) {
-            echo '<form method="post" action="' . URLHelper::getLink('?com=copychoose') . '" class="default">';
-            echo CSRFProtection::tokenTag();
-            echo "<fieldset>";
-            echo "<legend>" . _("Konfiguration kopieren") . "</legend>";
-
-            $choose_institute_copy = "<select name=\"copychooseinst\" class=\"nested-select size-m\">\n";
-            foreach ($conf_institutes as $conf_institute) {
-                $choose_institute_copy .= sprintf("<option value=\"%s\" class=\"%s\">%s</option>\n", $conf_institute['institut_id'], ($conf_institute['fakultaets_id'] == $conf_institute['institut_id'] ? 'nested-item-header' : 'nested-item'), htmlReady(mb_strlen($conf_institute['name']) > 60 ? substr_replace($conf_institute['name'], '[...]', 30, -30) : $conf_institute['name']));
-            }
-            $choose_institute_copy .= "</select>\n";
-
-            echo '<label>';
-            echo _('Einrichtung');
-            echo $choose_institute_copy;
-            echo '</label>';
-            echo "</fieldset>\n";
-
-            echo "<footer>" . Button::create(_("Weiter") . " >>", 'continue') . "</footer>\n";
-            echo "</form><br>\n";
-        }
-    } else {
-        if (Request::option('com') == 'copychoose') {
-            $choose_module_select = "<select name=\"copyconfigid\" class=\"nested-select\">\n";
-            $configurations_copy = ExternConfig::GetAllConfigurations(Request::option('copychooseinst'));
-            foreach ($module_types_ordered as $module_type) {
-                $print_module_name = TRUE;
-
-                if (is_array($configurations_copy[$GLOBALS['EXTERN_MODULE_TYPES'][$module_type]['module']])) {
-                    foreach ($configurations_copy[$GLOBALS['EXTERN_MODULE_TYPES'][$module_type]['module']] as $config_id_copy => $config_data_copy) {
-                        if ($print_module_name) {
-                            $choose_module_select .= '<optgroup class="nested-item-header" label="' . htmlReady($GLOBALS['EXTERN_MODULE_TYPES'][$module_type]['name']) . '">';
-                        }
-                        $choose_module_select .= '<option value="' . $config_id_copy . '" class="nested-item">' . htmlReady($config_data_copy['name']) . '</option>';
-                        $print_module_name = FALSE;
-                    }
-                }
-            }
-
-            echo '<form method="post" action="' . URLHelper::getLink('?com=copyconfig') . '" class="default">';
-            echo CSRFProtection::tokenTag();
-            echo "<fieldset>";
-            echo "<legend>" . _("Konfiguration kopieren") . "</legend>";
-
-            $iid = Request::get('copychooseinst');
-            echo '<label>' . _('Einrichtung');
-            echo '<div>' . htmlReady(get_object_name($iid, 'inst')['name']) . '</div>';
-            echo '</label>';
-            echo '<label>' . _('Konfiguration');
-            echo $choose_module_select . '</select>';
-            echo '</label>';
-            echo "</fieldset>\n";
-
-            echo "<footer>\n";
-            echo LinkButton::create("<< " . _("Zurück"), URLHelper::getURL('?list=TRUE&view=extern_inst'));
-            echo Button::create(_("Kopieren"));
-            echo "<input type=\"hidden\" name=\"copyinstid\" value=\"" . htmlReady(Request::quoted('copychooseinst')) . "\">\n";
-            echo "</footer>\n";
-            echo "</form>\n";
-
-        }
-    }
-}
-else {
-    echo "<blockquote>";
-    echo _("Sie haben bereits für alle Module die maximale Anzahl von Konfigurationen angelegt. Um eine neue Konfiguration anzulegen, müssen Sie erst eine bestehende im gewünschten Modul löschen.");
-    echo "</blockquote>\n";
-}
-
-
-if (empty($have_config)) {
-    echo "<blockquote>\n";
-    echo _("Es wurden noch keine Konfigurationen angelegt.");
-    echo "</blockquote>";
-} else {
-    echo "<table class=\"default\">\n";
-    echo "<caption>\n";
-    echo _("Angelegte Konfigurationen");
-    echo "</caption>\n";
-
-    foreach ($module_types_ordered as $order) {
-        $module_type = $GLOBALS['EXTERN_MODULE_TYPES'][$order];
-        if (isset($configurations[$module_type["module"]])) {
-
-            echo "<thead>\n";
-            echo "<tr>\n<th colspan=\"2\">";
-
-            if (isset($configurations[$module_type["module"]][$config_id])) {
-                echo "<a name=\"anker\"></a>\n";
-            }
-            echo $module_type["name"];
-
-            echo "</th></tr>\n</thead>\n";
-            echo "<tbody>\n";
-
-
-            foreach ($configurations[$module_type["module"]] as $configuration) {
-                echo "<tr><td style=\"width: 65%\">";
-                echo $configuration["name"];
-                if ($configuration['is_default']) {
-                    echo ' (' . _('Standard') . ')';
-                }
-                echo "</td>\n";
-                $actionMenu = ActionMenu::get();
-                $actionMenu->addLink(
-                        URLHelper::getURL('?com=download_config&config_id='. $configuration['id'] .'&module='. $module_type['module']),
-                        _('Konfigurationsdatei herunterladen'),
-                        Icon::create('download', 'clickable', ['title' => _('Konfigurationsdatei herunterladen')]));
-
-                $actionMenu->addLink(
-                        URLHelper::getURL('?com=upload_config&config_id='. $configuration['id']),
-                        _('Konfigurationsdatei hochladen'),
-                        Icon::create('upload', 'clickable', ['title' => _('Konfigurationsdatei hochladen')]));
-                $actionMenu->addLink(
-                        URLHelper::getURL('?com=info&config_id=' . $configuration['id']),
-                        _('weitere Informationen anzeigen'),
-                        Icon::create('infopage', 'clickable', ['title' => _('weitere Informationen anzeigen')]));
-
-
-                // Switching for the is_default option. Read the comment above.
-                if ($configuration["is_default"]) {
-                    $actionMenu->addLink(
-                            URLHelper::getURL('?com=unset_default&config_id=' . $configuration['id']) . '#anker',
-                            _('Standard entziehen'),
-                            Icon::create('checkbox-checked', 'clickable', ['title' => _('Standard entziehen')]));
-                } else {
-                    $actionMenu->addLink(
-                            URLHelper::getURL('?com=set_default&config_id=' . $configuration['id']) . '#anker',
-                            _('Standard zuweisen'),
-                            Icon::create('checkbox-checked', 'clickable', ['title' => _('Standard zuweisen')]));
-                }
-
-                $actionMenu->addLink(
-                        URLHelper::getURL('?com=delete_sec&config_id=' . $configuration['id']) . '#anker',
-                        _('Konfiguration löschen'),
-                        Icon::create('trash', 'clickable', ['title' => _('Konfiguration löschen')]));
-                $actionMenu->addLink(
-                        URLHelper::getURL('?com=edit&mod=' . $module_type['module'] . '&config_id=' . $configuration['id']),
-                        _('Konfiguration bearbeiten'),
-                        Icon::create('edit', 'clickable', ['title' => _('Konfiguration bearbeiten')]));
-                ?>
-                <?
-                echo "<td class=\"actions\" style=\"width: 20%\" ";
-                echo ">\n";
-                echo $actionMenu->render();
-                echo "</td></tr>\n";
-
-                if (Request::option('com') == 'upload_config' && Request::option('config_id') == $configuration['id']) {
-                    $template = $GLOBALS['template_factory']->open('extern/upload_form');
-                    $template->set_attribute('module', $module_type['module']);
-                    $template->set_attribute('config_id', $configuration['id']);
-                    $template->set_attribute('max_filesize', 1024 * 100); // currently 100kb
-
-                    echo $template->render();
-                }
-            }
-        }
-
-    }
-}
-echo "</table>\n";
-
-$info_max_configs = sprintf(_("Sie können pro Modul maximal %s Konfigurationen anlegen."),
-        $EXTERN_MAX_CONFIGURATIONS);
-
-Helpbar::get()->addPlainText(_('Information'), sprintf(_("Sie können pro Modul maximal %s Konfigurationen anlegen."),
-        $EXTERN_MAX_CONFIGURATIONS));
-
-if (is_array($configurations) && count($configurations)) {
-
-    Helpbar::get()->addPlainText(_('Standard-Konfiguration'),
-            _('Dieses Symbol kennzeichnet die Standard-Konfiguration, die zur Formatierung herangezogen wird, wenn Sie beim Aufruf dieses Moduls keine Konfiguration angeben.'),
-            Icon::create('checkbox-checked'));
-    Helpbar::get()->addPlainText(_('Keine Standard-Konfiguration'),
-            _('Wenn Sie keine Konfiguration als Standard ausgewählt haben, wird die Stud.IP-Konfiguration verwendet.'),
-            Icon::create('info'));
-    Helpbar::get()->addPlainText(_('Standard-Konfiguration zuweisen'),
-            _('Klicken Sie auf diesen Button, um eine Konfiguration zur Standard-Konfiguration zu erklären.'),
-            Icon::create('checkbox-unchecked'));
-    Helpbar::get()->addPlainText(_('Weitere Informationen'),
-            _('Klicken Sie auf diesen Button um weitere Informationen über diese Konfiguration zu erhalten. Hier finden Sie auch die Links, über die Sie die Module in Ihrer Website einbinden können.'),
-            Icon::create('infopage'));
-
-}
-
-//print_footer();
-
-$template = $GLOBALS['template_factory']->open('layouts/base.php');
-$template->content_for_layout = ob_get_clean();
-echo $template->render();
-page_close();
diff --git a/lib/extern/elements/ExternElementBody.class.php b/lib/extern/elements/ExternElementBody.class.php
deleted file mode 100644
index 8b17b9eba32..00000000000
--- a/lib/extern/elements/ExternElementBody.class.php
+++ /dev/null
@@ -1,66 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementBody.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElement
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementBody.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementBody extends ExternElement {
-
-    var $attributes = ["body_bgcolor", "body_text", "body_link", "body_vlink",
-            "body_alink", "body_background", "body_class", "body_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "Body";
-        $this->real_name = _("Seitenkörper");
-        $this->description = _("Eigenschaften des Seitenkörpers (HTML-Tag &gt;body&lt;).");
-    }
-
-    function toString ($args = null) {
-        $out = "\n" . $this->config->getTag($this->name, "body");
-        $out .= $args["content"] . "</body>\n";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementContact.class.php b/lib/extern/elements/ExternElementContact.class.php
deleted file mode 100644
index 996addd2b6c..00000000000
--- a/lib/extern/elements/ExternElementContact.class.php
+++ /dev/null
@@ -1,170 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementContact.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementContact
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementContact.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementContact extends ExternElement {
-
-    var $attributes = ["order", "visible", "aliases", "headline", "adradd", "table_width",
-                "table_align", "table_border", "table_bgcolor", "table_bordercolor", "table_cellpadding",
-                "table_cellspacing", "table_class", "table_style", "tr_class",
-                "tr_style", "td_height", "td_align", "td_valign", "td_bgcolor", "td_class", "td_style",
-                "fonttitle_face", "fonttitle_size", "fonttitle_color", "fonttitle_class",
-                "fonttitle_style", "fontcontent_face", "fontcontent_size", "fontcontent_color",
-                "fontcontent_class", "fontcontent_style", "hidepersname", "hideinstname", "separatelinks",
-                "showinstgroup", "defaultadr"];
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct() {
-        $this->name = "Contact";
-        $this->real_name = _("Name, Anschrift, Kontakt");
-        $this->description = _("Allgemeine Angaben zum und Formatierung des Kontaktfeldes (Anschrift, E-Mail, Homepage usw.).");
-    }
-
-    function getDefaultConfig () {
-
-        $config = [
-            "order" => "|0|1|2|3|4|5",
-            "visible" => "|1|1|1|1|1|1",
-            "aliases" => "|"._("Raum").":|"._("Telefon").":|"._("Fax").":|"._("E-Mail").":|"
-                    ._("Homepage").":|"._("Sprechzeiten").":",
-            "headline" => _("Kontakt").":",
-            "adrradd" => "",
-            "hidepersname" => "",
-            "hideinstname" => "",
-            "separatelinks" => "",
-            "showinstgroup" => "",
-            "defaultadr" => ""
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Aufbau der Adress- und Kontakt-Tabelle"));
-        $field_names = [_("Raum"), _("Telefon"), _("Fax"), _("E-Mail"), _("Homepage"), _("Sprechzeiten")];
-        $table = $edit_form->editMainSettings($field_names, "", ["width", "sort", "widthpp"]);
-
-        $title = _('Ãœberschrift') . ':';
-        $info = _("Ãœberschrift der Kontakt-Daten");
-        $table .= $edit_form->editTextfieldGeneric("headline", $title, $info, 35, 100);
-
-        $title = _('Standard-Adresse') . ':';
-        $info = _("Wenn Sie diese Option wählen, wird die Standard-Adresse ausgegeben, die jede(r) Mitarbeiter(in) bei seinen universitären Daten auswählen kann. Wählen Sie diese Option nicht, wenn immer die Adresse der Einrichtung ausgegeben werden soll.");
-        $table .= $edit_form->editCheckboxGeneric('defaultadr', $title, $info, '1', '0');
-
-        $title = _('Personenname ausblenden') . ':';
-        $info = _("Unterdrückt die Anzeige des Namens im Adressfeld.");
-        $table .= $edit_form->editCheckboxGeneric('hidepersname', $title, $info, '1', '0');
-
-        $title = _('Funktionen anzeigen') . ':';
-        $info = _("Ausgabe der Funktionen der Mitarbeiterin/des Mitarbeiters in der Einrichtung.");
-        $table .= $edit_form->editCheckboxGeneric('showinstgroup', $title, $info, '1', '0');
-
-        $title = _('Einrichtungsname') . ':';
-        $info = _("Anzeige des Einrichtungsnamens. Der Name kann auch als Link auf die in Stud.IP angegebene URL (unter Grunddaten der Einrichtung) angezeigt werden.");
-        $values = ['1', '0', 'link'];
-        $names = [_("nicht anzeigen"), _("anzeigen"), _("als Link anzeigen")];
-        $table .= $edit_form->editRadioGeneric('hideinstname', $title, $info, $values, $names);
-
-        $title = _('E-Mail und Hompage getrennt') . ':';
-        $info = _("Sinnvoll ist diese Option bei sehr langen E-Mail-Adressen und Homepage-Links der Mitarbeiter. Diese werden dann unterhalb des Adressfeldes ausgegeben.");
-        $table .= $edit_form->editCheckboxGeneric('separatelinks', $title, $info, '1', '0');
-
-        $title = _('Adresszusatz') . ':';
-        $info = _("Zusatz zur Adresse der Einrichtung, z.B. Universitätsname.");
-        $table .= $edit_form->editTextfieldGeneric("adradd", $title, $info, 35, 100);
-
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $attributes = ["table_width", "table_align",
-                "table_border", "table_bgcolor", "table_bordercolor", "table_cellpadding",
-                "table_cellspacing", "table_class", "table_style", "tr_class", "tr_style",
-                "td_height", "td_align", "td_valign", "td_bgcolor", "td_class", "td_style"];
-        $content_table .= $edit_form->getEditFormContent($attributes);
-        $content_table .= $edit_form->editBlankContent();
-
-        $attributes = ["fonttitle_face", "fonttitle_size", "fonttitle_color", "fonttitle_class",
-                "fonttitle_style", "fontcontent_face", "fontcontent_size", "fontcontent_color",
-                "fontcontent_class", "fontcontent_style"];
-        $headlines = ["fonttitle" => _("Schriftformatierung der Ãœberschrift"),
-                "fontcontent" => _("Schriftformatierung des Inhalts")];
-        $content_table .= $edit_form->getEditFormContent($attributes, $headlines);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == 'hidepersname' || $attribute == 'separatelinks'
-                || $attribute == 'defaultadr' || $attribute == 'showinstgroup') {
-            if (!isset($_POST["Contact_$attribute"])) {
-                $_POST["Contact_$attribute"] = 0;
-                return FALSE;
-            }
-
-            return !($value == '1' || $value == '');
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementContentNews.class.php b/lib/extern/elements/ExternElementContentNews.class.php
deleted file mode 100644
index 0a089724988..00000000000
--- a/lib/extern/elements/ExternElementContentNews.class.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementContentNews.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElement
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementContentNews.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementContentNews extends ExternElement {
-
-    var $attributes = ["fonttopic_size", "fonttopic_face", "fonttopic_color",
-            "fonttopic_class", "fonttopic_style","divtopic_align", "divtopic_class",
-            "divtopic_style", "fontbody_size", "fontbody_face", "fontbody_color",
-            "fontbody_class", "fontbody_style", "divbody_align", "divbody_class", "divbody_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "ContentNews";
-        $this->real_name = _("Ãœberschrift und Beschreibung der News");
-        $this->description = _("Eigenschaften der Ãœberschrift und der Beschreibung einer News.");
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $attributes = ["fonttopic_size", "fonttopic_face", "fonttopic_color",
-            "fonttopic_class", "fonttopic_style","divtopic_align", "divtopic_class",
-            "divtopic_style", "fontbody_size", "fontbody_face", "fontbody_color",
-            "fontbody_class", "fontbody_style", "divbody_align", "divbody_class", "divbody_style"];
-        $headlines = ["fonttopic" => _("Schriftformatierung News-Titel (HTML-Tag &lt;font&gt;)"),
-                "divtopic" => _("Ausrichtung News-Titel (HTML-Tag &lt;div&gt;)"),
-                "fontbody" => _("Schriftformatierung News-Beschreibung (HTML-Tag &lt;font&gt;)"),
-                "divbody" => _("Ausrichtung News-Beschreibung (HTML-Tag &lt;div&gt;)")];
-        $content_table = $edit_form->getEditFormContent($attributes, $headlines);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-
-        return $out;
-    }
-
-    function toString ($args = null) {
-        $font_topic = $this->config->getAttributes($this->name, "fonttopic");
-        $font_body = $this->config->getAttributes($this->name, "fontbody");
-
-        if ($font_topic)
-            $out = "<font$font_topic>{$args['content']['topic']}</font>";
-        else
-            $out = $args['content']['topic'];
-        $out = "<div" . $this->config->getAttributes($this->name, "divtopic") . ">$out</div>\n";
-
-        if ($args["content"]["body"]) {
-            $out .= "<div" . $this->config->getAttributes($this->name, "divbody");
-            if ($font_body)
-                $out .= "><font$font_body>{$args['content']['body']}</font>";
-            else
-                $out .= ">{$args['content']['body']}";
-            $out .= "</div>\n";
-        }
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementLecturesInnerTable.class.php b/lib/extern/elements/ExternElementLecturesInnerTable.class.php
deleted file mode 100644
index bc1f4160c20..00000000000
--- a/lib/extern/elements/ExternElementLecturesInnerTable.class.php
+++ /dev/null
@@ -1,189 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementLecturesInnerTable.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementLecturesInnerTable
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementLecturesInnerTable.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementLecturesInnerTable extends ExternElement {
-
-    var $attributes = ["tr_class", "tr_style", "td_bgcolor", "td_bgcolor2_",
-            "td_class", "td_style", "td1_height", "td1_align", "td1_valign",
-            "td2_height", "td2_align", "td2_valign", "td2width", "font2_face",
-            "font2_size", "font2_color", "font2_class", "font2_style", "td3_align"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "LecturesInnerTable";
-        $this->real_name = _("Veranstaltungsname/Zeiten(Termine)/Lehrende");
-        $this->description = _("Formatierung von Veranstaltungsname/Zeiten(Termine)/Lehrenden in der Veranstaltungsübersicht.");
-
-        $this->headlines = [_("Angaben zum HTML-Tag &lt;tr&gt;"), _("Angaben zum HTML-Tag &lt;td&gt;"),
-            _("Ausrichtung Veranstaltungsname"), _("Ausrichtung Zeiten(Termine)/Lehrenden"),
-            _("Schrift Zeiten(Termine)/Lehrende (HTML-Tag &lt;font&gt;)")];
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $attributes = ["tr_class", "tr_style", "td_bgcolor", "td_bgcolor2_",
-                "td_class", "td_style"];
-        $headline = ["tr" => $this->headlines[0], "td" => $this->headlines[1]];
-        $content_table = $edit_form->getEditFormContent($attributes, $headline);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline($this->headlines[2]);
-
-        $table = $edit_form->editHeight("td1_height");
-        $table .= $edit_form->editAlign("td1_align");
-        $table .= $edit_form->editValign("td1_valign");
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline($this->headlines[3]);
-
-        $table = $edit_form->editHeight("td2_height");
-
-        $title = _('Spaltenbreite Zeiten') . ':';
-        $info = _("Breite der Spalte \"Zeiten(Termine)\" in Prozent.");
-        $table .= $edit_form->editTextfieldGeneric("td2width", $title, $info, 2, 2);
-
-        $title = _('Horizontale Ausrichtung Zeiten') . ':';
-        $info = _("Wählen Sie aus der Auswahlliste die Art der horizontalen Ausrichtung.");
-        $values = ["left", "right", "center"];
-        $names = [_("linksbündig"), _("rechtsbündig"), _("zentriert")];
-        $table .= $edit_form->editOptionGeneric("td2_align", $title, $info, $values, $names);
-
-        $title = _('Horizontale Ausrichtung Lehrende') . ':';
-        $info = _("Wählen Sie aus der Auswahlliste die Art der horizontalen Ausrichtung.");
-        $values = ["left", "right", "center"];
-        $names = [_("linksbündig"), _("rechtsbündig"), _("zentriert")];
-        $table .= $edit_form->editOptionGeneric("td3_align", $title, $info, $values, $names);
-
-        $table .= $edit_form->editValign("td2_valign");
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $attributes = ["font2_face", "font2_size", "font2_color", "font2_class", "font2_style"];
-        $headline = ["font2" => $this->headlines[4]];
-        $content_table .= $edit_form->getEditFormContent($attributes, $headline);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-
-        return $out;
-    }
-
-    function toString ($args = null) {
-        static $zebra = 0;
-
-        $show_time = $this->config->getValue("Main", "time");
-        $show_lecturer = $this->config->getValue("Main", "lecturer");
-        if ($show_time && $show_lecturer) {
-          if (!$td2width = $this->config->getValue($this->name, "td2width"))
-            $td2width = 50;
-          $colspan = " colspan=\"2\"";
-          $td_time = $this->config->getAttributes($this->name, "td2");
-          $td_time .= " width=\"$td2width%\"";
-          $td_lecturer = " align=\"" . $this->config->getValue($this->name, "td3_align");
-          $td_lecturer .= "\" valign=\"" . $this->config->getValue($this->name, "td2_valign");
-          $td_lecturer .= "\" width=\"" . (100 - $td2width) . "%\"";
-        }
-        else {
-          $colspan = "";
-          $td_time = $this->config->getAttributes($this->name, "td2") . " width=\"100%\"";
-          $td_lecturer = " align=\"" . $this->config->getValue($this->name, "td3_align");
-          $td_lecturer .= "\" valign=\"" . $this->config->getValue($this->name, "td2_valign");
-          $td_lecturer .= " width=\"100%\"";
-        }
-
-        $out = "<tr" . $this->config->getAttributes($this->name, "tr").">";
-        if ($zebra % 2 && $this->config->getValue($this->name, "td_bgcolor2_"))
-            $out .= "<td width=\"100%\"".$this->config->getAttributes($this->name, "td", TRUE)."\">\n";
-        else
-            $out .= "<td width=\"100%\"".$this->config->getAttributes($this->name, "td", FALSE)."\">\n";
-        $zebra++;
-        $out .= "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
-        $out .= "<tr" . $this->config->getAttributes($this->name, "tr1") . ">";
-        $out .= "<td$colspan" . $this->config->getAttributes($this->name, "td1") . ">";
-        $out .= "{$args['content']['sem_name']}</td></tr>\n";
-
-        if ($show_time || $show_lecturer) {
-            $out .= "\n<tr" . $this->config->getAttributes($this->name, "tr2") . ">";
-            if ($show_time) {
-                $out .= "<td$td_time>";
-                $out .= "<font" . $this->config->getAttributes($this->name, "font2") . ">";
-                $out .= "{$args['content']['turnus']}</font></td>\n";
-            }
-            if ($show_lecturer) {
-                $out .= "<td$td_lecturer>";
-                $out .= "<font" . $this->config->getAttributes($this->name, "font2") . ">";
-
-                $out .= "{$args['content']['lecturers']}</font></td>";
-            }
-            $out .= "</tr>";
-        }
-        $out .= "</table></td></tr>\n";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementLink.class.php b/lib/extern/elements/ExternElementLink.class.php
deleted file mode 100644
index 7fefd7e8dd8..00000000000
--- a/lib/extern/elements/ExternElementLink.class.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementLink.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElement
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementLink.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementLink extends ExternElement {
-
-    var $attributes = ["font_size", "font_face", "font_color", "font_class", "font_style",
-            "a_class", "a_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "Link";
-        $this->real_name = _("Links");
-        $this->description = _("Eigenschaften der Schrift für Links.");
-    }
-
-    function toString ($args = null) {
-        // to set the color of the font in the style-attribute of the a-tag
-        if ($color = $this->config->getValue($this->name, "font_color")) {
-            $style = $this->config->getValue($this->name, "a_style");
-            $style = "color:$color;$style";
-            $this->config->setValue($this->name, "a_style", $style);
-        }
-
-        $out = $args["content"];
-        if ($tag = $this->config->getTag($this->name, "font", FALSE, TRUE))
-            $out = $tag . $out . "</font>";
-        $out = "<a href=\"{$args['link']}\"" . $this->config->getAttributes($this->name, "a")
-                . ">$out</a>";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementLinkIntern.class.php b/lib/extern/elements/ExternElementLinkIntern.class.php
deleted file mode 100644
index b7144b91769..00000000000
--- a/lib/extern/elements/ExternElementLinkIntern.class.php
+++ /dev/null
@@ -1,151 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementLinkIntern.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementLinkIntern
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementLinkIntern.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementLinkIntern extends ExternElement {
-
-    var $attributes = ["font_size", "font_face", "font_color", "font_class", "font_style",
-            "a_class", "a_style", "config", "srilink", "externlink"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "LinkIntern";
-        $this->real_name = _("Links");
-        $this->description = _("Eigenschaften der Schrift für Links.");
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $attributes = ["font_size", "font_face", "font_color", "font_class", "font_style",
-            "a_class", "a_style"];
-        $headlines = ["font" => _("Schriftformatierung"),
-                "a" => _("Linkformatierung")];
-        $content_table = $edit_form->getEditFormContent($attributes, $headlines);
-        $content_table .= $edit_form->editBlankContent();
-
-        $this->toStringConfigSelector($edit_form, $content_table);
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function toStringConfigSelector (&$edit_form, &$content_table) {
-        global $EXTERN_MODULE_TYPES;
-        $headline = $edit_form->editHeadline(_("Verlinkung zum Modul"));
-        $title = _('Konfiguration') . ':';
-        $info = _("Der Link ruft das Modul mit der gewählten Konfiguration auf. Wählen Sie \"Standard\", um die von Ihnen gesetzte Standardkonfiguration zu benutzen. Ist für das aufgerufene Modul noch keine Konfiguration erstellt worden, wird die Stud.IP-Default-Konfiguration verwendet.");
-        $values = [];
-        $names = [];
-        $spacer = '';
-        $first_module = TRUE;
-        foreach ((array) $this->link_module_type as $module_type) {
-            $configs = ExternConfig::GetAllConfigurations($this->config->range_id, $module_type);
-            if (is_array($configs) && count($configs)) {
-                if ($first_module) {
-                    $names[] = _("Standardkonfiguration") . ' ('. $EXTERN_MODULE_TYPES[$module_type]['name'] . ')';
-                    $values[] = '';
-                    $first_module = FALSE;
-                }
-                $configs = $configs[$EXTERN_MODULE_TYPES[$module_type]['module']];
-                foreach ($configs as $config_id => $config) {
-                    $names[] = $config['name'] . ' ('. $EXTERN_MODULE_TYPES[$module_type]['name'] . ')';
-                    $values[] = $config_id;
-                }
-            }
-        }
-        $table = $edit_form->editOptionGeneric('config', $title, $info, $values, $names);
-
-        $title = _('SRI-Link') . ':';
-        $info = _("Wenn Sie die SRI-Schnittstelle benutzen, müssen Sie hier die vollständige URL (mit http://) der Seite angeben, in der das Modul, das durch den Link aufgerufen wird, eingebunden ist. Lassen Sie dieses Feld unbedingt leer, falls Sie die SRI-Schnittstelle nicht nutzen.");
-        $table .= $edit_form->editTextfieldGeneric("srilink", $title, $info, 50, 250);
-
-        $title = _('Extern-Link') . ':';
-        $info = _("Wenn Sie die SRI-Schnittstelle nicht benutzen, können Sie hier die vollständige URL (mit http://) der Seite angeben, in der das Modul, das durch den Link aufgerufen wird, eingebunden wird. Lassen Sie dieses Feld unbedingt leer, falls Sie die SRI-Schnittstelle nutzen.");
-        $table .= $edit_form->editTextfieldGeneric("externlink", $title, $info, 50, 250);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-    }
-
-    function checkValues ($attribute, $value) {
-        if ($attribute == "srilink") {
-            return preg_match("|^https?://.*$|i", $value);
-        }
-    }
-
-    function toString ($args = null) {
-        $link = $this->createUrl($args);
-        // to set the color of the font in the style-attribute of the a-tag
-        if ($color = $this->config->getValue($this->name, "font_color")) {
-            $this->config->setValue($this->name, "a_style", "color:$color;"
-                    . $this->config->getValue($this->name, "a_style"));
-        }
-
-        if ($font_attr = $this->config->getAttributes($this->name, "font"))
-            $out = "<font$font_attr>" . $args["content"] . "</font>";
-        else
-            $out = $args["content"];
-        $out = "<a href=\"$link\"" . $this->config->getAttributes($this->name, "a") . ">" . $out . "</a>";
-
-        return $out;
-    }
-}
diff --git a/lib/extern/elements/ExternElementLinkInternSimple.class.php b/lib/extern/elements/ExternElementLinkInternSimple.class.php
deleted file mode 100644
index 9ee07183463..00000000000
--- a/lib/extern/elements/ExternElementLinkInternSimple.class.php
+++ /dev/null
@@ -1,201 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementLinkInternSimple.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementLinkInternSimple
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementLinkInternSimple.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'ExternElementLinkIntern.class.php';
-
-// this class is only for compatibility reasons (Stud.IP < 0.95)
-// this class is replaced by ExternElementLinkIntern and the
-// use of global configurations
-class ExternElementLinkInternSimple extends ExternElement {
-
-    var $attributes = ["font_size", "font_face", "font_color", "font_class", "font_style",
-            "a_class", "a_style", "config", "srilink", "externlink"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "LinkIntern";
-        $this->real_name = _("Links");
-        $this->description = _("Eigenschaften der Schrift für Links.");
-        $this->headlines = [_("Schriftformatierung"), _("Linkformatierung"),
-                _("Verlinkung zum Modul")];
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-        global $EXTERN_MODULE_TYPES;
-        if ($edit_form == "") {
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-        }
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $attributes = ["font_size", "font_face", "font_color", "font_class", "font_style",
-            "a_class", "a_style"];
-        $headlines = ["font" => $this->headlines[0],
-                "a" => $this->headlines[1]];
-        $content_table = $edit_form->getEditFormContent($attributes, $headlines);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline($this->headlines[2]);
-
-        $title = _('Konfiguration') . ':';
-        $info = _("Der Link ruft das Modul mit der gewählten Konfiguration auf. Wählen Sie \"Standard\", um die von Ihnen gesetzte Standardkonfiguration zu benutzen. Ist für das aufgerufene Modul noch keine Konfiguration erstellt worden, wird die Stud.IP-Default-Konfiguration verwendet.");
-        $configs = ExternConfig::GetAllConfigurations($this->config->range_id, $this->link_module_type);
-        if (is_array($configs) && count($configs)) {
-            $module_name = $EXTERN_MODULE_TYPES[$this->link_module_type]["module"];
-            $values = array_keys($configs[$module_name]);
-
-            $names = [];
-            foreach ($configs[$module_name] as $config) {
-                $names[] = $config["name"];
-            }
-        } else {
-            $values = [];
-            $names = [];
-        }
-        array_unshift($values, "");
-        array_unshift($names, _("Standardkonfiguration"));
-        $table = $edit_form->editOptionGeneric("config", $title, $info, $values, $names);
-
-        $title = _('SRI-Link') . ':';
-        $info = _("Wenn Sie die SRI-Schnittstelle benutzen, müssen Sie hier die vollständige URL (mit http://) der Seite angeben, in der das Modul, das durch den Link aufgerufen wird, eingebunden ist. Lassen Sie dieses Feld unbedingt leer, falls Sie die SRI-Schnittstelle nicht nutzen.");
-        $table .= $edit_form->editTextfieldGeneric("srilink", $title, $info, 50, 250);
-
-        $title = _('Extern-Link') . ':';
-        $info = _("Wenn Sie die SRI-Schnittstelle nicht benutzen, können Sie hier die vollständige URL (mit http://) der Seite angeben, in der das Modul, das durch den Link aufgerufen wird, eingebunden wird. Lassen Sie dieses Feld unbedingt leer, falls Sie die SRI-Schnittstelle nutzen.");
-        $table .= $edit_form->editTextfieldGeneric("externlink", $title, $info, 50, 250);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValues ($attribute, $value) {
-        if ($attribute == "srilink")
-            return preg_match("|^https?://.*$|i", $value);
-    }
-
-    function toString ($args = null) {
-        if (!$args["main_module"]) {
-            $args["main_module"] = "Main";
-        }
-        $config_meta_data = ExternConfig::GetConfigurationMetaData($this->config->range_id, $this->config->getValue($this->name, 'config'));
-        $sri_link = $this->config->getValue($this->name, "srilink");
-        $extern_link = $this->config->getValue($this->name, "externlink");
-        if ($this->config->config[$args["main_module"]]["incdata"]) {
-            $link = $sri_link;
-            if ($args["link_args"]) {
-                if (preg_match("#.*\?.*#", $link)) {
-                    $link .= "&" . $args["link_args"];
-                } else {
-                    $link .= "?" . $args["link_args"];
-                }
-            }
-        } else {
-            if ($sri_link) {
-                $link = $GLOBALS['EXTERN_SERVER_NAME'] . 'extern.php';
-                if ($args["link_args"]) {
-                    $link .= "?" . $args["link_args"] . "&";
-                } else {
-                    $link .= "?";
-                }
-                $link .= "page_url=" . $sri_link;
-            } elseif ($extern_link) {
-                if (mb_strrpos($extern_link, '?')) {
-                    $link = "$extern_link&module={$config_meta_data['module_name']}";
-                } else {
-                    $link = "$extern_link?module={$config_meta_data['module_name']}";
-                }
-                if ($config = $this->config->getValue($this->name, 'config')) {
-                    $link .= "&config_id=" . $config;
-                }
-                $link .= "&range_id={$this->config->range_id}";
-                if ($args["link_args"]) {
-                    $link .= "&" . $args["link_args"];
-                }
-            } else {
-                $link = $GLOBALS['EXTERN_SERVER_NAME'] . "extern.php?module={$config_meta_data['module_name']}";
-                if ($config = $this->config->getValue($this->name, 'config')) {
-                    $link .= "&config_id=" . $config;
-                }
-                $link .= "&range_id={$this->config->range_id}";
-                if ($args["link_args"]) {
-                    $link .= "&" . $args["link_args"];
-                }
-            }
-        }
-        if ($this->config->global_id) {
-            $link .= "&global_id=" . $this->config->global_id;
-        }
-
-        // to set the color of the font in the style-attribute of the a-tag
-        if ($color = $this->config->getValue($this->name, "font_color")) {
-            $this->config->setValue($this->name, "a_style", "color:$color;"
-                    . $this->config->getValue($this->name, "a_style"));
-        }
-
-        if ($font_attr = $this->config->getAttributes($this->name, "font")) {
-            $out = "<font$font_attr>" . $args["content"] . "</font>";
-        } else {
-            $out = $args["content"];
-        }
-        $out = "<a href=\"$link\"" . $this->config->getAttributes($this->name, "a") . ">" . $out . "</a>";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementLinkInternTemplate.class.php b/lib/extern/elements/ExternElementLinkInternTemplate.class.php
deleted file mode 100644
index fff3663a251..00000000000
--- a/lib/extern/elements/ExternElementLinkInternTemplate.class.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementLinkInternTemplate.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementLinkInternTemplate
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementLinkInternTemplate.class.php
-//
-// Copyright (C) 2007 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'ExternElementLinkIntern.class.php';
-
-class ExternElementLinkInternTemplate extends ExternElementLinkIntern {
-
-    var $attributes = ['config', 'srilink', 'externlink'];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = '') {
-        if ($config) {
-            $this->config = $config;
-        }
-
-        $this->name = "LinkInternTemplate";
-        $this->real_name = _("Links");
-        $this->description = _("Eigenschaften der Verlinkung zu anderen Modulen.");
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = '', $faulty_values = '',
-            $edit_form = '', $anker = '') {
-        global $EXTERN_MODULE_TYPES;
-        $out = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $this->toStringConfigSelector($edit_form, $content_table);
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function toString ($args = null) {
-
-        return $this->createUrl($args);
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementList.class.php b/lib/extern/elements/ExternElementList.class.php
deleted file mode 100644
index 1a5ff8f56d2..00000000000
--- a/lib/extern/elements/ExternElementList.class.php
+++ /dev/null
@@ -1,114 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementList.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementList
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementList.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementList extends ExternElement {
-
-    var $attributes = ["ul_class", "ul_style", "li_class", "li_style", "margin"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "List";
-        $this->real_name = _("Aufzählungsliste");
-        $this->description = _("Eigenschaften einer Aufzählungsliste.");
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-        $out = '';
-        $tag_headline = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $content_table = $edit_form->getEditFormContent($this->attributes);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Einzug"));
-        $title = _('Linker Einzug') . ':';
-        $info = _("Geben Sie an, wie weit (Pixel) die Aufzählungsliste im Absatz links eingerückt werden soll.");
-        $content = $edit_form->editTextfieldGeneric("margin", $title, $info, 3, 3);
-
-        $content_table .= $edit_form->editContentTable($headline, $content);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == "margin")
-            return !preg_match("|^\d{0,3}$|", $value);
-    }
-
-    function toString ($args = null) {
-        if ($args["level"] == "list") {
-            if ($this->config->getValue($this->name, "margin")) {
-                $out = "\n<div style=\"margin-left:" . $this->config->getValue($this->name, "margin");
-                $out .= "\">" . $this->config->getTag($this->name, "ul") . $args["content"];
-                $out .= "</ul></div>";
-            }
-            else
-                $out = "\n" . $this->config->getTag($this->name, "ul") . $args["content"] . "</ul>";
-        }
-        else if ($args["level"] == "item")
-            $out = "\n" . $this->config->getTag($this->name, "li") . $args["content"] . "</li>";
-        else
-            $out = "";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementPersondetailsHeader.class.php b/lib/extern/elements/ExternElementPersondetailsHeader.class.php
deleted file mode 100644
index 32595253e6e..00000000000
--- a/lib/extern/elements/ExternElementPersondetailsHeader.class.php
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementPersondetailsHeader.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTableHeader
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementPersondetailsHeader.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementPersondetailsHeader extends ExternElement {
-
-    var $attributes = ["table_width", "table_align", "table_border", "table_bgcolor",
-                "table_bordercolor", "table_cellpadding", "table_cellspacing", "table_class",
-                "table_style", "tr_class", "tr_style", "headlinetd_height", "headlinetd_align",
-                "headlinetd_valign", "headlinetd_bgcolor", "headlinetd_class", "headlinetd_style",
-                "picturetd_width", "picturetd_align", "picturetd_valign", "picturetd_bgcolor",
-                "picturetd_class", "picturetd_style", "contacttd_width", "contacttd_align",
-                "contacttd_valign", "contacttd_bgcolor", "contacttd_class", "contacttd_style",
-                "font_face", "font_size", "font_color", "font_class", "font_style", "img_align",
-                "img_border", "img_width", "img_height", "hidename"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "PersondetailsHeader";
-        $this->real_name = _("Seitenkopf/Bild");
-        $this->description = _("Angaben zur Gestaltung des Seitenkopfes.");
-    }
-
-    function getDefaultConfig () {
-        $config = [
-            "table_width" => "100%",
-            "table_border" => "0",
-            "table_bordercolor" => "",
-            "table_cellpadding" => "0",
-            "table_cellspacing" => "0",
-            "hidename" => ""
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben zum Element Seitenkopf/Bild"));
-
-        $title = _('Ãœberschrift (Name) ausblenden') . ':';
-        $info = _("Unterdrückt die Anzeige des Namens als Überschrift.");
-        $table .= $edit_form->editCheckboxGeneric("hidename", $title, $info, '1', '');
-
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $attributes = ["table_width", "table_align", "table_border", "table_bgcolor",
-                "table_bordercolor", "table_cellpadding", "table_cellspacing", "table_class",
-                "table_style", "tr_class", "tr_style", "headlinetd_height", "headlinetd_align",
-                "headlinetd_valign", "headlinetd_bgcolor", "headlinetd_class", "headlinetd_style",
-                "font_face", "font_size", "font_color", "font_class", "font_style",
-                "picturetd_width", "picturetd_align", "picturetd_valign", "picturetd_bgcolor",
-                "picturetd_class", "picturetd_style", "contacttd_width", "contacttd_align",
-                "contacttd_valign", "contacttd_bgcolor", "contacttd_class", "contacttd_style",];
-        $headlines = ["table" => _("Tabelle Seitenkopf/Bild (HTML-Tag &lt;table&gt;)"),
-                "tr" => _("Tabellenzeile Name (HTML-Tag &lt;tr&gt;)"),
-                "headlinetd" => _("Tabellenzelle Name (HTML-Tag &lt;td&gt;)"),
-                "font" => _("Schriftformatierung Name (HTML-Tag &lt;font&gt;)"),
-                "picturetd" => _("Tabellenzelle Bild (HTML-Tag &lt;td&gt;)"),
-                "contacttd" => _("Tabellenzelle Kontakt (HTML-Tag &lt;td&gt;)")];
-        $content_table .= $edit_form->getEditFormContent($attributes, $headlines);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Bild"));
-
-        $title = _('Ausrichtung') . ':';
-        $info = _("Ausrichtung des Bildes.");
-        $names = [_("zentriert"), _("linksbündig"), _("rechtsbündig"),
-                _("obenbündig"), _("untenbündig")];
-        $values = ["center", "left", "right", "top", "bottom"];
-        $table = $edit_form->editOptionGeneric("img_align", $title, $info, $values, $names);
-
-        $title = _('Rahmenbreite') . ':';
-        $info = _("Breite des Bildrahmens.");
-        $table .= $edit_form->editTextfieldGeneric("img_border", $title, $info, 3, 3);
-
-        $title = _('Breite') . ':';
-        $info = _("Breite des Bildes.");
-        $table .= $edit_form->editTextfieldGeneric("img_width", $title, $info, 3, 3);
-
-        $title = _('Höhe') . ':';
-        $info = _("Breite des Bildes.");
-        $table .= $edit_form->editTextfieldGeneric("img_height", $title, $info, 3, 3);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function toString ($args = null)
-    {
-        return '';
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == "hidename") {
-            if (!isset($_POST["PersondetailsHeader_$attribute"])) {
-                $_POST["PersondetailsHeader_$attribute"] = 0;
-                return FALSE;
-            }
-
-            return !($value == "1" || $value == "");
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementPersondetailsLectures.class.php b/lib/extern/elements/ExternElementPersondetailsLectures.class.php
deleted file mode 100644
index e4f4b50095d..00000000000
--- a/lib/extern/elements/ExternElementPersondetailsLectures.class.php
+++ /dev/null
@@ -1,183 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementPersondetailsLectures.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementPersondetailsLectures
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementPersondetailsLectures.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'lib/dates.inc.php';
-
-class ExternElementPersondetailsLectures extends ExternElement {
-
-    var $attributes = ["semstart", "semrange", "semswitch", "aliaswise",
-            "aliassose", "aslist", "semclass"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "PersondetailsLectures";
-        $this->real_name = _("Lehrveranstaltungen");
-        $this->description = _("Angaben zur Ausgabe von Lehrveranstaltungen.");
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            "semstart" => "",
-            "semrange" => "",
-            "semswitch" => "",
-            "aliaswise" => _("Wintersemester"),
-            "aliassose" => _("Sommersemester"),
-            "aslist" => "1",
-            'semclass' => '|1'
-
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        // get semester data
-        $semester_data = Semester::findAllVisible(false);
-
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben"));
-
-        $title = _('Startsemester') . ':';
-        $info = _("Geben Sie das erste anzuzeigende Semester an. Die Angaben \"vorheriges\", \"aktuelles\" und \"nächstes\" beziehen sich immer auf das laufende Semester und werden automatisch angepasst.");
-        $current_sem = get_sem_num_sem_browse();
-        if ($current_sem === FALSE) {
-            $names = [_("keine Auswahl"), _("aktuelles"), _("nächstes")];
-            $values = ["", "current", "next"];
-        }
-        else if ($current_sem === TRUE) {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles")];
-            $values = ["", "previous", "current"];
-        }
-        else {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles"), "nächstes"];
-            $values = ["", "previous", "current", "next"];
-        }
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $sem["name"];
-            $values[] = $sem_num + 1;
-        }
-        $table = $edit_form->editOptionGeneric("semstart", $title, $info, $values, $names);
-
-        $title = _('Anzahl der anzuzeigenden Semester') . ':';
-        $info = _("Geben Sie an, wieviele Semester (ab o.a. Startsemester) angezeigt werden sollen.");
-        $names = [_("keine Auswahl")];
-        $values = [""];
-        $i = 1;
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $i++;
-            $values[] = $sem_num + 1;
-        }
-        $table .= $edit_form->editOptionGeneric("semrange", $title, $info, $values, $names);
-
-        $title = _('Umschalten des aktuellen Semesters') . ':';
-        $info = _("Geben Sie an, wieviele Wochen vor Semesterende automatisch auf das nächste Semester umgeschaltet werden soll.");
-        $names = [_("keine Auswahl"), _("am Semesterende"), _("1 Woche vor Semesterende")];
-        for ($i = 2; $i < 13; $i++)
-            $names[] = sprintf(_("%s Wochen vor Semesterende"), $i);
-        $values = ["", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
-        $table .= $edit_form->editOptionGeneric("semswitch", $title, $info, $values, $names);
-
-        $title = _('Bezeichnung Sommersemester') . ':';
-        $info = _("Alternative Bezeichnung für den Begriff \"Sommersemester\".");
-        $table .= $edit_form->editTextfieldGeneric("aliassose", $title, $info, 40, 80);
-
-        $title = _('Bezeichnung Wintersemester') . ':';
-        $info = _("Alternative Bezeichnung für den Begriff \"Wintersemester\".");
-        $table .= $edit_form->editTextfieldGeneric("aliaswise", $title, $info, 40, 80);
-
-        $title = _('Darstellungsart') . ':';
-        $info = _("Wählen Sie zwischen Listendarstellung und reiner Textdarstellung.");
-        $names = [_("Liste"), _("nur Text")];
-        $values = ["1", "0"];
-        $table .= $edit_form->editRadioGeneric("aslist", $title, $info, $values, $names);
-
-        $title = _('Veranstaltungsklassen') . ':';
-        $info = _("Wählen Sie aus, welche Veranstaltungsklassen angezeigt werden sollen.");
-        foreach ($GLOBALS['SEM_CLASS'] as $key => $lecture_class) {
-            $class_names[] = $lecture_class['name'];
-            $class_values[] = $key;
-        }
-        $table .= $edit_form->editCheckboxGeneric("semclass", $title, $info, $class_values, $class_names);
-
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == 'semclass') {
-            if (!sizeof($_POST[$this->getName() . '_semclass'])) {
-                return true;
-            }
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementPersondetailsLecturesTemplate.class.php b/lib/extern/elements/ExternElementPersondetailsLecturesTemplate.class.php
deleted file mode 100644
index 2b13f4f2434..00000000000
--- a/lib/extern/elements/ExternElementPersondetailsLecturesTemplate.class.php
+++ /dev/null
@@ -1,175 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementPersondetailsLectures.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementPersondetailsLectures
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementPersondetailsLectures.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'ExternElementPersondetailsLectures.class.php';
-
-class ExternElementPersondetailsLecturesTemplate extends ExternElementPersondetailsLectures {
-
-    var $attributes = ['semstart', 'semrange', 'semswitch', 'aliaswise',
-            'aliassose', 'semclass'];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = '') {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = 'PersondetailsLecturesTemplate';
-        $this->real_name = _("Lehrveranstaltungen");
-        $this->description = _("Angaben zur Ausgabe von Lehrveranstaltungen.");
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            'semstart' => '',
-            'semrange' => '',
-            'semswitch' => '',
-            'aliaswise' => _("Wintersemester"),
-            'aliassose' => _("Sommersemester"),
-            'semclass' => '|1'
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = '', $faulty_values = '',
-            $edit_form = '', $anker = '') {
-
-        // get semester data
-        $semester_data = Semester::findAllVisible(false);
-
-        $out = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben"));
-
-        $title = _('Startsemester') . ':';
-        $info = _("Geben Sie das erste anzuzeigende Semester an. Die Angaben \"vorheriges\", \"aktuelles\" und \"nächstes\" beziehen sich immer auf das laufende Semester und werden automatisch angepasst.");
-        $current_sem = get_sem_num_sem_browse();
-        if ($current_sem === FALSE) {
-            $names = [_("keine Auswahl"), _("aktuelles"), _("nächstes")];
-            $values = ["", "current", "next"];
-        }
-        else if ($current_sem === TRUE) {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles")];
-            $values = ["", "previous", "current"];
-        }
-        else {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles"), "nächstes"];
-            $values = ["", "previous", "current", "next"];
-        }
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $sem["name"];
-            $values[] = $sem_num + 1;
-        }
-        $table = $edit_form->editOptionGeneric("semstart", $title, $info, $values, $names);
-
-        $title = _('Anzahl der anzuzeigenden Semester') . ':';
-        $info = _("Geben Sie an, wieviele Semester (ab o.a. Startsemester) angezeigt werden sollen.");
-        $names = [_("keine Auswahl")];
-        $values = [""];
-        $i = 1;
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $i++;
-            $values[] = $sem_num + 1;
-        }
-        $table .= $edit_form->editOptionGeneric("semrange", $title, $info, $values, $names);
-
-        $title = _('Umschalten des aktuellen Semesters') . ':';
-        $info = _("Geben Sie an, wieviele Wochen vor Semesterende automatisch auf das nächste Semester umgeschaltet werden soll.");
-        $names = [_("keine Auswahl"), _("am Semesterende"), _("1 Woche vor Semesterende")];
-        for ($i = 2; $i < 13; $i++)
-            $names[] = sprintf(_("%s Wochen vor Semesterende"), $i);
-        $values = ["", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
-        $table .= $edit_form->editOptionGeneric("semswitch", $title, $info, $values, $names);
-
-        $title = _('Bezeichnung Sommersemester') . ':';
-        $info = _("Alternative Bezeichnung für den Begriff \"Sommersemester\".");
-        $table .= $edit_form->editTextfieldGeneric("aliassose", $title, $info, 40, 80);
-
-        $title = _('Bezeichnung Wintersemester') . ':';
-        $info = _("Alternative Bezeichnung für den Begriff \"Wintersemester\".");
-        $table .= $edit_form->editTextfieldGeneric("aliaswise", $title, $info, 40, 80);
-
-        $title = _('Veranstaltungsklassen') . ':';
-        $info = _("Wählen Sie aus, welche Veranstaltungsklassen angezeigt werden sollen.");
-        foreach ($GLOBALS['SEM_CLASS'] as $key => $lecture_class) {
-            $class_names[] = $lecture_class['name'];
-            $class_values[] = $key;
-        }
-        $table .= $edit_form->editCheckboxGeneric("semclass", $title, $info, $class_values, $class_names);
-
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == 'semclass') {
-            if (!sizeof($_POST[$this->getName() . '_semclass'])) {
-                return true;
-            }
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementRangeTreeLevelContent.class.php b/lib/extern/elements/ExternElementRangeTreeLevelContent.class.php
deleted file mode 100644
index f51112c447b..00000000000
--- a/lib/extern/elements/ExternElementRangeTreeLevelContent.class.php
+++ /dev/null
@@ -1,101 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementRangeTreeLevelContent.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElement
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementRangeTreeLevelContent.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementRangeTreeLevelContent extends ExternElement {
-
-    var $attributes = ["mapping", "aliases", "table_bgcolor",
-                "table_cellpadding", "table_cellspacing", "table_class",
-                "table_style", "td_height", "td_align", "td_valign", "td_bgcolor",
-                "td_class", "td_style", "font_face", "font_size", "font_color",
-                "font_class", "font_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "RangeTreeLevelContent";
-        $this->real_name = _("Inhalt der Ebene");
-        $this->description = _("Formatierung des Ebeneninhalts in einer Baum-Navigation.");
-    }
-
-    function getDefaultConfig () {
-        $config = parent::getDefaultConfig();
-        $config["mapping"] = "|Strasse|Plz|telefon|fax|email|url";
-        $config["aliases"] = "|"._("Stra&szlig;e").":|"._("Ort").":|"._("Telefon")
-                .":|"._("Fax").":|"._("E-Mail").":|"._("Homepage").":";
-
-        return $config;
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-        if ($faulty_values == '')
-            $faulty_values = [];
-        $out = '';
-        $tag_headline = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Bezeichnungen"));
-        $info = _("Geben Sie eine alternative Bezeichnung ein.");
-        $names = [_("Stra&szlig;e"), _("Ort"), _("Telefon"), _("Fax"), _("E-Mail"), _("Homepage")];
-        $content = $edit_form->editTextfieldGeneric("aliases", $names, $info, 30, 60);
-
-        $content_table = $edit_form->editContentTable($headline, $content);
-        $content_table .= $edit_form->editBlankContent();
-
-        $out = $content_table . $edit_form->getEditFormContent($this->attributes);
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($out, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-}
diff --git a/lib/extern/elements/ExternElementRangeTreeLevelName.class.php b/lib/extern/elements/ExternElementRangeTreeLevelName.class.php
deleted file mode 100644
index 2463626167c..00000000000
--- a/lib/extern/elements/ExternElementRangeTreeLevelName.class.php
+++ /dev/null
@@ -1,107 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTreeLevelName.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTreeLevelName
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTreeLevelName.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementRangeTreeLevelName extends ExternElement {
-
-    var $attributes = ["aliases", "table_bgcolor",
-                "table_cellpadding", "table_cellspacing", "table_class",
-                "table_style", "td_height", "td_align", "td_valign", "td_bgcolor",
-                "td_class", "td_style", "font_face", "font_size", "font_color",
-                "font_class", "font_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "RangeTreeLevelName";
-        $this->real_name = _("Name der Ebene");
-        $this->description = _("Formatierung des Ebenennamens in einer Baum-Navigation.");
-    }
-
-    function getDefaultConfig () {
-        global $INST_TYPE;
-        $config = parent::getDefaultConfig();
-        foreach ($INST_TYPE as $type)
-            $names .= "|{$type['name']}:";
-        $config["aliases"] = $names;
-
-        return $config;
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        global $INST_TYPE;
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-        $out = '';
-        $tag_headline = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Bezeichnungen"));
-        $info = _("Geben Sie eine alternative Bezeichnung ein.");
-        foreach ($INST_TYPE as $type)
-            $names[] = $type["name"];
-        $content = $edit_form->editTextfieldGeneric("aliases", $names, $info, 35, 200);
-
-        $content_table = $edit_form->editContentTable($headline, $content);
-        $content_table .= $edit_form->editBlankContent();
-
-        $out = $content_table . $edit_form->getEditFormContent($this->attributes);
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($out, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementReplaceTextSemType.class.php b/lib/extern/elements/ExternElementReplaceTextSemType.class.php
deleted file mode 100644
index 72ace415fc4..00000000000
--- a/lib/extern/elements/ExternElementReplaceTextSemType.class.php
+++ /dev/null
@@ -1,140 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementReplaceTextSemType.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementReplaceTextSemType
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementReplaceTextSemType.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementReplaceTextSemType extends ExternElement {
-
-    var $attributes = [];
-    var $isset_visibilities = FALSE;
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config) {
-            $this->config = $config;
-        }
-
-        $this->name = "ReplaceTextSemType";
-        $this->real_name = _("Textersetzungen für Veranstaltungstypen");
-        $this->description = _("Ersetzt die Bezeichnung der Veranstaltungstypen.");
-        $this->attributes = ['order', 'visibility'];
-        for ($i = 1; $i <= count($GLOBALS["SEM_CLASS"]); $i++) {
-            $this->attributes[] = "class_" . $i;
-        }
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-        global $SEM_TYPE, $SEM_CLASS;
-        $config = [];
-        foreach ($SEM_CLASS as $class_index => $class) {
-            foreach ($SEM_TYPE as $type_index => $type) {
-                if ($type["class"] == $class_index) {
-                    $config["class_$class_index"] .= "|" . htmlReady($type["name"])
-                            . " ({$class['name']})";
-                }
-            }
-        }
-
-        foreach ($SEM_TYPE as $type_index => $foo) {
-            $config['order'] .= "|$type_index";
-            $config['visibility'] .= "|1";
-        }
-
-        return $config;
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "", $edit_form = "", $anker = "")
-    {
-        global $SEM_TYPE;
-
-        $order = $this->config->getValue($this->name, "order");
-        if (!is_array($order) || array_diff(array_keys($SEM_TYPE), $order)) {
-            $this->config->setValue($this->name, "order", array_keys($SEM_TYPE));
-            $this->config->store();
-        }
-
-        if (!$faulty_values)
-            $faulty_values = [];
-
-        if (!$edit_form) {
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-        }
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $table = $edit_form->editSemTypes();
-
-        $content_table = $edit_form->editContentTable('', $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($this->isset_visibilities) {
-            return FALSE;
-        }
-        if ($attribute == 'visibility') {
-            $this->isset_visibilities = TRUE;
-            $count_semtypes = intval($_POST['count_semtypes']);
-            if ($count_semtypes < 100) {
-                for ($i = 0; $i < $count_semtypes; $i++) {
-                    if ($_POST[$this->name . '_visibility'][$i] != '1') {
-                        $_POST[$this->name . '_visibility'][$i] = '0';
-                    }
-                }
-            }
-            return FALSE;
-        }
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementSelectInstitutes.class.php b/lib/extern/elements/ExternElementSelectInstitutes.class.php
deleted file mode 100644
index 28126864b51..00000000000
--- a/lib/extern/elements/ExternElementSelectInstitutes.class.php
+++ /dev/null
@@ -1,103 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementSelectInstitutes.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementSelectInstitutes
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementSelectInstitutes.class.php
-//
-// Copyright (C) 2006 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementSelectInstitutes extends ExternElement {
-
-    public $attributes = [];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    public function __construct ($config = '') {
-        if ($config != '')
-            $this->config = $config;
-
-        $this->name = "SelectInstitutes";
-        $this->real_name = _("Auswahl der anzuzeigenden Institute/Einrichtungen");
-        $this->description = _("Sie können hier die Institute/Einrichtungen auswählen, die auf der externen Seite ausgegeben werden sollen.");
-        $this->attributes = ['institutesselected'];
-    }
-
-    /**
-    *
-    */
-    public function getDefaultConfig () {
-        $config = ['institutesselected' => '|'];
-
-        return $config;
-    }
-
-    public function toStringEdit ($post_vars = '', $faulty_values = '', $edit_form = '', $anker = '')
-    {
-        if (!$faulty_values) {
-            $faulty_values = [];
-        }
-        if (!$edit_form) {
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-        }
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $table = $edit_form->editSelectInstitutes();
-
-        $content_table = $edit_form->editContentTable('', $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(), $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-    public function checkValue ($attribute, $value) {
-        if ($attribute == 'institutesselected') {
-            if (!is_array($_POST[$this->name . '_' . $attribute])) {
-                $_POST[$this->name . '_' . $attribute] = '';
-                return FALSE;
-            }
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementSelectSubjectAreas.class.php b/lib/extern/elements/ExternElementSelectSubjectAreas.class.php
deleted file mode 100644
index d4a4bdc9df7..00000000000
--- a/lib/extern/elements/ExternElementSelectSubjectAreas.class.php
+++ /dev/null
@@ -1,159 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementSelectSubjectAreas.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementReplaceTextSemType
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementReplaceTextSemType.class.php
-//
-// Copyright (C) 2006 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementSelectSubjectAreas extends ExternElement {
-
-    var $attributes = [];
-    var $selector;
-    var $all_ranges = [];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = '') {
-        if ($config != '')
-            $this->config = $config;
-
-        $this->name = "SelectSubjectAreas";
-        $this->real_name = _("Auswahl der anzuzeigenden Studienbereiche");
-        $this->description = _("Sie können hier die Studienbereiche auswählen, die auf der externen Seite ausgegeben werden sollen.");
-        $this->attributes = ['subjectareasselected', 'selectallsubjectareas', 'reverseselection'];
-
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config['subjectareasselected'] = '';
-        $config['subjectareasselected'] .= '|' . implode('|', $this->all_ranges);
-        $config['selectallsubjectareas'] = '1';
-        $config['reverseselection'] = '';
-
-        return $config;
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-        $out = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $title = _('Alle Studienbereiche anzeigen') . ':';
-        $info = _("Wählen Sie diese Option, wenn alle Veranstaltungen aus allen Studienbereichen angezeigt werden sollen - unabhängig von unten vorgenommener Auswahl.");
-        $values = '1';
-        $names = '';
-        $table = $edit_form->editCheckboxGeneric('selectallsubjectareas', $title, $info, $values, $names);
-        $table .= $edit_form->editSelectSubjectAreas(new StudipSemTreeSearch('dummy', 'SelectSubjectAreas', FALSE));
-
-        $title = _('Auswahl umkehren') . ':';
-        $info = _("Wählen Sie diese Option, wenn Veranstaltungen aus den ausgewählten Bereichen nicht angezeigt werden sollen.");
-        $values = '1';
-        $names = '';
-        $table .= $edit_form->editCheckboxGeneric('reverseselection', $title, $info, $values, $names);
-
-        $content_table = $edit_form->editContentTable('', $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-    function executeCommand ($command, $value = "") {
-
-        if ($command == 'do_search_x') {
-            $GLOBALS['com'] = 'edit';
-            $this->config->setValue($this->name, 'subjectareasselected',
-                    $_POST['SelectSubjectAreas_subjectareasselected']);
-        }
-        return TRUE;
-    }
-
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == 'selectallsubjectareas') {
-            // This is necessary for checkbox-values. If there is no checkbox
-            // checked, the variable is not declared and it is necessary to set the
-            // variable to "".
-            if (!isset($_POST[$this->name . '_' . $attribute])) {
-                $_POST[$this->name . '_' . $attribute] = '';
-                return FALSE;
-            }
-            return !($value == '1' || $value == '');
-        }
-        if ($attribute == 'subjectareasselected' && is_array($_POST[$this->name . '_selectallsubjectareas']) && count($_POST[$this->name . '_selectallsubjectareas'])) {
-            return ($value == '0');
-        }
-
-        if ($attribute == 'subjectareasselected') {
-            if (!is_array($_POST[$this->name . '_' . $attribute])) {
-                $_POST[$this->name . '_' . $attribute] = '';
-                return FALSE;
-            }
-        }
-
-        if ($attribute == 'reverseselection') {
-            // This is necessary for checkbox-values. If there is no checkbox
-            // checked, the variable is not declared and it is necessary to set the
-            // variable to "".
-            if (!isset($_POST[$this->name . '_' . $attribute])) {
-                $_POST[$this->name . '_' . $attribute] = '';
-                return FALSE;
-            }
-            return !($value == '1' || $value == '');
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementStudipInfo.class.php b/lib/extern/elements/ExternElementStudipInfo.class.php
deleted file mode 100644
index 27305b33a4b..00000000000
--- a/lib/extern/elements/ExternElementStudipInfo.class.php
+++ /dev/null
@@ -1,128 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementStudipInfo.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementStudipInfo
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementStudipInfo.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementStudipInfo extends ExternElement {
-
-    var $attributes = ["headline", "homeinst", "involvedinst", "countuser",
-            "countpostings", "countdocuments", "font_face", "font_size", "font_color",
-            "font_class", "font_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "StudipInfo";
-        $this->real_name = _("Informationen aus Stud.IP");
-        $this->description = _("Anzeige weiterer Informationen aus Stud.IP im Modul &quot;Veranstaltungsdetails&quot;.");
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-        $config = [
-            "headline" => _("Weitere Informationen aus Stud.IP zu dieser Veranstaltung"),
-            "homeinst" => _('Heimatinstitut') . ':',
-            "involvedinst" => _('beteiligte Institute') . ':',
-            "countuser" => _('In Stud.IP angemeldete Teilnehmende') . ':',
-            "countpostings" => _('Anzahl der Postings im Stud.IP-Forum') . ':',
-            "countdocuments" => _('Anzahl der Dokumente im Stud.IP-Downloadbereich') . ':',
-        ];
-
-        return $config;
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        if ($faulty_values == '') {
-            $faulty_values = [];
-        }
-        $table = '';
-        if ($edit_form == '') {
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-        }
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Textersetzungen"));
-
-        $info = _("Geben Sie jeweils einen Text ein, der an der entsprechenden Stelle ausgegeben werden soll.");
-        $attributes = ["headline", "homeinst", "involvedinst", "countuser",
-                "countpostings", "countdocuments"];
-        $titles = [_('Ãœberschrift') . ':', _('Heimatinstitut') . ':', _('beteiligte Institute') . ':',
-                _('Teilnehmende') . ':', _('Forenbeiträge') . ':', _('Dokumente') . ':'];
-        if (is_array($attributes)) {
-            for ($i = 0; $i < count($attributes); $i++) {
-                $table .= $edit_form->editTextfieldGeneric($attributes[$i], $titles[$i], $info, 40, 150);
-            }
-        }
-    
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $attributes = ["font_face", "font_size", "font_color", "font_class", "font_style"];
-        $headlines = ["font" => _("Schriftformatierung für Textersetzungen")];
-        $content_table .= $edit_form->getEditFormContent($attributes, $headlines);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-    function toString ($args = null) {
-        if ($attributes_font = $this->config->getAttributes($this->name, "font"))
-            return "\n" . $this->config->getTag($this->name, "font") . $args["content"]
-                . "</font>";
-
-        return $args["content"];
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementStudipLink.class.php b/lib/extern/elements/ExternElementStudipLink.class.php
deleted file mode 100644
index 21834a4bf95..00000000000
--- a/lib/extern/elements/ExternElementStudipLink.class.php
+++ /dev/null
@@ -1,165 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementStudipLink.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementStudipLink
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementStudipLink.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementStudipLink extends ExternElement {
-
-    var $attributes = ["linktext", "imageurl", "image", "a_class", "a_style", "font_face",
-            "font_size", "font_color", "font_class", "font_style", "align"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "StudipLink";
-        $this->real_name = _("Link zum Stud.IP Administrationsbereich");
-        $this->description = _("Link zum direkten Einsprung in den Stud.IP Administrationsbereich.");
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            "linktext" => _("Daten ändern"),
-            "imageurl" => "",
-            "image" => "1",
-            "align" => "left"
-        ];
-
-        return $config;
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-        $out = '';
-        $tag_headline = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $content_table = $edit_form->getEditFormContent($this->attributes);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $content = $edit_form->editAlign("align");
-
-        $title = _('Linktext') . ':';
-        $info = _("Geben Sie den Text für den Link ein.");
-        $content .= $edit_form->editTextfieldGeneric("linktext", $title, $info, 40, 150);
-
-        $title = _('Bild anzeigen') . ':';
-        $info = _("Anwählen, wenn ein Bild als Link angezeigt werden soll.");
-        $value = "1";
-        $content .= $edit_form->editCheckboxGeneric("image", $title, $info, $value, "");
-
-        $title = _('Bild-URL') . ':';
-        $info = _("Geben Sie die URL eines Bildes ein, dass als Link dienen soll. Wenn Sie keine URL angeben, wird ein Standard-Bild (Pfeile) ausgegeben.");
-        $content .= $edit_form->editTextfieldGeneric("imageurl", $title, $info, 40, 150);
-
-        $content_table .= $edit_form->editContentTable($headline, $content);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-    function toString ($args = null) {
-        $out = "<table width=\"{$args['width']}\" cellpadding=\"0\" cellspacing=\"0\" border=\"0\">\n";
-        $out .= "<tr>";
-        $out .= "<td height=\"{$args['height']}\" width=\"100%\" align=\""
-                . $this->config->getValue($this->name, "align") . "\">\n";
-        $font = "<font" . $this->config->getAttributes($this->name, "font") . ">";
-        $out .= sprintf(
-            "<a href=\"%s\"%s target=\"_blank\" rel=\"noopener noreferrer\">%s%s</font></a>",
-            $args['link'],
-            $this->config->getAttributes($this->name, "a"), $font,
-            $this->config->getValue($this->name, "linktext")
-        );
-        if ($this->config->getValue($this->name, "image")) {
-            if ($image_url = $this->config->getValue($this->name, "imageurl"))
-                $img = Assets::img($image_url);
-            else {
-                $img = Icon::create('door-enter', 'clickable')->asImg();
-            }
-            $out .= sprintf(
-                "&nbsp;<a href=\"%s\"%s target=\"_blank\" rel=\"noopener noreferrer\">%s</a>",
-                $args['link'],
-                $this->config->getAttributes($this->name, "a"),
-                $img
-            );
-        }
-        $out .= "\n</td></tr></table>\n";
-
-        return $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == "image") {
-            // This is especially for checkbox-values. If there is no checkbox
-            // checked, the variable is not declared and it is necessary to set the
-            // variable to 0.
-            if (!isset($_POST[$this->name . "_" . $attribute])) {
-                $_POST[$this->name . "_" . $attribute] = 0;
-                return FALSE;
-            }
-            return !($value == "1" || $value == "0");
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTableFooter.class.php b/lib/extern/elements/ExternElementTableFooter.class.php
deleted file mode 100644
index c7282ac58ce..00000000000
--- a/lib/extern/elements/ExternElementTableFooter.class.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTableFooter.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElement
-* @package      studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTableFooter.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementTableFooter extends ExternElement {
-
-    var $attributes = [];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TableFooter";
-        $this->real_name = _("Tabellenfuß");
-        $this->description = _("Der Tabellenfuß enthält keine administrierbaren Attribute.");
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTableGroup.class.php b/lib/extern/elements/ExternElementTableGroup.class.php
deleted file mode 100644
index cbf216cb128..00000000000
--- a/lib/extern/elements/ExternElementTableGroup.class.php
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTableGroup.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTableGroup
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTableGroup.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementTableGroup extends ExternElement {
-
-    var $attributes = ["tr_class", "tr_style", "td_height", "td_align",
-            "td_valign", "td_bgcolor", "td_bgcolor_2", "td_class", "td_style",
-            "font_face", "font_size", "font_color", "font_class", "font_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct ($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TableGroup";
-        $this->real_name = _("Gruppenüberschriften");
-        $this->description = _("Gruppenüberschriften sind Tabellenzeilen, die eine neue Gruppe einleiten.");
-    }
-
-    function toString ($args = null) {
-        if (!$args["main_module"])
-            $args["main_module"] = "Main";
-        if (isset($args["colspan"]))
-            $visible["1"] = $args["colspan"];
-        else
-            $visible = array_count_values($this->config->getValue($args["main_module"], "visible"));
-
-        if ($tag = $this->config->getTag($this->name, "font", FALSE, TRUE))
-            $content = $tag . $args["content"] . "</font>";
-        else
-            $content = $args["content"];
-        $out = "<tr" . $this->config->getAttributes($this->name, "tr") . ">";
-        if ($visible["1"] > 1)
-            $out .= "<td colspan=\"{$visible['1']}\" ";
-        else
-            $out .= "<td";
-        $out .= $this->config->getAttributes($this->name, "td") . ">";
-        $out .= "$content</td></tr>\n";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTableHeader.class.php b/lib/extern/elements/ExternElementTableHeader.class.php
deleted file mode 100644
index 8e15114ef0c..00000000000
--- a/lib/extern/elements/ExternElementTableHeader.class.php
+++ /dev/null
@@ -1,68 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTableHeader.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTableHeader
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTableHeader.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementTableHeader extends ExternElement {
-
-    var $attributes = ["table_width", "table_align", "table_border", "table_bgcolor",
-                "table_bordercolor", "table_cellpadding", "table_cellspacing", "table_class",
-                "table_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TableHeader";
-        $this->real_name = _("Tabellenkopf");
-        $this->description = _("Angaben zur Gestaltung der Tabelle.");
-    }
-
-    function toString ($args = null) {
-        $out = "\n" . $this->config->getTag($this->name, "table") . "\n";
-        $out .= $args["content"] . "</table>\n";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTableHeadrow.class.php b/lib/extern/elements/ExternElementTableHeadrow.class.php
deleted file mode 100644
index 8d1da41a764..00000000000
--- a/lib/extern/elements/ExternElementTableHeadrow.class.php
+++ /dev/null
@@ -1,120 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTableHeadrow.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTableHeadrow
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTableHeadrow.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementTableHeadrow extends ExternElement {
-
-    var $attributes = ["tr_class", "tr_style", "th_height", "th_align",
-            "th_valign", "th_bgcolor", "th_bgcolor2_", "th_zebrath_", "th_class", "th_style",
-            "font_face", "font_size", "font_color", "font_class", "font_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TableHeadrow";
-        $this->real_name = _("Kopfzeile");
-        $this->description = _("Angaben, die die Kopfzeile einer Tabelle betreffen.");
-    }
-
-    function toString ($args = NULL) {
-        if (!$args["main_module"])
-            $args["main_module"] = "Main";
-
-        $alias = $this->config->getValue($args["main_module"], "aliases");
-        $visible = $this->config->getValue($args["main_module"], "visible");
-        // if all visible aliases are empty return empty string
-        $al_empty = TRUE;
-        if(is_array($alias)) {
-            for ($i = 0; $i < count($alias); $i++) {
-                if ($alias[$i] != '' && $visible[$i]) {
-                    $al_empty = FALSE;
-                    break;
-                }
-            }
-        }
-        if ($al_empty) {
-            return '';
-        }
-
-        $out = "<tr" . $this->config->getAttributes($this->name, "tr") . ">\n";
-        $i = 0;
-        $zebra = $this->config->getValue($this->name, "th_zebrath_");
-        $order = $this->config->getValue($args["main_module"], "order");
-        $width = $this->config->getValue($args["main_module"], "width");
-        $attributes[0] = $this->config->getAttributes($this->name, "th", TRUE);
-        $attributes[1] = $this->config->getAttributes($this->name, "th", FALSE);
-        $font = $this->config->getTag($this->name, "font", FALSE, TRUE);
-
-        foreach ($order as $column) {
-            // "zebra-effect" in head-row
-            if ($zebra) {
-                $set = $attributes[++$i % 2];
-            }
-            else {
-                $set = $attributes[1];
-            }
-
-            if ($visible[$column]) {
-            $out .= "<th$set width=\"" . $width[$column] . "\">";
-                if ($font) {
-                    $out .= $font;
-                }
-                if ($alias[$column]) {
-                    $out .= $alias[$column];
-                }
-                else  {
-                    $out .= "&nbsp;";
-                }
-                if ($font) {
-                    $out .= "</font>";
-                }
-                $out .= "</th>\n";
-            }
-        }
-        $out .= "</tr>\n";
-
-        return $out;
-    }
-}
diff --git a/lib/extern/elements/ExternElementTableParagraph.class.php b/lib/extern/elements/ExternElementTableParagraph.class.php
deleted file mode 100644
index 99619082ff9..00000000000
--- a/lib/extern/elements/ExternElementTableParagraph.class.php
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTableParagraph.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementParagraph
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTableParagraph.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementTableParagraph extends ExternElement {
-
-    var $attributes = ["table_width", "table_align", "table_valign", "table_border",
-            "table_bgcolor", "table_bordercolor", "table_cellpadding", "table_cellspacing",
-            "table_class", "table_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TableParagraph";
-        $this->real_name = _("Allgemeine Angaben zum Absatz");
-        $this->description = _("Der Absatz wird mit Hilfe einer Tabelle aufgebaut.");
-    }
-
-    function toString ($args = null) {
-        return "\n" . $this->config->getTag($this->name, "table") . $args["content"]
-                . "</table>";
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTableParagraphHeadline.class.php b/lib/extern/elements/ExternElementTableParagraphHeadline.class.php
deleted file mode 100644
index 773279d57ad..00000000000
--- a/lib/extern/elements/ExternElementTableParagraphHeadline.class.php
+++ /dev/null
@@ -1,72 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTableParagraphHeadline.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTableParagraphHeadline
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTableParagraphHeadline.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementTableParagraphHeadline extends ExternElement {
-
-    var $attributes = ["tr_class", "tr_style", "td_height", "td_align",
-            "td_valign", "td_bgcolor", "td_class", "td_style", "font_face",
-            "font_size", "font_color", "font_class", "font_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TableParagraphHeadline";
-        $this->real_name = _("Absatzüberschrift");
-        $this->description = _("Angaben zur Formatierung einer Absatzüberschrift.");
-    }
-
-    function toString ($args = null) {
-        $out = "\n" . $this->config->getTag($this->name, "tr") . "\n";
-        $out .= $this->config->getTag($this->name, "td");
-        if ($attributes_font = $this->config->getAttributes($this->name, "font"))
-            $out .= "<font$attributes_font>{$args['content']}</font>";
-        else
-            $out .= $args["content"];
-        $out .= "</td>\n</tr>";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTableParagraphSubHeadline.class.php b/lib/extern/elements/ExternElementTableParagraphSubHeadline.class.php
deleted file mode 100644
index 247a56253cc..00000000000
--- a/lib/extern/elements/ExternElementTableParagraphSubHeadline.class.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTableParagraphSubHeadline.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTableParagraphSubHeadline
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTableParagraphSubHeadline.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementTableParagraphSubHeadline extends ExternElement {
-
-    var $attributes = ["tr_class", "tr_style", "td_height", "td_align",
-            "td_valign", "td_bgcolor", "td_class", "td_style", "font_face",
-            "font_size", "font_color", "font_class", "font_style", "margin"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TableParagraphSubHeadline";
-        $this->real_name = _("Ãœberschrift eines Unterabsatzes");
-        $this->description = _("Angaben zur Formatierung der Ãœberschrift eines Unterabsatzes.");
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-        $out = '';
-        $tag_headline = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $content_table = $edit_form->getEditFormContent($this->attributes);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Einzug"));
-        $title = _('Linker Einzug') . ':';
-        $info = _("Geben Sie an, wie weit (Pixel) die Überschrift im Absatz links eingerückt werden soll.");
-        $content = $edit_form->editTextfieldGeneric("margin", $title, $info, 3, 3);
-
-        $content_table .= $edit_form->editContentTable($headline, $content);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-    function toString ($args = null) {
-        $out = $args["content"];
-        if ($attributes_font = $this->config->getAttributes($this->name, "font"))
-            $out = "<font$attributes_font>$out</font>";
-        if ($margin = $this->config->getValue($this->name, "margin")) {
-            $div = "<div style=\"margin-left:$margin;\">";
-            $div_end = "</div>";
-        }
-        else {
-            $div = "";
-            $div_end = "";
-        }
-        $out = $this->config->getTag($this->name, "td") . $div . $out . $div_end . "</td>\n";
-        $out = "\n" . $this->config->getTag($this->name, "tr") . "\n$out\n</tr>";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTableParagraphText.class.php b/lib/extern/elements/ExternElementTableParagraphText.class.php
deleted file mode 100644
index cce8a2e3e10..00000000000
--- a/lib/extern/elements/ExternElementTableParagraphText.class.php
+++ /dev/null
@@ -1,111 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTableParagraphText.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTableParagraphText
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTableParagraphText.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementTableParagraphText extends ExternElement {
-
-    var $attributes = ["tr_class", "tr_style", "td_height", "td_align",
-            "td_valign", "td_bgcolor", "td_class", "td_style", "font_face",
-            "font_size", "font_color", "font_class", "font_style", "margin"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TableParagraphText";
-        $this->real_name = _("Text im Absatz");
-        $this->description = _("Angaben zur Formatierung des Absatztextes.");
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-        $out = '';
-        $tag_headline = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $content_table = $edit_form->getEditFormContent($this->attributes);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Einzug"));
-        $title = _('Linker Einzug') . ':';
-        $info = _("Geben Sie an, wie weit (Pixel) der Text im Absatz links eingerückt werden soll.");
-        $content = $edit_form->editTextfieldGeneric("margin", $title, $info, 3, 3);
-
-        $content_table .= $edit_form->editContentTable($headline, $content);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-    function toString ($args = null) {
-        $out = $args["content"];
-        if ($attributes_font = $this->config->getAttributes($this->name, "font"))
-            $out = "<font$attributes_font>$out</font>";
-        if ($margin = $this->config->getValue($this->name, "margin")) {
-            $div = "<div style=\"margin-left:$margin;\">";
-            $div_end = "</div>";
-        }
-        else {
-            $div = "";
-            $div_end = "";
-        }
-        $out = $this->config->getTag($this->name, "td") . $div . $out . $div_end . "</td>\n";
-        $out = "\n" . $this->config->getTag($this->name, "tr") . "\n$out</tr>";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTableRow.class.php b/lib/extern/elements/ExternElementTableRow.class.php
deleted file mode 100644
index 28f6851807a..00000000000
--- a/lib/extern/elements/ExternElementTableRow.class.php
+++ /dev/null
@@ -1,110 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTableRow.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTableRow
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTableRow.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementTableRow extends ExternElement {
-
-    var $attributes = ["tr_class", "tr_style", "td_height", "td_align",
-            "td_valign", "td_bgcolor", "td_bgcolor2_", "td_zebratd_",
-            "td_class", "td_style", "font_face", "font_size", "font_color",
-            "font_class", "font_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TableRow";
-        $this->real_name = _("Datenzeile");
-        $this->description = _("Angaben zur Formatierung einer Datenzeile.");
-    }
-
-    function toString ($args = null) {
-        static $i = 0;
-        static $j = 0;
-
-        if ($args["color"] === 0 || $args["color"] === 1)
-            $i = $args["color"];
-        if (!$args["main_module"])
-            $args["main_module"] = "Main";
-        $order = $this->config->getValue($args["main_module"], "order");
-        $visible = $this->config->getValue($args["main_module"], "visible");
-        $attributes[0] = $this->config->getAttributes($this->name, "td", FALSE);
-        $attributes[1] = $this->config->getAttributes($this->name, "td", TRUE);
-        $font = $this->config->getTag($this->name, "font", FALSE, TRUE);
-        $zebra = $this->config->getValue($this->name, "td_zebratd_");
-        $width = $this->config->getValue($args["main_module"], "width");
-
-        // "horizontal zebra"
-        if ($zebra == "HORIZONTAL")
-            $set_td = $attributes[$i % 2];
-        else
-            $set_td = $attributes[0];
-
-        $out = "<tr" . $this->config->getAttributes($this->name, "tr") . ">";
-
-        foreach ($order as $column) {
-            if ($visible[$column]) {
-                // "vertical zebra"
-                if ($zebra == "VERTICAL")
-                    $set_td = $attributes[$j++ % 2];
-
-                if (!$args["content"][$args["data_fields"][$column]])
-                    $args["content"][$args["data_fields"][$column]] = "&nbsp;";
-                $out .= "<td$set_td";
-                if ($i == 0 && $width[$column] != '')
-                    $out .= " width=\"$width[$column]\"";
-                $out .= '>';
-                if ($font)
-                    $out .= $font . $args["content"][$args["data_fields"][$column]] . "</font>";
-                else
-                    $out .= $args["content"][$args["data_fields"][$column]];
-                $out .= "</td>\n";
-            }
-        }
-        $out .= "</tr>\n";
-        $i++;
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTableRowTwoColumns.class.php b/lib/extern/elements/ExternElementTableRowTwoColumns.class.php
deleted file mode 100644
index 8565c7d7b2d..00000000000
--- a/lib/extern/elements/ExternElementTableRowTwoColumns.class.php
+++ /dev/null
@@ -1,117 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTableRowTwoColumns.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTableRowTwoColumns
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTableRowTwoColumns.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementTableRowTwoColumns extends ExternElement {
-
-    var $attributes = ["tr_height", "tr_class", "tr_style", "td1_align",
-            "td1_valign", "td1_bgcolor", "td1_class", "td1_style", "font1_face",
-            "font1_size", "td1width", "font1_color", "font1_class", "font1_style",
-            "td2_align", "td2_valign", "td2_bgcolor", "td2_class", "td2_style",
-            "font2_face", "font2_size", "font2_color", "font2_class", "font2_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TableRowTwoColumns";
-        $this->real_name = _("Zeile mit zwei Spalten");
-        $this->description = _("Angaben zur Formatierung einer Tabellenzeile mit zwei Spalten.");
-
-        $this->headlines = [_("Angaben zum HTML-Tag &lt;tr&gt;"), _("Linke Spalte &lt;td&gt;"),
-            _("Linke Spalte &lt;font&gt;"), _("Rechte Spalte &lt;td&gt;"),
-            _("Rechte Spalte &lt;font&gt;")];
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $attributes = ["tr_height", "tr_class", "tr_style"];
-        $headline = ["tr" => $this->headlines[0]];
-        $content_table = $edit_form->getEditFormContent($attributes, $headline);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline($this->headlines[1]);
-
-        $title = _('Spaltenbreite') . ':';
-        $info = _("Breite der Spalte in Prozent.");
-        $table = $edit_form->editTextfieldGeneric("td1width", $title, $info, 2, 2);
-
-        $table .= $edit_form->editAlign("td1_align");
-        $table .= $edit_form->editValign("td1_valign");
-        $table .= $edit_form->editBgcolor("td1_bgcolor");
-        $table .= $edit_form->editClass("td1_class");
-        $table .= $edit_form->editStyle("td1_style");
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $attributes = ["font1_face",   "font1_size","font1_color", "font1_class",
-                "font1_style", "td2_align", "td2_valign", "td2_bgcolor", "td2_class",
-                "td2_style", "font2_face", "font2_size", "font2_color", "font2_class", "font2_style"];
-        $headline = ["font1" => $this->headlines[2], "td2" => $this->headlines[3],
-                "font2" => $this->headlines[4]];
-        $content_table .= $edit_form->getEditFormContent($attributes, $headline);
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTemplateGeneric.class.php b/lib/extern/elements/ExternElementTemplateGeneric.class.php
deleted file mode 100644
index bdd8a3315d7..00000000000
--- a/lib/extern/elements/ExternElementTemplateGeneric.class.php
+++ /dev/null
@@ -1,135 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTemplateGeneric.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTemplateGeneric
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTemplateGeneric.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'vendor/exTpl/Template.php';
-
-class ExternElementTemplateGeneric extends ExternElement {
-
-    var $attributes = ['template'];
-    var $markers;
-    var $new_datafields = FALSE;
-
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = '') {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TemplateGeneric";
-        $this->real_name = _("Standard Template");
-        $this->description = _("Hier kann ein Template hinterlegt werden.");
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-        $config = [
-            'template' => _("Geben Sie hier das Template ein.")
-        ];
-
-        return $config;
-    }
-
-    function toStringEdit ($post_vars = '', $faulty_values = '',
-            $edit_form = '', $anker = '') {
-        global $EXTERN_MODULE_TYPES;
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-        $out = '';
-        $tag_headline = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Beschreibung der Marker"));
-        $table = $edit_form->editMarkerDescription($this->markers, $this->new_datafields);
-
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Template"));
-        $info = _("Geben Sie hier das Template ein.");
-        $table = $edit_form->editTextareaGeneric('template', '', $info, 40, 80);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $hidden = [$this->getName() . '_chdate' => time()];
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName(), $hidden);
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-    function toString ($args = null) {
-        $template = $this->config->getValue($this->getName(), 'template');
-        $template = preg_replace(
-            ['/###([\w-]+)###/', '/<!--\s+BEGIN\s+([\w-]+)\s+-->/', '/<!--\s+END\s+[\w-]+\s+-->/'],
-            ['{% $1 %}', '{% foreach $1 %}', '{% endforeach %}'], $template);
-        exTpl\Template::setTagMarkers('{%', '%}');
-
-        try {
-            $template = new exTpl\Template($template);
-            $out = $template->render((array) $args['content'] + (array) $args['content']['__GLOBAL__']);
-        } catch (exTpl\TemplateParserException $ex) {
-            $out = $GLOBALS['EXTERN_ERROR_MESSAGE'] . '<br>' . $ex->getMessage();
-        }
-
-        return $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == 'template') {
-        //  return preg_match("|^https?://.*$|i", $value);
-            return FALSE;
-        }
-        return FALSE;
-    }
-}
diff --git a/lib/extern/elements/ExternElementTreeBackLink.class.php b/lib/extern/elements/ExternElementTreeBackLink.class.php
deleted file mode 100644
index 91b68ad76ea..00000000000
--- a/lib/extern/elements/ExternElementTreeBackLink.class.php
+++ /dev/null
@@ -1,97 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTreeBackLink.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTreeBackLink
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTreeBackLink.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementTreeBackLink extends ExternElement {
-
-    var $attributes = ["linktext", "image", "table_bgcolor",
-                "table_cellpadding", "table_cellspacing", "table_class",
-                "table_style", "td_height", "td_align", "td_valign", "td_bgcolor",
-                "td_class", "td_style", "font_face", "font_size", "font_color",
-                "font_class", "font_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TreeBackLink";
-        $this->real_name = _("Link auf übergeordnete Ebene");
-        $this->description = _("Formatierung des Link auf die übergeordnete Ebene in einer Baum-Navigation.");
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-        if ($faulty_values == '')
-            $faulty_values = [];
-        $out = '';
-        $tag_headline = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben"));
-        $title = _('Link-Text') . ':';
-        $info = _("Geben Sie den Text ein, der auf die übergeordnete Ebene verweist (Link zurück).");
-        $content = $edit_form->editTextfieldGeneric("linktext", $title, $info, 25, 60);
-
-        $title = _('Link-Bild (URL)') . ':';
-        $info = _("Geben Sie die URL eines Bildes ein, das als Link auf die übergeordnete Ebene verweist (z.B. Back-Button).");
-        $content .= $edit_form->editTextfieldGeneric("image", $title, $info, 40, 200);
-
-        $content_table = $edit_form->editContentTable($headline, $content);
-        $content_table .= $edit_form->editBlankContent();
-
-        $out = $content_table . $edit_form->getEditFormContent($this->attributes);
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($out, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTreeKids.class.php b/lib/extern/elements/ExternElementTreeKids.class.php
deleted file mode 100644
index bb33850f5f0..00000000000
--- a/lib/extern/elements/ExternElementTreeKids.class.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTreeKids.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTreeKids
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTreeKids.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementTreeKids extends ExternElement {
-
-    var $attributes = ["table_bgcolor",
-                "table_cellpadding", "table_cellspacing", "table_class",
-                "table_style", "td_height", "td_align", "td_valign", "td_bgcolor",
-                "td_class", "td_style", "font_face", "font_size", "font_color",
-                "font_class", "font_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TreeKids";
-        $this->real_name = _("Ausgabe der Unterebenen");
-        $this->description = _("Formatierung der Unterebenen in einer Baum-Navigation.");
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTreeLevelContent.class.php b/lib/extern/elements/ExternElementTreeLevelContent.class.php
deleted file mode 100644
index 5f52efb9097..00000000000
--- a/lib/extern/elements/ExternElementTreeLevelContent.class.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTreeLevelContent.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTreeLevelContent
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTreeLevelContent.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementTreeLevelContent extends ExternElement {
-
-    var $attributes = ["table_bgcolor",
-                "table_cellpadding", "table_cellspacing", "table_class",
-                "table_style", "td_height", "td_align", "td_valign", "td_bgcolor",
-                "td_class", "td_style", "font_face", "font_size", "font_color",
-                "font_class", "font_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TreeLevelContent";
-        $this->real_name = _("Inhalt der Ebene");
-        $this->description = _("Formatierung des Ebeneninhalts in einer Baum-Navigation.");
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTreeLevelName.class.php b/lib/extern/elements/ExternElementTreeLevelName.class.php
deleted file mode 100644
index 65b7fe5c909..00000000000
--- a/lib/extern/elements/ExternElementTreeLevelName.class.php
+++ /dev/null
@@ -1,62 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTreeLevelName.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTreeLevelName
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTreeLevelName.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementTreeLevelName extends ExternElement {
-
-    var $attributes = ["table_bgcolor",
-                "table_cellpadding", "table_cellspacing", "table_class",
-                "table_style", "td_height", "td_align", "td_valign", "td_bgcolor",
-                "td_class", "td_style", "font_face", "font_size", "font_color",
-                "font_class", "font_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TreeLevelName";
-        $this->real_name = _("Name der Ebene");
-        $this->description = _("Formatierung des Ebenennamens in einer Baum-Navigation.");
-    }
-
-}
diff --git a/lib/extern/elements/ExternElementTreePath.class.php b/lib/extern/elements/ExternElementTreePath.class.php
deleted file mode 100644
index 3073acfb76d..00000000000
--- a/lib/extern/elements/ExternElementTreePath.class.php
+++ /dev/null
@@ -1,90 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementTreePath.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementTreePath
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementTreePath.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementTreePath extends ExternElement {
-
-    var $attributes = ["delimiter", "font_size", "font_face", "font_color", "font_class", "font_style",
-            "a_class", "a_style"];
-
-    /**
-    * Constructor
-    *
-    * @param array config
-    */
-    function __construct($config = "") {
-        if ($config)
-            $this->config = $config;
-
-        $this->name = "TreePath";
-        $this->real_name = _("Navigations-Pfad");
-        $this->description = _("Eigenschaften des Navigations-Pfades innerhalb einer Baum-Navigation.");
-    }
-
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-        if ($faulty_values == '')
-            $faulty_values = [];
-        $out = '';
-        $tag_headline = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben"));
-        $title = _('Pfad-Trennzeichen') . ':';
-        $info = _("Geben Sie ein oder mehrere Zeichen ein, die als Trennzeichen zwischen den Links im Navigations-Pfad erscheinen sollen.");
-        $content = $edit_form->editTextfieldGeneric("delimiter", $title, $info, 25, 50);
-
-        $content_table = $edit_form->editContentTable($headline, $content);
-        $content_table .= $edit_form->editBlankContent();
-
-        $out = $content_table . $edit_form->getEditFormContent($this->attributes);
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($out, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainDownload.class.php b/lib/extern/elements/main/ExternElementMainDownload.class.php
deleted file mode 100644
index 0468b4b1893..00000000000
--- a/lib/extern/elements/main/ExternElementMainDownload.class.php
+++ /dev/null
@@ -1,255 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter005: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainDownload.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainDownload
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainDownload.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementMainDownload extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct ($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'order', 'visible', 'aliases', 'width', 'sort',
-                'wholesite', 'lengthdesc', 'nameformat', 'urlcss', 'title',
-                'nodatatext', 'dateformat', 'language', 'iconpic', 'icontxt',
-                'iconpdf', 'iconppt', 'iconxls', 'iconrtf', 'iconzip',
-                'icondefault', 'copyright', 'author'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-        $config = [
-            "name" => "",
-            "order" => "|0|1|2|3|4|5",
-            "visible" => "|1|1|1|1|1|1",
-            "aliases" => "||"._("Name")."|"._("Beschreibung")."|"._("Upload am")."|"
-                    ._("Größe")."|"._("Upload durch"),
-            "width" => "|1%|20%|25%|15%|15%|24%",
-            "sort" => "|0|0|0|1|0|0",
-            "wholesite" => "",
-            "lengthdesc" => "",
-            "nameformat" => "",
-            "urlcss" => "",
-            "title" => _("Download"),
-            "nodatatext" => _("Keine Dateien vorhanden"),
-            "dateformat" => "%d. %b. %Y",
-            "language" => "",
-            "config" => "",
-            "srilink" => "",
-            "iconpic" => "",
-            "icontxt" => "",
-            "iconpdf" => "",
-            "iconppt" => "",
-            "iconxls" => "",
-            "iconrtf" => "",
-            "iconzip" => "",
-            "icondefault" => "",
-            "copyright" => htmlReady(Config::get()->UNI_NAME_CLEAN
-                    . " ({$GLOBALS['UNI_CONTACT']})"),
-            "author" => ""
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        $out = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben zum Tabellenaufbau"));
-
-        $edit_function = $this->edit_function;
-        $table = $edit_form->$edit_function($this->field_names, ["sort" => [0]]);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('HTML-Header/Footer') . ':';
-        $info = _("Anwählen, wenn die Seite als komplette HTML-Seite ausgegeben werden soll, z.B. bei direkter Verlinkung oder in einem Frameset.");
-        $values = "1";
-        $names = "";
-        $table = $edit_form->editCheckboxGeneric("wholesite", $title, $info, $values, $names);
-
-        $title = _('Max. Länge der Beschreibung') . ':';
-        $info = _("Geben Sie an, wieviele Zeichen der Beschreibung der Datei ausgegeben werden sollen.");
-        $table .= $edit_form->editTextfieldGeneric("lengthdesc", $title, $info, 3, 3);
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table .= $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Datumsformat') . ':';
-        $info = _("Wählen Sie, wie Datumsangaben formatiert werden sollen.");
-        $values = ["%d. %b. %Y", "%d.%m.%Y", "%d.%m.%y", "%d. %B %Y", "%m/%d/%y"];
-        $names = [_("25. Nov. 2003"), _("25.11.2003"), _("25.11.03"),
-                _("25. November 2003"), _("11/25/03")];
-        $table .= $edit_form->editOptionGeneric("dateformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        $title = _('Stylesheet-Datei') . ':';
-        $info = _("Geben Sie hier die URL Ihrer Stylesheet-Datei an.");
-        $table .= $edit_form->editTextfieldGeneric("urlcss", $title, $info, 50, 200);
-
-        $title = _('Seitentitel') . ':';
-        $info = _("Geben Sie hier den Titel der Seite ein. Der Titel wird bei der Anzeige im Web-Browser in der Titelzeile des Anzeigefensters angezeigt.");
-        $table .= $edit_form->editTextfieldGeneric("title", $title, $info, 50, 200);
-
-        $title = _('Keine Dateien') . ':';
-        $info = _("Dieser Text wird an Stelle der Tabelle ausgegeben, wenn keine Dateien zum Download verfügbar sind.");
-        $table .= $edit_form->editTextareaGeneric("nodatatext", $title, $info, 3, 50);
-
-        $title = _('Copyright') . ':';
-        $info = _("Geben Sie hier einen Copyright-Vermerk an. Dieser wird im Meta-Tag \"copyright\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("copyright", $title, $info, 50, 200);
-
-        $title = _('Autor') . ':';
-        $info = _("Geben Sie hier den Namen des Seitenautors an. Dieser wird im Meta-Tag \"author\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("author", $title, $info, 50, 200);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Eigene Icons"));
-        $icon_attributes = ["iconpic", "icontxt", "iconpdf", "iconppt",
-                "iconxls", "iconrtf", "iconzip", "icondefault"];
-        $icon_titles = [
-            _('Bilder') . ':',
-            _('Text') . ':',
-            _('Adobe pdf') . ':',
-            _('Powerpoint (ppt)') . ':',
-            _('Excel (xls)') . ':',
-            _('Rich Text (rtf)') . ':',
-            _('ZIP-Dateien') . ':',
-            _('sonstige Dateien') . ':',
-        ];
-        $icon_infos = [
-            _("Geben Sie die URL eines Bildes ein, dass als Icon für Bild-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-            _("Geben Sie die URL eines Bildes ein, dass als Icon für Text-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-            _("Geben Sie die URL eines Bildes ein, dass als Icon für PDF-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-            _("Geben Sie die URL eines Bildes ein, dass als Icon für Powerpoint-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-            _("Geben Sie die URL eines Bildes ein, dass als Icon für Excel-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-            _("Geben Sie die URL eines Bildes ein, dass als Icon für RTF-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-            _("Geben Sie die URL eines Bildes ein, dass als Icon für komprimierte Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-            _("Geben Sie die URL eines Bildes ein, dass als Icon für alle anderen Dateiformate dienen soll. ")
-        ];
-        $info_add = _("Wenn Sie keine URL angeben, wird ein Standard-Icon ausgegeben.");
-
-        $table = "";
-        if (is_array($icon_attributes)) {
-            for ($i = 0; $i < sizeof($icon_attributes); $i++) {
-                $table .= $edit_form->editTextfieldGeneric($icon_attributes[$i],
-                    $icon_titles[$i], $icon_infos[$i] . $info_add, 50, 200);
-            }
-        }
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        switch ($attribute) {
-            case "lengthdesc" :
-                return !preg_match("|^\d{0,3}$|", $value);
-            case "timelocale" :
-                return ($value != "de_DE" || $value != "en_US");
-            case "iconpic" :
-            case "icontxt" :
-            case "iconpdf" :
-            case "iconppt" :
-            case "iconxls" :
-            case "iconrtf" :
-            case "iconzip" :
-            case "icondefault" :
-                return $value
-                        && (
-                            preg_match("/(<|>|\"|<script|<php)/i", $value)
-                            || !preg_match("/^[^.\/\\\].*\.(png|jpg|jpeg|gif)$/i", $value)
-                        );
-        }
-
-        return false;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainGlobal.class.php b/lib/extern/elements/main/ExternElementMainGlobal.class.php
deleted file mode 100644
index ad1c0521a93..00000000000
--- a/lib/extern/elements/main/ExternElementMainGlobal.class.php
+++ /dev/null
@@ -1,230 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainPersons.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainPersons
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainPersons.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'lib/dates.inc.php';
-
-class ExternElementMainGlobal extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'semstart', 'semrange', 'semswitch',
-                'nameformat', 'language', 'wholesite', 'urlcss', 'copyright', 'author',
-                'defaultadr'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            "name" => "",
-            "semstart" => "",
-            "semrange" => "",
-            "semswitch" => "",
-            "wholesite" => "",
-            "nameformat" => "",
-            "language" => "",
-            "urlcss" => "",
-            "copyright" => htmlReady(Config::get()->UNI_NAME_CLEAN
-                    . " ({$GLOBALS['UNI_CONTACT']})"),
-            "author" => '',
-            "defaultadr" => '0'
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        // get semester data
-        $semester_data = Semester::findAllVisible(false);
-
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der globalen Konfiguration"));
-        $table = $edit_form->editName("name");
-
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Anzuzeigende Lehrveranstaltungen"));
-
-        $title = _('Startsemester') . ':';
-        $info = _("Geben Sie das erste anzuzeigende Semester an. Die Angaben \"vorheriges\", \"aktuelles\" und \"nächstes\" beziehen sich immer auf das laufende Semester und werden automatisch angepasst.");
-        $current_sem = get_sem_num_sem_browse();
-        if ($current_sem === FALSE) {
-            $names = [_("keine Auswahl"), _("aktuelles"), _("nächstes")];
-            $values = ["", "current", "next"];
-        }
-        else if ($current_sem === TRUE) {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles")];
-            $values = ["", "previous", "current"];
-        }
-        else {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles"), "nächstes"];
-            $values = ["", "previous", "current", "next"];
-        }
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $sem["name"];
-            $values[] = $sem_num + 1;
-        }
-        $table = $edit_form->editOptionGeneric("semstart", $title, $info, $values, $names);
-
-        $title = _('Anzahl der anzuzeigenden Semester') . ':';
-        $info = _("Geben Sie an, wieviele Semester (ab o.a. Startsemester) angezeigt werden sollen.");
-        $names = [_("keine Auswahl")];
-        $values = [""];
-        $i = 1;
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $i++;
-            $values[] = $sem_num + 1;
-        }
-        $table .= $edit_form->editOptionGeneric("semrange", $title, $info, $values, $names);
-
-        $title = _('Umschalten des aktuellen Semesters') . ':';
-        $info = _("Geben Sie an, wieviele Wochen vor Semesterende automatisch auf das nächste Semester umgeschaltet werden soll.");
-        $names = [_("keine Auswahl"), _("am Semesterende"), _("1 Woche vor Semesterende")];
-        for ($i = 2; $i < 13; $i++)
-            $names[] = sprintf(_("%s Wochen vor Semesterende"), $i);
-        $values = ["", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
-        $table .= $edit_form->editOptionGeneric("semswitch", $title, $info, $values, $names);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table = $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        $title = _('Standard-Adresse') . ':';
-        $info = _("Wenn Sie diese Option wählen, wird die Standard-Adresse ausgegeben, die jede(r) Mitarbeiter(in) bei seinen universitären Daten auswählen kann. Wählen Sie diese Option nicht, wenn immer die Adresse der Einrichtung ausgegeben werden soll.");
-        $table .= $edit_form->editCheckboxGeneric('defaultadr', $title, $info, '1', '0');
-
-        $title = _('HTML-Header/Footer') . ':';
-        $info = _("Anwählen, wenn die Seite als komplette HTML-Seite ausgegeben werden soll, z.B. bei direkter Verlinkung oder in einem Frameset.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("wholesite", $title, $info, $values, $names);
-
-        $title = _('Stylesheet-Datei') . ':';
-        $info = _("Geben Sie hier die URL Ihrer Stylesheet-Datei an.");
-        $table .= $edit_form->editTextfieldGeneric("urlcss", $title, $info, 50, 200);
-
-        $title = _('Copyright') . ':';
-        $info = _("Geben Sie hier einen Copyright-Vermerk an. Dieser wird im Meta-Tag \"copyright\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("copyright", $title, $info, 50, 200);
-
-        $title = _('Autor') . ':';
-        $info = _("Geben Sie hier den Namen des Seitenautors an. Dieser wird im Meta-Tag \"author\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("author", $title, $info, 50, 200);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkFormValues () {
-
-
-        if ($fault = parent::checkFormValues()) {
-
-            if ($_POST["Main_nameformat"] == ""
-                    && $fault["Main_nameformat"][0] == TRUE) {
-                $fault["Main_nameformat"][0] = FALSE;
-            }
-
-
-
-            return $fault;
-        }
-
-        return FALSE;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == 'defaultadr') {
-            if (!isset($_POST["Main_$attribute"])) {
-                $_POST["Main_$attribute"] = 0;
-                return FALSE;
-            }
-
-            return !($value == '1' || $value == '');
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainLecturedetails.class.php b/lib/extern/elements/main/ExternElementMainLecturedetails.class.php
deleted file mode 100644
index dedc42ef21c..00000000000
--- a/lib/extern/elements/main/ExternElementMainLecturedetails.class.php
+++ /dev/null
@@ -1,232 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainLecturedetails.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainDownload
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainLecturedetails.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementMainLecturedetails extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'genericdatafields', 'order', 'visible', 'aliases',
-                'aliaspredisc', 'aliasfirstmeeting', 'headlinerow', 'rangepathlevel',
-                'studipinfo',   'studiplink', 'studiplinktarget', 'wholesite',
-                'nameformat', 'urlcss', 'title', 'language', 'copyright', 'author'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-        $config = [
-            "name" => "",
-            "order" => "|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15",
-            "visible" => "|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1",
-            "aliases" => "|"._('Untertitel').": |"._("Lehrende").": |"._('Veranstaltungsart')
-                .": |"._('Veranstaltungstyp').": |"._('Beschreibung').": |"._('Ort').": |"._('Semester')
-                .": |"._('Zeiten').": |"._('Veranstaltungsnummer').": |"._('Teilnehmende')
-                .": |"._('Voraussetzungen').": |"._('Lernorganisation').": |"._('Leistungsnachweis')
-                .": |"._('Bereichseinordnung').": |"._('Sonstiges').": |"._('ECTS-Punkte'),
-            "aliaspredisc" => _('Vorbesprechung') . ": ",
-            "aliasfirstmeeting" => _('Erster Termin') . ": ",
-            "headlinerow" => "1",
-            "rangepathlevel" => "1",
-            "studipinfo" => "1",
-            "studiplink" => "top",
-            "studiplinktarget" => "admin",
-            "wholesite" => "",
-            "nameformat" => "",
-            "urlcss" => "",
-            "title" => _("Veranstaltungsdaten"),
-            "language" => "",
-            "copyright" => htmlReady(Config::get()->UNI_NAME_CLEAN
-                    . " ({$GLOBALS['UNI_CONTACT']})"),
-            "author" => ""
-        ];
-
-        get_default_generic_datafields($config, "sem");
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        update_generic_datafields($this->config, $this->data_fields, $this->field_names, "sem");
-        $out = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben zum Tabellenaufbau"));
-
-        $table = $edit_form->editMainSettings($this->field_names, "", ["sort", "width", "widthpp"]);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Textersetzungen"));
-
-        $titles = _('Vorbesprechung') . ':';
-        $info = _("Geben Sie eine alternative Bezeichnung ein.");
-        $table = $edit_form->editTextfieldGeneric("aliaspredisc", $titles, $info, 40, 150);
-
-        $titles = _('Erster Termin') . ':';
-        $info = _("Geben Sie eine alternative Bezeichnung ein.");
-        $table .= $edit_form->editTextfieldGeneric("aliasfirstmeeting", $titles, $info, 40, 150);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Absatzüberschrift in eigener Zeile') . ':';
-        $info = _("Diese Option bewirkt, dass die Überschrift eines Absatzes in einer eigenen Zeile ausgegeben wird. Ist diese Option nicht ausgewählt, wird die Überschrift dem Text des Absatzes direkt vorangestellt.");
-        $values = "1";
-        $names = "";
-        $table = $edit_form->editCheckboxGeneric("headlinerow", $title, $info, $values, $names);
-
-        $title = _('Bereichspfad ab Ebene') . ':';
-        $info = _("Wählen Sie, ab welcher Ebene der Bereichspfad ausgegeben werden soll.");
-        $values = ["1", "2", "3", "4", "5"];
-        $names = ["1", "2", "3", "4", "5"];
-        $table .= $edit_form->editOptionGeneric("rangepathlevel", $title, $info, $values, $names);
-
-        $title = _('Stud.IP-Info') . ':';
-        $info = _("Diese Option zeigt weitere Informationen aus der Stud.IP-Datenbank an (Anzahl Teilnehmender, Posting, Dokumente usw.).");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("studipinfo", $title, $info, $values, $names);
-
-        $title = _('Stud.IP-Link') . ':';
-        $info = _("Ausgabe eines Links, der direkt zum Stud.IP-Administrationsbereich verweist.");
-        $value = ["top", "bottom", "0"];
-        $names = [_("oberhalb"), _("unterhalb der Tabelle"), _("ausblenden")];
-        $table .= $edit_form->editRadioGeneric("studiplink", $title, $info, $value, $names);
-
-        $title = _('Stud.IP-Link-Ziel') . ':';
-        $info = _("Ziel des Stud.IP-Links. Entweder direkter Einsprung zur Anmeldeseite oder in den Administrationsbereich (nur für berechtigte Nutzer) der Veranstaltung");
-        $value = ["signin", "admin"];
-        $names = [_("Anmeldung"), _("Administrationsbereich")];
-        $table .= $edit_form->editRadioGeneric("studiplinktarget", $title, $info, $value, $names);
-
-        $title = _('HTML-Header/Footer') . ':';
-        $info = _("Anwählen, wenn die Seite als komplette HTML-Seite ausgegeben werden soll, z.B. bei direkter Verlinkung oder in einem Frameset.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("wholesite", $title, $info, $values, $names);
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table .= $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        $title = _('Stylesheet-Datei') . ':';
-        $info = _("Geben Sie hier die URL Ihrer Stylesheet-Datei an.");
-        $table .= $edit_form->editTextfieldGeneric("urlcss", $title, $info, 50, 200);
-
-        $title = _('Seitentitel') . ':';
-        $info = _("Geben Sie hier den Titel der Seite ein. Der Titel wird bei der Anzeige im Web-Browser in der Titelzeile des Anzeigefensters angezeigt.");
-        $table .= $edit_form->editTextfieldGeneric("title", $title, $info, 50, 200);
-
-        $title = _('Copyright') . ':';
-        $info = _("Geben Sie hier einen Copyright-Vermerk an. Dieser wird im Meta-Tag \"copyright\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("copyright", $title, $info, 50, 200);
-
-        $title = _('Autor') . ':';
-        $info = _("Geben Sie hier den Namen des Seitenautors an. Dieser wird im Meta-Tag \"author\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("author", $title, $info, 50, 200);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == "studipinfo" || $attribute == "headlinerow") {
-            // This is especially for checkbox-values. If there is no checkbox
-            // checked, the variable is not declared and it is necessary to set the
-            // variable to "".
-            if (!isset($_POST[$this->name . "_" . $attribute])) {
-                $_POST[$this->name . "_" . $attribute] = "";
-                return FALSE;
-            }
-            return !($value == "1" || $value == "");
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainLectures.class.php b/lib/extern/elements/main/ExternElementMainLectures.class.php
deleted file mode 100644
index 79fa8a9b102..00000000000
--- a/lib/extern/elements/main/ExternElementMainLectures.class.php
+++ /dev/null
@@ -1,300 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainLectures.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainLectures
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainLectures.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'lib/dates.inc.php';
-
-class ExternElementMainLectures extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'grouping', 'semrange', 'semstart', 'semswitch',
-                'allseminars', 'rangepathlevel', 'addinfo', 'time', 'lecturer', 'semclasses',
-                'textlectures', 'textgrouping', 'textnogroups', 'aliasesgrouping', 'wholesite',
-                'nameformat', 'language', 'urlcss', 'title', 'copyright', 'author'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            "name" => "",
-            "grouping" => "3",
-            "semstart" => "",
-            "semrange" => "",
-            "semswitch" => "",
-            "allseminars" => "",
-            "rangepathlevel" => "1",
-            "addinfo" => "1",
-            "time" => "1",
-            "lecturer" => "1",
-            "semclasses" => "|1",
-            "textlectures" => " " . _("Veranstaltungen"),
-            "textgrouping" => _("Gruppierung") . ": ",
-            "textnogroups" => _("keine Studienbereiche eingetragen"),
-            "aliasesgrouping" => "|"._("Semester")."|"._("Bereich")."|"._("Lehrende")."|"
-                    ._("Typ")."|"._("Einrichtung"),
-            "wholesite" => "",
-            "nameformat" => "",
-            "language" => "",
-            "urlcss" => "",
-            "title" => _("Lehrveranstaltungen"),
-            "copyright" => htmlReady(Config::get()->UNI_NAME_CLEAN
-                    . " ({$GLOBALS['UNI_CONTACT']})"),
-            "author" => ""
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-        global $SEM_CLASS;
-
-        // get semester data
-        $semester_data = Semester::findAllVisible(false);
-
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben Seitenaufbau"));
-
-        $title = _('Gruppierung') . ':';
-        $info = _("Wählen Sie, wie die Veranstaltungen gruppiert werden sollen.");
-        $values = ["0", "1", "2", "3", "4"];
-        $names = [_("Semester"), _("Bereich"), _("Lehrende"),
-                _("Typ"), _("Einrichtung")];
-        $table = $edit_form->editOptionGeneric("grouping", $title, $info, $values, $names);
-
-        $title = _('Startsemester') . ':';
-        $info = _("Geben Sie das erste anzuzeigende Semester an. Die Angaben \"vorheriges\", \"aktuelles\" und \"nächstes\" beziehen sich immer auf das laufende Semester und werden automatisch angepasst.");
-        $current_sem = get_sem_num_sem_browse();
-        if ($current_sem === FALSE) {
-            $names = [_("keine Auswahl"), _("aktuelles"), _("nächstes")];
-            $values = ["", "current", "next"];
-        }
-        else if ($current_sem === TRUE) {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles")];
-            $values = ["", "previous", "current"];
-        }
-        else {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles"), "nächstes"];
-            $values = ["", "previous", "current", "next"];
-        }
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $sem["name"];
-            $values[] = $sem_num + 1;
-        }
-        $table .= $edit_form->editOptionGeneric("semstart", $title, $info, $values, $names);
-
-        $title = _('Anzahl der anzuzeigenden Semester') . ':';
-        $info = _("Geben Sie an, wieviele Semester (ab o.a. Startsemester) angezeigt werden sollen.");
-        $names = [_("keine Auswahl")];
-        $values = [""];
-        $i = 1;
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $i++;
-            $values[] = $sem_num + 1;
-        }
-        $table .= $edit_form->editOptionGeneric("semrange", $title, $info, $values, $names);
-
-        $title = _('Umschalten des aktuellen Semesters') . ':';
-        $info = _("Geben Sie an, wieviele Wochen vor Semesterende automatisch auf das nächste Semester umgeschaltet werden soll.");
-        $names = [_("keine Auswahl"), _("am Semesterende"), _("1 Woche vor Semesterende")];
-        for ($i = 2; $i < 13; $i++)
-            $names[] = sprintf(_("%s Wochen vor Semesterende"), $i);
-        $values = ["", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
-        $table .= $edit_form->editOptionGeneric("semswitch", $title, $info, $values, $names);
-
-        $title = _('Veranstaltungen beteiligter Institute anzeigen') . ':';
-        $info = _("Wählen Sie diese Option, um Veranstaltungen anzuzeigen, bei denen diese Einrichtung als beteiligtes Institut eingetragen ist.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("allseminars", $title, $info, $values, $names);
-
-        $title = _('Bereichspfad ab Ebene') . ':';
-        $info = _("Wählen Sie, ab welcher Ebene der Bereichspfad ausgegeben werden soll.");
-        $values = ["1", "2", "3", "4", "5"];
-        $table .= $edit_form->editOptionGeneric("rangepathlevel", $title, $info, $values, $values);
-
-        $title = _('Anzahl Veranstaltungen/Gruppierung anzeigen') . ':';
-        $info = _("Wählen Sie diese Option, wenn die Anzahl der Veranstaltungen und die gewählte Gruppierungsart angezeigt werden sollen.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("addinfo", $title, $info, $values, $names);
-
-        $title = _('Termine/Zeiten anzeigen') . ':';
-        $info = _("Wählen Sie diese Option, wenn Termine und Zeiten der Veranstaltung unter dem Veranstaltungsnamen angezeigt werden sollen.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("time", $title, $info, $values, $names);
-
-        $title = _('Lehrende anzeigen') . ':';
-        $info = _("Wählen Sie diese Option, wenn die Namen der Lehrenden der Veranstaltung angezeigt werden sollen.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("lecturer", $title, $info, $values, $names);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Ausgabe bestimmter Veranstaltungsklassen"));
-
-        unset($names);
-        unset($values);
-        $info = _("Wählen Sie die anzuzeigenden Veranstaltungsklassen aus.");
-        foreach ($SEM_CLASS as $key => $class) {
-            $values[] = $key;
-            $names[] = $class["name"];
-        }
-        $table = $edit_form->editCheckboxGeneric("semclasses", $names, $info, $values, "");
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Textersetzungen"));
-
-        $title = _('Anzahl Veranstaltungen') . ':';
-        $info = _("Geben Sie einen Text ein, der nach der Anzahl der Veranstaltungen steht. Nur wirksam, wenn die Ausgabe der Anzahl der Veranstaltungen und der Gruppierung aktiviert wurde.");
-        $table = $edit_form->editTextfieldGeneric("textlectures", $title, $info, 40, 150);
-
-        $title = _('Gruppierungsinformation') . ':';
-        $info = _("Geben Sie einen Text ein, der vor der Gruppierungsart steht. Nur wirksam, wenn die Ausgabe der Anzahl der Veranstaltungen und der Gruppierung aktiviert wurde.");
-        $table .= $edit_form->editTextfieldGeneric("textgrouping", $title, $info, 40, 150);
-
-        $title = _('&quot;Keine Studienbereiche&quot;') . ':';
-        $info = _("Geben Sie einen Text ein, der Angezeigt wird, wenn Lehrveranstaltungen vorliegen, die keinem Bereich zugeordnet sind. Nur wirksam in Gruppierung nach Bereich.");
-        $table .= $edit_form->editTextfieldGeneric("textnogroups", $title, $info, 40, 150);
-
-        $titles = [_("Semester"), _("Bereich"), _("Lehrende"), _("Typ"), _("Einrichtung")];
-        $info = _("Geben Sie eine Bezeichnung für die entsprechende Gruppierungsart ein.");
-        $table .= $edit_form->editTextfieldGeneric("aliasesgrouping", $titles, $info, 40, 150);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table = $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        $title = _('HTML-Header/Footer') . ':';
-        $info = _("Anwählen, wenn die Seite als komplette HTML-Seite ausgegeben werden soll, z.B. bei direkter Verlinkung oder in einem Frameset.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("wholesite", $title, $info, $values, $names);
-
-        $title = _('Stylesheet-Datei') . ':';
-        $info = _("Geben Sie hier die URL Ihrer Stylesheet-Datei an.");
-        $table .= $edit_form->editTextfieldGeneric("urlcss", $title, $info, 50, 200);
-
-        $title = _('Seitentitel') . ':';
-        $info = _("Geben Sie hier den Titel der Seite ein. Der Titel wird bei der Anzeige im Web-Browser in der Titelzeile des Anzeigefensters angezeigt.");
-        $table .= $edit_form->editTextfieldGeneric("title", $title, $info, 50, 200);
-
-        $title = _('Copyright') . ':';
-        $info = _("Geben Sie hier einen Copyright-Vermerk an. Dieser wird im Meta-Tag \"copyright\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("copyright", $title, $info, 50, 200);
-
-        $title = _('Autor') . ':';
-        $info = _("Geben Sie hier den Namen des Seitenautors an. Dieser wird im Meta-Tag \"author\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("author", $title, $info, 50, 200);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == "allseminars") {
-            // This is necessary for checkbox-values. If there is no checkbox
-            // checked, the variable is not declared and it is necessary to set the
-            // variable to "".
-            if (!isset($_POST[$this->name . "_" . $attribute])) {
-                $_POST[$this->name . "_" . $attribute] = "";
-                return FALSE;
-            }
-            return !($value == "1" || $value == "");
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainLecturestable.class.php b/lib/extern/elements/main/ExternElementMainLecturestable.class.php
deleted file mode 100644
index ed102551bd1..00000000000
--- a/lib/extern/elements/main/ExternElementMainLecturestable.class.php
+++ /dev/null
@@ -1,312 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainLecturestable.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainLectures
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainLecturestable.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementMainLecturestable extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'order', 'visible', 'aliases', 'width', 'widthpp',
-                'grouping', 'semstart', 'semrange', 'semswitch', 'allseminars', 'rangepathlevel',
-                'addinfo', 'time', 'lecturer', 'repeatheadrow', 'semclasses', 'textlectures',
-                'textgrouping', 'textnogroups', 'aliasesgrouping', 'wholesite', 'nameformat',
-                'language', 'urlcss', 'title', 'copyright', 'author', 'genericdatafields'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            "name" => "",
-            "order" => "|0|1|2|3|4|5|6|7",
-            "visible" => "|0|1|0|1|1|1|1|1",
-            "aliases" => "|"._("Veranstaltungsnummer")."|"._("Titel")."|"._("Untertitel")."|"._("Status")
-                    ."|"._("Ort")."|"._("Veranstaltungsart")."|"._("Zeiten")."|"._("Lehrende"),
-            "width" => "|0%|15%|0%|10%|15%|20%|25%|15%",
-            "widthpp" => "",
-            "grouping" => "3",
-            "semstart" => "",
-            "semrange" => "",
-            "semswitch" => "",
-            "allseminars" => "",
-            "rangepathlevel" => "1",
-            "addinfo" => "1",
-            "time" => "1",
-            "lecturer" => "1",
-            "repeatheadrow" => "",
-            "semclasses" => "|1",
-            "textlectures" => " " . _("Veranstaltungen"),
-            "textgrouping" => _("Gruppierung") . ": ",
-            "textnogroups" => _("keine Studienbereiche eingetragen"),
-            "aliasesgrouping" => "|"._("Semester")."|"._("Bereich")."|"._("Lehrende")."|"
-                    ._("Typ")."|"._("Einrichtung"),
-            "wholesite" => "",
-            "nameformat" => "",
-            "language" => "",
-            "urlcss" => "",
-            "title" => _("Lehrveranstaltungen"),
-            "copyright" => htmlReady(Config::get()->UNI_NAME_CLEAN
-                    . " ({$GLOBALS['UNI_CONTACT']})"),
-            "author" => ""
-        ];
-
-        get_default_generic_datafields($config, "sem");
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        // get semester data
-        $semester_data = Semester::findAllVisible(false);
-
-        update_generic_datafields($this->config, $this->data_fields, $this->field_names, "sem");
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben zum Tabellenaufbau"));
-
-        $edit_function = $this->edit_function;
-        $table = $edit_form->$edit_function($this->field_names, [], ["sort"]);
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben Seitenaufbau"));
-
-        $title = _('Gruppierung') . ':';
-        $info = _("Wählen Sie, wie die Veranstaltungen gruppiert werden sollen.");
-        $values = ["0", "1", "2", "3", "4"];
-        $names = [_("Semester"), _("Bereich"), _("Lehrende"),
-                _("Typ"), _("Einrichtung")];
-        $table = $edit_form->editOptionGeneric("grouping", $title, $info, $values, $names);
-
-        $title = _('Startsemester') . ':';
-        $info = _("Geben Sie das erste anzuzeigende Semester an. Die Angaben \"vorheriges\", \"aktuelles\" und \"nächstes\" beziehen sich immer auf das laufende Semester und werden automatisch angepasst.");
-        $current_sem = get_sem_num_sem_browse();
-        if ($current_sem === FALSE) {
-            $names = [_("keine Auswahl"), _("aktuelles"), _("nächstes")];
-            $values = ["", "current", "next"];
-        }
-        else if ($current_sem === TRUE) {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles")];
-            $values = ["", "previous", "current"];
-        }
-        else {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles"), "nächstes"];
-            $values = ["", "previous", "current", "next"];
-        }
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $sem["name"];
-            $values[] = $sem_num + 1;
-        }
-        $table .= $edit_form->editOptionGeneric("semstart", $title, $info, $values, $names);
-
-        $title = _('Anzahl der anzuzeigenden Semester') . ':';
-        $info = _("Geben Sie an, wieviele Semester (ab o.a. Startsemester) angezeigt werden sollen.");
-        $names = [_("keine Auswahl")];
-        $values = [""];
-        $i = 1;
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $i++;
-            $values[] = $sem_num + 1;
-        }
-        $table .= $edit_form->editOptionGeneric("semrange", $title, $info, $values, $names);
-
-        $title = _('Umschalten des aktuellen Semesters') . ':';
-        $info = _("Geben Sie an, wieviele Wochen vor Semesterende automatisch auf das nächste Semester umgeschaltet werden soll.");
-        $names = [_("keine Auswahl"), _("am Semesterende"), _("1 Woche vor Semesterende")];
-        for ($i = 2; $i < 13; $i++)
-            $names[] = sprintf(_("%s Wochen vor Semesterende"), $i);
-        $values = ["", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
-        $table .= $edit_form->editOptionGeneric("semswitch", $title, $info, $values, $names);
-
-        $title = _('Veranstaltungen beteiligter Institute anzeigen') . ':';
-        $info = _("Wählen Sie diese Option, um Veranstaltungen anzuzeigen, bei denen diese Einrichtung als beteiligtes Institut eingetragen ist.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("allseminars", $title, $info, $values, $names);
-
-        $title = _('Bereichspfad ab Ebene') . ':';
-        $info = _("Wählen Sie, ab welcher Ebene der Bereichspfad ausgegeben werden soll.");
-        $values = ["1", "2", "3", "4", "5"];
-        $names = ["1", "2", "3", "4", "5"];
-        $table .= $edit_form->editOptionGeneric("rangepathlevel", $title, $info, $values, $names);
-
-        $title = _('Anzahl Veranstaltungen/Gruppierung anzeigen') . ':';
-        $info = _("Wählen Sie diese Option, wenn die Anzahl der Veranstaltungen und die gewählte Gruppierungsart angezeigt werden sollen.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("addinfo", $title, $info, $values, $names);
-
-        $title = _('Spaltenüberschriften wiederholen') . ':';
-        $info = _("Wiederholung der Spaltenüberschriften über oder unter der Gruppierungszeile.");
-        $values = ["above", "beneath", ""];
-        $names = [_("über"), _("unter Gruppierungszeile"), _("keine")];
-        $table .= $edit_form->editRadioGeneric("repeatheadrow", $title, $info, $values, $names);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Ausgabe bestimmter Veranstaltungsklassen"));
-
-        $table = "";
-        unset($names);
-        unset($values);
-        $info = _("Wählen Sie die anzuzeigenden Veranstaltungsklassen aus.");
-
-        foreach ($GLOBALS["SEM_CLASS"] as $key => $class) {
-            $values[] = $key;
-            $names[] = $class["name"];
-        }
-        $table = $edit_form->editCheckboxGeneric("semclasses", $names, $info, $values, "");
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Textersetzungen"));
-
-        $title = _('Anzahl Veranstaltungen') . ':';
-        $info = _("Geben Sie einen Text ein, der nach der Anzahl der Veranstaltungen steht. Nur wirksam, wenn die Ausgabe der Anzahl der Veranstaltungen und der Gruppierung aktiviert wurde.");
-        $table = $edit_form->editTextfieldGeneric("textlectures", $title, $info, 40, 150);
-
-        $title = _('Gruppierungsinformation') . ':';
-        $info = _("Geben Sie einen Text ein, der vor der Gruppierungsart steht. Nur wirksam, wenn die Ausgabe der Anzahl der Veranstaltungen und der Gruppierung aktiviert wurde.");
-        $table .= $edit_form->editTextfieldGeneric("textgrouping", $title, $info, 40, 150);
-
-        $title = _('&quot;Keine Studienbereiche&quot;') . ':';
-        $info = _("Geben Sie einen Text ein, der Angezeigt wird, wenn Lehrveranstaltungen vorliegen, die keinem Bereich zugeordnet sind. Nur wirksam in Gruppierung nach Bereich.");
-        $table .= $edit_form->editTextfieldGeneric("textnogroups", $title, $info, 40, 150);
-
-        $titles = [_("Semester"), _("Bereich"), _("Lehrende"), _("Typ"), _("Einrichtung")];
-        $info = _("Geben Sie eine Bezeichnung für die entsprechende Gruppierungsart ein.");
-        $table .= $edit_form->editTextfieldGeneric("aliasesgrouping", $titles, $info, 40, 150);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table = $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        $title = _('HTML-Header/Footer') . ':';
-        $info = _("Anwählen, wenn die Seite als komplette HTML-Seite ausgegeben werden soll, z.B. bei direkter Verlinkung oder in einem Frameset.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("wholesite", $title, $info, $values, $names);
-
-        $title = _('Stylesheet-Datei') . ':';
-        $info = _("Geben Sie hier die URL Ihrer Stylesheet-Datei an.");
-        $table .= $edit_form->editTextfieldGeneric("urlcss", $title, $info, 50, 200);
-
-        $title = _('Seitentitel') . ':';
-        $info = _("Geben Sie hier den Titel der Seite ein. Der Titel wird bei der Anzeige im Web-Browser in der Titelzeile des Anzeigefensters angezeigt.");
-        $table .= $edit_form->editTextfieldGeneric("title", $title, $info, 50, 200);
-
-        $title = _('Copyright') . ':';
-        $info = _("Geben Sie hier einen Copyright-Vermerk an. Dieser wird im Meta-Tag \"copyright\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("copyright", $title, $info, 50, 200);
-
-        $title = _('Autor') . ':';
-        $info = _("Geben Sie hier den Namen des Seitenautors an. Dieser wird im Meta-Tag \"author\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("author", $title, $info, 50, 200);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == "allseminars") {
-            // This is especially for checkbox-values. If there is no checkbox
-            // checked, the variable is not declared and it is necessary to set the
-            // variable to "".
-            if (!isset($_POST[$this->name . "_" . $attribute])) {
-                $_POST[$this->name . "_" . $attribute] = "";
-                return FALSE;
-            }
-            return !($value == "1" || $value == "");
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainNews.class.php b/lib/extern/elements/main/ExternElementMainNews.class.php
deleted file mode 100644
index 76d4de95c32..00000000000
--- a/lib/extern/elements/main/ExternElementMainNews.class.php
+++ /dev/null
@@ -1,210 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainNews.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainNews
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainNews.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementMainNews extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'order', 'visible', 'aliases', 'width',
-                'width_pp', 'sort', 'studiplink', 'wholesite', 'nameformat',
-                'dateformat', 'language',   'urlcss', 'title', 'nodatatext',
-                'copyright', 'author', 'showdateauthor', 'notauthorlink'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            "name" => "",
-            "order" => "|0|1",
-            "visible" => "|1|1",
-            "aliases" => "|"._("Datum")."|"._("Nachricht"),
-            "width" => "|10%|90%",
-            "widthpp" => "",
-            "sort" => "|1|0",
-            "wholesite" => "",
-            "studiplink" => "top",
-            "nameformat" => "",
-            "dateformat" => "%d. %b. %Y",
-            "language" => "",
-            "urlcss" => "",
-            "title" => _("News"),
-            "nodatatext" => _("Keine aktuellen News"),
-            "copyright" => htmlReady(Config::get()->UNI_NAME_CLEAN
-                    . " ({$GLOBALS['UNI_CONTACT']})"),
-            "author" => "",
-            "showdateauthor" => "0",
-            "notauthorlink" => ""
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben zum Tabellenaufbau"));
-
-        $edit_function = $this->edit_function;
-        $table = $edit_form->$edit_function($this->field_names, []);
-
-        $title = _('Datum/Autor anzeigen') . ':';
-        $info = _("Anzeige von Datum und Autor, nur Datum oder nur Autor in der Spalte Datum/Autor.");
-        $values = ["0", "date", "author"];
-        $names = [_("Datum und Autor"), _("nur Datum"), ("nur Autor")];
-        $table .= $edit_form->editRadioGeneric("showdateauthor", $title, $info, $values, $names);
-
-        $title = _('Autorenname nicht verlinken') . ':';
-        $info = _("Wählen Sie diese Option, wenn der Autorenname nicht auf das Modul Personendetails verlinkt werden soll.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("notauthorlink", $title, $info, $values, $names);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev", "last"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr."), _("Meyer")];
-        $table = $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Datumsformat') . ':';
-        $info = _("Wählen Sie, wie Datumsangaben formatiert werden sollen.");
-        $values = ["%d. %b. %Y", "%d.%m.%Y", "%d.%m.%y", "%d. %B %Y", "%m/%d/%y"];
-        $names = [_("25. Nov. 2003"), "25.11.2003", "25.11.03",
-                _("25. November 2003"), "11/25/03"];
-        $table .= $edit_form->editOptionGeneric("dateformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        $title = _('Stud.IP-Link') . ':';
-        $info = _("Ausgabe eines Links, der direkt zum Stud.IP-Administrationsbereich verweist.");
-        $values = ["top", "bottom", "0"];
-        $names = [_("oberhalb"), _("unterhalb der Tabelle"), _("ausblenden")];
-        $table .= $edit_form->editRadioGeneric("studiplink", $title, $info, $values, $names);
-
-        $title = _('HTML-Header/Footer') . ':';
-        $info = _("Anwählen, wenn die Seite als komplette HTML-Seite ausgegeben werden soll, z.B. bei direkter Verlinkung oder in einem Frameset.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("wholesite", $title, $info, $values, $names);
-
-        $title = _('Stylesheet-Datei') . ':';
-        $info = _("Geben Sie hier die URL Ihrer Stylesheet-Datei an.");
-        $table .= $edit_form->editTextfieldGeneric("urlcss", $title, $info, 50, 200);
-
-        $title = _('Seitentitel') . ':';
-        $info = _("Geben Sie hier den Titel der Seite ein. Der Titel wird bei der Anzeige im Web-Browser in der Titelzeile des Anzeigefensters angezeigt.");
-        $table .= $edit_form->editTextfieldGeneric("title", $title, $info, 50, 200);
-
-        $title = _('Keine News') . ':';
-        $info = _("Dieser Text wird an Stelle der Tabelle ausgegeben, wenn keine News verfügbar sind.");
-        $table .= $edit_form->editTextareaGeneric("nodatatext", $title, $info, 3, 50);
-
-        $title = _('Copyright') . ':';
-        $info = _("Geben Sie hier einen Copyright-Vermerk an. Dieser wird im Meta-Tag \"copyright\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("copyright", $title, $info, 50, 200);
-
-        $title = _('Autor') . ':';
-        $info = _("Geben Sie hier den Namen des Seitenautors an. Dieser wird im Meta-Tag \"author\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("author", $title, $info, 50, 200);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == 'notauthorlink') {
-            if (!isset($_POST["Main_$attribute"])) {
-                $_POST["Main_$attribute"] = 0;
-                return FALSE;
-            }
-
-            return !($value == "1" || $value == "");
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainNewsticker.class.php b/lib/extern/elements/main/ExternElementMainNewsticker.class.php
deleted file mode 100644
index 6a320dc5175..00000000000
--- a/lib/extern/elements/main/ExternElementMainNewsticker.class.php
+++ /dev/null
@@ -1,191 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter005: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainNewsticker.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainNewsticker
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainNews.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementMainNewsticker extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'rows', 'length', 'pause', 'frequency',
-                'starttext', 'endtext', 'nodatatext', 'automaticstart', 'jsonly', 'style'];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            "name" => "",
-            "rows" => "3",
-            "length" => "40",
-            "pause" => "2000",
-            "frequency" => "15",
-            "starttext" => _("Der Ticker wird geladen..."),
-            "endtext" => _("Ende des Tickers."),
-            "nodatatext" => _("Keine aktuellen News"),
-            "automaticstart" => "1",
-            "style" => ""
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Tick-Frequenz') . ':';
-        $info = _("Geben Sie an, wieviele Zeichen pro Sekunde ausgegeben werden sollen.");
-        $table = $edit_form->editTextfieldGeneric("frequency", $title, $info, 2, 2);
-
-        $title = _('Pause zwischen News') . ':';
-        $info = _("Geben Sie an, wie lange der Ticker warten soll (in Millisekunden), bis er die nächste News ausgibt.");
-        $table .= $edit_form->editTextfieldGeneric("pause", $title, $info, 4, 4);
-
-        $title = _('Text am Anfang der Ausgabe') . ':';
-        $info = _("Dieser Text wird ausgegeben, während die News in den Ticker geladen werden, also am Anfang des ersten Durchlaufs.");
-        $table .= $edit_form->editTextfieldGeneric("starttext", $title, $info, 50, 200);
-
-        $title = _('Text am Ende der Ausgabe') . ':';
-        $info = _("Dieser Text wird ausgegeben, nachdem alle News angezeigt wurden, also am Ende jedes Durchlaufs.");
-        $table .= $edit_form->editTextfieldGeneric("endtext", $title, $info, 50, 200);
-
-        $title = _('Keine News') . ':';
-        $info = _("Dieser Text wird ausgegeben, wenn keine News verfügbar sind.");
-        $table .= $edit_form->editTextfieldGeneric("nodatatext", $title, $info, 50, 200);
-
-        $title = _("Ticker sofort starten?");
-        $info = _("Wählen Sie diese Option, wenn das Modul den Ticker automatisch starten soll. Bei längeren Ladezeiten der Seite, in der Sie den Ticker integriert haben, kann es sinnvoll sein, den Ticker erst zu starten, wenn die Seite komplett geladen ist. Deaktivieren Sie dafür diese Option, und tragen Sie im <body>-Tag der Seite das Attribut onLoad=\"newsticker\" ein.");
-        $table .= $edit_form->editCheckboxGeneric("automaticstart", $title, $info, "1", "");
-
-        $title = _("Nur JavaScript-Funktion ausgeben?");
-        $info = _("Wählen Sie diese Option, wenn das Modul nur die JavaScript-Funktion ausgeben soll. Die Funktionsname ist newsticker(). Sie kann z.B. innerhalb von <textarea> eingesetzt werden. Beispiel:");
-        $info .= "\n<!DOCTYPE html>\n";
-        $info .= "<html>\n\t<head>\n\t\t";
-        $info .= "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n";
-        $info .= "\t\t<title>Newsticker</title>\n\t</head>\n";
-        $info .= "\t\t<script src=\"Link to SRI-Interface for newsticker. Look at info-page (i).\" type=\"text/javascript\">\n";
-        $info .= "\t<body>\n\t\t<form name=\"tickform\">\n\t\t\t";
-        $info .= "<textarea name=\"tickfield\" rows=\"5\" cols=\"50\">Loading ticker...</textarea>\n";
-        $info .= "\t\t</form>\n\t\t<script type=\"text/javascript\">\n\t\t\t";
-        $info .= "newsticker();\n\t\t</script>\n\t</body>\n</html>";
-        $table .= $edit_form->editCheckboxGeneric("jsonly", $title, $info, "1", "");
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Angaben zum HTML-Tag &lt;textarea&gt;"));
-
-        $title = _('Anzahl Zeilen im Ausgabefenster') . ':';
-        $info = _("Geben Sie die Anzahl der Zeilen an. Es sind nur Werte zwischen 1 und 10 erlaubt.");
-        $table = $edit_form->editTextfieldGeneric("rows", $title, $info, 2, 2);
-
-        $title = _('Anzahl der Zeichen pro Zeile') . ':';
-        $info = _("Geben Sie die Anzahl der Zeichen pro Zeile an. Es sind nur Werte zwischen 10 und 200 erlaubt.");
-        $table .= $edit_form->editTextfieldGeneric("length", $title, $info, 3, 3);
-
-        $table .= $edit_form->editStyle("style");
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        switch ($attribute) {
-            case "rows" :
-                return !(preg_match("'^\d{1,2}$'", $value) && $value > 0 && $value < 11);
-            case "length" :
-                return !(preg_match("'^\d{1,3}$'", $value) && $value > 9 && $value < 201);
-            case "automaticstart" :
-            case "jsonly" :
-                if (!isset($_POST[$this->name . "_" . $attribute])) {
-                    $_POST[$this->name . "_" . $attribute] = 0;
-                    return FALSE;
-                }
-                return !($value == "1" || $value == "0");
-            case "frequency" :
-                return !(preg_match("'^\d{1,2}$'", $value) && $value > 0);
-            case "pause" :
-                return !(preg_match("'^\d{1,4}$'", $value) && $value > 0);
-            case "starttext" :
-            case "endtext" :
-            case "nodatatext" :
-                return mb_strlen($value) > 200;
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainPersondetails.class.php b/lib/extern/elements/main/ExternElementMainPersondetails.class.php
deleted file mode 100644
index 2253e2b8ac9..00000000000
--- a/lib/extern/elements/main/ExternElementMainPersondetails.class.php
+++ /dev/null
@@ -1,222 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainPersondetails.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainPersondetails
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainPersondetails.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementMainPersondetails extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'genericdatafields', 'order', 'visible',
-                'aliases', 'width', 'showcontact', 'showimage', 'wholesite', 'nameformat',
-                'dateformat', 'language', 'studiplink', 'urlcss', 'title', 'copyright',
-                'author'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            "name" => '',
-            /*
-            "order" => '|0|1|2|3|4|5|6|7|8',
-            "visible" => '|1|1|1|1|1|1|1|1|1',
-            "aliases" => '||'._("Lebenslauf").'|'._("Schwerpunkte").'|'._("Lehrveranstaltungen").'|'
-                    ._("Aktuell").'|'._("Termine").'|'._("Publikationen").'|'._("Literaturlisten").'|',
-            */
-            "order" => '|0|1|2|3|4|5|6|7',
-            "visible" => '|1|1|1|1|1|1|1|1',
-            "aliases" => '||'._("Lebenslauf").'|'._("Schwerpunkte").'|'._("Lehrveranstaltungen").'|'
-                    ._("Aktuell").'|'._("Termine").'|'._("Publikationen").'|',
-            "showcontact" => '1',
-            "showimage" => 'right',
-            "wholesite" => '0',
-            "nameformat" => '',
-            "dateformat" => '%d. %b. %Y',
-            "language" => '',
-            "studiplink" => 'top',
-            "urlcss" => '',
-            "title" => _("MitarbeiterInnen"),
-            "copyright" => htmlReady(Config::get()->UNI_NAME_CLEAN
-                    . " ({$GLOBALS['UNI_CONTACT']})"),
-            "author" => ''
-        ];
-
-        get_default_generic_datafields($config, "user");
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        update_generic_datafields($this->config, $this->data_fields["content"],
-                $this->field_names["content"], "user");
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben zum Tabellenaufbau"));
-
-        $edit_function = $this->edit_function;
-        $table = $edit_form->editMainSettings($this->field_names["content"],
-                ["aliases" => [0, 7]], ["sort", "width", "widthpp"]);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Kontaktdaten anzeigen') . ':';
-        $info = _("Anwählen, wenn die Kontaktdaten (Anschrift, Email, Telefon usw.) angezeigt werden sollen.");
-        $values = "1";
-        $names = "";
-        $table = $edit_form->editCheckboxGeneric("showcontact", $title, $info, $values, $names);
-
-        $title = _('Bild anzeigen') . ':';
-        $info = _("Wählen Sie, ob ein vom Nutzer in Stud.IP eingestelltes Bild links oder rechts neben den Kontaktdaten angezeigt werden soll.");
-        $value = ["left", "right", "0"];
-        $names = [_("links"), _("rechts"), _("nicht anzeigen")];
-        $table .= $edit_form->editRadioGeneric("showimage", $title, $info, $value, $names);
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table .= $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Datumsformat') . ':';
-        $info = _("Wählen Sie, wie Datumsangaben formatiert werden sollen.");
-        $values = ["%d. %b. %Y", "%d.%m.%Y", "%d.%m.%y", "%d. %B %Y", "%m/%d/%y"];
-        $names = [_("25. Nov. 2003"), _("25.11.2003"), _("25.11.03"),
-                _("25. November 2003"), _("11/25/03")];
-        $table .= $edit_form->editOptionGeneric("dateformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        $title = _('Stud.IP-Link') . ':';
-        $info = _("Ausgabe eines Links, der direkt zum Stud.IP-Administrationsbereich verweist.");
-        $value = ["top", "bottom", "0"];
-        $names = [_("oberhalb"), _("unterhalb der Tabelle"), _("ausblenden")];
-        $table .= $edit_form->editRadioGeneric("studiplink", $title, $info, $value, $names);
-
-        $title = _('HTML-Header/Footer') . ':';
-        $info = _("Anwählen, wenn die Seite als komplette HTML-Seite ausgegeben werden soll, z.B. bei direkter Verlinkung oder in einem Frameset.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("wholesite", $title, $info, $values, $names);
-
-        $title = _('Stylesheet-Datei') . ':';
-        $info = _("Geben Sie hier die URL Ihrer Stylesheet-Datei an.");
-        $table .= $edit_form->editTextfieldGeneric("urlcss", $title, $info, 50, 200);
-
-        $title = _('Seitentitel') . ':';
-        $info = _("Geben Sie hier den Titel der Seite ein. Der Titel wird bei der Anzeige im Web-Browser in der Titelzeile des Anzeigefensters angezeigt.");
-        $table .= $edit_form->editTextfieldGeneric("title", $title, $info, 50, 200);
-
-        $title = _('Copyright') . ':';
-        $info = _("Geben Sie hier einen Copyright-Vermerk an. Dieser wird im Meta-Tag \"copyright\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("copyright", $title, $info, 50, 200);
-
-        $title = _('Autor') . ':';
-        $info = _("Geben Sie hier den Namen des Seitenautors an. Dieser wird im Meta-Tag \"author\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("author", $title, $info, 50, 200);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == "showcontact") {
-            if (!isset($_POST["Main_$attribute"])) {
-                $_POST["Main_$attribute"] = 0;
-                return FALSE;
-            }
-
-            return !($value == "1" || $value == "");
-        }
-
-        if ($attribute == "showimage") {
-            if (!isset($_POST["Main_$attribute"])) {
-                $_POST["Main_$attribute"] = 0;
-                return FALSE;
-            }
-
-            return !($value == "left" || $value == "right" || $value == "0");
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainPersons.class.php b/lib/extern/elements/main/ExternElementMainPersons.class.php
deleted file mode 100644
index ee20144df58..00000000000
--- a/lib/extern/elements/main/ExternElementMainPersons.class.php
+++ /dev/null
@@ -1,217 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainPersons.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainPersons
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainPersons.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementMainPersons extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'genericdatafields', 'order', 'visible', 'aliases', 'width',
-                'width_pp', 'sort', 'groupsalias', 'groupsvisible', 'grouping', 'wholesite',
-                'nameformat', 'repeatheadrow', 'urlcss', 'title', 'bodystyle', 'bodyclass',
-                'copyright', 'author', 'defaultadr'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-        if ($groups = get_all_statusgruppen($this->config->range_id))
-            $groups = "|" . implode("|", array_keys($groups));
-        else
-            $groups = "";
-
-        $config = [
-            "name" => "",
-            "order" => "|0|1|2|3|4",
-            "visible" => "|1|1|1|1|1",
-            "aliases" => "|"._("Name")."|"._("Telefon")."|"._("Raum")."|"._("E-Mail")."|"._("Sprechzeiten"),
-            "width" => "|30%|15%|15%|20%|20%",
-            "widthpp" => "",
-            "sort" => "|1|0|0|0|0",
-            "groupsalias" => "",
-            "groupsvisible" => $groups,
-            "grouping" => "1",
-            "wholesite" => "",
-            "nameformat" => "",
-            "repeatheadrow" => "",
-            "urlcss" => "",
-            "title" => _("MitarbeiterInnen"),
-            "nodatatext" => "",
-            "config" => "",
-            "srilink" => "",
-            "copyright" => htmlReady(Config::get()->UNI_NAME_CLEAN
-                    . " ({$GLOBALS['UNI_CONTACT']})"),
-            "author" => "",
-            "defaultadr" => ''
-        ];
-
-        get_default_generic_datafields($config, "user");
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        update_generic_datafields($this->config, $this->data_fields, $this->field_names, "user");
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben zum Tabellenaufbau"));
-
-        $edit_function = $this->edit_function;
-        for ($i = 5; $i < sizeof($this->field_names); $i++)
-            $hide_sort[] = $i;
-        $table = $edit_form->$edit_function($this->field_names, ['sort' => $hide_sort]);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Anzeige von Gruppen"));
-
-        $table = $edit_form->editGroups();
-        if ($table) {
-            $title = _('Gruppierung') . ':';
-            $info = _("Personen nach Gruppen/Funktionen gruppieren.");
-            $values = "1";
-            $table .= $edit_form->editCheckboxGeneric("grouping", $title, $info, $values, "");
-        }
-        else {
-            $text = _("An dieser Einrichtung wurden noch keine Gruppen/Funktionen angelegt, oder es wurden diesen noch keine Personen zugeordnet.");
-            $text .= _("Das Modul gibt nur Daten von Personen aus, die einer Gruppe/Funktion zugeordnet sind.");
-            $table = $edit_form->editTextblock('<font size="2"><b>' . $text . '</b></font>');
-        }
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer, Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table = $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Spaltenüberschriften wiederholen') . ':';
-        $info = _("Wiederholung der Spaltenüberschriften über oder unter der Gruppierungszeile.");
-        $values = ["above", "beneath", ""];
-        $names = [_("über"), _("unter Gruppenname"), _("keine")];
-        $table .= $edit_form->editRadioGeneric("repeatheadrow", $title, $info, $values, $names);
-
-        $title = _('Standard-Adresse') . ':';
-        $info = _("Wenn Sie diese Option wählen, wird die Standard-Adresse ausgegeben, die jede(r) Mitarbeiter(in) bei seinen universitären Daten auswählen kann. Wählen Sie diese Option nicht, wenn immer die Adresse der Einrichtung ausgegeben werden soll.");
-        $table .= $edit_form->editCheckboxGeneric('defaultadr', $title, $info, '1', '0');
-
-        $title = _('HTML-Header/Footer') . ':';
-        $info = _("Anwählen, wenn die Seite als komplette HTML-Seite ausgegeben werden soll, z.B. bei direkter Verlinkung oder in einem Frameset.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("wholesite", $title, $info, $values, $names);
-
-        $title = _('Stylesheet-Datei') . ':';
-        $info = _("Geben Sie hier die URL Ihrer Stylesheet-Datei an.");
-        $table .= $edit_form->editTextfieldGeneric("urlcss", $title, $info, 50, 200);
-
-        $title = _('Seitentitel') . ':';
-        $info = _("Geben Sie hier den Titel der Seite ein. Der Titel wird bei der Anzeige im Web-Browser in der Titelzeile des Anzeigefensters angezeigt.");
-        $table .= $edit_form->editTextfieldGeneric("title", $title, $info, 50, 200);
-
-        $title = _('Copyright') . ':';
-        $info = _("Geben Sie hier einen Copyright-Vermerk an. Dieser wird im Meta-Tag \"copyright\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("copyright", $title, $info, 50, 200);
-
-        $title = _('Autor') . ':';
-        $info = _("Geben Sie hier den Namen des Seitenautors an. Dieser wird im Meta-Tag \"author\" ausgegeben, wenn Sie die Option \"HTML-Header/Footer\" angewählt haben.");
-        $table .= $edit_form->editTextfieldGeneric("author", $title, $info, 50, 200);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == "grouping" || $attribute == "defaultadr") {
-            // This is especially for checkbox-values. If there is no checkbox
-            // checked, the variable is not declared and it is necessary to set the
-            // variable to "0".
-            if (!isset($_POST[$this->name . "_" . $attribute])) {
-                $_POST[$this->name . "_" . $attribute] = "";
-                return FALSE;
-            }
-            return !($value == '1' || $value == '');
-        }
-
-        return FALSE;
-    }
-
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainRangelecturetree.class.php b/lib/extern/elements/main/ExternElementMainRangelecturetree.class.php
deleted file mode 100644
index 1bfb897b4b0..00000000000
--- a/lib/extern/elements/main/ExternElementMainRangelecturetree.class.php
+++ /dev/null
@@ -1,125 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainRangelecturetree.class.php
-*
-* This class defines
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementRangelecturetree
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainRangelecturetree.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementMainRangeLectureTree extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'table_width', 'table_align', 'table_border', 'table_bgcolor',
-                'table_bordercolor', 'table_cellpadding', 'table_cellspacing', 'table_class',
-                'table_style', 'wholesite', 'urlcss', 'title', 'bodystyle',
-                'bodyclass'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $attributes = ["table_width", "table_align", "table_border", "table_bgcolor",
-                "table_bordercolor", "table_cellpadding", "table_cellspacing", "table_class",
-                "table_style"];
-        $headline = ["table" => _("Umschließende Tabelle")];
-        $content_table .= $edit_form->getEditFormContent($attributes, $headline);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('HTML-Header/Footer') . ':';
-        $info = _("Anwählen, wenn die Seite als komplette HTML-Seite ausgegeben werden soll, z.B. bei direkter Verlinkung oder in einem Frameset.");
-        $wholesite_values = "1";
-        $wholesite_names = "";
-        $table = $edit_form->editCheckboxGeneric("wholesite", $title, $info, $wholesite_values, $wholesite_names);
-
-        $title = _('Stylesheet-Datei') . ':';
-        $info = _("Geben Sie hier die URL Ihrer Stylesheet-Datei an.");
-        $table .= $edit_form->editTextfieldGeneric("urlcss", $title, $info, 50, 200);
-
-        $title = _('Seitentitel') . ':';
-        $info = _("Geben Sie hier den Titel der Seite ein. Der Titel wird bei der Anzeige im Web-Browser in der Titelzeile des Anzeigefensters angezeigt.");
-        $table .= $edit_form->editTextfieldGeneric("title", $title, $info, 50, 200);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainSemlecturetree.class.php b/lib/extern/elements/main/ExternElementMainSemlecturetree.class.php
deleted file mode 100644
index bd874dd04c9..00000000000
--- a/lib/extern/elements/main/ExternElementMainSemlecturetree.class.php
+++ /dev/null
@@ -1,126 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainSemlecturetree.class.php
-*
-* This class defines
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainSemlecturetree
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainSemlecturetree.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementMainSemLectureTree extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'table_width', 'table_align', 'table_border', 'table_bgcolor',
-                'table_bordercolor', 'table_cellpadding', 'table_cellspacing', 'table_class',
-                'table_style', 'wholesite', 'urlcss', 'title', 'bodystyle',
-                'bodyclass'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $attributes = ["table_width", "table_align", "table_border", "table_bgcolor",
-                "table_bordercolor", "table_cellpadding", "table_cellspacing", "table_class",
-                "table_style"];
-        $headline = ["table" => _("Umschließende Tabelle")];
-        $content_table .= $edit_form->getEditFormContent($attributes, $headline);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('HTML-Header/Footer') . ':';
-        $info = _("Anwählen, wenn die Seite als komplette HTML-Seite ausgegeben werden soll, z.B. bei direkter Verlinkung oder in einem Frameset.");
-        $wholesite_values = "1";
-        $wholesite_names = "";
-        $table = $edit_form->editCheckboxGeneric("wholesite", $title, $info, $wholesite_values, $wholesite_names);
-
-        $title = _('Stylesheet-Datei') . ':';
-        $info = _("Geben Sie hier die URL Ihrer Stylesheet-Datei an.");
-        $table .= $edit_form->editTextfieldGeneric("urlcss", $title, $info, 50, 200);
-
-        $title = _('Seitentitel') . ':';
-        $info = _("Geben Sie hier den Titel der Seite ein. Der Titel wird bei der Anzeige im Web-Browser in der Titelzeile des Anzeigefensters angezeigt.");
-        $table .= $edit_form->editTextfieldGeneric("title", $title, $info, 50, 200);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainTemplateDownload.class.php b/lib/extern/elements/main/ExternElementMainTemplateDownload.class.php
deleted file mode 100644
index 879284ede2e..00000000000
--- a/lib/extern/elements/main/ExternElementMainTemplateDownload.class.php
+++ /dev/null
@@ -1,219 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter005: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainTemplateDownload.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainTemplateDownload
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainTemplateDownload.class.php
-//
-// Copyright (C) 2007 Peter Thienel <thienelqdata-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementMainTemplateDownload extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'sort',
-                'lengthdesc', 'nameformat',
-                'nodatatext', 'dateformat', 'language', 'iconpic', 'icontxt',
-                'iconpdf', 'iconppt', 'iconxls', 'iconrtf', 'iconzip',
-                'icondefault'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-        $this->edit_function = 'editSort';
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-        $config = [
-            "name" => "",
-            "sort" => "|0|0|0|1|0|0",
-            "lengthdesc" => "",
-            "nameformat" => "",
-            "nodatatext" => _("Keine Dateien vorhanden"),
-            "dateformat" => "%d. %b. %Y",
-            "language" => "",
-            "iconpic" => "",
-            "icontxt" => "",
-            "iconpdf" => "",
-            "iconppt" => "",
-            "iconxls" => "",
-            "iconrtf" => "",
-            "iconzip" => "",
-            "icondefault" => ""
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        $out = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben zum Tabellenaufbau"));
-
-        $edit_function = $this->edit_function;
-        $table = $edit_form->$edit_function($this->field_names);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Max. Länge der Beschreibung') . ':';
-        $info = _("Geben Sie an, wieviele Zeichen der Beschreibung der Datei ausgegeben werden sollen.");
-        $table = $edit_form->editTextfieldGeneric("lengthdesc", $title, $info, 3, 3);
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table .= $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Datumsformat') . ':';
-        $info = _("Wählen Sie, wie Datumsangaben formatiert werden sollen.");
-        $values = ["%d. %b. %Y", "%d.%m.%Y", "%d.%m.%y", "%d. %B %Y", "%m/%d/%y"];
-        $names = [_("25. Nov. 2003"), _("25.11.2003"), _("25.11.03"),
-                _("25. November 2003"), _("11/25/03")];
-        $table .= $edit_form->editOptionGeneric("dateformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        $title = _('Keine Dateien') . ':';
-        $info = _("Dieser Text wird an Stelle der Tabelle ausgegeben, wenn keine Dateien zum Download verfügbar sind.");
-        $table .= $edit_form->editTextareaGeneric("nodatatext", $title, $info, 3, 50);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Eigene Icons"));
-        $icon_attributes = ["iconpic", "icontxt", "iconpdf", "iconppt",
-                "iconxls", "iconrtf", "iconzip", "icondefault"];
-        $icon_titles = [
-                _('Bilder') . ':',
-                _('Text') . ':',
-                _('Adobe pdf') . ':',
-                _('Powerpoint (ppt)') . ':',
-                _('Excel (xls)') . ':',
-                _('Rich Text (rtf)') . ':',
-                _('ZIP-Dateien') . ':',
-                _('sonstige Dateien') . ':',
-        ];
-        $icon_infos = [
-                _("Geben Sie die URL eines Bildes ein, dass als Icon für Bild-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-                _("Geben Sie die URL eines Bildes ein, dass als Icon für Text-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-                _("Geben Sie die URL eines Bildes ein, dass als Icon für PDF-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-                _("Geben Sie die URL eines Bildes ein, dass als Icon für Powerpoint-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-                _("Geben Sie die URL eines Bildes ein, dass als Icon für Excel-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-                _("Geben Sie die URL eines Bildes ein, dass als Icon für RTF-Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-                _("Geben Sie die URL eines Bildes ein, dass als Icon für komprimierte Dateien dienen soll. Erlaubte Formate: jpg, png, gif. "),
-                _("Geben Sie die URL eines Bildes ein, dass als Icon für alle anderen Dateiformate dienen soll. ")
-        ];
-        $info_add = _("Wenn Sie keine URL angeben, wird ein Standard-Icon ausgegeben.");
-
-        $table = "";
-        for ($i = 0; $i < sizeof($icon_attributes); $i++) {
-            $table .= $edit_form->editTextfieldGeneric($icon_attributes[$i],
-                    $icon_titles[$i], $icon_infos[$i] . $info_add, 50, 200);
-        }
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        switch ($attribute) {
-            case "lengthdesc" :
-                return !preg_match("|^\d{0,3}$|", $value);
-            case "timelocale" :
-                return ($value != "de_DE" || $value != "en_US");
-            case "iconpic" :
-            case "icontxt" :
-            case "iconpdf" :
-            case "iconppt" :
-            case "iconxls" :
-            case "iconrtf" :
-            case "iconzip" :
-            case "icondefault" :
-                return $value
-                    && (
-                        preg_match("/(<|>|\"|<script|<php)/i", $value)
-                        || !preg_match("/^[^.\/\\\].*\.(png|jpg|jpeg|gif)$/i", $value)
-                    );
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainTemplateLecturedetails.class.php b/lib/extern/elements/main/ExternElementMainTemplateLecturedetails.class.php
deleted file mode 100644
index 6f747978777..00000000000
--- a/lib/extern/elements/main/ExternElementMainTemplateLecturedetails.class.php
+++ /dev/null
@@ -1,154 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainTemplateLecturedetails.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainTemplateLecturedetails
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainLecturedetails.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementMainTemplateLecturedetails extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'genericdatafields', 'rangepathlevel',
-                'nameformat', 'dateformat', 'language'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-        $config = [
-            "name" => "",
-            "rangepathlevel" => "1",
-            "nameformat" => "",
-            "dateformat" => '%d. %b. %Y',
-            "language" => ""
-        ];
-
-        get_default_generic_datafields($config, "sem");
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        update_generic_datafields($this->config, $this->data_fields, $this->field_names, "sem");
-        $out = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Bereichspfad ab Ebene') . ':';
-        $info = _("Wählen Sie, ab welcher Ebene der Bereichspfad ausgegeben werden soll.");
-        $values = ["1", "2", "3", "4", "5"];
-        $names = ["1", "2", "3", "4", "5"];
-        $table = $edit_form->editOptionGeneric("rangepathlevel", $title, $info, $values, $names);
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table .= $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Datumsformat') . ':';
-        $info = _("Wählen Sie, wie Datumsangaben formatiert werden sollen.");
-        $values = ["%d. %b. %Y", "%d.%m.%Y", "%d.%m.%y", "%d. %B %Y", "%m/%d/%y"];
-        $names = [_("25. Nov. 2003"), _("25.11.2003"), _("25.11.03"),
-                _("25. November 2003"), _("11/25/03")];
-        $table .= $edit_form->editOptionGeneric("dateformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    /*
-    function checkValue ($attribute, $value) {
-        if ($attribute == "studipinfo" || $attribute == "headlinerow") {
-            // This is especially for checkbox-values. If there is no checkbox
-            // checked, the variable is not declared and it is necessary to set the
-            // variable to "".
-            if (!isset($_POST[$this->name . "_" . $attribute])) {
-                $_POST[$this->name . "_" . $attribute] = "";
-                return FALSE;
-            }
-            return !($value == "1" || $value == "");
-        }
-
-        return FALSE;
-    }
-    */
-}
diff --git a/lib/extern/elements/main/ExternElementMainTemplateLectures.class.php b/lib/extern/elements/main/ExternElementMainTemplateLectures.class.php
deleted file mode 100644
index fdc6f547b94..00000000000
--- a/lib/extern/elements/main/ExternElementMainTemplateLectures.class.php
+++ /dev/null
@@ -1,253 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainTemplateLectures.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainTemplateLectures
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainTemplateLectures.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementMainTemplateLectures extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'grouping', 'semstart', 'semrange', 'semswitch', 'allseminars', 'rangepathlevel',
-                'time', 'lecturer', 'semclasses', 'textnogroups', 'aliasesgrouping', 'nameformat',
-                'language', "nodatatext"
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-        $this->edit_function = 'editSort';
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            "name" => "",
-            "grouping" => "3",
-            "semstart" => "",
-            "semrange" => "",
-            "semswitch" => "",
-            "allseminars" => "",
-            "rangepathlevel" => "1",
-            "time" => "1",
-            "lecturer" => "1",
-            "repeatheadrow" => "",
-            "semclasses" => "|1",
-            "textnogroups" => _("keine Studienbereiche eingetragen"),
-            "aliasesgrouping" => "|"._("Semester")."|"._("Bereich")."|"._("Lehrende")."|"
-                    ._("Typ")."|"._("Einrichtung"),
-            "nameformat" => "",
-            "language" => "",
-            "nodatatext" => _("Keine Veranstaltungen in diesem Bereich vorhanden.")
-        ];
-
-        get_default_generic_datafields($config, 'sem');
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        // get semester data
-        $semester_data = Semester::findAllVisible(false);
-
-        update_generic_datafields($this->config, $this->data_fields, $this->field_names, "sem");
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben Seitenaufbau"));
-
-        $title = _('Gruppierung') . ':';
-        $info = _("Wählen Sie, wie die Veranstaltungen gruppiert werden sollen.");
-        $values = ["0", "1", "2", "3", "4"];
-        $names = [_("Semester"), _("Bereich"), _("Lehrende"),
-                _("Typ"), _("Einrichtung")];
-        $table = $edit_form->editOptionGeneric("grouping", $title, $info, $values, $names);
-
-        $title = _('Startsemester') . ':';
-        $info = _("Geben Sie das erste anzuzeigende Semester an. Die Angaben \"vorheriges\", \"aktuelles\" und \"nächstes\" beziehen sich immer auf das laufende Semester und werden automatisch angepasst.");
-        $current_sem = get_sem_num_sem_browse();
-        if ($current_sem === FALSE) {
-            $names = [_("keine Auswahl"), _("aktuelles"), _("nächstes")];
-            $values = ["", "current", "next"];
-        }
-        else if ($current_sem === TRUE) {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles")];
-            $values = ["", "previous", "current"];
-        }
-        else {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles"), "nächstes"];
-            $values = ["", "previous", "current", "next"];
-        }
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $sem["name"];
-            $values[] = $sem_num + 1;
-        }
-        $table .= $edit_form->editOptionGeneric("semstart", $title, $info, $values, $names);
-
-        $title = _('Anzahl der anzuzeigenden Semester') . ':';
-        $info = _("Geben Sie an, wieviele Semester (ab o.a. Startsemester) angezeigt werden sollen.");
-        $names = [_("keine Auswahl")];
-        $values = [""];
-        $i = 1;
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $i++;
-            $values[] = $sem_num + 1;
-        }
-        $table .= $edit_form->editOptionGeneric("semrange", $title, $info, $values, $names);
-
-        $title = _('Umschalten des aktuellen Semesters') . ':';
-        $info = _("Geben Sie an, wieviele Wochen vor Semesterende automatisch auf das nächste Semester umgeschaltet werden soll.");
-        $names = [_("keine Auswahl"), _("am Semesterende"), _("1 Woche vor Semesterende")];
-        for ($i = 2; $i < 13; $i++)
-            $names[] = sprintf(_("%s Wochen vor Semesterende"), $i);
-        $values = ["", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
-        $table .= $edit_form->editOptionGeneric("semswitch", $title, $info, $values, $names);
-
-        $title = _('Veranstaltungen beteiligter Institute anzeigen') . ':';
-        $info = _("Wählen Sie diese Option, um Veranstaltungen anzuzeigen, bei denen diese Einrichtung als beteiligtes Institut eingetragen ist.");
-        $values = "1";
-        $names = "";
-        $table .= $edit_form->editCheckboxGeneric("allseminars", $title, $info, $values, $names);
-
-        $title = _('Bereichspfad ab Ebene') . ':';
-        $info = _("Wählen Sie, ab welcher Ebene der Bereichspfad ausgegeben werden soll.");
-        $values = ["1", "2", "3", "4", "5"];
-        $names = ["1", "2", "3", "4", "5"];
-        $table .= $edit_form->editOptionGeneric("rangepathlevel", $title, $info, $values, $names);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Ausgabe bestimmter Veranstaltungsklassen"));
-
-        $table = "";
-        unset($names);
-        unset($values);
-        $info = _("Wählen Sie die anzuzeigenden Veranstaltungsklassen aus.");
-
-        foreach ($GLOBALS["SEM_CLASS"] as $key => $class) {
-            $values[] = $key;
-            $names[] = $class["name"];
-        }
-        $table = $edit_form->editCheckboxGeneric("semclasses", $names, $info, $values, "");
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Textersetzungen"));
-
-        $title = _('&quot;Keine Studienbereiche&quot;') . ':';
-        $info = _("Geben Sie einen Text ein, der Angezeigt wird, wenn Lehrveranstaltungen vorliegen, die keinem Bereich zugeordnet sind. Nur wirksam in Gruppierung nach Bereich.");
-        $table = $edit_form->editTextfieldGeneric("textnogroups", $title, $info, 40, 150);
-
-        $titles = [_("Semester"), _("Bereich"), _("Lehrende"), _("Typ"), _("Einrichtung")];
-        $info = _("Geben Sie eine Bezeichnung für die entsprechende Gruppierungsart ein.");
-        $table .= $edit_form->editTextfieldGeneric("aliasesgrouping", $titles, $info, 40, 150);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table = $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        $title = _('Keine Veranstaltungen') . ':';
-        $info = _("Dieser Text wird an Stelle der Tabelle ausgegeben, wenn keine Veranstaltungen vorhanden sind.");
-        $table .= $edit_form->editTextareaGeneric("nodatatext", $title, $info, 3, 50);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == "allseminars") {
-            // This is especially for checkbox-values. If there is no checkbox
-            // checked, the variable is not declared and it is necessary to set the
-            // variable to "".
-            if (!isset($_POST[$this->name . "_" . $attribute])) {
-                $_POST[$this->name . "_" . $attribute] = "";
-                return FALSE;
-            }
-            return !($value == "1" || $value == "");
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainTemplateNews.class.php b/lib/extern/elements/main/ExternElementMainTemplateNews.class.php
deleted file mode 100644
index 9b23b153270..00000000000
--- a/lib/extern/elements/main/ExternElementMainTemplateNews.class.php
+++ /dev/null
@@ -1,148 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainTemplateNews.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainTemplateNews
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainTemplateNews.class.php
-//
-// Copyright (C) 2007 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementMainTemplateNews extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'order', 'visible', 'aliases', 'width',
-                'width_pp', 'sort', 'studiplink', 'wholesite', 'nameformat',
-                'dateformat', 'language',   'urlcss', 'title', 'nodatatext',
-                'copyright', 'author', 'showdateauthor', 'notauthorlink'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-        $this->edit_function = 'editSort';
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            "name" => "",
-            "nameformat" => "",
-            "dateformat" => "%d. %b. %Y",
-            "language" => "",
-            "nodatatext" => _("Keine aktuellen News")
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev", "last"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr."), _("Meyer")];
-        $table = $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Datumsformat') . ':';
-        $info = _("Wählen Sie, wie Datumsangaben formatiert werden sollen.");
-        $values = ["%d. %b. %Y", "%d.%m.%Y", "%d.%m.%y", "%d. %B %Y", "%m/%d/%y"];
-        $names = [_("25. Nov. 2003"), "25.11.2003", "25.11.03",
-                _("25. November 2003"), "11/25/03"];
-        $table .= $edit_form->editOptionGeneric("dateformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        $title = _('Keine News') . ':';
-        $info = _("Dieser Text wird an Stelle der Tabelle ausgegeben, wenn keine News verfügbar sind.");
-        $table .= $edit_form->editTextareaGeneric("nodatatext", $title, $info, 3, 50);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == 'notauthorlink') {
-            if (!isset($_POST["Main_$attribute"])) {
-                $_POST["Main_$attribute"] = 0;
-                return FALSE;
-            }
-
-            return !($value == "1" || $value == "");
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainTemplatePersBrowse.class.php b/lib/extern/elements/main/ExternElementMainTemplatePersBrowse.class.php
deleted file mode 100644
index 7a5eb0a9fa6..00000000000
--- a/lib/extern/elements/main/ExternElementMainTemplatePersBrowse.class.php
+++ /dev/null
@@ -1,169 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainTemplatePersBrowse.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainTemplatePersBrowse
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainTemplatePersBrowse.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementMainTemplatePersBrowse extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    public function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'sort', 'groupsalias', 'groupsvisible', 'grouping',
-                'nameformat', 'defaultadr', 'genericdatafields', 'onlylecturers', 'onlygrouped',
-                'instperms'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-        $this->edit_function = 'editSort';
-    }
-
-    /**
-    *
-    */
-    public function getDefaultConfig () {
-        $config = [
-            'name' => '',
-            'sort' => '|1|0|0|0|0',
-            'nameformat' => '',
-            'defaultadr' => '',
-            'instperms' => '|dozent',
-            'onlylecturers' => '1'
-        ];
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    public function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        $out = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName('name');
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Sortierung der Personenliste"));
-        $edit_function = $this->edit_function;
-        $table = $edit_form->$edit_function($this->field_names);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        if (in_array(get_object_type($this->config->range_id), ['fak', 'global'])) {
-            $headline = $edit_form->editHeadline(_("Filter"));
-
-            $title = _('Rechtestufe in Einrichtung') . ':';
-            $info = _("Es werden nur Personen angezeigt, die in einer Einrichtung die angegebenen Rechtestufen besitzen");
-            $values = ['tutor', 'dozent', 'admin'];
-            $names = [_("Tutor"), _("Dozent"), _("Administrator")];
-            $table = $edit_form->editCheckboxGeneric('instperms', $title, $info, $values, $names);
-
-            $title = _('Nur Lehrende') . ':';
-            $info = _("Es werden nur Personen angezeigt, die in einer sichtbaren Veranstaltung des aktuellen Semesters Lehrperson sind.");
-            $values = '1';
-            $table .= $edit_form->editCheckboxGeneric('onlylecturers', $title, $info, $values, '');
-
-            $table .= $edit_form->editTextblock('<span style="font-weight: bold">'
-                . _("Das Modul zeigt nur Personen an, die eine Standardadresse angegeben haben.")
-                . '</span>');
-
-            $content_table .= $edit_form->editContentTable($headline, $table);
-            $content_table .= $edit_form->editBlankContent();
-        }
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer, Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table = $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    public function checkValue ($attribute, $value) {
-        if (in_array($attribute, ['grouping', 'defaultadr', 'onlylecturers'])) {
-            // This is especially for checkbox-values. If there is no checkbox
-            // checked, the variable is not declared and it is necessary to set the
-            // variable to "0".
-            if (!isset($_POST[$this->name . "_" . $attribute])) {
-                $_POST[$this->name . "_" . $attribute] = "";
-                return false;
-            }
-            return !($value == '1' || $value == '');
-        }
-
-        if ($attribute == 'instperms') {
-            if (!isset($_POST[$this->name . '_instperms'])) {
-                $_POST[$this->name . '_instperms'] = [];
-                return false;
-            }
-        }
-
-        return false;
-    }
-
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainTemplatePersondetails.class.php b/lib/extern/elements/main/ExternElementMainTemplatePersondetails.class.php
deleted file mode 100644
index fda783a3a35..00000000000
--- a/lib/extern/elements/main/ExternElementMainTemplatePersondetails.class.php
+++ /dev/null
@@ -1,159 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainTemplatePersondetails.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainTemplatePersondetails
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainTemplatePersondetails.class.php
-//
-// Copyright (C) 2007 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementMainTemplatePersondetails extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'nameformat', 'dateformat', 'language', 'studiplink', 'defaultaddr', 'onlylecturers'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-
-        $config = [
-            "name" => '',
-            "nameformat" => '',
-            "dateformat" => '%d. %b. %Y',
-            "language" => '',
-            'defaultaddr' => '',
-            'onlylecturers' => '1'
-        ];
-
-        get_default_generic_datafields($config, "user");
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        update_generic_datafields($this->config, $this->data_fields["content"],
-                $this->field_names["content"], "user");
-        $out = "";
-        $table = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName("name");
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table = $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Datumsformat') . ':';
-        $info = _("Wählen Sie, wie Datumsangaben formatiert werden sollen.");
-        $values = ["%d. %b. %Y", "%d.%m.%Y", "%d.%m.%y", "%d. %B %Y", "%m/%d/%y"];
-        $names = [_("25. Nov. 2003"), _("25.11.2003"), _("25.11.03"),
-                _("25. November 2003"), _("11/25/03")];
-        $table .= $edit_form->editOptionGeneric("dateformat", $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric("language", $title, $info, $values, $names);
-
-        if (in_array(get_object_type($this->config->range_id), ['global'])) {
-            $title = _('Nur Lehrende') . ':';
-            $info = _("Es werden nur Personen angezeigt, die in einer sichtbaren Veranstaltung des aktuellen Semesters Lehrperson sind.");
-            $values = '1';
-            $table .= $edit_form->editCheckboxGeneric('onlylecturers', $title, $info, $values, '');
-
-            $table .= $edit_form->editTextblock('<span style="font-weight: bold">'
-                . _("Das Modul zeigt nur Personen an, die eine Standardadresse angegeben haben.")
-                . '</span>');
-        } else {
-            $title = _('Standard-Adresse') . ':';
-            $info = _("Wenn Sie diese Option wählen, wird die Standard-Adresse ausgegeben, die jede(r) Mitarbeiter(in) bei seinen universitären Daten auswählen kann. Wählen Sie diese Option nicht, wenn immer die Adresse der Einrichtung ausgegeben werden soll.");
-            $table .= $edit_form->editCheckboxGeneric('defaultaddr', $title, $info, '1', '0');
-        }
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == 'defaultaddr' || $attribute == 'onlylecturers') {
-            if (!isset($_POST["Main_$attribute"])) {
-                $_POST["Main_$attribute"] = 0;
-                return FALSE;
-            }
-            return !($value == "1" || $value == "");
-        }
-
-        return FALSE;
-    }
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainTemplatePersons.class.php b/lib/extern/elements/main/ExternElementMainTemplatePersons.class.php
deleted file mode 100644
index a82aa442996..00000000000
--- a/lib/extern/elements/main/ExternElementMainTemplatePersons.class.php
+++ /dev/null
@@ -1,170 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainTemplatePersons.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainTemplatePersons
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainTemplatePersons.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementMainTemplatePersons extends ExternElementMain {
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-                'name', 'sort', 'groupsalias', 'groupsvisible', 'grouping',
-                'nameformat', 'defaultadr', 'genericdatafields'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-        $this->edit_function = 'editSort';
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-        if ($groups = get_all_statusgruppen($this->config->range_id))
-            $groups = '|' . implode('|', array_keys($groups));
-        else
-            $groups = '';
-
-        $config = [
-            'name' => '',
-            'sort' => '|1|0|0|0|0',
-            'groupsalias' => '',
-            'groupsvisible' => $groups,
-            'nameformat' => '',
-        //  'nodatatext' => '',
-            'defaultadr' => ''
-        ];
-
-        return $config;
-    }
-
-
-
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        $out = '';
-        $table = '';
-        if ($edit_form == '')
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName('name');
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form);
-
-        $headline = $edit_form->editHeadline(_("Allgemeine Angaben zum Tabellenaufbau"));
-        $edit_function = $this->edit_function;
-        $table = $edit_form->$edit_function($this->field_names);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Anzeige von Gruppen"));
-
-        $table = $edit_form->editGroups();
-        if ($table) {
-            $title = _('Gruppierung') . ':';
-            $info = _("Personen nach Gruppen/Funktionen gruppieren.");
-            $values = "1";
-            $table .= $edit_form->editCheckboxGeneric("grouping", $title, $info, $values, "");
-        } else {
-            $text = _("An dieser Einrichtung wurden noch keine Gruppen/Funktionen angelegt, oder es wurden diesen noch keine Personen zugeordnet.");
-            $text .= _("Das Modul gibt nur Daten von Personen aus, die einer Gruppe/Funktion zugeordnet sind.");
-            $table = $edit_form->editTextblock('<font size="2"><b>' . $text . '</b></font>');
-        }
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer, Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table = $edit_form->editOptionGeneric("nameformat", $title, $info, $values, $names);
-
-        $title = _('Standard-Adresse') . ':';
-        $info = _("Wenn Sie diese Option wählen, wird die Standard-Adresse ausgegeben, die jede(r) Mitarbeiter(in) bei seinen universitären Daten auswählen kann. Wählen Sie diese Option nicht, wenn immer die Adresse der Einrichtung ausgegeben werden soll.");
-        $table .= $edit_form->editCheckboxGeneric('defaultadr', $title, $info, '1', '0');
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == "grouping" || $attribute == "defaultadr") {
-            // This is especially for checkbox-values. If there is no checkbox
-            // checked, the variable is not declared and it is necessary to set the
-            // variable to "0".
-            if (!isset($_POST[$this->name . "_" . $attribute])) {
-                $_POST[$this->name . "_" . $attribute] = "";
-                return FALSE;
-            }
-            return !($value == '1' || $value == '');
-        }
-
-        return FALSE;
-    }
-
-
-}
diff --git a/lib/extern/elements/main/ExternElementMainTemplateSemBrowse.class.php b/lib/extern/elements/main/ExternElementMainTemplateSemBrowse.class.php
deleted file mode 100644
index 058b92c5d7d..00000000000
--- a/lib/extern/elements/main/ExternElementMainTemplateSemBrowse.class.php
+++ /dev/null
@@ -1,319 +0,0 @@
-<?php
-# Lifter002: TODO
-# Lifter010: TODO
-/**
-* ExternElementMainTemplateLecturedetails.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMainTemplateLecturedetails
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMainLecturedetails.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternElementMainTemplateSemBrowse extends ExternElementMain {
-
-    function __construct($module_name, &$data_fields, &$field_names, &$config) {
-        $this->attributes = [
-            'name', 'includeurl', 'grouping', 'semstart', 'semrange', 'semswitch', 'allseminars', 'rangepathlevel',
-            'time', 'lecturer', 'semclasses', 'aliasesgrouping', 'nameformat',
-            'language', 'genericdatafields', 'mode', 'countshowsublevels', 'startitem',
-            'disableemptylevels', 'selectedeventtypes', 'resultorderby', 'maxnumberofhits', 'maxpagesresultbrowser'
-        ];
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Moduls ändern.");
-        parent::__construct($module_name, $data_fields, $field_names, $config);
-    }
-
-    function getDefaultConfig () {
-        $config = [
-            'name' => '',
-            'grouping' => '3',
-            'semstart' => '',
-    //      'semrange' => '',
-            'semswitch' => '',
-            'allseminars' => '',
-            'rangepathlevel' => '1',
-            'time' => '1',
-            'lecturer' => '1',
-            'semclasses' => '|1',
-            "aliasesgrouping" => "|"._("Semester")."|"._("Bereich")."|"._("Lehrende")."|"
-                    ._("Typ")."|"._("Einrichtung"),
-            "nameformat" => '',
-            "language" => '',
-            'mode' => 'show_sem_range',
-            'countshowsublevels' => '0',
-            'startitem' => '',
-            'disableemptylevels' => '',
-            'selectedeventtypes' => '|all',
-            'resultorderby' => 'VeranstaltungsNummer',
-            'maxnumberofhits' => '10',
-            'maxpagesresultbrowser' => ''
-        ];
-
-        get_default_generic_datafields($config, 'sem');
-
-        return $config;
-    }
-
-    function toStringEdit ($post_vars = '', $faulty_values = '', $edit_form = '', $anker = '') {
-        // get semester data
-        $semester_data = Semester::findAllVisible(false);
-
-        update_generic_datafields($this->config, $this->data_fields, $this->field_names, "sem");
-
-        $out = '';
-        $table = '';
-        if ($edit_form == '') {
-            $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-        }
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE, $anker);
-
-        if ($faulty_values == '') {
-            $faulty_values = [];
-        }
-
-        $headline = $edit_form->editHeadline(_("Name der Konfiguration"));
-        $table = $edit_form->editName('name');
-        $content_table = $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $content_table .= $this->getSRIFormContent($edit_form, true);
-
-        $headline = $edit_form->editHeadline(_("Konfiguration des Moduls"));
-
-        $title = _('Anzeigemodus') . ':';
-        $info = _("Auswahl zwischen Einrichtungsbaum und Bereichsbaum");
-        $values = ['show_sem_range', 'show_sem_range_tree'];
-        $names = [_("Vorlesungsverzeichnis"), _("Einrichtungen")];
-        $table = $edit_form->editRadioGeneric('mode', $title, $info, $values, $names);
-
-        $title = _('Gruppierung') . ':';
-        $info = _("Wählen Sie, wie die Veranstaltungen gruppiert werden sollen.");
-        $values = ['0', '1', '2', '3', '4'];
-        $names = [_("Semester"), _("Bereich"), _("Lehrende"),
-                _("Typ"), _("Einrichtung")];
-        $table .= $edit_form->editOptionGeneric('grouping', $title, $info, $values, $names);
-
-        $title = _('Startsemester') . ':';
-        $info = _("Geben Sie das erste anzuzeigende Semester an. Die Angaben \"vorheriges\", \"aktuelles\" und \"nächstes\" beziehen sich immer auf das laufende Semester und werden automatisch angepasst.");
-        $current_sem = get_sem_num_sem_browse();
-        if ($current_sem === FALSE) {
-            $names = [_("keine Auswahl"), _("aktuelles"), _("nächstes")];
-            $values = ['', 'current', 'next'];
-        }
-        else if ($current_sem === TRUE) {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles")];
-            $values = ['', 'previous', 'current'];
-        }
-        else {
-            $names = [_("keine Auswahl"), _("vorheriges"), _("aktuelles"), "nächstes"];
-            $values = ['', 'previous', 'current', 'next'];
-        }
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $sem['name'];
-            $values[] = $sem_num + 1;
-        }
-        $table .= $edit_form->editOptionGeneric("semstart", $title, $info, $values, $names);
-        /*
-        $title = _('Anzahl der anzuzeigenden Semester') . ':';
-        $info = _("Geben Sie an, wieviele Semester (ab o.a. Startsemester) angezeigt werden sollen.");
-        $names = array(_("keine Auswahl"));
-        $values = array('');
-        $i = 1;
-        foreach ($semester_data as $sem_num => $sem) {
-            $names[] = $i++;
-            $values[] = $sem_num + 1;
-        }
-        $table .= $edit_form->editOptionGeneric('semrange', $title, $info, $values, $names);
-        */
-        $title = _('Umschalten des aktuellen Semesters') . ':';
-        $info = _("Geben Sie an, wieviele Wochen vor Semesterende automatisch auf das nächste Semester umgeschaltet werden soll.");
-        $names = [_("keine Auswahl"), _("am Semesterende"), _("1 Woche vor Semesterende")];
-        for ($i = 2; $i < 13; $i++) {
-            $names[] = sprintf(_("%s Wochen vor Semesterende"), $i);
-        }
-        $values = ['', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12'];
-        $table .= $edit_form->editOptionGeneric('semswitch', $title, $info, $values, $names);
-
-        /*
-        $title = _('Veranstaltungen beteiligter Institute anzeigen') . ':';
-        $info = _("Wählen Sie diese Option, um Veranstaltungen anzuzeigen, bei denen diese Einrichtung als beteiligtes Institut eingetragen ist.");
-        $values = '1';
-        $names = '';
-        $table .= $edit_form->editCheckboxGeneric('allseminars', $title, $info, $values, $names);
-        */
-
-        $title = _('Bereichspfad ab Ebene') . ':';
-        $info = _("Wählen Sie, ab welcher Ebene der Bereichspfad ausgegeben werden soll.");
-        $values = ['1', '2', '3', '4', '5', '6'];
-        $names = ['1', '2', '3', '4', '5', '6'];
-        $table .= $edit_form->editOptionGeneric('rangepathlevel', $title, $info, $values, $names);
-
-        $title = _('Anzeige von Unterebenen') . ':';
-        $info = _("Anzahl der Unterebenen des Baumes, die angezeigt werden sollen.");
-        $values = ['0', '1', '2', '3', '4', '5', '6'];
-        $names = ['0', '1', '2', '3', '4', '5', '6'];
-        $table .= $edit_form->editOptionGeneric('countshowsublevels', $title, $info, $values, $names);
-        $cid = Request::option('cid') ;
-        if ($GLOBALS['perm']->have_perm('root') && $cid = 'studip') {
-            $title = _('Start bei Root-Ebene') . ':';
-            $info = _("Wird das Modul ohne weitere Parameter aufgerufen startet die Anzeige beim Root-Level (alle Fakultäten).");
-            $table .= $edit_form->editCheckboxGeneric('startitem', $title, $info, 'root', '0');
-        }
-
-        $title = _('Leere Ebenen ausblenden') . ':';
-        $info = _("Ebenen ohne Veranstaltungen und ohne Veranstaltungen in ihren Unterebenen werden nicht angezeigt.");
-        $table .= $edit_form->editCheckboxGeneric('disableemptylevels', $title, $info, '1', '0');
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Konfiguration der Suche"));
-
-        $title = _('Sortierung des Treffersets') . ':';
-        $info = _("Nach welchem Tabellenfeld soll das Trefferset sortiert werden?");
-        $values = ['VeranstaltungsNummer', 'Name'];
-        $names = ['Veranstaltungsnummer', 'Name'];
-        $table = $edit_form->editOptionGeneric('resultorderby', $title, $info, $values, $names);
-
-        $title = _('Anzahl der Treffer bei Suche') . ':';
-        $info = _("Maximale Anzahl der Veranstaltungen im Trefferset. Angabe 0, um alle anzuzeigen.");
-        $table .= $edit_form->editTextfieldGeneric('maxnumberofhits', $title, $info, 3, 3);
-
-        $title = _('Anzahl der Seiten im Result Browser') . ':';
-        $info = _("Maximale Anzahl der Seiten, die der Result Browser anzeigen soll.");
-        $table .= $edit_form->editTextfieldGeneric('maxpagesresultbrowser', $title, $info, 3, 3);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Ausgabe bestimmter Veranstaltungsklassen"));
-
-        $names = [];
-        $values = [];
-        $info = _("Wählen Sie die anzuzeigenden Veranstaltungsklassen aus.");
-
-        foreach ($GLOBALS['SEM_CLASS'] as $key => $class) {
-            $values[] = $key;
-            $names[] = $class['name'];
-        }
-        $table = $edit_form->editCheckboxGeneric('semclasses', $names, $info, $values, "");
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Textersetzungen"));
-
-        $titles = [_("Semester"), _("Bereich"), _("Lehrende"), _("Typ"), _("Einrichtung")];
-        $info = _("Geben Sie eine Bezeichnung für die entsprechende Gruppierungsart ein.");
-        $table = $edit_form->editTextfieldGeneric('aliasesgrouping', $titles, $info, 40, 150);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Termine"));
-
-        $title = _('Termintypen') . ':';
-        $info = _("Wählen Sie aus, welche Termintypen angezeigt werden sollen.");
-        $values = ['all', 'meeting', 'other', ''];
-        $names = [_("alle Termine"), _("nur Sitzungstermine"), _("nur andere Termine"), '-----------'];
-        foreach ($GLOBALS['TERMIN_TYP'] as $termin_key => $termin_typ) {
-            $values[] = $termin_key;
-            $names[] = $termin_typ['name'] . ($termin_typ['sitzung'] ? ' ('._("Sitzung").')' : '');
-        }
-        $table = $edit_form->editOptionGeneric('selectedeventtypes', $title, $info, $values, $names, 5, true);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $headline = $edit_form->editHeadline(_("Weitere Angaben"));
-
-        $title = _('Namensformat') . ':';
-        $info = _("Wählen Sie, wie Personennamen formatiert werden sollen.");
-        $values = ["", "no_title_short", "no_title", "no_title_rev", "full", "full_rev"];
-        $names = [_("keine Auswahl"), _("Meyer, P."), _("Peter Meyer"), _("Meyer Peter"),
-                _("Dr. Peter Meyer"), _("Meyer, Peter, Dr.")];
-        $table = $edit_form->editOptionGeneric('nameformat', $title, $info, $values, $names);
-
-        $title = _('Sprache') . ':';
-        $info = _("Wählen Sie eine Sprache für die Datumsangaben aus.");
-        $values = ["", "de_DE", "en_GB"];
-        $names = [_("keine Auswahl"), _("Deutsch"), _("Englisch")];
-        $table .= $edit_form->editOptionGeneric('language', $title, $info, $values, $names);
-
-        $content_table .= $edit_form->editContentTable($headline, $table);
-        $content_table .= $edit_form->editBlankContent();
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function checkValue ($attribute, $value) {
-        if ($attribute == 'mode') {
-            if (!sizeof($_POST[$this->getName() . '_mode'])) {
-                return true;
-            }
-        }
-        if ($attribute == 'startitem') {
-            if (!($GLOBALS['perm']->have_perm('root') && Request::option('cid') == 'studip')) {
-                return false;
-            }
-            if (!isset($_POST[$this->name . '_' . $attribute])) {
-                $_POST[$this->name . '_' . $attribute] = '';
-                return FALSE;
-            }
-            return !($value == 'root' || $value == '');
-        }
-        if ($attribute == 'disableemptylevels') {
-            if (!isset($_POST[$this->name . '_' . $attribute])) {
-                $_POST[$this->name . '_' . $attribute] = '';
-                return FALSE;
-            }
-            return !($value == '1' || $value == '');
-        }
-        if ($attribute == 'resultorderby') {
-            $_POST[$this->getName() . '_resultorderby'] = (in_array($_POST[$this->getName() . '_resultorderby'], ['Name', 'VeranstaltungsNummer']) ? $_POST[$this->getName() . '_resultorderby'] : 'VeranstaltungsNummer');
-        }
-        if ($attribute == 'maxpagesresultbrowser') {
-            $_POST[$this->getName() . '_maxpagesresultbrowser'] = intval($_POST[$this->getName() . '_maxpagesresultbrowser']);
-        }
-        if ($attribute == 'maxnumberofhits') {
-            $_POST[$this->getName() . '_maxnumberofhits'] = intval($_POST[$this->getName() . '_maxnumberofhits']);
-        }
-        return false;
-    }
-
-}
diff --git a/lib/extern/extern.inc.php b/lib/extern/extern.inc.php
deleted file mode 100644
index c94d7d739f4..00000000000
--- a/lib/extern/extern.inc.php
+++ /dev/null
@@ -1,139 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* extern.inc.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       extern
-* @package  extern.inc.php
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// extern.inc.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-$default = "";
-
-// set up dummy user environment (but no session)
-$user = new Seminar_User('nobody');
-$auth = new Seminar_Default_Auth();
-$perm = new Seminar_Perm();
-
-// there is a page_url, switch to the sri-interface
-$page_url = Request::quoted('page_url');
-if ($page_url) {
-    require "lib/extern/sri.inc.php";
-    exit;
-}
-
-// set base url for URLHelper class
-URLHelper::setBaseUrl($GLOBALS['ABSOLUTE_URI_STUDIP']);
-$range_id = Request::option('range_id',Context::getId());
-$module = Request::quoted('module');
-$config_id = Request::option('config_id');
-$global_id = Request::option('global_id');
-// range_id and module are always necessary
-if ($range_id && $module) {
-    // $module = ucfirst(mb_strtolower($module));
-
-    // Is it a valid module name?
-    foreach ($GLOBALS['EXTERN_MODULE_TYPES'] as $module_type => $module_data) {
-        if ($module_data["module"] == $module) {
-            $type = $module_type;
-            break;
-        }
-    }
-    // Wrong module name!
-    if (!$type) {
-        echo $GLOBALS['EXTERN_ERROR_MESSAGE'];
-        exit;
-    }
-
-    if (!empty($config_name)) {
-        // check for valid configuration name and convert it into a config_id
-        if (!$config_id = ExternConfig::GetConfigurationByName($range_id, $type, $config_name)) {
-            echo $GLOBALS['EXTERN_ERROR_MESSAGE'];
-            exit;
-        }
-    } elseif (empty($config_id)) {
-        // check for standard configuration
-        if ($id = ExternConfig::GetStandardConfiguration($range_id, $type)) {
-            $config_id = $id;
-        } else {
-            if (Config::get()->EXTERN_ALLOW_ACCESS_WITHOUT_CONFIG) {
-                // use default configuraion
-                $default = 'DEFAULT';
-                $config_id = '';
-            } else {
-                echo $GLOBALS['EXTERN_ERROR_MESSAGE'];
-                exit;
-            }
-        }
-    }
-    // the module itself validates the rest
-} else {
-    // without a range_id and a module-name there's no chance to printout data
-    // except an error message
-    echo $GLOBALS['EXTERN_ERROR_MESSAGE'];
-    exit;
-}
-
-// check for standard global configuration
-if (empty($global_id) && ($global_configuration = ExternConfig::GetGlobalConfiguration($range_id))) {
-    $global_id = $global_configuration;
-}
-
-// all parameters ok, instantiate module and print data
-foreach ($GLOBALS['EXTERN_MODULE_TYPES'] as $type) {
-    if ($type["module"] == $module) {
-        $module_obj = ExternModule::GetInstance($range_id, $module, $config_id, $default, $global_id);
-    }
-}
-
-// Workaround to include data in scripts
-if (!empty($incdata)) {
-    $module_obj->config->config["Main"]["incdata"] = 1;
-}
-
-$args = $module_obj->getArgs();
-foreach ($args as $arg) {
-    $arguments[$arg] = Request::quoted($arg);
-}
-
-// declare Stud.IP encoding by default
-header('Content-Type: text/html; charset=utf-8');
-
-if (Request::option('preview')) {
-    $module_obj->printoutPreview();
-} else {
-    Metrics::increment('core.extern_page_request');
-    $module_obj->printout($arguments);
-}
-
-?>
diff --git a/lib/extern/extern_config.inc.php b/lib/extern/extern_config.inc.php
deleted file mode 100644
index 70968f3e020..00000000000
--- a/lib/extern/extern_config.inc.php
+++ /dev/null
@@ -1,135 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* extern_config.inc.php
-* 
-* extern modules configuration file
-* 
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       extern_config
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// extern_config.inc.php
-// extern modules configuration file
-// Copyright (C) 2003 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-global
-    $EXTERN_MODULE_TYPES,
-    $EXTERN_MAX_CONFIGURATIONS,
-    $EXTERN_ERROR_MESSAGE,
-    $EXTERN_CONFIG_STORAGE_CONTAINER,
-    $EXTERN_ENABLE_ERROR_LOGGING,
-    $EXTERN_LOG_FILE;
-
-
-$EXTERN_MODULE_TYPES[0] = ["module" => "Global", "name" => _("globale Konfiguration"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;globale Konfiguration&quot; enthält Einstellungen, die für alle Module gelten, solange sie nicht in den jeweiligen Modulen überschrieben werden."), 'order' => 1, 'view' => ['inst','fak','studip']];
-
-$EXTERN_MODULE_TYPES[1] = ["module" => "Persons", "name" => _("Mitarbeiter"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;Mitarbeiter&quot; gibt ein Mitarbeiterverzeichnis einer Einrichtung aus."), 'order' => 20, 'view' => ['inst','fak']];
-
-$EXTERN_MODULE_TYPES[2] = ["module" => "Persondetails", "name" => _("Mitarbeiterdetails"), "level" => 2,
-                                                    "description" => _("Das Modul &quot;Mitarbeiterdetails&quot; gibt die Daten eines Mitarbeiters einer Einrichtung aus."), 'order' => 30, 'view' => ['inst','fak']];
-
-$EXTERN_MODULE_TYPES[3] = ["module" => "Lectures", "name" => _("Veranstaltungen"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;Veranstaltungen&quot; gibt alle Veranstaltungen einer Einrichtung aus."), 'order' => 40, 'view' => ['inst','fak']];
-
-$EXTERN_MODULE_TYPES[4] = ["module" => "Lecturedetails", "name" => _("Veranstaltungsdetails"), "level" => 2,
-                                                    "description" => _("Das Modul &quot;Veranstaltungsdetails&quot; gibt alle allgemeinen Daten einer Veranstaltung aus."), 'order' => 50, 'view' => ['inst','fak']];
-
-$EXTERN_MODULE_TYPES[5] = ["module" => "News", "name" => _("News"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;News&quot; gibt alle News einer Einrichtung aus."), 'order' => 60, 'view' => ['inst','fak']];
-
-$EXTERN_MODULE_TYPES[6] = ["module" => "Download", "name" => _("Download"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;Download&quot; stellt alle Dateien aus dem Dateibereich einer Einrichtung zum Download zur Verfügung."), 'order' => 70, 'view' => ['inst','fak']];
-/*
-$EXTERN_MODULE_TYPES[8] = array("module" => "Semlecturetree", "name" => _("Bereichsbaum Veranstaltungen"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;Veranstaltungen&quot; gibt alle Veranstaltungen einer Einrichtung aus."));
-
-$EXTERN_MODULE_TYPES[9] = array("module" => "Rangelecturetree", "name" => _("Einrichtungsbaum Veranstaltungen"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;Veranstaltungen&quot; gibt alle Veranstaltungen einer Einrichtung aus."));
-*/
-$EXTERN_MODULE_TYPES[7] = ["module" => "Newsticker", "name" => _("Newsticker"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;Newsticker&quot; gibt alle News einer Einrichtung in einem Ticker aus."), 'order' => 75, 'view' => ['inst','fak']];
-
-$EXTERN_MODULE_TYPES[8] = ["module" => "Lecturestable", "name" => _("Veranstaltungen (Tabelle)"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;Veranstaltungen&quot; gibt alle Veranstaltungen einer Einrichtung als Tabelle aus."), 'order' => 45, 'view' => ['inst','fak']];
-
-$EXTERN_MODULE_TYPES[9] = ["module" => "TemplatePersons", "name" => _("Mitarbeiter (templatebasiert)"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;Mitarbeiter&quot; gibt ein Mitarbeiterverzeichnis einer Einrichtung aus."), 'order' => 22, 'view' => ['inst','fak', 'studip']];
-                                                    
-$EXTERN_MODULE_TYPES[10] = ["module" => "TemplateDownload", "name" => _("Download (templatebasiert)"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;Download&quot; stellt alle Dateien aus dem Dateibereich einer Einrichtung zum Download zur Verfügung."), 'order' => 72, 'view' => ['inst','fak']];
-
-$EXTERN_MODULE_TYPES[11] = ["module" => "TemplateNews", "name" => _("News (templatebasiert)"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;News&quot; gibt alle News einer Einrichtung aus."), 'order' => 62, 'view' => ['inst','fak']];
-
-$EXTERN_MODULE_TYPES[12] = ["module" => "TemplateLectures", "name" => _("Veranstaltungen (templatebasiert)"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;Veranstaltungen&quot; gibt alle Veranstaltungen einer Einrichtung aus."), 'order' => 42, 'view' => ['inst','fak']];
-                                                    
-$EXTERN_MODULE_TYPES[13] = ["module" => "TemplateLecturedetails", "name" => _("Veranstaltungsdetails (templatebasiert)"), "level" => 2,
-                                                    "description" => _("Das Modul &quot;Veranstaltungsdetails&quot; gibt alle allgemeinen Daten einer Veranstaltung aus."), 'order' => 52, 'view' => ['inst','fak','studip']];
-                                                    
-$EXTERN_MODULE_TYPES[14] = ["module" => "TemplatePersondetails", "name" => _("Mitarbeiterdetails (templatebasiert)"), "level" => 2,
-                                                    "description" => _("Das Modul &quot;Mitarbeiterdetails&quot; gibt die Daten eines Mitarbeiters einer Einrichtung aus."), 'order' => 32, 'view' => ['inst','fak','studip']];
-
-$EXTERN_MODULE_TYPES[15] = ["module" => "TemplateSemBrowse", "name" => _("Veranstaltungsbrowser (templatebasiert)"), "level" => 1,
-                                                    "description" => _("Das Modul &quot;Veranstaltungsbrowser&quot; ermöglicht das Suchen nach Veranstaltungen im Einrichtungs- und Vorlesungsverzeichnis."), 'order' => 47, 'view' => ['studip']];
-                                                    
-$EXTERN_MODULE_TYPES[16] = ['module' => 'TemplatePersBrowse', 'name' => _("Personenbrowser (templatebasiert)"), 'level' => 1, 'description' => _("Das Modul &quot;Personenbrowser&quot; ermöglicht die Anzeige eines systemweiten Personalverzeichnisses."), 'order' => 55, 'view' => ['studip']];
-
-// Allowed number of configurations
-$EXTERN_MAX_CONFIGURATIONS = 32;
-
-// print this message instead of data if an error occurs
-$EXTERN_ERROR_MESSAGE = "<b>Ein Fehler ist aufgetreten. Die Daten können nicht angezeigt werden. Bitte wenden Sie sich an den Webmaster.</b>";
-
-// change this to match your class name, if you have extended the class ExternConfig to store configurations in a different manner
-$EXTERN_CONFIG_STORAGE_CONTAINER = 'DB';
-
-// Not yet implemented!
-$EXTERN_ENABLE_ERROR_LOGGING = FALSE;
-
-// Not yet implemented!
-$EXTERN_LOG_FILE = "";
-
-// don't edit below this line
-//==============================================================================
-
-// path generation for SRI-interface (external pages)
-if (preg_match('#^(http://|https://)?(.+?)(/)?$#', $GLOBALS['EXTERN_SERVER_NAME'], $matches)) {
-    if ($matches[1]) {
-        $GLOBALS['EXTERN_SERVER_NAME']  = $matches[1];
-    } else {
-        $GLOBALS['EXTERN_SERVER_NAME']  = 'http://';
-    }
-    $GLOBALS['EXTERN_SERVER_NAME']  .= $matches[2] . '/';
-} else {
-    $GLOBALS['EXTERN_SERVER_NAME'] = $GLOBALS['ABSOLUTE_URI_STUDIP'];
-} 
-
-?>
diff --git a/lib/extern/lib/ExternConfig.class.php b/lib/extern/lib/ExternConfig.class.php
deleted file mode 100644
index 85c7fad6ac5..00000000000
--- a/lib/extern/lib/ExternConfig.class.php
+++ /dev/null
@@ -1,680 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: test
-# Lifter010: TODO
-/**
-* ExternConfig.class.php
-*
-* Abstract class for storing configurations.
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @modulegroup  extern
-* @module       ExternConfig
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElement.class.php
-// This is a wrapper class for configuration files.
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternConfig
-{
-    public $id = null;
-    public $config = [];
-    public $global_id = null;
-    public $module_type;
-    public $module_name;
-    public $config_name;
-    public $range_id;
-
-    public static function GetInstance ($range_id, $module_name, $config_id = '')
-    {
-        $class_name = 'ExternConfig' . ucfirst(mb_strtolower($GLOBALS['EXTERN_CONFIG_STORAGE_CONTAINER']));
-        $instance = new $class_name($range_id, $module_name, $config_id);
-        return $instance;
-    }
-
-    /**
-    *
-    */
-    public function __construct ($range_id, $module_name, $config_id = '')
-    {
-        if ($config_id) {
-            if ($configuration = self::GetConfigurationMetaData($range_id, $config_id)) {
-                $this->id = $config_id;
-                $this->module_type = $configuration['type'];
-                $this->module_name = $configuration['module_name'];
-                $this->config_name = $configuration['name'];
-                $this->range_id = $range_id;
-                $this->parse();
-            } else {
-                ExternModule::printError();
-            }
-        } else {
-            foreach ($GLOBALS['EXTERN_MODULE_TYPES'] as $type => $module) {
-                if ($module['module'] == $module_name) {
-                    $this->module_name = $module_name;
-                    $this->module_type = $type;
-                    $this->range_id = $range_id;
-                    break;
-                }
-            }
-        }
-    }
-
-    public function getName ()
-    {
-        return $this->module_name;
-    }
-
-    public function getConfigName ()
-    {
-        return $this->config_name;
-    }
-
-    public function getType ()
-    {
-        global $EXTERN_MODULE_TYPES;
-        foreach ($EXTERN_MODULE_TYPES as $key => $known_module) {
-            if ($known_module['name'] == $this->module_type)
-                return $key;
-        }
-
-        return FALSE;
-    }
-
-    public function getTypeName ()
-    {
-        return $this->module_type;
-    }
-
-    public function &getConfiguration ()
-    {
-        return $this->config;
-    }
-
-    public function setConfiguration ($config)
-    {
-        $this->config = $config;
-    }
-
-    public function setDefaultConfiguration ($config)
-    {
-        foreach ($config as $element_name => $element) {
-            if (is_array($element)) foreach ($element as $attribute => $value) {
-                if (!empty($value[0]) && (string)$value[0] == '|') {
-                    $new_config[$element_name][$attribute] = explode('|', mb_substr($value, 1));
-                } else {
-                    $new_config[$element_name][$attribute] = $value;
-                }
-            }
-        }
-
-        $this->id = $this->makeId();
-        $this->config_name = $this->createConfigName($this->range_id);
-
-        // take the new configuration, write the name in the configuration
-        // insert it into the database and store it (method of storaging deepends on
-        // object type)
-        $this->config = $new_config;
-        $this->setValue('Main', 'name', $this->config_name);
-        if ($this->insertConfiguration()) {
-            $this->store();
-        } else {
-            echo MessageBox::error(_("Sie haben die maximale Anzahl an Konfigurationen für dieses Modul erreicht! Kopieren fehlgeschlagen!"));
-            ExternModule::printError();
-        }
-    }
-
-    public function getParameterNames ()
-    {
-    }
-
-    public function getAllParameterNames ()
-    {
-    }
-
-    public function getValue ($element_name, $attribute)
-    {
-        if (!isset($this->config[$element_name])) {
-            return null;
-        }
-        return $this->config[$element_name][$attribute]?? null;
-    }
-
-    public function setValue ($element_name, $attribute, $value)
-    {
-        if (is_array($value)) {
-            ksort($value, SORT_NUMERIC);
-        }
-        $this->config[$element_name][$attribute] = $value;
-    }
-
-    public function getAttributes ($element_name, $tag, $second_set = false)
-    {
-        if (!is_array($this->config[$element_name])) {
-            return '';
-        }
-
-        $attributes = '';
-
-        reset($this->config);
-        if ($second_set) {
-            foreach ($this->config[$element_name] as $tag_attribute_name => $value) {
-                if ($value != '') {
-                    $tag_attribute = explode('_', $tag_attribute_name);
-                    if ($tag_attribute[0] == $tag && !isset($tag_attribute[2])) {
-                        if ($this->config[$element_name]["{$tag_attribute_name}2_"] == '') {
-                            $attributes .= " {$tag_attribute[1]}=\"$value\"";
-                        } else {
-                            $attributes .= " {$tag_attribute[1]}=\""
-                                    . $this->config[$element_name]["{$tag_attribute_name}2_"] . "\"";
-                        }
-                    }
-                }
-            }
-        }
-        else {
-            foreach ($this->config[$element_name] as $tag_attribute_name => $value) {
-                if ($value != '') {
-                    $tag_attribute = explode('_', $tag_attribute_name);
-                    if ($tag_attribute[0] == $tag && !isset($tag_attribute[2])) {
-                        $attributes .= " {$tag_attribute[1]}=\"$value\"";
-                    }
-                }
-            }
-        }
-
-        return $attributes;
-    }
-
-    /**
-     * Returns a complete HTML-tag with attributes
-     */
-    public function getTag ($element_name, $tag, $second_set = false)
-    {
-        return "<$tag" . $this->getAttributes($element_name, $tag, $second_set) . ">";
-    }
-
-    /**
-    * Restores a configuration with all registered elements and their attributes.
-    * The restored configuration contains only the attributes of the current
-    * registered elements.
-    *
-    * @access       public
-    * @param        object   $module        The module whose configuration will be restored
-    * @param        string   $element_name  The name of the element
-    * @param        string[]     $values        These values overwrites the values in current configuration
-    */
-    public function restore($module, $element_name = '', $values = '')
-    {
-        if ($values && $module) {
-            if ($element_name) {
-                $module_elements[$element_name] = $module->elements[$element_name];
-            } else {
-                $module_elements = $module->elements;
-            }
-
-            foreach ($module_elements as $element_name => $element_obj) {
-                if ($element_obj->isEditable()) {
-                    $attributes = $element_obj->getAttributes();
-                    foreach ($attributes as $attribute) {
-                        $form_name = $element_name . '_' . $attribute;
-                        if (isset($values[$form_name])) {
-                            if (is_array($values[$form_name])) {
-                                $form_value = array_map('stripslashes', $values[$form_name]);
-                            } else {
-                                $form_value = stripslashes($values[$form_name]);
-                            }
-                            $this->setValue($element_name, $attribute, $form_value);
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    public function store ()
-    {
-        $this->permCheck();
-    }
-
-    public function parse ()
-    {
-    }
-
-    public function makeId ()
-    {
-        mt_srand((double) microtime() * 1000000);
-
-        return md5(uniqid(mt_rand(), 1));
-    }
-
-    public function getId ()
-    {
-        return $this->id;
-    }
-
-    public function createConfigName ($range_id)
-    {
-        $configurations = self::GetAllConfigurations($range_id, $this->module_type);
-
-        $config_name_prefix = _("Konfiguration") . ' ';
-        $config_name_suffix = 1;
-        $config_name = $config_name_prefix . $config_name_suffix;
-        $all_config_names = "";
-
-        if (!empty($configurations[$this->module_name]) && count($configurations[$this->module_name])) {
-            foreach ($configurations[$this->module_name] as $configuration) {
-                $all_config_names .= $configuration['name'];
-            }
-        }
-
-        while(mb_stristr($all_config_names, $config_name)) {
-            $config_name = $config_name_prefix . $config_name_suffix;
-            $config_name_suffix++;
-        }
-
-        return $config_name;
-    }
-
-    public function setGlobalConfig ($global_config, $registered_elements)
-    {
-        $this->global_id = $global_config->getId();
-
-        // the name of the global configuration has to be overwritten by the
-        // the name of the main configuration
-        $global_config->config['Main']['name'] = $this->config['Main']['name'];
-
-        // The Main-element is not a registered element, because it is part of every
-        // module. So register it now.
-        $registered_elements[] = 'Main';
-
-        foreach ($registered_elements as $name => $element) {
-            if ((is_int($name) || !$name) && $this->config[$element]) {
-                foreach ($this->config[$element] as $attribute => $value) {
-                    if ($value === '') {
-                        $this->config[$element][$attribute] = $global_config->config[$element][$attribute];
-                    }
-                }
-            }
-            else if ($this->config[$name]) {
-                foreach ($this->config[$name] as $attribute => $value) {
-                    if ($value === '') {
-                        $this->config[$name][$attribute] = $global_config->config[$name][$attribute];
-                    }
-                }
-            }
-        }
-    }
-
-    protected function updateConfiguration ()
-    {
-        $stmt = DBManager::get()->prepare("UPDATE extern_config SET chdate = ?
-            WHERE config_id = ? AND range_id = ?");
-        return $stmt->execute([time(), $this->id, $this->range_id]);
-    }
-
-    public function insertConfiguration ()
-    {
-        $this->permCheck();
-        $query = "SELECT COUNT(config_id) AS count FROM extern_config WHERE ";
-        $query .= "range_id = ? AND config_type = ?";
-        $parameters = [$this->range_id, $this->module_type];
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-        $row = $statement->fetch(PDO::FETCH_ASSOC);
-        if ($row === false && $row['count'] > $GLOBALS['EXTERN_MAX_CONFIGURATIONS']) {
-            return false;
-        }
-
-        return true;
-    }
-
-    public function deleteConfiguration ()
-    {
-        $query = "SELECT config_id FROM extern_config WHERE config_id = ? ";
-        $query .= "AND range_id = ?";
-        $parameters = [$this->id ,$this->range_id];
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-        $row = $statement->fetchColumn();
-        if ($row !== false) {
-            $query = "DELETE FROM extern_config WHERE config_id = ? ";
-            $query .= "AND range_id = ?";
-            $parameters = [$this->id ,$this->range_id];
-            $statement = DBManager::get()->prepare($query);
-            $statement->execute($parameters);
-            return true;
-        }
-        return false;
-    }
-
-    public function copy ($range_id)
-    {
-        $copy_config = self::GetInstance($range_id, $this->module_name);
-        $copy_config->setDefaultConfiguration($this->getConfiguration());
-
-        return $copy_config;
-    }
-
-    /**
-    * Returns an array of meta data for all configurations of an institute
-    *
-    * @param    string  $range_id
-    * @param    string  $type optional parameter to check the right type of
-    * the range_id (the right type of "Einrichtung" sem or fak)
-    *
-    * @return   array       ("name" the name of the configuration, "id" the config_id,
-    * "is_default" TRUE if it is the default configuration)
-    */
-    public static function GetAllConfigurations ($range_id, $type = null)
-    {
-        $all_configs = [];
-        $query = "SELECT * FROM extern_config WHERE range_id = ? ";
-        $parameters = [$range_id];
-        if ($type) {
-            $query .= "AND config_type = ? ";
-            $parameters[] = $type;
-        }
-
-        $query .= 'ORDER BY name ASC';
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-        while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
-            // return registered modules only!
-            $module = $GLOBALS['EXTERN_MODULE_TYPES'][$row['config_type']]['module'];
-            if ($module) {
-                $all_configs[$module][$row['config_id']] = [
-                    'name'       => $row['name'],
-                    'id'         => $row['config_id'],
-                    'is_default' => $row['is_standard'],
-                ];
-            }
-        }
-
-        return $all_configs;
-    }
-
-    public static function GetConfigurationMetaData ($range_id, $config_id)
-    {
-        $query = "SELECT * FROM extern_config WHERE config_id = ? ";
-        $query .= "AND range_id = ? ";
-        $parameters = [$config_id, $range_id];
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-        $row = $statement->fetch(PDO::FETCH_ASSOC);
-        if ($row) {
-            $module_name = $GLOBALS['EXTERN_MODULE_TYPES'][$row['config_type']]['module'];
-            if ($module_name) {
-                $config = ['name' => $row['name'], 'module_name' => $module_name,
-                        'id' => $row['config_id'], 'is_default' => $row['is_standard'],
-                        'type' => $row['config_type']];
-            }
-        } else {
-            return FALSE;
-        }
-
-        return $config;
-    }
-
-    public static function ExistConfiguration ($range_id, $config_id)
-    {
-        $query = "SELECT config_id
-                  FROM extern_config
-                  WHERE config_id = ? AND range_id = ?";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$config_id, $range_id]);
-        return $statement->fetchColumn() > 0;
-    }
-
-    public static function SetStandardConfiguration ($range_id, $config_id)
-    {
-        $query = "SELECT config_type, is_standard FROM extern_config WHERE config_id = ? ";
-        $query .= "AND range_id = ? ";
-        $parameters = [$config_id, $range_id];
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-        $row = $statement->fetch(PDO::FETCH_ASSOC);
-        if ($row !== false) {
-            if ($row['is_standard'] == 0) {
-                $query = "SELECT config_id FROM extern_config WHERE range_id = ? ";
-                $query .= "AND is_standard=1 AND config_type=" . $row['config_type'];
-
-                $params = [$range_id];
-                $state = DBManager::get()->prepare($query);
-                $state->execute($params);
-                $res = $state->fetch(PDO::FETCH_ASSOC);
-                if ($res) {
-                    $query = "UPDATE extern_config SET is_standard=0 WHERE config_id='";
-                    $query .= $res['config_id'] . "'";
-
-                    $state = DBManager::get()->prepare($query);
-                    $state->execute();
-                    if ($state->rowCount() != 1) {
-                        return FALSE;
-                    }
-                }
-            } else {
-                $query = "UPDATE extern_config SET is_standard=0 WHERE config_id = ? ";
-                $params = [$config_id];
-                $state = DBManager::get()->prepare($query);
-                $state->execute($params);
-                if ($state->rowCount() != 1) {
-                    return FALSE;
-                }
-
-                return TRUE;
-            }
-
-            $query = "UPDATE extern_config SET is_standard=1 WHERE config_id = ? ";
-            $params = [$config_id];
-            $state = DBManager::get()->prepare($query);
-            $state->execute($params);
-            if ($state->rowCount() != 1) {
-                return FALSE;
-            }
-        } else {
-            return FALSE;
-        }
-
-        return TRUE;
-    }
-
-    public static function DeleteAllConfigurations ($range_id)
-    {
-        $query = "SELECT config_id FROM extern_config WHERE range_id = ?";
-        $params = [$range_id];
-        $state = DBManager::get()->prepare($query);
-        $state->execute($params);
-        $i = 0;
-        while($res = $state->fetch(PDO::FETCH_ASSOC))
-        {
-            $config = self::getInstance($range_id, '', $res['config_id']);
-            if ($config->deleteConfiguration()) {
-                $i++;
-            }
-        }
-        return $i;
-    }
-
-
-    public static function GetInfo ($range_id, $config_id)
-    {
-        $query = "SELECT * FROM extern_config WHERE config_id = ? ";
-        $query .= " AND range_id = ? ";
-        $params = [$config_id, $range_id];
-        $state = DBManager::get()->prepare($query);
-        $state->execute($params);
-        $res = $state->fetch(PDO::FETCH_ASSOC);
-        if ($res) {
-            $global_config = self::GetGlobalConfiguration($range_id);
-            $module_type = $res['config_type'];
-            $module = $GLOBALS["EXTERN_MODULE_TYPES"][$res['config_type']]["module"];
-            $level = $GLOBALS["EXTERN_MODULE_TYPES"][$res['config_type']]["level"];
-            $make = strftime("%x", $res['mkdate']);
-            $change = strftime("%x", $res['chdate']);
-            $sri = "&lt;studip_remote_include&gt;\n\t&lt;module name=\"$module\" /&gt;";
-            $sri .= "\n\t&lt;config id=\"$config_id\" /&gt;\n\t";
-            if ($global_config) {
-                $sri .= "&lt;global id=\"$global_config\" /&gt;\n\t";
-            }
-            $sri .= "&lt;range id=\"$range_id\" /&gt;";
-            $sri .= "\n&lt;/studip_remote_include&gt;";
-            $link_sri = $GLOBALS["EXTERN_SERVER_NAME"] . 'extern.php?page_url=' . _("URL_DER_INCLUDE_SEITE");
-
-            if ($level) {
-                $link = $GLOBALS["EXTERN_SERVER_NAME"] . "extern.php?module=$module";
-                if ($global_config) {
-                    $link .= "&config_id=$config_id&global_id=$global_config&range_id=$range_id";
-                } else {
-                    $link .= "&config_id=$config_id&range_id=$range_id";
-                }
-                $link_structure = $link . "&view=tree";
-                $sri_structure = "&lt;studip_remote_include&gt;\n\tmodule = $module\n\t";
-                $sri_structure = "config_id = $config_id\n\t";
-                if ($global_config) {
-                    $sri_structure .= "global_id = $global_config\n\t";
-                }
-                $sri_structure .= "range_id=$range_id";
-                $sri_structure .= "\n\tview = tree\n&lt;/studip_remote_include&gt;";
-                $link_br = $GLOBALS["EXTERN_SERVER_NAME"] . "extern.php?module=$module<br>";
-                if ($global_config) {
-                    $link_br .= "&config_id=$config_id<br>&global_id=$global_config<br>&range_id=$range_id";
-                } else {
-                    $link_br .= "&config_id=$config_id<br>&range_id=$range_id";
-                }
-
-                $info = ["module_type" => $module_type, "module_name" => $module,
-                    "name" => $res['name'], "make_date" => $make,
-                    "change_date" => $change, "link" => $link, "link_stucture" => $link_structure,
-                    "sri" => $sri, "sri_structure" => $sri_structure, "link_sri" => $link_sri,
-                    "level" => $level, "link_br" => $link_br];
-            } else {
-                $info = ["module_type" => $module_type, "module_name" => $module,
-                    "name" =>$res['name'], "make_date" => $make,
-                    "change_date" => $change,   "sri" => $sri, "link_sri" => $link_sri,
-                    "level" => $level];
-            }
-
-            return $info;
-        }
-
-        return FALSE;
-    }
-
-    public static function GetGlobalConfiguration ($range_id)
-    {
-        $query = "SELECT config_id
-                  FROM extern_config
-                  WHERE range_id = ? AND config_type = 0 AND is_standard = 1";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$range_id]);
-        return $statement->fetchColumn() ?: false;
-    }
-
-    public static function ChangeName ($range_id, $module_type, $config_id, $old_name, $new_name)
-    {
-        $query = "SELECT 1
-                  FROM extern_config
-                  WHERE range_id = ? AND config_type = ? AND name = ? ";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$range_id, $module_type, $new_name]);
-        if ($statement->fetchColumn()) {
-            return false;
-        }
-
-        $query = "UPDATE extern_config
-                  SET name = ?, chdate = UNIX_TIMESTAMP()
-                  WHERE config_id = ? AND range_id = ? ";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$new_name, $config_id, $range_id]);
-        return $statement->rowCount() > 0;
-    }
-
-    public static function GetConfigurationByName ($range_id, $module_type, $name)
-    {
-        $query = "SELECT config_id
-                  FROM extern_config
-                  WHERE range_id = ?
-                    AND config_type = ?
-                    AND name = ?";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$range_id, $module_type, $name]);
-        return $statement->fetchColumn() ?: false;
-    }
-
-    public static function GetStandardConfiguration ($range_id, $type)
-    {
-        // pick the first one if none is explicitly marked
-        $query = "SELECT config_id
-                  FROM extern_config
-                  WHERE range_id = ?
-                    AND config_type = ?
-                  ORDER BY is_standard DESC, name";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$range_id, $type]);
-        return $statement->fetchColumn() ?: false;
-    }
-
-    public static function GetInstitutesWithConfigurations($check_view = null)
-    {
-        $inst_array = [];
-        $c_types = [];
-        foreach ($GLOBALS['EXTERN_MODULE_TYPES'] as $id => $conf_type) {
-            if ($check_view === null || in_array($check_view, $conf_type['view'])) {
-                $c_types[] = $id;
-            }
-        }
-
-        $query = "SELECT i.Institut_id, i.Name, fakultaets_id
-                  FROM Institute AS i
-                  LEFT JOIN extern_config AS ec ON i.Institut_id = ec.range_id
-                  WHERE i.Institut_id = ec.range_id AND ec.config_type IN (?)
-                  ORDER BY Name";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$c_types ?: '']);
-
-        while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
-            $inst_array[$row['Institut_id']] = [
-                'institut_id'   => $row['Institut_id'],
-                'fakultaets_id' => $row['fakultaets_id'],
-                'name'          => $row['Name'],
-            ];
-        }
-        return $inst_array;
-    }
-
-    private function permCheck ()
-    {
-        // check for sufficient rights
-        if ($this->range_id === 'studip' && $GLOBALS['perm']->have_perm('root')) {
-            return true;
-        }
-        if ($GLOBALS['perm']->have_studip_perm('admin', $this->range_id)) {
-            return true;
-        }
-
-        throw new Exception(_('Sie verfügen nicht über ausreichend Rechte für diese Aktion.'));
-    }
-
-}
diff --git a/lib/extern/lib/ExternConfigDb.class.php b/lib/extern/lib/ExternConfigDb.class.php
deleted file mode 100644
index c1ab29b4ad3..00000000000
--- a/lib/extern/lib/ExternConfigDb.class.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: test
-# Lifter010: TODO
-/**
-* ExternConfigDb.class.php
-*
-* This class is a wrapper class for configuration files.
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternConfig
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternConfigDb.class.php
-// This is a wrapper class for configuration data stored in the database.
-// Copyright (C) 2007 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternConfigDb extends ExternConfig
-{
-    public function store ()
-    {
-        parent::store();
-        $serialized_config = json_encode($this->config);
-
-        if (mb_strlen($serialized_config)) {
-            $stmt = DBManager::get()->prepare("UPDATE extern_config
-                SET config = ?, chdate = UNIX_TIMESTAMP()
-                WHERE config_id = ? AND range_id = ?");
-            $stmt->execute($data = [$serialized_config, $this->id, $this->range_id]);
-
-            return($this->updateConfiguration());
-        } else {
-            ExternModule::printError();
-            return FALSE;
-        }
-
-    }
-
-    public function parse ()
-    {
-        $query = "SELECT config FROM extern_config WHERE config_id = ?";
-        $parameters = [$this->id];
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-        $row = $statement->fetchColumn();
-        if ($row) {
-            $this->config = json_decode($row, true);
-        } else {
-            ExternModule::printError();
-        }
-    }
-
-    public function insertConfiguration ()
-    {
-        if (!parent::insertConfiguration()) {
-            return false;
-        }
-         $serialized_config = json_encode($this->config ?? null);
-         $time = time();
-         $query = "INSERT INTO extern_config VALUES (?, ?, ?, ?, 0, ?, ?, ?)";
-         $statement = DBManager::get()->prepare($query);
-         $statement->execute([
-             $this->id,
-             $this->range_id,
-             $this->module_type,
-             $this->config_name,
-             $serialized_config,
-             $time,
-             $time
-        ]);
-        return $statement->rowCount() > 0;
-    }
-}
diff --git a/lib/extern/lib/ExternEdit.class.php b/lib/extern/lib/ExternEdit.class.php
deleted file mode 100644
index ea7d340d80f..00000000000
--- a/lib/extern/lib/ExternEdit.class.php
+++ /dev/null
@@ -1,270 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternEdit.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternEdit
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternEdit.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-use Studip\Button, Studip\LinkButton;
-
-class ExternEdit {
-
-    var $config;
-    var $form_values = [];
-    var $faulty_values = [];
-    var $element_name = "main";
-    var $is_post_vars = FALSE;
-    var $edit_element;
-    var $width_1 = " width=\"20%\"";
-    var $width_2 = " width=\"80%\"";
-    var $error_sign = "<font size=\"4\" color=\"ff0000\">&nbsp; &nbsp;<b>*</b></font>";
-
-    function __construct(&$config, $form_values = "", $faulty_values = "",
-             $edit_element = "") {
-
-        $this->config =& $config;
-        $this->form_values = $form_values;
-        $this->edit_element = $edit_element;
-
-        if (is_array($form_values))
-            $this->is_post_vars = TRUE;
-
-        if ($faulty_values != "")
-            $this->faulty_values = $faulty_values;
-    }
-
-    function setElementName ($element_name) {
-        $this->element_name = $element_name;
-    }
-
-    function getValue ($attribute) {
-        if ($this->is_post_vars && ($this->edit_element == $this->element_name)) {
-            $form_name = $this->element_name . "_" . $attribute;
-            $value = $this->form_values[$form_name];
-
-            if ($value != "" || $this->faulty_values[$form_name]) {
-                if (is_array($value)) {
-                    // fit the values for output in a form
-                    foreach ($value as $key => $val) {
-                        $val_tmp[$key] = htmlReady(stripslashes($val));
-                    }
-                    return $val_tmp;
-                }
-                return htmlReady(stripslashes($value));
-            }
-        }
-
-        $value = $this->config->getValue($this->element_name, $attribute);
-        if (is_array($value)) {
-            // fit the values for output in a form
-            foreach ($value as $key => $val) {
-                $val_tmp[$key] = htmlReady(stripslashes($val));
-            }
-            return $val_tmp;
-        }
-        return htmlReady($this->config->getValue($this->element_name, $attribute));
-    }
-
-    function getEditFormContent ($attributes, $tag_headlines = NULL)
-    {
-        $previous_tag = '';
-
-        $out = '';
-
-        foreach ($attributes as $attribute) {
-            $attribute_part = explode('_', $attribute);
-
-            if (!$attribute_part[2] && $attribute_part[1]) {
-                $edit_function = 'edit' . $attribute_part[1];
-
-                if ($attribute_part[0] != $previous_tag) {
-                    if ($previous_tag != '') {
-                        $out .= $this->editContentTable($headline, $table);
-                        $out .= $this->editBlankContent();
-                        if (!is_array($tag_headlines)) {
-                            $headline = sprintf(_("Angaben zum HTML-Tag &lt;%s&gt;"), $attribute_part[0]);
-                        } else {
-                            $headline = $tag_headlines[$attribute_part[0]];
-                        }
-                        $headline = $this->editHeadline($headline);
-                        $table = '';
-                    } else {
-                        if (!is_array($tag_headlines)) {
-                            $headline = sprintf(_("Angaben zum HTML-Tag &lt;%s&gt;"), $attribute_part[0]);
-                        } else {
-                            $headline = $tag_headlines[$attribute_part[0]];
-                        }
-                        $headline = $this->editHeadline($headline);
-                    }
-                    $previous_tag = $attribute_part[0];
-                }
-                $table .= $this->$edit_function($attribute);
-
-            } elseif ($attribute_part[2] && $tag_headlines["{$attribute_part[0]}_{$attribute_part[2]}"]) {
-
-                $attribute_name = $attribute_part[0] . '_' . $attribute_part[2];
-                $edit_function = 'edit' . $attribute_part[1];
-                if ($attribute_name != $previous_tag) {
-                    if ($previous_tag != '') {
-                        $out .= $this->editContentTable($headline, $table);
-                        $out .= $this->editBlankContent();
-                        $headline = $this->editHeadline($tag_headlines[$attribute_name]);
-                        $table = '';
-                    } else {
-                        $headline = $this->editHeadline($tag_headlines[$attribute_name]);
-                    }
-                    $previous_tag = $attribute_name;
-                }
-                $table .= $this->$edit_function($attribute);
-            }
-
-        }
-
-        $out .= $this->editContentTable($headline, $table);
-
-        return $out;
-    }
-
-    function editHeader () {
-        $out = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" ";
-        $out .= "width=\"95%\" align=\"left\">\n";
-
-        return $out;
-    }
-
-    function editFooter () {
-        $out = "</table>\n";
-
-        return $out;
-    }
-
-    function editSubmit ($module_name, $config_id, $element_name = "", $hidden = NULL) {
-        $out = "<footer>";
-        $out .= Button::createAccept(_("Ãœbernehmen"), "submit");
-        $out .= LinkButton::createCancel(_("Abbrechen"), URLHelper::getURL('?list=TRUE'));
-        $out .= "<input type=\"hidden\" name=\"config_id\" value=\"$config_id\">";
-        $out .= "<input type=\"hidden\" name=\"mod\" value=\"$module_name\">";
-        if ($element_name) {
-            $out .= "<input type=\"hidden\" name=\"edit\" value=\"$element_name\">";
-        }
-        if (!is_null($hidden)) {
-            foreach ($hidden as $name => $value) {
-                $out .= "<input type=\"hidden\" name=\"$name\" value=\"$value\">";
-            }
-        }
-        $out .= "</footer>";
-
-        return $out;
-    }
-
-    function editHeadline ($headline) {
-        $out = "<legend>" . $headline . "</legend>";
-        return $out;
-    }
-
-    function editElementHeadline ($element_real_name, $module_name, $config_id,
-            $open = TRUE) {
-
-        $icon =  Icon::create('file-generic', 'clickable')->asImg(['class' => 'text-top']);
-
-        if ($open) {
-            $link = URLHelper::getLink('?com=close&mod=' . $module_name . '&edit=' . $this->element_name . '&config_id=' . $config_id . '#anker');
-            $open = "open";
-        }
-        else {
-            $link = URLHelper::getLink('?com=open&mod=' . $module_name . '&edit=' . $this->element_name . '&config_id=' . $config_id . '#anker');
-            $open = "close";
-        }
-
-        $titel = $element_real_name;
-        $titel = "<a class=\"tree\" href=\"$link\">$titel</a>";
-        if ($this->element_name == $this->edit_element)
-            $titel .= "<a name=\"anker\">&nbsp;</a>";
-
-        $out = "<tr><td class=\"blank\" width=\"100%\">\n";
-        $out .= "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
-        $out .= "<tr>\n";
-        $out .= printhead(0, "", $link, $open, TRUE, $icon, $titel, "", 0, FALSE);
-        $out .= "</tr></table>\n</td></tr>\n";
-
-        return $out;
-    }
-
-    function editContentTable ($header, $body) {
-        $out = "\n<!-- BEGIN ContentTable -->\n";
-        $out .= "<fieldset>" . $header . $body . "</fieldset>";
-
-        $out .= "<!-- END ContentTable -->\n";
-
-        return $out;
-    }
-
-    function editContent ($content, $submit, $class = "") {
-        $out = "<tr><td class=\"$class\" width=\"100%\" align=\"left\">\n";
-        $out .= '<form name="edit_form" class="default method-'.__METHOD__.'" action="' . URLHelper::getLink('?com=store#anker') .  '" method="post">';
-        $out .= CSRFProtection::tokenTag();
-        $out .= "$content$submit</form>\n";
-        $out .= "</td></tr>\n";
-
-        return $out;
-    }
-
-    function editBlankContent ($class = "") {
-        $out = "";
-        return $out;
-    }
-
-    function editBlankContentTable ($class = "") {
-        $out = "<tr><td>\n<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
-        $out .= "<tr><td class=\"$class\">&nbsp;</td></tr>\n";
-        $out .= "</table>\n</td></tr>\n";
-
-        return $out;
-    }
-
-    function editBlank ($class = "") {
-        $out = '';
-        return $out;
-    }
-
-    function editTextblock ($text, $class = "") {
-        $out = "<tr><td>\n<table width=\"100%\" border=\"0\" cellpadding=\"5\" cellspacing=\"0\">\n";
-        $out .= "<tr><td class=\"$class\">$text</td></tr>\n";
-        $out .= "</table>\n</td></tr>\n";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/lib/ExternElement.class.php b/lib/extern/lib/ExternElement.class.php
deleted file mode 100644
index 5f2f9262751..00000000000
--- a/lib/extern/lib/ExternElement.class.php
+++ /dev/null
@@ -1,529 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter005: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElement.class.php
-*
-* This is an abstract class that define an interface to every so called HTML-element
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElement
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElement.class.php
-// This is an abstract class that define an interface to every so called HTML-element
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-class ExternElement {
-
-    var $type;
-    var $config;
-    var $name;
-    var $attributes;
-    var $real_name;
-    var $description;
-    var $headlines = [];
-    var $link_module_type;
-
-
-    /**
-    *
-    */
-    public static function GetInstance (&$config, $element_name, &$data_fields = null, &$field_names = null) {
-        $class_name = "ExternElement" . $element_name;
-        require_once "lib/extern/elements/$class_name.class.php";
-        $element = new $class_name();
-        $element->config =& $config;
-
-        return $element;
-    }
-
-
-    /**
-    * Constructor
-    * Don't call direct, use GetInstance() instead.
-    *
-    * @param array config
-    * @param string element_name
-    */
-    function __construct (&$config, $element_name) {
-    }
-
-    /**
-    *
-    */
-    function getType () {
-        return $this->type;
-    }
-
-    /**
-    *
-    */
-    function getName () {
-        return $this->name;
-    }
-
-    /**
-    *
-    */
-    function getRealname () {
-        return $this->real_name;
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-        $config = [];
-
-        reset($this->attributes);
-        foreach ($this->attributes as $attribute)
-            $config[$attribute] = "";
-
-        return $config;
-    }
-
-    /**
-    *
-    */
-    function isEditable () {
-        if (is_array($this->attributes) && count($this->attributes))
-            return TRUE;
-
-        return FALSE;
-    }
-
-    /**
-    *
-    */
-    function getValue ($attribute) {
-        return $this->config->getValue($this->type, $attribute);
-    }
-
-    /**
-    *
-    */
-    function toString ($args = NULL) {
-        return "";
-    }
-
-    /**
-    *
-    */
-    function printout ($args = NULL) {
-        echo $this->toString($args);
-    }
-
-    /**
-    *
-    */
-    function toStringEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-        $out = "";
-        if ($edit_form == "")
-            $edit_form = new ExternEditHtml($this->config, $post_vars, $faulty_values, $anker);
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $this->getEditFormHeadline($edit_form);
-
-        $out = $edit_form->getEditFormContent($this->attributes);
-
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($out, $submit);
-        $out .= $edit_form->editBlank();
-
-        return  $element_headline . $out;
-    }
-
-    function getEditFormHeadline (&$edit_form) {
-        $headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE);
-
-        return $headline;
-    }
-
-    /**
-    *
-    */
-    function printoutEdit ($post_vars = "", $faulty_values = "",
-            $edit_form = "", $anker = "") {
-
-        echo $this->toStringEdit($post_vars, $faulty_values, $edit_form, $anker);
-    }
-
-    /**
-    *
-    */
-    function getAttributes ($short = TRUE) {
-        if ($short)
-            return $this->attributes;
-
-        reset($this->attributes);
-        foreach($this->attributes as $attribute)
-            $attributes_long[] = $this->name . "_" . $attribute;
-
-        return $attributes_long;
-    }
-
-    /**
-    *
-    */
-    function getDescription () {
-        return $this->description;
-    }
-
-    /**
-    *
-    */
-    function executeCommand ($command, $value = "") {
-        switch ($command) {
-            case "show" :
-                $visible = $this->config->getValue($this->name, "visible");
-                if ($value >= 0 || $value < sizeof($visible)) {
-                    $visible[$value] = "1";
-                    $this->config->setValue($this->name, "visible", $visible);
-
-                    Request::set("{$this->name}_visible",$visible);
-                    $_POST["{$this->name}_visible"] = $visible;
-                }
-                break;
-
-            case "hide" :
-                $visible = $this->config->getValue($this->name, "visible");
-                if ($value >= 0 || $value < sizeof($visible)) {
-                    $visible[$value] = "0";
-                    $this->config->setValue($this->name, "visible", $visible);
-                    Request::set("{$this->name}_visible",$visible);
-                    $_POST["{$this->name}_visible"] = $visible;
-                }
-                break;
-
-            case "move_left" :
-                $order = $this->config->getValue($this->name, "order");
-                if ($value >= 0 || $value < sizeof($order)) {
-                    $a = $order[$value];
-                    if (($value - 1) < 0) {
-                        $b = array_pop($order);
-                        array_push($order, $a);
-                        $order[0] = $b;
-                    } else {
-                        $b = $order[$value - 1];
-                        $order[$value - 1] = $a;
-                        $order[$value] = $b;
-                    }
-                    $this->config->setValue($this->name, "order", $order);
-                    Request::set("{$this->name}_order", $order);
-                }
-                break;
-
-            case "move_right" :
-                $order = $this->config->getValue($this->name, "order");
-                if ($value >= 0 || $value < sizeof($order)) {
-                    $a = $order[$value];
-                    if (($value + 1) >= sizeof($order)) {
-                        $b = $order[0];
-                        $order[0] = $a;
-                        $order[$value] = $b;
-                    } else {
-                        $b = $order[$value + 1];
-                        $order[$value + 1] = $a;
-                        $order[$value] = $b;
-                    }
-                    $this->config->setValue($this->name, "order", $order);
-                    Request::set("{$this->name}_order", $order);
-                }
-                break;
-
-            case "show_group" :
-                $groups = get_all_statusgruppen($this->config->range_id);
-                if (!$groups) {
-                    $this->config->setValue($this->name, 'groupsvisible', []);
-                } else if (is_array($value)) {
-                    $groups_visible = [];
-                    foreach ($value as $group_id => $checked) {
-                        if ($checked) {
-                            $groups_visible[] = $group_id;
-                        }
-                    }
-                    $visible = array_intersect($groups_visible, array_keys($groups));
-                    $this->config->setValue($this->name, 'groupsvisible', $visible);
-                    Request::set("{$this->name}_groupsvisible", array_values($visible));
-                }
-                break;
-
-            case "hide_group" :
-                $visible = $this->config->getValue($this->name, "groupsvisible");
-                if ($groups = get_all_statusgruppen($this->config->range_id)) {
-                    $groups = array_keys($groups);
-                    $visible = array_intersect($groups, $visible);
-                } else break;
-                // initialize groupsvisible if it isn't set in the config file
-                // all groups are visible (1)
-                if (!$visible) {
-                    $visible = array_keys(get_all_statusgruppen($this->config->range_id));
-                }
-                $visible = array_diff($visible, [$value]);
-                $this->config->setValue($this->name, "groupsvisible", $visible);
-                Request::set("{$this->name}_groupsvisible", array_values($visible));
-                break;
-
-            default :
-                return FALSE;
-        }
-
-        return TRUE;
-    }
-
-    /**
-    *
-    */
-    function checkFormValues () {
-
-        $fault = [];
-
-        $_POST['Main_copyright'] = htmlReady(decodeHTML(
-                $_POST['Main_copyright']));
-        $_POST['Main_author'] = htmlReady(decodeHTML(
-                $_POST['Main_author']));
-
-        foreach ($this->attributes as $attribute) {
-            $form_name = $this->name . "_" . $attribute;
-
-            // Check for an alternative input field. All names of alternative input
-            // fields begin with an underscore. The alternative input field overwrites
-            // the input field having the same name but without the leading underscore.
-            if (isset($_POST["_$form_name"])) {
-                if ($_POST[$form_name] == $this->config->config[$this->name][$attribute]
-                        && $_POST["_$form_name"] != "")
-                    $_POST[$form_name] = $_POST["_$form_name"];
-            }
-            if (is_array($_POST[$form_name])) {
-                $value = $_POST[$form_name];
-            } else {
-                $value = [$_POST[$form_name]];
-            }
-
-            $splitted_attribute = explode("_", $attribute);
-            if (sizeof($splitted_attribute) == 1) {
-                $html_attribute = $splitted_attribute[0];
-            } else {
-                $html_attribute = $splitted_attribute[1] . $splitted_attribute[2];
-            }
-
-            for ($i = 0; $i < sizeof($value); $i++) {
-
-                if ($html_attribute != 'template') {
-                    // Don't accept strings longer than 200 characters!
-                    if (mb_strlen($value[$i]) > 200) {
-                        $fault[$form_name][$i] = TRUE;
-                        continue;
-                    }
-
-                    if (preg_match("/(<|>|\"|\|)/i", $value[$i])) {
-                        $fault[$form_name][$i] = TRUE;
-                        continue;
-                    }
-                }
-
-                switch ($html_attribute) {
-
-                    case "height" :
-                        $fault[$form_name][$i] = (!preg_match("/^\d{0,3}$/", $value[$i])
-                                || $value[$i]> 2000 || $value[$i]< 0);
-                        break;
-                    case "cellpadding" :
-                    case "cellspacing" :
-                    case "border" :
-                    case "sort" :
-                        $fault[$form_name][$i] = (!preg_match("/^\d{0,2}$/", $value[$i])
-                                || $value[$i]> 100 || $value[$i]< 0);
-                        break;
-                    case "width" :
-                        $fault[$form_name][$i] = (!preg_match("/^\d{0,4}$/", $value[$i])
-                                || $value[$i]> 2000 || $value[$i]< 0);
-                        if ($_POST["{$form_name}pp"] == "%") {
-                            if (is_array($_POST[$form_name])) {
-                                $_POST[$form_name][$i] = $_POST[$form_name][$i] . "%";
-                            } else {
-                                $_POST[$form_name] = $_POST[$form_name] . "%";
-                            }
-                        }
-                        break;
-                    case "valign" :
-                        $fault[$form_name][$i] = $value[$i]
-                                && !preg_match("/^(top|bottom|center)$/", $value[$i]);
-                        break;
-                    case "align" :
-                        $fault[$form_name][$i] = $value[$i]
-                                && !preg_match("/^(left|right|center|bottom|middle|top)$/", $value[$i]);
-                        break;
-                    case "size" :
-                        $fault[$form_name][$i] = $value[$i]
-                                && !preg_match("/^(-|\+)*(1|2|3|4|5|6|7)$/", $value[$i]);
-                        break;
-                    case "face" :
-                        $fault[$form_name][$i] = $value[$i] && !preg_match("/^(Arial,Helvetica,sans-serif|"
-                                . "Times,Times New Roman,serif|Courier,Courier New,monospace)$/", $value[$i]);
-                        break;
-                    case "background" :
-                        $fault[$form_name][$i] = ($value[$i]
-                                && (preg_match("/(<|>|\"|<script|<php)/i", $value[$i])
-                                || !preg_match("/^[^.\/\\\].*\.(png|jpg|jpeg|gif)$/i", $value[$i])));
-                        break;
-                    case "wholesite" :
-                    case "addinfo" :
-                    case "time" :
-                    case "lecturer" :
-                        // This is especially for checkbox-values. If there is no checkbox
-                        // checked, the variable is not declared and it is necessary to set the
-                        // variable to "".
-                        if (!isset($_POST[$form_name])) {
-                            $_POST[$form_name] = "";
-                            break;
-                        }
-                        $fault[$form_name][$i] = !($value[$i] == "1" || $value[$i] == "" || !isset($value[$i]));
-                        break;
-                    case "name" :
-                        $_POST[$form_name] = trim($_POST[$form_name]);
-                        $fault[$form_name][$i] = (preg_match("/^.*(<script|<php).*$/i", $value[$i])
-                                || !preg_match("/^[0-9a-z\._\- ]+$/i", $value[$i]));
-                        break;
-                    case "widthpp" :
-                        $fault[$form_name][$i] = !($value[$i] == "" || $value[$i] == "%");
-                        break;
-                    case "nameformat" :
-                        $fault[$form_name][$i] = !($value[$i] == "no_title_short" || $value[$i] == "no_title"
-                                || $value[$i] == "no_title_rev" || $value[$i] == "full"
-                                || $value[$i] == "full_rev" || $value[$i] == "");
-                        break;
-                    case "dateformat" :
-                        $fault[$form_name][$i] = !($value[$i] == "%d. %b. %Y" || $value[$i] == "%d.%m.%Y"
-                                || $value[$i] == "%d.%m.%y" || $value[$i] == "%d. %B %Y" || $value[$i] == "%m/%d/%y");
-                        break;
-                    case "language" :
-                        $fault[$form_name][$i] = !($value[$i] == "de_DE" || $value[$i] == "en_GB"
-                                || $value[$i] == "");
-                        break;
-                    default :
-                        $fault[$form_name][$i] = $this->checkValue($html_attribute, $value[$i]);
-
-                }
-
-            }
-
-        }
-
-        if (in_array(TRUE, $fault)) {
-            return $fault;
-        }
-
-        return FALSE;
-    }
-
-    function checkValue ($attribute, $value) {
-
-        return FALSE;
-    }
-
-    function createUrl ($args = NULL) {
-        if (!isset($args['main_module'])) {
-            $args['main_module'] = 'Main';
-        }
-        $config_meta_data = ExternConfig::GetConfigurationMetaData($this->config->range_id, $this->config->getValue($this->getName(), 'config'));
-        if (is_array($config_meta_data)) {
-            $module_name = $config_meta_data['module_name'];
-        } else {
-            foreach ((array) $this->link_module_type as $type) {
-                $module_name = $GLOBALS['EXTERN_MODULE_TYPES'][$type]['module'];
-                $configs = ExternConfig::GetAllConfigurations($this->config->range_id, $type);
-                if (is_array($configs) && count($configs)) {
-                    break;
-                }
-            }
-        }
-        $sri_link = $this->config->getValue($this->getName(), 'srilink');
-        $extern_link = $this->config->getValue($this->getName(), 'externlink');
-        if ($this->config->getValue($args['main_module'], 'incdata')) {
-            $link = $sri_link;
-            if ($args['link_args']) {
-                if (strpos($link, '?')) {
-                    $link .= '&' . $args['link_args'];
-                } else {
-                    $link .= '?' . $args['link_args'];
-                }
-            }
-            if ($this->config->global_id) {
-                $link .= '&global_id=' . $this->config->global_id;
-            }
-        } else {
-            if ($sri_link) {
-                $link = $GLOBALS['EXTERN_SERVER_NAME'] . 'extern.php';
-                if ($args['link_args']) {
-                    $link .= '?' . $args['link_args'] . '&';
-                } else {
-                    $link .= '?';
-                }
-                if ($this->config->global_id) {
-                    $link .= 'global_id=' . $this->config->global_id . '&';
-                }
-                $link .= 'page_url=' . $sri_link;
-            } elseif ($extern_link) {
-                if (strpos($extern_link, '?')) {
-                    $link = "$extern_link&module=$module_name";
-                } else {
-                    $link = "$extern_link?module=$module_name";
-                }
-                if ($config = $this->config->getValue($this->getName(), 'config')) {
-                    $link .= '&config_id=' . $config;
-                }
-                $link .= '&range_id=' . $this->config->range_id;
-                if ($args['link_args']) {
-                    $link .= '&' . $args['link_args'];
-                }
-                if ($this->config->global_id) {
-                    $link .= '&global_id=' . $this->config->global_id;
-                }
-            } else {
-                $link = $GLOBALS['EXTERN_SERVER_NAME'] . "extern.php?module=$module_name";
-                if ($config = $this->config->getValue($this->getName(), 'config')) {
-                    $link .= '&config_id=' . $config;
-                }
-                $link .= '&range_id=' . $this->config->range_id;
-                if ($args['link_args']) {
-                    $link .= '&' . $args['link_args'];
-                }
-                if ($this->config->global_id) {
-                    $link .= '&global_id=' . $this->config->global_id;
-                }
-            }
-        }
-        return ExternModule::ExtHtmlReady($link);
-    }
-}
diff --git a/lib/extern/lib/ExternElementMain.class.php b/lib/extern/lib/ExternElementMain.class.php
deleted file mode 100644
index 30a572af01c..00000000000
--- a/lib/extern/lib/ExternElementMain.class.php
+++ /dev/null
@@ -1,133 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternElementMain.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternElementMain
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElementMain.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-class ExternElementMain extends ExternElement {
-
-    var $attributes = [];
-    var $edit_function;
-    var $data_fields;
-    var $field_names;
-
-    /**
-    *
-    */
-    public static function GetInstance (&$config, $module_name, &$data_fields = null, &$field_names = null) {
-        if ($module_name != '') {
-            $main_class_name = 'ExternElementMain' . ucfirst($module_name);
-            require_once "lib/extern/elements/main/$main_class_name.class.php";
-            $main_module = new $main_class_name($module_name, $data_fields, $field_names, $config);
-
-            return $main_module;
-        }
-
-        return NULL;
-    }
-
-    /**
-    * Constructor
-    *
-    */
-    function __construct ($module_name, &$data_fields, &$field_names, &$config) {
-        $this->real_name = _("Grundeinstellungen");
-        $this->description = _("In den Grundeinstellungen können Sie allgemeine Daten des Elements ändern.");
-        $this->name = 'Main';
-        $this->edit_function = 'editMainSettings';
-        $this->config =& $config;
-        $this->data_fields =& $data_fields;
-        $this->field_names =& $field_names;
-        if (Config::get()->EXTERN_SRI_ENABLE && (!Config::get()->EXTERN_SRI_ENABLE_BY_ROOT ||
-                (sri_is_enabled($this->config->range_id) && Config::get()->EXTERN_SRI_ENABLE_BY_ROOT))) {
-            $this->attributes[] = 'sriurl';
-        }
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {}
-
-    public function toStringEdit ($post_vars = "", $faulty_values = "", $edit_form = "", $anker = "")
-    {
-        if (!$edit_form) {
-            $edit_form = new ExternEdit($this->config, $post_vars, $faulty_values, $anker);
-        }
-
-        $edit_form->setElementName($this->getName());
-        $element_headline = $edit_form->editElementHeadline($this->real_name,
-                $this->config->getName(), $this->config->getId(), TRUE);
-
-        if ($faulty_values == '')
-            $faulty_values = [];
-
-        $edit_function = $this->edit_function;
-        $table = $edit_form->$edit_function($this->field_names);
-
-        $content_table = $edit_form->editContentTable('', $table);
-        $submit = $edit_form->editSubmit($this->config->getName(),
-                $this->config->getId(), $this->getName());
-        $out = $edit_form->editContent($content_table, $submit);
-        $out .= $edit_form->editBlank();
-
-        return $element_headline . $out;
-    }
-
-    function getSRIFormContent (&$edit_form, $include_url = false) {
-        $content = '';
-        $sri_info = _("Nur bei Benutzung der SRI-Schnittstelle für dieses Modul: Geben Sie hier die vollständige URL der Seite an, in die die Ausgabe des Moduls eingefügt werden soll.");
-        if (!$include_url && Config::get()->EXTERN_SRI_ENABLE && (!Config::get()->EXTERN_SRI_ENABLE_BY_ROOT ||
-                (sri_is_enabled($this->config->range_id) && Config::get()->EXTERN_SRI_ENABLE_BY_ROOT))) {
-            $headline = $edit_form->editHeadline(_("URL des SRI-Templates"));
-            $table = $edit_form->editTextfieldGeneric("sriurl", '', $sri_info, 70, 350);
-            $content = $edit_form->editContentTable($headline, $table);
-            $content .= $edit_form->editBlankContent();
-        }
-        if ($include_url) {
-            $table = '';
-            $headline = $edit_form->editHeadline(_("Einbindung des Moduls"));
-            if (Config::get()->EXTERN_SRI_ENABLE && (!Config::get()->EXTERN_SRI_ENABLE_BY_ROOT ||(sri_is_enabled($this->config->range_id) && Config::get()->EXTERN_SRI_ENABLE_BY_ROOT))) {
-                $table = $edit_form->editTextfieldGeneric('sriurl', 'SRI-URL', $sri_info, 50, 350);
-            }
-            $table .= $edit_form->editTextfieldGeneric('includeurl', 'include-URL', _("URL der Seite, in der die Ausgabe des Moduls per Include (z.B. durch eine Script-Sprache) eingebunden wird."), 50, 350);
-            $content = $edit_form->editContentTable($headline, $table);
-            $content .= $edit_form->editBlankContent();
-        }
-        return $content;
-    }
-
-}
diff --git a/lib/extern/lib/ExternModule.class.php b/lib/extern/lib/ExternModule.class.php
deleted file mode 100644
index 9b9d55ba919..00000000000
--- a/lib/extern/lib/ExternModule.class.php
+++ /dev/null
@@ -1,574 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: test
-# Lifter010: TODO
-/**
-* ExternModule.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModule
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternElement.class.php
-// This is an abstract class that define an interface to every so called HTML-element
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'lib/extern/views/ExternEditModule.class.php';
-
-class ExternModule {
-
-    var $type = NULL;
-    var $name;
-    var $config;
-    var $registered_elements = [];
-    var $elements = [];
-    var $field_names = [];
-    var $data_fields = [];
-    var $args = [];
-    private static $is_raw_output = false;
-
-
-    /**
-    *
-    */
-    public static function GetInstance ($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-
-        if ($module_name != '') {
-            $module_name = ucfirst($module_name);
-            require_once "lib/extern/modules/ExternModule$module_name.class.php";
-
-            $class_name = "ExternModule" . $module_name;
-            $module = new $class_name($range_id, $module_name, $config_id, $set_config, $global_id);
-            return $module;
-        }
-
-        return NULL;
-    }
-
-    /**
-    * The constructor of a child class has to call this parent constructor!
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-
-        foreach ($GLOBALS["EXTERN_MODULE_TYPES"] as $type => $module) {
-            if ($module["module"] == $module_name) {
-                $this->type = $type;
-                break;
-            }
-        }
-
-        // the module is called via extern.php (not via the admin area) and there is
-        // no config_id so it's necessary to check the range_id
-        if (!$config_id && !$this->checkRangeId($range_id)) {
-            self::printError();
-        }
-        if (is_null($this->type)) {
-            self::printError();
-        }
-
-        $this->name = $module_name;
-
-        if ($config_id) {
-            $this->config = ExternConfig::GetInstance($range_id, $module_name, $config_id);
-        } else  {
-            $this->config = ExternConfig::GetInstance($range_id, $module_name);
-        }
-
-        // the "Main"-element is included in every module and needs information
-        // about the data this module handles with
-        $this->elements["Main"] = ExternElementMain::GetInstance(
-            $this->config, $module_name,
-            $this->data_fields, $this->field_names
-        );
-
-        // instantiate the registered elements
-        foreach ($this->registered_elements as $name => $registered_element) {
-            if (is_int($name) || !$name) {
-                $this->elements[$registered_element] = ExternElement::GetInstance($this->config, $registered_element);
-            } else {
-                $this->elements[$name] = ExternElement::GetInstance($this->config, $registered_element);
-                $this->elements[$name]->name = $name;
-            }
-        }
-
-        if ($set_config && !$config_id) {
-            $config = $this->getDefaultConfig();
-            $this->config->setDefaultConfiguration($config);
-        }
-
-        // overwrite modules configuration with global configuration
-        if (!is_null($global_id)) {
-            $this->config->setGlobalConfig(ExternConfig::GetInstance($range_id, $module_name, $global_id),
-                    $this->registered_elements);
-        }
-
-        $this->setup();
-    }
-
-    /**
-    *
-    */
-    function getType () {
-        return $this->type;
-    }
-
-    /**
-    *
-    */
-    function getName () {
-        return $this->name;
-    }
-
-    /**
-    *
-    */
-    function &getConfig () {
-        return $this->config;
-    }
-
-    /**
-    *
-    */
-    function getDefaultConfig () {
-        $default_config = [];
-
-        if ($default_config = $this->getRangeDefaultConfig('global')) {
-            return $default_config;
-        }
-        foreach ($this->elements as $element) {
-            if ($element->isEditable()) {
-                $default_config[$element->getName()] = $element->getDefaultConfig();
-            }
-        }
-
-        return $default_config;
-    }
-
-    function getRangeDefaultConfig ($range_id = 'global') {
-        $query = "SELECT config_type FROM extern_config WHERE config_id = ? AND range_id = ?";
-        $parameters = [$this->getName(), $range_id ];
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-        $row = $statement->fetchColumn();
-        if ($row !== false) {
-            $config_obj = ExternConfig::GetInstance($range_id, $this->getName(), $this->getName());
-            $config = $config_obj->getConfiguration();
-            return $config;
-        }
-
-        return FALSE;
-    }
-
-    /**
-    *
-    */
-    function getAllElements () {
-        return $this->elements;
-    }
-
-    /**
-    *
-    */
-    function getValue ($attribute) {
-        return $this->config->getValue($this->name, $attribute);
-    }
-
-    /**
-    *
-    */
-    function setValue ($attribute, $value) {
-        $this->config->setValue($this->name, $attribute, $value);
-    }
-
-    /**
-    *
-    */
-    function getAttributes ($element_name, $tag_name) {
-        return $this->config->getAttributes($element_name, $tag_name);
-    }
-
-    function getArgs () {
-
-        return $this->args;
-    }
-
-    /**
-    *
-    */
-    function toString ($args) {}
-
-    /**
-    *
-    */
-    function toStringEdit ($open_elements = "", $post_vars = "",
-            $faulty_values = "", $anker = "") {
-
-        require_once "lib/extern/views/ExternEditModule.class.php";
-        $edit_form = new ExternEditModule($this->config, $post_vars, $faulty_values, $anker);
-
-        $out = $edit_form->editHeader();
-
-        foreach ($this->elements as $element) {
-            if ($element->isEditable()) {
-                if (isset($open_elements[$element->getName()])) {
-                    $out .= $element->toStringEdit($post_vars, $faulty_values, $edit_form, $anker);
-                } else {
-                    $edit_form->setElementName($element->getName());
-                    $out .= $edit_form->editElementHeadline($element->getRealName(),
-                            $this->getName(), $this->config->getId(), FALSE, $anker);
-                }
-            }
-        }
-
-        $out .= $edit_form->editFooter();
-
-        return $out;
-    }
-
-    /**
-    *
-    */
-    function printout ($args) {
-        echo $this->toString($args);
-    }
-    /**
-    *
-    */
-    function printoutEdit ($element_name = "", $post_vars = "",
-            $faulty_values = "", $anker = "") {
-
-        echo $this->toStringEdit($element_name, $post_vars, $faulty_values, $anker);
-    }
-
-    /**
-    *
-    */
-    function checkFormValues ($element_name = "") {
-        $faulty_values = [];
-
-        if ($element_name == "") {
-            foreach ($this->elements as $element) {
-                if ($faulty = $element->checkFormValues()) {
-                    $faulty_values = $faulty_values + $faulty;
-                }
-            }
-        }
-        else {
-            if ($faulty_values = $this->elements[$element_name]->checkFormValues()) {
-                return $faulty_values;
-            }
-        }
-
-        if (is_array($faulty_values) && count($faulty_values)) {
-            return $faulty_values;
-        }
-
-        return FALSE;
-    }
-
-    /**
-    *
-    */
-    function store ($element_name = '', $values = '') {
-        $this->config->restore($this, $element_name, $values);
-        $this->config->store();
-    }
-
-    /**
-    *
-    */
-    function getDescription () {
-        return $GLOBALS["EXTERN_ELEMENT_TYPES"][$this->type]["description"];
-    }
-
-    /**
-    *
-    */
-    function executeCommand ($element, $command, $value) {
-        if ($element == "Main" || in_array($element, $this->registered_elements)) {
-            return $this->elements[$element]->executeCommand($command, $value);
-        }
-    }
-
-    /**
-    *
-    */
-    function checkRangeId ($range_id) {
-        if ($range_id == 'studip') {
-            return in_array('studip', $GLOBALS['EXTERN_MODULE_TYPES'][$this->type]['view']);
-        }
-
-        return in_array(get_object_type($range_id), $GLOBALS['EXTERN_MODULE_TYPES'][$this->type]['view']);
-    }
-
-    public static function printError ()
-    {
-        page_close();
-        exit;
-    }
-
-    /**
-    *
-    */
-    function getModuleLink ($module_name, $config_id, $sri_link) {
-        if ($this->config->global_id) {
-            $global_param = "global_id=" . $this->config->global_id;
-        } else {
-            $global_param = '';
-        }
-        if ($this->config->config["Main"]["incdata"]) {
-            if (mb_strrpos($sri_link, '?')) {
-                $link = $sri_link . ($global_param != '' ? '&' : '') . $global_param;
-            } else {
-                $link = $sri_link . ($global_param != '' ? '?' : '') . $global_param;
-            }
-        } else {
-            $global_param = $global_param != '' ? $global_param . '&' : '';
-            if ($sri_link) {
-                $link = $GLOBALS['EXTERN_SERVER_NAME'] . "extern.php?{$global_param}page_url=$sri_link";
-            } else {
-                $link = $GLOBALS['EXTERN_SERVER_NAME'] . "extern.php?{$global_param}module=$module_name";
-                if ($config_id) {
-                    $link .= "&config_id=$config_id";
-                }
-                $link .= "&range_id={$this->config->range_id}";
-            }
-        }
-
-        return $link;
-    }
-
-    /**
-    *
-    */
-    function setup () {}
-
-    function updateGenericDatafields ($element_name, $object_type) {
-        $datafields_config = $this->config->getValue($element_name, 'genericdatafields');
-        if (!is_array($datafields_config)) {
-            $datafields_config = [];
-        }
-        $datafields = get_generic_datafields($object_type);
-        if (!empty($datafields['ids'])) {
-            foreach ((array) $datafields['ids'] as $df) {
-                if (!in_array($df, $datafields_config)) {
-                    $datafields_config[] = $df;
-                }
-            }
-        }
-        $this->config->setValue($element_name, 'genericdatafields', $datafields_config);
-        $this->config->store();
-    }
-
-    function insertDatafieldMarkers ($object_type, &$markers, $element_name) {
-        $datafields_config = $this->config->getValue($element_name, 'genericdatafields');
-        if (!is_array($datafields_config)) {
-            $datafields_config = [];
-        }
-        /*
-        $datafields_obj = new DataFields();
-        $datafields = $datafields_obj->getFields($object_type);
-        $i = 1;
-        foreach ((array) $datafields_config as $df_id) {
-            if (isset($datafields[$df_id])) {
-                $markers[$element_name][] = array("###DATAFIELD_$i###", $datafields[$df_id]['name']);
-            }
-            $i++;
-        }
-        */
-        $datafields = get_generic_datafields($object_type);
-        $i = 1;
-        foreach ((array) $datafields_config as $df_id) {
-            if (isset($datafields['ids_names'][$df_id])) {
-                $markers[$element_name][] = ["###DATAFIELD_$i###", $datafields['ids_names'][$df_id]];
-            }
-            $i++;
-        }
-    }
-
-    function insertPluginMarkers ($plugin_type, &$markers, $element_name) {
-        $plugin_manager = PluginManager::getInstance();
-
-        foreach ($plugin_manager->getPluginInfos($plugin_type) as $plugin) {
-            $keyname = 'PLUGIN_' . mb_strtoupper($plugin['name']);
-            $markers[$element_name][] = ["###$keyname###", $plugin['description']];
-        }
-    }
-
-    public static function SetRawOutput ($raw = TRUE) {
-        self::$is_raw_output = $raw;
-    }
-
-    public static function ExtHtmlReady ($text, $allow_links = FALSE) {
-        if (self::$is_raw_output) {
-            return $text;
-        }
-        return $allow_links ? formatLinks($text) : htmlReady($text);
-    }
-
-    public static function ExtFormatReady ($text) {
-        if (self::$is_raw_output) {
-            return $text;
-        }
-        return Studip\Markup::apply(new StudipFormat(), $text, true);
-    }
-
-    public static function ExtWikiReady ($text, $show_comments = 'all') {
-        if (self::$is_raw_output) {
-            return $text;
-        }
-        return wikiReady($text, TRUE, TRUE, $show_comments);
-    }
-
-    public static function GetOrderedModuleTypes () {
-        $order = [];
-        foreach ($GLOBALS['EXTERN_MODULE_TYPES'] as $key => $module) {
-            $order[$GLOBALS['EXTERN_MODULE_TYPES'][$key]['order']] = $key;
-        }
-        ksort($order, SORT_NUMERIC);
-        return $order;
-    }
-
-    function getLinkToModule ($linked_element_name = null, $params = null, $with_module_params = false, $self = false) {
-        if ($with_module_params) {
-            $module_params = $this->getModuleParams();
-            $params = array_merge($module_params, $params);
-        }
-        $query_parts = [];
-        if (is_array($params)) {
-            $param_key = 'ext_' . strtolower($this->name);
-            foreach ($params as $name => $value) {
-                $query_parts[] = "{$param_key}[{$name}]=" . urlencode($value);
-            }
-        }
-
-        if (is_null($linked_element_name)) {
-            $sriurl = trim($this->config->getValue('Main', 'sriurl'));
-            $includeurl = trim($this->config->getValue('Main', 'includeurl'));
-        } else {
-            $sriurl = trim($this->config->getValue($linked_element_name, 'srilink'));
-            $includeurl = trim($this->config->getValue($linked_element_name, 'includlink'));
-        }
-
-        if ($sriurl) {
-            $url = $sriurl;
-        } else if ($includeurl) {
-            $url = $includeurl;
-        } else {
-            $url = $GLOBALS['EXTERN_SERVER_NAME'] . 'extern.php';
-        }
-
-        if (parse_url($url, PHP_URL_QUERY)) {
-            $url .= '&';
-        } else {
-            $url .= '?';
-        }
-
-        if ($self) {
-            $module = $this->name;
-        } else {
-            // get module name by config id
-            $linked_element_id = $this->config->getValue($linked_element_name, 'config');
-            // linked with module declared as standard?
-            if ($linked_element_id) {
-                $config_meta_data = ExternConfig::GetConfigurationMetaData($this->config->range_id, $linked_element_id);
-            } else {
-                $config_meta_data = ['module_name' => $this->config->module_name];
-            }
-            if (is_array($config_meta_data)) {
-                $module = $config_meta_data['module_name'];
-            } else {
-                return '';
-            }
-        }
-
-        $url .= "module={$module}&config_id=" . (is_null($linked_element_name) ? $this->config->getId() : $this->config->getValue($linked_element_name, 'config')) . "&range_id={$this->config->range_id}";
-        if (is_array($query_parts) && count($query_parts)) {
-            $url .= '&' . implode('&', $query_parts);
-        }
-        return self::ExtHtmlReady($url);
-    }
-
-    function getLinkToSelf ($params = null, $with_module_params = false, $linked_element_name = null) {
-        return $this->getLinkToModule($linked_element_name, $params, $with_module_params, true);
-    }
-
-    function getModuleParams ($params = null) {
-        $param_key = 'ext_' . strtolower($this->name);
-        if (is_array($_REQUEST[$param_key])) {
-            $ret = [];
-            if (is_null($params)) {
-                return $_REQUEST[$param_key];
-            }
-            foreach ($params as $param) {
-                if (isset($_REQUEST[$param_key][$param])) {
-                    $ret[$param] = $_REQUEST[$param_key][$param];
-                }
-            }
-            return $ret;
-        }
-        return [];
-    }
-
-    /**
-     * Checks access for a module in a given view.of the admin area.
-     *
-     * @param string $view view in the admin area ('extern_inst' or 'extern_global')
-     * @param int $module_id (optional) ID of the module (see extern_config.inc.php)
-     * @param string $module_name (optional) name of the module (see extern_config.inc.php)
-     * @return bool access granted
-     */
-    public static function HaveAccessModuleType ($view, $module_id = NULL, $module_name = NULL) {
-        if (!is_null($module_id)) {
-            if (!is_array($GLOBALS['EXTERN_MODULE_TYPES'][$module_id])) {
-                return false;
-            }
-            switch ($view) {
-                case 'extern_inst' :
-                    return (in_array('inst', $GLOBALS['EXTERN_MODULE_TYPES'][$module_id]['view']) || in_array('fak', $GLOBALS['EXTERN_MODULE_TYPES'][$module_id]['view']));
-                case 'extern_global' :
-                    return in_array('studip', $GLOBALS['EXTERN_MODULE_TYPES'][$module_id]['view']);
-                default :
-                    return false;
-            }
-        } else if (!is_null($module_name)) {
-            foreach ($GLOBALS['EXTERN_MODULE_TYPES'] as $id => $module) {
-                if ($module_id == $id || $module_name == $module['module']) {
-                    switch ($view) {
-                        case 'extern_inst' :
-                            return (in_array('inst', $module['view']) || in_array('fak', $module['view']));
-                        case 'extern_global' :
-                            return in_array('studip', $module['view']);
-                        default :
-                            return false;
-                    }
-                }
-            }
-        }
-        return false;
-    }
-}
diff --git a/lib/extern/lib/extern_functions.inc.php b/lib/extern/lib/extern_functions.inc.php
deleted file mode 100644
index 150ccac95f9..00000000000
--- a/lib/extern/lib/extern_functions.inc.php
+++ /dev/null
@@ -1,362 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: test
-# Lifter010: TODO
-/**
-* extern_functions.inc.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       extern_functions
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// extern_functions.inc.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/statusgruppe.inc.php';
-
-/**
-* Returns all statusgruppen for the given range.
-*
-* If there is no statusgruppe for the given range, it returns FALSE.
-*
-* @access   public
-* @param    string  $range_id
-* @return   array|bool  (structure statusgruppe_id => name)
-*/
-function get_all_statusgruppen ($range_id) {
-    $ret = [];
-    $roles = getFlattenedRoles(getAllStatusgruppen($range_id));
-
-    foreach ($roles as $id => $role) {
-        $ret[$id] = $role['name_long'];
-    }
-    return count($ret) ? $ret : false;
-}
-
-/**
-* Returns an array containing the ids as key and the name as value
-* for every given name of statusgruppe.
-*
-* If there is no known statusgruppe in the given range and name,
-* it returns FALSE.
-*
-* @access   public
-* @param    string  $range_id
-* @param    array  $ids statusgruppe_id for
-* statusgruppe valid for the given range
-*
-* @return   array|bool       (structure statusgruppe_id => name)
-*/
-function get_statusgruppen_by_id ($range_id, $ids) {
-    $ret = [];
-    $groups = get_all_statusgruppen($range_id);
-    if (is_array($ids)) {
-        foreach ($ids as $id) {
-            if (isset($groups[$id])) {
-                $ret[$id] = $groups[$id];
-            }
-        }
-    }
-    return count($ret) ? $ret : false;
-}
-
-function print_footer () {
-    echo "\n</td></tr></table>";
-    echo "\n</td></tr>\n<tr><td class=\"blank\" colspan=\"2\" width=\"100%\">&nbsp;";
-    echo "</td></tr>\n</table>\n</body>\n</html>";
-    page_close();
-}
-
-function mila_extern ($string, $length) {
-    if ($length > 0 && mb_strlen($string) > $length)
-        $string = mb_substr($string, 0, $length) . "... ";
-
-    return $string;
-}
-
-function get_start_item_id ($object_id) {
-
-    $query = "SELECT item_id FROM range_tree WHERE studip_object_id=?";
-    $parameters = [$object_id];
-    $statement = DBManager::get()->prepare($query);
-    $statement->execute($parameters);
-    $row = $statement->fetchColumn();
-    if ($row) {
-       return $row;
-    }
-    return FALSE;
-}
-
-function get_generic_datafields ($object_type) {
-//  $datafields_obj = new DataFields();
-    $fieldStructs = DataField::getDataFields($object_type);
-//  $generic_datafields = $datafields_obj->getFields($object_type);
-
-    if (is_array($fieldStructs) && count($fieldStructs)) {
-        foreach ($fieldStructs as $struct) {
-            $datafields["ids"][] = $struct->getID();
-            $datafields["names"][] = $struct->getName();
-            $datafields["ids_names"][$struct->getID()] = $struct->getName();
-        }
-
-        return $datafields;
-    }
-
-    return false;
-}
-
-function array_condense ($array) {
-    foreach ($array as $value)
-        $array_ret[] = $value;
-
-    return $array_ret;
-}
-
-function update_generic_datafields (&$config, &$data_fields, &$field_names, $object_type) {
-    // setup the generic data fields if they exist or if there are any changes
-    if ($generic_datafields = get_generic_datafields($object_type)) {
-        $config_datafields = $config->getValue("Main", "genericdatafields");
-        if (!is_array($config_datafields))
-            $config_datafields = [];
-
-        $visible = (array) $config->getValue("Main", "visible");
-        $order = (array) $config->getValue("Main", "order");
-        $aliases = (array) $config->getValue("Main", "aliases");
-        $store = false;
-
-        // data fields deleted
-        if ($diff_generic_datafields = array_diff($config_datafields,
-                $generic_datafields["ids"])) {
-            $swapped_datafields = array_flip($config_datafields);
-            $swapped_order = array_flip($order);
-            $offset = count($data_fields) - count($config_datafields);
-            $deleted = [];
-            foreach ($diff_generic_datafields as $datafield) {
-                $deleted[] = $offset + $swapped_datafields[$datafield];
-                unset($visible[$offset + $swapped_datafields[$datafield]]);
-                unset($swapped_order[$offset + $swapped_datafields[$datafield]]);
-                unset($aliases[$offset + $swapped_datafields[$datafield]]);
-            }
-            $visible = array_condense($visible);
-            $order = array_condense(array_flip($swapped_order));
-            $aliases = array_condense($aliases);
-
-            $config_generic_datafields = array_diff($config_datafields,
-                    $diff_generic_datafields);
-            for ($i = 0; $i < count($order); $i++) {
-                foreach ($deleted as $position) {
-                    if ($order[$i] >= $position)
-                        $order[$i]--;
-                }
-            }
-            $store = TRUE;
-        }
-
-        if (!$config_generic_datafields)
-            $config_generic_datafields = $config_datafields;
-        // data fields added
-        if ($diff_generic_datafields = array_diff($generic_datafields["ids"],
-                $config_generic_datafields)) {
-            $config_generic_datafields = array_merge((array)$config_generic_datafields,
-                    (array)$diff_generic_datafields);
-            foreach ($diff_generic_datafields as $datafield) {
-                $visible[] = "0";
-                $order[] = count($order);
-                $aliases[] = $generic_datafields["ids_names"][$datafield];
-            }
-            $store = TRUE;
-        }
-
-        if ($store) {
-            $config->setValue("Main", "visible", $visible);
-            $config->setValue("Main", "order", $order);
-            $config->setValue("Main", "aliases", $aliases);
-            $config->setValue("Main", "genericdatafields", $config_generic_datafields);
-            $config->store();
-        }
-
-        $config_generic_datafields = $config->getValue("Main", "genericdatafields");
-        foreach ($config_generic_datafields as $datafield) {
-            $field_names[] = $generic_datafields["ids_names"][$datafield];
-        }
-
-        if ($store)
-            return TRUE;
-
-        return FALSE;
-    }
-
-    return FALSE;
-}
-
-function get_default_generic_datafields (&$default_config, $object_type) {
-    // extend $default_config if generic data fields exist
-    if ($generic_datafields = get_generic_datafields($object_type)) {
-        foreach ($generic_datafields["ids"] as $datafield) {
-            $default_config["genericdatafields"] .= "|" . $datafield;
-            $default_config["visible"] .= "|0";
-            $default_config["order"] .= "|" . mb_substr_count($default_config["order"], "|");
-            $default_config["aliases"] .= "|" . $generic_datafields["ids_names"][$datafield];
-        }
-
-        return TRUE;
-    }
-
-    return FALSE;
-}
-
-function enable_sri ($i_id, $enable) {
-
-    if ($enable) {
-        $query = "UPDATE Institute SET srienabled = 1 WHERE Institut_id = ?";
-    } else {
-        $query = "UPDATE Institute SET srienabled = 0 WHERE Institut_id = ?";
-    }
-     $statement = DBManager::get()->prepare($query);
-     $statement->execute([ $i_id ]);
-
-}
-
-function sri_is_enabled ($i_id) {
-    if (Config::get()->EXTERN_SRI_ENABLE) {
-        if (!Config::get()->EXTERN_SRI_ENABLE_BY_ROOT) {
-            return 1;
-        }
-        $query = "SELECT srienabled FROM Institute WHERE Institut_id = ? AND srienabled = 1";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([ $i_id ]);
-        $row = $statement->fetchColumn();
-        if ($row) {
-            return 1;
-        }
-
-    }
-    return 0;
-}
-
-/*
- * Download an external configuration.
- *
- * @param string $range_id the range_id
- * @param string $config_id the id of the config to download
- * @param string $module the config-type
- */
-function download_config($range_id, $config_id, $module) {
-    $extern = new ExternConfigDb($range_id, '',$config_id);
-
-    // check, if we have an external configuration with the given ids
-    $stmt = DBManager::get()->prepare("SELECT COUNT(*) as c FROM extern_config 
-        WHERE config_id = ? AND range_id = ?");
-    $stmt->execute([$config_id, $range_id]);
-    $result = $stmt->fetch(PDO::FETCH_ASSOC);
-
-    // show download-content
-    if ($result['c'] == 1) {
-        header("Content-Type: text/plain");
-        header("Content-Disposition: attachment; " . encode_header_parameter('filename', $config_id . '.cfg'));
-        $extern->parse();
-        $extern->config['config_type'] = $module;
-
-        // create json, working only with utf8-encoded data
-        $extern_attributes = json_encode($extern->config);
-
-        echo indentJson($extern_attributes);
-
-    }
-
-    return TRUE;
-}
-
-/*
- * Store an (uploaded) external configuration.
- *
- * @param string $range_id the range_id
- * @param string $config_id the id of the config to overwrite
- * @param string $jsonconfig the json-ified configuration
- *
- * @return boolean returns true on success, false otherwise
- */
-function store_config($range_id, $config_id, $jsonconfig)
-{
-    $extern = new ExternConfigDb($range_id, '', $config_id);
-    $extern->config = $jsonconfig;
-    return ($extern->store()) ? true : false;
-}
-
-/*
- * Some checks trying to validate someone is uploadin the correct type of config.
- *
- * @param string $data the content of the new (uploaded) config
- * @param string $type the type it should have
- *
- * @return boolean true if the types match
- */
-function check_config($data, $type) {
-    if ($data['config_type'] == $type) {
-        return true;
-    } else {
-        return false;
-    }
-}
-
-/*
- * Create correct indention for json-string.
- *
- * @param string $str the json to indent
- *
- * @return string teh indented json
- */
-function indentJson($str) {
-    $strOut = '';
-    $identPos = 0;
-    for($loop = 0;$loop<= mb_strlen($str) ;$loop++){
-        $_char = mb_substr($str,$loop,1);
-        //part 1
-        if($_char == '}' || $_char == ']'){
-            $strOut .= "\n";
-            $identPos --;
-            for($ident = 0;$ident < $identPos;$ident++){
-                $strOut .= "\t";
-            }
-        }
-        //part 2
-        $strOut .= $_char;
-        //part 3
-        if($_char == ',' || $_char == '{' || $_char == '['){
-            $strOut .= "\n";
-            if($_char == '{' || $_char == '[')
-                $identPos ++;
-            for($ident = 0;$ident < $identPos;$ident++){
-                $strOut .= "\t";
-            }
-        }
-    }
-    return $strOut;
-}
-
diff --git a/lib/extern/modules/ExternModuleDownload.class.php b/lib/extern/modules/ExternModuleDownload.class.php
deleted file mode 100644
index 5a311187546..00000000000
--- a/lib/extern/modules/ExternModuleDownload.class.php
+++ /dev/null
@@ -1,343 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleDownload.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleDownload
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleDownload.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/statusgruppe.inc.php';
-
-
-class ExternModuleDownload extends ExternModule {
-
-    var $field_names = [];
-    var $data_fields = ["icon", "filename", "description", "mkdate",
-                             "filesize", "fullname"];
-    var $registered_elements = ["Body", "TableHeader", "TableHeadrow",
-                                                                     "TableRow", "Link", "LinkIntern", "TableFooter"];
-    var $args = ['seminar_id'];
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->field_names =
-        [
-                _("Icon"),
-                _("Dateiname"),
-                _("Beschreibung"),
-                _("Datum"),
-                _("Größe"),
-                _("Upload durch")
-        ];
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    function setup () {
-        $this->elements["LinkIntern"]->link_module_type = 2;
-        $this->elements["LinkIntern"]->real_name = _("Link zum Modul MitarbeiterInnendetails");
-        $this->elements["Link"]->real_name = _("Link zum Dateidownload");
-    }
-
-    function printout ($args) {
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->toString($args);
-
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-
-    function printoutPreview () {
-        echo html_header($this->config);
-
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->toStringPreview();
-
-        echo html_footer();
-    }
-
-    function toString ($args = NULL) {
-
-        $error_message = "";
-
-        // check for valid range_id
-        if(!$this->checkRangeId($this->config->range_id)) {
-            $error_message = $GLOBALS["EXTERN_ERROR_MESSAGE"];
-        }
-        // if $args['seminar_id'] is given, check for free access
-        if ($args['seminar_id']) {
-            $seminar_id = $args['seminar_id'];
-            $query = "SELECT Lesezugriff FROM seminare s LEFT JOIN seminar_inst si ";
-            $query .= "USING(seminar_id) WHERE s.seminar_id = ? ";
-            $query .= "AND si.institut_id = ?";
-
-            $parameters = [$seminar_id, $this->config->range_id];
-            $statement = DBManager::get()->prepare($query);
-            $statement->execute($parameters);
-            $row = $statement->fetch(PDO::FETCH_ASSOC);
-
-            if ($row === false && $row['Lesezugriff'] == 0)
-                $error_message = $GLOBALS["EXTERN_ERROR_MESSAGE"];
-        } else {
-            $seminar_id = $this->config->range_id;
-        }
-
-        $sort = $this->config->getValue("Main", "sort");
-        $query_order = [];
-        foreach ($sort as $key => $position) {
-            if ($position > 0) {
-                $query_order[$position] = $this->data_fields[$key];
-            }
-        }
-        if (count($query_order)) {
-            ksort($query_order, SORT_NUMERIC);
-            $query_order = implode(",", $query_order) . " DESC";
-        } else {
-            $query_order = '';
-        }
-
-        if (!$nameformat = $this->config->getValue("Main", "nameformat")) {
-            $nameformat = "no_title_short";
-        }
-
-        $downloadable_file_refs = [];
-
-        $top_folder = Folder::findTopFolder($seminar_id);
-        $top_folder = $top_folder->getTypedFolder();
-
-        $files = $folders = [];
-        extract(FileManager::getFolderFilesRecursive($top_folder, 'nobody'));
-
-        foreach ($files as $f) {
-            if ($folders[$f->folder_id]->isFileDownloadable($f, 'nobody')) {
-                $file_data = $f->toArray();
-                $file_data['fullname'] = $f->owner->getFullname($nameformat);
-                $file_data['username'] = $f->owner->username;
-                $file_data['filename'] = $f->name;
-                $file_data['filesize'] = $f->size;
-                $downloadable_file_refs[] = $file_data;
-            }
-        }
-
-        if (empty($downloadable_file_refs)) {
-            $error_message = $this->config->getValue("Main", "nodatatext");
-        }
-
-        $out = $this->elements["TableHeadrow"]->toString();
-
-        if ($error_message) {
-            // use one column and set it visible to display error_message
-            $this->config->setValue('Main', 'order', ['0']);
-            $this->config->setValue('Main', 'visible', ['1']);
-            $this->config->setValue('Main', 'width', ['100%']);
-            $out = $this->elements['TableRow']->toString(['content' => ['' => $error_message]]);
-        } else {
-
-            $table_row_data["data_fields"] = $this->data_fields;
-            $downloadable_file_refs = new SimpleCollection($downloadable_file_refs);
-            $downloadable_file_refs->orderBy($query_order);
-            foreach ($downloadable_file_refs as $downloadable_file_ref) {
-                $icon = Icon::create(FileManager::getIconNameForMimeType($downloadable_file_ref->mime_type), 'clickable');
-
-                $download_link = $downloadable_file_ref->download_url;
-
-                // Aufbereiten der Daten
-                $table_row_data["content"] = [
-                    "icon"        => sprintf("<a href=\"%s\">%s</a>",
-                                             $download_link,
-                                             $icon->asImg()),
-
-                    "filename"    => $this->elements["Link"]->toString(["content" =>
-                                                        htmlReady($downloadable_file_ref->name), "link" => $download_link]),
-
-                    "description" => htmlReady(mila_extern($downloadable_file_ref->description,
-                                                     $this->config->getValue("Main", "lengthdesc"))),
-
-                    "mkdate"      => strftime($this->config->getValue("Main", "dateformat"), $downloadable_file_ref->mkdate),
-
-                    "filesize"    => $downloadable_file_ref->size > 1048576 ? round($downloadable_file_ref->size / 1048576, 1) . " MB"
-                        : round($downloadable_file_ref->size / 1024, 1) . " kB",
-
-                ];
-                // if user is member of a group then link name to details page
-                if (GetRoleNames(GetAllStatusgruppen($this->config->range_id, $downloadable_file_ref['user_id']))) {
-                    $table_row_data['content']['fullname'] =
-                            $this->elements['LinkIntern']->toString(['content' =>
-                            htmlReady($downloadable_file_ref->fullname), 'module' => 'Persondetails',
-                            'link_args' => 'username=' . $downloadable_file_ref->username]);
-                } else {
-                    $table_row_data['content']['fullname'] = htmlReady($downloadable_file_ref->fullname);
-                }
-                $out .= $this->elements["TableRow"]->toString($table_row_data);
-            }
-        }
-
-        return $this->elements["TableHeader"]->toString(["content" => $out]);
-    }
-
-    function toStringPreview () {
-        $time = time();
-        // preview data
-        $data[] = ["dokument_id" => 1, "description" => _("Das ist eine Text-Datei."),
-            "filename" => "text_file.txt", "mkdate" => ($time - 100000), "chdate" => ($time - 50000),
-            "filesize" => 26378, "Vorname" => "Julius", "Nachname" => "Rodman"];
-        $data[] = ["dokument_id" => 2, "description" => _("Das ist eine Powerpoint-Datei."),
-            "filename" => "powerpoint_file.ppt", "mkdate" => ($time - 200000), "chdate" => ($time - 150000),
-            "filesize" => 263784, "Vorname" => "William", "Nachname" => "Wilson"];
-        $data[] = ["dokument_id" => 3, "description" => _("Das ist eine ZIP-Datei."),
-            "filename" => "zip_file.zip", "mkdate" => ($time - 300000), "chdate" => ($time - 250000),
-            "filesize" => 63784, "Vorname" => "August", "Nachname" => "Bedloe"];
-        $data[] = ["dokument_id" => 4, "description" => _("Das ist eine Excel-Datei."),
-            "filename" => "excel_file.txt", "mkdate" => ($time - 400000), "chdate" => ($time - 350000),
-            "filesize" => 23784, "Vorname" => "Ernst", "Nachname" => "Waldemar"];
-        $data[] = ["dokument_id" => 5, "description" => _("Das ist eine Bild-Datei."),
-            "filename" => "bild_jpeg_file.jpg", "mkdate" => ($time - 500000), "chdate" => ($time - 450000),
-            "filesize" => 53784, "Vorname" => "Absalom", "Nachname" => "Hicks"];
-        $data[] = ["dokument_id" => 6, "description" => _("Das ist ein Dokument im Microsoft Rich-Text-Format."),
-            "filename" => "microsoft_rtf_file.rtf", "mkdate" => ($time - 600000), "chdate" => ($time - 550000),
-            "filesize" => 563784, "Vorname" => "Dirk", "Nachname" => "Peters"];
-        $data[] = ["dokument_id" => 7, "description" => _("Das ist ein Adobe PDF-Dokument."),
-            "filename" => "adobe_pdf_file.pdf", "mkdate" => ($time - 700000), "chdate" => ($time - 650000),
-            "filesize" => 13784, "Vorname" => "Augustus", "Nachname" => "Barnard"];
-        $data[] = ["dokument_id" => 8, "description" => _("Und noch ein ZIP-Archiv."),
-            "filename" => "gnu_zip_file.tar.gz", "mkdate" => ($time - 800000), "chdate" => ($time - 750000),
-            "filesize" => 2684, "Vorname" => "Gordon", "Nachname" => "Pym"];
-        $data[] = ["dokument_id" => 9, "description" => _("Eine weitere Text-Datei."),
-            "filename" => "text2_file.txt", "mkdate" => ($time - 900000), "chdate" => ($time - 850000),
-            "filesize" => 123784, "Vorname" => "Hans", "Nachname" => "Pfaal"];
-        $data[] = ["dokument_id" => 10, "description" => _("Ein Bild im PNG-Format."),
-            "filename" => "picture_png_file.png", "mkdate" => ($time - 1000000), "chdate" => ($time - 950000),
-            "filesize" => 813784, "Vorname" => "John", "Nachname" => "Greely"];
-        $data[] = ["dokument_id" => 11, "description" => _("Eine anderes Format."),
-            "filename" => "good_music.mp3", "mkdate" => ($time - 1150000), "chdate" => ($time - 653900),
-            "filesize" => 934651, "Vorname" => "Augustus", "Nachname" => "Barnard"];
-
-        $table_row_data["data_fields"] = $this->data_fields;
-        $out = $this->elements["TableHeadrow"]->toString();
-
-        foreach ($data as $db) {
-
-            preg_match("/^.+\.([a-z1-9_-]+)$/i", $db["filename"], $file_suffix);
-
-            // choose the icon for the given file format
-            $icon = "";
-            switch ($file_suffix[1]) {
-                case "txt" :
-                    if (!$picture_file = $this->config->getValue("Main", "icontxt"))
-                        $icon = Icon::create("file-text", "clickable");
-                    break;
-                case "xls" :
-                    if (!$picture_file = $this->config->getValue("Main", "iconxls"))
-                        $icon = Icon::create("file-xls", "clickable");
-                    break;
-                case "ppt" :
-                    if (!$picture_file = $this->config->getValue("Main", "iconppt"))
-                        $icon = Icon::create("file-presentation", "clickable");
-                    break;
-                case "rtf" :
-                    if (!$picture_file = $this->config->getValue("Main", "iconrtf"))
-                        $icon = Icon::create("file-text", "clickable");
-                    break;
-                case "zip" :
-                case "tgz" :
-                case "gz" :
-                    if (!$picture_file = $this->config->getValue("Main", "iconzip"))
-                        $icon = Icon::create("file-archive", "clickable");
-                    break;
-                case "jpg" :
-                case "png" :
-                case "gif" :
-                case "jpeg" :
-                case "tif" :
-                    if (!$picture_file = $this->config->getValue("Main", "iconpic"))
-                        $icon = Icon::create("file-image", "clickable");
-                    break;
-                case "pdf" :
-                    if (!$picture_file = $this->config->getValue("Main", "iconpdf"))
-                        $icon = Icon::create("file-pdf", "clickable");
-                    break;
-                default :
-                    if (!$picture_file = $this->config->getValue("Main", "icondefault"))
-                        $icon = Icon::create("file-generic", "clickable");
-            }
-
-            if ($icon)
-                $picture_file = $icon;
-
-            // Aufbereiten der Daten
-            $table_row_data["content"] = [
-                "icon"        => $this->elements["Link"]->toString(
-                    [
-                        "content" => is_string($picture_file)
-                                     ? Assets::img($picture_file)
-                                     : $picture_file->asImg(),
-                        "link"    => ""]),
-
-                "filename"    => $this->elements["Link"]->toString(["content" =>
-                                                    htmlReady($db["filename"]), "link" => ""]),
-
-                "description" => htmlReady(mila_extern($db["description"],
-                                                    $this->config->getValue("Main", "lengthdesc"))),
-
-                "mkdate"      => strftime($this->config->getValue("Main", "dateformat"), $db["mkdate"]),
-
-                "filesize"    => $db["filesize"] > 1048576 ? round($db["filesize"] / 1048576, 1) . " MB"
-                                                    : round($db["filesize"] / 1024, 1) . " kB",
-
-                "fullname"    => $this->elements["LinkIntern"]->toString(
-                                                    ["content" => htmlReady($db["Vorname"]." ".$db["Nachname"])])
-
-            ];
-            $out .= $this->elements["TableRow"]->toString($table_row_data);
-        }
-
-        return $this->elements["TableHeader"]->toString(["content" => $out]);
-    }
-
-
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleGlobal.class.php b/lib/extern/modules/ExternModuleGlobal.class.php
deleted file mode 100644
index bded6e824a4..00000000000
--- a/lib/extern/modules/ExternModuleGlobal.class.php
+++ /dev/null
@@ -1,226 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleGlobal.class.php
-* 
-* 
-* 
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleGlobal
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModulePersons.class.php
-// 
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-
-class ExternModuleGlobal extends ExternModule {
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->registered_elements = 
-            [
-                'PageBodyGlobal' => 'Body',
-                'MainTableHeaderGlobal' => 'TableHeader',
-                'InnerTableHeaderGlobal' => 'TableHeader',
-                'MainTableHeadrowGlobal' => 'TableHeadrow',
-                'TableGrouprowGlobal' => 'TableGroup',
-                'TableRowGlobal' => 'TableRow',
-                'TableHeadrowTextGlobal' => 'Link',
-                'Headline1TextGlobal' => 'Link',
-                'Headline2TextGlobal' => 'Link',
-                'TextGlobal' => 'Link',
-                'LinksGlobal' => 'Link'
-            ];
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-    
-    /**
-    *
-    */
-    function setup () {
-        $this->elements["PageBodyGlobal"]->real_name = _("Seitenkörper");
-        $this->elements["MainTableHeaderGlobal"]->real_name = _("Tabellenkopf Gesamttabelle");
-        $this->elements["InnerTableHeaderGlobal"]->real_name = _("Tabellenkopf innere Tabelle");
-        $this->elements["MainTableHeadrowGlobal"]->real_name = _("Kopfzeile");
-        $this->elements["TableGrouprowGlobal"]->real_name = _("Gruppenzeile");
-        $this->elements["TableRowGlobal"]->real_name = _("Datenzeile");
-        $this->elements["TableHeadrowTextGlobal"]->real_name = _("Text in Tabellenkopf");
-        $this->elements["Headline1TextGlobal"]->real_name = _("Ãœberschriften erster Ordnung");
-        $this->elements["Headline2TextGlobal"]->real_name = _("Ãœberschriften zweiter Ordnung");
-        $this->elements["TextGlobal"]->real_name = _("Schrift");
-        $this->elements["LinksGlobal"]->real_name = _("Links");
-        
-        $this->elements["MainTableHeadrowGlobal"]->attributes = ["tr_class", "tr_style",
-                "th_height", "th_align", "th_valign", "th_bgcolor", "th_bgcolor2_",
-                "th_zebrath_", "th_class", "th_style"];
-        $this->elements["TableGrouprowGlobal"]->attributes = ["tr_class", "tr_style",
-                "td_height", "td_align", "td_valign", "td_bgcolor", "td_bgcolor_2", "td_class",
-                "td_style"];
-        $this->elements["TableRowGlobal"]->attributes = ["tr_class", "tr_style",
-                "td_height", "td_align", "td_valign", "td_bgcolor", "td_bgcolor2_",
-                "td_zebratd_", "td_class", "td_style"];
-        $this->elements["TableHeadrowTextGlobal"]->attributes = ["font_size", "font_face",
-                "font_color", "font_class", "font_style"];
-        $this->elements["Headline1TextGlobal"]->attributes = ["font_size", "font_face",
-                "font_color", "font_class", "font_style"];
-        $this->elements["Headline2TextGlobal"]->attributes = ["font_size", "font_face",
-                "font_color", "font_class", "font_style"];
-        $this->elements["TextGlobal"]->attributes = ["font_size", "font_face",
-                "font_color", "font_class", "font_style"];
-        
-    }
-    
-    /**
-    *
-    */
-    function store ($element_name = '', $values = '') {
-        $this->config->restore($this, $element_name, $values);
-        $this->globalConfigMapping();
-        $this->config->store();
-    }
-    
-    /**
-    *
-    */
-    function globalConfigMapping () {
-    
-        // mapping entire elements
-                
-        $elements_map["Body"][] = $this->elements["PageBodyGlobal"];
-        $elements_map["TableHeader"][] = $this->elements["MainTableHeaderGlobal"];
-        
-        $elements_map["TableHeadrow"][] = $this->elements["MainTableHeadrowGlobal"];
-        $elements_map["TableHeadrow"][] = $this->elements["TableHeadrowTextGlobal"];
-        
-        $elements_map["TableRow"][] = $this->elements["TableRowGlobal"];
-        $elements_map["TableRow"][] = $this->elements["TextGlobal"];
-        
-        $elements_map["TableGroup"][] = $this->elements["TableGrouprowGlobal"];
-        $elements_map["TableGroup"][] = $this->elements["Headline2TextGlobal"];
-        
-        $elements_map["Grouping"][] = $this->elements["TableGrouprowGlobal"];
-        $elements_map["Grouping"][] = $this->elements["Headline2TextGlobal"];
-        
-        $elements_map["Link"][] = $this->elements["LinksGlobal"];
-        $elements_map["LinkIntern"][] = $this->elements["LinksGlobal"];
-        $elements_map["LinkInternSimple"][] = $this->elements["LinksGlobal"];
-        $elements_map["LecturerLink"][] = $this->elements["LinksGlobal"];
-        
-        $elements_map["SemName"][] = $this->elements["Headline1TextGlobal"];
-        $elements_map["Headline"][] = $this->elements["Headline2TextGlobal"];
-        $elements_map["Headline"][] = $this->elements["TableGrouprowGlobal"];
-        $elements_map["Content"][] = $this->elements["TextGlobal"];
-        $elements_map["Content"][] = $this->elements["TableRowGlobal"];
-        
-        $elements_map["StudipLink"][] = $this->elements["LinksGlobal"];
-        $elements_map["SemLink"][] = $this->elements["LinksGlobal"];
-        
-        $elements_map["Contact"][] = $this->elements["InnerTableHeaderGlobal"];
-        
-        $elements_map["TableParagraph"][] = $this->elements["InnerTableHeaderGlobal"];
-        
-        $elements_map["TableParagraphHeadline"][] = $this->elements["TableGrouprowGlobal"];
-        $elements_map["TableParagraphHeadline"][] = $this->elements["Headline2TextGlobal"];
-        
-        $elements_map["TableParagraphSubHeadline"][] = $this->elements["TableRowGlobal"];
-        $elements_map["TableParagraphSubHeadline"][] = $this->elements["TableHeadrowTextGlobal"];
-        
-        $elements_map["TableParagraphText"][] = $this->elements["TableRowGlobal"];
-        $elements_map["TableParagraphText"][] = $this->elements["TextGlobal"];
-                
-        $elements_map["PersondetailsHeader"][] = $this->elements["Headline1TextGlobal"];
-        
-        foreach ($elements_map as $name => $elements) {
-            foreach ($elements as $element) {
-                foreach ($element->attributes as $attribute) {
-                    $this->config->config[$name][$attribute]
-                            = $this->config->getValue($element->name, $attribute);
-                }
-            }
-        }
-        
-        // mapping single attributes
-        
-        $this->config->config["PersondetailsHeader"]["headlinetd_align"]
-                = $this->config->getValue("MainTableHeadrowGlobal", "th_align");
-        $this->config->config["PersondetailsHeader"]["headlinetd_valign"]
-                = $this->config->getValue("MainTableHeadrowGlobal", "th_valign");
-        $this->config->config["PersondetailsHeader"]["headlinetd_bgcolor"]
-                = $this->config->getValue("MainTableHeadrowGlobal", "th_bgcolor");
-        $this->config->config["PersondetailsHeader"]["headlinetd_class"]
-                = $this->config->getValue("MainTableHeadrowGlobal", "th_class");
-        $this->config->config["PersondetailsHeader"]["headlinetd_style"]
-                = $this->config->getValue("MainTableHeadrowGlobal", "th_style");
-        
-        $this->config->config["SemName"]["td_align"]
-                = $this->config->getValue("MainTableHeadrowGlobal", "th_align");
-        $this->config->config["SemName"]["td_valign"]
-                = $this->config->getValue("MainTableHeadrowGlobal", "th_valign");
-        $this->config->config["SemName"]["td_bgcolor"]
-                = $this->config->getValue("MainTableHeadrowGlobal", "th_bgcolor");
-        $this->config->config["SemName"]["td_class"]
-                = $this->config->getValue("MainTableHeadrowGlobal", "th_class");
-        $this->config->config["SemName"]["td_style"]
-                = $this->config->getValue("MainTableHeadrowGlobal", "th_style");
-        
-        $this->config->config["Contact"]["defaultadr"]
-                = $this->config->getValue("Main", "defaultadr");
-        
-        $this->config->config["PersondetailsLectures"]["semstart"]
-                = $this->config->getValue("Main", "semstart");
-        $this->config->config["PersondetailsLectures"]["semrange"]
-                = $this->config->getValue("Main", "semrange");
-        $this->config->config["PersondetailsLectures"]["semswitch"]
-                = $this->config->getValue("Main", "semswitch");
-    }
-    
-    /**
-    *
-    */
-    function printout ($args) {
-    
-    // nothing to print
-    
-    }
-    
-    /**
-    *
-    */
-    function printoutPreview () {
-    
-    // nothing to print
-    
-    }
-    
-}
-
-?>
\ No newline at end of file
diff --git a/lib/extern/modules/ExternModuleLecturedetails.class.php b/lib/extern/modules/ExternModuleLecturedetails.class.php
deleted file mode 100644
index 379d3fec3fc..00000000000
--- a/lib/extern/modules/ExternModuleLecturedetails.class.php
+++ /dev/null
@@ -1,606 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleLecturedetails.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleLecturedetails
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleLecturedetails.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/extern/modules/views/ExternSemBrowse.class.php';
-require_once 'lib/dates.inc.php';
-
-class ExternModuleLecturedetails extends ExternModule {
-
-
-    // private
-    var $seminar_id;
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->data_fields = ['subtitle', 'lecturer', 'art', 'status', 'description',
-            'location', 'semester', 'time', 'number', 'teilnehmer', 'requirements',
-            'lernorga', 'leistung', 'range_path', 'misc', 'ects'];
-        $this->registered_elements = [
-            'ReplaceTextSemType',
-            'Body',
-            'TableHeader',
-            'SemName' => 'TableParagraphText',
-            'Headline' => 'TableParagraphText',
-            'Content' => 'TableParagraphText',
-            'LinkInternSimple' => 'LinkIntern',
-            'StudipInfo',
-            'StudipLink'];
-        $this->args = ['seminar_id'];
-        $this->field_names = [
-                _("Untertitel"),
-                _("Lehrende"),
-                _("Veranstaltungsart"),
-                _("Veranstaltungstyp"),
-                _("Beschreibung"),
-                _("Ort"),
-                _("Semester"),
-                _("Zeiten"),
-                _("Veranstaltungsnummer"),
-                _("Teilnehmende"),
-                _("Voraussetzungen"),
-                _("Lernorganisation"),
-                _("Leistungsnachweis"),
-                _("Bereichseinordnung"),
-                _("Sonstiges"),
-                _("ECTS-Punkte")];
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    function setup () {
-        // extend $data_fields if generic datafields are set
-        $config_datafields = $this->config->getValue("Main", "genericdatafields");
-        $this->data_fields = array_merge((array)$this->data_fields, (array)$config_datafields);
-
-        // setup module properties
-        $this->elements["SemName"]->real_name = _("Name der Veranstaltung");
-        $this->elements["Headline"]->real_name = _("Ãœberschriften");
-        $this->elements["Content"]->real_name = _("Absätze");
-        $this->elements["LinkInternSimple"]->link_module_type = 2;
-        $this->elements["LinkInternSimple"]->real_name = _("Link zum Modul Mitarbeiterdetails");
-    }
-
-    function printout ($args) {
-
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->toString($args);
-
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-
-    function printoutPreview () {
-
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        include "lib/extern/modules/views/lecturedetails_preview.inc.php";
-
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-
-    function toString ($args) {
-        $out = "";
-        $this->seminar_id = $args["seminar_id"];
-        $query = "SELECT * FROM seminare WHERE Seminar_id = ?";
-        $parameters = [$this->seminar_id];
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-        $row = $statement->fetch(PDO::FETCH_ASSOC);
-
-        $visible = $this->config->getValue("Main", "visible");
-        $j = -1;
-        if ($row !== false) {
-            $sem_object = Seminar::getInstance($this->seminar_id);
-
-            $data["name"] = htmlReady($sem_object->name);
-
-            if ($visible[++$j] && $row['Untertitel'])
-                $data["subtitle"] = htmlReady($sem_object->untertitel);
-
-            if ($visible[++$j]) {
-                if (!$name_sql = $this->config->getValue("Main", "nameformat"))
-                    $name_sql = "full";
-                $name_sql = $GLOBALS['_fullname_sql'][$name_sql];
-
-                $query = "SELECT $name_sql AS name, username, position FROM seminar_user su LEFT JOIN
-                        auth_user_md5 USING(user_id) LEFT JOIN user_info USING(user_id)
-                        WHERE su.Seminar_id = ? AND su.status='dozent' ORDER BY position, username";
-                $parameters = [$this->seminar_id];
-                $statement = DBManager::get()->prepare($query);
-                $statement->execute($parameters);
-                while ($res = $statement->fetch(PDO::FETCH_ASSOC)) {
-                    $data["lecturer"][] = $this->elements["LinkInternSimple"]->toString(
-                            ["module" => "Persondetails",
-                            "link_args" => "username=" . $res['username']
-                            . "&seminar_id=" . $this->seminar_id,
-                            "content" => $res['name'] ]);
-                }
-                if (is_array($data["lecturer"]))
-                    $data["lecturer"] = implode(", ", $data["lecturer"]);
-            }
-
-            if ($visible[++$j] && $row['art'])
-                $data["art"] = htmlReady($sem_object->art);
-
-            if ($visible[++$j]) {
-                // reorganize the $SEM_TYPE-array
-                foreach ($GLOBALS["SEM_CLASS"] as $key_class => $class) {
-                    $i = 0;
-                    foreach ($GLOBALS["SEM_TYPE"] as $key_type => $type) {
-                        if ($type["class"] == $key_class) {
-                            $i++;
-                            $sem_types_position[$key_type] = $i;
-                        }
-                    }
-                }
-
-                $aliases_sem_type = $this->config->getValue("ReplaceTextSemType",
-                        "class_" . $GLOBALS["SEM_TYPE"][$row['status']]['class']);
-                if ($aliases_sem_type[$sem_types_position[$row['status']] - 1])
-                    $data["status"] =  $aliases_sem_type[$sem_types_position[$row['status']] - 1];
-                else
-                    $data["status"] = htmlReady($GLOBALS["SEM_TYPE"][$row['status']]["name"]);
-            }
-
-            if ($visible[++$j] && $row['Beschreibung'])
-                $data["description"] = formatLinks($sem_object->beschreibung);
-
-            if ($visible[++$j])
-                $data["location"] = htmlReady($sem_object->getDatesTemplate('dates/seminar_export_location'));
-
-            if ($visible[++$j])
-                $data["semester"] = get_semester($this->seminar_id);
-
-            if ($visible[++$j]) {
-                $data["time"] = htmlReady($sem_object->getDatesExport());
-                if ($first_app = vorbesprechung($this->seminar_id, 'export')) {
-                    $data["time"] .= "<br>" . $this->config->getValue("Main", "aliaspredisc") . htmlReady($first_app);
-                }
-                if ($begin = $sem_object->getFirstDate('export')) {
-                    $data["time"] .= "<br>" . $this->config->getValue("Main", "aliasfirstmeeting") . htmlReady($begin);
-                }
-            }
-
-            if ($visible[++$j] && $row['VeranstaltungsNummer'])
-                $data["number"] = htmlReady($row['VeranstaltungsNummer']);
-
-            if ($visible[++$j] && $row['teilnehmer'])
-                $data["teilnehmer"] = htmlReady($sem_object->teilnehmer);
-
-            if ($visible[++$j] && $row['vorrausetzungen'])
-                $data["requirements"] = htmlReady($sem_object->vorrausetzungen);
-
-            if ($visible[++$j] && $row['lernorga'])
-                $data["lernorga"] = htmlReady($sem_object->lernorga);
-
-            if ($visible[++$j] && $row['leistungsnachweis'])
-                $data["leistung"] = htmlReady($sem_object->leistungsnachweis);
-
-            if ($visible[++$j]) {
-                $range_path_level = $this->config->getValue("Main", "rangepathlevel");
-                $pathes = get_sem_tree_path($this->seminar_id, $range_path_level);
-                if (is_array($pathes)) {
-                    $data["range_path"] = htmlReady(implode("\n", array_values($pathes)),true,true);
-                }
-            }
-
-            if ($visible[++$j] && $row['Sonstiges'])
-                $data["misc"] = formatLinks($row['Sonstiges']);
-
-            if ($visible[++$j] && $row['ects'])
-                $data["ects"] = htmlReady($row['ects']);
-
-            // generic data fields
-            if ($generic_datafields = $this->config->getValue("Main", "genericdatafields")) {
-                $localEntries = DataFieldEntry::getDataFieldEntries($this->seminar_id);
-                foreach ($generic_datafields as $id) {
-                    if ($visible[++$j] && isset($localEntries[$id]) && is_object($localEntries[$id])) {
-                        $data[$id] = $localEntries[$id]->getDisplayValue();
-                    }
-                }
-            }
-            $out = $this->toStringMainTable($data, FALSE);
-        }
-
-        return $out;
-    }
-
-    function toStringPreview ($args) {
-        // reorganize the $SEM_TYPE-array
-        foreach ($GLOBALS["SEM_CLASS"] as $key_class => $class) {
-            $i = 0;
-            foreach ($GLOBALS["SEM_TYPE"] as $key_type => $type) {
-                if ($type["class"] == $key_class) {
-                    $i++;
-                    $sem_types_position[$key_type] = $i;
-                }
-            }
-        }
-
-        $data_sem["name"] = _("Name der Veranstaltung");
-        $data_sem["subtitle"] = _("Untertitel der Veranstaltung");
-        switch ($this->config->getValue("Main", "nameformat")) {
-            case "no_title_short" :
-                $data_sem["lecturer"] = _("Meyer, P.");
-                break;
-            case "no_title" :
-                $data_sem["lecturer"] = _("Peter Meyer");
-                break;
-            case "no_title_rev" :
-                $data_sem["lecturer"] = _("Meyer Peter");
-                break;
-            case "full" :
-                $data_sem["lecturer"] = _("Dr. Peter Meyer");
-                break;
-            case "full_rev" :
-                $data_sem["lecturer"] = _("Meyer, Peter, Dr.");
-                break;
-            default :
-                $data_sem["lecturer"] = _("Dr. Peter Meyer");
-        }
-        $data_sem["art"] = _("Testveranstaltung");
-        $data_sem["semtype"] = 1;
-        $data_sem["description"] = str_repeat(_("Beschreibung") . " ", 10);
-        $data_sem["location"] = _("A 123, 1. Stock");
-        $data_sem["semester"] = "WS 2003/2004";
-        $data_sem["time"] = _("Di. 8:30 - 13:30, Mi. 8:30 - 13:30, Do. 8:30 - 13:30");
-        $data_sem["number"] = "1234";
-        $data_sem["teilnehmer"] = str_repeat(_("Teilnehmende") . " ", 6);
-        $data_sem["requirements"] = str_repeat(_("Voraussetzungen") . " ", 6);
-        $data_sem["lernorga"] = str_repeat(_("Lernorganisation") . " ", 6);
-        $data_sem["leistung"] = str_repeat(_("Leistungsnachweis") . " ", 6);
-        $data_sem["range_path"] = _("Fakultät &gt; Studiengang &gt; Bereich");
-        $data_sem["misc"] = str_repeat(_("Sonstiges") . " ", 6);
-        $data_sem["ects"] = "4";
-
-
-        setlocale(LC_TIME, $this->config->getValue("Main", "timelocale"));
-        $visible = $this->config->getValue("Main", "visible");
-        $j = -1;
-
-        $data["name"] = $data_sem["name"];
-
-        if ($visible[++$j])
-            $data["subtitle"] = $data_sem["subtitle"];
-
-        if ($visible[++$j]) {
-            $data["lecturer"][] = sprintf("<a href=\"\"%s>%s</a>",
-                    $this->config->getAttributes("LinkInternSimple", "a"),
-                    $data_sem["lecturer"]);
-            if (is_array($data["lecturer"]))
-                $data["lecturer"] = implode(", ", $data["lecturer"]);
-        }
-
-        if ($visible[++$j])
-            $data["art"] = $data_sem["art"];
-
-        if ($visible[++$j]) {
-            $aliases_sem_type = $this->config->getValue("ReplaceTextSemType",
-                    "class_{$GLOBALS['SEM_TYPE'][$data_sem['semtype']]['class']}");
-            if ($aliases_sem_type[$sem_types_position[$data_sem['semtype']] - 1])
-                $data["status"] = $aliases_sem_type[$sem_types_position[$data_sem['semtype']] - 1];
-            else {
-                $data["status"] = htmlReady($GLOBALS['SEM_TYPE'][$data_sem['semtype']]["name"]
-                        ." (". $GLOBALS['SEM_CLASS'][$GLOBALS['SEM_TYPE'][$data_sem['semtype']]["class"]]["name"].")");
-            }
-        }
-
-        if ($visible[++$j])
-            $data["description"] = $data_sem["description"];
-
-        if ($visible[++$j])
-            $data["location"] = $data_sem["location"];
-
-        if ($visible[++$j])
-            $data["semester"] = $data_sem["semester"];
-
-        if ($visible[++$j])
-            $data["time"] = $data_sem["time"];
-
-        if ($visible[++$j])
-            $data["number"] = $data_sem["number"];
-
-        if ($visible[++$j])
-            $data["teilnehmer"] = $data_sem["teilnehmer"];
-
-        if ($visible[++$j])
-            $data["requirements"] = $data_sem["requirements"];
-
-        if ($visible[++$j])
-            $data["lernorga"] = $data_sem["lernorga"];
-
-        if ($visible[++$j])
-            $data["leistung"] = $data_sem["leistung"];
-
-        if ($visible[++$j]) {
-            $pathes = [$data_sem["range_path"]];
-            if (is_array($pathes)) {
-                $pathes_values = array_values($pathes);
-                if ($this->config->getValue("Main", "range") == "long")
-                    $data["range_path"] = $pathes_values;
-                else {
-                    foreach ($pathes_values as $path) {
-                        $_paths = explode("&gt;", $path);
-                        $data["range_path"][] = array_pop($_paths);
-                    }
-                }
-                $data["range_path"] = array_filter($data["range_path"], "htmlReady");
-                $data["range_path"] = implode("<br>", $data["range_path"]);
-            }
-        }
-
-        if ($visible[++$j])
-            $data["misc"] = $data_sem["misc"];
-
-        if ($visible[++$j])
-            $data["ects"] = $data_sem["ects"];
-
-        return $this->toStringMainTable($data, TRUE);
-    }
-
-
-    private function toStringMainTable ($data, $preview)
-    {
-        $order = $this->config->getValue("Main", "order");
-        $visible = $this->config->getValue("Main", "visible");
-        $aliases = $this->config->getValue("Main", "aliases");
-
-        $out = '';
-
-        if ($this->config->getValue("Main", "studiplink")) {
-            $out .= "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"";
-            if ($studiplink_width = $this->config->getValue("TableHeader", "table_width"))
-                $out .= " width=\"$studiplink_width\"";
-            if ($studiplink_align = $this->config->getValue("TableHeader", "table_align"))
-                $out .= " align=\"$studiplink_align\">\n";
-
-            if ($preview)
-                $studip_link = "";
-            else {
-                if ($this->config->getValue("Main", "studiplinktarget") != "signin") {
-                    $studip_link = $GLOBALS['ABSOLUTE_URI_STUDIP'] . 'seminar_main.php?auswahl=';
-                    $studip_link .= $this->seminar_id;
-                    $studip_link .= "&again=1&redirect_to=dispatch.php/course/basicdata/view/".$this->seminar_id."&login=true&new_sem=TRUE";
-                }
-                else {
-                    $studip_link = $GLOBALS['ABSOLUTE_URI_STUDIP'] . 'dispatch.php/course/details/?again=1&sem_id=';
-                    $studip_link .= $this->seminar_id;
-                }
-            }
-            if ($this->config->getValue("Main", "studiplink") == "top") {
-                $args = ["width" => "100%", "height" => "40", "link" => $studip_link];
-                $out .= "<tr><td width=\"100%\">\n";
-                $out .= $this->elements["StudipLink"]->toString($args);
-                $out .= "</td></tr>";
-            }
-            $table_attr = $this->config->getAttributes("TableHeader", "table");
-            $pattern = ["/width=\"[0-9%]+\"/", "/align=\"[a-z]+\"/"];
-            $replace = ["width=\"100%\"", ""];
-            $table_attr = preg_replace($pattern, $replace, $table_attr);
-            $out .= "<tr><td width=\"100%\">\n<table$table_attr>";
-        }
-        else
-            $out .= "<table" . $this->config->getAttributes("TableHeader", "table") . ">";
-
-        $out .= $this->elements["SemName"]->toString(["content" => $data["name"]]);
-
-        if ($this->config->getValue("Main", "headlinerow")) {
-            foreach ($order as $position) {
-                if ($visible[$position] && $data[$this->data_fields[$position]]) {
-                    $out .= $this->elements["Headline"]->toString(
-                            ["content" => $aliases[$position]]);
-                    $out .= $this->elements["Content"]->toString(
-                            ["content" => $data[$this->data_fields[$position]]]);
-                }
-            }
-        }
-        else {
-            foreach ($order as $position) {
-                if ($visible[$position] && $data[$this->data_fields[$position]]) {
-                    $out .= $this->elements["Content"]->toString(["content" =>
-                            $this->config->getTag("Headline", "font") . $aliases[$position] .
-                            "</font>" . $data[$this->data_fields[$position]]]);
-                }
-            }
-        }
-
-        if ($this->config->getValue("Main", "studipinfo")) {
-            $out .= $this->elements["Headline"]->toString(["content" =>
-                    $this->config->getValue("StudipInfo", "headline")]);
-            $out .= $this->toStringStudipInfo($preview);
-        }
-
-        $out .= "</table>\n";
-
-        if ($this->config->getValue("Main", "studiplink")) {
-            if ($this->config->getValue("Main", "studiplink") == "bottom") {
-                $args = ["width" => "100%", "height" => "40", "link" => $studip_link];
-                $out .= "</td></tr>\n<tr><td width=\"100%\">\n";
-                $out .= $this->elements["StudipLink"]->toString($args);
-            }
-            $out .= "</td></tr></table>\n";
-        }
-
-        return $out;
-    }
-
-    // private
-    function toStringStudipInfo ($preview) {
-        if ($preview) {
-            $studip_info = $this->elements["StudipInfo"]->toString(["content" =>
-                    $this->config->getValue("StudipInfo", "homeinst") . "&nbsp;"]);
-            $studip_info .= sprintf("<a href=\"\"%s>%s</a><br>\n",
-                    $this->config->getAttributes("LinkInternSimple", "a"),
-                    _("Heimatinstitut"));
-
-            $studip_info .= $this->elements["StudipInfo"]->toString(["content" =>
-                    $this->config->getValue("StudipInfo", "involvedinst") . "&nbsp;"]);
-            $studip_info .= str_repeat(_("Beteiligte Institute") . " ", 5) . "<br>\n";
-
-            $studip_info .= $this->elements["StudipInfo"]->toString(["content" =>
-                    $this->config->getValue("StudipInfo", "countuser") . "&nbsp;"]);
-            $studip_info .= "23<br>\n";
-
-            $studip_info .= $this->elements["StudipInfo"]->toString(["content" =>
-                    $this->config->getValue("StudipInfo", "countpostings") . "&nbsp;"]);
-            $studip_info .= "42<br>\n";
-
-            $studip_info .= $this->elements["StudipInfo"]->toString(["content" =>
-                    $this->config->getValue("StudipInfo", "countdocuments") . "&nbsp;"]);
-            $studip_info .= "7<br>\n";
-        }
-        else {
-            $query="SELECT i.Institut_id, i.Name, i.url FROM seminare LEFT JOIN Institute i
-                                    USING(institut_id) WHERE Seminar_id = ?";
-            $parameters = [$this->seminar_id];
-            $statement = DBManager::get()->prepare($query);
-            $statement->execute($parameters);
-            $res = $statement->fetch(PDO::FETCH_ASSOC);
-            $own_inst = $res['Institut_id'];
-
-            $studip_info = $this->elements["StudipInfo"]->toString(["content" =>
-                    $this->config->getValue("StudipInfo", "homeinst") . "&nbsp;"]);
-
-            if ($res['url']) {
-                $link_inst = htmlReady($res['url']);
-                if (!preg_match('{^https?://.+$}', $link_inst))
-                    $link_inst = "http://$link_inst";
-                $studip_info .= sprintf(
-                    "<a href=\"%s\"%s target=\"_blank\" rel=\"noopener noreferrer\">%s</a>",
-                    $link_inst,
-                    $this->config->getAttributes("LinkInternSimple", "a"),
-                    htmlReady($res['Name'])
-                );
-            }else
-                $studip_info .= htmlReady($res['Name']);
-            $studip_info .= "<br>\n";
-
-
-            $query = "SELECT Name, url FROM seminar_inst LEFT JOIN Institute i USING(institut_id)
-                                    WHERE seminar_id = ? AND i.institut_id!='$own_inst'";
-            $parameters = [$this->seminar_id];
-            $statement = DBManager::get()->prepare($query);
-            $statement->execute($parameters);
-            $involved_insts = NULL;
-            foreach ($statement->fetchAll(PDO::FETCH_ASSOC) as $res) {
-                if ($res['url']) {
-                    $link_inst = htmlReady($res['url']);
-                    if (!preg_match('{^https?://.+$}', $link_inst))
-                        $link_inst = "http://$link_inst";
-                        $involved_insts[] = sprintf(
-                            "<a href=\"%s\"%s target=\"_blank\" rel=\"noopener noreferrer\">%s</a>",
-                            $link_inst,
-                            $this->config->getAttributes("LinkInternSimple", "a"),
-                            htmlReady($res['Name'])
-                        );
-                }
-                else
-                    $involved_insts[] = $res['Name'];
-            }
-
-            if ($involved_insts) {
-                $involved_insts = implode(", ", $involved_insts);
-                $studip_info .= $this->elements["StudipInfo"]->toString(["content" =>
-                        $this->config->getValue("StudipInfo", "involvedinst") . "&nbsp;"]);
-                $studip_info .= $involved_insts . "<br>\n";
-            }
-
-            $query = "SELECT count(*) as count_user FROM seminar_user WHERE Seminar_id = ?";
-            $parameters = [$this->seminar_id];
-            $statement = DBManager::get()->prepare($query);
-            $statement->execute($parameters);
-            $res = $statement->fetch(PDO::FETCH_ASSOC);
-
-            if ($res['count_user']) {
-                $studip_info .= $this->elements["StudipInfo"]->toString(["content" =>
-                            $this->config->getValue("StudipInfo", "countuser") . "&nbsp;"]);
-                $studip_info .= $res['count_user'] . "<br>\n";
-            }
-
-
-            // get postings for all ForumModules
-            foreach (PluginEngine::getPlugins('ForumModule') as $plugin) {
-                $postings += $plugin->getNumberOfPostingsForSeminar($this->seminar_id);
-            }
-
-            if ($postings) {
-                $studip_info .= $this->elements["StudipInfo"]->toString(["content" =>
-                            $this->config->getValue("StudipInfo", "countpostings") . "&nbsp;"]);
-                $studip_info .= $postings . "<br>\n";
-            }
-
-            $query = "SELECT COUNT(*) AS count_documents
-                  FROM folders
-                  INNER JOIN file_refs ON folder_id = folders.id
-                  WHERE range_id = ? AND range_type = 'course'
-            AND folder_type IN ('RootFolder', 'StandardFolder')
-                  GROUP BY range_id";
-            $parameters = [$this->seminar_id];
-            $statement = DBManager::get()->prepare($query);
-            $statement->execute($parameters);
-            $res = $statement->fetch(PDO::FETCH_ASSOC);
-
-            if ($res['count_documents']) {
-                $studip_info .= $this->elements["StudipInfo"]->toString(["content" =>
-                            $this->config->getValue("StudipInfo", "countdocuments") . "&nbsp;"]);
-                $studip_info .= $res['count_documents'] . "\n";
-            }
-        }
-
-        return $this->elements["Content"]->toString(["content" => $studip_info]);
-    }
-
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleLectures.class.php b/lib/extern/modules/ExternModuleLectures.class.php
deleted file mode 100644
index 7a95fbce544..00000000000
--- a/lib/extern/modules/ExternModuleLectures.class.php
+++ /dev/null
@@ -1,104 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleLectures.class.php
-* 
-* 
-* 
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleLectures
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleLectures.class.php
-// 
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/extern/modules/views/ExternSemBrowse.class.php';
-
-class ExternModuleLectures extends ExternModule {
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->registered_elements = [
-            'ReplaceTextSemType',
-            'SelectSubjectAreas',
-            'Body',
-            'TableHeader',
-            'InfoCountSem' => 'TableGroup',
-            'Grouping' => 'TableGroup',
-            'LecturesInnerTable',
-            'SemLink' => 'LinkIntern',
-            'LecturerLink' => 'LinkIntern'];
-        $this->args = ['group'];
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-    
-    function setup () {
-        $this->elements["InfoCountSem"]->real_name = _("Anzahl Veranstaltungen/Gruppierung");
-        $this->elements["SemLink"]->link_module_type = 4;
-        $this->elements["SemLink"]->real_name = _("Link zum Modul Veranstaltungsdetails");
-        $this->elements["LecturerLink"]->link_module_type = 2;
-        $this->elements["LecturerLink"]->real_name = _("Link zum Modul MitarbeiterInnendetails");
-    }
-    
-    function printout ($args) {
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-        
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-        
-        $start_item_id = get_start_item_id($this->config->range_id);
-        $browser = new ExternSemBrowse($this, $start_item_id);
-        $browser->print_result();
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-    
-    function printoutPreview () {
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-        
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-        
-        include "lib/extern/modules/views/lectures_preview.inc.php";
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-    
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleLecturestable.class.php b/lib/extern/modules/ExternModuleLecturestable.class.php
deleted file mode 100644
index 784e144b6c1..00000000000
--- a/lib/extern/modules/ExternModuleLecturestable.class.php
+++ /dev/null
@@ -1,122 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleLecturestable.class.php
-* 
-* 
-* 
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleLecturestable
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleLecturestable.class.php
-// 
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/extern/modules/views/ExternSemBrowseTable.class.php';
-
-class ExternModuleLecturestable extends ExternModule {
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->data_fields = ['VeranstaltungsNummer', 'Name', 'Untertitel', 'status', 'Ort',
-            'art', 'zeiten', 'dozent'];
-        $this->registered_elements = [
-            'ReplaceTextSemType',
-            'SelectSubjectAreas',
-            'Body',
-            'TableHeader',
-            'InfoCountSem' => 'TableGroup',
-            'Grouping' => 'TableGroup',
-            'TableHeadrow',
-            'TableRow',
-            'SemLink' => 'LinkIntern',
-            'LecturerLink' => 'LinkIntern'];
-        $this->field_names = [
-                _("Veranstaltungsnummer"),
-                _("Name"),
-                _("Untertitel"),
-                _("Status"),
-                _("Ort"),
-                _("Art"),
-                _("Zeiten"),
-                _("Lehrende")
-        ];
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-    
-    function setup () {
-        // extend $data_fields if generic datafields are set
-        $config_datafields = $this->config->getValue("Main", "genericdatafields");
-        $this->data_fields = array_merge((array)$this->data_fields, (array)$config_datafields);
-        
-        // setup module properties
-        $this->elements["InfoCountSem"]->real_name = _("Anzahl Veranstaltungen/Gruppierung");
-        $this->elements["SemLink"]->link_module_type = 4;
-        $this->elements["SemLink"]->real_name = _("Link zum Modul Veranstaltungsdetails");
-        $this->elements["LecturerLink"]->link_module_type = 2;
-        $this->elements["LecturerLink"]->real_name = _("Link zum Modul MitarbeiterInnendetails");
-    }
-    
-    function printout ($args) {
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-        
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-        
-        $start_item_id = get_start_item_id($this->config->range_id);
-        $browser = new ExternSemBrowseTable($this, $start_item_id);
-        $browser->print_result();
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-    
-    function printoutPreview () {
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-        
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-        
-        include "lib/extern/modules/views/lecturestable_preview.inc.php";
-        
-        if ($this->config->getValue("Main", "wholesite"))   
-            echo html_footer();
-    }
-    
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleNews.class.php b/lib/extern/modules/ExternModuleNews.class.php
deleted file mode 100644
index 65afeb99fec..00000000000
--- a/lib/extern/modules/ExternModuleNews.class.php
+++ /dev/null
@@ -1,102 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleNews.class.php
-* 
-* 
-* 
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleNews
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleNews.class.php
-// 
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-
-class ExternModuleNews extends ExternModule {
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->registered_elements = [
-                                'Body',
-                                'TableHeader',
-                                'TableHeadrow',
-                                'TableRow',
-                                'ContentNews',
-                                'LinkInternSimple' => 'LinkIntern',
-                                'StudipLink'];
-        $this->data_fields = ['date', 'topic'];
-        $this->field_names = 
-        [
-                _("Datum/Autor"),
-                _("Nachricht")
-        ];
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-    
-    function setup () {
-        $this->elements["LinkInternSimple"]->link_module_type = 2;
-        $this->elements["LinkInternSimple"]->real_name = _("Link zum Modul MitarbeiterInnendetails");
-        $this->elements["TableRow"]->real_name = _("Datenzeilen, Schrift von Name und Datum");
-    }
-    
-    function printout ($args) {
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-        
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-        
-        include "lib/extern/modules/views/news.inc.php";
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-    
-    function printoutPreview () {
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-        
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-        
-        include "lib/extern/modules/views/news_preview.inc.php";
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-    
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleNewsticker.class.php b/lib/extern/modules/ExternModuleNewsticker.class.php
deleted file mode 100644
index ab4f3a533b4..00000000000
--- a/lib/extern/modules/ExternModuleNewsticker.class.php
+++ /dev/null
@@ -1,169 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter005: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleNewsticker.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleNewsticker
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleNews.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-
-class ExternModuleNewsticker extends ExternModule {
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    function setup () {}
-
-    function printout ($args) {
-        echo $this->toString();
-    }
-
-    function printoutPreview () {
-        echo html_header($this->config);
-
-        echo $this->toStringPreview();
-
-        echo html_footer();
-    }
-
-    function toString ($args = NULL) {
-        $js_only = $this->config->getValue("Main", "jsonly");
-        if (!$js_only)
-            $out = "<script type=\"text/javascript\">\n<!--\n";
-        $out .= "var newsticker_max = 0;\n\n";
-        $out .= "function textlist() {\n\tnewsticker_max = textlist.arguments.length;\n\t";
-        $out .= "for (i = 0; i < newsticker_max; i++)\n\t\tthis[i] = textlist.arguments[i];\n}\n\n";
-        $out .= "newsticker_tl = new textlist(";
-
-        $topics = [];
-        foreach(StudipNews::GetNewsByRange($this->config->range_id, true) as $news_content){
-            $topics[] = "'" . addslashes((string) $news_content->topic) . "'";
-        }
-        if (!count($topics)) {
-            $topics[] = "'" . $this->config->getValue("Main", "nodatatext") . "'";
-        }
-        if ($this->config->getValue("Main", "endtext")) {
-            $topics[] = "'" . $this->config->getValue("Main", "endtext") . "'";
-        }
-
-        $out .= implode(", ", $topics) . ");\n\n";
-
-        $out .= "var newsticker_x = 0; newsticker_pos = 0;\n";
-        $out .= "var newsticker_l = newsticker_tl[0].length;\n\n";
-        $out .= "function newsticker() {\n\t";
-        $out .= "document.tickform.tickfield.value = newsticker_tl[newsticker_x].substring(0, newsticker_pos) + \"_\";\n";
-        $out .= "\tif (newsticker_pos++ == newsticker_l) {\n";
-        $out .= "\t\tnewsticker_pos = 0;\n\t\tsetTimeout(\"newsticker()\", ";
-
-        $out .= $this->config->getValue("Main", "pause");
-
-        $out .= ");\n\t\tif (++newsticker_x == newsticker_max)\n\t\t\tnewsticker_x = 0;\n";
-        $out .= "\t\tnewsticker_l = newsticker_tl[newsticker_x].length;\n\t}\n";
-        $out .= "\telse\n\t\tsetTimeout(\"newsticker()\", ";
-
-        $out .= ceil(1000 / $this->config->getValue("Main", "frequency"));
-
-        $out .= ");\n}\n";
-        if (!$js_only) {
-            $out .= "//-->\n</script>\n";
-            $out .= "<form name=\"tickform\">\t\n<textarea name=\"tickfield\" rows=\"";
-
-            $out .= $this->config->getValue("Main", "rows") . "\" cols=\"";
-            $out .= $this->config->getValue("Main", "length") . "\" style=\"";
-            $out .= $this->config->getValue("Main", "style") . "\" wrap=\"virtual\">";
-            $out .= $this->config->getValue("Main", "starttext");
-            $out .= "</textarea>\n</form>\n";
-
-            if ($this->config->getValue("Main", "automaticstart"))
-                $out .= "<script type=\"text/javascript\">\n\tnewsticker();\n</script>\n";
-        }
-
-        return $out;
-    }
-
-    function toStringPreview () {
-        $out = "<script type=\"text/javascript\">\n<!--\nvar newsticker_max = 0;\n";
-        $out .= "function textlist() {\n\tnewsticker_max = textlist.arguments.length;\n\t";
-        $out .= "for (i = 0; i < newsticker_max; i++)\n\t\tthis[i] = textlist.arguments[i];\n}\n\n";
-        $out .= "newsticker_tl = new textlist(";
-
-        for ($i = 1; $i < 5; $i++) {
-            $topics[] = sprintf("'" . _("Das ist News Nummer %s!") . "'", $i);
-        }
-        if ($this->config->getValue("Main", "endtext")) {
-            $topics[] = "'" . $this->config->getValue("Main", "endtext") . "'";
-        }
-
-        $out .= implode(", ", $topics) . ")\n\n";
-
-        $out .= "var newsticker_x = 0; newsticker_pos = 0;\n";
-        $out .= "var newsticker_l = newsticker_tl[0].length;\n\n";
-        $out .= "function newsticker() {\n\t";
-        $out .= "document.tickform.tickfield.value = newsticker_tl[newsticker_x].substring(0, newsticker_pos) + \"_\";\n";
-        $out .= "\tif (newsticker_pos++ == newsticker_l) {\n";
-        $out .= "\t\tnewsticker_pos = 0;\n\t\tsetTimeout(\"newsticker()\", ";
-
-        $out .= $this->config->getValue("Main", "pause");
-
-        $out .= ");\n\t\tif (++newsticker_x == newsticker_max)\n\t\t\tnewsticker_x = 0;\n";
-        $out .= "\t\tnewsticker_l = newsticker_tl[newsticker_x].length;\n\t}\n";
-        $out .= "\telse\n\t\tsetTimeout(\"newsticker()\", ";
-
-        $out .= ceil(1000 / $this->config->getValue("Main", "frequency"));
-
-        $out .= ");\n}\n//-->\n</script>\n";
-        $out .= "<form name=\"tickform\">\t\n<textarea name=\"tickfield\" rows=\"";
-
-        $out .= $this->config->getValue("Main", "rows") . "\" cols=\"";
-        $out .= $this->config->getValue("Main", "length") . "\" style=\"";
-        $out .= $this->config->getValue("Main", "style") . "\" wrap=\"virtual\">";
-        $out .= $this->config->getValue("Main", "starttext");
-        $out .= "</textarea>\n</form>\n";
-
-        if ($this->config->getValue("Main", "automaticstart"))
-            $out .= "<script type=\"text/javascript\">\n\tnewsticker();\n</script>\n";
-
-        return $out;
-    }
-
-}
-
-?>
diff --git a/lib/extern/modules/ExternModulePersondetails.class.php b/lib/extern/modules/ExternModulePersondetails.class.php
deleted file mode 100644
index 890e8e48b33..00000000000
--- a/lib/extern/modules/ExternModulePersondetails.class.php
+++ /dev/null
@@ -1,132 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModulePersondetail.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModulePersondetail
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModulePersondetail.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/dates.inc.php';
-
-class ExternModulePersondetails extends ExternModule {
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->data_fields = [
-                'contact' => [
-                    'raum', 'Telefon', 'Fax', 'Email',
-                    'Home', 'sprechzeiten'],
-                'content' => [
-                    'head', 'lebenslauf', 'schwerp', 'lehre',
-                    'news', 'termine', 'publi', 'kategorien']
-        ];
-        $this->registered_elements = [
-                'Body', 'TableHeader', 'PersondetailsHeader', 'Contact',
-                'PersondetailsLectures', 'TableParagraph', 'TableParagraphHeadline',
-                'TableParagraphSubHeadline', 'TableParagraphText', 'List',
-                'LinkIntern', 'StudipLink'
-        ];
-        $this->args = ['username', 'seminar_id'];
-        $this->field_names =
-        [
-            "contact" =>
-            [
-                _("Raum"),
-                _("Telefon"),
-                _("Fax"),
-                _("E-Mail"),
-                _("Homepage"),
-                _("Sprechzeiten")
-            ],
-            "content" =>
-            [
-                _("Name, Anschrift, Kontakt"),
-                _("Lebenslauf"),
-                _("Schwerpunkte"),
-                _("Lehrveranstaltungen"),
-                _("News"),
-                _("Termine"),
-                _("Publikationen"),
-                _("eigene Kategorien")/*,
-                _("Literaturlisten")*/
-            ]
-        ];
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    function setup () {
-        // extend $data_fields if generic datafields are set
-        $config_datafields = $this->config->getValue("Main", "genericdatafields");
-        $this->data_fields["content"] = array_merge((array)$this->data_fields['content'], (array)$config_datafields);
-
-        // setup module properties
-        $this->elements["LinkIntern"]->link_module_type = 4;
-        $this->elements["LinkIntern"]->real_name = _("Link zum Modul Veranstaltungsdetails");
-        $this->elements["TableHeader"]->real_name = _("Umschließende Tabelle");
-    }
-
-    function printout ($args) {
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        include "lib/extern/modules/views/persondetails.inc.php";
-
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-
-    function printoutPreview () {
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        include "lib/extern/modules/views/persondetails_preview.inc.php";
-
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-
-}
-
-?>
diff --git a/lib/extern/modules/ExternModulePersons.class.php b/lib/extern/modules/ExternModulePersons.class.php
deleted file mode 100644
index 75a96c93d5b..00000000000
--- a/lib/extern/modules/ExternModulePersons.class.php
+++ /dev/null
@@ -1,104 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModulePersons.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModulePersons
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModulePersons.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-
-class ExternModulePersons extends ExternModule {
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->data_fields = [
-                'Nachname', 'Telefon', 'raum', 'Email', 'sprechzeiten'
-        ];
-        $this->registered_elements = [
-                'Body', 'TableHeader', 'TableHeadrow', 'TableGroup',
-                'TableRow', 'Link', 'LinkIntern', 'TableFooter'
-        ];
-        $this->field_names =
-        [
-                _("Name"),
-                _("Telefon"),
-                _("Raum"),
-                _("E-Mail"),
-                _("Sprechzeiten")
-        ];
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    function setup () {
-        // extend $data_fields if generic datafields are set
-        $config_datafields = $this->config->getValue("Main", "genericdatafields");
-        $this->data_fields = array_merge((array)$this->data_fields, (array)$config_datafields);
-
-        // setup module properties
-        $this->elements["LinkIntern"]->link_module_type = [2, 14];
-        $this->elements["LinkIntern"]->real_name = _("Link zum Modul MitarbeiterInnendetails");
-        $this->elements["Link"]->real_name = _("E-Mail-Link");
-    }
-
-    function printout ($args) {
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        include "lib/extern/modules/views/persons.inc.php";
-
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-
-    function printoutPreview () {
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-
-        include "lib/extern/modules/views/persons_preview.inc.php";
-
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleRangelecturetree.class.php b/lib/extern/modules/ExternModuleRangelecturetree.class.php
deleted file mode 100644
index fc10eccdab5..00000000000
--- a/lib/extern/modules/ExternModuleRangelecturetree.class.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleRangelecturetree.class.php
-* 
-* 
-* 
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleRangelecturetree
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleRangelecturetree.class.php
-// 
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-
-class ExternModuleRangeLectureTree extends ExternModule {
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->registered_elements = [
-                'Body', 'TreePath', 'RangeTreeLevelName', 'RangeTreeLevelContent',
-                'TreeKids', 'TreeBackLink'
-        ];
-        $this->args = ['sem', 'start_item_id'];
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-    
-    function printout ($args) {
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-        
-        require_once "lib/extern/modules/views/ExternRangeLectureTree.class.php";
-        
-        $tree = new ExternRangeLectureTree($this->config, $args["start_item_id"]);
-        $tree->showSemRangeTree();
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-    
-    function printoutPreview ($args) {
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-        
-        require_once "lib/extern/modules/views/ExternRangeLectureTree.class.php";
-        
-        $tree = new ExternRangeLectureTree($this->config, $args["start_item_id"]);
-        $tree->showSemRangeTree();
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-    
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleSemlecturetree.class.php b/lib/extern/modules/ExternModuleSemlecturetree.class.php
deleted file mode 100644
index 4ddfd1e128e..00000000000
--- a/lib/extern/modules/ExternModuleSemlecturetree.class.php
+++ /dev/null
@@ -1,87 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleSemlecturetree.class.php
-* 
-* 
-* 
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleSemlecturetree
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleSemlecturetree.class.php
-// 
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-
-class ExternModuleSemLectureTree extends ExternModule {
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->registered_elements = [
-                'Body', 'TreePath', 'TreeLevelName', 'TreeLevelContent', 'TreeKids',
-                'TreeBackLink'
-        ];
-        $this->args = ['sem', 'start_item_id'];
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-    
-    function printout ($args) {
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-        
-        require_once "lib/extern/modules/views/ExternSemLectureTree.class.php";
-        
-        $tree = new ExternSemLectureTree($this->config, $args["start_item_id"]);
-        $tree->showSemTree();
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-    
-    function printoutPreview ($args) {
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_header($this->config);
-        
-        require_once "lib/extern/modules/views/ExternSemLectureTree.class.php";
-        
-        $tree = new ExternSemLectureTree($this->config, $args["start_item_id"]);
-        $tree->showSemTree();
-        
-        if ($this->config->getValue("Main", "wholesite"))
-            echo html_footer();
-    }
-    
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleTemplateDownload.class.php b/lib/extern/modules/ExternModuleTemplateDownload.class.php
deleted file mode 100644
index ee4c82afd40..00000000000
--- a/lib/extern/modules/ExternModuleTemplateDownload.class.php
+++ /dev/null
@@ -1,296 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleTemplateDownload.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleTemplateDownload
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleTemplateDownload.class.php
-//
-// Copyright (C) 2007 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/user_visible.inc.php';
-require_once 'lib/statusgruppe.inc.php';
-
-
-class ExternModuleTemplateDownload extends ExternModule {
-
-    var $markers = [];
-    var $args = ['seminar_id'];
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-
-        $this->data_fields = ["icon", "filename", "description", "mkdate",
-                             "filesize", "fullname"];
-        $this->registered_elements = [
-                'LinkInternTemplate', 'TemplateGeneric'
-        ];
-
-        $this->field_names =  [
-                _("Icon"),
-                _("Dateiname"),
-                _("Beschreibung"),
-                _("Datum"),
-                _("Größe"),
-                _("Upload durch")
-        ];
-
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    function setup () {
-        // extend $data_fields if generic datafields are set
-    //  $config_datafields = $this->config->getValue("Main", "genericdatafields");
-    //  $this->data_fields = array_merge((array)$this->data_fields, (array)$config_datafields);
-
-        // setup module properties
-    //  $this->elements["LinkIntern"]->link_module_type = 2;
-    //  $this->elements["LinkIntern"]->real_name = _("Link zum Modul MitarbeiterInnendetails");
-
-        $this->elements['TemplateGeneric']->real_name = _("Template");
-        $this->elements['LinkInternTemplate']->link_module_type = [2, 14];
-        $this->elements['LinkInternTemplate']->real_name = _("Link zum Modul MitarbeiterInnendetails");
-
-    }
-
-    function toStringEdit ($open_elements = '', $post_vars = '',
-            $faulty_values = '', $anker = '') {
-
-        $this->updateGenericDatafields('TemplateGeneric', 'user');
-        $this->elements['TemplateGeneric']->markers = $this->getMarkerDescription('TemplateGeneric');
-
-        return parent::toStringEdit($open_elements, $post_vars, $faulty_values, $anker);
-    }
-
-    function getMarkerDescription ($element_name) {
-        $markers['TemplateGeneric'][] = ['__GLOBAL__', _("Globale Variablen (gültig im gesamten Template).")];
-        $markers['TemplateGeneric'][] = ['###FILES-COUNT###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN DOWNLOAD -->', ''];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN NO-FILES -->', ''];
-        $markers['TemplateGeneric'][] = ['###NO-FILES-TEXT###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END NO-FILES -->', ''];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN FILES -->', ''];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN FILE -->', ''];
-        $markers['TemplateGeneric'][] = ['###FILE_NAME###', ''];
-        $markers['TemplateGeneric'][] = ['###FILE_FILE-NAME###', ''];
-        $markers['TemplateGeneric'][] = ['###FILE_SIZE###', ''];
-        $markers['TemplateGeneric'][] = ['###FILE_NO###', ''];
-        $markers['TemplateGeneric'][] = ['###FILE_DESCRIPTION###', ''];
-        $markers['TemplateGeneric'][] = ['###FILE_UPLOAD-DATE###', ''];
-        $markers['TemplateGeneric'][] = ['###FULLNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###LASTNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###FIRSTNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###TITLEFRONT###', ''];
-        $markers['TemplateGeneric'][] = ['###TITLEREAR###', ''];
-        $markers['TemplateGeneric'][] = ['###PERSONDETAIL-HREF###', ''];
-        $markers['TemplateGeneric'][] = ['###USERNAME###', ''];
-        $this->insertDatafieldMarkers('user', $markers, 'TemplateGeneric');
-        $markers['TemplateGeneric'][] = ['###FILE_HREF###', ''];
-        $markers['TemplateGeneric'][] = ['###FILE_ICON-HREF###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN PERSONDETAIL-LINK -->'];
-        $markers['TemplateGeneric'][] = ['###LINK_FULLNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###LINK_LASTNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###LINK_FIRSTNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###LINK_TITLEFRONT###', ''];
-        $markers['TemplateGeneric'][] = ['###LINK_TITLEREAR###', ''];
-        $markers['TemplateGeneric'][] = ['###LINK_PERSONDETAIL-HREF###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END PERSONDETAIL-LINK -->'];
-        $markers['TemplateGeneric'][] = ['<!-- END FILE -->'];
-        $markers['TemplateGeneric'][] = ['<!-- END FILES -->', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END DOWNLOAD -->', ''];
-
-        return $markers[$element_name];
-    }
-
-    function getContent ($args = NULL, $raw = FALSE) {
-        if (!$args) {
-            $args = [];
-        }
-        $content = [];
-
-        // if $args['seminar_id'] is given, check for free access
-        if ($args['seminar_id']) {
-            $seminar_id = $args['seminar_id'];
-            $query = "SELECT Lesezugriff FROM seminare s LEFT JOIN seminar_inst si ";
-            $query .= "USING(seminar_id) WHERE s.seminar_id = ? ";
-            $query .= "AND si.institut_id = ?";
-            $params = [$seminar_id, $this->config->range_id];
-            $statement = DBManager::get()->prepare($query);
-            $statement->execute($params);
-            $row = $statement->fetchColumn();
-        } else {
-            $seminar_id = $this->config->range_id;
-        }
-
-        $sort = (array) $this->config->getValue('Main', 'sort');
-        $query_order = [];
-        foreach ($sort as $key => $position) {
-            if ($position > 0) {
-                $query_order[$position] = $this->data_fields[$key];
-            }
-        }
-        if (count($query_order)) {
-            ksort($query_order, SORT_NUMERIC);
-            $query_order = implode(',', $query_order) . ' DESC';
-        } else {
-            $query_order = '';
-        }
-
-        if (!$nameformat = $this->config->getValue('Main', 'nameformat')) {
-            $nameformat = 'no_title_short';
-        }
-
-        // generic data fields
-        $generic_datafields = $this->config->getValue('TemplateGeneric', 'genericdatafields');
-
-        $downloadable_file_refs = [];
-
-        $top_folder = Folder::findTopFolder($seminar_id);
-        $top_folder = $top_folder->getTypedFolder();
-
-        $files = $folders = [];
-        extract(FileManager::getFolderFilesRecursive($top_folder, 'nobody'));
-
-        foreach ($files as $f) {
-            if ($folders[$f->folder_id]->isFileDownloadable($f, 'nobody')) {
-                $file_data = $f->toArray();
-                $file_data['fullname'] = $f->owner->getFullname($nameformat);
-                $file_data['username'] = $f->owner->username;
-                $file_data['vorname'] = $f->owner->vorname;
-                $file_data['nachname'] = $f->owner->nachname;
-                $file_data['title_front'] = $f->owner->title_front;
-                $file_data['title_rear'] = $f->owner->title_rear;
-
-                $file_data['filename'] = $f->name;
-                $file_data['filesize'] = $f->size;
-                $downloadable_file_refs[] = $file_data;
-            }
-        }
-
-
-        if (empty($downloadable_file_refs)) {
-            $content['NO-FILES']['NO-FILES-TEXT'] = $this->config->getValue('Main', 'nodatatext');
-        } else {
-            $i = 0;
-            $downloadable_file_refs = new SimpleCollection($downloadable_file_refs);
-            $downloadable_file_refs->orderBy($query_order);
-            foreach ($downloadable_file_refs as $downloadable_file_ref) {
-
-                $content['FILES']['FILE'][$i]['FILE_ICON-HREF'] = Icon::create(
-                    FileManager::getIconNameForMimeType($downloadable_file_ref->mime_type),
-                    'clickable'
-                    )->asImagePath(16);
-
-
-                $content['FILES']['FILE'][$i]['FILE_NO'] = $i + 1;
-
-                $download_link = $downloadable_file_ref->download_url;
-
-                $content['FILES']['FILE'][$i]['FILE_HREF'] = $download_link;
-                $content['FILES']['FILE'][$i]['FILE_NAME'] = ExternModule::ExtHtmlReady($downloadable_file_ref->name);
-                $content['FILES']['FILE'][$i]['FILE_FILE-NAME'] = ExternModule::ExtHtmlReady($downloadable_file_ref->name);
-                $content['FILES']['FILE'][$i]['FILE_DESCRIPTION'] = ExternModule::ExtHtmlReady(mila_extern($downloadable_file_ref->description,
-                                                     $this->config->getValue("Main", "lengthdesc")));
-                $content['FILES']['FILE'][$i]['FILE_UPLOAD-DATE'] = strftime($this->config->getValue("Main", "dateformat"), $downloadable_file_ref->mkdate);
-                $content['FILES']['FILE'][$i]['FILE_SIZE'] = $downloadable_file_ref->filesize > 1048576 ? round($downloadable_file_ref->filesize / 1048576, 1) . " MB" : round($downloadable_file_ref->filesize / 1024, 1) . " kB";
-
-                $content['FILES']['FILE'][$i]['USERNAME'] = $downloadable_file_ref->username;
-                $content['FILES']['FILE'][$i]['FULLNAME'] = ExternModule::ExtHtmlReady($downloadable_file_ref->fullname);
-                $content['FILES']['FILE'][$i]['FIRSTNAME'] = ExternModule::ExtHtmlReady($downloadable_file_ref->vorname);
-                $content['FILES']['FILE'][$i]['LASTNAME'] = ExternModule::ExtHtmlReady($downloadable_file_ref->nachname);
-                $content['FILES']['FILE'][$i]['TITLEFRONT'] = ExternModule::ExtHtmlReady($downloadable_file_ref->title_front);
-                $content['FILES']['FILE'][$i]['TITLEREAR'] = ExternModule::ExtHtmlReady($downloadable_file_ref->title_rear);
-                $content['FILES']['FILE'][$i]['PERSONDETAIL-HREF'] = $this->elements['LinkInternTemplate']->createUrl(['link_args' => 'username=' . $downloadable_file_ref->username]);
-
-                // if user is member of a group then link name to details page
-                $link_persondetail = '';
-                if (GetRoleNames(GetAllStatusgruppen($this->config->range_id, $downloadable_file_ref->user_id))) {
-                    $content['FILES']['FILE'][$i]['PERSONDETAIL-LINK']['LINK_PERSONDETAIL-HREF'] = $this->elements['LinkInternTemplate']->createUrl(['link_args' => 'username=' . $downloadable_file_ref->username]);
-                    $content['FILES']['FILE'][$i]['PERSONDETAIL-LINK']['LINK_FULLNAME'] = ExternModule::ExtHtmlReady($downloadable_file_ref->fullname);
-                    $content['FILES']['FILE'][$i]['PERSONDETAIL-LINK']['LINK_FIRSTNAME'] = ExternModule::ExtHtmlReady($downloadable_file_ref->vorname);
-                    $content['FILES']['FILE'][$i]['PERSONDETAIL-LINK']['LINK_LASTNAME'] = ExternModule::ExtHtmlReady($downloadable_file_ref->nachname);
-                    $content['FILES']['FILE'][$i]['PERSONDETAIL-LINK']['LINK_TITLEFRONT'] = ExternModule::ExtHtmlReady($downloadable_file_ref->title_front);
-                    $content['FILES']['FILE'][$i]['PERSONDETAIL-LINK']['LINK_TITLEREAR'] = ExternModule::ExtHtmlReady($downloadable_file_ref->title_rear);
-                }
-
-                // generic data fields
-                if (is_array($generic_datafields)) {
-                    $localEntries = DataFieldEntry::getDataFieldEntries($downloadable_file_ref->owner->user_id, 'user');
-                    $k = 1;
-                    foreach ($generic_datafields as $datafield) {
-                        if (isset($localEntries[$datafield]) && is_object($localEntries[$datafield])) {
-                            $localEntry = $localEntries[$datafield]->getDisplayValue();
-                            if ($localEntry) {
-                                $content['FILES']['FILE'][$i]['DATAFIELD_' . $k] = $localEntry;
-                            }
-                        }
-                        $k++;
-                    }
-                }
-
-                $i++;
-            //}while($row = $statement->fetch(PDO::FETCH_ASSOC));
-            }
-        }
-        $content = ['DOWNLOAD' => $content];
-        $content['__GLOBAL__']['FILES-COUNT'] = $i;
-
-        return $content;
-    }
-
-    function printout ($args) {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateGeneric']->toString(['content' => $this->getContent($args), 'subpart' => 'DOWNLOAD']);
-
-    }
-
-    public function printoutPreview ()
-    {
-        $language = $this->config->getValue("Main", "language") ?: 'de_DE';
-        init_i18n($language);
-
-        echo $this->elements['TemplateGeneric']->toString([
-            'content'      => $this->getContent(),
-            'subpart'      => 'DOWNLOAD',
-            'hide_markers' => false,
-        ]);
-
-    }
-
-}
diff --git a/lib/extern/modules/ExternModuleTemplateLecturedetails.class.php b/lib/extern/modules/ExternModuleTemplateLecturedetails.class.php
deleted file mode 100644
index 3b7d9ab825a..00000000000
--- a/lib/extern/modules/ExternModuleTemplateLecturedetails.class.php
+++ /dev/null
@@ -1,567 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleTemplateLecturedetails.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleTemplateLecturedetails
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleTemplateLecturedetails.class.php
-//
-// Copyright (C) 2007 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/user_visible.inc.php';
-require_once 'lib/dates.inc.php';
-
-class ExternModuleTemplateLecturedetails extends ExternModule {
-
-    var $markers = [];
-    var $args = ['seminar_id'];
-    var $seminar_id;
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-
-        $this->data_fields = ['subtitle', 'lecturer', 'art', 'status', 'description',
-            'location', 'semester', 'time', 'number', 'teilnehmer', 'requirements',
-            'lernorga', 'leistung', 'range_path', 'misc', 'ects'];
-        $this->registered_elements = [
-                'ReplaceTextSemType',
-                'LinkInternPersondetails' => 'LinkInternTemplate',
-                'TemplateLectureData' => 'TemplateGeneric',
-                'TemplateNews' => 'TemplateGeneric',
-                'TemplateStudipData' => 'TemplateGeneric'
-        ];
-        $this->field_names =
-        [
-                _("Untertitel"),
-                _("Lehrende"),
-                _("Veranstaltungsart"),
-                _("Veranstaltungstyp"),
-                _("Beschreibung"),
-                _("Ort"),
-                _("Semester"),
-                _("Zeiten"),
-                _("Veranstaltungsnummer"),
-                _("Teilnehmende"),
-                _("Voraussetzungen"),
-                _("Lernorganisation"),
-                _("Leistungsnachweis"),
-                _("Bereichseinordnung"),
-                _("Sonstiges"),
-                _("ECTS-Punkte")
-        ];
-
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    function setup () {
-        // extend $data_fields if generic datafields are set
-    //  $config_datafields = $this->config->getValue("Main", "genericdatafields");
-    //  $this->data_fields = array_merge((array)$this->data_fields, (array)$config_datafields);
-
-        // setup module properties
-    //  $this->elements["LinkIntern"]->link_module_type = 2;
-    //  $this->elements["LinkIntern"]->real_name = _("Link zum Modul MitarbeiterInnendetails");
-
-        $this->elements['LinkInternPersondetails']->real_name = _("Verlinkung zum Modul MitarbeiterInnendetails");
-        $this->elements['LinkInternPersondetails']->link_module_type = [2, 14];
-        $this->elements['TemplateLectureData']->real_name = _("Haupttemplate");
-        $this->elements['TemplateNews']->real_name = _("Template für News");
-        $this->elements['TemplateStudipData']->real_name = _("Template für statistische Daten aus Stud.IP");
-
-    }
-
-    function toStringEdit ($open_elements = '', $post_vars = '',
-            $faulty_values = '', $anker = '') {
-
-        $this->updateGenericDatafields('TemplateLectureData', 'sem');
-        $this->elements['TemplateLectureData']->markers = $this->getMarkerDescription('TemplateLectureData');
-        $this->elements['TemplateNews']->markers = $this->getMarkerDescription('TemplateNews');
-        $this->elements['TemplateStudipData']->markers = $this->getMarkerDescription('TemplateStudipData');
-
-        return parent::toStringEdit($open_elements, $post_vars, $faulty_values, $anker);
-    }
-
-    function getMarkerDescription ($element_name) {
-        $markers['TemplateLectureData'][] = ['__GLOBAL__', _("Globale Variablen (gültig im gesamten Template).")];
-        $markers['TemplateLectureData'][] = ['###STUDIP-EDIT-HREF###', ''];
-        $markers['TemplateLectureData'][] = ['###STUDIP-REGISTER-HREF###', ''];
-
-        $markers['TemplateLectureData'][] = ['<!-- BEGIN LECTUREDETAILS -->', ''];
-        $markers['TemplateLectureData'][] = ['###TITLE###', ''];
-        $markers['TemplateLectureData'][] = ['###SUBTITLE###', ''];
-        $markers['TemplateLectureData'][] = ['###SEMESTER###', ''];
-        $markers['TemplateLectureData'][] = ['###CYCLE###', ''];
-        $markers['TemplateLectureData'][] = ['###ROOM###', ''];
-        $markers['TemplateLectureData'][] = ['###NUMBER###', _("Die Veranstaltungsnummer")];
-
-        $markers['TemplateLectureData'][] = ['<!-- BEGIN LECTURERS -->', ''];
-        $markers['TemplateLectureData'][] = ['<!-- BEGIN LECTURER -->', ''];
-        $markers['TemplateLectureData'][] = ['###FULLNAME###', ''];
-        $markers['TemplateLectureData'][] = ['###LASTNAME###', ''];
-        $markers['TemplateLectureData'][] = ['###FIRSTNAME###', ''];
-        $markers['TemplateLectureData'][] = ['###TITLEFRONT###', ''];
-        $markers['TemplateLectureData'][] = ['###TITLEREAR###', ''];
-        $markers['TemplateLectureData'][] = ['###PERSONDETAILS-HREF###', ''];
-        $markers['TemplateLectureData'][] = ['###LECTURER-NO###', ''];
-        $markers['TemplateLectureData'][] = ['###UNAME###', ''];
-        $markers['TemplateLectureData'][] = ['<!-- END LECTURER -->', ''];
-        $markers['TemplateLectureData'][] = ['<!-- END LECTURERS -->', ''];
-
-        $markers['TemplateLectureData'][] = ['<!-- BEGIN TUTORS -->', ''];
-        $markers['TemplateLectureData'][] = ['<!-- BEGIN TUTOR -->', ''];
-        $markers['TemplateLectureData'][] = ['###TUTOR_FULLNAME###', ''];
-        $markers['TemplateLectureData'][] = ['###TUTOR_LASTNAME###', ''];
-        $markers['TemplateLectureData'][] = ['###TUTOR_FIRSTNAME###', ''];
-        $markers['TemplateLectureData'][] = ['###TUTOR_TITLEFRONT###', ''];
-        $markers['TemplateLectureData'][] = ['###TUTOR_TITLEREAR###', ''];
-        $markers['TemplateLectureData'][] = ['###TUTOR_PERSONDETAILS-HREF###', ''];
-        $markers['TemplateLectureData'][] = ['###TUTOR-NO###', ''];
-        $markers['TemplateLectureData'][] = ['###TUTOR_UNAME###', ''];
-        $markers['TemplateLectureData'][] = ['<!-- END TUTOR -->', ''];
-        $markers['TemplateLectureData'][] = ['<!-- END TUTORS -->', ''];
-
-        $markers['TemplateLectureData'][] = ['###PRELIM-DISCUSSION###', ''];
-        $markers['TemplateLectureData'][] = ['###SEMTYPE-SUBSTITUTE###', ''];
-        $markers['TemplateLectureData'][] = ['###SEMTYPE###', ''];
-        $markers['TemplateLectureData'][] = ['###FORM###', _("Die Veranstaltungsart")];
-        $markers['TemplateLectureData'][] = ['###PARTICIPANTS###', ''];
-        $markers['TemplateLectureData'][] = ['###DESCRIPTION###', ''];
-        $markers['TemplateLectureData'][] = ['###MISC###', _("Sonstiges")];
-        $markers['TemplateLectureData'][] = ['###REQUIREMENTS###', ''];
-        $markers['TemplateLectureData'][] = ['###ORGA###', _("Organisationsform")];
-        $markers['TemplateLectureData'][] = ['###LEISTUNGSNACHWEIS###', _("Leistungsnachweis")];
-        $markers['TemplateLectureData'][] = ['###FORM###', ''];
-        $markers['TemplateLectureData'][] = ['###ECTS###', ''];
-        $markers['TemplateLectureData'][] = ['###PRELIM-DISCUSSION###', ''];
-        $markers['TemplateLectureData'][] = ['###FIRST-MEETING###', ''];
-
-        $this->insertDatafieldMarkers('sem', $markers, 'TemplateLectureData');
-
-        $markers['TemplateLectureData'][] = ['###NEWS###', _("Inhalt aus dem Template für News")];
-        $markers['TemplateLectureData'][] = ['###STUDIP-DATA###', 'Inhalt aus dem Template für statistische Daten aus Stud.IP'];
-
-        $markers['TemplateLectureData'][] = ['<!-- BEGIN RANGE-PATHES -->', ''];
-        $markers['TemplateLectureData'][] = ['<!-- BEGIN RANGE-PATH -->', ''];
-        $markers['TemplateLectureData'][] = ['###PATH###', ''];
-        $markers['TemplateLectureData'][] = ['<!-- END RANGE-PATH -->', ''];
-        $markers['TemplateLectureData'][] = ['<!-- END RANGE-PATHES -->', ''];
-
-        $markers['TemplateLectureData'][] = ['<!-- BEGIN MODULES -->', ''];
-        $markers['TemplateLectureData'][] = ['<!-- BEGIN MODULE -->', ''];
-        $markers['TemplateLectureData'][] = ['###PATH###', _('Modulzuordnungen der Veranstaltung')];
-        $markers['TemplateLectureData'][] = ['<!-- END MODULE -->', ''];
-        $markers['TemplateLectureData'][] = ['<!-- END MODULES -->', ''];
-
-        $markers['TemplateLectureData'][] = ['<!-- END LECTUREDETAILS -->'];
-
-        $markers['TemplateNews'][] = ['<!-- BEGIN NEWS -->', ''];
-        $markers['TemplateNews'][] = ['<!-- BEGIN NO-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['###NEWS_NO-NEWS-TEXT###', ''];
-        $markers['TemplateNews'][] = ['<!-- END NO-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['<!-- BEGIN ALL-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['<!-- BEGIN SINGLE-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['###NEWS_TOPIC###', ''];
-        $markers['TemplateNews'][] = ['###NEWS_BODY###', ''];
-        $markers['TemplateNews'][] = ['###NEWS_DATE###', ''];
-        $markers['TemplateNews'][] = ['###NEWS_ADMIN-MESSAGE###', ''];
-        $markers['TemplateNews'][] = ['###NEWS_NO###', ''];
-        $markers['TemplateNews'][] = ['###FULLNAME###', _("Vollständiger Name des Autors.")];
-        $markers['TemplateNews'][] = ['###LASTNAME###', _("Nachname des Autors.")];
-        $markers['TemplateNews'][] = ['###FIRSTNAME###', _("Vorname des Autors.")];
-        $markers['TemplateNews'][] = ['###TITLEFRONT###', _("Titel des Autors (vorangestellt).")];
-        $markers['TemplateNews'][] = ['###TITLEREAR###', _("Titel des Autors (nachgestellt).")];
-        $markers['TemplateNews'][] = ['###PERSONDETAIL-HREF###', ''];
-        $markers['TemplateNews'][] = ['###USERNAME###', ''];
-        $markers['TemplateNews'][] = ['<!-- END SINGLE-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['<!-- END ALL-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['<!-- END NEWS -->', ''];
-
-        $markers['TemplateStudipData'][] = ['<!-- BEGIN STUDIP-DATA -->', ''];
-        $markers['TemplateStudipData'][] = ['###HOME-INST-NAME###', ''];
-        $markers['TemplateStudipData'][] = ['###HOME-INST-HREF###', ''];
-        $markers['TemplateStudipData'][] = ['###COUNT-USER###', ''];
-        $markers['TemplateStudipData'][] = ['###COUNT-POSTINGS###', ''];
-        $markers['TemplateStudipData'][] = ['###COUNT-DOCUMENTS###', ''];
-
-        $markers['TemplateStudipData'][] = ['<!-- BEGIN INVOLVED-INSTITUTES -->', ''];
-        $markers['TemplateStudipData'][] = ['<!-- BEGIN INVOLVED-INSTITUTE -->', ''];
-        $markers['TemplateStudipData'][] = ['###INVOLVED-INSTITUTE_HREF###', ''];
-        $markers['TemplateStudipData'][] = ['###INVOLVED-INSTITUTE_NAME###', ''];
-        $markers['TemplateStudipData'][] = ['<!-- END INVOLVED-INSTITUTE -->', ''];
-        $markers['TemplateStudipData'][] = ['<!-- END INVOLVED-INSTITUTES -->', ''];
-
-        $markers['TemplateStudipData'][] = ['<!-- END STUDIP-DATA -->', ''];
-
-        return $markers[$element_name];
-    }
-
-    function getContent ($args = NULL, $raw = FALSE) {
-        $this->seminar_id = $args["seminar_id"];
-        $course_object = new Course($this->seminar_id);
-        $seminar = new Seminar($course_object);
-
-        $visible = $this->config->getValue("Main", "visible");
-
-        $j = -1;
-        if ($seminar->visible == 1) {
-            $content['LECTUREDETAILS']['TITLE'] = ExternModule::ExtHtmlReady($seminar->getName());
-            if (trim($seminar->seminar_number)) {
-                $content['LECTUREDETAILS']['NUMBER'] = ExternModule::ExtHtmlReady($seminar->seminar_number);
-            }
-            if (trim($seminar->subtitle)) {
-                $content['LECTUREDETAILS']['SUBTITLE'] = ExternModule::ExtHtmlReady($seminar->subtitle);
-            }
-            if (trim($seminar->description)) {
-                $content['LECTUREDETAILS']['DESCRIPTION'] = ExternModule::ExtHtmlReady($seminar->description, TRUE);
-            }
-            if (trim($seminar->misc)) {
-                $content['LECTUREDETAILS']['MISC'] = ExternModule::ExtHtmlReady($seminar->misc, TRUE);
-            }
-            if (trim($seminar->participants)) {
-                $content['LECTUREDETAILS']['PARTICIPANTS'] = ExternModule::ExtHtmlReady($seminar->participants);
-            }
-            if (trim($seminar->requirements)) {
-                $content['LECTUREDETAILS']['REQUIREMENTS'] = ExternModule::ExtHtmlReady($seminar->requirements);
-            }
-            if (trim($seminar->orga)) {
-                $content['LECTUREDETAILS']['ORGA'] = ExternModule::ExtHtmlReady($seminar->orga);
-            }
-            if (trim($seminar->leistungsnachweis)) {
-                $content['LECTUREDETAILS']['LEISTUNGSNACHWEIS'] = ExternModule::ExtHtmlReady($seminar->leistungsnachweis);
-            }
-            if (trim($seminar->form)) {
-                $content['LECTUREDETAILS']['FORM'] = ExternModule::ExtHtmlReady($seminar->form);
-            }
-            if (trim($seminar->ects)) {
-                $content['LECTUREDETAILS']['ECTS'] = ExternModule::ExtHtmlReady($seminar->ects);
-            }
-
-            if (!$name_sql = $this->config->getValue("Main", "nameformat")) {
-                $name_sql = "full";
-            }
-
-            $lecturers = array_keys($seminar->getMembers('dozent'));
-
-            $l = 0;
-            foreach ($lecturers as $lecturer) {
-                $query = "SELECT {$GLOBALS['_fullname_sql'][$name_sql]} AS name, username, Vorname, Nachname, title_rear, title_front FROM auth_user_md5 aum LEFT JOIN user_info ui USING(user_id) WHERE aum.user_id = ?";
-                $parameters = [$lecturer];
-                $state = DBManager::get()->prepare($query);
-                $state->execute($parameters);
-                $rowlec = $state->fetch(PDO::FETCH_ASSOC);
-                if ($rowlec !== false) {
-                    $content['LECTUREDETAILS']['LECTURERS']['LECTURER'][$l]['PERSONDETAILS-HREF'] = $this->elements['LinkInternPersondetails']->createUrl(['link_args' => 'username=' . $rowlec['username']]);
-                    $content['LECTUREDETAILS']['LECTURERS']['LECTURER'][$l]['FULLNAME'] = ExternModule::ExtHtmlReady($rowlec['name']);
-                    $content['LECTUREDETAILS']['LECTURERS']['LECTURER'][$l]['FIRSTNAME'] = ExternModule::ExtHtmlReady($rowlec['Vorname']);
-                    $content['LECTUREDETAILS']['LECTURERS']['LECTURER'][$l]['LASTNAME'] = ExternModule::ExtHtmlReady($rowlec['Nachname']);
-                    $content['LECTUREDETAILS']['LECTURERS']['LECTURER'][$l]['TITLEFRONT'] = ExternModule::ExtHtmlReady($rowlec['title_front']);
-                    $content['LECTUREDETAILS']['LECTURERS']['LECTURER'][$l]['TITLEREAR'] = ExternModule::ExtHtmlReady($rowlec['title_rear']);
-                    $content['LECTUREDETAILS']['LECTURERS']['LECTURER'][$l]['UNAME'] = $rowlec['username'];
-                    $content['LECTUREDETAILS']['LECTURERS']['LECTURER'][$l]['LECTURER-NO'] = $l + 1;
-                    $l++;
-                }
-            }
-
-            $tutors = array_keys($seminar->getMembers('tutor'));
-
-            $l = 0;
-            foreach ($tutors as $tutor) {
-                $query = "SELECT {$GLOBALS['_fullname_sql'][$name_sql]} AS name, username, Vorname, Nachname, title_rear, title_front FROM auth_user_md5 aum LEFT JOIN user_info ui USING(user_id) WHERE aum.user_id = ?";
-                $parameters = [$tutor];
-                $state = DBManager::get()->prepare($query);
-                $state->execute($parameters);
-                $rowtut = $state->fetch(PDO::FETCH_ASSOC);
-                if ($rowtut !== false) {
-                    $content['LECTUREDETAILS']['TUTORS']['TUTOR'][$l]['TUTOR_PERSONDETAILS-HREF'] = $this->elements['LinkInternPersondetails']->createUrl(['link_args' => 'username=' . $rowtut['username']]);
-                    $content['LECTUREDETAILS']['TUTORS']['TUTOR'][$l]['TUTOR_FULLNAME'] = ExternModule::ExtHtmlReady($rowtut['name']);
-                    $content['LECTUREDETAILS']['TUTORS']['TUTOR'][$l]['TUTOR_FIRSTNAME'] = ExternModule::ExtHtmlReady($rowtut['Vorname']);
-                    $content['LECTUREDETAILS']['TUTORS']['TUTOR'][$l]['TUTOR_LASTNAME'] = ExternModule::ExtHtmlReady($rowtut['Nachname']);
-                    $content['LECTUREDETAILS']['TUTORS']['TUTOR'][$l]['TUTOR_TITLEFRONT'] = ExternModule::ExtHtmlReady($rowtut['title_front']);
-                    $content['LECTUREDETAILS']['TUTORS']['TUTOR'][$l]['TUTOR_TITLEREAR'] = ExternModule::ExtHtmlReady($rowtut['title_rear']);
-                    $content['LECTUREDETAILS']['TUTORS']['TUTOR'][$l]['TUTOR_UNAME'] = $rowtut['username'];
-                    $content['LECTUREDETAILS']['TUTORS']['TUTOR'][$l]['TUTOR-NO'] = $l + 1;
-                    $l++;
-                }
-            }
-
-            // reorganize the $SEM_TYPE-array
-            foreach ($GLOBALS["SEM_CLASS"] as $key_class => $class) {
-                $i = 0;
-                foreach ($GLOBALS["SEM_TYPE"] as $key_type => $type) {
-                    if ($type["class"] == $key_class) {
-                        $i++;
-                        $sem_types_position[$key_type] = $i;
-                    }
-                }
-            }
-            $aliases_sem_type = $this->config->getValue("ReplaceTextSemType",
-                    "class_" . $GLOBALS["SEM_TYPE"][$seminar->status]['class']);
-            if ($aliases_sem_type[$sem_types_position[$seminar->status] - 1]) {
-                $content['LECTUREDETAILS']['SEMTYPE-SUBSTITUTE'] = $aliases_sem_type[$sem_types_position[$seminar->status] - 1];
-            } else {
-                $content['LECTUREDETAILS']['SEMTYPE-SUBSTITUTE'] = ExternModule::ExtHtmlReady($GLOBALS["SEM_TYPE"][$seminar->status]["name"]);
-            }
-            $content['LECTUREDETAILS']['SEMTYPE'] = ExternModule::ExtHtmlReady($GLOBALS["SEM_TYPE"][$seminar->status]["name"]);
-            $room = trim(Seminar::getInstance($this->seminar_id)->getDatesTemplate('dates/seminar_export_location'));
-            if ($room) {
-                $content['LECTUREDETAILS']['ROOM'] = ExternModule::ExtHtmlReady($room);
-            }
-            $content['LECTUREDETAILS']['SEMESTER'] = get_semester($this->seminar_id);
-            $content['LECTUREDETAILS']['CYCLE'] = ExternModule::ExtHtmlReady(Seminar::getInstance($this->seminar_id)->getDatesExport());
-            if ($vorbesprechung = vorbesprechung($this->seminar_id, 'export')) {
-                $content['LECTUREDETAILS']['PRELIM-DISCUSSION'] = ExternModule::ExtHtmlReady($vorbesprechung);
-            }
-            if ($veranstaltung_beginn = Seminar::getInstance($this->seminar_id)->getFirstDate('export')) {
-                $content['LECTUREDETAILS']['FIRST-MEETING'] = ExternModule::ExtHtmlReady($veranstaltung_beginn);
-            }
-
-            $range_path_level = $this->config->getValue('Main', 'rangepathlevel');
-            $pathes = get_sem_tree_path($this->seminar_id, $range_path_level);
-            if (is_array($pathes)) {
-                $i = 0;
-                foreach ($pathes as $foo => $path) {
-                    $content['LECTUREDETAILS']['RANGE-PATHES']['RANGE-PATH'][$i]['PATH'] = ExternModule::ExtHtmlReady($path);
-                    $i++;
-                }
-            }
-
-            if ($seminar->getSemClass()['module']) {
-                ModuleManagementModelTreeItem::setObjectFilter('Modul', function ($modul) use ($course_object) {
-                    // check for public status
-                    if (!$GLOBALS['MVV_MODUL']['STATUS']['values'][$modul->stat]['public']) {
-                        return false;
-                    }
-                    $modul_start = Semester::find($modul->start)->beginn ?: 0;
-                    $modul_end = Semester::find($modul->end)->beginn ?: PHP_INT_MAX;
-                    return ($course_object->start_time <= $modul_end)
-                        && (
-                            ($course_object->start_time >= $modul_start)
-                            || $course_object->isOpenEnded()
-                            || $course_object->getEndSemester()->ende <= $modul_end
-                            || $course_object->getEndSemester()->ende >= $modul_start
-                        );
-                });
-                ModuleManagementModelTreeItem::setObjectFilter('StgteilVersion', function ($version) {
-                    return $GLOBALS['MVV_STGTEILVERSION']['STATUS']['values'][$version->stat]['public'];
-                });
-                $trail_classes = ['Modulteil', 'StgteilabschnittModul', 'StgteilAbschnitt', 'StgteilVersion'];
-                $mvv_object_paths = MvvCourse::get($this->seminar_id)->getTrails($trail_classes);
-                $mvv_paths = [];
-
-                foreach ($mvv_object_paths as $mvv_object_path) {
-                    // show only complete paths
-                    if (count($mvv_object_path) === 4) {
-                        $mvv_object_names = [];
-                        foreach ($mvv_object_path as $mvv_object) {
-                            $mvv_object_names[] = $mvv_object->getDisplayName();
-                        }
-                        $mvv_paths[] = implode(' > ', $mvv_object_names);
-                    }
-                }
-
-                foreach ($mvv_paths as $mvv_path) {
-                    $content['LECTUREDETAILS']['MODULES']['MODULE'][] = ['PATH' => ExternModule::ExtHtmlReady($mvv_path)];
-                }
-            }
-
-            $content['LECTUREDETAILS']['NEWS'] = $this->elements['TemplateNews']->toString(['content' => $this->getContentNews(), 'subpart' => 'NEWS']);
-            $content['LECTUREDETAILS']['STUDIP-DATA'] = $this->getStudipData();
-
-            // generic data fields
-            if ($generic_datafields = $this->config->getValue('TemplateLectureData', 'genericdatafields')) {
-                $localEntries = DataFieldEntry::getDataFieldEntries($this->seminar_id, 'sem');
-                $k = 1;
-                foreach ($generic_datafields as $datafield) {
-                    if (isset($localEntries[$datafield]) && is_object($localEntries[$datafield])) {
-                        $localEntry = trim($localEntries[$datafield]->getDisplayValue());
-                        if ($localEntry) {
-                            $content['LECTUREDETAILS']["DATAFIELD_$k"] = $localEntry;
-                        }
-                    }
-                    $k++;
-                }
-            }
-
-            $content['__GLOBAL__']['STUDIP-EDIT-HREF'] = "{$GLOBALS['ABSOLUTE_URI_STUDIP']}seminar_main.php?auswahl={$this->seminar_id}&again=1&redirect_to=dispatch.php/course/basicdata/view/".$this->seminar_id."&login=true&new_sem=TRUE";
-            $content['__GLOBAL__']['STUDIP-REGISTER-HREF'] = "{$GLOBALS['ABSOLUTE_URI_STUDIP']}dispatch.php/course/details/?again=1&sem_id={$this->seminar_id}";
-        }
-
-        return $content;
-    }
-
-    private function getContentNews ()
-    {
-        $local_fullname_sql = $GLOBALS['_fullname_sql'];
-        if (!$nameformat = $this->config->getValue('Main', 'nameformat')) {
-            $nameformat = 'no_title';
-        }
-        if ($nameformat == 'last') {
-            $local_fullname_sql['last'] = ' Nachname ';
-        }
-        $dateform = $this->config->getValue('Main', 'dateformat');
-
-        $news = StudipNews::GetNewsByRange($this->seminar_id, TRUE);
-        if (!count($news)) {
-            $content['NEWS']['NO-NEWS']['NEWS_NO-NEWS-TEXT'] = $this->config->getValue('Main', 'nodatatext');
-        } else {
-            $i = 0;
-            foreach ($news as $news_id => $news_detail) {
-                $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_BODY'] = ExternModule::ExtFormatReady((string) $news_detail->body);
-                $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_DATE'] = strftime($dateform, $news_detail->date);
-                $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_TOPIC'] = ExternModule::ExtHtmlReady((string) $news_detail->topic);
-                $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_NO'] = $i + 1;
-
-                $query = "SELECT Nachname, Vorname, title_front, title_rear,
-                                 {$local_fullname_sql[$nameformat]} AS fullname, username,
-                                 aum.user_id
-                          FROM auth_user_md5 AS aum
-                          LEFT JOIN user_info AS ui USING (user_id)
-                          WHERE aum.user_id = ?";
-                $statement = DBManager::get()->prepare($query);
-                $statement->execute([$news_detail->user_id]);
-                $temp = $statement->fetch(PDO::FETCH_ASSOC);
-                if ($temp) {
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['FULLNAME'] = ExternModule::ExtHtmlReady($temp['fullname']);
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['FIRSTNAME'] = ExternModule::ExtHtmlReady($temp['Vorname']);
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['LASTNAME'] = ExternModule::ExtHtmlReady($temp['Nachname']);
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['TITLEFRONT'] = ExternModule::ExtHtmlReady($temp['title_front']);
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['TITLEREAR'] = ExternModule::ExtHtmlReady($temp['title_rear']);
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['USERNAME'] = $temp['username'];
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['PERSONDETAIL-HREF'] = $this->elements['LinkInternPersondetails']->createUrl(['link_args' => 'username=' . $temp['username']]);
-                }
-                $i++;
-            }
-        }
-        return $content;
-    }
-
-    function getStudipData () {
-        $query = "SELECT i.Institut_id, i.Name, i.url FROM seminare LEFT JOIN Institute i USING(institut_id) WHERE Seminar_id = ?";
-        $parameters = [$this->seminar_id];
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-        $row = $statement->fetch(PDO::FETCH_ASSOC);
-        $own_inst = $row['Institut_id'];
-        $content['STUDIP-DATA']['HOME-INST-NAME'] = ExternModule::ExtHtmlReady($row['Name']);
-
-        if ($row['url']) {
-            $link_inst = htmlReady($row['url']);
-            if (!preg_match('{^https?://.+$}', $link_inst)) {
-                $link_inst = "http://$link_inst";
-            }
-            $content['STUDIP-DATA']['HOME-INST-HREF'] = $link_inst;
-        }
-
-        $query = "SELECT Name, url FROM seminar_inst LEFT JOIN Institute i USING(institut_id) WHERE seminar_id='{$this->seminar_id}' AND i.institut_id!='$own_inst'";
-        $involved_insts = NULL;
-        $i = 0;
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute();
-
-        while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
-            if ($row['url']) {
-                $link_inst = htmlReady($row['url']);
-                if (!preg_match('{^https?://.+$}', $link_inst)) {
-                    $link_inst = "http://$link_inst";
-                }
-                $content['STUDIP-DATA']['INVOLVED-INSTITUES']['INVOLVED-INSTITUTE'][$i]['INVOLVED-INSTITUTE_HREF'] = $link_inst;
-            }
-            $content['STUDIP-DATA']['INVOLVED-INSTITUTES']['INVOLVED-INSTITUTE'][$i]['INVOLVED-INSTITUTE_NAME'] = ExternModule::ExtHtmlReady($row['Name']);
-            $i++;
-        }
-
-        $query = "SELECT count(*) as count_user FROM seminar_user WHERE Seminar_id = ?";
-        $parameters = [$this->seminar_id];
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-        $row = $statement->fetch(PDO::FETCH_ASSOC);
-
-        if ($row['count_user']) {
-            $content['STUDIP-DATA']['COUNT-USER'] = $row['count_user'];
-        } else {
-            $content['STUDIP-DATA']['COUNT-USER'] = '0';
-        }
-
-        $count = 0;
-        foreach (PluginEngine::getPlugins('ForumModule') as $plugin) {
-            $count += $plugin->getNumberOfPostingsForSeminar($this->seminar_id);
-        }
-        $content['STUDIP-DATA']['COUNT-POSTINGS'] = $count;
-
-        $query = "SELECT COUNT(*) AS count_documents
-                  FROM folders
-                  INNER JOIN file_refs ON folder_id = folders.id
-                  WHERE range_id = ? AND range_type = 'course'
-            AND folder_type IN ('RootFolder', 'StandardFolder')
-                  GROUP BY range_id";
-        $parameters = [$this->seminar_id];
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-        $row = $statement->fetch(PDO::FETCH_ASSOC);
-
-        if ($row['count_documents']) {
-            $content['STUDIP-DATA']['COUNT-DOCUMENTS'] = $row['count_documents'];
-        } else {
-            $content['STUDIP-DATA']['COUNT-DOCUMENTS'] = '0';
-        }
-
-        return $this->elements['TemplateStudipData']->toString(['content' => $content, 'subpart' => 'STUDIP-DATA']);
-    }
-
-    function printout ($args) {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateLectureData']->toString(['content' => $this->getContent($args), 'subpart' => 'LECTUREDETAILS']);
-
-    }
-
-    function printoutPreview () {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateLectureData']->toString(['content' => $this->getContent([]), 'subpart' => 'LECTUREDETAILS', 'hide_markers' => FALSE]);
-
-    }
-
-    function addContentStudipInfo (&$content) {
-
-    }
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleTemplateLectures.class.php b/lib/extern/modules/ExternModuleTemplateLectures.class.php
deleted file mode 100644
index 00277ad48fc..00000000000
--- a/lib/extern/modules/ExternModuleTemplateLectures.class.php
+++ /dev/null
@@ -1,575 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleTemplateLectures.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleTemplateLectures
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleTemplateLectures.class.php
-//
-// Copyright (C) 2007 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/dates.inc.php';
-
-
-class ExternModuleTemplateLectures extends ExternModule {
-
-    var $markers = [];
-    var $args = ['seminar_id'];
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-
-        $this->data_fields = ['VeranstaltungsNummer', 'Name', 'Untertitel', 'status', 'Ort',
-            'art', 'zeiten', 'dozent'];
-        $this->registered_elements = [
-                'ReplaceTextSemType',
-                'SelectSubjectAreas',
-                'LinkInternLecturedetails' => 'LinkInternTemplate',
-                'LinkInternPersondetails' => 'LinkInternTemplate',
-                'TemplateGeneric'
-        ];
-        $this->field_names =
-        [
-                _("Veranstaltungsnummer"),
-                _("Name"),
-                _("Untertitel"),
-                _("Status"),
-                _("Ort"),
-                _("Art"),
-                _("Zeiten"),
-                _("Lehrende")
-        ];
-
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    function setup () {
-        // extend $data_fields if generic datafields are set
-    //  $config_datafields = $this->config->getValue("Main", "genericdatafields");
-    //  $this->data_fields = array_merge((array)$this->data_fields, (array)$config_datafields);
-
-        // setup module properties
-    //  $this->elements["LinkIntern"]->link_module_type = 2;
-    //  $this->elements["LinkIntern"]->real_name = _("Link zum Modul MitarbeiterInnendetails");
-
-        $this->elements['LinkInternLecturedetails']->real_name = _("Link zum Modul Veranstaltungsdetails");
-        $this->elements['LinkInternLecturedetails']->link_module_type = [4, 13];
-        $this->elements['LinkInternPersondetails']->real_name = _("Verlinkung zum Modul MitarbeiterInnendetails");
-        $this->elements['LinkInternPersondetails']->link_module_type = [2, 14];
-        $this->elements['TemplateGeneric']->real_name = _("Template");
-        $this->elements['TemplateGeneric']->link_module_type = 2;
-
-    }
-
-    function toStringEdit ($open_elements = '', $post_vars = '',
-            $faulty_values = '', $anker = '') {
-
-        $this->updateGenericDatafields('TemplateGeneric', 'sem');
-        $this->elements['TemplateGeneric']->markers = $this->getMarkerDescription('TemplateGeneric');
-
-        return parent::toStringEdit($open_elements, $post_vars, $faulty_values, $anker);
-    }
-
-    function getMarkerDescription ($element_name) {
-        $markers['TemplateGeneric'][] = ['__GLOBAL__', _("Globale Variablen (gültig im gesamten Template).")];
-        $markers['TemplateGeneric'][] = ['###LECTURES-COUNT###', ''];
-        $markers['TemplateGeneric'][] = ['###LECTURES-SUBSTITUTE-GROUPED-BY###', ''];
-        $markers['TemplateGeneric'][] = ['###START_SEMESTER###', _('Name des Startsemesters')];
-
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN LECTURES -->', ''];
-
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN NO-LECTURES -->', ''];
-        $markers['TemplateGeneric'][] = ['###NO-LECTURES-TEXT###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END NO-LECTURES -->', ''];
-
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN GROUP -->', ''];
-        $markers['TemplateGeneric'][] = ['###GROUP###', ''];
-        $markers['TemplateGeneric'][] = ['###GROUP-NO###', ''];
-
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN LECTURE -->', ''];
-        $markers['TemplateGeneric'][] = ['###TITLE###', ''];
-        $markers['TemplateGeneric'][] = ['###LECTUREDETAILS-HREF###', ''];
-        $markers['TemplateGeneric'][] = ['###SUBTITLE###', ''];
-        $markers['TemplateGeneric'][] = ['###NUMBER###', _("Die Veranstaltungsnummer")];
-
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN LECTURERS -->', ''];
-        $markers['TemplateGeneric'][] = ['###FULLNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###LASTNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###FIRSTNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###TITLEFRONT###', ''];
-        $markers['TemplateGeneric'][] = ['###TITLEREAR###', ''];
-        $markers['TemplateGeneric'][] = ['###PERSONDETAIL-HREF###', ''];
-        $markers['TemplateGeneric'][] = ['###LECTURER-NO###', ''];
-        $markers['TemplateGeneric'][] = ['###UNAME###', _("Stud.IP-Username")];
-        $markers['TemplateGeneric'][] = ['<!-- END LECTURERS -->', ''];
-
-        $markers['TemplateGeneric'][] = ['###ROOM###', ''];
-        $markers['TemplateGeneric'][] = ['###FORM###', _("Die Veranstaltungsart")];
-        $markers['TemplateGeneric'][] = ['###SEMTYPE###', ''];
-        $markers['TemplateGeneric'][] = ['###SEMTYPE-SUBSTITUTE###', ''];
-        $markers['TemplateGeneric'][] = ['###SEMESTER###', ''];
-        $markers['TemplateGeneric'][] = ['###CYCLE###', ''];
-        $this->insertDatafieldMarkers('sem', $markers, 'TemplateGeneric');
-
-        $markers['TemplateGeneric'][] = ['<!-- END LECTURE -->', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END GROUP -->', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END LECTURES -->', ''];
-
-        return $markers[$element_name];
-    }
-
-    function getContent ($args = NULL, $raw = FALSE) {
-
-        $start_item_id = get_start_item_id($this->config->range_id);
-        $browser = new ExternSemBrowseTemplate($this, $start_item_id);
-
-        return $browser->getContent();
-    }
-
-    function printout ($args) {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        ob_start();
-        echo $this->elements['TemplateGeneric']->toString(['content' => $this->getContent(), 'subpart' => 'LECTURES']);
-        ob_end_flush();
-
-    }
-
-    function printoutPreview () {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateGeneric']->toString(['content' => $this->getContent(), 'subpart' => 'LECTURES', 'hide_markers' => FALSE]);
-
-    }
-
-}
-
-
-
-class ExternSemBrowseTemplate extends SemBrowse {
-
-    var $module;
-    var $sem_types_position;
-    var $sem_dates;
-    var $start_sem;
-
-    function __construct(&$module, $start_item_id) {
-
-        global $SEM_TYPE,$SEM_CLASS;
-        $all_semester = Semester::findAllVisible(false);
-        array_unshift($all_semester, 0);
-
-        $this->group_by_fields = [ ['name' => _("Semester"), 'group_field' => 'sem_number'],
-                                        ['name' => _("Bereich"), 'group_field' => 'bereich'],
-                                        ['name' => _("Lehrende"), 'group_field' => 'fullname', 'unique_field' => 'username'],
-                                        ['name' => _("Typ"), 'group_field' => 'status'],
-                                        ['name' => _("Einrichtung"), 'group_field' => 'Institut', 'unique_field' => 'Institut_id']];
-
-        $this->module = $module;
-        $this->sem_browse_data["group_by"] = $this->module->config->getValue("Main", "grouping");
-        $this->sem_dates = $all_semester;
-        $this->sem_dates[0] = ["name" => _("abgelaufene Semester")];
-
-        // reorganize the $SEM_TYPE-array
-        foreach ($SEM_CLASS as $key_class => $class) {
-            $i = 0;
-            foreach ($SEM_TYPE as $key_type => $type) {
-                if ($type["class"] == $key_class) {
-                    $i++;
-                    $this->sem_types_position[$key_type] = $i;
-                }
-            }
-        }
-
-        // Is a semester switch defined?
-        $week_offset = $this->module->config->getValue("Main", "semswitch");
-        if (ctype_digit($week_offset)) {
-            $switch_time = strtotime("+{$week_offset} weeks 0:00:00");
-        } else {
-            $switch_time = strtotime('0:00:00');
-        }
-
-        // get current semester
-        $current_sem = get_sem_num($switch_time) + 1;
-
-        switch ($this->module->config->getValue("Main", "semstart")) {
-            case "previous" :
-                if (isset($all_semester[$current_sem - 1])) {
-                    $current_sem--;
-                }
-                break;
-            case "next" :
-                if (isset($all_semester[$current_sem + 1])) {
-                    $current_sem++;
-                }
-                break;
-            case "current" :
-                break;
-            default :
-                if (isset($all_semester[$this->module->config->getValue('Main', 'semstart')])) {
-                    $current_sem = $this->module->config->getValue('Main', 'semstart');
-                }
-        }
-
-        $last_sem = $current_sem + $this->module->config->getValue('Main', 'semrange');
-        if ($last_sem < $current_sem)
-            $last_sem = $current_sem;
-        if (!isset($all_semester[$last_sem]))
-            $last_sem = sizeof($all_semester);
-
-        for (;$last_sem > $current_sem; $last_sem--)
-            $this->sem_number[] = $last_sem - 1;
-
-        $this->start_sem = $current_sem;
-
-        $semclasses = $this->module->config->getValue('Main', 'semclasses');
-        foreach ($SEM_TYPE as $key => $type) {
-            if (in_array($type['class'], (array) $semclasses))
-                $this->sem_browse_data['sem_status'][] = $key;
-        }
-
-        $this->get_sem_range_tree($start_item_id, true);
-    }
-
-    function getContent () {
-        global $SEM_TYPE, $SEM_CLASS, $sem_type_tmp;
-
-        if (is_array($this->sem_browse_data['search_result']) && count($this->sem_browse_data['search_result'])) {
-
-            // show only selected subject areas
-            $selected_ranges = (array) $this->module->config->getValue('SelectSubjectAreas', 'subjectareasselected');
-            $selected_ranges[] = $this->sem_browse_data['start_item_id'];
-            if (!$this->module->config->getValue('SelectSubjectAreas', 'selectallsubjectareas')
-                    && count($selected_ranges)) {
-                if ($this->module->config->getValue('SelectSubjectAreas', 'reverseselection')) {
-                    $sem_range_query =  "AND seminar_sem_tree.sem_tree_id NOT IN ('".implode("','", $selected_ranges)."')";
-                } else {
-                    $sem_range_query =  "AND seminar_sem_tree.sem_tree_id IN ('".implode("','", $selected_ranges)."')";
-                }
-            } else {
-                $sem_range_query = '';
-            }
-
-            // show only selected SemTypes
-            $selected_semtypes = $this->module->config->getValue('ReplaceTextSemType', 'visibility');
-            $sem_types_array = [];
-            if (count($selected_semtypes)) {
-                foreach ($selected_semtypes as $i => $active) {
-                    if ($active == '1') {
-                        $sem_types_array[] = $i + 1;
-                    }
-                }
-                $sem_types_query = "AND seminare.status IN ('" . implode("','", $sem_types_array) . "')";
-            } else {
-                $sem_types_query = '';
-            }
-
-            // number of visible columns
-            $group_colspan = array_count_values((array) $this->module->config->getValue("Main", "visible"));
-
-            if ($this->sem_browse_data['group_by'] == 1){
-                if (!is_object($this->sem_tree)){
-                    $the_tree = TreeAbstract::GetInstance("StudipSemTree");
-                } else {
-                    $the_tree =& $this->sem_tree->tree;
-                }
-            $the_tree->buildIndex();
-            }
-
-            if (!$this->module->config->getValue("Main", "allseminars")){
-                $sem_inst_query = " AND seminare.Institut_id='{$this->module->config->range_id}' ";
-            }
-            if (!$nameformat = $this->module->config->getValue("Main", "nameformat"))
-                $nameformat = "no_title_short";
-
-            $dbv = DbView::getView('sem_tree');
-
-            $query = "SELECT seminare.Seminar_id, seminare.Name, seminare.Untertitel, seminare.VeranstaltungsNummer, seminare.status, seminare.art
-                , Institute.Name AS Institut,Institute.Institut_id,
-                seminar_sem_tree.sem_tree_id AS bereich, " . $GLOBALS['_fullname_sql'][$nameformat] ." AS fullname, auth_user_md5.username, Vorname, Nachname, title_front, title_rear,
-                " . $dbv->sem_number_sql . " AS sem_number, " . $dbv->sem_number_end_sql . " AS sem_number_end,
-                seminar_user.position AS position FROM seminare
-                LEFT JOIN seminar_user ON (seminare.Seminar_id=seminar_user.Seminar_id AND seminar_user.status='dozent')
-                LEFT JOIN auth_user_md5 USING (user_id)
-                LEFT JOIN user_info USING (user_id)
-                LEFT JOIN seminar_sem_tree ON (seminare.Seminar_id = seminar_sem_tree.seminar_id)
-                LEFT JOIN seminar_inst ON (seminare.Seminar_id = seminar_inst.Seminar_id)
-                LEFT JOIN Institute ON (seminar_inst.institut_id = Institute.Institut_id)
-                WHERE seminare.Seminar_id IN('" . join("','", array_keys($this->sem_browse_data['search_result']))
-                 . "') $sem_inst_query $sem_range_query $sem_types_query";
-
-            $db = new DB_Seminar($query);
-            $snap = new DbSnapshot($db);
-            $group_field = $this->group_by_fields[$this->sem_browse_data['group_by']]['group_field'];
-            $data_fields[0] = "Seminar_id";
-            if ($this->group_by_fields[$this->sem_browse_data['group_by']]['unique_field']){
-                $data_fields[1] = $this->group_by_fields[$this->sem_browse_data['group_by']]['unique_field'];
-            }
-            $group_by_data = $snap->getGroupedResult($group_field, $data_fields);
-            $sem_data = $snap->getGroupedResult("Seminar_id");
-            if ($this->sem_browse_data['group_by'] == 0){
-                $group_by_duration = $snap->getGroupedResult("sem_number_end", ["sem_number","Seminar_id"]);
-                foreach ($group_by_duration as $sem_number_end => $detail){
-                    if ($sem_number_end != -1 && ($detail['sem_number'][$sem_number_end - 1] && count($detail['sem_number']) == 1)){
-                        continue;
-                    } else {
-                        foreach ($detail['Seminar_id'] as $seminar_id => $foo){
-                            $start_sem = key($sem_data[$seminar_id]["sem_number"]);
-                            if ($sem_number_end == -1){
-                                if (is_array($this->sem_number)){
-                                    $sem_number_end = $this->sem_number[0];
-                                } else {
-                                    $sem_number_end = count($this->sem_dates)-1;
-                                }
-                            }
-                            for ($i = $start_sem; $i <= $sem_number_end; ++$i){
-                                if ($this->sem_number === false || (is_array($this->sem_number) && in_array($i,$this->sem_number))){
-                                    if ($group_by_data[$i] && !$tmp_group_by_data[$i]){
-                                        foreach($group_by_data[$i]['Seminar_id'] as $id => $bar){
-                                            $tmp_group_by_data[$i]['Seminar_id'][$id] = true;
-                                        }
-                                    }
-                                    $tmp_group_by_data[$i]['Seminar_id'][$seminar_id] = true;
-                                }
-                            }
-                        }
-                    }
-                }
-                if (is_array($tmp_group_by_data)){
-                    if ($this->sem_number !== false){
-                        unset($group_by_data);
-                    }
-                    foreach ($tmp_group_by_data as $start_sem => $detail){
-                        $group_by_data[$start_sem] = $detail;
-                    }
-                }
-            }
-
-            foreach ($group_by_data as $group_field => $sem_ids){
-                foreach ($sem_ids['Seminar_id'] as $seminar_id => $foo){
-                    $name = mb_strtolower(key($sem_data[$seminar_id]["Name"]));
-                    $name = str_replace("ä","ae",$name);
-                    $name = str_replace("ö","oe",$name);
-                    $name = str_replace("ü","ue",$name);
-                    $group_by_data[$group_field]['Seminar_id'][$seminar_id] = $name;
-                }
-                uasort($group_by_data[$group_field]['Seminar_id'], 'strnatcmp');
-            }
-
-            switch ($this->sem_browse_data["group_by"]){
-                case 0:
-                    krsort($group_by_data, SORT_NUMERIC);
-                    break;
-
-                case 1:
-                    uksort($group_by_data, function ($a, $b) {
-                        $the_tree = TreeAbstract::GetInstance('StudipSemTree', false);
-                        return $the_tree->tree_data[$a]['index'] - $the_tree->tree_data[$b]['index'];
-                    });
-                    break;
-
-                case 3:
-                    if ($order = $this->module->config->getValue("ReplaceTextSemType", "order")) {
-                        foreach ((array) $order as $position) {
-                            if (isset($group_by_data[$position]))
-                                $group_by_data_tmp[$position] = $group_by_data[$position];
-                        }
-                        $group_by_data = $group_by_data_tmp;
-                        unset($group_by_data_tmp);
-                    }
-                    else {
-                        uksort($group_by_data, function ($a, $b) {
-                            global $SEM_CLASS,$SEM_TYPE;
-                            return strnatcasecmp(
-                                $SEM_TYPE[$a]['name'] . ' (' . $SEM_CLASS[$SEM_TYPE[$a]['class']]['name'] . ')',
-                                $SEM_TYPE[$b]['name'] . ' (' . $SEM_CLASS[$SEM_TYPE[$b]['class']]['name'] . ')'
-                            );
-                        });
-                    }
-                    break;
-
-                default:
-                    uksort($group_by_data, 'strnatcasecmp');
-                    break;
-
-            }
-
-            // generic datafields
-            $generic_datafields = $this->module->config->getValue("TemplateGeneric", "genericdatafields");
-
-            $content['__GLOBAL__']['LECTURES-COUNT'] = count($sem_data);
-            $group_by_name = $this->module->config->getValue("Main", "aliasesgrouping");
-            $content['__GLOBAL__']['LECTURES-SUBSTITUTE-GROUPED-BY'] = $group_by_name[$this->sem_browse_data['group_by']];
-            $content['__GLOBAL__']['START_SEMESTER'] = ExternModule::ExtHtmlReady($this->sem_dates[$this->start_sem]['name']);
-
-            $i = 0;
-            foreach ((array) $group_by_data as $group_field => $sem_ids) {
-                $content['LECTURES']['GROUP'][$i]['GROUP'] = $this->getGroupContent($the_tree, $group_field);
-                $content['LECTURES']['GROUP'][$i]['GROUP-NO'] = $i + 1;
-
-                if (is_array($sem_ids['Seminar_id'])) {
-                    $j = 0;
-                    foreach(array_keys($sem_ids['Seminar_id']) as $seminar_id) {
-                        $sem_object = Seminar::GetInstance($seminar_id);
-                        $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['TITLE'] = ExternModule::ExtHtmlReady($sem_object->name);
-
-                        $sem_number_start = key($sem_data[$seminar_id]['sem_number']);
-                        $sem_number_end = key($sem_data[$seminar_id]['sem_number_end']);
-                        $sem_semester = $this->sem_dates[$sem_number_start]['name'];
-                        if ($sem_number_start != $sem_number_end){
-                            $sem_semester .= ' - ' . ($sem_number_end == -1 ? _("unbegrenzt") : $this->sem_dates[$sem_number_end]['name']);
-                        }
-
-                        $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['SEMESTER'] = $sem_semester;
-
-                        // create turnus field
-                        $sem_turnus = $sem_object->getDatesExport(['show_room' => true]);
-
-                        $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['CYCLE'] = ExternModule::ExtHtmlReady($sem_turnus);
-
-                        $doz_name = array_keys($sem_data[$seminar_id]['fullname']);
-                        $doz_lastname = array_keys($sem_data[$seminar_id]['Nachname']);
-                        $doz_firstname = array_keys($sem_data[$seminar_id]['Vorname']);
-                        $doz_titlefront = array_keys($sem_data[$seminar_id]['title_front']);
-                        $doz_titlerear = array_keys($sem_data[$seminar_id]['title_rear']);
-                        $doz_uname = array_keys($sem_data[$seminar_id]['username']);
-                        $doz_position = array_keys($sem_data[$seminar_id]['position']);
-                        if (sizeof($doz_position) < sizeof($doz_name)) {
-                            $doz_position = array_fill(0, sizeof($doz_name), 0);
-                        }
-                        if (is_array($doz_name)){
-                            array_multisort($doz_position, $doz_name, $doz_uname);
-                            $k = 0;
-                            foreach ($doz_name as $index => $value) {
-                                $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['LECTURERS'][$k]['PERSONDETAIL-HREF'] = $this->module->elements['LinkInternPersondetails']->createUrl(['link_args' => 'username=' . $doz_uname[$index]]);
-                                $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['LECTURERS'][$k]['FULLNAME'] = ExternModule::ExtHtmlReady($doz_name[$index]);
-                                $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['LECTURERS'][$k]['LASTNAME'] = ExternModule::ExtHtmlReady($doz_lastname[$index]);
-                                $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['LECTURERS'][$k]['FIRSTNAME'] = ExternModule::ExtHtmlReady($doz_firstname[$index]);
-                                $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['LECTURERS'][$k]['TITLEFRONT'] = ExternModule::ExtHtmlReady($doz_titlefront[$index]);
-                                $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['LECTURERS'][$k]['TITLEREAR'] = ExternModule::ExtHtmlReady($doz_titlerear[$index]);
-                                $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['LECTURERS'][$k]['UNAME'] = $doz_uname[$index];
-                                $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['LECTURERS'][$k]['LECTURER-NO'] = $k + 1;
-                                $k++;
-                            }
-                        }
-
-                        $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['LECTUREDETAILS-HREF'] = $this->module->elements['LinkInternLecturedetails']->createUrl(['link_args' => 'seminar_id=' . $seminar_id]);
-                        $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['NUMBER'] = ExternModule::ExtHtmlReady(key($sem_data[$seminar_id]['VeranstaltungsNummer']));
-                        $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['SUBTITLE'] = ExternModule::ExtHtmlReady($sem_object->untertitel);
-                        $aliases_sem_type = $this->module->config->getValue('ReplaceTextSemType', 'class_' . $SEM_TYPE[key($sem_data[$seminar_id]['status'])]['class']);
-                        $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['SEMTYPE-SUBSTITUTE'] = $aliases_sem_type[$this->sem_types_position[key($sem_data[$seminar_id]['status'])] - 1];
-                        $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['SEMTYPE'] = ExternModule::ExtHtmlReady($SEM_TYPE[key($sem_data[$seminar_id]['status'])]['name']
-                                    .' ('. $SEM_CLASS[$SEM_TYPE[key($sem_data[$seminar_id]['status'])]['class']]['name'] . ')');
-                        $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['ROOM'] = ExternModule::ExtHtmlReady(Seminar::getInstance($seminar_id)->getDatesTemplate('dates/seminar_export_location'));
-                        $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['FORM'] = ExternModule::ExtHtmlReady($sem_object->art);
-
-                        // generic data fields
-                        if (is_array($generic_datafields)) {
-                            $localEntries = DataFieldEntry::getDataFieldEntries($seminar_id, 'sem');
-                            #$datafields = $datafields_obj->getLocalFields($seminar_id);
-                            $l = 1;
-                            foreach ($generic_datafields as $datafield) {
-                                if (isset($localEntries[$datafield]) && is_object($localEntries[$datafield])) {
-                                    $localEntry = $localEntries[$datafield]->getDisplayValue();
-                                    if ($localEntry) {
-                                        $content['LECTURES']['GROUP'][$i]['LECTURE'][$j]['DATAFIELD_' . $l] = $localEntry;
-                                    }
-                                }
-                                $l++;
-                            }
-
-                        }
-
-                        $j++;
-                    }
-                }
-                $i++;
-            }
-        } else {
-            $content['__GLOBAL__']['LECTURES-COUNT'] = 0;
-            $group_by_name = $this->module->config->getValue('Main', 'aliasesgrouping');
-            $content['__GLOBAL__']['LECTURES-SUBSTITUTE-GROUPED-BY'] = $group_by_name[$this->sem_browse_data['group_by']];
-            $content['LECTURES']['NO-LECTURES']['NO-LECTURES-TEXT'] = ExternModule::ExtHtmlReady($this->module->config->getValue('Main', 'nodatatext'));
-        }
-        return $content;
-
-    }
-
-    // private
-    function getGroupContent ($the_tree, $group_field) {
-        global $SEM_TYPE, $SEM_CLASS;
-
-        switch ($this->sem_browse_data['group_by']){
-            case 0:
-                $content = $this->sem_dates[$group_field]['name'];
-                break;
-
-            case 1:
-                if ($the_tree->tree_data[$group_field]) {
-                    $range_path_level = $this->module->config->getValue('Main', 'rangepathlevel');
-                    $content = htmlReady($the_tree->getShortPath($group_field, NULL, '>', $range_path_level ? $range_path_level - 1 : 0));
-                } else {
-                    $content = $this->module->config->getValue('Main', 'textnogroups');
-                }
-                break;
-
-            case 2:
-                $content = htmlReady($group_field);
-                break;
-
-            case 3:
-                $aliases_sem_type = $this->module->config->getValue('ReplaceTextSemType', "class_{$SEM_TYPE[$group_field]['class']}");
-                if ($aliases_sem_type[$this->sem_types_position[$group_field] - 1]) {
-                    $content = $aliases_sem_type[$this->sem_types_position[$group_field] - 1];
-                } else {
-                    $content = htmlReady($GLOBALS['SEM_TYPE'][$group_field]['name'] . ' (' . $SEM_CLASS[$SEM_TYPE[$group_field]['class']]['name'] . ')');
-                }
-                break;
-            case 4:
-                $content = htmlReady($group_field);
-                break;
-
-        }
-
-        return $content;
-    }
-
-}
-?>
diff --git a/lib/extern/modules/ExternModuleTemplateNews.class.php b/lib/extern/modules/ExternModuleTemplateNews.class.php
deleted file mode 100644
index aad057938a9..00000000000
--- a/lib/extern/modules/ExternModuleTemplateNews.class.php
+++ /dev/null
@@ -1,278 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter003: TEST
-# Lifter007: TODO
-# Lifter010: TODO
-/**
-* ExternModuleTemplateNews.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleTemplateNews
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleTemplateNews.class.php
-//
-// Copyright (C) 2007 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/user_visible.inc.php';
-require_once 'lib/statusgruppe.inc.php';
-
-
-class ExternModuleTemplateNews extends ExternModule {
-
-    var $markers = [];
-    var $args = ['seminar_id'];
-
-    /**
-    *
-    */
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-
-        $this->data_fields = [];
-        $this->registered_elements = [
-                'LinkInternTemplate',
-                'TemplateGeneric'
-        ];
-        $this->field_names = [];
-
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    function setup () {
-        // extend $data_fields if generic datafields are set
-    //  $config_datafields = $this->config->getValue("Main", "genericdatafields");
-    //  $this->data_fields = array_merge((array)$this->data_fields, (array)$config_datafields);
-
-        // setup module properties
-    //  $this->elements["LinkIntern"]->link_module_type = 2;
-    //  $this->elements["LinkIntern"]->real_name = _("Link zum Modul MitarbeiterInnendetails");
-
-        $this->elements['TemplateGeneric']->real_name = _("Template");
-        // Set internal link to module 'staff details'
-        $this->elements['LinkInternTemplate']->link_module_type = [2, 14];
-        $this->elements['LinkInternTemplate']->real_name = _("Verlinkung zum Modul MitarbeiterInnendetails");
-
-    }
-
-    function toStringEdit ($open_elements = '', $post_vars = '',
-            $faulty_values = '', $anker = '') {
-
-        $this->elements['TemplateGeneric']->markers = $this->getMarkerDescription('TemplateGeneric');
-
-        return parent::toStringEdit($open_elements, $post_vars, $faulty_values, $anker);
-    }
-
-    function getMarkerDescription ($element_name) {
-        $markers['TemplateGeneric'][] = ['__GLOBAL__', ''];
-        $markers['TemplateGeneric'][] = ['###STUDIP-LINK###',''];
-        $markers['TemplateGeneric'][] = ['###NEWS-COUNT###', _('Anzahl aller sichtbaren News')];
-        $markers['TemplateGeneric'][] = ['###ARCHIV-NEWS-COUNT###', _('Anzahl aller archivierten News')];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN NEWS -->', ''];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN NO-NEWS -->', ''];
-        $markers['TemplateGeneric'][] = ['###NO-NEWS_TEXT###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END NO-NEWS -->', ''];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN ALL-NEWS -->', _('Alle sichtbaren News')];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN SINGLE-NEWS -->', ''];
-        $markers['TemplateGeneric'][] = ['###NEWS_DATE###', ''];
-        $markers['TemplateGeneric'][] = ['###NEWS_TOPIC###', ''];
-        $markers['TemplateGeneric'][] = ['###NEWS_BODY###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN NEWS_ADMIN-MESSAGE -->', ''];
-        $markers['TemplateGeneric'][] = ['###NEWS_ADMIN-MESSAGE###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END NEWS_ADMIN-MESSAGE -->', ''];
-        $markers['TemplateGeneric'][] = ['###NEWS_NO###', ''];
-        $markers['TemplateGeneric'][] = ['###FULLNAME###', _("Vollständiger Name des Autors.")];
-        $markers['TemplateGeneric'][] = ['###LASTNAME###', _("Nachname des Autors.")];
-        $markers['TemplateGeneric'][] = ['###FIRSTNAME###', _("Vorname des Autors.")];
-        $markers['TemplateGeneric'][] = ['###TITLEFRONT###', _("Titel des Autors (vorangestellt).")];
-        $markers['TemplateGeneric'][] = ['###TITLEREAR###', _("Titel des Autors (nachgestellt).")];
-        $markers['TemplateGeneric'][] = ['###PERSONDETAIL-HREF###', ''];
-        $markers['TemplateGeneric'][] = ['###USERNAME###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END SINGLE-NEWS -->', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END ALL-NEWS -->', _('Ende aller sichtbaren News')];
-
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN ALL-ARCHIV-NEWS -->', _('Alle archivierten News')];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN SINGLE-ARCHIVE-NEWS -->', ''];
-        $markers['TemplateGeneric'][] = ['###ARCHIV_NEWS_DATE###', ''];
-        $markers['TemplateGeneric'][] = ['###ARCHIV_NEWS_TOPIC###', ''];
-        $markers['TemplateGeneric'][] = ['###ARCHIV_NEWS_BODY###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN ARCHIV-NEWS-ADMIN-MESSAGE -->', ''];
-        $markers['TemplateGeneric'][] = ['###ARCHIV-NEWS_ADMIN-MESSAGE###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END ARCHIV-NEWS-ADMIN-MESSAGE -->', ''];
-        $markers['TemplateGeneric'][] = ['###ARCHIV_NEWS_NO###', ''];
-        $markers['TemplateGeneric'][] = ['###ARCHIV_FULLNAME###', _("Vollständiger Name des Autors.")];
-        $markers['TemplateGeneric'][] = ['###ARCHIV_LASTNAME###', _("Nachname des Autors.")];
-        $markers['TemplateGeneric'][] = ['###ARCHIV_FIRSTNAME###', _("Vorname des Autors.")];
-        $markers['TemplateGeneric'][] = ['###ARCHIV_TITLEFRONT###', _("Titel des Autors (vorangestellt).")];
-        $markers['TemplateGeneric'][] = ['###ARCHIV_TITLEREAR###', _("Titel des Autors (nachgestellt).")];
-        $markers['TemplateGeneric'][] = ['###ARCHIV_PERSONDETAIL-HREF###', ''];
-        $markers['TemplateGeneric'][] = ['###ARCHIV_USERNAME###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END SINGLE-ARCHIVE-NEWS -->', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END ALL-ARCHIV-NEWS -->', _('Ende aller archivierten News')];
-        $markers['TemplateGeneric'][] = ['<!-- END NEWS -->', ''];
-
-        return $markers[$element_name];
-    }
-
-    function getContent ($args = NULL, $raw = FALSE)
-    {
-        $content = [];
-        $error_message = "";
-
-        // stimmt die übergebene range_id?
-        $query = "SELECT 1 FROM Institute WHERE Institut_id = ?";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$this->config->range_id]);
-        if (!$statement->fetchColumn()) {
-            $error_message = $GLOBALS['EXTERN_ERROR_MESSAGE'];
-        }
-
-        $local_fullname_sql = $GLOBALS['_fullname_sql'];
-        if (!$nameformat = $this->config->getValue('Main', 'nameformat')) {
-            $nameformat = 'no_title';
-        }
-        if ($nameformat == 'last') $local_fullname_sql['last'] = ' Nachname ';
-
-        $news = StudipNews::GetNewsByRange($this->config->range_id, false, true);
-        if (!count($news)) {
-            $content['NEWS']['NO-NEWS']['NO-NEWS_TEXT'] = $this->config->getValue('Main', "nodatatext");
-        }
-
-        $studip_link = URLHelper::getLink('dispatch.php/institute/overview?again=yes&cid='. $this->config->range_id);
-        $content['__GLOBAL__']['STUDIP-LINK'] = $studip_link;
-
-        $dateform = $this->config->getValue("Main", "dateformat");
-        $show_date_author = $this->config->getValue("Main", "showdateauthor");
-        $i = 1;
-        $j = 1;
-        $now = time();
-        foreach ($news as $news_id => $news_detail) {
-            //aktuelle News ausgeben
-            if ($news_detail->date < $now && $news_detail->date + $news_detail->expire > $now) {
-                if ($news_detail->chdate_uid){
-                    $admin_msg = StudipNews::GetAdminMsg($news_detail->chdate_uid, $news_detail->chdate);
-                }
-                if ($admin_msg) {
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_ADMIN-MESSAGE'] = preg_replace('# \(?(.*)\)?#', '$1', $admin_msg);
-                }
-
-                if (!(string) $news_detail->body) {
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_BODY'] = _('Keine Beschreibung vorhanden.');
-                } else {
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_BODY'] =  ExternModule::ExtFormatReady((string) $news_detail->body);
-                }
-
-                $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_DATE'] = strftime($dateform, $news_detail->date);
-                $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_TOPIC'] = ExternModule::ExtHtmlReady((string) $news_detail->topic);
-                $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_NO'] = $i;
-
-                $query = "SELECT Nachname, Vorname, title_front, title_rear,
-                                 {$local_fullname_sql[$nameformat]} AS fullname, username,
-                                 aum.user_id
-                          FROM auth_user_md5 AS aum
-                          LEFT JOIN user_info AS ui USING (user_id)
-                          WHERE aum.user_id = ?";
-                $statement = DBManager::get()->prepare($query);
-                $statement->execute([$news_detail->user_id]);
-                $temp = $statement->fetch(PDO::FETCH_ASSOC);
-                if ($temp) {
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['FULLNAME'] = ExternModule::ExtHtmlReady($temp['fullname']);
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['FIRSTNAME'] = ExternModule::ExtHtmlReady($temp['Vorname']);
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['LASTNAME'] = ExternModule::ExtHtmlReady($temp['Nachname']);
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['TITLEFRONT'] = ExternModule::ExtHtmlReady($temp['title_front']);
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['TITLEREAR'] = ExternModule::ExtHtmlReady($temp['title_rear']);
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['USERNAME'] = $temp['username'];
-                    $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['PERSONDETAIL-HREF'] = $this->elements['LinkInternTemplate']->createUrl(['link_args' => 'username=' . $temp['username']]);
-                }
-                $i++;
-
-            } else if ($news_detail->date < $now) {
-                //archivierte News ausgeben
-                if ($news_detail->chdate_uid){
-                    $admin_msg = StudipNews::GetAdminMsg($news_detail->chdate_uid, $news_detail->chdate);
-                }
-                if ($admin_msg) {
-                    $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_NEWS_ADMIN-MESSAGE'] = preg_replace('# \(?(.*)\)?#', '$1', $admin_msg);
-                }
-
-                if (!(string) $news_detail->body) {
-                    $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_NEWS_BODY'] = _("Keine Beschreibung vorhanden.");
-                } else {
-                    $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_NEWS_BODY'] =  ExternModule::ExtFormatReady((string) $news_detail->body);
-                }
-
-                $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_NEWS_DATE'] = strftime($dateform, $news_detail->date);
-                $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_NEWS_TOPIC'] = ExternModule::ExtHtmlReady((string) $news_detail->topic);
-                $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_NEWS_NO'] = $j;
-
-                $query = "SELECT Nachname, Vorname, title_front, title_rear,
-                                 {$local_fullname_sql[$nameformat]} AS fullname, username,
-                                 aum.user_id
-                          FROM auth_user_md5 AS aum
-                          LEFT JOIN user_info AS ui USING (user_id)
-                          WHERE aum.user_id = ?";
-                $statement = DBManager::get()->prepare($query);
-                $statement->execute([$news_detail['user_id']]);
-                $temp = $statement->fetch(PDO::FETCH_ASSOC);
-                if ($temp) {
-                    $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_FULLNAME'] = ExternModule::ExtHtmlReady($temp['fullname']);
-                    $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_FIRSTNAME'] = ExternModule::ExtHtmlReady($temp['Vorname']);
-                    $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_LASTNAME'] = ExternModule::ExtHtmlReady($temp['Nachname']);
-                    $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_TITLEFRONT'] = ExternModule::ExtHtmlReady($temp['title_front']);
-                    $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_TITLEREAR'] = ExternModule::ExtHtmlReady($temp['title_rear']);
-                    $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_USERNAME'] = $temp['username'];
-                    $content['NEWS']['ALL-ARCHIV-NEWS']['SINGLE-ARCHIVE-NEWS'][$j]['ARCHIV_PERSONDETAIL-HREF'] = $this->elements['LinkInternTemplate']->createUrl(['link_args' => 'username=' . $temp['username']]);
-                }
-                $j++;
-            }
-        }
-        $content['__GLOBAL__']['NEWS-COUNT'] = $i  - 1;
-        $content['__GLOBAL__']['ARCHIV-NEWS-COUNT'] = $j -1;
-        return $content;
-    }
-
-    function printout ($args) {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateGeneric']->toString(['content' => $this->getContent(), 'subpart' => 'NEWS']);
-
-    }
-
-    function printoutPreview () {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateGeneric']->toString(['content' => $this->getContent(), 'subpart' => 'NEWS', 'hide_markers' => FALSE]);
-
-    }
-
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleTemplatePersBrowse.class.php b/lib/extern/modules/ExternModuleTemplatePersBrowse.class.php
deleted file mode 100644
index 9e87647e66f..00000000000
--- a/lib/extern/modules/ExternModuleTemplatePersBrowse.class.php
+++ /dev/null
@@ -1,539 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleTemplatePersBrowser.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleTemplatePersBrowser
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleTemplatePersBrowser.class.php
-//
-// Copyright (C) 2009 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/user_visible.inc.php';
-require_once 'lib/dates.inc.php';
-
-class ExternModuleTemplatePersBrowse extends ExternModule {
-
-    public $markers = [];
-    private $approved_params = [];
-    private $range_tree;
-    private $global_markers = [];
-
-    /**
-    *
-    */
-    public function __construct ($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->data_fields = [
-                'Nachname', 'Telefon', 'raum', 'Email', 'sprechzeiten'
-        ];
-        $this->registered_elements = [
-                'SelectInstitutes',
-                'LinkInternListCharacters' => 'LinkInternTemplate',
-                'LinkInternListInstitutes' => 'LinkInternTemplate',
-                'LinkInternPersondetails' => 'LinkInternTemplate',
-                'TemplateListCharacters' => 'TemplateGeneric',
-                'TemplateListInstitutes' => 'TemplateGeneric',
-                'TemplateListPersons' => 'TemplateGeneric',
-                'TemplateMain' => 'TemplateGeneric'
-        ];
-
-        $this->field_names =
-        [
-                _("Name"),
-                _("Telefon"),
-                _("Raum"),
-                _("E-Mail"),
-                _("Sprechzeiten")
-        ];
-
-        $this->approved_params = ['item_id', 'initiale'];
-
-        $this->range_tree = TreeAbstract::GetInstance('StudipRangeTree');
-
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    public function setup () {
-        $this->elements['LinkInternListCharacters']->real_name = _("Verlinkung der alpabetischen Liste zur Personenliste");
-        $this->elements['LinkInternListCharacters']->link_module_type = [16];
-        $this->elements['LinkInternListInstitutes']->real_name = _("Verlinkung der Einrichtungsliste zur Personenliste");
-        $this->elements['LinkInternListInstitutes']->link_module_type = [16];
-        $this->elements['LinkInternPersondetails']->real_name = _("Verlinkung der Personenliste zum Modul MitarbeiterInnendetails");
-        $this->elements['LinkInternPersondetails']->link_module_type = [2, 14];
-        $this->elements['TemplateMain']->real_name = _("Haupttemplate");
-        $this->elements['TemplateListInstitutes']->real_name = _("Einrichtungsliste");
-        $this->elements['TemplateListPersons']->real_name = _("Personenliste");
-        $this->elements['TemplateListCharacters']->real_name = _("Liste mit Anfangsbuchstaben der Nachnamen");
-
-    }
-
-    public function toStringEdit ($open_elements = '', $post_vars = '', $faulty_values = '', $anker = '') {
-
-        $this->updateGenericDatafields('TemplateListPersons', 'user');
-        $this->elements['TemplateMain']->markers = $this->getMarkerDescription('TemplateMain');
-        $this->elements['TemplateListInstitutes']->markers = $this->getMarkerDescription('TemplateListInstitutes');
-        $this->elements['TemplateListPersons']->markers = $this->getMarkerDescription('TemplateListPersons');
-        $this->elements['TemplateListCharacters']->markers = $this->getMarkerDescription('TemplateListCharacters');
-
-        return parent::toStringEdit($open_elements, $post_vars, $faulty_values, $anker);
-    }
-
-    public function getMarkerDescription ($element_name) {
-
-        $markers['TemplateMain'] = [
-            ['__GLOBAL__', _("Globale Variablen (gültig im gesamten Template).")],
-            ['###CHARACTER###', ''],
-            ['###INSTNAME###', ''],
-            ['<!-- BEGIN PERS_BROWSER -->', ''],
-            ['###LISTCHARACTERS###', _("Auflistung der Anfangsbuchstaben")],
-            ['###LISTINSTITUTES###', _("Auflistung der Einrichtungen")],
-            ['###LISTPERSONS###', _("Auflistung der gefundenen Personen")],
-            ['<!-- END PERS_BROWSER -->', '']
-        ];
-
-        $markers['TemplateListInstitutes'] = [
-            ['<!-- BEGIN LIST_INSTITUTES -->', ''],
-            ['<!-- BEGIN INSTITUTE -->', ''],
-            ['###INSTITUTE_NAME###', _("Name der Einrichtung (erster Level im Einrichtungsbaum)")],
-            ['###INSTITUTE_COUNT_USER###', _("Anzahl der Personen innerhalb der Einrichtung (und untergeordneten Einrichtungen)")],
-            ['###URL_LIST_PERSONS###', _("URL zur Personenlist mit diesem Anfangsbuchstaben")],
-            ['<!-- END INSTITUTE -->', ''],
-            ['<!-- END LIST_INSTITUTES -->', '']
-        ];
-
-        $markers['TemplateListCharacters'] = [
-            ['<!-- BEGIN LIST_CHARACTERS -->', ''],
-            ['<!-- BEGIN CHARACTER -->', ''],
-            ['###CHARACTER_USER###', _("Anfangsbuchstabe der Namen zur Verlinkung nach alpabetische Ãœbersicht")],
-            ['###CHARACTER_COUNT_USER###', _("Anzahl der Personennamen mit diesem Anfangsbuchstaben")],
-            ['###URL_LIST_PERSONS###', _("URL zur Personenlist mit diesem Anfangsbuchstaben")],
-            ['<!-- END CHARACTER -->', ''],
-            ['<!-- END LIST_CHARACTERS -->', '']
-        ];
-
-        $markers['TemplateListPersons'] = [
-            ['<!-- BEGIN LIST_PERSONS -->', ''],
-            ['<!-- BEGIN NO-PERSONS -->', ''],
-            ['<!-- END NO-PERSONS -->', ''],
-            ['<!-- BEGIN PERSONS -->', ''],
-            ['<!-- BEGIN PERSON -->', ''],
-            ['###FULLNAME###', ''],
-            ['###LASTNAME###', ''],
-            ['###FIRSTNAME###', ''],
-            ['###TITLEFRONT###', ''],
-            ['###TITLEREAR###', ''],
-            ['###PERSONDETAIL-HREF###', ''],
-            ['###USERNAME###', ''],
-            ['###INSTNAME###', ''],
-            ['###PHONE###', ''],
-            ['###ROOM###', ''],
-            ['###EMAIL###', ''],
-            ['###EMAIL-LOCAL###', _("Der local-part der E-Mail-Adresse (vor dem @-Zeichen)")],
-            ['###EMAIL-DOMAIN###', _("Der domain-part der E-Mail-Adresse (nach dem @-Zeichen)")],
-            ['###OFFICEHOURS###', ''],
-            ['###PERSON-NO###', ''],
-            $this->insertDatafieldMarkers('user', $markers, 'TemplateList'),
-            ['<!-- END PERSON -->', ''],
-            ['<!-- END PERSONS -->', ''],
-            ['<!-- END LIST_PERSONS -->', '']
-        ];
-
-        return $markers[$element_name];
-    }
-
-    private function getContent ($args = null, $raw = false) {
-        if ($raw) {
-            self::SetRawOutput();
-        }
-
-        if (trim($this->config->getValue('TemplateListInstitutes', 'template'))) {
-            $content['PERS_BROWSER']['LISTINSTITUTES'] = $this->elements['TemplateListInstitutes']->toString(['content' => $this->getContentListInstitutes(), 'subpart' => 'LIST_INSTITUTES']);
-        }
-        if (trim($this->config->getValue('TemplateListCharacters', 'template'))) {
-            $content['PERS_BROWSER']['LISTCHARACTERS'] = $this->elements['TemplateListCharacters']->toString(['content' => $this->getContentListCharacters(), 'subpart' => 'LIST_CHARACTERS']);
-        }
-        if (trim($this->config->getValue('TemplateListPersons', 'template'))) {
-            $content['PERS_BROWSER']['LISTPERSONS'] = $this->elements['TemplateListPersons']->toString(['content' => $this->getContentListPersons(), 'subpart' => 'LIST_PERSONS']);
-        }
-        // set super global markers
-        $content['__GLOBAL__'] = $this->global_markers;
-        return $content;
-    }
-
-    private function getContentListPersons () {
-        if (!$nameformat = $this->config->getValue('Main', 'nameformat')) {
-            $nameformat = 'full_rev';
-        }
-
-        $selected_item_ids = $this->config->getValue('SelectInstitutes', 'institutesselected');
-        // at least one institute has to be selected in the configuration
-        if (!is_array($selected_item_ids)) {
-            return [];
-        }
-
-        $sort = $this->config->getValue('Main', 'sort');
-        $query_order = [];
-        foreach ($sort as $key => $position) {
-            if ($position > 0) {
-                $query_order[$position] = $this->data_fields[$key];
-            }
-        }
-        if (count($query_order)) {
-            ksort($query_order, SORT_NUMERIC);
-            $query_order = ' ORDER BY ' . implode(',', $query_order);
-        } else {
-            $query_order = '';
-        }
-
-        $module_params = $this->getModuleParams($this->approved_params);
-
-        $dbv = DbView::getView('sem_tree');
-        if ($module_params['initiale']) {
-            if ($this->config->getValue('Main', 'onlylecturers')) {
-                $current_semester = get_sem_num(time());
-                $query = sprintf("SELECT ui.Institut_id, su.user_id "
-                . "FROM seminar_user su "
-                . "LEFT JOIN seminare s USING (seminar_id) "
-                . "LEFT JOIN auth_user_md5 aum USING(user_id) "
-                . "LEFT JOIN user_inst ui USING(user_id) "
-                . "WHERE LOWER(LEFT(TRIM(aum.Nachname), 1)) = LOWER('%s') "
-                . "AND su.status = 'dozent' "
-                . "AND s.visible = 1 "
-                . "AND ((%s) = %s OR ((%s) <= %s  AND ((%s) >= %s OR (%s) = -1))) "
-                . "AND ui.Institut_id IN ('%s') "
-                . "AND ui.inst_perms = 'dozent' "
-                . "AND ui.externdefault = 1 "
-                . "AND " . get_ext_vis_query(),
-                mb_substr($module_params['initiale'], 0, 1),
-                $dbv->sem_number_sql,
-                $current_semester,
-                $dbv->sem_number_sql,
-                $current_semester,
-                $dbv->sem_number_end_sql,
-                $current_semester,
-                $dbv->sem_number_end_sql,
-                implode("','", $selected_item_ids));
-            } else {
-                    // get only users with the given status
-                $query = sprintf("SELECT ui.Institut_id, ui.user_id "
-                    . "FROM user_inst ui "
-                    . "LEFT JOIN auth_user_md5 aum USING(user_id) "
-                    . "WHERE LOWER(LEFT(TRIM(aum.Nachname), 1)) = LOWER('%s') "
-                    . "AND ui.inst_perms IN('%s') "
-                    . "AND ui.Institut_id IN ('%s') "
-                    . "AND ui.externdefault = 1 "
-                    . "AND " . get_ext_vis_query(),
-                    mb_substr($module_params['initiale'], 0, 1),
-                    implode("','", $this->config->getValue('Main', 'instperms')),
-                    implode("','", $selected_item_ids));
-            }
-        // item_id is given and it is in the list of item_ids selected in the configuration
-        } else if ($module_params['item_id'] && in_array($module_params['item_id'], $selected_item_ids)) {
-            if ($this->config->getValue('Main', 'onlylecturers')) {
-                $current_semester = get_sem_num(time());
-                // get only users with status dozent in an visible seminar in the current semester
-                $query = sprintf("SELECT ui.Institut_id, ui.user_id "
-                    . "FROM user_inst ui "
-                    . "INNER JOIN auth_user_md5 aum USING (user_id) "
-                    . "LEFT JOIN seminar_user su USING(user_id) "
-                    . "LEFT JOIN seminare s USING (seminar_id) "
-                    . "WHERE ui.Institut_id = '%s' "
-                    . "AND ui.inst_perms = 'dozent' "
-                    . "AND ui.externdefault = 1 "
-                    . "AND " . get_ext_vis_query()
-                    . "AND su.status = 'dozent' "
-                    . "AND s.visible = 1 "
-                    . "AND ((%s) = %s OR ((%s) <= %s  AND ((%s) >= %s OR (%s) = -1))) ",
-                    $module_params['item_id'],
-                    $dbv->sem_number_sql,
-                    $current_semester,
-                    $dbv->sem_number_sql,
-                    $current_semester,
-                    $dbv->sem_number_end_sql,
-                    $current_semester,
-                    $dbv->sem_number_end_sql);
-            } else {
-                // get only users with the given status
-                $query = sprintf("SELECT ui.Institut_id, ui.user_id "
-                    . "FROM user_inst ui "
-                    . "INNER JOIN auth_user_md5 aum USING (user_id) "
-                    . "WHERE ui.Institut_id = '%s' "
-                    . "AND ui.inst_perms IN('%s') "
-                    . "AND ui.externdefault = 1 "
-                    . "AND " . get_ext_vis_query(),
-                    $module_params['item_id'],
-                    implode("','", $this->config->getValue('Main', 'instperms')));
-            }
-        } else {
-            return [];
-        }
-
-        $rows = DBManager::get()->fetchAll($query);
-
-        $user_list = [];
-        foreach ($rows as $row) {
-            if (!isset($user_list[$row['user_id']])) {
-                $user_list[$row['user_id']] = $row['user_id'] . $row['Institut_id'];
-            }
-        }
-
-        if (count($user_list) === 0) {
-            return [];
-        }
-
-        $query = sprintf(
-            "SELECT ui.Institut_id, ui.raum, ui.sprechzeiten, ui.Telefon, "
-            . "inst_perms,  i.Name, aum.Email, aum.user_id, username, "
-            . "%s AS fullname, aum.Nachname, aum.Vorname "
-            . "FROM user_inst ui "
-            . "LEFT JOIN Institute i USING(Institut_id) "
-            . "LEFT JOIN auth_user_md5 aum USING(user_id) "
-            . "LEFT JOIN user_info uin USING(user_id) "
-            . "WHERE CONCAT(ui.user_id, ui.Institut_id) IN ('%s') "
-            . "AND " . get_ext_vis_query()
-            . "ORDER BY aum.Nachname, aum.Vorname ",
-            $GLOBALS['_fullname_sql'][$nameformat],
-            implode("','", $user_list));
-
-        $rows = DBManager::get()->fetchAll($query);
-
-        $j = 0;
-        foreach ($rows as $row) {
-            $content['PERSONS']['PERSON'][$j]['FULLNAME'] = ExternModule::ExtHtmlReady($row['fullname']);
-            $content['PERSONS']['PERSON'][$j]['LASTNAME'] = ExternModule::ExtHtmlReady($row['Nachname']);
-            $content['PERSONS']['PERSON'][$j]['FIRSTNAME'] = ExternModule::ExtHtmlReady($row['Vorname']);
-            $content['PERSONS']['PERSON'][$j]['TITLEFRONT'] = ExternModule::ExtHtmlReady($row['title_front']);
-            $content['PERSONS']['PERSON'][$j]['TITLEREAR'] = ExternModule::ExtHtmlReady($row['title_rear']);
-            $content['PERSONS']['PERSON'][$j]['PERSONDETAIL-HREF'] = $this->elements['LinkInternPersondetails']->createUrl(['link_args' => 'username=' . $row['username']]);
-            $content['PERSONS']['PERSON'][$j]['USERNAME'] = $row['username'];
-            $content['PERSONS']['PERSON'][$j]['INSTNAME'] = ExternModule::ExtHtmlReady($row['Name']);
-            $content['PERSONS']['PERSON'][$j]['PHONE'] = ExternModule::ExtHtmlReady($row['Telefon']);
-            $content['PERSONS']['PERSON'][$j]['ROOM'] = ExternModule::ExtHtmlReady($row['raum']);
-            $content['PERSONS']['PERSON'][$j]['EMAIL'] = ExternModule::ExtHtmlReady(get_visible_email($row['user_id']));
-            $emails = explode('@', $content['PERSONS']['PERSON'][$j]['EMAIL']);
-            $content['PERSONS']['PERSON'][$j]['EMAIL-LOCAL'] = array_shift($emails);
-            $emails = explode('@', $content['PERSONS']['PERSON'][$j]['EMAIL']);
-            $content['PERSONS']['PERSON'][$j]['EMAIL-DOMAIN'] = array_pop($emails);
-            $content['PERSONS']['PERSON'][$j]['OFFICEHOURS'] = ExternModule::ExtHtmlReady($row['sprechzeiten']);
-            $content['PERSONS']['PERSON'][$j]['PERSON-NO'] = $j + 1;
-
-            // generic data fields
-            $generic_datafields = $this->config->getValue('TemplateListPersons', 'genericdatafields');
-
-            if (is_array($generic_datafields)) {
-                $localEntries = DataFieldEntry::getDataFieldEntries($row['user_id'], 'user');
-                $k = 1;
-                foreach ($generic_datafields as $datafield) {
-                    if (isset($localEntries[$datafield]) && is_object($localEntries[$datafield])) {
-                        if ($localEntries[$datafield]->getType() == 'link') {
-                            $localEntry = ExternModule::extHtmlReady($localEntries[$datafield]->getValue());
-                        } else {
-                            $localEntry = $localEntries[$datafield]->getDisplayValue();
-                        }
-                        if ($localEntry) {
-                            $content['PERSONS']['PERSON'][$j]['DATAFIELD_' . $k] = $localEntry;
-                        }
-                    }
-                    $k++;
-                }
-            }
-            $j++;
-        }
-        if (!$module_params['initiale']) {
-            $this->global_markers['INSTNAME'] = $content['PERSONS']['PERSON'][0]['INSTNAME'];
-        } else {
-            $this->global_markers['CHARACTER'] = mb_substr($module_params['initiale'], 0, 1);
-        }
-
-        return $content;
-    }
-
-
-    private function getContentListCharacters () {
-        $selected_item_ids = $this->config->getValue('SelectInstitutes', 'institutesselected');
-        // at least one institute has to be selected in the configuration
-        if (!is_array($selected_item_ids)) {
-            return [];
-        }
-        $content = [];
-
-        // at least one institute has to be selected in the configuration
-        if (!is_array($selected_item_ids)) {
-            return [];
-        }
-        $dbv = DbView::getView('sem_tree');
-        if ($this->config->getValue('Main', 'onlylecturers')) {
-            $current_semester = get_sem_num(time());
-                $query = sprintf("SELECT COUNT(DISTINCT aum.user_id) as count_user, "
-                . "UPPER(LEFT(TRIM(aum.Nachname),1)) AS initiale "
-                . "FROM user_inst ui "
-                . "LEFT JOIN seminar_user su ON ui.user_id = su.user_id "
-                . "LEFT JOIN seminare s ON su.Seminar_id = s.Seminar_id "
-                . "LEFT JOIN auth_user_md5 aum ON su.user_id = aum.user_id "
-                . "WHERE su.status = 'dozent' AND s.visible = 1 "
-                . "AND ((%s) = %s OR ((%s) <= %s  AND ((%s) >= %s OR (%s) = -1))) "
-                . "AND TRIM(aum.Nachname) != '' "
-                . "AND ui.Institut_id IN ('%s') "
-                . "AND ui.externdefault = 1 "
-                . "AND " . get_ext_vis_query()
-                . "GROUP BY initiale",
-                $dbv->sem_number_sql,
-                $current_semester,
-                $dbv->sem_number_sql,
-                $current_semester,
-                $dbv->sem_number_end_sql,
-                $current_semester,
-                $dbv->sem_number_end_sql,
-                implode("','", $selected_item_ids));
-        } else {
-            $query = sprintf("SELECT COUNT(DISTINCT ui.user_id) as count_user, "
-                . "UPPER(LEFT(TRIM(aum.Nachname),1)) AS initiale "
-                . "FROM user_inst ui "
-                . "LEFT JOIN auth_user_md5 aum USING (user_id) "
-                . "WHERE ui.inst_perms IN ('%s') "
-                . "AND ui.Institut_id IN ('%s') "
-                . "AND ui.externdefault = 1 "
-                . "AND TRIM(aum.Nachname) != '' "
-                . "GROUP BY initiale",
-                implode("','", $this->config->getValue('Main', 'instperms')),
-                implode("','", $selected_item_ids));
-        }
-
-        $rows = DBManager::get()->fetchAll($query);
-        foreach ($rows as $row) {
-            $content['LIST_CHARACTERS']['CHARACTER'][] = [
-                'CHARACTER_USER'       => ExternModule::ExtHtmlReady($row['initiale']),
-                'CHARACTER_COUNT_USER' => ExternModule::ExtHtmlReady($row['count_user']),
-                'URL_LIST_PERSONS'     => $this->getLinkToModule('LinkInternListCharacters', ['initiale' => $row['initiale']]),
-            ];
-        }
-        return $content;
-    }
-
-    private function getContentListInstitutes () {
-        $selected_item_ids = $this->config->getValue('SelectInstitutes', 'institutesselected');
-        // at least one institute has to be selected in the configuration
-        if (!is_array($selected_item_ids)) {
-            return [];
-        }
-        $content = [];
-
-        $first_levels = $this->range_tree->getKids('root');
-    //  var_dump($first_levels);
-        $current_semester = get_sem_num(time());
-
-        $dbv = DbView::getView('sem_tree');
-        $mrks = str_repeat('?,', count($selected_item_ids) - 1) . '?';
-        $query = "SELECT Institut_id, Name "
-            . "FROM Institute "
-            . "WHERE Institut_id IN ($mrks) "
-            . "AND fakultaets_id != Institut_id "
-            . "ORDER BY Name ASC";
-        $parameters = $selected_item_ids;
-
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute($parameters);
-
-        while ($row = $statement->fetch(PDO::FETCH_ASSOC)) {
-            if ($this->config->getValue('Main', 'onlylecturers')) {
-                // get only users with status dozent in an visible seminar in the current semester
-                $query = sprintf("SELECT COUNT(DISTINCT(su.user_id)) AS count_user "
-                    . "FROM user_inst ui "
-                    . "LEFT JOIN seminar_user su USING(user_id) "
-                    . "LEFT JOIN seminare s USING (seminar_id) "
-                    . "LEFT JOIN auth_user_md5 aum ON su.user_id = aum.user_id "
-                    . "WHERE ui.Institut_id = '%s' "
-                    . "AND su.status = 'dozent' "
-                    . "AND ui.externdefault = 1 "
-                    . "AND " . get_ext_vis_query()
-                    . "AND ui.inst_perms = 'dozent' "
-                    . "AND ((%s) = %s OR ((%s) <= %s  AND ((%s) >= %s OR (%s) = -1)))",
-                    $row['Institut_id'],
-                    $dbv->sem_number_sql,
-                    $current_semester,
-                    $dbv->sem_number_sql,
-                    $current_semester,
-                    $dbv->sem_number_end_sql,
-                    $current_semester,
-                    $dbv->sem_number_end_sql);
-            } else {
-                // get only users with the given status
-                $query = sprintf("SELECT COUNT(DISTINCT(ui.user_id)) AS count_user "
-                    . "FROM user_inst ui "
-                    . "INNER JOIN auth_user_md5 aum USING (user_id) "
-                    . "WHERE ui.Institut_id = '%s' "
-                    . "AND ui.inst_perms IN('%s') "
-                    . "AND ui.externdefault = 1 "
-                    . "AND " . get_ext_vis_query(),
-                    $row['Institut_id'],
-                    implode("','", $this->config->getValue('Main', 'instperms')));
-            }
-
-
-            $state = DBManager::get()->prepare($query);
-            $state->execute($parameters);
-            while ($row_count = $state->fetch(PDO::FETCH_ASSOC)) {
-
-                if ($row_count['count_user'] > 0) {
-                    $content['LIST_INSTITUTES']['INSTITUTE'][] = [
-                        'INSTITUTE_NAME' => ExternModule::ExtHtmlReady($row['Name']),
-                        'INSTITUTE_COUNT_USER' => $row_count['count_user'],
-                        'URL_LIST_PERSONS' => $this->getLinkToModule('LinkInternListInstitutes', ['item_id' => $row['Institut_id']])];
-                }
-            }
-        }
-
-        return $content;
-    }
-
-    public function printout ($args) {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateMain']->toString(['content' => $this->getContent($args), 'subpart' => 'PERS_BROWSE']);
-
-    }
-
-    public function printoutPreview () {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateMain']->toString(['content' => $this->getContent(), 'subpart' => 'PERS_BROWSE', 'hide_markers' => FALSE]);
-
-    }
-
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleTemplatePersondetails.class.php b/lib/extern/modules/ExternModuleTemplatePersondetails.class.php
deleted file mode 100644
index 6813e4715cc..00000000000
--- a/lib/extern/modules/ExternModuleTemplatePersondetails.class.php
+++ /dev/null
@@ -1,774 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter010: TODO
-/**
-* ExternModuleTemplatePersondetails.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleTemplatePersondetails
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleTemplatePersondetails.class.php
-//
-// Copyright (C) 2007 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/user_visible.inc.php';
-require_once 'lib/statusgruppe.inc.php';
-require_once 'lib/dates.inc.php';
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-
-class ExternModuleTemplatePersondetails extends ExternModule {
-
-    public $markers = [];
-    private $user_id;
-    private $user_perm;
-    private $visibilities;
-
-    /**
-    *
-    */
-    public function __construct ($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->data_fields = [];
-        if (Config::get()->CALENDAR_ENABLE) {
-            $this->registered_elements = [
-                'PersondetailsLectures' => 'PersondetailsLecturesTemplate',
-                'LinkInternLecturedetails' => 'LinkInternTemplate',
-                'TemplateMain' => 'TemplateGeneric',
-                'TemplateLectures' => 'TemplateGeneric',
-                'TemplateNews' => 'TemplateGeneric',
-                'TemplateAppointments' => 'TemplateGeneric',
-                'TemplateOwnCategories' => 'TemplateGeneric'
-            ];
-        } else {
-            $this->registered_elements = [
-                'PersondetailsLectures' => 'PersondetailsLecturesTemplate',
-                'LinkInternLecturedetails' => 'LinkInternTemplate',
-                'TemplateMain' => 'TemplateGeneric',
-                'TemplateLectures' => 'TemplateGeneric',
-                'TemplateNews' => 'TemplateGeneric',
-                'TemplateOwnCategories' => 'TemplateGeneric'
-            ];
-        }
-        if (in_array(get_object_type($range_id), ['global'])) {
-            array_unshift($this->registered_elements, 'SelectInstitutes');
-        }
-        $this->field_names = [];
-        $this->args = ['username', 'seminar_id', 'group_id'];
-
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-
-    }
-
-    public function setup () {
-
-        // setup module properties
-        $this->elements['LinkInternLecturedetails']->real_name = _("Link zum Modul Veranstaltungsdetails");
-        $this->elements['LinkInternLecturedetails']->link_module_type = [4, 13];
-        $this->elements['PersondetailsLectures']->real_name = _("Einstellungen für Lehrveranstaltungen");
-        $this->elements['TemplateMain']->real_name = _("Haupttemplate");
-        $this->elements['TemplateLectures']->real_name = _("Template für Lehrveranstaltungen");
-        $this->elements['TemplateNews']->real_name = _("Template für News");
-        if (Config::get()->CALENDAR_ENABLE) {
-            $this->elements['TemplateAppointments']->real_name = _("Template für Termine");
-        }
-        $this->elements['TemplateOwnCategories']->real_name = _("Template für eigene Kategorien");
-        if (in_array(get_object_type($this->config->range_id), ['global'])) {
-            $this->elements['SelectInstitutes']->real_name = _("Einschränkung auf Institute/Einrichtungen");
-        }
-    }
-
-    public function toStringEdit ($open_elements = '', $post_vars = '',
-            $faulty_values = '', $anker = '') {
-
-        $this->updateGenericDatafields('TemplateMain', 'user');
-        $this->updateGenericDatafields('TemplateMain', 'userinstrole');
-        $this->elements['TemplateMain']->markers = $this->getMarkerDescription('TemplateMain');
-        $this->elements['TemplateLectures']->markers = $this->getMarkerDescription('TemplateLectures');
-        if (Config::get()->CALENDAR_ENABLE) {
-            $this->elements['TemplateAppointments']->markers = $this->getMarkerDescription('TemplateAppointments');
-        }
-        $this->elements['TemplateNews']->markers = $this->getMarkerDescription('TemplateNews');
-        $this->elements['TemplateOwnCategories']->markers = $this->getMarkerDescription('TemplateOwnCategories');
-
-        return parent::toStringEdit($open_elements, $post_vars, $faulty_values, $anker);
-
-    }
-
-    public function getMarkerDescription ($element_name) {
-        $markers['TemplateMain'][] = ['__GLOBAL__', _("Globale Variablen (gültig im gesamten Template).")];
-        $markers['TemplateMain'][] = ['###STUDIP-EDIT-HREF###', ''];
-
-        $markers['TemplateMain'][] = ['<!-- BEGIN PERSONDETAILS -->', ''];
-        $markers['TemplateMain'][] = ['###FULLNAME###', ''];
-        $markers['TemplateMain'][] = ['###LASTNAME###', ''];
-        $markers['TemplateMain'][] = ['###FIRSTNAME###', ''];
-        $markers['TemplateMain'][] = ['###TITLEFRONT###', ''];
-        $markers['TemplateMain'][] = ['###TITLEREAR###', ''];
-        $markers['TemplateMain'][] = ['###USERNAME###', ''];
-        $markers['TemplateMain'][] = ['###STATUSGROUPS###', _("Kommaseparierte Liste mit Statusgruppen")];
-        $markers['TemplateMain'][] = ['###IMAGE-HREF###', ''];
-        $markers['TemplateMain'][] = ['###INST-NAME###', ''];
-        $markers['TemplateMain'][] = ['###INST-HREF###', ''];
-        $markers['TemplateMain'][] = ['###STREET###', ''];
-        $markers['TemplateMain'][] = ['###ZIPCODE###', ''];
-        $markers['TemplateMain'][] = ['###EMAIL###', ''];
-        $markers['TemplateMain'][] = ['###EMAIL-LOCAL###', _("Der local-part der E-Mail-Adresse (vor dem @-Zeichen)")];
-        $markers['TemplateMain'][] = ['###EMAIL-DOMAIN###', _("Der domain-part der E-Mail-Adresse (nach dem @-Zeichen)")];
-        $markers['TemplateMain'][] = ['###ROOM###', ''];
-        $markers['TemplateMain'][] = ['###PHONE###', ''];
-        $markers['TemplateMain'][] = ['###FAX###', ''];
-        $markers['TemplateMain'][] = ['###HOMEPAGE-HREF###', ''];
-        $markers['TemplateMain'][] = ['###OFFICE-HOURS###', ''];
-        $markers['TemplateMain'][] = ['###RESEARCH-INTERESTS###', ''];
-        $markers['TemplateMain'][] = ['###CV###', _("Lebenslauf")];
-        $markers['TemplateMain'][] = ['###PUBLICATIONS###', ''];
-        $markers['TemplateMain'][] = ['###OFFICE-HOURS###', ''];
-
-        $markers['TemplateMain'][] = ['<!-- BEGIN ALL-INST -->', ''];
-        $markers['TemplateMain'][] = ['<!-- BEGIN SINGLE-INST -->', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-NAME###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-HREF###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-STREET###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-ZIPCODE###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-EMAIL###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-EMAIL-LOCAL###', _("Der local-part der E-Mail-Adresse (vor dem @-Zeichen)")];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-EMAIL-DOMAIN###', _("Der domain-part der E-Mail-Adresse (nach dem @-Zeichen)")];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-ROOM###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-PHONE###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-FAX###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-HOMEPAGE-HREF###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-OFFICE-HOURS###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-RESEARCH-INTERESTS###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-CV###', _("Lebenslauf")];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-PUBLICATIONS###', ''];
-        $markers['TemplateMain'][] = ['###SINGLE-INST-OFFICE-HOURS###', ''];
-        $markers['TemplateMain'][] = ['<!-- END SINGLE-INST -->', ''];
-        $markers['TemplateMain'][] = ['<!-- END ALL-INST -->', ''];
-
-        $this->insertDatafieldMarkers('user', $markers, 'TemplateMain');
-        $this->insertDatafieldMarkers('userinstrole', $markers, 'TemplateMain');
-        $this->insertPluginMarkers('HomepagePlugin', $markers, 'TemplateMain');
-        $markers['TemplateMain'][] = ['###LECTURES###', _("Inhalt aus dem Template für Veranstaltungen")];
-        $markers['TemplateMain'][] = ['###NEWS###', _("Inhalt aus dem Template für News")];
-        $markers['TemplateMain'][] = ['###APPOINTMENTS###', _("Inhalt aus dem Template für Termine")];
-        $markers['TemplateMain'][] = ['###OWNCATEGORIES###', _("Inhalt aus dem Template für eigene Kategorien")];
-        $markers['TemplateMain'][] = ['<!-- END PERSONDETAILS -->', ''];
-
-        $markers['TemplateLectures'][] = ['<!-- BEGIN LECTURES -->', ''];
-        $markers['TemplateLectures'][] = ['<!-- BEGIN SEMESTER -->', ''];
-        $markers['TemplateLectures'][] = ['###NAME###', ''];
-        $markers['TemplateLectures'][] = ['<!-- BEGIN LECTURE -->', ''];
-        $markers['TemplateLectures'][] = ['###TITLE###', ''];
-        $markers['TemplateLectures'][] = ['###SUBTITLE###', ''];
-        $markers['TemplateLectures'][] = ['###NUMBER###', _("Die Veranstaltungsnummer")];
-        $markers['TemplateLectures'][] = ['###LECTUREDETAILS-HREF###', ''];
-        $markers['TemplateLectures'][] = ['<!-- END LECTURE -->', ''];
-        $markers['TemplateLectures'][] = ['<!-- END SEMESTER -->', ''];
-        $markers['TemplateLectures'][] = ['<!-- END LECTURES -->', ''];
-
-        $markers['TemplateNews'][] = ['<!-- BEGIN NEWS -->', ''];
-        $markers['TemplateNews'][] = ['<!-- BEGIN NO-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['###NEWS_NO-NEWS-TEXT###', ''];
-        $markers['TemplateNews'][] = ['<!-- END NO-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['<!-- BEGIN ALL-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['<!-- BEGIN SINGLE-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['###NEWS_TOPIC###', ''];
-        $markers['TemplateNews'][] = ['###NEWS_BODY###', ''];
-        $markers['TemplateNews'][] = ['###NEWS_DATE###', ''];
-        $markers['TemplateNews'][] = ['###NEWS_ADMIN-MESSAGE###', ''];
-        $markers['TemplateNews'][] = ['###NEWS_NO###', ''];
-        $markers['TemplateNews'][] = ['<!-- END SINGLE-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['<!-- END ALL-NEWS -->', ''];
-        $markers['TemplateNews'][] = ['<!-- END NEWS -->', ''];
-
-        if (Config::get()->CALENDAR_ENABLE) {
-            $markers['TemplateAppointments'][] = ['<!-- BEGIN APPOINTMENTS -->', ''];
-            $markers['TemplateAppointments'][] = ['###LIST-START###', _("Startdatum der Terminliste")];
-            $markers['TemplateAppointments'][] = ['###LIST-END###', _("Enddatum der Terminliste")];
-            $markers['TemplateAppointments'][] = ['<!-- BEGIN NO-APPOINTMENTS -->', ''];
-            $markers['TemplateAppointments'][] = ['###NO-APPOINTMENTS-TEXT###', ''];
-            $markers['TemplateAppointments'][] = ['<!-- END NO-APPOINTMENTS -->', ''];
-            $markers['TemplateAppointments'][] = ['<!-- BEGIN ALL-APPOINTMENTS -->', ''];
-            $markers['TemplateAppointments'][] = ['<!-- BEGIN SINGLE-APPOINTMENT -->', ''];
-            $markers['TemplateAppointments'][] = ['###DATE###', _("Start und Endzeit oder ganztägig")];
-            $markers['TemplateAppointments'][] = ['###BEGIN###', ''];
-            $markers['TemplateAppointments'][] = ['###END###', ''];
-            $markers['TemplateAppointments'][] = ['###TITLE###', ''];
-            $markers['TemplateAppointments'][] = ['###DESCRIPTION###', ''];
-            $markers['TemplateAppointments'][] = ['###LOCATION###', ''];
-            $markers['TemplateAppointments'][] = ['###REPETITION###', ''];
-            $markers['TemplateAppointments'][] = ['###CATEGORY###', ''];
-            $markers['TemplateAppointments'][] = ['###PRIORITY###', ''];
-            $markers['TemplateAppointments'][] = ['<!-- END SINGLE-APPOINTMENT -->', ''];
-            $markers['TemplateAppointments'][] = ['<!-- END ALL-APPOINTMENTS -->', ''];
-            $markers['TemplateAppointments'][] = ['<!-- END APPOINTMENTS -->', ''];
-        }
-
-        $markers['TemplateOwnCategories'][] = ['<!-- BEGIN OWNCATEGORIES -->', ''];
-        $markers['TemplateOwnCategories'][] = ['<!-- BEGIN OWNCATEGORY -->', ''];
-        $markers['TemplateOwnCategories'][] = ['###OWNCATEGORY_TITLE###', ''];
-        $markers['TemplateOwnCategories'][] = ['###OWNCATEGORY_CONTENT###', ''];
-        $markers['TemplateOwnCategories'][] = ['###OWNCATEGORY_NO###', _("Laufende Nummer")];
-        $markers['TemplateOwnCategories'][] = ['<!-- END OWNCATEGORY -->', ''];
-        $markers['TemplateOwnCategories'][] = ['<!-- END OWNCATEGORIES -->', ''];
-
-        return $markers[$element_name];
-    }
-
-    private function getContent ($args = NULL, $raw = FALSE) {
-        $instituts_id = $this->config->range_id;
-        $username = $args['username'];
-        $sem_id = $args['seminar_id'];
-        $group_id = $args['group_id'];
-
-        if (!$nameformat = $this->config->getValue('Main', 'nameformat')) {
-            $nameformat = 'full';
-        }
-
-        $row = false;
-        $global_view = false;
-        $dbv = new DbView();
-        if (in_array(get_object_type($this->config->range_id), ['global'])) {
-            $global_view = true;
-            $selected_item_ids = $this->config->getValue('SelectInstitutes', 'institutesselected');
-            // at least one institute has to be selected in the configuration
-            if (!is_array($selected_item_ids)) {
-                // default to always show user for now
-            } else if ($this->config->getValue('Main', 'onlylecturers')) {
-                // is user lecturer ?
-                $current_semester = get_sem_num(time());
-                $stm = DBManager::get()->prepare(sprintf(
-                    "SELECT aum.user_id "
-                    . "FROM auth_user_md5 aum "
-                    . "LEFT JOIN seminar_user su USING(user_id) "
-                    . "LEFT JOIN seminare s USING (seminar_id) "
-                    . "LEFT JOIN user_inst ui ON aum.user_id = ui.user_id "
-                    . "WHERE aum.username = ? "
-                    . "AND su.status = 'dozent' "
-                    . "AND s.visible = 1 "
-                    . "AND ((%s) = %s OR ((%s) <= %s  AND ((%s) >= %s OR (%s) = -1))) "
-                    . "AND ui.Institut_id IN ('%s') "
-                    . "AND ui.inst_perms = 'dozent' "
-                    . "AND ui.externdefault = 1 "
-                    . "AND %s",
-                    $dbv->sem_number_sql,
-                    $current_semester,
-                    $dbv->sem_number_sql,
-                    $current_semester,
-                    $dbv->sem_number_end_sql,
-                    $current_semester,
-                    $dbv->sem_number_end_sql,
-                    implode("','", $selected_item_ids),
-                    get_ext_vis_query()));
-                $stm->execute([$username]);
-                // user is not a lecturer
-                if (!$stm->fetch()) {
-                    return [];
-                }
-            } else {
-                // have user the status dozent at an institute in the list of accepted institutes
-                $stm = DBManager::get()->prepare(sprintf(
-                    "SELECT aum.user_id "
-                    . "FROM auth_user_md5 aum "
-                    . "LEFT JOIN user_inst ui USING(user_id) "
-                    . "WHERE aum.username = ? "
-                    . "AND ui.Institut_id IN ('%s') "
-                    . "AND ui.externdefault = 1 "
-                    . "AND %s",
-                    implode("','", $selected_item_ids), get_ext_vis_query()));
-                $stm->execute([$username]);
-                // user is not dozent at an institute that is in the list of accepted institutes
-                if (!$stm->fetch()) {
-                    return [];
-                }
-            }
-        }
-
-        // Mitarbeiter/in am Institut
-        $stm_inst = DBManager::get()->prepare(
-            "SELECT i.Institut_id "
-            . "FROM Institute i "
-            . "LEFT JOIN user_inst ui USING(Institut_id) "
-            . "LEFT JOIN auth_user_md5 aum USING(user_id) "
-            . "WHERE i.Institut_id = ? "
-            . "AND aum.username = ? AND ui.inst_perms IN ('autor','tutor','dozent') AND " . get_ext_vis_query());
-        $stm_inst->execute([$instituts_id, $username]);
-
-        // Mitarbeiter/in am Heimatinstitut des Seminars
-        if (!$row = $stm_inst->fetch(PDO::FETCH_ASSOC) && $sem_id) {
-            $stm_inst = DBManager::get()->prepare(
-                "SELECT s.Institut_id "
-                . "FROM seminare s "
-                . "LEFT JOIN user_inst ui USING(Institut_id) "
-                . "LEFT JOIN auth_user_md5 aum USING(user_id) "
-                . "WHERE s.Seminar_id = ? "
-                . "AND aum.username = ? AND ui.inst_perms = 'dozent' AND " . get_ext_vis_query());
-            $stm_inst->execute([$sem_id, $username]);
-            if ($row = $stm_inst->fetch(PDO::FETCH_ASSOC)) {
-                $instituts_id = $row['Institut_id'];
-            }
-        }
-
-        // an beteiligtem Institut Dozent(in)
-        if (!$row && $sem_id) {
-            $stm_inst = DBManager::get()->prepare(
-                "SELECT si.institut_id "
-                . "FROM seminare s "
-                . "LEFT JOIN seminar_inst si ON(s.Seminar_id = si.seminar_id) "
-                . "LEFT JOIN user_inst ui ON(si.institut_id = ui.Institut_id) "
-                . "LEFT JOIN auth_user_md5 aum USING(user_id) "
-                . "WHERE s.Seminar_id = ? "
-                . "AND si.institut_id != ? AND ui.inst_perms = 'dozent' AND aum.username = ? AND " . get_ext_vis_query());
-            $stm_inst->execute([$sem_id, $instituts_id, $username]);
-            if ($row = $stm_inst->fetch(PDO::FETCH_ASSOC)) {
-                $instituts_id = $row['institut_id'];
-            }
-        }
-
-        // ist zwar global Dozent, aber an keinem Institut eingetragen
-        if (!$row && $sem_id) {
-            $stm = DBManager::get()->prepare(sprintf(
-                "SELECT aum.*, %s AS fullname "
-                . "FROM auth_user_md5 aum "
-                . "LEFT JOIN user_info USING(user_id) "
-                . "LEFT JOIN seminar_user su "
-                . "WHERE username = ? "
-                . "AND perms = 'dozent' AND su.seminar_id = ? AND su.status = 'dozent' AND %s"
-                , $GLOBALS['_fullname_sql'][$nameformat], get_ext_vis_query()));
-            $stm->execute([$username, $sem_id]);
-            $row = $stm->fetch(PDO::FETCH_ASSOC);
-        } elseif ($global_view || $this->config->getValue('Main', 'defaultaddr')) {
-            $stm = DBManager::get()->prepare(sprintf(
-                "SELECT i.Institut_id, i.Name, i.Strasse, i.Plz, i.url, ui.*, aum.*, "
-                . "%s AS fullname, uin.user_id, uin.lebenslauf, uin.publi, uin.schwerp, "
-                . "uin.Home, uin.title_front, uin.title_rear "
-                . "FROM Institute i "
-                . "LEFT JOIN user_inst ui USING(Institut_id) "
-                . "LEFT JOIN auth_user_md5 aum USING(user_id) "
-                . "LEFT JOIN user_info uin USING (user_id) "
-                . "WHERE ui.inst_perms IN ('autor','tutor','dozent') "
-                . "AND aum.username = ? AND ui.externdefault = 1 AND %s"
-                , $GLOBALS['_fullname_sql'][$nameformat], get_ext_vis_query()));
-            $stm->execute([$username]);
-            $row = $stm->fetch(PDO::FETCH_ASSOC);
-            if (!$row) {
-                $stm = DBManager::get()->prepare(sprintf(
-                    "SELECT i.Institut_id, i.Name, i.Strasse, i.Plz, i.url, ui.*, aum.*, "
-                    . "%s AS fullname, uin.user_id, uin.lebenslauf, uin.publi, uin.schwerp, "
-                    . "uin.Home, uin.title_front, uin.title_rear "
-                    . "FROM Institute i "
-                    . "LEFT JOIN user_inst ui USING(Institut_id) "
-                    . "LEFT JOIN auth_user_md5 aum USING(user_id) "
-                    . "LEFT JOIN user_info uin USING (user_id) "
-                    . "WHERE ui.inst_perms IN ('autor','tutor','dozent') "
-                    . "AND aum.username = ? AND i.Institut_id = ? AND %s"
-                    , $GLOBALS['_fullname_sql'][$nameformat], get_ext_vis_query()));
-                $stm->execute([$username, $instituts_id]);
-                $row = $stm->fetch(PDO::FETCH_ASSOC);
-            } else {
-                $instituts_id = $row['Institut_id'];
-            }
-        } else {
-            $stm = DBManager::get()->prepare(sprintf(
-                "SELECT i.Institut_id, i.Name, i.Strasse, i.Plz, i.url, ui.*, aum.*, "
-                . "%s AS fullname, uin.user_id, uin.lebenslauf, uin.publi, uin.schwerp, "
-                . "uin.Home, uin.title_front, uin.title_rear "
-                . "FROM Institute i "
-                . "LEFT JOIN user_inst ui USING(Institut_id) "
-                . "LEFT JOIN auth_user_md5 aum USING(user_id) "
-                . "LEFT JOIN user_info uin USING (user_id) "
-                . "WHERE ui.inst_perms IN ('autor','tutor','dozent') "
-                . "AND aum.username = ? AND i.Institut_id = ? AND %s"
-                , $GLOBALS['_fullname_sql'][$nameformat], get_ext_vis_query()));
-            $stm->execute([$username, $instituts_id]);
-            $row = $stm->fetch(PDO::FETCH_ASSOC);
-        }
-
-        // the user with the given username does not fulfill the conditions above
-        if (!$row) {
-            return [];
-        }
-
-        // Alle Einrichtungen hohlen
-        $stm = DBManager::get()->prepare(sprintf(
-                "SELECT i.Institut_id, i.Name, i.Strasse, i.Plz, i.url, ui.*, aum.*, "
-                . "%s AS fullname, uin.user_id, uin.lebenslauf, uin.publi, uin.schwerp, "
-                . "uin.Home, uin.title_front, uin.title_rear "
-                . "FROM Institute i "
-                . "LEFT JOIN user_inst ui USING(Institut_id) "
-                . "LEFT JOIN auth_user_md5 aum USING(user_id) "
-                . "LEFT JOIN user_info uin USING (user_id) "
-                . "WHERE ui.inst_perms IN ('autor','tutor','dozent') "
-                . "AND aum.username = ? "
-                . "AND ui.`visible` = 1 "
-                . "ORDER BY ui.`externdefault` DESC, ui. `priority` ASC, i.`Name` ASC"
-                , $GLOBALS['_fullname_sql'][$nameformat]));
-        $stm->execute([$username]);
-        $allRows = $stm->fetchAll();
-
-        $this->user_id = $row['user_id'];
-
-        $content['__GLOBAL__']['STUDIP-EDIT-HREF'] = "{$GLOBALS['ABSOLUTE_URI_STUDIP']}dispatch.php/settings/account?username=$username&login=yes";
-
-        $content['PERSONDETAILS']['FULLNAME'] = ExternModule::ExtHtmlReady($row['fullname']);
-        $content['PERSONDETAILS']['LASTNAME'] = ExternModule::ExtHtmlReady($row['Nachname']);
-        $content['PERSONDETAILS']['FIRSTNAME'] = ExternModule::ExtHtmlReady($row['Vorname']);
-        $content['PERSONDETAILS']['TITLEFRONT'] = ExternModule::ExtHtmlReady($row['title_front']);
-        $content['PERSONDETAILS']['TITLEREAR'] = ExternModule::ExtHtmlReady($row['title_rear']);
-        if ($statusgroups = Statusgruppen::getUserRoles($instituts_id, $this->user_id)) {
-            $content['PERSONDETAILS']['STATUSGROUPS'] = ExternModule::ExtHtmlReady(join(', ', array_values($statusgroups)));
-        }
-        $content['PERSONDETAILS']['USERNAME'] = $row['username'];
-
-        $content['PERSONDETAILS']['IMAGE-HREF'] = Avatar::getAvatar($this->user_id)->getURL(Avatar::NORMAL);
-
-        $gruppen = GetRoleNames(GetAllStatusgruppen($this->config->range_id, $row['user_id'])) ?? [];
-        if ($gruppen) {
-            for ($i = 0; $i < count($gruppen); $i++) {
-                $content['PERSONDETAILS']['GROUPS'][$i]['GROUP'] = ExternModule::ExtHtmlReady($gruppen[$i]);
-            }
-        }
-
-        $content['PERSONDETAILS']['INST-NAME'] = ExternModule::ExtHtmlReady($row['Name']);
-        $content['PERSONDETAILS']['INST-HREF'] = ExternModule::ExtHtmlReady(trim($row['url']));
-        $content['PERSONDETAILS']['STREET'] = ExternModule::ExtHtmlReady($row['Strasse']);
-        $content['PERSONDETAILS']['ZIPCODE'] = ExternModule::ExtHtmlReady($row['Plz']);
-        $email = get_visible_email($this->user_id);
-        $content['PERSONDETAILS']['EMAIL'] = ExternModule::ExtHtmlReady($email);
-        $emails = explode('@', $content['PERSONDETAILS']['EMAIL']);
-        $content['PERSONDETAILS']['EMAIL-LOCAL'] = array_shift($emails);
-        $emails = explode('@', $content['PERSONDETAILS']['EMAIL']);
-        $content['PERSONDETAILS']['EMAIL-DOMAIN'] = array_pop($emails);
-        $content['PERSONDETAILS']['ROOM'] = ExternModule::ExtHtmlReady($row['raum']);
-        $content['PERSONDETAILS']['PHONE'] = ExternModule::ExtHtmlReady($row['Telefon']);
-        $content['PERSONDETAILS']['FAX'] = ExternModule::ExtHtmlReady($row['Fax']);
-        if (Visibility::verify('homepage', $this->user_id)) {
-            $content['PERSONDETAILS']['HOMEPAGE-HREF'] = ExternModule::ExtHtmlReady(trim($row['Home']));
-        }
-        $content['PERSONDETAILS']['OFFICE-HOURS'] = ExternModule::ExtHtmlReady($row['sprechzeiten']);
-
-        $j = 0;
-        foreach($allRows as $curRow)
-        {
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-NAME'] = ExternModule::ExtHtmlReady($curRow['Name']);
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-HREF'] = ExternModule::ExtHtmlReady(trim($curRow['url']));
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-STREET'] = ExternModule::ExtHtmlReady($curRow['Strasse']);
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-ZIPCODE'] = ExternModule::ExtHtmlReady($curRow['Plz']);
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-EMAIL'] = ExternModule::ExtHtmlReady($curRow['Email']);
-            $emails = explode('@', $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-EMAIL']);
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-EMAIL-LOCAL'] = array_shift($emails);
-            $emails = explode('@', $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-EMAIL']);
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-EMAIL-DOMAIN'] = array_pop($emails);
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-ROOM'] = ExternModule::ExtHtmlReady($curRow['raum']);
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-PHONE'] = ExternModule::ExtHtmlReady($curRow['Telefon']);
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-FAX'] = ExternModule::ExtHtmlReady($curRow['Fax']);
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-HOMEPAGE-HREF'] = ExternModule::ExtHtmlReady(trim($curRow['Home']));
-            $content['PERSONDETAILS']['ALL-INST']['SINGLE-INST'][$j]['SINGLE-INST-OFFICE-HOURS'] = ExternModule::ExtHtmlReady($curRow['sprechzeiten']);
-            $j++;
-        }
-
-        // generic data fields
-        if ($generic_datafields = $this->config->getValue('TemplateMain', 'genericdatafields')) {
-            $localEntries = DataFieldEntry::getDataFieldEntries($this->user_id, 'user');
-            $k = 1;
-            foreach ($generic_datafields as $datafield) {
-                if (isset($localEntries[$datafield]) &&
-                        is_object($localEntries[$datafield]) &&
-                        Visibility::verify($localEntries[$datafield]->getId(), $this->user_id)) {
-                    if ($localEntries[$datafield]->getType() == 'link') {
-                        $localEntry = ExternModule::extHtmlReady($localEntries[$datafield]->getValue());
-                    } else {
-                        $localEntry = $localEntries[$datafield]->getDisplayValue();
-                    }
-                    if ($localEntry) {
-                        $content['PERSONDETAILS']["DATAFIELD_$k"] = $localEntry;
-                    }
-                }
-                $k++;
-            }
-
-            $localEntries = DataFieldEntry::getDataFieldEntries([$this->user_id, $instituts_id], 'userinstrole');
-            if (isset($group_id)) {
-                $roleEntries = DataFieldEntry::getDataFieldEntries([$this->user_id, $group_id], 'userinstrole');
-                $roleEntries = array_filter($roleEntries, function($val) { return $val->getValue() !== 'default_value'; });
-                $localEntries = $roleEntries + $localEntries;
-            }
-            $k = 1;
-            foreach ($generic_datafields as $datafield) {
-                if (isset($localEntries[$datafield]) &&
-                        is_object($localEntries[$datafield])) {
-                    $localEntry = $localEntries[$datafield]->getDisplayValue();
-                    if ($localEntry) {
-                        $content['PERSONDETAILS']["DATAFIELD_$k"] = $localEntry;
-                    }
-                }
-                $k++;
-            }
-        }
-
-        // homepage plugins
-        $plugins = PluginEngine::getPlugins('HomepagePlugin');
-
-        foreach ($plugins as $plugin) {
-            $template = $plugin->getHomepageTemplate($this->user_id);
-
-            if ($template) {
-                $keyname = 'PLUGIN_' . mb_strtoupper($plugin->getPluginName());
-                $content['PERSONDETAILS'][$keyname] = $template->render();
-            }
-        }
-
-        $user_obj = User::find($this->user_id);
-        if (Visibility::verify('lebenslauf', $this->user_id)) {
-            $content['PERSONDETAILS']['CV'] = ExternModule::ExtFormatReady($user_obj->lebenslauf);
-        }
-        if (Visibility::verify('schwerp', $this->user_id)) {
-            $content['PERSONDETAILS']['RESEARCH-INTERESTS'] = ExternModule::ExtFormatReady($user_obj->schwerp);
-        }
-        if (Visibility::verify('publi', $this->user_id)) {
-            $content['PERSONDETAILS']['PUBLICATIONS'] = ExternModule::ExtFormatReady($user_obj->publi);
-        }
-
-        $content['PERSONDETAILS']['LECTURES'] = $this->elements['TemplateLectures']->toString(['content' => $this->getContentLectures(), 'subpart' => 'LECTURES']);
-        if (Visibility::verify('news', $this->user_id)) {
-            $content['PERSONDETAILS']['NEWS'] = $this->elements['TemplateNews']->toString(['content' => $this->getContentNews(), 'subpart' => 'NEWS']);
-        }
-        if (Visibility::verify('dates', $this->user_id)) {
-            $content['PERSONDETAILS']['APPOINTMENTS'] = $this->elements['TemplateAppointments']->toString(['content' => $this->getContentAppointments(), 'subpart' => 'APPOINTMENTS']);
-        }
-        $content['PERSONDETAILS']['OWNCATEGORIES'] = $this->elements['TemplateOwnCategories']->toString(['content' => $this->getContentOwnCategories(), 'subpart' => 'OWNCATEGORIES']);
-
-        return $content;
-    }
-
-    private function getContentOwnCategories () {
-        $stm = DBManager::get()->prepare(
-            "SELECT kategorie_id, name, content "
-            . "FROM kategorien "
-            . "WHERE range_id = ? "
-            . "ORDER BY priority");
-        $stm->execute([$this->user_id]);
-        $i = 0;
-        while ($row = $stm->fetch(PDO::FETCH_ASSOC)) {
-            if (Visibility::verify('kat_'.$row['kategorie_id'], $this->user_id)) {
-                $content['OWNCATEGORIES']['OWNCATEGORY'][$i]['OWNCATEGORY_TITLE'] = ExternModule::ExtHtmlReady($row['name']);
-                $content['OWNCATEGORIES']['OWNCATEGORY'][$i]['OWNCATEGORY_CONTENT'] = ExternModule::ExtFormatReady($row['content']);
-                $content['OWNCATEGORIES']['OWNCATEGORY'][$i]['OWNCATEGORY_NO'] = $i + 1;
-                $i++;
-            }
-        }
-        return $content;
-    }
-
-    private function getContentNews () {
-        $dateform = $this->config->getValue('Main', 'dateformat');
-
-        $news = StudipNews::GetNewsByRange($this->user_id, TRUE);
-        if (!count($news)) {
-            $content['NEWS']['NO-NEWS']['NEWS_NO-NEWS-TEXT'] = $this->config->getValue('Main', 'nodatatext');
-        } else {
-            $i = 0;
-            foreach ($news as $news_id => $news_detail) {
-                $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_BODY'] = ExternModule::ExtFormatReady((string) $news_detail->body);
-                $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_DATE'] = strftime($dateform, $news_detail->date);
-                $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_TOPIC'] = ExternModule::ExtHtmlReady((string) $news_detail->topic);
-                $content['NEWS']['ALL-NEWS']['SINGLE-NEWS'][$i]['NEWS_NO'] = $i + 1;
-                $i++;
-            }
-        }
-        return $content;
-    }
-
-    private function getContentAppointments () {
-        if (Config::get()->CALENDAR_ENABLE) {
-            $events = SingleCalendar::getEventList($this->user_id, time(), time() + 60 * 60 * 24 * 7, null, ['class' => 'PUBLIC'], ['CalendarEvent']);
-            $content['APPOINTMENTS']['LIST-START'] = ExternModule::ExtHtmlReady(strftime($this->config->getValue('Main', 'dateformat') . ' %X', time()));
-            $content['APPOINTMENTS']['LIST-END'] = ExternModule::ExtHtmlReady(strftime($this->config->getValue('Main', 'dateformat') . ' %X', time() + 60 * 60 * 24 * 7));
-            if (sizeof($events)) {
-                $i = 0;
-                foreach ($events as $event) {
-                    if ($event->isDayEvent()) {
-                        $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['DATE'] = ExternModule::ExtHtmlReady(strftime($this->config->getValue('Main', 'dateformat'), $event->getStart()) . ' (' . _("ganztägig") . ')');
-                    } else {
-                        $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['DATE'] = ExternModule::ExtHtmlReady(strftime($this->config->getValue('Main', 'dateformat') . " %X", $event->getStart()));
-                        if (date("dmY", $event->getStart()) == date("dmY", $event->getEnd())) {
-                            $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['DATE'] .= ExternModule::ExtHtmlReady(strftime(" - %X", $event->getEnd()));
-                        } else {
-                            $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['DATE'] .= ExternModule::ExtHtmlReady(strftime(" - " . $this->config->getValue('Main', 'dateformat') . " %X", $event->getEnd()));
-                        }
-                    }
-                    $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['TITLE'] = ExternModule::ExtHtmlReady($event->getTitle());
-                    $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['DESCRIPTION'] = ExternModule::ExtHtmlReady($event->getDescription());
-                    $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['LOCATION'] = ExternModule::ExtHtmlReady($event->getLocation());
-                    $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['REPETITION'] = ExternModule::ExtHtmlReady($event->toStringRecurrence());
-                    $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['CATEGORY'] = ExternModule::ExtHtmlReady($event->toStringCategories());
-                    $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['PRIORITY'] = ExternModule::ExtHtmlReady($event->toStringPriority());
-                    $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['START'] = ExternModule::ExtHtmlReady(strftime($this->config->getValue('Main', 'dateformat') . " %X", $event->getStart()));
-                    $content['APPOINTMENTS']['ALL-APPOINTMENTS']['SINGLE-APPOINTMENT'][$i]['END'] = ExternModule::ExtHtmlReady(strftime($this->config->getValue('Main', 'dateformat') . " %X", $event->getEnd()));
-                    $i++;
-                }
-            } else {
-                $content['APPOINTMENTS']['NO-APPOINTMENTS']['NO-APPOINTMENTS_TEXT'] = $this->config->getValue('Main', 'noappointmentstext');
-            }
-            return $content;
-        }
-        return NULL;
-    }
-
-    private function getContentLectures () {
-        global $attr_text_td, $end, $start;
-
-        $all_semester = Semester::findAllVisible(false);
-        // old hard coded $SEMESTER-array starts with index 1
-        array_unshift($all_semester, 0);
-
-        $types = [];
-        $semclass = $this->config->getValue('PersondetailsLectures', 'semclass');
-        if (is_null($semclass)) {
-            $semclass = [1];
-        }
-
-        // Is a semester switch defined?
-        $week_offset = $this->config->getValue('PersondetailsLectures', 'semswitch');
-        if (ctype_digit($week_offset)) {
-            $switch_time = strtotime("+{$week_offset} weeks 0:00:00");
-        } else {
-            $switch_time = strtotime('0:00:00');
-        }
-
-        // get current semester
-        $current_sem = get_sem_num($switch_time) + 1;
-
-        switch ($this->config->getValue("PersondetailsLectures", "semstart")) {
-            case "previous" :
-                if (isset($all_semester[$current_sem - 1])) {
-                    $current_sem--;
-                }
-                break;
-            case "next" :
-                if (isset($all_semester[$current_sem + 1])) {
-                    $current_sem++;
-                }
-                break;
-            case "current" :
-                break;
-            default :
-                if (isset($all_semester[$this->config->getValue("PersondetailsLectures", "semstart")])) {
-                    $current_sem = $this->config->getValue("PersondetailsLectures", "semstart");
-                }
-        }
-
-        $last_sem = $current_sem - 1;
-
-        $sem_offset = $this->config->getValue("PersondetailsLectures", "semrange");
-        if ($sem_offset && ctype_digit($sem_offset)) {
-            $last_sem += $sem_offset;
-        }
-
-        if ($last_sem < $current_sem) {
-            $last_sem = $current_sem;
-        }
-        if (!isset($all_semester[$last_sem])) {
-            $last_sem = sizeof($all_semester) - 1;
-        }
-
-        $types = [];
-        $semclass = $this->config->getValue('PersondetailsLectures', 'semclass');
-        if (is_null($semclass)) {
-            $semclass = [1];
-        }
-        foreach ($GLOBALS["SEM_TYPE"] as $key => $type) {
-            if (in_array($type["class"], $semclass)) {
-                $types[] = $key;
-            }
-        }
-        $stm = DBManager::get()->prepare(
-            "SELECT s.Name, s.Seminar_id, s.Untertitel, s.VeranstaltungsNummer "
-            . "FROM seminar_user su "
-            . "LEFT JOIN seminare s USING(seminar_id) "
-            . "LEFT JOIN semester_courses ON (semester_courses.course_id = s.Seminar_id) "
-            . "WHERE user_id = ? "
-            . "AND su.status LIKE 'dozent' "
-            . "AND start_time <= ? AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = ?) "
-            . "AND s.status IN (?) AND s.visible = 1 "
-            . "ORDER BY Name");
-
-        $i = 0;
-        for (;$current_sem <= $last_sem; $last_sem--) {
-            $stm->execute([$this->user_id, $all_semester[$last_sem]['beginn'], $all_semester[$last_sem]['semester_id'], $types ?: '']);
-            $result = $stm->fetchAll();
-
-            if ($result && sizeof($result)) {
-                if (!($this->config->getValue('PersondetailsLectures', 'semstart') == 'current' && $this->config->getValue('PersondetailsLectures', 'semrange') == 1)) {
-                    $month = date('n', $all_semester[$last_sem]['beginn']);
-                    if ($month > 9) {
-                        $content['LECTURES']['SEMESTER'][$i]['NAME'] = $this->config->getValue('PersondetailsLectures', 'aliaswise') . date(' Y/', $all_semester[$last_sem]['beginn']) . date('y', $all_semester[$last_sem]['ende']);
-                    } else if ($month > 3 && $month < 10) {
-                        $content['LECTURES']['SEMESTER'][$i]['NAME'] = $this->config->getValue('PersondetailsLectures', 'aliassose') . date(' Y', $all_semester[$last_sem]['beginn']);
-                    }
-                }
-                $k = 0;
-                foreach ($result as $row) {
-                    $sem_object = Seminar::GetInstance($row['Seminar_id']);
-
-                    $content['LECTURES']['SEMESTER'][$i]['LECTURE'][$k]['TITLE'] = ExternModule::ExtHtmlReady($sem_object->name);
-                    $content['LECTURES']['SEMESTER'][$i]['LECTURE'][$k]['LECTUREDETAILS-HREF'] = $this->elements['LinkInternLecturedetails']->createUrl(['link_args' => 'seminar_id=' . $row['Seminar_id']]);
-                    if (trim($row['Untertitel']) != '') {
-                        $content['LECTURES']['SEMESTER'][$i]['LECTURE'][$k]['SUBTITLE'] = ExternModule::ExtHtmlReady($sem_object->untertitel);
-                    }
-                    if (trim($row['VeranstaltungsNummer']) != '') {
-                        $content['LECTURES']['SEMESTER'][$i]['LECTURE'][$k]['NUMBER'] = ExternModule::ExtHtmlReady($row['VeranstaltungsNummer']);
-                    }
-                    $k++;
-                }
-            }
-            $i++;
-        }
-        return $content;
-    }
-
-    public function printout ($args) {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateMain']->toString(['content' => $this->getContent($args), 'subpart' => 'PERSONDETAILS']);
-
-    }
-
-    public function printoutPreview () {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateMain']->toString(['content' => $this->getContent(), 'subpart' => 'PERSONDETAILS', 'hide_markers' => FALSE]);
-
-    }
-
-}
-?>
diff --git a/lib/extern/modules/ExternModuleTemplatePersons.class.php b/lib/extern/modules/ExternModuleTemplatePersons.class.php
deleted file mode 100644
index ce6290e519e..00000000000
--- a/lib/extern/modules/ExternModuleTemplatePersons.class.php
+++ /dev/null
@@ -1,375 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternModuleTemplatePersons.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleTemplatePersons
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleTemplatePersons.class.php
-//
-// Copyright (C) 2007 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/user_visible.inc.php';
-
-class ExternModuleTemplatePersons extends ExternModule {
-
-    var $markers = [];
-
-    /**
-    *
-    */
-    function __construct ($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-        $this->data_fields = [
-                'Nachname', 'Telefon', 'raum', 'Email', 'sprechzeiten'
-        ];
-        $this->registered_elements = [
-                'LinkInternTemplate',
-                'TemplateGeneric'
-        ];
-
-        $this->field_names =
-        [
-                _("Name"),
-                _("Telefon"),
-                _("Raum"),
-                _("E-Mail"),
-                _("Sprechzeiten")
-        ];
-
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    function setup () {
-        $this->elements['TemplateGeneric']->real_name = _("Template");
-        // Set internal link to module 'staff details'
-        $this->elements['LinkInternTemplate']->link_module_type = [2, 14];
-        $this->elements['LinkInternTemplate']->real_name = _("Verlinkung zum Modul MitarbeiterInnendetails");
-
-    }
-
-    function toStringEdit ($open_elements = '', $post_vars = '',
-            $faulty_values = '', $anker = '') {
-
-        $this->updateGenericDatafields('TemplateGeneric', 'user');
-        $this->updateGenericDatafields('TemplateGeneric', 'userinstrole');
-        $this->elements['TemplateGeneric']->markers = $this->getMarkerDescription('TemplateGeneric');
-
-        return parent::toStringEdit($open_elements, $post_vars, $faulty_values, $anker);
-    }
-
-    function getMarkerDescription ($element_name) {
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN PERSONS -->', ''];
-
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN NO-PERSONS -->', ''];
-        $markers['TemplateGeneric'][] = ['###NO-LECTURES-TEXT###', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END NO-PERSONS -->', ''];
-
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN GROUP -->', ''];
-        $markers['TemplateGeneric'][] = ['###GROUPTITLE###', ''];
-        $markers['TemplateGeneric'][] = ['###GROUPTITLE-SUBSTITUTE###', ''];
-        $markers['TemplateGeneric'][] = ['###GROUP-NO###', ''];
-
-        $markers['TemplateGeneric'][] = ['<!-- BEGIN PERSON -->', ''];
-        $markers['TemplateGeneric'][] = ['###FULLNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###LASTNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###FIRSTNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###TITLEFRONT###', ''];
-        $markers['TemplateGeneric'][] = ['###TITLEREAR###', ''];
-        $markers['TemplateGeneric'][] = ['###PERSONDETAIL-HREF###', ''];
-        $markers['TemplateGeneric'][] = ['###USERNAME###', ''];
-        $markers['TemplateGeneric'][] = ['###IMAGE-URL-NORMAL###', _('Nutzerbild (groß)')];
-        $markers['TemplateGeneric'][] = ['###IMAGE-URL-MEDIUM###', _('Nutzerbild (mittel)')];
-        $markers['TemplateGeneric'][] = ['###IMAGE-URL-SMALL###', _('Nutzerbild (klein)')];
-        $markers['TemplateGeneric'][] = ['###PHONE###', ''];
-        $markers['TemplateGeneric'][] = ['###ROOM###', ''];
-        $markers['TemplateGeneric'][] = ['###EMAIL###', ''];
-        $markers['TemplateGeneric'][] = ['###EMAIL-LOCAL###', _("Der local-part der E-Mail-Adresse (vor dem @-Zeichen)")];
-        $markers['TemplateGeneric'][] = ['###EMAIL-DOMAIN###', _("Der domain-part der E-Mail-Adresse (nach dem @-Zeichen)")];
-        $markers['TemplateGeneric'][] = ['###HOMEPAGE-HREF###', ''];
-        $markers['TemplateGeneric'][] = ['###OFFICEHOURS###', ''];
-        $markers['TemplateGeneric'][] = ['###PERSON-NO###', ''];
-        $this->insertDatafieldMarkers('user', $markers, 'TemplateGeneric');
-        $this->insertDatafieldMarkers('userinstrole', $markers, 'TemplateGeneric');
-        $markers['TemplateGeneric'][] = ['<!-- END PERSON -->', ''];
-
-        $markers['TemplateGeneric'][] = ['<!-- END GROUP -->', ''];
-        $markers['TemplateGeneric'][] = ['<!-- END PERSONS -->', ''];
-
-        return $markers[$element_name];
-    }
-
-    function getContent ($args = NULL, $raw = FALSE) {
-        if ($raw) {
-            self::SetRawOutput();
-        }
-
-        if (!$all_groups = get_all_statusgruppen($this->config->range_id)) {
-            die($GLOBALS["EXTERN_ERROR_MESSAGE"]);
-        } else {
-            $all_groups = array_keys($all_groups);
-        }
-
-        if (!$group_ids = $this->config->getValue('Main', 'groupsvisible')) {
-            die($GLOBALS["EXTERN_ERROR_MESSAGE"]);
-        } else {
-            $group_ids = array_intersect($all_groups, $group_ids);
-        }
-
-        if (!is_array($group_ids)) {
-            die($GLOBALS["EXTERN_ERROR_MESSAGE"]);
-        }
-
-        if (!$visible_groups = get_statusgruppen_by_id($this->config->range_id, $group_ids)) {
-            die($GLOBALS["EXTERN_ERROR_MESSAGE"]);
-        }
-
-        $sort = $this->config->getValue('Main', 'sort');
-        $query_order = [];
-        foreach ($sort as $key => $position) {
-            if ($position > 0) {
-                $query_order[$position] = $this->data_fields[$key];
-            }
-        }
-        if (count($query_order)) {
-            ksort($query_order, SORT_NUMERIC);
-            $query_order = ' ORDER BY ' . implode(',', $query_order);
-        } else {
-            $query_order = '';
-        }
-
-        $grouping = $this->config->getValue("Main", "grouping");
-        if (!$nameformat = $this->config->getValue('Main', 'nameformat')) {
-            $nameformat = 'full_rev';
-        }
-
-        if(!$grouping) {
-            $query = "SELECT DISTINCT ui.raum, ui.sprechzeiten, ui.Telefon, inst_perms, Email, aum.user_id, ";
-            $query .= 'username, aum.Vorname, title_front, title_rear, Home, ';
-            $query .= $GLOBALS['_fullname_sql'][$nameformat] . " AS fullname, aum.Nachname ";
-            if ($query_order) {
-                $query .= "FROM statusgruppe_user LEFT JOIN auth_user_md5 aum USING(user_id) ";
-                $query .= "LEFT JOIN user_info USING(user_id) LEFT JOIN user_inst ui USING(user_id) ";
-                $query .= "WHERE statusgruppe_id IN (?) AND Institut_id = ? AND ".get_ext_vis_query()."$query_order";
-            } else {
-                $query .= "FROM statusgruppen s LEFT JOIN statusgruppe_user su USING(statusgruppe_id) ";
-                $query .= "LEFT JOIN auth_user_md5 aum USING(user_id) ";
-                $query .= "LEFT JOIN user_info USING(user_id) LEFT JOIN user_inst ui USING(user_id) ";
-                $query .= "WHERE su.statusgruppe_id IN (?) AND Institut_id = ? ";
-                $query .= " AND ".get_ext_vis_query()." ORDER BY ";
-                $query .= "s.position ASC, su.position ASC";
-            }
-            $parameters = [$this->config->getValue('Main', 'groupsvisible'), $this->config->range_id];
-            $statement = DBManager::get()->prepare($query);
-            $statement->execute($parameters);
-            $row = $statement->fetch(PDO::FETCH_ASSOC);
-            $visible_groups = [''];
-        }
-
-        // generic data fields
-        $generic_datafields = $this->config->getValue('TemplateGeneric', 'genericdatafields');
-
-        $data['data_fields'] = $this->data_fields;
-        $defaultaddress = $this->config->getValue('Main', 'defaultadr');
-        if (! $defaultaddress) {
-           $db_out =& $row;
-        }
-
-        $content = null;
-        $i = 0;
-        $aliases_groups = $this->config->getValue('Main', 'groupsalias');
-        foreach ($visible_groups as $group_id => $group) {
-            if ($grouping) {
-                if (!$query_order) {
-                    $query_order = ' ORDER BY su.position';
-                }
-                $query = 'SELECT ui.raum, ui.sprechzeiten, ui.Telefon, inst_perms, Email, aum.user_id, ';
-                $query .= 'username, aum.Vorname, title_front, title_rear, Home, ';
-                $query .= $GLOBALS['_fullname_sql'][$nameformat] . " AS fullname, aum.Nachname ";
-                $query .= 'FROM statusgruppe_user su LEFT JOIN auth_user_md5 aum USING(user_id) ';
-                $query .= 'LEFT JOIN user_info USING(user_id) LEFT JOIN user_inst ui USING(user_id) ';
-                $query .= "WHERE su.statusgruppe_id = ? AND ".get_ext_vis_query()." AND Institut_id = ? $query_order";
-
-                $parameters = [$group_id, $this->config->range_id ];
-                $statement = DBManager::get()->prepare($query);
-                $statement->execute($parameters);
-                $row = $statement->fetch(PDO::FETCH_ASSOC);
-
-                if($aliases_groups[$group_id]) {
-                    $group = $aliases_groups[$group_id];
-                }
-            }
-
-
-            if ($row !== false) {
-                if($aliases_groups[$group_id]) {
-                    $content['PERSONS']['GROUP'][$i]['GROUPTITLE-SUBSTITUTE'] = ExternModule::ExtHtmlReady($aliases_groups[$group_id]);
-                }
-                $content['PERSONS']['GROUP'][$i]['GROUPTITLE'] = ExternModule::ExtHtmlReady($group);
-                $content['PERSONS']['GROUP'][$i]['GROUP-NO'] = $i + 1;
-
-                $j = 0;
-                do{
-                    $visibilities = get_local_visibility_by_id($row['user_id'], 'homepage', true);
-                    $user_perm = $visibilities['perms'];
-                    $visibilities = json_decode($visibilities['homepage'], true);
-                    $instituts_id = $this->config->range_id;
-
-                    if ($defaultaddress) {
-                        $query = 'SELECT ui.raum, ui.sprechzeiten, ui.Telefon, inst_perms,  Email, ';
-                        $query .= 'title_front, title_rear, Home, Institut_id, ';
-                        $query .= 'aum.user_id, username, ' . $GLOBALS['_fullname_sql'][$nameformat];
-                        $query .= ' AS fullname, aum.Nachname, aum.Vorname FROM auth_user_md5 aum LEFT JOIN ';
-                        $query .= 'user_info USING(user_id) LEFT JOIN ';
-                        $query .= "user_inst ui USING(user_id) WHERE aum.user_id = '" . $row['user_id'];
-                        $query .= "' AND ".get_ext_vis_query().' AND externdefault = 1';
-
-                        $statement2 = DBManager::get()->prepare($query);
-                        $statement2->execute();
-                        $db_out = $statement2->fetch(PDO::FETCH_ASSOC);
-                        //no default
-                        if ($db_out === false) {
-                            $query = 'SELECT ui.raum, ui.sprechzeiten, ui.Telefon, inst_perms,  Email, ';
-                            $query .= 'title_front, title_rear, Home, ';
-                            $query .= 'aum.user_id, username, ' . $GLOBALS['_fullname_sql'][$nameformat];
-                            $query .= ' AS fullname, aum.Nachname, aum.Vorname FROM auth_user_md5 aum LEFT JOIN ';
-                            $query .= 'user_info USING(user_id) LEFT JOIN ';
-                            $query .= "user_inst ui USING(user_id) WHERE aum.user_id = '" . $row['user_id'];
-                            $query .= "' AND ".get_ext_vis_query()." AND Institut_id = ? " ;
-                            $statement2 = DBManager::get()->prepare($query);
-                            $params = [$this->config->range_id];
-                            $statement2->execute($params);
-                            $db_out = $statement2->fetch(PDO::FETCH_ASSOC);
-                        } else {
-                            $instituts_id = $db_out['Institut_id'];
-                        }
-                    }
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['FULLNAME'] = ExternModule::ExtHtmlReady($db_out['fullname']);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['LASTNAME'] = ExternModule::ExtHtmlReady($db_out['Nachname']);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['FIRSTNAME'] = ExternModule::ExtHtmlReady($db_out['Vorname']);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['TITLEFRONT'] = ExternModule::ExtHtmlReady($db_out['title_front']);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['TITLEREAR'] = ExternModule::ExtHtmlReady($db_out['title_rear']);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['PERSONDETAIL-HREF'] =
-                        $this->elements['LinkInternTemplate']->createUrl(['link_args' => 'username=' . $db_out['username'] . ($grouping ? '&group_id=' . $group_id : '')]);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['USERNAME'] = $db_out['username'];
-
-                    if (Visibility::verify('picture', $row['user_id']) == 5) {
-                        $avatar = Avatar::getAvatar($db_out['user_id']);
-                    } else {
-                        $avatar = Avatar::getNobody();
-                    }
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['IMAGE-URL-SMALL'] = $avatar->getURL(Avatar::SMALL);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['IMAGE-URL-MEDIUM'] = $avatar->getURL(Avatar::MEDIUM);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['IMAGE-URL-NORMAL'] = $avatar->getURL(Avatar::NORMAL);
-
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['PHONE'] = ExternModule::ExtHtmlReady($db_out['Telefon']);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['ROOM'] = ExternModule::ExtHtmlReady($db_out['raum']);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['EMAIL'] = get_visible_email($row['user_id']);
-                    $emails = explode('@', $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['EMAIL']);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['EMAIL-LOCAL'] = array_shift($emails);
-                    $emails = explode('@', $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['EMAIL']);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['EMAIL-DOMAIN'] = array_pop($emails);
-                    if ($row['Home'] && Visibility::verify('homepage', $row['user_id'])) {
-                        $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['HOMEPAGE-HREF'] = ExternModule::ExtHtmlReady(trim($row['Home']));
-                    }
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['OFFICEHOURS'] = ExternModule::ExtHtmlReady($db_out['sprechzeiten']);
-                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['PERSON-NO'] = $j + 1;
-
-                    // generic data fields
-                    if (is_array($generic_datafields)) {
-                        $localEntries = DataFieldEntry::getDataFieldEntries($db_out['user_id'], 'user');
-                        #$datafields = $datafields_obj->getLocalFields($db_out->f('user_id'));
-                        $k = 1;
-                        foreach ($generic_datafields as $datafield) {
-                            if (isset($localEntries[$datafield]) &&
-                                    is_object($localEntries[$datafield] &&
-                                    is_element_visible_externally($db_out['user_id'],
-                                        $user_perm, $localEntries[$datafield]->getId(),
-                                        $visibilities[$localEntries[$datafield]->getId()]))) {
-                                if ($localEntries[$datafield]->getType() == 'link') {
-                                    $localEntry = ExternModule::extHtmlReady($localEntries[$datafield]->getValue());
-                                } else {
-                                    $localEntry = $localEntries[$datafield]->getDisplayValue();
-                                }
-                                if ($localEntry) {
-                                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['DATAFIELD_' . $k] = $localEntry;
-                                }
-                            }
-                            $k++;
-                        }
-
-                        $localEntries = DataFieldEntry::getDataFieldEntries([$db_out['user_id'], $instituts_id], 'userinstrole');
-                        if ($grouping) {
-                            $roleEntries = DataFieldEntry::getDataFieldEntries([$db_out['user_id'], $group_id], 'userinstrole');
-                            $roleEntries = array_filter($roleEntries, function($val) { return $val->getValue() !== 'default_value'; });
-                            $localEntries = $roleEntries + $localEntries;
-                        }
-                        $k = 1;
-                        foreach ($generic_datafields as $datafield) {
-                            if (isset($localEntries[$datafield]) &&
-                                    is_object($localEntries[$datafield])) {
-                                $localEntry = $localEntries[$datafield]->getDisplayValue();
-                                if ($localEntry) {
-                                    $content['PERSONS']['GROUP'][$i]['PERSON'][$j]['DATAFIELD_' . $k] = $localEntry;
-                                }
-                            }
-                            $k++;
-                        }
-                    }
-                    $j++;
-                }while ($row = $statement->fetch(PDO::FETCH_ASSOC));
-            }
-            $i++;
-        }
-
-        return $content;
-    }
-
-    function printout ($args) {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-        echo $this->elements['TemplateGeneric']->toString(['content' => $this->getContent($args), 'subpart' => 'PERSONS']);
-
-    }
-
-    function printoutPreview () {
-        if (!$language = $this->config->getValue("Main", "language"))
-            $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateGeneric']->toString(['content' => $this->getContent(), 'subpart' => 'PERSONS', 'hide_markers' => FALSE]);
-
-    }
-
-}
-
-?>
diff --git a/lib/extern/modules/ExternModuleTemplateSemBrowse.class.php b/lib/extern/modules/ExternModuleTemplateSemBrowse.class.php
deleted file mode 100644
index 18a77c0827a..00000000000
--- a/lib/extern/modules/ExternModuleTemplateSemBrowse.class.php
+++ /dev/null
@@ -1,1495 +0,0 @@
-<?php
-# Lifter010: TODO
-/**
-* ExternModuleTemplateSemBrowse.class.php
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternModuleTemplateSemBrowse
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternModuleTemplateSemBrowse.class.php
-//
-// Copyright (C) 2008 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/extern/views/extern_html_templates.inc.php';
-require_once 'lib/dates.inc.php';
-
-class ExternModuleTemplateSemBrowse extends ExternModule {
-
-    var $markers = [];
-    var $args = [];
-    var $sem_browse_data = [];
-    var $search_obj;
-    var $sem_tree;
-    var $range_tree;
-    var $sem_number = [];
-    var $sem_dates;
-    var $sem_types_position = [];
-    var $group_by_fields = [];
-    //var $current_level_name = ''; //only set if tree is rendered with getContentTree()!
-    var $global_markers = [];
-    var $approved_params = [];
-    var $module_params = [];
-    var $classes_show_class = null;
-
-
-    function __construct($range_id, $module_name, $config_id = NULL, $set_config = NULL, $global_id = NULL) {
-
-        $this->data_fields = ['VeranstaltungsNummer', 'Name', 'Untertitel', 'status', 'Ort',
-            'art', 'zeiten', 'dozent'];
-        $this->registered_elements = [
-                'ReplaceTextSemType',
-                'SelectSubjectAreas',
-                'LinkInternLecturedetails' => 'LinkInternTemplate',
-                'LinkInternPersondetails' => 'LinkInternTemplate',
-                'LinkInternSearchForm' => 'LinkInternTemplate',
-                'LinkInternTree' => 'LinkInternTemplate',
-                'LinkInternShowCourses' => 'LinkInternTemplate',
-                'TemplateSimpleSearch' => 'TemplateGeneric',
-                'TemplateExtendedSearch' => 'TemplateGeneric',
-                'TemplateTree' => 'TemplateGeneric',
-                'TemplateResult' => 'TemplateGeneric',
-                'TemplateMain' => 'TemplateGeneric'
-        ];
-        $this->field_names =
-        [
-                _("Veranstaltungsnummer"),
-                _("Name"),
-                _("Untertitel"),
-                _("Status"),
-                _("Ort"),
-                _("Art"),
-                _("Zeiten"),
-                _("Lehrende")
-        ];
-
-        $this->approved_params = ['start_item_id', 'sem', 'do_search', 'quick_search', 'show_result', 'title', 'sub_title', 'number', 'comment', 'lecturer', 'scope', 'combination', 'type', 'qs_choose', 'withkids', 'xls_export', 'group_by', 'start'];
-
-        parent::__construct($range_id, $module_name, $config_id, $set_config, $global_id);
-    }
-
-    function setup () {
-        $this->elements['LinkInternLecturedetails']->real_name = _("Verlinkung zum Modul Veranstaltungsdetails");
-        $this->elements['LinkInternLecturedetails']->link_module_type = [4, 13];
-        $this->elements['LinkInternPersondetails']->real_name = _("Verlinkung zum Modul MitarbeiterInnendetails");
-        $this->elements['LinkInternPersondetails']->link_module_type = [2, 14];
-        $this->elements['LinkInternSearchForm']->real_name = _("Ziel für Suchformular");
-        $this->elements['LinkInternSearchForm']->link_module_type = [15];
-        $this->elements['LinkInternTree']->real_name = _("Ziel für Links auf Ebenen");
-        $this->elements['LinkInternTree']->link_module_type = [15];
-        $this->elements['LinkInternShowCourses']->real_name = _("Ziel für Links auf Ebenen zur Anzeige von Veranstaltungen");
-        $this->elements['LinkInternShowCourses']->link_module_type = [15];
-        $this->elements['TemplateSimpleSearch']->real_name = _("Template einfaches Suchformular");
-        $this->elements['TemplateExtendedSearch']->real_name = _("Template erweitertes Suchformular");
-        $this->elements['TemplateTree']->real_name = _("Template Navigation");
-        $this->elements['TemplateResult']->real_name = _("Template Veranstaltungsliste");
-        $this->elements['TemplateMain']->real_name = _("Haupttemplate");
-
-    }
-
-    function toStringEdit ($open_elements = '', $post_vars = '', $faulty_values = '', $anker = '') {
-
-        $this->updateGenericDatafields('TemplateResult', 'sem');
-        $this->elements['TemplateSimpleSearch']->markers = $this->getMarkerDescription('TemplateSimpleSearch');
-        $this->elements['TemplateExtendedSearch']->markers = $this->getMarkerDescription('TemplateExtendedSearch');
-        $this->elements['TemplateTree']->markers = $this->getMarkerDescription('TemplateTree');
-        $this->elements['TemplateResult']->markers = $this->getMarkerDescription('TemplateResult');
-        $this->elements['TemplateMain']->markers = $this->getMarkerDescription('TemplateMain');
-
-        return parent::toStringEdit($open_elements, $post_vars, $faulty_values, $anker);
-    }
-
-    function getMarkerDescription ($element_name) {
-        $markers['TemplateMain'] = [
-            ['__GLOBAL__', _("Globale Variablen (gültig im gesamten Template).")],
-            ['###CURRENT_SEMESTER###', _("Name des aktuellen Semesters")],
-            ['###CURRENT_LEVEL_NAME###', _("Name der aktuelllen Ebene")],
-            ['###CURRENT_LEVEL_ID###', _("ID der aktuellen Ebene")],
-            ['###CURRENT_LEVEL_INFO###', _("Infotext zur aktuellen Ebene")],
-            ['###TREE_LEVEL_NAME_x###', _("Name der Ebene an Stelle x des Pfades")],
-            ['###TREE_LEVEL_ID_x###', _("Interne ID der Ebene an Stelle x des Pfades")],
-            ['###URL_SEARCH_PARAMS###', _("Such-Parameter, die in einer URL-Query weitergreicht werden")],
-            ['###URL_PERSONDETAILS###', _("URL zur Personendetailseite ohne Auswahlparameter")],
-            ['###URL_LECTUREDETAILS###', _("URL zur Veranstaltungsdetailseite ohne Auswahlparameter")],
-            ['###URL_LEVEL_NO_COURSES###', _("URL zur Zielseite der Ebenenlinks ohne Auswahlparameter")],
-            ['###URL_LEVEL_COURSES###', _("URL zur Zielseite der Ebenenlinks mit Kursansicht ohne Auswahlparameter")],
-            ['###CURRENT_RESULT_PAGE###', _("Nummer der Ergebnisseite der Suche")],
-            ['###NUMBER_OF_RESULT_PAGES###', _("Anzahl der Ergenisseiten der Suche")],
-            ['<!-- BEGIN SEM_BROWSER -->', ''],
-            ['###SIMPLE_SEARCH###', ''],
-            ['###EXTENDED_SEARCH###', ''],
-            ['###TREE###', ''],
-            ['###RESULT###', ''],
-            ['<!-- END SEM_BROWSER -->', '']];
-
-        $markers['TemplateSimpleSearch'] = [
-            ['<!-- BEGIN SEARCH_FORM -->', ''],
-            ['###SEARCHFORM_ACTION_SELECT_SEM###', _("URL zum ändern des Semesters, ohne eine Suche auszulösen")],
-            ['###SEARCHFORM_ACTION###', _("URL, um Suche auszulösen")],
-            ['###SELECT_FIELD###', _("Optionen für Suchfeld")],
-            ['###SELECT_SEMESTER', _("Optionen für Semesterauswahl")],
-            ['###INPUT_SEARCH_TERM###', _("Eingabefeld für Suchbegriff")],
-        //  array('###AJAX_AUTOCOMPLETE###', _("JavaScript für Autovervollständigen des Suchfeldes")),
-            ['###HREF_RESET_SEARCH###', _("Link, der das Suchformular zurücksetzt")],
-            ['<!-- END SEARCH_FORM -->', '']];
-
-        $markers['TemplateExtendedSearch'] = [
-            ['<!-- BEGIN SEARCH_FORM-->', ''],
-            ['###SEARCHFORM_ACTION###', ''],
-            ['###INPUT_TITLE###', _("Eingabefeld für Titel")],
-            ['###INPUT_SUBTITLE###', _("Eingabefeld für Untertitel")],
-            ['###INPUT_NUMBER###', _("Eingabefeld für Veranstaltungsnummer")],
-            ['###INPUT_COMMENT###', _("Eingabefeld für Kommentar zur Veranstaltung")],
-            ['###INPUT_LECTURER###', _("Eingabefeld für Lehrendenname")],
-            ['###INPUT_SUBJECTAREAS###', _("Eingabefeld für Studienbereich")],
-            ['###SELECT_TYPE###', _("Optionen für Veranstaltungstyp")],
-            ['###SELECT_SEMESTER###', _("Optionen für Semesterauswahl")],
-            ['###SELECT_COMBINATION###', _("Optionen für logische Verknüpfung")],
-            ['###HREF_RESET_SEARCH###', _("Link, der das Suchformular zurücksetzt")],
-            ['<!-- END SEARCH_FORM -->', '']];
-
-        $markers['TemplateTree'] = [
-            ['<!-- BEGIN NO_COURSES_LEVEL -->', _("Ausgabe, wenn keine Veranstaltungen auf aktueller Ebene vorhanden sind")],
-            ['<!-- END NO_COURSES_LEVEL -->', ''],
-            ['<!-- BEGIN NO_SUBLEVELS -->', _("Ausgabe, wenn keine Unterebenen vorhanden sind")],
-            ['<!-- END NO_SUBLEVELS -->', ''],
-            ['###COURSE_COUNT_LEVEL###', _("Anzahl der Veranstaltungen der aktueller Ebene")],
-            ['###COURSES_LEVEL-HREF###', _("URL zur Liste mit allen Veranstaltungen der aktuellen Ebene")],
-            ['###COURSE_COUNT_SUBLEVELS###', _("Anzahl der Veranstaltungen aller untergeordneten Ebenen")],
-            ['###COURSES_SUBLEVELS-HREF###', _("URL zur Liste mit allen Veranstaltungen der untergeordneten Ebenen")],
-            ['###ONE_LEVEL_UP-HREF###', _("URL zur übergeordneten Ebene")],
-            ['###CURRENT_LEVEL_NAME###', _("Name des aktuellen Levels")],
-            ['<!-- BEGIN LEVEL_TREE -->', ''],
-            ['<!-- BEGIN LEVEL_PATH -->', _("Anfang des Bereichspfades")],
-            ['<!-- BEGIN LEVEL_PATH_ITEM -->', _("Bereich im Bereichspfad")],
-            ['###LEVEL-HREF###', ''],
-            ['###LEVEL_NAME###', _("Name des Studienbereichs/der Einrichtung")],
-            ['###LEVEL_INFO###', _("Weitere Informationen")],
-            ['<!-- BEGIN LEVEL_NO_INFO -->', ''],
-            ['<!-- END LEVEL_NO_INFO -->', ''],
-            ['<!-- BEGIN PATH_DELIMITER -->', _("Text, der zwischen den einzelnen Ebenen im Pfad ausgegeben wird (nicht nach letzter Ebene)")],
-            ['<!-- END PATH_DELIMITER -->', ''],
-            ['<!-- END LEVEL_PATH_ITEM -->', ''],
-            ['<!-- END LEVEL_PATH -->', ''],
-            ['<!-- BEGIN NO_SUBLEVELS -->', _("Dieser Inhalt wird ausgegeben, wenn keine Unterbereiche vorhanden sind")],
-            ['<!-- END NO_SUBLEVELS -->', ''],
-            ['<!-- BEGIN SUBLEVELS_x -->', _("Beginn der Ebene x mit allen Unterebenen, wobei x die aktuelle Ebenennummer ist (x > 0 und x <= Anzahl der angezeigten Ebenen)")],
-            ['<!-- BEGIN SUBLEVEL_x -->', _("Beginn der aktuellen Ebene x")],
-            ['###SUBLEVEL_RESULT_x###', _("Liste mit Veranstaltungen auf Ebene x (Template Veranstaltungsliste)")],
-            ['<!-- BEGIN NO_LINK_TO_COURSES_x -->', ''],
-            ['###SUBLEVEL-HREF_x###', ''],
-            ['###SUBLEVEL-HREF_SHOW_COURSES_x###', ''],
-            ['###SUBLEVEL_NAME_x###', ''],
-            ['###SUBLEVEL_ID_x###', ''],
-            ['###SUBLEVEL_COURSE_COUNT_x###', _("Anzahl der Veranstaltungen in der Ebene x (einschließlich Unterebenen)")],
-            ['###SUBLEVEL_NO_x###', ''],
-            ['###SUBLEVEL_INFO_x###', _("Weitere Informationen zur Ebene x")],
-            ['<!-- BEGIN SUBLEVEL_NO_INFO_x -->', ''],
-            ['<!-- END SUBLEVEL_NO_INFO_x -->', ''],
-            ['<!-- END NO_LINK_TO_COURSES_x -->', ''],
-            ['<!-- BEGIN LINK_TO_COURSES_x -->', ''],
-            ['###SUBLEVEL-HREF_x###', ''],
-            ['###SUBLEVEL-HREF_SHOW_COURSES_x###', ''],
-            ['###SUBLEVEL_NAME_x###', ''],
-            ['###SUBLEVEL_ID_x###', ''],
-            ['###SUBLEVEL_COURSE_COUNT_x###', _("Anzahl der Veranstaltungen in der Ebene x (einschließlich Unterebenen)")],
-            ['###SUBLEVEL_NO_x###', ''],
-            ['<!-- END LINK_TO_COURSES_x -->', ''],
-            ['<!-- END SUBLEVEL_x -->', ''],
-            ['<!-- END SUBLEVELS_x -->', ''],
-            ['<!-- END LEVEL_TREE -->', '']];
-
-        $markers['TemplateResult'] = [
-            ['__GLOBAL__', _("Globale Variablen (gültig im gesamten Template).")],
-            ['###COURSES_COUNT###', _("Anzahl der Veranstaltungen in der Liste")],
-            ['###COURSES_SUBSTITUTE-GROUPED-BY###', _("Textersetzung für Gruppierungsart")],
-            ['###COURSES_GROUPING###', _("Gruppierungsart")],
-            ['###XLS_EXPORT-HREF###', _("URL zum Export der Veranstaltungsliste")],
-            ['###GROUP_BY_TYPE-HREF###', _("URL für Gruppierung nach Typ")],
-            ['###GROUP_BY_SEMESTER-HREF###', _("URL für Gruppierung nach Semester")],
-            ['###GROUP_BY_RANGE-HREF###', _("URL für Gruppierung nach Studienbereich")],
-            ['###GROUP_BY_LECTURER-HREF###', _("URL für Gruppierung nach Lehrperson")],
-            ['###GROUP_BY_INSTITUTE-HREF###', _("URL für Gruppierung nach Einrichtung")],
-            ['###CURRENT_RESULT_PAGE###', _("Nummer der Ergebnisseite der Suche")],
-            ['###NUMBER_OF_RESULT_PAGES###', _("Anzahl der Ergenisseiten der Suche")],
-            ['<!-- BEGIN NO_COURSES -->', _("Ausgabe, wenn keine Veranstaltungen gefunden wurden")],
-            ['<!-- END NO_COURSES -->', ''],
-            ['<!-- BEGIN RESULT -->', ''],
-            ['<!-- BEGIN GROUP -->', ''],
-            ['###GROUP_NAME###', ''],
-            ['<!-- BEGIN NO_GROUP_NAME -->', _("Geben Sie einen Text ein, der Angezeigt wird, wenn Lehrveranstaltungen vorliegen, die keinem Bereich zugeordnet sind. Nur wirksam in Gruppierung nach Bereich.")],
-            ['<!-- END NO_GROUP_NAME -->', ''],
-            ['###GROUP_INFO###', _("Info-Text für Studienbereiche. Wird nur angezeigt bei Gruppierung nach Bereich.")],
-            ['<!-- BEGIN NO_GROUP_INFO -->', _("Wird angezeigt, wenn kein Info-Text für Bereiche verfügbar ist. Nur bei Gruppierung nach Bereich.")],
-            ['<!-- END NO_GROUP_INFO -->', ''],
-            ['###GROUP-NO###', _("Fortlaufende Gruppennummer")],
-            ['<!-- BEGIN COURSE -->', ''],
-            ['###TITLE###', ''],
-            ['###COURSE_ID###', ''],
-            ['###COURSEDETAILS-HREF###', ''],
-            ['###SUBTITLE###', ''],
-            ['###COURSE_NUMBER###', _("Die Veranstaltungsnummer")],
-            ['###DESCRIPTION###', _("Feld Beschreibung der Veranstaltungsdaten")],
-            ['###ECTS###', _("Feld ECTS der Veranstaltunsdaten")],
-            ['<!-- BEGIN LECTURERS -->', ''],
-            ['###FULLNAME###', ''],
-            ['###LASTNAME###', ''],
-            ['###FIRSTNAME###', ''],
-            ['###TITLEFRONT###', ''],
-            ['###TITLEREAR###', ''],
-            ['###PERSONDETAILS-HREF###', ''],
-            ['###LECTURER-NO###', ''],
-            ['###UNAME###', _("Stud.IP-Username")],
-            ['<!-- BEGIN LECTURER_DELIMITER -->', ''],
-            ['<!-- END LECTURER_DELIMITER -->', ''],
-            ['<!-- END LECTURERS -->', ''],
-            ['<!-- BEGIN NO_LECTURERS -->', _("Wird ausgegeben, wenn keine Lehrenden vorhanden sind.")],
-            ['<!-- END NO_LECTURERS -->', ''],
-            ['###FORM###', _("Die Veranstaltungsart")],
-            ['###SEMTYPE###', ''],
-            ['###SEMTYPE-SUBSTITUTE###', ''],
-            ['###SEMESTER###', ''],
-            ['###LOCATION###', _("Freie Raumangabe")],
-            ['<!-- BEGIN DATES -->', ''],
-            ['<!-- BEGIN REGULAR_DATES -->', ''],
-            ['###TURNUS###', ''],
-            ['<!-- BEGIN REGULAR_DATE -->', ''],
-            ['###DAY_OF_WEEK###', ''],
-            ['###START_TIME###', ''],
-            ['###END_TIME###', ''],
-            ['###START_WEEK###', ''],
-            ['###CYCLE###', ''],
-            ['###REGULAR_DESCRIPTION###', ''],
-            ['<!-- BEGIN REGULAR_ROOMS -->', ''],
-            ['<!-- BEGIN ROOMS -->', ''],
-            ['###ROOM###', ''],
-            ['<!-- BEGIN ROOMS_DELIMITER -->', ''],
-            ['<!-- END ROOMS_DELIMITER -->', ''],
-            ['<!-- END ROOMS -->', ''],
-            ['<!-- BEGIN NO_ROOM -->', _("Wird ausgegeben, wenn kein Raum zum Termin angegeben ist.")],
-            ['<!-- END NO_ROOM -->', ''],
-            ['<!-- BEGIN FREE_ROOMS -->', ''],
-            ['###FREE_ROOM###', ''],
-            ['<!-- BEGIN FREE_ROOMS_DELIMITER -->', ''],
-            ['<!-- END FREE_ROOMS_DELIMITER -->', ''],
-            ['<!-- END FREE_ROOMS -->', ''],
-        //  array('<!-- BEGIN NO_FREE_ROOM -->', _("Wird ausgegeben, wenn keine freie Raumangabe zum Termin angegeben ist")),
-        //  array('<!-- END NO_FREE_ROOM -->', ''),
-            ['<!-- END REGULAR_DATE -->', ''],
-            ['<!-- END REGULAR_DATES -->', ''],
-            ['<!-- END REGULAR_DATA -->', ''],
-            ['<!-- BEGIN IRREGULAR_DATES -->', ''],
-            ['<!-- BEGIN IRREGULAR_DATE -->', ''],
-            ['###DAY_OF_WEEK###', ''],
-            ['###START_TIME###', ''],
-            ['###END_TIME###', ''],
-            ['###DATE###', ''],
-            ['###IRREGULAR_DESCRIPTION###', ''],
-            ['###IRREGUALR_TYPE_MEETING###', _("Ausgabe des Namens des Termintyps, wenn Sitzungstermin")],
-            ['###IRREGUALR_TYPE_OTHER###', _("Ausgabe des Namens des Termintyps, wenn kein Sitzungstermin")],
-            ['###IRREGULAR_ROOM###', ''],
-            ['<!-- BEGIN IRREGULAR_NO_ROOM -->', _("Wird ausgegeben, wenn kein Raum zum Termin angegeben ist")],
-            ['<!-- END IRREGULAR_NO_ROOM -->', ''],
-            ['<!-- BEGIN IRREGULAR_DELIMITER -->', ''],
-            ['<!-- END IRREGULAR_DELIMITER -->', ''],
-            ['<!-- END IRREGULAR_DATE -->', ''],
-            ['<!-- END IRREGULAR_DATES -->',''],
-            ['<!-- END DATES -->', ''],
-            ['###CYCLE###', _("Kommaseparierte, zusammengefasste Temindaten")]];
-            $this->insertDatafieldMarkers('sem', $markers, 'TemplateResult');
-
-        array_push($markers['TemplateResult'],
-            ['<!-- END COURSE -->', ''],
-            ['<!-- END GROUP -->', ''],
-            ['<!-- BEGIN RESULT_BROWSER -->', ''],
-            ['<!-- BEGIN RESULT_BROWSER_PAGES -->', ''],
-            ['<!-- BEGIN RESULT_BROWSER_PAGE -->', ''],
-            ['###RESULT_PAGE_NUMBER###', ''],
-            ['###RESULT_PAGE-HREF###', ''],
-            ['<!-- END RESULT_BROWSER_PAGE -->', ''],
-            ['<!-- BEGIN RESULT_BROWSER_CURRENT_PAGE -->', ''],
-            ['###RESULT_PAGE_NUMBER###', ''],
-            ['###RESULT_PAGE-HREF###', ''],
-            ['<!-- END RESULT_BROWSER_CURRENT_PAGE -->', ''],
-            ['<!-- BEGIN RESULT_PAGE_DELIMITER -->', ''],
-            ['<!-- END RESULT_PAGE_DELIMITER -->', ''],
-            ['<!-- BEGIN RESULT_BROWSER_PAGES_SPLIT -->', ''],
-            ['<!-- END RESULT_BROWSER_PAGES_SPLIT -->', ''],
-            ['<!-- END RESULT_BROWSER_PAGES -->', ''],
-            ['###RESULT_FIRST_PAGE-HREF###', ''],
-            ['###RESULT_LAST_PAGE-HREF###', ''],
-            ['###RESULT_FORWARD-HREF###', ''],
-            ['###RESULT_BACKWARD-HREF###', ''],
-            ['<!-- END RESULT_BROWSER -->', ''],
-            ['<!-- END RESULT -->', '']);
-
-        return $markers[$element_name];
-    }
-
-    function getContent ($args = null, $raw = false) {
-        global $SEM_TYPE,$SEM_CLASS;
-
-        $this->group_by_fields = [ ['name' => _("Semester"), 'group_field' => 'sem_number'],
-                            ['name' => _("Bereich"), 'group_field' => 'bereich'],
-                            ['name' => _("Lehrende"), 'group_field' => 'fullname', 'unique_field' => 'username'],
-                            ['name' => _("Typ"), 'group_field' => 'status'],
-                            ['name' => _("Einrichtung"), 'group_field' => 'Institut', 'unique_field' => 'Institut_id']];
-
-        // initialise data
-        $this->sem_browse_data = [
-            'start_item_id' => $this->getRootStartItemId(),
-            'do_search' => '0',
-            'type' => 'all',
-            'sem' => 'all',
-            'withkids' => '0',
-            'show_result' => '0'
-        ];
-
-        // Daten aus config übernehmen
-        $this->sem_browse_data['group_by'] = $this->config->getValue('Main', 'grouping');
-
-        $level_change = $args['start_item_id'];
-
-        $this->search_obj = new StudipSemSearchHelper(null, true);
-
-        $all_semester = Semester::findAllVisible(false);
-        array_unshift($all_semester,0);
-
-        $switch_time = mktime(0, 0, 0, date('m'), date('d') + 7 * $this->config->getValue('Main', 'semswitch'), date('Y'));
-
-        // get current semester
-        $current_sem = get_sem_num($switch_time) + 1;
-
-        switch ($this->config->getValue('Main', 'semstart')) {
-            case 'previous' :
-                if (isset($all_semester[$current_sem - 1]))
-                    $current_sem--;
-                break;
-            case 'next' :
-                if (isset($all_semester[$current_sem + 1]))
-                    $current_sem++;
-                break;
-            case 'current' :
-                break;
-            default :
-                if (isset($all_semester[$this->config->getValue('Main', 'semstart')]))
-                    $current_sem = $this->config->getValue('Main', 'semstart');
-        }
-        $this->sem_number = [$current_sem];
-        $this->sem_browse_data['sem'] = $current_sem;
-        $sem_classes = (array) $this->config->getValue('Main', 'semclasses');
-        $sem_types_order = (array) $this->config->getValue('ReplaceTextSemType', 'order');
-        $sem_types_visbility = (array) $this->config->getValue('ReplaceTextSemType', 'visibility');
-        foreach ($sem_types_order as $type_id) {
-            if ($sem_types_visbility[$type_id] && in_array($GLOBALS['SEM_TYPE'][$type_id]['class'], $sem_classes)) {
-                $this->sem_browse_data['sem_status'][] = $type_id;
-            }
-        }
-
-        $this->module_params = $this->getModuleParams($this->approved_params);
-        if (!$this->module_params['reset_search']) {
-            $this->sem_browse_data = array_merge($this->sem_browse_data, $this->module_params);
-        }
-
-        $sem_status = (is_array($this->sem_browse_data['sem_status'])) ? $this->sem_browse_data['sem_status'] : false;
-
-        $params = $this->sem_browse_data;
-        // delete array of semester data from the search object's parameters
-        $params['sem_status'] = false;
-        if ($this->config->getValue('Main', 'mode') == 'show_sem_range') {
-            $params['scope_choose'] = $this->sem_browse_data['start_item_id'];
-        } else {
-            $params['range_choose'] = $this->sem_browse_data['start_item_id'];
-        }
-
-        if ($this->sem_browse_data['sem'] == 'all') {
-            $this->sem_number = array_keys($all_semester);
-        } else if (isset($this->sem_browse_data['sem'])) {
-            $this->sem_number = [(int) $this->sem_browse_data['sem']];
-        }
-        // set params for search object
-        $this->search_obj->setParams($params, true);
-
-        if ($this->sem_browse_data['do_search'] == 1) {
-            $this->search_obj->doSearch();
-            $search_result = $this->search_obj->getSearchResultAsArray();
-            if (count($search_result)) {
-                $this->sem_browse_data['search_result'] = array_flip($search_result);
-            } else {
-                $this->sem_browse_data['search_result'] = [];
-            }
-            $this->sem_browse_data['show_result'] = '1';
-            $this->sem_browse_data['show_entries'] = false;
-        } else if ($this->config->getValue('Main', 'mode') == 'show_sem_range') {
-            $this->get_sem_range($this->sem_browse_data['start_item_id'], $this->sem_browse_data['withkids'] == 1);
-        } else { //($this->config->getValue('Main', 'mode') == 'show_sem_range_tree') {
-            $this->get_sem_range_tree($this->sem_browse_data['start_item_id'], $this->sem_browse_data['withkids'] == 1);
-        }
-
-        $this->sem_dates = $all_semester;
-        $this->sem_dates[0] = ['name' => sprintf(_("vor dem %s"),$this->sem_dates[1]['name'])];
-
-        // reorganize the $SEM_TYPE-array
-        foreach ($GLOBALS['SEM_CLASS'] as $key_class => $class) {
-            $i = 0;
-            foreach ($GLOBALS['SEM_TYPE'] as $key_type => $type) {
-                if ($type['class'] == $key_class) {
-                    $i++;
-                    $this->sem_types_position[$key_type] = $i;
-                }
-            }
-        }
-
-        if ($this->sem_browse_data['xls_export']) {
-            $tmp_file = basename($this->createResultXls());
-            if ($tmp_file) {
-                ob_end_clean();
-                header('Location: ' . FileManager::getDownloadURLForTemporaryFile($tmp_file, _("ErgebnisVeranstaltungssuche.xls"), 4));
-                page_close();
-                die;
-            }
-        }
-
-        $this->global_markers['URL_SEARCH_PARAMS'] = '';
-        $search_params = $this->module_params;
-        $param_key = 'ext_' . mb_strtolower($this->name);
-        foreach ($search_params as $key => $value) {
-            $this->global_markers['URL_SEARCH_PARAMS'] .= "&{$param_key}[{$key}]=" . urlencode($value);
-        }
-
-        $this->global_markers['URL_PERSONDETAILS'] = $this->getLinkToModule('LinkInternPersondetails');
-        $this->global_markers['URL_LECTUREDETAILS'] = $this->getLinkToModule('LinkInternLecturedetails');
-        $this->global_markers['URL_LEVEL_NO_COURSES'] = $this->getLinkToModule('LinkInternTree');
-        $this->global_markers['URL_LEVEL_COURSES'] = $this->getLinkToModule('LinkInternShowCourses');
-
-        $this->global_markers['CURRENT_SEMESTER'] = ExternModule::ExtHtmlReady($all_semester[$this->sem_number[0]]['name']);
-
-        if (trim($this->config->getValue('TemplateSimpleSearch', 'template'))) {
-            $content['SEM_BROWSER']['SIMPLE_SEARCH'] = $this->elements['TemplateSimpleSearch']->toString(['content' => $this->getContentSimpleSearch(), 'subpart' => 'SIMPLE_SEARCH']);
-        }
-        if (trim($this->config->getValue('TemplateExtendedSearch', 'template'))) {
-            $content['SEM_BROWSER']['EXTENDED_SEARCH'] = $this->elements['TemplateExtendedSearch']->toString(['content' => $this->getContentExtendedSearch(), 'subpart' => 'EXTENDED_SEARCH']);
-        }
-        if (trim($this->config->getValue('TemplateTree', 'template'))) {
-            $content['SEM_BROWSER']['TREE'] = $this->elements['TemplateTree']->toString(['content' => $this->getContentTree(), 'subpart' => 'TREE']);
-        }
-        if (trim($this->config->getValue('TemplateResult', 'template')) && $this->sem_browse_data['show_result'] == '1') {
-            $content['SEM_BROWSER']['RESULT'] = $this->elements['TemplateResult']->toString(['content' => $this->getContentResult(), 'subpart' => 'RESULT']);
-        }
-        // set super global markers
-        $content['__GLOBAL__'] = $this->global_markers;
-        return $content;
-    }
-
-    function get_sem_range ($item_id, $with_kids) {
-        $tree_args = [];
-        if (!is_object($this->sem_tree)) {
-            $tree_args['sem_status'] = (is_array($this->sem_browse_data['sem_status'])) ? $this->sem_browse_data['sem_status'] : false;
-            $tree_args['sem_number'] = $this->sem_number;
-            $tree_args['visible_only'] = true;
-            $this->sem_tree = TreeAbstract::GetInstance('StudipSemTree', $tree_args);
-            $this->sem_tree->enable_lonely_sem = false;
-        //  $this->sem_tree = new StudipSemTreeViewSimple($this->getRootStartItemId(), $this->sem_number, $sem_status, true);
-        }
-        $sem_ids = $this->sem_tree->getSemIds($item_id, $with_kids);
-
-        if (is_array($sem_ids)){
-            $this->sem_browse_data['search_result'] = array_flip($sem_ids);
-        } else {
-            $this->sem_browse_data['search_result'] = [];
-        }
-    }
-
-    function get_sem_range_tree ($item_id, $with_kids) {
-        $range_object = RangeTreeObject::GetInstance($item_id);
-        if ($with_kids) {
-            $inst_ids = $range_object->getAllObjectKids();
-        }
-        $inst_ids[] = $range_object->item_data['studip_object_id'];
-        $db_view = DbView::getView('sem_tree');
-        $db_view->params[0] = $inst_ids;
-        $db_view->params[1] = ' AND c.visible=1';
-        $db_view->params[1] .= (is_array($this->sem_browse_data['sem_status'])) ? " AND c.status IN('" . join("','",$this->sem_browse_data['sem_status']) ."')" : "";
-        $db_view->params[2] = (is_array($this->sem_number)) ? " HAVING sem_number IN (" . join(",", $this->sem_number) .") OR (sem_number <= " . $this->sem_number[0] . "  AND (sem_number_end >= " . $this->sem_number[0] . " OR sem_number_end = -1)) " : '';
-        $db_snap = new DbSnapshot($db_view->get_query("view:SEM_INST_GET_SEM"));
-        if ($db_snap->numRows) {
-            $sem_ids = $db_snap->getRows("Seminar_id");
-            $this->sem_browse_data['search_result'] = array_flip($sem_ids);
-        } else {
-            $this->sem_browse_data['search_result'] = [];
-        }
-    }
-
-    function getContentSimpleSearch () {
-        $select_qs = '<select name="ext_templatesembrowse[qs_choose]" id="ext_templatesembrowse_qs_choose">';
-        foreach (StudipSemSearchHelper::GetQuickSearchFields() as $key => $value) {
-            if ($this->sem_browse_data['qs_choose'] == $key) {
-                $select_qs .= "<option value=\"$key\" selected=\"selected\">$value</option>";
-            } else {
-                $select_qs .= "<option value=\"$key\">$value</option>";
-            }
-        }
-        $select_qs .= '</select>';
-        $content['SEARCH_FORM'] = [
-            'SELECT_FIELD' => $select_qs,
-            'SELECT_SEMESTER' => $this->getSelectSem(),
-            'INPUT_SEARCH_TERM' => '<input type="text" name="ext_templatesembrowse[quick_search]" id="ext_templatesembrowse_quick_search" value="' . ExternModule::ExtHtmlReady($this->sem_browse_data['quick_search'] ? $this->sem_browse_data['quick_search'] : '') . '" size="' . $this->config->getValue('Main', 'sizeinput') . '" maxlength="50">',
-            'SEARCHFORM_ACTION' => $this->getLinkToSelf(['start_item_id' => $this->sem_browse_data['start_item_id'], 'do_search' => '1'], true, 'LinkInternSearchForm'),
-            'SEARCHFORM_ACTION_SELECT_SEM' => $this->getLinkToSelf(['start_item_id' => $this->sem_browse_data['start_item_id'], 'do_search' => '0', 'show_result' => '1'], true, 'LinkInternSearchForm'),
-            'HREF_RESET_SEARCH' => $this->getLinkToSelf(['start_item_id' => $this->getRootStartItemId()])
-        ];
-
-        return $content;
-    }
-
-    function getSelectSem () {
-        $select_sem = '<select name="ext_templatesembrowse[sem]" id="ext_templatesembrowse_sem" size="1">';
-        $semester = Semester::findAllVisible();
-        $sem_options = [['name' =>_("alle"),'value' => 'all']];
-        for ($i = count($semester) -1; $i >= 0; --$i) {
-            $sem_options[] = ['name' => $semester[$i]['name'], 'value' => "$i"];
-        }
-        foreach ($sem_options as $sem_option) {
-            if ($this->sem_browse_data['sem'] == $sem_option['value']) {
-                $select_sem .= "<option value=\"{$sem_option['value']}\" selected=\"selected\">" . ExternModule::ExtHtmlReady($sem_option['name']) . '</option>';
-            } else {
-                $select_sem .= "<option value=\"{$sem_option['value']}\">" . ExternModule::ExtHtmlReady($sem_option['name']) . '</option>';
-            }
-        }
-        $select_sem .= '</select>';
-
-        return $select_sem;
-    }
-
-    function getContentExtendedSearch () {
-        $content['SEARCH_FORM']['INPUT_TITLE'] = '<input type="text" name="ext_templatesembrowse[title]" id="ext_templatesembrowse_title" value="' . ExternModule::ExtHtmlReady($this->sem_browse_data['title'] ? $this->sem_browse_data['title'] : '') . '" size="' . $this->config->getValue('Main', 'sizeinput') . '" maxlength="150">';
-        $content['SEARCH_FORM']['INPUT_SUBTITLE'] = '<input type="text" name="ext_templatesembrowse[sub_title]" id="ext_templatesembrowse_sub_title" value="' . ExternModule::ExtHtmlReady($this->sem_browse_data['sub_title'] ? $this->sem_browse_data['sub_title'] : '') . '" size="' . $this->config->getValue('Main', 'sizeinput') . '" maxlength="150">';
-        $content['SEARCH_FORM']['INPUT_NUMBER'] = '<input type="text" name="ext_templatesembrowse[number]" id="ext_templatesembrowse_number" value="' . ExternModule::ExtHtmlReady($this->sem_browse_data['number'] ? $this->sem_browse_data['number'] : '') . '" size="' . $this->config->getValue('Main', 'sizeinput') . '" maxlength="50">';
-        $content['SEARCH_FORM']['INPUT_COMMENT'] = '<input type="text" name="ext_templatesembrowse[comment]" id="ext_templatesembrowse_comment" value="' . ExternModule::ExtHtmlReady($this->sem_browse_data['comment'] ? $this->sem_browse_data['comment'] : '') . '" size="' . $this->config->getValue('Main', 'sizeinput') . '" maxlength="150">';
-        $content['SEARCH_FORM']['INPUT_LECTURER'] = '<input type="text" name="ext_templatesembrowse[lecturer]" id="ext_templatesembrowse_lecturer" value="' . ExternModule::ExtHtmlReady($this->sem_browse_data['lecturer'] ? $this->sem_browse_data['lecturer'] : '') . '" size="' . $this->config->getValue('Main', 'sizeinput') . '" maxlength="150">';
-        $content['SEARCH_FORM']['INPUT_SUBJECTAREAS'] = '<input type="text" name="ext_templatesembrowse[scope]" id="ext_templatesembrowsee_scope" value="' . ExternModule::ExtHtmlReady($this->sem_browse_data['scope'] ? $this->sem_browse_data['scope'] : '') . '" size="' . $this->config->getValue('Main', 'sizeinput') . '" maxlength="150">';
-        $content['SEARCH_FORM']['SELECT_TYPE'] = $this->getSelectSemType();
-        $content['SEARCH_FORM']['SELECT_SEMESTER'] = $this->getSelectSem();
-        $content['SEARCH_FORM']['SELECT_COMBINATION'] = '<select name="ext_templatesembrowse[combination]" id="ext_templatesembrowse_combination" size="1">';
-        $content['SEARCH_FORM']['SELECT_COMBINATION'] .= '<option value="AND">' . _("UND") . '</option>';
-        $content['SEARCH_FORM']['SELECT_COMBINATION'] .= '<option value="OR"' . ($this->module_params['combination'] == 'OR' ? ' selected="selected"' : '') . '>' . _("ODER") . '</option></select>';
-        $content['SEARCH_FORM']['SEARCHFORM_ACTION'] = $this->getLinkToSelf(['start_item_id' => $this->sem_browse_data['start_item_id'], 'do_search' => '1', 'start' => '0'], true, 'LinkInternSearchForm');
-        $content['SEARCH_FORM']['HREF_RESET_SEARCH'] = $this->getLinkToSelf(['start_item_id' => $this->getRootStartItemId()]);
-
-        return $content;
-    }
-
-    function getSelectSemType () {
-        $select = '<select name="ext_templatesembrowse[type]" id="ext_templatesembrowse_type" size="1">';
-        $select .= '<option value="all"' . ($this->sem_browse_data['type'] == 'all' ? ' selected="selected"' : '') . '>' . _("alle") . '</option>';
-        foreach ((array) $this->sem_browse_data['sem_status'] as $type_id) {
-            $select .= '<option value="' .  $type_id;
-            if ($this->sem_browse_data['type'] == $type_id) {
-                $select .= '" selected="selected">';
-            } else {
-                $select .= '">';
-            }
-            $select .= ExternModule::ExtHtmlReady($GLOBALS['SEM_TYPE'][$type_id]['name'] .' (' . $GLOBALS['SEM_CLASS'][$GLOBALS['SEM_TYPE'][$type_id]['class']]['name']) . ')</option>';
-        }
-        return $select . '</select>';
-    }
-
-    function getContentTree () {
-        $tree_args['sem_status'] = (is_array($this->sem_browse_data['sem_status'])) ? $this->sem_browse_data['sem_status'] : false;
-        $tree_args['sem_number'] = $this->sem_number;
-        $tree_args['visible_only'] = true;
-        if ($this->config->getValue('Main', 'mode') == 'show_sem_range') {
-            $tree = TreeAbstract::GetInstance('StudipSemTree', $tree_args);
-        } else {
-            $tree = TreeAbstract::GetInstance('StudipRangeTree', $tree_args);
-        }
-        $tree->enable_lonely_sem = false;
-        $j = 0;
-        if ($parents = $tree->getParents($this->sem_browse_data['start_item_id'])) {
-            for ($i = count($parents) - 2; $i >= 0; --$i) {
-                if (trim($tree->tree_data[$parents[$i]]['info'])) {
-                    $info = kill_format(trim($tree->tree_data[$parents[$i]]['info']));
-                } else {
-                    $info = '';
-                    $content['LEVEL_TREE']['LEVEL_PATH']['LEVEL_PATH_ITEM'][$j]['LEVEL_NO_INFO'] = true;
-                }
-                $content['LEVEL_TREE']['LEVEL_PATH']['LEVEL_PATH_ITEM'][$j] = [
-                        'LEVEL-HREF' => $this->getLinkToSelf(['start_item_id' => $parents[$i], 'do_search' => '0', 'show_result' => (($parents[$i] == $this->getRootStartItemId()) ? '1' : '0')], true, 'LinkInternTree'),
-                        'LEVEL_NAME' => ExternModule::ExtHtmlReady($tree->tree_data[$parents[$i]]['name']),
-                        'LEVEL_INFO' => $info
-                ];
-                $content['LEVEL_TREE']['LEVEL_PATH']['LEVEL_PATH_ITEM'][$j]['PATH_DELIMITER'] = true;
-                $this->global_markers['TREE_LEVEL_NAME_' . ($j + 1)] = $content['LEVEL_TREE']['LEVEL_PATH']['LEVEL_PATH_ITEM'][$j]['LEVEL_NAME'];
-                $this->global_markers['TREE_LEVEL_ID_' . ($j + 1)] = $parents[$i];
-                $j++;
-            }
-            if ($j) {
-                // remove last path delimiter
-                unset($content['LEVEL_TREE']['LEVEL_PATH']['LEVEL_PATH_ITEM'][$j - 1]['PATH_DELIMITER']);
-            }
-            // set this as global marker in getContent()
-            $this->global_markers['CURRENT_LEVEL_NAME'] = $tree->getValue($this->sem_browse_data['start_item_id'], 'name');
-            $this->global_markers['CURRENT_LEVEL_ID'] = $this->sem_browse_data['start_item_id'];
-            if (trim($tree->tree_data[$this->sem_browse_data['start_item_id']]['info'])) {
-                $this->global_markers['CURRENT_LEVEL_INFO'] = ExternModule::ExtFormatReady($tree->tree_data[$this->sem_browse_data['start_item_id']]['info']);
-            }
-        }
-
-        $content['LEVEL_TREE']['LEVEL_PATH']['LEVEL_PATH_ITEM'][$j] = [
-                'LEVEL-HREF' => $this->getLinkToSelf(['start_item_id' => $this->sem_browse_data['start_item_id'], 'do_search' => '0', 'show_result' => (($parents[$i] == $this->getRootStartItemId()) ? '1' : '0')], true, 'LinkInternTree'),
-                'LEVEL_NAME' => ExternModule::ExtHtmlReady($tree->tree_data[$this->sem_browse_data['start_item_id']]['name']),
-                'LEVEL_INFO' => kill_format(($tree->tree_data[$this->sem_browse_data['start_item_id']]['info']) ? $tree->tree_data[$this->sem_browse_data['start_item_id']]['info'] :  _("Keine weitere Info vorhanden"))
-        ];
-
-        $content['LEVEL_TREE']['SUBLEVELS_1'] = $this->getAllTreeLevelContent($tree, $this->sem_browse_data['start_item_id'], ($this->config->getValue('Main', 'countshowsublevels') ? $this->config->getValue('Main', 'countshowsublevels') : 0));
-
-        $content['__GLOBAL__'] = $this->global_markers;
-        if ($tree->hasKids($this->sem_browse_data['start_item_id']) && ($num_entries = $tree->getNumEntries($this->sem_browse_data['start_item_id'], true))) {
-            $content['__GLOBAL__']['COURSE_COUNT_SUBLEVELS'] = $num_entries;
-            $content['__GLOBAL__']['COURSES_SUBLEVELS-HREF'] = $this->getLinkToSelf(['start_item_id' => $this->sem_browse_data['start_item_id'], 'show_result' => '1', 'withkids' => '1', 'do_search' => '0'], true, 'LinkInternTree');
-        }
-
-        if ($num_entries = $tree->getNumEntries($this->sem_browse_data['start_item_id'])) {
-            $content['__GLOBAL__']['COURSE_COUNT_LEVEL'] = $num_entries;
-            $content['__GLOBAL__']['COURSES_LEVEL-HREF'] = $this->getLinkToSelf(['start_item_id' => $this->sem_browse_data['start_item_id'], 'show_result' => '1', 'withkids' => '0', 'do_search' => '0'], true, 'LinkInternTree');
-        } else {
-            $content['__GLOBAL__']['NO_COURSES_LEVEL'] = true;
-        }
-
-        return $content;
-    }
-
-
-    function getAllTreeLevelContent (&$tree, $start_item_id, $max_level, $level = 0) {
-        if (($num_kids = $tree->getNumKids($start_item_id)) && $level <= $max_level) {
-            $level++;
-            if ($this->config->getValue('SelectSubjectAreas', 'selectallsubjectareas')) {
-                $kids = $tree->getKids($start_item_id);
-            } else if (is_array($this->config->getValue('SelectSubjectAreas', 'subjectareasselected'))) {
-                if ($this->config->getValue('SelectSubjectAreas', 'reverseselection')) {
-                    $kids = array_diff($tree->getKids($start_item_id), $this->config->getValue('SelectSubjectAreas', 'subjectareasselected'));
-                } else {
-                    $kids = array_intersect($tree->getKids($start_item_id), $this->config->getValue('SelectSubjectAreas', 'subjectareasselected'));
-                }
-            } else {
-                return false;
-            }
-            $count = 0;
-            foreach ($kids as $kid) {
-                $num_entries = $tree->getNumEntries($kid, true);
-                if (!($this->config->getValue('Main', 'disableemptylevels') && $num_entries == 0)) {
-                    if (trim($tree->tree_data[$kid]['info'])) {
-                        $info = kill_format(trim($tree->tree_data[$kid]['info']));
-                    } else {
-                        $info = '';
-                        $content['SUBLEVEL_' . $level][$count]['SUBLEVEL_NO_INFO_' . $level] = true;
-                    }
-                    $level_content = [
-                            'SUBLEVEL_NAME_' . $level => ExternModule::ExtHtmlReady($tree->tree_data[$kid]['name']),
-                            'SUBLEVEL_ID_' . $level => $kid,
-                            'SUBLEVEL_COURSE_COUNT_' . $level => $num_entries,
-                            'SUBLEVEL_NO_' . $level => $count + 1,
-                            'SUBLEVEL_INFO_' . $level => $info
-                    ];
-                    $content['SUBLEVEL_' . $level][$count]['SUBLEVEL_RESULT_' . $level] = $this->elements['TemplateResult']->toString(['content' => $this->getContentResult($kid), 'subpart' => 'RESULT']);
-                    if ($this->config->getValue('LinkInternShowCourses', 'config') && $tree->getNumEntries($kid, false)) {
-                        $content['SUBLEVEL_' . $level][$count]['LINK_TO_COURSES_' . $level] = $level_content;
-                        $content['SUBLEVEL_' . $level][$count]['LINK_TO_COURSES_' . $level]['SUBLEVEL-HREF_SHOW_COURSES_' . $level] = $this->getLinkToSelf(['start_item_id' => $kid, 'show_result' => '1', 'withkids' => '1', 'do_search' => '0'], true, 'LinkInternShowCourses');
-                        $content['SUBLEVEL_' . $level][$count]['NO_LINK_TO_COURSES_' . $level]['SUBLEVEL-HREF_' . $level] = $this->getLinkToSelf(['start_item_id' => $kid, 'show_result' => '1', 'withkids' => '1', 'do_search' => '0'], true, 'LinkInternTree');
-                        $content['SUBLEVEL_' . $level][$count]['NO_LINK_TO_COURSES_' . $level] = false;
-                    } else {
-                        $content['SUBLEVEL_' . $level][$count]['NO_LINK_TO_COURSES_' . $level] = $level_content;
-                        $content['SUBLEVEL_' . $level][$count]['NO_LINK_TO_COURSES_' . $level]['SUBLEVEL-HREF_' . $level] = $this->getLinkToSelf(['start_item_id' => $kid, 'show_result' => '1', 'withkids' => '1', 'do_search' => '0'], true, 'LinkInternTree');
-                        $content['SUBLEVEL_' . $level][$count]['LINK_TO_COURSES_' . $level] = false;
-                    }
-                    if ($sublevel = $this->getAllTreeLevelContent($tree, $kid, $max_level, $level)) {
-                        $content['SUBLEVEL_' . $level][$count]['SUBLEVELS_' . ($level + 1)] = $sublevel;
-                    }
-                    $count++;
-                }
-            }
-            return $content;
-        }
-        return false;
-    }
-
-    function getContentResult ($level_id = null) {
-        global $_fullname_sql, $SEM_TYPE, $SEM_CLASS;
-        $content['__GLOBAL__'] = $this->global_markers;
-        if (is_array($this->sem_browse_data['search_result']) && count($this->sem_browse_data['search_result'])) {
-            list($group_by_data, $sem_data) = $this->getResult($level_id);
-            if (count($sem_data)) {
-                $content['__GLOBAL__']['COURSES_COUNT'] = count($sem_data);
-                $content['__GLOBAL__']['COURSES_GROUPING'] = $this->group_by_fields[$this->sem_browse_data['group_by']]['name'];
-                $group_by_name = $this->config->getValue('Main', 'aliasesgrouping');
-                $content['__GLOBAL__']['COURSES_SUBSTITUTE-GROUPED-BY'] = $group_by_name[$this->sem_browse_data['group_by']];
-                $content['__GLOBAL__']['XLS_EXPORT-HREF'] = $this->getLinkToSelf(['xls_export' => '1'], true);
-                $content['__GLOBAL__']['GROUP_BY_TYPE-HREF'] = $this->getLinkToSelf(['group_by' => '3'], true);
-                $content['__GLOBAL__']['GROUP_BY_SEMESTER-HREF'] = $this->getLinkToSelf(['group_by' => '0'], true);
-                $content['__GLOBAL__']['GROUP_BY_RANGE-HREF'] = $this->getLinkToSelf(['group_by' => '1'], true);
-                $content['__GLOBAL__']['GROUP_BY_LECTURER-HREF'] = $this->getLinkToSelf(['group_by' => '2'], true);
-                $content['__GLOBAL__']['GROUP_BY_INSTITUTE-HREF'] = $this->getLinkToSelf(['group_by' => '4'], true);
-                $j = 0;
-                $semester = Semester::findAllVisible();
-                foreach ($group_by_data as $group_field => $sem_ids) {
-                    switch ($this->sem_browse_data['group_by']) {
-                        case 0:
-                            ExternModule::ExtHtmlReady($content['RESULT']['GROUP'][$j]['GROUP_NAME'] = $semester[$group_field]['name']);
-                        break;
-                        case 1:
-                            if (!is_object($this->sem_tree)) {
-                                $this->sem_tree = TreeAbstract::GetInstance("StudipSemTree");
-                            }
-                            if ($this->sem_tree->tree_data[$group_field]) {
-                                $range_path_level = $this->config->getValue('Main', 'rangepathlevel');
-                                $content['RESULT']['GROUP'][$j]['GROUP_NAME'] = ExternModule::ExtHtmlReady($this->sem_tree->getShortPath($group_field, NULL, '>', $range_path_level ? $range_path_level - 1 : 0));
-                                $content['RESULT']['GROUP'][$j]['NO_GROUP_INFO'] = true;
-                            } else {
-                                $content['RESULT']['GROUP'][$j]['NO_GROUP_NAME'] = true;
-                            }
-                        break;
-                        case 3:
-                            $aliases_sem_type = $this->config->getValue('ReplaceTextSemType', "class_{$SEM_TYPE[$group_field]['class']}");
-                            if ($aliases_sem_type[$this->sem_types_position[$group_field] - 1]) {
-                                $content['RESULT']['GROUP'][$j]['GROUP_NAME'] = $aliases_sem_type[$this->sem_types_position[$group_field] - 1];
-                            } else {
-                                $content['RESULT']['GROUP'][$j]['GROUP_NAME'] = ExternModule::ExtHtmlReady($SEM_TYPE[$group_field]['name'].' ('. $SEM_CLASS[$SEM_TYPE[$group_field]['class']]['name'].')');
-                            }
-                        break;
-                        default:
-                            $content['RESULT']['GROUP'][$j]['GROUP_NAME'] = ExternModule::ExtHtmlReady($group_field);
-                    }
-                    $content['RESULT']['GROUP'][$j]['GROUP-NO'] = $j + 1;
-
-                    if (is_array($sem_ids['Seminar_id'])) {
-                        $k = 0;
-                        $semester = Semester::findAllVisible();
-                        foreach (array_keys($sem_ids['Seminar_id'])  as $seminar_id) {
-                            $sem_object = Seminar::GetInstance($seminar_id);
-
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['COURSE_ID'] = $seminar_id;
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['TITLE'] = ExternModule::ExtHtmlReady($sem_object->name);
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['COURSE-NO'] = $k + 1;
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['COURSEDETAILS-HREF'] = $this->elements['LinkInternLecturedetails']->createUrl(['link_args' => 'seminar_id=' . $seminar_id]);
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['COURSE_NUMBER'] = ExternModule::ExtHtmlReady(key($sem_data[$seminar_id]['VeranstaltungsNummer']));
-
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['DESCRIPTION'] = ExternModule::ExtHtmlReady($sem_object->beschreibung, true);
-
-                            $sem_number_start = key($sem_data[$seminar_id]["sem_number"]);
-                            $sem_number_end = key($sem_data[$seminar_id]["sem_number_end"]);
-                            if ($sem_number_start != $sem_number_end) {
-                                $sem_name = $semester[$sem_number_start]['name'] . " - ";
-                                $sem_name .= (($sem_number_end == -1) ? _("unbegrenzt") : $semester[$sem_number_end]['name']);
-                            } else {
-                                $sem_name = $semester[$sem_number_start]['name'];
-                            }
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['SEMESTER'] = ExternModule::ExtHtmlReady($sem_name);
-
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['DATES'] = $this->getDates($seminar_id, $semester[$this->sem_browse_data['sem']]['beginn'], $semester[$this->sem_browse_data['sem']]['ende']);
-                            if (!sizeof($content['RESULT']['GROUP'][$j]['COURSE'][$k]['DATES'])) {
-                                $content['RESULT']['GROUP'][$j]['COURSE'][$k]['NO_DATES_TEXT'] = [];
-                            }
-
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['SUBTITLE'] = ExternModule::ExtHtmlReady($sem_object->untertitel);
-                            $aliases_sem_type = $this->config->getValue('ReplaceTextSemType', 'class_' . $SEM_TYPE[key($sem_data[$seminar_id]['status'])]['class']);
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['SEMTYPE-SUBSTITUTE'] = $aliases_sem_type[$this->sem_types_position[key($sem_data[$seminar_id]['status'])] - 1];
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['SEMTYPE'] = ExternModule::ExtHtmlReady($SEM_TYPE[key($sem_data[$seminar_id]['status'])]['name']
-                                        .' ('. $SEM_CLASS[$SEM_TYPE[key($sem_data[$seminar_id]['status'])]['class']]['name'] . ')');
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['LOCATION'] = ExternModule::ExtHtmlReady(trim($sem_object->ort));
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['FORM'] = ExternModule::ExtHtmlReady($sem_object->art);
-                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['ECTS'] = ExternModule::ExtHtmlReady(key($sem_data[$seminar_id]['ects']));
-
-                            // generic data fields
-                            $generic_datafields = $this->config->getValue('TemplateResult', 'genericdatafields');
-                            if (is_array($generic_datafields)) {
-                                $localEntries = DataFieldEntry::getDataFieldEntries($seminar_id, 'sem', $SEM_TYPE[key($sem_data[$seminar_id]['status'])]['class']);
-                                $m = 1;
-                                foreach ($generic_datafields as $datafield) {
-                                    if (isset($localEntries[$datafield]) && is_object($localEntries[$datafield])) {
-                                        if ($localEntries[$datafield]->getType() == 'link') {
-                                            $localEntry = ExternModule::extHtmlReady($localEntries[$datafield]->getValue());
-                                        } else {
-                                            $localEntry = $localEntries[$datafield]->getDisplayValue();
-                                        }
-                                        if ($localEntry) {
-                                            $content['RESULT']['GROUP'][$j]['COURSE'][$k]['DATAFIELD_' . $m] = $localEntry;
-                                        }
-                                    }
-                                    $m++;
-                                }
-                            }
-
-                            $doz_name = array_keys($sem_data[$seminar_id]['fullname']);
-                            $doz_uname = array_keys($sem_data[$seminar_id]['username']);
-                            $doz_lastname = array_keys($sem_data[$seminar_id]['Nachname']);
-                            $doz_firstname = array_keys($sem_data[$seminar_id]['Vorname']);
-                            $doz_titlefront = array_keys($sem_data[$seminar_id]['title_front']);
-                            $doz_titlerear = array_keys($sem_data[$seminar_id]['title_rear']);
-                            $doz_position = array_keys($sem_data[$seminar_id]['position']);
-                            if (is_array($doz_name)) {
-                                if (count($doz_position) != count($doz_uname)) {
-                                    $doz_position = range(1, count($doz_uname));
-                                }
-                                array_multisort($doz_position, $doz_name, $doz_uname);
-                                $l = 0;
-                                foreach ($doz_name as $index => $value) {
-                                    $content['RESULT']['GROUP'][$j]['COURSE'][$k]['LECTURERS'][$l]['UNAME'] = $doz_uname[$index];
-                                    $content['RESULT']['GROUP'][$j]['COURSE'][$k]['LECTURERS'][$l]['PERSONDETAILS-HREF'] = $this->elements['LinkInternPersondetails']->createUrl(['link_args' => 'username=' . $doz_uname[$index] . '&seminar_id=' . $seminar_id]);
-                                    $content['RESULT']['GROUP'][$j]['COURSE'][$k]['LECTURERS'][$l]['FULLNAME'] = ExternModule::ExtHtmlReady($doz_name[$index]);
-                                    $content['RESULT']['GROUP'][$j]['COURSE'][$k]['LECTURERS'][$l]['LASTNAME'] = ExternModule::ExtHtmlReady($doz_lastname[$index]);
-                                    $content['RESULT']['GROUP'][$j]['COURSE'][$k]['LECTURERS'][$l]['FIRSTNAME'] = ExternModule::ExtHtmlReady($doz_firstname[$index]);
-                                    $content['RESULT']['GROUP'][$j]['COURSE'][$k]['LECTURERS'][$l]['TITLEFRONT'] = ExternModule::ExtHtmlReady($doz_titlefront[$index]);
-                                    $content['RESULT']['GROUP'][$j]['COURSE'][$k]['LECTURERS'][$l]['TITLEREAR'] = ExternModule::ExtHtmlReady($doz_titlerear[$index]);
-                                    $content['RESULT']['GROUP'][$j]['COURSE'][$k]['LECTURERS'][$l]['LECTURER-NO'] = $l + 1;
-                                    $content['RESULT']['GROUP'][$j]['COURSE'][$k]['LECTURERS'][$l]['LECTURER_DELIMITER'] = true;
-                                    $l++;
-                                }
-                                // remove last delimiter
-                                unset($content['RESULT']['GROUP'][$j]['COURSE'][$k]['LECTURERS'][$l - 1]['LECTURER_DELIMITER']);
-                            } else {
-                                $content['RESULT']['GROUP'][$j]['COURSE'][$k]['NO_LECTURERS'] = true;
-                            }
-                            $k++;
-                        }
-                    }
-                    $j++;
-                }
-                if ($this->config->getValue('Main', 'maxnumberofhits')) {
-                    array_push($content['RESULT'], $this->getResultBrowser());
-                }
-            } else {
-                $content['__GLOBAL__']['NO_COURSES'] = true;
-            }
-        } else {
-            $content['__GLOBAL__']['NO_COURSES'] = true;
-        }
-        return $content;
-    }
-
-    /**
-     * Generates markers and subparts for a result browser.
-     *
-     * @return array Array with markers and their values
-     */
-    function getResultBrowser()
-    {
-        $result_pages = ceil(sizeof($this->sem_browse_data['search_result']) / $this->config->getValue('Main', 'maxnumberofhits'));
-        // only one page no result browser needed
-        if ($result_pages < 2) {
-            return '';
-        }
-        $this->global_markers['NUMBER_OF_RESULT_PAGES'] = $result_pages;
-        $page_split = $result_pages;
-        if ($result_pages > $this->config->getValue('Main', 'maxpagesresultbrowser')) {
-            $page_split = ceil($this->config->getValue('Main', 'maxpagesresultbrowser') / 2);
-        }
-        $start_page = ceil($this->module_params['start']) /  $this->config->getValue('Main', 'maxnumberofhits');
-        $start_page -= (($start_page < $page_split) ? ($start_page % ($page_split)) : 0);
-
-        if ($start_page > abs($result_pages - $this->config->getValue('Main', 'maxpagesresultbrowser'))) {
-            $start_page = $result_pages - $this->config->getValue('Main', 'maxpagesresultbrowser');
-        }
-
-        $splitted = false;
-        $i = $start_page;
-        while ($i < $result_pages) {
-            if ($i < $page_split + $start_page + 1 || $i > ($result_pages - $page_split)) {
-                if ($this->module_params['start'] == $i * $this->config->getValue('Main', 'maxnumberofhits')) {
-                    $subpart_name = 'RESULT_BROWSER_CURRENT_PAGE';
-                    $this->global_markers['CURRENT_RESULT_PAGE'] = $i + 1;
-                } else {
-                    $subpart_name = 'RESULT_BROWSER_PAGE';
-                }
-                $content['RESULT_BROWSER']['RESULT_BROWSER_PAGES'][$i][$subpart_name]['RESULT_PAGE_NUMBER'] = $i + 1;
-                $content['RESULT_BROWSER']['RESULT_BROWSER_PAGES'][$i][$subpart_name]['RESULT_PAGE-HREF'] = $this->getLinkToSelf(['start_item_id' => $this->sem_browse_data['start_item_id'], 'do_search' => '1', 'start' => $i * $this->config->getValue('Main', 'maxnumberofhits')], true, 'LinkInternSearchForm');
-                $content['RESULT_BROWSER']['RESULT_BROWSER_PAGES'][$i]['RESULT_PAGE_DELIMITER'] = true;
-            } else {
-                if (!$splitted) {
-                    $content['RESULT_BROWSER']['RESULT_BROWSER_PAGES'][$i]['RESULT_BROWSER_PAGES_SPLIT'] = true;
-                    $splitted = true;
-                }
-            }
-            $i++;
-        }
-        unset($content['RESULT_BROWSER']['RESULT_BROWSER_PAGES'][$i]['RESULT_PAGE_DELIMITER']);
-        $start = ceil($this->module_params['start'] / $this->config->getValue('Main', 'maxnumberofhits') + 1) * $this->config->getValue('Main', 'maxnumberofhits');
-        if ($start < sizeof($this->sem_browse_data['search_result'])) {
-            $content['RESULT_BROWSER']['RESULT_FORWARD-HREF'] = $this->getLinkToSelf(['start_item_id' => $this->sem_browse_data['start_item_id'], 'do_search' => '1', 'start' => $start], true, 'LinkInternSearchForm');
-            $content['RESULT_BROWSER']['RESULT_LAST_PAGE-HREF'] = $this->getLinkToSelf(['start_item_id' => $this->sem_browse_data['start_item_id'], 'do_search' => '1', 'start' => floor(sizeof($this->sem_browse_data['search_result']) / $this->config->getValue('Main', 'maxnumberofhits')) * $this->config->getValue('Main', 'maxnumberofhits')], true, 'LinkInternSearchForm');
-        }
-        $start = ceil($this->module_params['start'] / $this->config->getValue('Main', 'maxnumberofhits') - 1) * $this->config->getValue('Main', 'maxnumberofhits');
-        if ($start >= 0) {
-            $content['RESULT_BROWSER']['RESULT_BACKWARD-HREF'] = $this->getLinkToSelf(['start_item_id' => $this->sem_browse_data['start_item_id'], 'do_search' => '1', 'start' => $start], true, 'LinkInternSearchForm');
-            $content['RESULT_BROWSER']['RESULT_FIRST_PAGE-HREF'] = $this->getLinkToSelf(['start_item_id' => $this->sem_browse_data['start_item_id'], 'do_search' => '1', 'start' => '0'], true, 'LinkInternSearchForm');
-        }
-
-        return $content;
-    }
-
-    function getDates ($seminar_id, $start_time = 0, $end_time = 0) {
-        $dow_array = [_("So"), _("Mo"), _("Di"), _("Mi"), _("Do"), _("Fr"), _("Sa")];
-        $cycles_array = [_("wöchentlich"), _("zweiwöchentlich"), _("dreiwöchentlich")];
-
-        $cont = [];
-        // irregular dates
-        $meta = new MetaDate($seminar_id);
-        if ($meta->getTurnus() == 1) {
-            $cont['REGULAR_DATES']['TURNUS'] = true;
-        }
-        if ($meta->getStartWoche()) {
-            $cont['REGULAR_DATES']['START_WEEK'] = $meta->getStartWoche();
-        }
-
-        $i = 0;
-
-        $cycle_data = $meta->getCycleData();
-
-        foreach ($cycle_data as $metadate_id => $cycle) {
-            $cont['REGULAR_DATES']['REGULAR_DATE'][$i] = [
-                'DAY_OF_WEEK' => $dow_array[$cycle['day']],
-                'START_TIME' => sprintf('%02d:%02d', $cycle['start_hour'], $cycle['start_minute']),
-                'END_TIME' => sprintf('%02d:%02d', $cycle['end_hour'], $cycle['end_minute']),
-                'START_WEEK' => $cycle['week_offset'] + 1,
-                'CYCLE' => $cycles_array[(int)$cycle['cycle']],
-                'REGULAR_DESCRIPTION' => ExternModule::ExtHtmlReady(trim($cycle['desc'])),
-                'REGULAR_DELIMITER' => true];
-            $k = 0;
-            if (Config::get()->RESOURCES_ENABLE) {
-                if (($resource_ids = CycleDataDB::getPredominantRoomDB($metadate_id, $start_time, $end_time)) !== false) {
-                    foreach ($resource_ids as $resource_id => $foo) {
-                        $resource = Resource::find($resource_id);
-                        if (!($resource instanceof Resource)) {
-                            continue;
-                        }
-                        $cont['REGULAR_DATES']['REGULAR_DATE'][$i]['REGULAR_ROOMS']['ROOMS'][$k]['ROOM'] = ExternModule::ExtHtmlReady(trim($resource->name));
-                        $cont['REGULAR_DATES']['REGULAR_DATE'][$i]['REGULAR_ROOMS']['ROOMS'][$k]['ROOMS_DELIMITER'] = true;
-                        $k++;
-                    }
-                    unset($cont['REGULAR_DATES']['REGULAR_DATE'][$i]['REGULAR_ROOMS']['ROOMS'][$k - 1]['ROOMS_DELIMITER']);
-                }
-            }
-            if (!$k) {
-                if (($free_rooms = CycleDataDB::getFreeTextPredominantRoomDB($metadate_id, $start_time, $end_time)) !== false) {
-                    foreach ($free_rooms as $free_room => $foo) {
-                        $cont['REGULAR_DATES']['REGULAR_DATE'][$i]['REGULAR_ROOMS']['FREE_ROOMS'][$k]['FREE_ROOM'] = ExternModule::ExtHtmlReady(trim($free_room));
-                        $cont['REGULAR_DATES']['REGULAR_DATE'][$i]['REGULAR_ROOMS']['FREE_ROOMS'][$k]['FREE_ROOMS_DELIMITER'] = true;
-                        $k++;
-                    }
-                    unset($cont['REGULAR_DATES']['REGULAR_DATE'][$i]['REGULAR_ROOMS']['FREE_ROOMS'][$k - 1]['FREE_ROOMS_DELIMITER']);
-                } else {
-                    $cont['REGULAR_DATES']['REGULAR_DATE'][$i]['NO_ROOM'] = true;
-                }
-            }
-    //      if (!$k) {
-        //      $cont['REGULAR_DATES']['REGULAR_DATE'][$i]['REGULAR_ROOMS']['NO_FREE_ROOM'] = true;
-            //}
-            $i++;
-        }
-        // remove last delimiter
-        if ($i) {
-            unset($cont['REGULAR_DATES']['REGULAR_DATE'][$i - 1]['REGULAR_DELIMITER']);
-        }
-        // regular dates
-        if ($start_time && $end_time) {
-            $dates = SeminarDB::getSingleDates($seminar_id, $start_time, $end_time);
-        } else {
-            $dates = [];
-        }
-        $i = 0;
-        $selected_types = $this->config->getValue('Main', 'selectedeventtypes');
-
-        foreach ($dates as $date) {
-            if (in_array('all', $selected_types) || (in_array('meeting', $selected_types) && $GLOBALS['TERMIN_TYP'][$date['date_typ']]['sitzung']) || (in_array('other', $selected_types) && !$GLOBALS['TERMIN_TYP'][$date['date_typ']]['sitzung']) || in_array($date['date_typ'], $selected_types)) {
-                $cont['IRREGULAR_DATES']['IRREGULAR_DATE'][$i] = [
-                    'DAY_OF_WEEK' => $dow_array[date('w', $date['date'])],
-                    'START_TIME' => date('H:i', $date['date']),
-                    'END_TIME' => date('H:i', $date['end_time']),
-                    'DATE' => date('d.m.y', $date['date']),
-                    'IRREGULAR_DESCRIPTION' => ExternModule::ExtHtmlReady(trim($date['description'])),
-                    'IRREGULAR_DELIMITER' => true];
-                if ($GLOBALS['TERMIN_TYP'][$date['date_typ']]['sitzung']) {
-                    $cont['IRREGULAR_DATES']['IRREGULAR_DATE'][$i]['IRREGULAR_TYPE_MEETING'] = $GLOBALS['TERMIN_TYP'][$date['date_typ']]['name'];
-                } else {
-                    $cont['IRREGULAR_DATES']['IRREGULAR_DATE'][$i]['IRREGULAR_TYPE_OTHER'] = $GLOBALS['TERMIN_TYP'][$date['date_typ']]['name'];
-                }
-                if (Config::get()->RESOURCES_ENABLE && $date['resource_id']) {
-                    $resource = Resource::find($date['resource_id']);
-                    if ($resource instanceof Resource) {
-                        $cont['IRREGULAR_DATES']['IRREGULAR_DATE'][$i]['IRREGULAR_ROOM'] = ExternModule::ExtHtmlReady(trim($resource->name));
-                    }
-                } else if (trim($date['raum'])) {
-                    $cont['IRREGULAR_DATES']['IRREGULAR_DATE'][$i]['IRREGULAR_ROOM'] = ExternModule::ExtHtmlReady(trim($date['raum']));
-                } else {
-                    $cont['IRREGULAR_DATES']['IRREGULAR_DATE'][$i]['IRREGULAR_NO_ROOM'] = true;
-                }
-            }
-            $i++;
-        }
-        // remove last delimiter
-        if ($i) {
-            unset($cont['IRREGULAR_DATES']['IRREGULAR_DATE'][$i - 1]['IRREGULAR_DELIMITER']);
-        }
-        return $cont;
-    }
-
-
-    function getResult ($level_id = null) {
-        global $_fullname_sql,$SEM_TYPE,$SEM_CLASS;
-        $add_fields = '';
-        $add_query = '';
-        $sem_tree_query = '';
-        $limit_sql = '';
-        $orderby_field = ($this->config->getValue('Main', 'resultorderby') ? $this->config->getValue('Main', 'resultorderby') : 'VeranstaltungsNummer');
-        if ($this->sem_browse_data['group_by'] == 1
-            || (sizeof($this->config->getValue('SelectSubjectAreas', 'subjectareasselected'))
-            && !($this->config->getValue('SelectSubjectAreas', 'selectallsubjectareas') || $this->sem_browse_data['start_item_id'] == 'root'))) {
-            if ($this->config->getValue('Main', 'mode') == 'show_sem_range' &&  $this->sem_browse_data['start_item_id'] != 'root') {
-                $allowed_ranges = [];
-                if (is_null($level_id)) {
-                    if (!is_object($this->sem_tree)){
-                        $this->sem_tree = TreeAbstract::GetInstance('StudipSemTree');
-                    }
-                    if ($kids = $this->sem_tree->getKidsKids($this->sem_browse_data['start_item_id'])) {
-                        $allowed_ranges = $kids;
-                    }
-                    $allowed_ranges[] = $this->sem_browse_data['start_item_id'];
-                } else {
-                    $allowed_ranges[] = $level_id;
-                }
-
-                if ($this->config->getValue('SelectSubjectAreas', 'selectallsubjectareas')) {
-                    $sem_tree_query = " AND sem_tree_id IN('" . join("','", $allowed_ranges) . "') ";
-                } elseif (is_array($this->config->getValue('SelectSubjectAreas', 'subjectareasselected'))) {
-                    if ($this->config->getValue('SelectSubjectAreas', 'reverseselection')) {
-                        $allowed_ranges = array_diff($allowed_ranges, $this->config->getValue('SelectSubjectAreas', 'subjectareasselected'));
-                    } else {
-                        $allowed_ranges = array_intersect($allowed_ranges, $this->config->getValue('SelectSubjectAreas', 'subjectareasselected'));
-                    }
-                    $sem_tree_query = " AND sem_tree_id IN('" . join("','", $allowed_ranges) . "') ";
-                } else {
-                    return [[], []];
-                }
-            }
-            $add_fields = 'seminar_sem_tree.sem_tree_id AS bereich,';
-            $add_query = "LEFT JOIN seminar_sem_tree ON (seminare.Seminar_id = seminar_sem_tree.seminar_id)";
-        } else if ($this->config->getValue('Main', 'maxnumberofhits')) {
-                $limit_sql = ' ORDER BY sem_number DESC, ' . $orderby_field . ' ASC LIMIT ' . ($this->module_params['start'] ? intval($this->module_params['start']) : '0') . ',' . $this->config->getValue('Main', 'maxnumberofhits');
-        }
-        if ($this->sem_browse_data['group_by'] == 4) {
-            $add_fields = 'Institute.Name AS Institut,Institute.Institut_id,';
-            $add_query = 'LEFT JOIN seminar_inst ON (seminare.Seminar_id = seminar_inst.Seminar_id)
-            LEFT JOIN Institute ON (Institute.Institut_id = seminar_inst.institut_id)';
-        }
-        // show only selected SemTypes
-        $selected_semtypes = $this->config->getValue('ReplaceTextSemType', 'visibility');
-        $sem_types_array = [];
-        if (count($selected_semtypes)) {
-            foreach ($selected_semtypes as $i => $active) {
-                if ($active == '1') {
-                    $sem_types_array[] = $i + 1;
-                }
-            }
-            $sem_types_query = "AND seminare.status IN ('" . implode("','", $sem_types_array) . "')";
-        } else {
-            $sem_types_query = '';
-        }
-
-        if (!$nameformat = $this->config->getValue('Main', 'nameformat')) {
-            $nameformat = 'full_rev';
-        }
-        $dbv = DbView::getView('sem_tree');
-        $query = "SELECT seminare.Seminar_id, VeranstaltungsNummer, seminare.status, seminare.Untertitel, seminare.Ort, seminare.art, seminare.Beschreibung, seminare.ects, IF(seminare.visible=0,CONCAT(seminare.Name, ' ". _("(versteckt)") ."'), seminare.Name) AS Name,
-                $add_fields" . $_fullname_sql[$nameformat] ." AS fullname, auth_user_md5.username, title_front, title_rear, Vorname, Nachname,
-                " . $dbv->sem_number_sql . " AS sem_number, " . $dbv->sem_number_end_sql . " AS sem_number_end, seminar_user.position AS position FROM seminare
-                LEFT JOIN seminar_user ON (seminare.Seminar_id=seminar_user.Seminar_id AND seminar_user.status='dozent')
-                LEFT JOIN auth_user_md5 USING (user_id)
-                LEFT JOIN user_info USING (user_id)
-                $add_query
-                WHERE seminare.Seminar_id IN('" . join("','", array_keys($this->sem_browse_data['search_result'])) . "') $sem_types_query $sem_tree_query $limit_sql";
-        $db = new DB_Seminar($query);
-        if (!$db->num_rows()) {
-            return [[], []];
-        }
-        $snap = new DbSnapshot($db);
-        $group_field = $this->group_by_fields[$this->sem_browse_data['group_by']]['group_field'];
-        $data_fields[0] = 'Seminar_id';
-        if ($this->group_by_fields[$this->sem_browse_data['group_by']]['unique_field']) {
-            $data_fields[1] = $this->group_by_fields[$this->sem_browse_data['group_by']]['unique_field'];
-        }
-        $group_by_data = $snap->getGroupedResult($group_field, $data_fields);
-        $sem_data = $snap->getGroupedResult('Seminar_id');
-        if ($this->sem_browse_data['group_by'] == 0) {
-            $semester = Semester::findAllVisible();
-            $group_by_duration = $snap->getGroupedResult('sem_number_end', ['sem_number', 'Seminar_id']);
-            foreach ($group_by_duration as $sem_number_end => $detail) {
-                if ($sem_number_end != -1 && ($detail['sem_number'][$sem_number_end] && count($detail['sem_number']) == 1)) {
-                    continue;
-                } else {
-                    foreach ($detail['Seminar_id'] as $seminar_id => $foo) {
-                        $start_sem = key($sem_data[$seminar_id]['sem_number']);
-                        if ($sem_number_end == -1){
-                            $sem_number_end = count($semester) - 1;
-                        }
-                        for ($i = $start_sem; $i <= $sem_number_end; ++$i) {
-                            if ($this->sem_number === false || (is_array($this->sem_number) && in_array($i, $this->sem_number))) {
-                                if ($group_by_data[$i] && !$tmp_group_by_data[$i]) {
-                                    foreach($group_by_data[$i]['Seminar_id'] as $id => $bar) {
-                                        $tmp_group_by_data[$i]['Seminar_id'][$id] = true;
-                                    }
-                                }
-                                $tmp_group_by_data[$i]['Seminar_id'][$seminar_id] = true;
-                            }
-                        }
-                    }
-                }
-            }
-            if (is_array($tmp_group_by_data)){
-                if ($this->sem_number !== false){
-                    unset($group_by_data);
-                }
-                foreach ($tmp_group_by_data as $start_sem => $detail){
-                    $group_by_data[$start_sem] = $detail;
-                }
-            }
-        }
-
-        //release memory
-        unset($snap);
-        unset($tmp_group_by_data);
-
-        foreach ($group_by_data as $group_field => $sem_ids) {
-            foreach ($sem_ids['Seminar_id'] as $seminar_id => $foo) {
-                if ($orderby_field) {
-                    $name = mb_strtolower(key($sem_data[$seminar_id][$orderby_field]));
-                } else {
-                    $name = mb_strtolower(key($sem_data[$seminar_id]["VeranstaltungsNummer"]));
-                }
-                $name = str_replace(['ä', 'ö', 'ü'], ['ae', 'oe', 'ue'], $name);
-                $group_by_data[$group_field]['Seminar_id'][$seminar_id] = $name;
-            }
-            uasort($group_by_data[$group_field]['Seminar_id'], 'strnatcmp');
-        }
-
-        switch ($this->sem_browse_data['group_by']) {
-            case 0:
-                krsort($group_by_data, SORT_NUMERIC);
-                break;
-
-            case 1:
-                uksort($group_by_data, function ($a, $b) {
-                    $the_tree = TreeAbstract::GetInstance('StudipSemTree', false);
-                    $the_tree->buildIndex();
-                    return $the_tree->tree_data[$a]['index'] - $the_tree->tree_data[$b]['index'];
-                });
-                break;
-
-            case 3:
-                uksort($group_by_data, function ($a,$b) {
-                    global $SEM_CLASS,$SEM_TYPE;
-                    return strnatcasecmp(
-                        $SEM_TYPE[$a]['name'] . ' (' . $SEM_CLASS[$SEM_TYPE[$a]['class']]['name'] . ')',
-                        $SEM_TYPE[$b]['name'] . ' (' . $SEM_CLASS[$SEM_TYPE[$b]['class']]['name'] . ')'
-                    );
-                });
-                break;
-            default:
-                uksort($group_by_data, 'strnatcasecmp');
-                break;
-        }
-
-        return [$group_by_data, $sem_data];
-    }
-
-    function show_class(){
-        if ($this->sem_browse_data['show_class'] == 'all'){
-            return true;
-        }
-        if (!is_array($this->classes_show_class)){
-            $this->classes_show_class = [];
-            foreach ($GLOBALS['SEM_CLASS'] as $sem_class_key => $sem_class){
-                if ($sem_class['bereiche']){
-                    $this->classes_show_class[] = $sem_class_key;
-                }
-            }
-        }
-        return in_array($this->sem_browse_data['show_class'], $this->classes_show_class);
-    }
-
-    function printout ($args) {
-            if (!$language = $this->config->getValue("Main", "language"))
-                    $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateMain']->toString(['content' => $this->getContent(), 'subpart' => 'LECTURES']);
-
-    }
-
-    function printoutPreview () {
-            if (!$language = $this->config->getValue("Main", "language"))
-                    $language = "de_DE";
-        init_i18n($language);
-
-        echo $this->elements['TemplateMain']->toString(['content' => $this->getContent(), 'subpart' => 'LECTURES', 'hide_markers' => FALSE]);
-
-    }
-
-    function getRootStartItemId () {
-        if ($this->config->getValue('Main', 'startitem') == 'root') {
-            return 'root';
-        }
-        $db = DBManager::get();
-        if ($this->config->getValue('Main', 'mode') == 'show_sem_range') {
-                    $stmt = $db->prepare("SELECT sem_tree_id AS item_id FROM sem_tree WHERE studip_object_id = ? AND parent_id = 'root'");
-                } else {
-                    $stmt = $db->prepare("SELECT item_id FROM range_tree WHERE studip_object_id = ? AND parent_id = 'root'");
-                }
-        $stmt->execute([$this->config->range_id]);
-        return $stmt->fetchColumn() ?: false;
-    }
-
-    function createResultXls () {
-        require_once "vendor/write_excel/OLEwriter.php";
-        require_once "vendor/write_excel/BIFFwriter.php";
-        require_once "vendor/write_excel/Worksheet.php";
-        require_once "vendor/write_excel/Workbook.php";
-
-        global $_fullname_sql, $SEM_TYPE, $SEM_CLASS, $TMP_PATH;
-
-        $headline = _("Stud.IP Veranstaltungen") . ' - ' . Config::get()->UNI_NAME_CLEAN;
-        if (is_array($this->sem_browse_data['search_result']) && count($this->sem_browse_data['search_result'])) {
-            if (!is_object($this->sem_tree)){
-                $the_tree = TreeAbstract::GetInstance("StudipSemTree", false);
-            } else {
-                $the_tree = $this->sem_tree;
-            }
-            list($group_by_data, $sem_data) = $this->getResult();
-            $tmpfile = $TMP_PATH . '/' . md5(uniqid('write_excel',1));
-            // Creating a workbook
-            $workbook = new Workbook($tmpfile);
-            $head_format =& $workbook->addformat();
-            $head_format->set_size(12);
-            $head_format->set_bold();
-            $head_format->set_align("left");
-            $head_format->set_align("vcenter");
-
-            $head_format_merged =& $workbook->addformat();
-            $head_format_merged->set_size(12);
-            $head_format_merged->set_bold();
-            $head_format_merged->set_align("left");
-            $head_format_merged->set_align("vcenter");
-            $head_format_merged->set_merge();
-            $head_format_merged->set_text_wrap();
-
-            $caption_format =& $workbook->addformat();
-            $caption_format->set_size(10);
-            $caption_format->set_align("left");
-            $caption_format->set_align("vcenter");
-            $caption_format->set_bold();
-            //$caption_format->set_text_wrap();
-
-            $data_format =& $workbook->addformat();
-            $data_format->set_size(10);
-            $data_format->set_align("left");
-            $data_format->set_align("vcenter");
-
-            $caption_format_merged =& $workbook->addformat();
-            $caption_format_merged->set_size(10);
-            $caption_format_merged->set_merge();
-            $caption_format_merged->set_align("left");
-            $caption_format_merged->set_align("vcenter");
-            $caption_format_merged->set_bold();
-
-
-            // Creating the first worksheet
-            $worksheet1 = $workbook->addworksheet(_("Veranstaltungen"));
-            $worksheet1->set_row(0, 20);
-            $worksheet1->write_string(0, 0, mb_convert_encoding($headline, 'WINDOWS-1252') ,$head_format);
-            $worksheet1->set_row(1, 20);
-            $worksheet1->write_string(
-                1,
-                0,
-                mb_convert_encoding(sprintf(
-                    _('%s Veranstaltungen gefunden %s, Gruppierung: %s'),
-                    count($sem_data),
-                    $this->sem_browse_data['sset'] ? '(' . _('Suchergebnis') . ')' : '',
-                    $this->group_by_fields[$this->sem_browse_data['group_by']]['name']
-                ), 'WINDOWS-1252'),
-                $caption_format
-            );
-
-            $worksheet1->write_blank(0,1,$head_format);
-            $worksheet1->write_blank(0,2,$head_format);
-            $worksheet1->write_blank(0,3,$head_format);
-
-            $worksheet1->write_blank(1,1,$head_format);
-            $worksheet1->write_blank(1,2,$head_format);
-            $worksheet1->write_blank(1,3,$head_format);
-
-            $worksheet1->set_column(0, 0, 70);
-            $worksheet1->set_column(0, 1, 25);
-            $worksheet1->set_column(0, 2, 25);
-            $worksheet1->set_column(0, 3, 50);
-
-            $row = 2;
-
-            foreach ($group_by_data as $group_field => $sem_ids){
-                switch ($this->sem_browse_data["group_by"]){
-                    case 0:
-                    $semester = Semester::findAllVisible();
-                    $headline = $semester[$group_field]['name'];
-                    break;
-
-                    case 1:
-                    if ($the_tree->tree_data[$group_field]) {
-                        $headline = $the_tree->getShortPath($group_field);
-                    } else {
-                        $headline =  _("keine Studienbereiche eingetragen");
-                    }
-                    break;
-
-                    case 3:
-                    $headline = $SEM_TYPE[$group_field]["name"]." (". $SEM_CLASS[$SEM_TYPE[$group_field]["class"]]["name"].")";
-                    break;
-
-                    default:
-                    $headline = $group_field;
-                    break;
-
-                }
-                ++$row;
-                $worksheet1->write_string($row, 0 , mb_convert_encoding($headline, 'WINDOWS-1252') , $caption_format);
-                $worksheet1->write_blank($row,1, $caption_format);
-                $worksheet1->write_blank($row,2, $caption_format);
-                $worksheet1->write_blank($row,3, $caption_format);
-                ++$row;
-                if (is_array($sem_ids['Seminar_id'])) {
-                    $semester = Semester::findAllVisible();
-                    foreach (array_keys($sem_ids['Seminar_id']) as $seminar_id) {
-                        $seminar_obj = new Seminar($seminar_id);
-                        $sem_name = $seminar_obj->name;
-                        $seminar_number = key($sem_data[$seminar_id]['VeranstaltungsNummer']);
-                        $sem_number_start = key($sem_data[$seminar_id]["sem_number"]);
-                        $sem_number_end = key($sem_data[$seminar_id]["sem_number_end"]);
-                        if ($sem_number_start != $sem_number_end) {
-                            $sem_name .= ' (' . $semester[$sem_number_start]['name'] . ' - ';
-                            $sem_name .= (($sem_number_end == -1) ? _("unbegrenzt") : $semester[$sem_number_end]['name']) . ')';
-                        } elseif ($this->sem_browse_data['group_by']) {
-                            $sem_name .= ' (' . $semester[$sem_number_start]['name'] . ")";
-                        }
-                        //create Turnus field
-                        // is this sem a studygroup?
-                        $studygroup_mode = SeminarCategories::GetByTypeId($seminar_obj->getStatus())->studygroup_mode;
-                        if ($studygroup_mode) {
-                            $sem_name = $seminar_obj->getName() . ' ('. _("Studiengruppe");
-                            if ($seminar_obj->admission_prelim) $sem_name .= ', '. _("Zutritt auf Anfrage");
-                            $sem_name .= ')';
-                        }
-                        $worksheet1->write_string($row, 0, mb_convert_encoding($sem_name, 'WINDOWS-1252'), $data_format);
-                        $temp_turnus_string = $seminar_obj->getFormattedTurnus(true);
-                        //Shorten, if string too long (add link for details.php)
-                        if (mb_strlen($temp_turnus_string) > 245) {
-                            $temp_turnus_string = mb_substr($temp_turnus_string, 0, mb_strpos(mb_substr($temp_turnus_string, 245, mb_strlen($temp_turnus_string)), ",") + 246);
-                            $temp_turnus_string .= " ... ("._("mehr").")";
-                        }
-                        $worksheet1->write_string($row, 1, mb_convert_encoding($seminar_number, 'WINDOWS-1252'), $data_format);
-                        $worksheet1->write_string($row, 2, mb_convert_encoding($temp_turnus_string, 'WINDOWS-1252'), $data_format);
-
-                        $doz_name = [];
-                        $c = 0;
-                        reset($sem_data[$seminar_id]['fullname']);
-                        foreach($sem_data[$seminar_id]['username'] as $anzahl1){
-                            if($c == 0){
-                                $d_name = key($sem_data[$seminar_id]['fullname']);
-                                $anzahl2 = current($anzahl2);
-                                next($sem_data[$seminar_id]['fullname']);
-                                $c = $anzahl2/$anzahl1;
-                                $doz_name = array_merge($doz_name, array_fill(0, $c, $d_name));
-                            }
-                            --$c;
-                        }
-                        $doz_position = array_keys($sem_data[$seminar_id]['position']);
-                        if (is_array($doz_name)){
-                            if(count($doz_position) != count($doz_name)) $doz_position = range(1, count($doz_name));
-                            array_multisort($doz_position, $doz_name);
-                            $worksheet1->write_string($row, 3, mb_convert_encoding(join(', ', $doz_name), 'WINDOWS-1252'), $data_format);
-                        }
-                        ++$row;
-                    }
-                }
-            }
-            $workbook->close();
-        }
-        return $tmpfile;
-    }
-
-    public function getAllDates ($seminar, $start, $end) {
-        $data = $seminar->getUndecoratedData();
-        $date = [];
-
-        $i = 0;
-        if (is_array($data['regular']['turnus_data'])) {
-            foreach ($data['regular']['turnus_data'] as $cycle_id => $cycle) {
-                $date[$i]['time'] = sprintf('%02d:%02d - %02d:%02d', $cycle['start_hour'], $cycle['start_minute'], $cycle['end_hour'], $cycle['end_minute']);
-                $date[$i]['interval'] = (empty($data['regular']['turnus']) ? '' : _("14-täglich"));
-                if (Config::get()->RESOURCES_ENABLE) {
-                    if ($room_ids = $seminar->metadate->cycles[$cycle_id]->getPredominantRoom($start, $end)) {
-                        $room_names = [];
-                        foreach ($room_ids as $room_id) {
-                            $resource = Resource::find($room_id);
-                            if ($resource) {
-                                $room_names[] = $resource->name;
-                            }
-                        }
-                        $date[$i]['room'] = implode(', ', $room_names);
-                    } else {
-                        $date[$i]['room'] = trim($seminar->metadate->cycles[$cycle_id]->getFreeTextPredominantRoom($start, $end));
-                    }
-                    $date[$i]['dow'] = getWeekDay($cycle['day']);
-                }
-                $i++;
-            }
-        }
-        if (sizeof( (array) $data['irregular'])) {
-            foreach ($data['irregular'] as $irregular_date) {
-                if ($irregular_date['start_time'] >= $start && $irregular_date['start_time'] <= $end) {
-                    $date[$i]['time'] = date('H:i', $irregular_date['start_time']) . date(' - H:i', $irregular_date['end_time']);
-                    $date[$i]['date'] = strftime('%x', $irregular_date['start_time']);
-                    $date[$i]['dow'] = getWeekDay(date('w', $irregular_date['start_time']));
-                    if (Config::get()->RESOURCES_ENABLE && $irregular_date['resource_id']) {
-                        $resource = Resource::find($irregular_date['resource_id']);
-                        if ($resource instanceof Resource) {
-                            $date[$i]['room'] = $resource->name;
-                        }
-                    } else {
-                        $date[$i]['room'] = trim($irregular_date['raum']);
-                    }
-                    $i++;
-                }
-            }
-        }
-
-        return $date;
-    }
-
-}
diff --git a/lib/extern/modules/views/ExternRangeLectureTree.class.php b/lib/extern/modules/views/ExternRangeLectureTree.class.php
deleted file mode 100644
index d8337fc4c53..00000000000
--- a/lib/extern/modules/views/ExternRangeLectureTree.class.php
+++ /dev/null
@@ -1,170 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter003: TEST
-# Lifter007: TODO
-# Lifter010: TODO
-
-/**
-* class to print out the range tree
-*
-* This class prints out a html representation of the tree for the "extern modules"
-*
-* @access   public
-* @author   André Noack <noack@data-quest.de>
-* @package
-*/
-class ExternRangeLectureTree
-{
-    var $tree;
-    var $config;
-    var $param;
-    var $root_id;
-    var $start_item_id;
-
-    /**
-    * constructor
-    *
-    * @access public
-    */
-    function __construct(&$config, $start_item_id, $sem_number = false, $sem_status = false)
-    {
-        $this->config = $config;
-
-        $query = "SELECT item_id FROM range_tree WHERE studip_object_id = ?";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$this->config->range_id]);
-        $this->root_id = $statement->fetchColumn();
-
-        $this->start_item_id = $start_item_id ?: $this->root_id;
-        $args = NULL;
-        if ($sem_number !== false) {
-            $args['sem_number'] = $sem_number;
-        }
-        if ($sem_status !== false) {
-            $args['sem_status'] =  $sem_status;
-        }
-        $this->param = "range_id={$this->config->range_id}&module=Rangelecturetree&config_id={$this->config->id}&";
-
-        $this->tree = TreeAbstract::GetInstance("StudipRangeTree",$args);
-    }
-
-    function showSemRangeTree () {
-        echo "\n<table" . $this->config->getAttributes("Main", "table") . ">";
-        echo "\n<tr><td>". $this->getSemPath() . "</td></tr>\n<tr><td>";
-        $this->showContent($this->start_item_id);
-        echo "\n</td></tr>";
-        if ($this->tree->getNumKids($this->start_item_id)) {
-            echo "\n<tr><td>";
-            echo $this->showKids($this->start_item_id);
-            echo "\n</td></tr>";
-        }
-        if ($this->config->getAttributes("TreeBackLink", "image")
-                || $this->config->getAttributes("TreeBackLink", "linktext")) {
-            echo "\n<tr><td>";
-            echo $this->backLink($this->start_item_id) . "\n</td></tr>";
-        }
-        echo "\n</table>";
-    }
-
-    function showKids ($item_id) {
-        $num_kids = $this->tree->getNumKids($item_id);
-        $kids = $this->tree->getKids($item_id);
-        $attributes_a = $this->config->getAttributes("TreeKids", "a");
-        $attributes_font = $this->config->getAttributes("TreeKids", "font");
-        $attributes_td = $this->config->getAttributes("TreeKids", "td");
-        echo "\n<table width=\"100%\" border=\"0\"";
-        echo $this->config->getAttributes("TreeKids", "table") . ">";
-        for ($i = 0; $i < $num_kids; ++$i){
-            $num_entries = $this->tree->getNumEntries($kids[$i],true);
-            echo "<tr>\n<td$attributes_td>";
-            echo "<a href=\"" .URLHelper::getLink($this->getSelf("{$this->param}start_item_id={$kids[$i]}", false));
-            echo "\"$attributes_a><font$attributes_font>";
-            echo htmlReady($this->tree->tree_data[$kids[$i]]['name']);
-            echo "&nbsp;($num_entries)";
-            echo "</font></a>";
-            echo "</td></tr>\n";
-        }
-        echo "</table>\n";
-    }
-
-    function backLink ($item_id) {
-        if ($item_id != $this->root_id){
-            echo "<table width=\"100%\" border=\"0\"";
-            echo $this->config->getAttributes("TreeBackLink", "table") . ">\n";
-            echo "<tr><td" . $this->config->getAttributes("TreeBackLink", "td") . ">";
-            if ($image = $this->config->getValue("TreeBackLink", "image")) {
-                echo "<a href=\"" .URLHelper::getLink($this->getSelf("{$this->param}start_item_id={$this->tree->tree_data[$item_id]['parent_id']}", false)) . "\">";
-                echo "<img src=\"$image\" border=\"0\"></a>&nbsp;";
-            }
-            if ($link_text = $this->config->getValue("TreeBackLink", "linktext")) {
-                echo "<a href=\"" .URLHelper::getLink($this->getSelf("{$this->param}start_item_id={$this->tree->tree_data[$item_id]['parent_id']}", false)) . "\">";
-                echo "<font" . $this->config->getAttributes("TreeBackLink", "font");
-                echo ">" . htmlReady($link_text) . "</font></a>";
-            }
-            echo "</td></tr></table>\n";
-        }
-    }
-
-    function showContent ($item_id) {
-        echo "<table" . $this->config->getAttributes("RangeTreeLevelName", "table");
-        echo ">\n<tr><td" . $this->config->getAttributes("RangeTreeLevelName", "td") . ">";
-        echo "<font" . $this->config->getAttributes("RangeTreeLevelName", "font") . ">";
-        $alias_names = $this->config->getValue("RangeTreeLevelName", "aliases");
-        $range_object = RangeTreeObject::GetInstance($item_id);
-        if ($range_object->item_data['type'])
-            $name = $alias_names[$range_object->item_data['type_num'] - 1] . " ";
-        $name .= $range_object->item_data['name'];
-        echo htmlReady($name) ."</font></td></tr>\n</table>\n";
-        if (is_array($range_object->item_data_mapping)) {
-            echo "</td></tr><tr><td>\n";
-            echo "<table" . $this->config->getAttributes("RangeTreeLevelContent", "table");
-            echo ">\n<tr><td" . $this->config->getAttributes("RangeTreeLevelContent", "td") . ">";
-            $alias_mapping = $this->config->getValue("RangeTreeLevelContent", "mapping");
-            $aliases = $this->config->getValue("RangeTreeLevelContent", "aliases");
-            foreach ($alias_mapping as $position => $key) {
-                if ($range_object->item_data[$key]) {
-                    echo "<font" . $this->config->getAttributes("RangeTreeLevelContent", "fontalias") . ">";
-                    echo htmlReady($aliases[$position]) . "&nbsp;</font>";
-                    echo "<font" . $this->config->getAttributes("RangeTreeLevelContent", "fontdata") . ">";
-                    echo formatLinks($range_object->item_data[$key]) . "&nbsp; </font>";
-                }
-            }
-            echo "</td></tr></table>\n";
-        }
-    }
-
-    function getSemPath () {
-        $delimiter = $this->config->getValue("TreePath", "delimiter");
-        $attributes_a = $this->config->getAttributes("TreePath", "a");
-        $ret = "<table width=\"100%\"";
-        $ret .= $this->config->getAttributes("TreePath", "table") . "><tr>\n";
-        $ret .= "<td". $this->config->getAttributes("TreePath", "td") . ">";
-        $ret .= "<font". $this->config->getAttributes("TreePath", "td") . ">";
-        $parents = $this->tree->getParents($this->start_item_id);
-        $parents_root = $this->tree->getParents($this->root_id);
-        if (is_array($parents)) {
-            $parents = array_diff($parents, $parents_root);
-            while ($parent = array_pop($parents)) {
-                $ret .= $delimiter;
-                $ret .= "<a href=\"" . URLHelper::getLink($this->getSelf("{$this->param}start_item_id=".$parent,false));
-                $ret .= "\"$attributes_a>" . htmlReady($this->tree->tree_data[$parent]["name"]) . "</a>";
-            }
-        }
-        if ($this->start_item_id != $this->root_id)
-            $ret .= $delimiter;
-        $ret .= htmlReady($this->tree->tree_data[$this->start_item_id]["name"]);
-        $ret .= "</font></td></tr></table>\n";
-
-        return $ret;
-    }
-
-
-
-    function getSelf ($param = "", $with_start_item = true) {
-        if ($param)
-            $url = $_SERVER['PHP_SELF'] . (($with_start_item) ? "?start_item_id=" . $this->start_item_id . "&" : "?") . $param ;
-        else
-            $url = $_SERVER['PHP_SELF'] . (($with_start_item) ? "?start_item_id=" . $this->start_item_id : "") ;
-        return $url;
-    }
-}
diff --git a/lib/extern/modules/views/ExternSemBrowse.class.php b/lib/extern/modules/views/ExternSemBrowse.class.php
deleted file mode 100644
index a5e86db00bc..00000000000
--- a/lib/extern/modules/views/ExternSemBrowse.class.php
+++ /dev/null
@@ -1,545 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternSemBrowse.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternSemBrowse
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternSemBrowse.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/dates.inc.php';
-
-class ExternSemBrowse extends SemBrowse {
-
-    var $module;
-    var $config;
-    var $sem_types_position;
-    var $sem_dates;
-
-    function __construct(&$module, $start_item_id) {
-
-        global $SEM_TYPE,$SEM_CLASS;
-        // prevent warnings if snapshot of database is empty
-        ob_start();
-        $all_semester = Semester::findAllVisible(false);
-        array_unshift($all_semester,0);
-
-        $this->group_by_fields = [ ['name' => _("Semester"), 'group_field' => 'sem_number'],
-                                        ['name' => _("Bereich"), 'group_field' => 'bereich'],
-                                        ['name' => _("Lehrende"), 'group_field' => 'fullname', 'unique_field' => 'username'],
-                                        ['name' => _("Typ"), 'group_field' => 'status'],
-                                        ['name' => _("Einrichtung"), 'group_field' => 'Institut', 'unique_field' => 'Institut_id']];
-
-        $this->module = $module;
-        $this->config = $this->module->config;
-        $this->sem_browse_data["group_by"] = $this->config->getValue("Main", "grouping");
-        $this->sem_dates = $all_semester;
-        $this->sem_dates[0] = ["name" => _("abgelaufene Semester")];
-
-        // reorganize the $SEM_TYPE-array
-        foreach ($SEM_CLASS as $key_class => $class) {
-            $i = 0;
-            foreach ($SEM_TYPE as $key_type => $type) {
-                if ($type["class"] == $key_class) {
-                    $i++;
-                    $this->sem_types_position[$key_type] = $i;
-                }
-            }
-        }
-
-        // Is a semester switch defined?
-        $week_offset = $this->config->getValue('Main', 'semswitch');
-        if (ctype_digit($week_offset)) {
-            $switch_time = strtotime("+{$week_offset} weeks 0:00:00");
-        } else {
-            $switch_time = strtotime('0:00:00');
-        }
-
-        // get current semester
-        $current_sem = get_sem_num($switch_time) + 1;
-
-        switch ($this->config->getValue("Main", "semstart")) {
-            case "previous" :
-                if (isset($all_semester[$current_sem - 1]))
-                    $current_sem--;
-                break;
-            case "next" :
-                if (isset($all_semester[$current_sem + 1]))
-                    $current_sem++;
-                break;
-            case "current" :
-                break;
-            default :
-                if (isset($all_semester[$this->config->getValue("Main", "semstart")]))
-                    $current_sem = $this->config->getValue("Main", "semstart");
-        }
-
-        $last_sem = $current_sem + $this->config->getValue("Main", "semrange");
-        if ($last_sem < $current_sem)
-            $last_sem = $current_sem;
-        if (!isset($all_semester[$last_sem]))
-            $last_sem = sizeof($all_semester);
-
-        for ($i = $last_sem; $i > $current_sem; $i--)
-            $this->sem_number[] = $i - 1;
-
-        $semclasses = $this->config->getValue("Main", "semclasses");
-        foreach ($SEM_TYPE as $key => $type) {
-            if (in_array($type["class"], $semclasses))
-                $this->sem_browse_data['sem_status'][] = $key;
-        }
-
-        $this->get_sem_range_tree($start_item_id, true);
-    }
-
-    function print_result () {
-        global $_fullname_sql,$SEM_TYPE,$SEM_CLASS;
-
-        if (is_array($this->sem_browse_data['search_result']) && count($this->sem_browse_data['search_result'])) {
-
-            // show only selected subject areas
-            $selected_ranges = $this->config->getValue('SelectSubjectAreas', 'subjectareasselected');
-            if ($stid = Request::option('sem_tree_id')) {
-                if (!is_object($this->sem_tree)){
-                    $the_tree = TreeAbstract::GetInstance("StudipSemTree");
-                } else {
-                    $the_tree =& $this->sem_tree->tree;
-                }
-                $the_tree->buildIndex();
-                $selected_ranges = array_merge([$stid], $the_tree->getKidsKids($stid));
-            }
-            if (!$this->config->getValue('SelectSubjectAreas', 'selectallsubjectareas') && $selected_ranges) {
-                if ($this->config->getValue('SelectSubjectAreas', 'reverseselection')) {
-                    $sem_range_query =  "AND seminar_sem_tree.sem_tree_id NOT IN ('".implode("','", $selected_ranges)."')";
-                } else {
-                    $sem_range_query =  "AND seminar_sem_tree.sem_tree_id IN ('".implode("','", $selected_ranges)."')";
-                }
-            } else {
-                $sem_range_query = '';
-            }
-
-            // show only selected SemTypes
-            $selected_semtypes = $this->config->getValue('ReplaceTextSemType', 'visibility');
-            if (Request::get('semstatus')) {
-                $selected_semtypes = [Request::get('semstatus')];
-            }
-            $sem_types_array = [];
-            if ($selected_semtypes) {
-                foreach ($selected_semtypes as $i => $active) {
-                    if ($active == '1') {
-                        $sem_types_array[] = $i + 1;
-                    }
-                }
-                $sem_types_query = "AND seminare.status IN ('" . implode("','", $sem_types_array) . "')";
-            } else {
-                $sem_types_query = '';
-            }
-
-            if ($this->sem_browse_data['group_by'] == 1){
-                if (!is_object($this->sem_tree)){
-                    $the_tree = TreeAbstract::GetInstance("StudipSemTree");
-                } else {
-                    $the_tree =& $this->sem_tree->tree;
-                }
-                $the_tree->buildIndex();
-            }
-
-            if (!$this->config->getValue("Main", "allseminars") && !Request::get('allseminars')) {
-                $sem_inst_query = " AND seminare.Institut_id='{$this->config->range_id}' ";
-            }
-            if (Request::option('aggregation')) {
-                $i = Institute::find($this->config->range_id);
-                $children = $i->sub_institutes->pluck('institut_id');
-                $children[] = $i->institut_id;
-                $sem_inst_query = " AND seminare.Institut_id IN ('".(implode("', '", $children))."')";
-            }
-
-            $dbv = DbView::getView('sem_tree');
-
-            if (!$nameformat = $this->config->getValue("Main", "nameformat"))
-                $nameformat = "no_title_short";
-            $query = "SELECT seminare.Seminar_id, seminare.status, seminare.Name
-                , seminare.Institut_id, Institute.Name AS Institut,Institute.Institut_id,
-                seminar_sem_tree.sem_tree_id AS bereich, "
-                . $_fullname_sql[$nameformat]
-                . " AS fullname, auth_user_md5.username,
-                " . $dbv->sem_number_sql . " AS sem_number, " . $dbv->sem_number_end_sql . " AS sem_number_end, " .
-            " seminar_user.position AS position, seminare.parent_course, seminare.visible " .
-            " FROM seminare
-                LEFT JOIN seminar_user ON (seminare.Seminar_id=seminar_user.Seminar_id AND seminar_user.status='dozent')
-                LEFT JOIN auth_user_md5 USING (user_id)
-                LEFT JOIN user_info USING (user_id)
-                LEFT JOIN seminar_sem_tree ON (seminare.Seminar_id = seminar_sem_tree.seminar_id)
-                LEFT JOIN seminar_inst ON (seminare.Seminar_id = seminar_inst.Seminar_id)
-                LEFT JOIN Institute ON (seminar_inst.institut_id = Institute.Institut_id)
-                WHERE (seminare.Seminar_id IN('" . join("','", array_keys($this->sem_browse_data['search_result'])) . "')
-                    OR seminare.parent_course IN ('" . join("','", array_keys($this->sem_browse_data['search_result'])) . "'))
-                 $sem_inst_query $sem_range_query $sem_types_query";
-
-            $db = new DB_Seminar($query);
-            $snap = new DbSnapshot($db);
-            $group = Request::int('group');
-            if (isset($group) && $group >= 0 && $group < 5) {
-                $this->sem_browse_data['group_by'] = $group;
-            }
-            $group_field = $this->group_by_fields[$this->sem_browse_data['group_by']]['group_field'];
-            $data_fields[0] = "Seminar_id";
-            if ($this->group_by_fields[$this->sem_browse_data['group_by']]['unique_field']){
-                $data_fields[1] = $this->group_by_fields[$this->sem_browse_data['group_by']]['unique_field'];
-            }
-            $group_by_data = $snap->getGroupedResult($group_field, $data_fields);
-            $sem_data = $snap->getGroupedResult("Seminar_id");
-
-            if ($this->sem_browse_data['group_by'] == 0){
-                $group_by_duration = $snap->getGroupedResult("sem_number_end", ["sem_number","Seminar_id"]);
-                foreach ($group_by_duration as $sem_number_end => $detail){
-                    if ($sem_number_end != -1 && ($detail['sem_number'][$sem_number_end - 1] && count($detail['sem_number']) == 1)){
-                        continue;
-                    } else {
-                        foreach ($detail['Seminar_id'] as $seminar_id => $foo){
-                            $start_sem = key($sem_data[$seminar_id]["sem_number"]);
-                            if ($sem_number_end == -1){
-                                if (is_array($this->sem_number)){
-                                    $sem_number_end = $this->sem_number[0];
-                                } else {
-                                    $sem_number_end = count($this->sem_dates) - 1;
-                                }
-                            }
-                            for ($i = $start_sem; $i <= $sem_number_end; ++$i){
-                                if ($this->sem_number === false || (is_array($this->sem_number) && in_array($i,$this->sem_number))){
-                                    if ($group_by_data[$i] && !$tmp_group_by_data[$i]){
-                                        foreach($group_by_data[$i]['Seminar_id'] as $id => $bar){
-                                            $tmp_group_by_data[$i]['Seminar_id'][$id] = true;
-                                        }
-                                    }
-                                    $tmp_group_by_data[$i]['Seminar_id'][$seminar_id] = true;
-                                }
-                            }
-                        }
-                    }
-                }
-                if (is_array($tmp_group_by_data)){
-                    if ($this->sem_number !== false){
-                        unset($group_by_data);
-                    }
-                    foreach ($tmp_group_by_data as $start_sem => $detail){
-                        $group_by_data[$start_sem] = $detail;
-                    }
-                }
-            }
-
-            foreach ($group_by_data as $group_field => $sem_ids){
-                foreach ($sem_ids['Seminar_id'] as $seminar_id => $foo){
-                    $name = mb_strtolower(key($sem_data[$seminar_id]["Name"]));
-                    $name = str_replace("ä","ae",$name);
-                    $name = str_replace("ö","oe",$name);
-                    $name = str_replace("ü","ue",$name);
-                    $group_by_data[$group_field]['Seminar_id'][$seminar_id] = $name;
-                }
-                uasort($group_by_data[$group_field]['Seminar_id'], 'strnatcmp');
-            }
-
-            switch ($this->sem_browse_data["group_by"]){
-                    case 0:
-                        krsort($group_by_data, SORT_NUMERIC);
-                        break;
-
-                    case 1:
-                        uksort($group_by_data, function ($a, $b) {
-                            $the_tree = TreeAbstract::GetInstance('StudipSemTree');
-                            return $the_tree->tree_data[$a]['index'] - $the_tree->tree_data[$b]['index'];
-                        });
-                        break;
-
-                    case 3:
-                        if ($order = $this->module->config->getValue("ReplaceTextSemType", "order")) {
-                            foreach ($order as $position) {
-                                if (isset($group_by_data[$position]))
-                                    $group_by_data_tmp[$position] = $group_by_data[$position];
-                            }
-                            $group_by_data = $group_by_data_tmp;
-                            unset($group_by_data_tmp);
-                        }
-                        else {
-                            uksort($group_by_data, function ($a, $b) {
-                                global $SEM_CLASS,$SEM_TYPE;
-                                return strnatcasecmp(
-                                    $SEM_TYPE[$a]['name'] . ' (' . $SEM_CLASS[$SEM_TYPE[$a]['class']]['name'] . ')',
-                                    $SEM_TYPE[$b]['name'] . ' (' . $SEM_CLASS[$SEM_TYPE[$b]['class']]['name'] . ')'
-                                );
-                            });
-                        }
-                        break;
-
-                    default:
-                        uksort($group_by_data, 'strnatcasecmp');
-                        break;
-            }
-
-            $show_time = $this->config->getValue("Main", "time");
-            $show_lecturer = $this->config->getValue("Main", "lecturer");
-            if ($show_time && $show_lecturer) {
-                if (!$td2width = $this->config->getValue("LecturesInnerTable", "td2width"))
-                    $td2width = 50;
-                $colspan = " colspan=\"2\"";
-                $td_time = $this->config->getAttributes("LecturesInnerTable", "td2");
-                $td_time .= " width=\"$td2width%\"";
-                $td_lecturer = " align=\"" . $this->config->getValue("LecturesInnerTable", "td3_align");
-                $td_lecturer .= "\" valign=\"" . $this->config->getValue("LecturesInnerTable", "td2_valign");
-                $td_lecturer .= "\" width=\"" . (100 - $td2width) . "%\"";
-            }
-            else {
-                $colspan = "";
-                $td_time = $this->config->getAttributes("LecturesInnerTable", "td2") . " width=\"100%\"";
-                $td_lecturer = " align=\"" . $this->config->getValue("LecturesInnerTable", "td3_align");
-                $td_lecturer .= "\" valign=\"" . $this->config->getValue("LecturesInnerTable", "td2_valign");
-                $td_lecturer .= " width=\"100%\"";
-            }
-            // erase output buffer with warnings and start unbuffered output
-            ob_end_clean();
-            echo "\n<table" . $this->config->getAttributes("TableHeader", "table") . ">\n";
-            if ($this->config->getValue("Main", "addinfo")) {
-                echo "\n<tr" . $this->config->getAttributes("InfoCountSem", "tr") . ">";
-                echo "<td" . $this->config->getAttributes("InfoCountSem", "td") . ">";
-                echo "<font" . $this->config->getAttributes("InfoCountSem", "font") . ">&nbsp;";
-                $visibles = array_filter($sem_data, function ($c) { return key($c['visible']) == 1; });
-                echo count($visibles);
-                echo $this->config->getValue("Main", "textlectures");
-                echo ", " . $this->config->getValue("Main", "textgrouping");
-                $group_by_name = $this->config->getValue("Main", "aliasesgrouping");
-                echo $group_by_name[$this->sem_browse_data['group_by']];
-                echo "</font></td></tr>";
-            }
-            if (count($group_by_data)) {
-                foreach ($group_by_data as $group_field => $sem_ids) {
-                    echo "\n<tr" . $this->config->getAttributes("Grouping", "tr") . ">";
-                    echo "<td" . $this->config->getAttributes("Grouping", "td") . ">";
-                    echo "<font" . $this->config->getAttributes("Grouping", "font") . ">";
-                    switch ($this->sem_browse_data["group_by"]){
-                        case 0:
-                        echo $this->sem_dates[$group_field]['name'];
-                        break;
-
-                        case 1:
-                        if ($the_tree->tree_data[$group_field]) {
-                            $range_path_level = $this->config->getValue("Main", "rangepathlevel");
-                            echo htmlReady($the_tree->getShortPath($group_field, NULL, '>', $range_path_level ? $range_path_level - 1 : 0));
-                        } else {
-                            echo $this->config->getValue("Main", "textnogroups");
-                        }
-                        /*
-                        $range_path_new = NULL;
-                        if ($the_tree->tree_data[$group_field]) {
-                            $range_path = explode(" ^ ", $the_tree->getShortPath($group_field, "^"));
-                            $range_path_level = $this->config->getValue("Main", "rangepathlevel");
-                            if ($range_path_level > sizeof($range_path))
-                                $range_path_level = sizeof($range_path);
-                            for ($i = $range_path_level - 1; $i < sizeof($range_path); $i++)
-                                $range_path_new[] = $range_path[$i];
-                            echo htmlReady(implode(" > ", $range_path_new));
-                        }
-                        else
-                            echo $this->config->getValue("Main", "textnogroups");
-                        */
-                        break;
-
-                        case 2:
-                        echo htmlReady($group_field);
-                        break;
-
-                        case 3:
-                        $aliases_sem_type = $this->config->getValue("ReplaceTextSemType",
-                                "class_{$SEM_TYPE[$group_field]['class']}");
-                        if ($aliases_sem_type[$this->sem_types_position[$group_field] - 1])
-                            echo $aliases_sem_type[$this->sem_types_position[$group_field] - 1];
-                        else {
-                            echo htmlReady($SEM_TYPE[$group_field]["name"]
-                                    ." (". $SEM_CLASS[$SEM_TYPE[$group_field]["class"]]["name"].")");
-                        }
-                        break;
-
-                        case 4:
-                        echo htmlReady($group_field);
-                        break;
-
-                    }
-                    echo "</font></td></tr>";
-                    if (is_array($sem_ids['Seminar_id'])) {
-                        $zebra = 0;
-                        $group_sem_types = SemType::getGroupingSemTypes();
-                        $table_data = compact('zebra', 'colspan', 'show_time',
-                            'show_lecturer', 'td_time', 'td_lecturer', 'group_sem_types');
-
-                        foreach (array_keys($sem_ids['Seminar_id']) as $seminar_id) {
-                            $this->printCourseRow($seminar_id, $sem_data, $table_data);
-                        }
-
-                        echo '<script type="text/javascript">
-                            function toggleChildren(showhide) {
-                                var children = document.getElementsByName("child-course");
-
-                                var display = "none";
-                                if (showhide == "show") {
-                                    display = "block";
-                                }
-
-                                for (var i = 0 ; i < children.length ; i++) {
-                                    if (children[i].style.display == "") {
-                                        children[i].style.display = "none";
-                                    } else {
-                                        children[i].style.display = "";
-                                    }
-                                }
-                                return false;
-                            }
-                            window.onload = function() { toggleChildren(); };
-                            </script>';
-                    }
-                }
-            }
-            echo "</table>";
-        }
-    }
-
-    /**
-     * Generate output for a single course (including children, if applicable)
-     * @param string $seminar_id the course ID to show
-     * @param mixed $sem_data global data with all found courses
-     * @param bool $table_data some variables needed for displaying
-     * @param bool $child are we showing a child or a normal or parent course?
-     */
-    private function printCourseRow($seminar_id, &$sem_data, $table_data, $child = false)
-    {
-        /*
-         * Generate output only if parent course is not already present
-         * because the current course will be sorted there as a child.
-         */
-        if (!key($sem_data[$seminar_id]['parent_course']) || !$sem_data[key($sem_data[$seminar_id]['parent_course'])] || $child) {
-            extract($table_data);
-
-            $sem_object = Seminar::GetInstance($seminar_id);
-            $sem_name = $sem_object->name;
-            $sem_number_start = key($sem_data[$seminar_id]["sem_number"]);
-            $sem_number_end = key($sem_data[$seminar_id]["sem_number_end"]);
-            if ($sem_number_start != $sem_number_end) {
-                $sem_name .= " (" . $this->sem_dates[$sem_number_start]['name'] . " - ";
-                $sem_name .= (($sem_number_end == -1) ? _("unbegrenzt") : $this->sem_dates[$sem_number_end]['name']) . ")";
-            }
-            echo "\n<tr" . $this->config->getAttributes("LecturesInnerTable", "tr") . ($child ? ' name="child-course"' : '') . ">";
-            if ($zebra % 2 && $this->config->getValue("LecturesInnerTable", "td_bgcolor2_"))
-                echo "<td width=\"100%\"" . $this->config->getAttributes("LecturesInnerTable", "td", TRUE) . "\">\n";
-            else
-                echo "<td width=\"100%\"" . $this->config->getAttributes("LecturesInnerTable", "td") . "\">\n";
-            $zebra++;
-            echo "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
-            echo "<tr" . $this->config->getAttributes("LecturesInnerTable", "tr1") . ">";
-            echo "<td$colspan" . $this->config->getAttributes("LecturesInnerTable", "td1") . ">";
-            echo "<font" . $this->config->getAttributes("LecturesInnerTable", "font1") . ">";
-            $sem_link["module"] = "Lecturedetails";
-            $sem_link["link_args"] = "seminar_id=$seminar_id";
-            $sem_link["content"] = htmlReady($sem_name);
-            $this->module->elements["SemLink"]->printout($sem_link);
-            echo "</font>";
-            $children = [];
-            if (in_array(key($sem_data[$seminar_id]['status']), $table_data['group_sem_types'])) {
-                $children = array_filter(Course::findByParent_Course($seminar_id), function ($c) {
-                    return $c->visible == 1;
-                });
-                if (count($children) > 0) {
-                    echo '<br><a href="" onclick="return toggleChildren()">' .
-                        sprintf(
-                            ngettext('%s Unterveranstaltung', '%s Unterveranstaltungen', count($children)),
-                            count($children)) . '</a>';
-                }
-            }
-            echo "</td></tr>\n";
-            //create Turnus field
-            $temp_turnus_string = $sem_object->getDatesExport(['show_room' => true]);
-            //Shorten, if string too long (add link for details.php)
-            if (mb_strlen($temp_turnus_string) > 70) {
-                $temp_turnus_string = mb_substr($temp_turnus_string, 0,
-                    mb_strpos(mb_substr($temp_turnus_string, 70,
-                        mb_strlen($temp_turnus_string)), ',') + 71);
-                $temp_turnus_string .= '...';
-            }
-            if ($show_time || $show_lecturer) {
-                echo "\n<tr" . $this->config->getAttributes('LecturesInnerTable', 'tr2') . '>';
-                if ($show_time) {
-                    echo "<td$td_time>";
-                    echo '<font' . $this->config->getAttributes('LecturesInnerTable', 'font2') . '>';
-                    echo $temp_turnus_string . "</font></td>\n";
-                }
-                if ($show_lecturer) {
-                    echo "<td$td_lecturer>";
-                    echo '<font' . $this->config->getAttributes('LecturesInnerTable', 'font2') . '>(';
-                    $doz_position = array_keys($sem_data[$seminar_id]['position']);
-                    $doz_name = array_keys($sem_data[$seminar_id]['fullname']);
-                    $doz_uname = array_keys($sem_data[$seminar_id]['username']);
-                    if (is_array($doz_name)) {
-                        $lecturer_link['module'] = 'Persondetails';
-                        if (count($doz_position) != count($doz_uname)) $doz_position = range(1, count($doz_uname));
-                        array_multisort($doz_position, $doz_name, $doz_uname);
-                        $i = 0;
-                        foreach ($doz_name as $index => $value) {
-                            if ($i == 4) {
-                                echo '...';
-                                break;
-                            }
-                            $lecturer_link['link_args'] = "username={$doz_uname[$index]}&seminar_id=$seminar_id";
-                            $lecturer_link['content'] = htmlReady($value);
-                            $this->module->elements['LecturerLink']->printout($lecturer_link);
-                            if ($i != count($doz_name) - 1) {
-                                echo ', ';
-                            }
-                            ++$i;
-                        }
-                        echo ') ';
-                    }
-                    echo '</font></td>';
-                }
-                echo '</tr>';
-            }
-            echo "</table>";
-            echo "</td></tr>\n";
-
-            if (count($children) > 0) {
-                foreach ($children as $child) {
-                    $this->printCourseRow($child->id, $sem_data, $table_data, true);
-                }
-            }
-        }
-    }
-
-}
-?>
diff --git a/lib/extern/modules/views/ExternSemBrowseTable.class.php b/lib/extern/modules/views/ExternSemBrowseTable.class.php
deleted file mode 100644
index 29f8b2f5013..00000000000
--- a/lib/extern/modules/views/ExternSemBrowseTable.class.php
+++ /dev/null
@@ -1,476 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternSemBrowseTable.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternSemBrowseTable
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternSemBrowseTable.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once 'lib/dates.inc.php';
-
-class ExternSemBrowseTable extends SemBrowse {
-
-    var $module;
-    var $sem_types_position;
-    var $sem_dates;
-
-    function __construct(&$module, $start_item_id) {
-
-        global $SEM_TYPE,$SEM_CLASS;
-        ob_start();
-        $all_semester = Semester::findAllVisible(false);
-        array_unshift($all_semester, 0);
-
-        $this->group_by_fields = [ ['name' => _("Semester"), 'group_field' => 'sem_number'],
-                                        ['name' => _("Bereich"), 'group_field' => 'bereich'],
-                                        ['name' => _("Lehrende"), 'group_field' => 'fullname', 'unique_field' => 'username'],
-                                        ['name' => _("Typ"), 'group_field' => 'status'],
-                                        ['name' => _("Einrichtung"), 'group_field' => 'Institut', 'unique_field' => 'Institut_id']];
-
-        $this->module = $module;
-        $this->sem_browse_data["group_by"] = $this->module->config->getValue("Main", "grouping");
-        $this->sem_dates = $all_semester;
-        $this->sem_dates[0] = ["name" => _("abgelaufene Semester")];
-
-        // reorganize the $SEM_TYPE-array
-        foreach ($SEM_CLASS as $key_class => $class) {
-            $i = 0;
-            foreach ($SEM_TYPE as $key_type => $type) {
-                if ($type["class"] == $key_class) {
-                    $i++;
-                    $this->sem_types_position[$key_type] = $i;
-                }
-            }
-        }
-
-        $switch_time = mktime(0, 0, 0, date("m"),
-                date("d") + 7 * $this->module->config->getValue("Main", "semswitch"), date("Y"));
-        // get current semester
-        $current_sem = get_sem_num($switch_time) + 1;
-
-        switch ($this->module->config->getValue("Main", "semstart")) {
-            case "previous" :
-                if (isset($all_semester[$current_sem - 1]))
-                    $current_sem--;
-                break;
-            case "next" :
-                if (isset($all_semester[$current_sem + 1]))
-                    $current_sem++;
-                break;
-            case "current" :
-                break;
-            default :
-                if (isset($all_semester[$this->module->config->getValue("Main", "semstart")]))
-                    $current_sem = $this->module->config->getValue("Main", "semstart");
-        }
-
-        $last_sem = $current_sem + $this->module->config->getValue("Main", "semrange");
-        if ($last_sem < $current_sem)
-            $last_sem = $current_sem;
-        if (!isset($all_semester[$last_sem]))
-            $last_sem = sizeof($all_semester);
-
-        for (;$last_sem > $current_sem; $last_sem--)
-            $this->sem_number[] = $last_sem - 1;
-
-        $semclasses = $this->module->config->getValue("Main", "semclasses");
-        foreach ($SEM_TYPE as $key => $type) {
-            if (in_array($type["class"], $semclasses))
-                $this->sem_browse_data['sem_status'][] = $key;
-        }
-
-        $this->get_sem_range_tree($start_item_id, true);
-    }
-
-    function print_result () {
-        global $_fullname_sql,$SEM_TYPE,$SEM_CLASS,$sem_type_tmp;
-
-        $sem_link = $this->module->getModuleLink("Lecturedetails",
-            $this->module->config->getValue("SemLink", "config"),
-            $this->module->config->getValue("SemLink", "srilink"));
-
-        $lecturer_link = $this->module->getModuleLink("Persondetails",
-            $this->module->config->getValue("LecturerLink", "config"),
-            $this->module->config->getValue("LecturerLink", "srilink"));
-
-        if (is_array($this->sem_browse_data['search_result']) && count($this->sem_browse_data['search_result'])) {
-
-            // show only selected subject areas
-            $selected_ranges = $this->module->config->getValue('SelectSubjectAreas', 'subjectareasselected');
-            if ($stid = Request::option('sem_tree_id')) {
-                if (!is_object($this->sem_tree)){
-                    $the_tree = TreeAbstract::GetInstance("StudipSemTree");
-                } else {
-                    $the_tree =& $this->sem_tree->tree;
-                }
-                $the_tree->buildIndex();
-                $selected_ranges = array_merge([$stid], $the_tree->getKidsKids($stid));
-            }
-            if (!$this->module->config->getValue('SelectSubjectAreas', 'selectallsubjectareas') && $selected_ranges) {
-                if ($this->module->config->getValue('SelectSubjectAreas', 'reverseselection')) {
-                    $sem_range_query =  "AND seminar_sem_tree.sem_tree_id NOT IN ('".implode("','", $selected_ranges)."')";
-                } else {
-                    $sem_range_query =  "AND seminar_sem_tree.sem_tree_id IN ('".implode("','", $selected_ranges)."')";
-                }
-            } else {
-                $sem_range_query = '';
-            }
-
-            // show only selected SemTypes
-            $selected_semtypes = $this->module->config->getValue('ReplaceTextSemType', 'visibility');
-            if (Request::get('semstatus')) {
-                $selected_semtypes = [Request::get('semstatus')];
-            }
-            $sem_types_array = [];
-            if ($selected_semtypes) {
-                foreach ($selected_semtypes as $i => $active) {
-                    if ($active == '1') {
-                        $sem_types_array[] = $i + 1;
-                    }
-                }
-                $sem_types_query = "AND seminare.status IN ('" . implode("','", $sem_types_array) . "')";
-            } else {
-                $sem_types_query = '';
-            }
-
-            // number of visible columns
-            $group_colspan = array_count_values($this->module->config->getValue("Main", "visible"));
-
-            if ($this->sem_browse_data['group_by'] == 1){
-                if (!is_object($this->sem_tree)){
-                    $the_tree = TreeAbstract::GetInstance("StudipSemTree");
-                } else {
-                    $the_tree =& $this->sem_tree->tree;
-                }
-            $the_tree->buildIndex();
-            }
-
-            if (!$this->module->config->getValue("Main", "allseminars") && !Request::get('allseminars')){
-                $sem_inst_query = " AND seminare.Institut_id='{$this->module->config->range_id}' ";
-            }
-            if (Request::option('aggregation')) {
-                $i = Institute::find($this->module->config->range_id);
-                $children = $i->sub_institutes->pluck('institut_id');
-                $children[] = $i->institut_id;
-                $sem_inst_query = " AND seminare.Institut_id IN ('".(implode("', '", $children))."')";
-            }
-            if (!$nameformat = $this->module->config->getValue("Main", "nameformat"))
-                $nameformat = "no_title_short";
-
-            $dbv = DbView::getView('sem_tree');
-
-            $query = "SELECT seminare.*
-                , Institute.Name AS Institut,Institute.Institut_id,
-                seminar_sem_tree.sem_tree_id AS bereich, " . $_fullname_sql[$nameformat] ." AS fullname, auth_user_md5.username,
-                " . $dbv->sem_number_sql . " AS sem_number, " . $dbv->sem_number_end_sql . " AS sem_number_end, " .
-            " seminar_user.position AS position " .
-            " FROM seminare
-                LEFT JOIN seminar_user ON (seminare.Seminar_id=seminar_user.Seminar_id AND seminar_user.status='dozent')
-                LEFT JOIN auth_user_md5 USING (user_id)
-                LEFT JOIN user_info USING (user_id)
-                LEFT JOIN seminar_sem_tree ON (seminare.Seminar_id = seminar_sem_tree.seminar_id)
-                LEFT JOIN seminar_inst ON (seminare.Seminar_id = seminar_inst.Seminar_id)
-                LEFT JOIN Institute ON (seminar_inst.institut_id = Institute.Institut_id)
-                WHERE seminare.Seminar_id IN('" . join("','", array_keys($this->sem_browse_data['search_result']))
-                 . "') $sem_inst_query $sem_range_query $sem_types_query";
-
-            $db = new DB_Seminar($query);
-            $snap = new DbSnapshot($db);
-            $group_field = $this->group_by_fields[$this->sem_browse_data['group_by']]['group_field'];
-            $data_fields[0] = "Seminar_id";
-            if ($this->group_by_fields[$this->sem_browse_data['group_by']]['unique_field']){
-                $data_fields[1] = $this->group_by_fields[$this->sem_browse_data['group_by']]['unique_field'];
-            }
-            $group_by_data = $snap->getGroupedResult($group_field, $data_fields);
-            $sem_data = $snap->getGroupedResult("Seminar_id");
-            if ($this->sem_browse_data['group_by'] == 0){
-                $group_by_duration = $snap->getGroupedResult("sem_number_end", ["sem_number","Seminar_id"]);
-                foreach ($group_by_duration as $sem_number_end => $detail){
-                    if ($sem_number_end != -1 && ($detail['sem_number'][$sem_number_end - 1] && count($detail['sem_number']) == 1)){
-                        continue;
-                    } else {
-                        foreach ($detail['Seminar_id'] as $seminar_id => $foo){
-                            $start_sem = key($sem_data[$seminar_id]["sem_number"]);
-                            if ($sem_number_end == -1){
-                                if (is_array($this->sem_number)){
-                                    $sem_number_end = $this->sem_number[0];
-                                } else {
-                                    $sem_number_end = count($this->sem_dates)-1;
-                                }
-                            }
-                            for ($i = $start_sem; $i <= $sem_number_end; ++$i){
-                                if ($this->sem_number === false || (is_array($this->sem_number) && in_array($i,$this->sem_number))){
-                                    if ($group_by_data[$i] && !$tmp_group_by_data[$i]){
-                                        foreach($group_by_data[$i]['Seminar_id'] as $id => $bar){
-                                            $tmp_group_by_data[$i]['Seminar_id'][$id] = true;
-                                        }
-                                    }
-                                    $tmp_group_by_data[$i]['Seminar_id'][$seminar_id] = true;
-                                }
-                            }
-                        }
-                    }
-                }
-                if (is_array($tmp_group_by_data)){
-                    if ($this->sem_number !== false){
-                        unset($group_by_data);
-                    }
-                    foreach ($tmp_group_by_data as $start_sem => $detail){
-                        $group_by_data[$start_sem] = $detail;
-                    }
-                }
-            }
-            //release memory
-            unset($snap);
-            unset($tmp_group_by_data);
-
-            foreach ($group_by_data as $group_field => $sem_ids){
-                foreach ($sem_ids['Seminar_id'] as $seminar_id => $foo){
-                    $name = mb_strtolower(key($sem_data[$seminar_id]["Name"]));
-                    $name = str_replace("ä","ae",$name);
-                    $name = str_replace("ö","oe",$name);
-                    $name = str_replace("ü","ue",$name);
-                    $group_by_data[$group_field]['Seminar_id'][$seminar_id] = $name;
-                }
-                uasort($group_by_data[$group_field]['Seminar_id'], 'strnatcmp');
-            }
-
-            switch ($this->sem_browse_data["group_by"]){
-                    case 0:
-                        krsort($group_by_data, SORT_NUMERIC);
-                        break;
-
-                    case 1:
-                        uksort($group_by_data, function ($a, $b) {
-                            $the_tree = TreeAbstract::GetInstance('StudipSemTree');
-                            return $the_tree->tree_data[$a]['index'] - $the_tree->tree_data[$b]['index'];
-                        });
-                        break;
-
-                    case 3:
-                        if ($order = $this->module->config->getValue("ReplaceTextSemType", "order")) {
-                            foreach ($order as $position) {
-                                if (isset($group_by_data[$position]))
-                                    $group_by_data_tmp[$position] = $group_by_data[$position];
-                            }
-                            $group_by_data = $group_by_data_tmp;
-                            unset($group_by_data_tmp);
-                        }
-                        else {
-                            uksort($group_by_data, function ($a, $b) {
-                                global $SEM_CLASS,$SEM_TYPE;
-                                return strnatcasecmp(
-                                    $SEM_TYPE[$a]['name'] . ' (' . $SEM_CLASS[$SEM_TYPE[$a]['class']]['name'] . ')',
-                                    $SEM_TYPE[$b]['name'] . ' (' . $SEM_CLASS[$SEM_TYPE[$b]['class']]['name'] . ')'
-                                );
-                            });
-                        }
-                        break;
-                    default:
-                    uksort($group_by_data, 'strnatcasecmp');
-                    break;
-
-            }
-
-            // generic datafields
-            $generic_datafields = $this->module->config->getValue("Main", "genericdatafields");
-//              $datafields_obj = new DataFields();
-
-            if ($this->module->config->getValue("Main", "addinfo")) {
-                $info = "&nbsp;" . count($sem_data);
-                $info .= $this->module->config->getValue("Main", "textlectures");
-                $info .= ", " . $this->module->config->getValue("Main", "textgrouping");
-                $group_by_name = $this->module->config->getValue("Main", "aliasesgrouping");
-                $info .= $group_by_name[$this->sem_browse_data['group_by']];
-                $out = $this->module->elements["InfoCountSem"]->toString(["content" => $info]);
-            }
-            else
-                $out = "";
-
-            $first_loop = TRUE;
-            $repeat_headrow = $this->module->config->getValue("Main", "repeatheadrow");
-            foreach ($group_by_data as $group_field => $sem_ids) {
-
-                $group_content = $this->getGroupContent($the_tree, $group_field);
-
-                if ($repeat_headrow == "beneath") {
-                    $out .= $this->module->elements["Grouping"]->toString(["content" => $group_content]);
-                    $out .= $this->module->elements["TableHeadrow"]->toString();
-                }
-
-                if($first_loop && $repeat_headrow != "beneath")
-                    $out .= $this->module->elements["TableHeadrow"]->toString();
-
-                if ($repeat_headrow != "beneath") {
-                    if ($repeat_headrow && !$first_loop)
-                        $out .= $this->module->elements["TableHeadrow"]->toString();
-                    $out .= $this->module->elements["Grouping"]->toString(["content" => $group_content]);
-                }
-                $first_loop = FALSE;
-
-                if (is_array($sem_ids['Seminar_id'])) {
-                    foreach (array_keys($sem_ids['Seminar_id']) as $seminar_id) {
-                        $sem_object = Seminar::GetInstance($seminar_id);
-                        $sem_name = $sem_object->name;
-                        $sem_number_start = key($sem_data[$seminar_id]["sem_number"]);
-                        $sem_number_end = key($sem_data[$seminar_id]["sem_number_end"]);
-                        if ($sem_number_start != $sem_number_end){
-                            $sem_name .= " (" . $this->sem_dates[$sem_number_start]['name'] . " - ";
-                            $sem_name .= (($sem_number_end == -1) ? _("unbegrenzt") : $this->sem_dates[$sem_number_end]['name']) . ")";
-                        }
-
-                        //create Turnus field
-                        $data["content"]["zeiten"] = $sem_object->getDatesExport(['show_room' => true]);
-                        //Shorten, if string too long
-                        if (mb_strlen($data["content"]["zeiten"]) >70) {
-                            $data["content"]["zeiten"] = mb_substr($data["content"]["zeiten"], 0,
-                                    mb_strpos(mb_substr($data["content"]["zeiten"], 70, mb_strlen($data["content"]["zeiten"])), ",") +71);
-                            $data["content"]["zeiten"] .= "...";
-                        }
-                        $data["content"]["zeiten"] = htmlReady($data["content"]["zeiten"]);
-                        $doz_position = array_keys($sem_data[$seminar_id]['position']);
-                        $doz_name = array_keys($sem_data[$seminar_id]['fullname']);
-                        $doz_uname = array_keys($sem_data[$seminar_id]['username']);
-                        if (is_array($doz_name)){
-                            if(count($doz_position) != count($doz_uname)) $doz_position = range(1, count($doz_uname));
-                     array_multisort($doz_position, $doz_name, $doz_uname);
-                            $data["content"]["dozent"] = "";
-                            $i = 0;
-                            foreach ($doz_name as $index => $value) {
-                                if ($i == 4) {
-                                    $data["content"]["dozent"] .= $this->module->elements["LecturerLink"]->toString(
-                                        ["module" => "Lecturedetails", "link_args" => "seminar_id=$seminar_id",
-                                        "content" => "..."]);
-                                    break;
-                                }
-                                $data["content"]["dozent"] .= $this->module->elements["LecturerLink"]->toString(
-                                        ["module" => "Persondetails", "link_args" => "username="
-                                        . $doz_uname[$index] . "&seminar_id=$seminar_id",
-                                        "content" =>  htmlReady($value)]);
-                                if ($i != count($doz_name) - 1) {
-                                    $data["content"]["dozent"] .= ", ";
-                                }
-                                ++$i;
-                            }
-                        }
-
-                        $data["content"]["Name"] = $this->module->elements["SemLink"]->toString(
-                                ["module" => "Lecturedetails", "link_args" => "seminar_id=$seminar_id",
-                                "content" => htmlReady($sem_name)]);
-                        $data["content"]["VeranstaltungsNummer"] =
-                                htmlReady(key($sem_data[$seminar_id]["VeranstaltungsNummer"]));
-                        $data["content"]["Untertitel"] = htmlReady($sem_object->untertitel);
-
-                        $aliases_sem_type = $this->module->config->getValue("ReplaceTextSemType",
-                                "class_" . $SEM_TYPE[key($sem_data[$seminar_id]["status"])]['class']);
-                        if ($aliases_sem_type[$this->sem_types_position[key($sem_data[$seminar_id]["status"])] - 1]) {
-                            $data["content"]["status"] =
-                                    $aliases_sem_type[$this->sem_types_position[key($sem_data[$seminar_id]["status"])] - 1];
-                        }
-                        else {
-                            $data["content"]["status"] =
-                                    htmlReady($SEM_TYPE[key($sem_data[$seminar_id]["status"])]["name"]
-                                    ." (". $SEM_CLASS[$SEM_TYPE[key($sem_data[$seminar_id]["status"])]["class"]]["name"].")");
-                        }
-
-                        $data["content"]["Ort"] = $sem_object->getDatesTemplate('dates/seminar_export_location');
-                        if ($sem_data[$seminar_id]["art"])
-                            $data["content"]["art"] = htmlReady($sem_object->art);
-                        else
-                            $data["content"]["art"] = "";
-
-                        // generic data fields
-                        if (is_array($generic_datafields)) {
-                            $localEntries = DataFieldEntry::getDataFieldEntries($seminar_id);
-                            foreach ($generic_datafields as $id) {
-                                if (isset($localEntries[$id]) && is_object($localEntries[$id])) {
-                                    $data["content"][$id] = $localEntries[$id]->getDisplayValue();
-                                }
-                            }
-                        }
-
-                        $data["data_fields"] = $this->module->data_fields;
-                        $out .= $this->module->elements["TableRow"]->toString($data);
-                    }
-                }
-            }
-            ob_end_clean();
-            $this->module->elements["TableHeader"]->printout(["content" => $out]);
-        }
-    }
-
-    // private
-    function getGroupContent ($the_tree, $group_field) {
-        global $SEM_TYPE, $SEM_CLASS;
-
-        switch ($this->sem_browse_data["group_by"]){
-            case 0:
-                $content = $this->sem_dates[$group_field]['name'];
-                break;
-
-            case 1:
-                if ($the_tree->tree_data[$group_field]) {
-                    $range_path_level = $this->module->config->getValue("Main", "rangepathlevel");
-                    $content = htmlReady($the_tree->getShortPath($group_field, NULL, '>', $range_path_level ? $range_path_level - 1 : 0));
-                } else {
-                    $content = $this->module->config->getValue("Main", "textnogroups");
-                }
-                break;
-
-            case 2:
-                $content = htmlReady($group_field);
-                break;
-
-            case 3:
-                $aliases_sem_type = $this->module->config->getValue("ReplaceTextSemType",
-                        "class_{$SEM_TYPE[$group_field]['class']}");
-                if ($aliases_sem_type[$this->sem_types_position[$group_field] - 1])
-                    $content = $aliases_sem_type[$this->sem_types_position[$group_field] - 1];
-                else {
-                    $content = htmlReady($GLOBALS["SEM_TYPE"][$group_field]["name"]
-                            ." (". $SEM_CLASS[$SEM_TYPE[$group_field]["class"]]["name"].")");
-                }
-                break;
-            case 4:
-                $content = htmlReady($group_field);
-                break;
-
-        }
-
-        return $content;
-    }
-
-}
-?>
diff --git a/lib/extern/modules/views/ExternSemLectureTree.class.php b/lib/extern/modules/views/ExternSemLectureTree.class.php
deleted file mode 100644
index 02820e8014b..00000000000
--- a/lib/extern/modules/views/ExternSemLectureTree.class.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter003: TEST
-# Lifter007: TODO
-# Lifter010: TODO
-
-class ExternSemLectureTree extends StudipSemTreeViewSimple {
-
-    var $config;
-    var $param;
-    var $root_id;
-
-    function __construct(&$config, $start_item_id = "", $sem_number = FALSE)
-    {
-        $this->config = $config;
-
-        $query = "SELECT sem_tree_id FROM sem_tree WHERE studip_object_id = ?";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$this->config->range_id]);
-        $this->root_id = $statement->fetchColumn();
-
-        $this->start_item_id = ($start_item_id) ? $start_item_id : $this->root_id;
-        $this->param = "range_id={$this->config->range_id}&module=Semlecturetree&config_id={$this->config->id}&";
-
-        parent::__construct($this->start_item_id, $sem_number);
-    }
-
-    function showSemTree ($start_id = null) {
-        echo "\n<table" . $this->config->getAttributes("Main", "table") . ">";
-        echo "\n<tr><td>". $this->getSemPath() . "</td></tr>\n<tr><td>";
-        $this->showContent($this->start_item_id);
-        echo "\n</td></tr>";
-        if ($this->tree->getNumKids($this->start_item_id)) {
-            echo "\n<tr><td>";
-            echo $this->showKids($this->start_item_id);
-            echo "\n</td></tr>";
-        }
-        if ($this->config->getAttributes("TreeBackLink", "image")
-                || $this->config->getAttributes("TreeBackLink", "linktext")) {
-            echo "\n<tr><td>";
-            echo $this->backLink($this->start_item_id) . "\n</td></tr>";
-        }
-        echo "\n</table>";
-    }
-
-    function showKids ($item_id) {
-        $num_kids = $this->tree->getNumKids($item_id);
-        $kids = $this->tree->getKids($item_id);
-        $attributes_a = $this->config->getAttributes("TreeKids", "a");
-        $attributes_font = $this->config->getAttributes("TreeKids", "font");
-        $attributes_td = $this->config->getAttributes("TreeKids", "td");
-        echo "\n<table width=\"100%\" border=\"0\"";
-        echo $this->config->getAttributes("TreeKids", "table") . ">";
-        for ($i = 0; $i < $num_kids; ++$i){
-            $num_entries = $this->tree->getNumEntries($kids[$i],true);
-            echo "<tr>\n<td$attributes_td>";
-            echo "<a href=\"" .URLHelper::getLink($this->getSelf("{$this->param}start_item_id={$kids[$i]}", false));
-            echo "\"$attributes_a><font$attributes_font>";
-            echo htmlReady($this->tree->tree_data[$kids[$i]]['name']);
-            echo "&nbsp;($num_entries)";
-            echo "</font></a>";
-            echo "</td></tr>\n";
-        }
-        echo "</table>\n";
-    }
-
-    function backLink ($item_id) {
-        if ($item_id != $this->root_id){
-            echo "<table width=\"100%\" border=\"0\"";
-            echo $this->config->getAttributes("TreeBackLink", "table") . ">\n";
-            echo "<tr><td" . $this->config->getAttributes("TreeBackLink", "td") . ">";
-            if ($image = $this->config->getValue("TreeBackLink", "image")) {
-                echo "<a href=\"" .URLHelper::getLink($this->getSelf("{$this->param}start_item_id={$this->tree->tree_data[$item_id]['parent_id']}", false)) . "\">";
-                echo "<img src=\"$image\" border=\"0\"></a>&nbsp;";
-            }
-            if ($link_text = $this->config->getValue("TreeBackLink", "linktext")) {
-                echo "<a href=\"" .URLHelper::getLink($this->getSelf("{$this->param}start_item_id={$this->tree->tree_data[$item_id]['parent_id']}", false)) . "\">";
-                echo "<font" . $this->config->getAttributes("TreeBackLink", "font");
-                echo ">$link_text</font></a>";
-            }
-            echo "</td></tr></table>\n";
-        }
-    }
-
-    function showContent ($item_id, $num_all_entries = 0) {
-        echo "<table" . $this->config->getAttributes("TreeLevelName", "table");
-        echo ">\n<tr><td" . $this->config->getAttributes("TreeLevelName", "td") . ">";
-        echo "<font" . $this->config->getAttributes("TreeLevelName", "font") . ">";
-        echo htmlReady($this->tree->tree_data[$item_id]['name']) ."</font></td></tr>\n</table>";
-        echo "</td></tr><tr><td>\n";
-        echo "<table" . $this->config->getAttributes("TreeLevelContent", "table");
-        echo ">\n<tr><td" . $this->config->getAttributes("TreeLevelContent", "td") . ">";
-        echo "<font" . $this->config->getAttributes("TreeLevelContent", "font") . ">";
-        echo formatReady($this->tree->tree_data[$item_id]['info'], TRUE, TRUE) ."</font></td></tr>\n</table>";
-    }
-
-    function getSemPath ($start_id = null) {
-        $delimiter = $this->config->getValue("TreePath", "delimiter");
-        $attributes_a = $this->config->getAttributes("TreePath", "a");
-        $ret = "<table width=\"100%\"";
-        $ret .= $this->config->getAttributes("TreePath", "table") . "><tr>\n";
-        $ret .= "<td". $this->config->getAttributes("TreePath", "td") . ">";
-        $ret .= "<font". $this->config->getAttributes("TreePath", "td") . ">";
-        $parents = $this->tree->getParents($this->start_item_id);
-        $parents_root[] = $this->tree->getParents($this->root_id);
-        if (is_array($parents)) {
-            $parents = array_diff($parents, $parents_root);
-            while ($parent = array_pop($parents)) {
-                $ret .= $delimiter;
-                $ret .= "<a href=\"" . URLHelper::getLink($this->getSelf("{$this->param}start_item_id=".$parent,false));
-                $ret .= "\"$attributes_a>" . htmlReady($this->tree->tree_data[$parent]["name"]) . "</a>";
-            }
-        }
-        if ($this->start_item_id != $this->root_id)
-            $ret .= $delimiter;
-        $ret .= htmlReady($this->tree->tree_data[$this->start_item_id]["name"]);
-        $ret .= "</font></td></tr></table>\n";
-
-        return $ret;
-    }
-
-}
-
-?>
diff --git a/lib/extern/modules/views/lecturedetails_preview.inc.php b/lib/extern/modules/views/lecturedetails_preview.inc.php
deleted file mode 100644
index cbd48690f1c..00000000000
--- a/lib/extern/modules/views/lecturedetails_preview.inc.php
+++ /dev/null
@@ -1,263 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-
-require_once 'lib/dates.inc.php';
-
-global $SEM_CLASS, $SEM_TYPE;
-
-// reorganize the $SEM_TYPE-array
-foreach ($SEM_CLASS as $key_class => $class) {
-    $i = 0;
-    foreach ($SEM_TYPE as $key_type => $type) {
-        if ($type["class"] == $key_class) {
-            $i++;
-            $sem_types_position[$key_type] = $i;
-        }
-    }
-}
-
-$data_sem["name"] = _("Name der Veranstaltung");
-$data_sem["subtitle"] = _("Untertitel der Veranstaltung");
-switch ($this->config->getValue("Main", "nameformat")) {
-    case "no_title_short" :
-        $data_sem["lecturer"] = _("Meyer, P.");
-        break;
-    case "no_title" :
-        $data_sem["lecturer"] = _("Peter Meyer");
-        break;
-    case "no_title_rev" :
-        $data_sem["lecturer"] = _("Meyer Peter");
-        break;
-    case "full" :
-        $data_sem["lecturer"] = _("Dr. Peter Meyer");
-        break;
-    case "full_rev" :
-        $data_sem["lecturer"] = _("Meyer, Peter, Dr.");
-        break;
-    default :
-        $data_sem["lecturer"] = _("Meyer, P.");
-}
-$data_sem["art"] = _("Testveranstaltung");
-$data_sem["semtype"] = 1;
-$data_sem["description"] = str_repeat(_("Beschreibung") . " ", 10);
-$data_sem["location"] = _("A 123, 1. Stock");
-$data_sem["semester"] = "WS 2003/2004";
-$data_sem["time"] = _("Di. 8:30 - 13:30, Mi. 8:30 - 13:30, Do. 8:30 - 13:30");
-$data_sem["number"] = "1234";
-$data_sem["teilnehmer"] = str_repeat(_("Teilnehmende") . " ", 6);
-$data_sem["requirements"] = str_repeat(_("Voraussetzungen") . " ", 6);
-$data_sem["lernorga"] = str_repeat(_("Lernorganisation") . " ", 6);
-$data_sem["leistung"] = str_repeat(_("Leistungsnachweis") . " ", 6);
-$data_sem["range_path"] = _("Fakultät &gt; Studiengang &gt; Bereich");
-$data_sem["misc"] = str_repeat(_("Sonstiges") . " ", 6);
-$data_sem["ects"] = "4";
-
-
-setlocale(LC_TIME, $this->config->getValue("Main", "timelocale"));
-$order = $this->config->getValue("Main", "order");
-$visible = $this->config->getValue("Main", "visible");
-$aliases = $this->config->getValue("Main", "aliases");
-$j = -1;
-
-$data["name"] = $data_sem["name"];
-
-if ($visible[++$j])
-    $data["subtitle"] = $data_sem["subtitle"];
-
-if ($visible[++$j]) {
-    $data["lecturer"][] = sprintf("<a href=\"\"%s>%s</a>",
-            $this->config->getAttributes("LinkInternSimple", "a"),
-            $data_sem["lecturer"]);
-    if (is_array($data["lecturer"]))
-        $data["lecturer"] = implode(", ", $data["lecturer"]);
-}
-
-if ($visible[++$j])
-    $data["art"] = $data_sem["art"];
-
-if ($visible[++$j]) {
-    $aliases_sem_type = $this->config->getValue("ReplaceTextSemType",
-            "class_{$SEM_TYPE[$data_sem['semtype']]['class']}");
-    if ($aliases_sem_type[$sem_types_position[$data_sem['semtype']] - 1])
-        $data["status"] = $aliases_sem_type[$sem_types_position[$data_sem['semtype']] - 1];
-    else {
-        $data["status"] = htmlReady($SEM_TYPE[$data_sem['semtype']]["name"]
-                ." (". $SEM_CLASS[$SEM_TYPE[$data_sem['semtype']]["class"]]["name"].")");
-    }
-}
-
-if ($visible[++$j])
-    $data["description"] = $data_sem["description"];
-
-if ($visible[++$j])
-    $data["location"] = $data_sem["location"];
-
-if ($visible[++$j])
-    $data["semester"] = $data_sem["semester"];
-
-if ($visible[++$j])
-    $data["time"] = $data_sem["time"];
-
-if ($visible[++$j])
-    $data["number"] = $data_sem["number"];
-
-if ($visible[++$j])
-    $data["teilnehmer"] = $data_sem["teilnehmer"];
-
-if ($visible[++$j])
-    $data["requirements"] = $data_sem["requirements"];
-
-if ($visible[++$j])
-    $data["lernorga"] = $data_sem["lernorga"];
-
-if ($visible[++$j])
-    $data["leistung"] = $data_sem["leistung"];
-
-if ($visible[++$j]) {
-    $pathes = [$data_sem["range_path"]];
-    if (is_array($pathes)) {
-        $pathes_values = array_values($pathes);
-        if ($this->config->getValue("Main", "range") == "long")
-            $data["range_path"] = $pathes_values;
-        else {
-            foreach ($pathes_values as $path) {
-                $_paths = explode("&gt;", $path);
-                $data["range_path"][] = array_pop($_paths);
-            }
-        }
-        $data["range_path"] = array_filter($data["range_path"], "htmlReady");
-        $data["range_path"] = implode("<br>", $data["range_path"]);
-    }
-}
-
-if ($visible[++$j])
-    $data["misc"] = $data_sem["misc"];
-
-if ($visible[++$j])
-    $data["ects"] = $data_sem["ects"];
-
-if ($this->config->getValue("Main", "studiplink")) {
-    echo "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" ";
-    if ($studiplink_width = $this->config->getValue("TableHeader", "table_width"))
-        echo " width=\"$studiplink_width\"";
-    if ($studiplink_align = $this->config->getValue("TableHeader", "table_align"))
-        echo " align=\"$studiplink_align\">\n";
-
-
-    if ($this->config->getValue("Main", "studiplink") == "top") {
-        $args = ["width" => "100%", "height" => "40", "link" => ""];
-        echo "<tr><td width=\"100%\">\n";
-        $this->elements["StudipLink"]->printout($args);
-        echo "</td></tr>";
-    }
-    $table_attr = $this->config->getAttributes("TableHeader", "table");
-    $pattern = ["/width=\"[0-9%]+\"/", "/align=\"[a-z]+\"/"];
-    $replace = ["width=\"100%\"", ""];
-    $table_attr = preg_replace($pattern, $replace, $table_attr);
-    echo "<tr><td width=\"100%\">\n<table$table_attr>\n";
-}
-else
-    echo "<table" . $this->config->getAttributes("TableHeader", "table") . ">\n";
-
-echo "<tr" . $this->config->getAttributes("SemName", "tr") . ">";
-echo "<td" . $this->config->getAttributes("SemName", "td") . ">";
-
-if ($margin = $this->config->getValue("SemName", "margin"))
-    echo "<div style=\"margin-left:{$margin}px;\">";
-else
-    echo "<div>";
-echo "<font" . $this->config->getAttributes("SemName", "font") . ">";
-echo $data["name"] . "</font></div></td></tr>\n";
-
-$headline_tr = $this->config->getAttributes("Headline", "tr");
-$headline_td = $this->config->getAttributes("Headline", "td");
-$headline_font = $this->config->getAttributes("Headline", "font");
-if ($headline_margin = $this->config->getValue("Headline", "margin")) {
-    $headline_div = "<div style=\"margin-left:$headline_margin;\">";
-    $headline_div_end = "</div>";
-}
-else {
-    $headline_div = "";
-    $headline_div_end = "";
-}
-$content_tr =$this->config->getAttributes("Content", "tr");
-$content_td = $this->config->getAttributes("Content", "td");
-$content_font = $this->config->getAttributes("Content", "font");
-if ($content_margin = $this->config->getValue("Content", "margin")) {
-    $content_div = "<div style=\"margin-left:$content_margin;\">";
-    $content_div_end = "</div>";
-}
-else {
-    $content_div = "";
-    $content_div_end = "";
-}
-
-if ($this->config->getValue("Main", "headlinerow")) {
-    foreach ($order as $position) {
-        if ($visible[$position] && $data[$this->data_fields[$position]]) {
-            echo "<tr$headline_tr><td$headline_td>$headline_div";
-            echo "<font$headline_font>{$aliases[$position]}</font>$headline_div_end</td></tr>\n";
-            echo "<tr$content_tr><td$content_td>$content_div";
-            echo "<font$content_font>" . $data[$this->data_fields[$position]];
-            echo "</font>$content_div_end</td></tr>\n";
-        }
-    }
-}
-else {
-    foreach ($order as $position) {
-        if ($visible[$position] && $data[$this->data_fields[$position]]) {
-            echo "<tr$content_tr><td$content_td>$content_div";
-            echo "<font$headline_font>{$aliases[$position]}</font>\n";
-            echo "<font$content_font>" . $data[$this->data_fields[$position]];
-            echo "</font>$content_div_end</td></tr>\n";
-        }
-    }
-}
-
-if ($this->config->getValue("Main", "studipinfo")) {
-    echo "<tr$headline_tr><td$headline_td>$headline_div";
-    echo "<font$headline_font>" . $this->config->getValue("StudipInfo", "headline");
-    echo "<font>$headline_div_end</td></tr>\n";
-
-    $pre_font = $this->config->getAttributes("StudipInfo", "font");
-    echo "<tr$content_tr><td$content_td>$content_div";
-    echo "<font$pre_font>" . $this->config->getValue("StudipInfo", "homeinst");
-    echo "&nbsp;</font><font$content_font>";
-    printf("<a href=\"\"%s>%s</a>",
-            $this->config->getAttributes("LinkInternSimple", "a"),
-            _("Heimatinstitut"));
-    echo "<br></font>\n";
-
-    echo "<font$pre_font>" . $this->config->getValue("StudipInfo", "involvedinst");
-    echo "&nbsp;</font><font$content_font>";
-    echo str_repeat(_("Beteiligte Institute") . " ", 5) . "<br></font>\n";
-
-    echo "<font$pre_font>" . $this->config->getValue("StudipInfo", "countuser");
-    echo "&nbsp;</font><font$content_font>";
-    echo "23<br></font>\n";
-
-    echo "<font$pre_font>" . $this->config->getValue("StudipInfo", "countpostings");
-    echo "&nbsp;</font><font$content_font>";
-    echo "42<br></font>\n";
-
-    echo "<font$pre_font>" . $this->config->getValue("StudipInfo", "countdocuments");
-    echo "&nbsp;</font><font$content_font>";
-    echo "7<br></font>\n";
-    echo "$content_div_end</td></tr>";
-}
-
-echo "</table>\n";
-
-if ($this->config->getValue("Main", "studiplink")) {
-    if ($this->config->getValue("Main", "studiplink") == "bottom") {
-        $args = ["width" => "100%", "height" => "40", "link" => ""];
-        echo "</td></tr>\n<tr><td width=\"100%\">\n";
-        $this->elements["StudipLink"]->printout($args);
-    }
-    echo "</td></tr></table>\n";
-}
-
-?>
diff --git a/lib/extern/modules/views/lectures_preview.inc.php b/lib/extern/modules/views/lectures_preview.inc.php
deleted file mode 100644
index aab2de80d02..00000000000
--- a/lib/extern/modules/views/lectures_preview.inc.php
+++ /dev/null
@@ -1,150 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-
-
-global $SEM_TYPE,$SEM_CLASS ;
-$all_semester = Semester::findAllVisible(false);
-
-// reorganize the $SEM_TYPE-array
-foreach ($SEM_CLASS as $key_class => $class) {
-    $i = 0;
-    foreach ($SEM_TYPE as $key_type => $type) {
-        if ($type["class"] == $key_class) {
-            $i++;
-            $sem_types_position[$key_type] = $i;
-        }
-    }
-}
-
-// current semester
-$now = time();
-foreach ($all_semester as $key => $sem) {
-    if ($sem["beginn"] >= $now)
-        break;
-}
-
-$data_sem[0]["group"] = 1;
-$data_sem[1]["group"] = 1;
-$data_sem[2]["group"] = 2;
-$data_sem[0]["name"] = sprintf(_('Name der Veranstaltung %u'), 1);
-$data_sem[1]["name"] = sprintf(_('Name der Veranstaltung %u'), 2);
-$data_sem[2]["name"] = sprintf(_('Name der Veranstaltung %u'), 3);
-$data_sem[0]["time"] = _("Di. 8:30 - 13:30, Mi. 8:30 - 13:30, Do. 8:30 - 13:30");
-$data_sem[1]["time"] = _("Termine am 31.7. 14:00 - 16:00, 17.8. 11:00 - 14:30, 6.9. 14:00 - 16:00,...");
-$data_sem[2]["time"] = _("Di. 8:30 - 13:30, Mi. 8:30 - 13:30, Do. 8:30 - 13:30");
-
-switch ($this->config->getValue("Main", "nameformat")) {
-    case "no_title_short" :
-        $data_sem[0]["lecturer"] = _("Meyer, P.");
-        break;
-    case "no_title" :
-        $data_sem[0]["lecturer"] = _("Peter Meyer");
-        break;
-    case "no_title_rev" :
-        $data_sem[0]["lecturer"] = _("Meyer Peter");
-        break;
-    case "full" :
-        $data_sem[0]["lecturer"] = _("Dr. Peter Meyer");
-        break;
-    case "full_rev" :
-        $data_sem[0]["lecturer"] = _("Meyer, Peter, Dr.");
-        break;
-    default :
-        $data_sem[0]["lecturer"] = _("Meyer, P.");
-        break;
-}
-$data_sem[1]["lecturer"] = $data_sem[0]["lecturer"];
-$data_sem[2]["lecturer"] = $data_sem[0]["lecturer"];
-
-$show_time = $this->config->getValue("Main", "time");
-$show_lecturer = $this->config->getValue("Main", "lecturer");
-if ($show_time && $show_lecturer) {
-    if (!$td2width = $this->config->getValue("LecturesInnerTable", "td2width"))
-        $td2width = 50;
-    $colspan = " colspan=\"2\"";
-    $td_time = $this->config->getAttributes("LecturesInnerTable", "td2");
-    $td_time .= " width=\"$td2width%\"";
-    $td_lecturer = " align=\"" . $this->config->getValue("LecturesInnerTable", "td3_align");
-    $td_lecturer .= "\" valign=\"" . $this->config->getValue("LecturesInnerTable", "td2_valign");
-    $td_lecturer .= "\" width=\"" . (100 - $td2width) . "%\"";
-}
-else {
-    $colspan = "";
-    $td_time = $this->config->getAttributes("LecturesInnerTable", "td2") . " width=\"100%\"";
-    $td_lecturer = " align=\"" . $this->config->getValue("LecturesInnerTable", "td3_align");
-    $td_lecturer .= "\" valign=\"" . $this->config->getValue("LecturesInnerTable", "td2_valign");
-    $td_lecturer .= " width=\"100%\"";
-}
-
-echo "\n<table" . $this->config->getAttributes("TableHeader", "table") . ">";
-if ($this->config->getValue("Main", "addinfo")) {
-    echo "\n<tr" . $this->config->getAttributes("InfoCountSem", "tr") . ">";
-    echo "<td" . $this->config->getAttributes("InfoCountSem", "td") . ">";
-    echo "<font" . $this->config->getAttributes("InfoCountSem", "font") . ">&nbsp;";
-    echo "2";
-    echo $this->config->getValue("Main", "textlectures");
-    echo ", " . $this->config->getValue("Main", "textgrouping");
-    $group_by_name = $this->config->getValue("Main", "aliasesgrouping");
-    echo $group_by_name[3];
-    echo "</font></td></tr>";
-}
-$i = 0;
-$group = "";
-foreach ($data_sem as $dat) {
-    $aliases_sem_type = $this->config->getValue("ReplaceTextSemType",
-            "class_{$SEM_TYPE[$dat['group']]['class']}");
-    if ($aliases_sem_type[$sem_types_position[$dat['group']] - 1])
-        $group2 = $aliases_sem_type[$sem_types_position[$dat['group']] - 1];
-    else {
-        $group2 = htmlReady($SEM_TYPE[$dat['group']]["name"]
-                ." (". $SEM_CLASS[$SEM_TYPE[$dat['group']]["class"]]["name"].")");
-    }
-
-    if ($group != $group2) {
-        echo "\n<tr" . $this->config->getAttributes("Grouping", "tr") . ">";
-        echo "<td" . $this->config->getAttributes("Grouping", "td") . ">";
-        echo "<font" . $this->config->getAttributes("Grouping", "font") . ">";
-        echo $group2;
-        echo "\n</td></tr>\n";
-        $group = $group2;
-    }
-
-    echo "<tr" . $this->config->getAttributes("LecturesInnerTable", "tr").">";
-    if ($i % 2 && $this->config->getValue("LecturesInnerTable", "td_bgcolor2_"))
-        echo "<td width=\"100%\"".$this->config->getAttributes("LecturesInnerTable", "td", TRUE)."\">\n";
-    else
-        echo "<td width=\"100%\"".$this->config->getAttributes("LecturesInnerTable", "td")."\">\n";
-    $i++;
-    echo "<table width=\"100%\" border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
-    echo "<tr" . $this->config->getAttributes("LecturesInnerTable", "tr1") . ">";
-    echo "<td$colspan" . $this->config->getAttributes("LecturesInnerTable", "td1") . ">";
-    echo "<font" . $this->config->getAttributes("LecturesInnerTable", "font1") . ">";
-    echo "<a href=\"\"";
-    echo $this->config->getAttributes("SemLink", "a") . ">";
-    echo $dat["name"] . "</a></font></td></tr>";
-
-    if ($show_time || $show_lecturer) {
-        echo "\n<tr" . $this->config->getAttributes("LecturesInnerTable", "tr2") . ">";
-        if ($show_time) {
-            echo "<td$td_time>";
-            echo "<font" . $this->config->getAttributes("LecturesInnerTable", "font2") . ">";
-            echo $dat["time"] . "</font>\n";
-        }
-        if ($show_lecturer) {
-            echo "<td$td_lecturer>";
-            echo "<font" . $this->config->getAttributes("LecturesInnerTable", "font2") . ">(";
-            echo "<a href=\"\"";
-            echo $this->config->getAttributes("LecturerLink", "a") . ">";
-            echo $dat["lecturer"] . "</a>";
-            echo ") </font></td>";
-        }
-        echo "</tr>\n";
-    }
-    echo "</table></td></tr>\n";
-}
-echo "</table>";
-
-?>
diff --git a/lib/extern/modules/views/lecturestable_preview.inc.php b/lib/extern/modules/views/lecturestable_preview.inc.php
deleted file mode 100644
index f032661778c..00000000000
--- a/lib/extern/modules/views/lecturestable_preview.inc.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-
-global $SEM_TYPE, $SEM_CLASS;
-
-// reorganize the $SEM_TYPE-array
-foreach ($SEM_CLASS as $key_class => $class) {
-    $i = 0;
-    foreach ($SEM_TYPE as $key_type => $type) {
-        if ($type["class"] == $key_class) {
-            $i++;
-            $sem_types_position[$key_type] = $i;
-        }
-    }
-}
-
-// get semester data
-$semester_data = Semester::findAllVisible(false);
-// current semester
-$now = time();
-foreach ($semester_data as $key => $sem) {
-    if ($sem["beginn"] >= $now)
-        break;
-}
-$i = 1;
-$data_group[] = 1;
-$data_group[] = 1;
-$data_group[] = 2;
-$data_sem[0]["Name"] = sprintf(_("Name der Veranstaltung %s"), $i++);
-$data_sem[0]["Untertitel"] = sprintf(_("Untertitel der Veranstaltung %s"), $i);
-$data_sem[1]["Name"] = sprintf(_("Name der Veranstaltung %s"), $i++);
-$data_sem[1]["Untertitel"] = sprintf(_("Untertitel der Veranstaltung %s"), $i);
-$data_sem[2]["Name"] = sprintf(_("Name der Veranstaltung %s"), $i);
-$data_sem[2]["Untertitel"] = sprintf(_("Untertitel der Veranstaltung %s"), $i);
-$data_sem[0]["zeiten"] = _("Di. 8:30 - 13:30, Mi. 8:30 - 13:30, Do. 8:30 - 13:30");
-$data_sem[1]["zeiten"] = _("Termine am 31.7. 14:00 - 16:00, 17.8. 11:00 - 14:30, 6.9. 14:00 - 16:00,...");
-$data_sem[2]["zeiten"] = _("Di. 8:30 - 13:30, Mi. 8:30 - 13:30, Do. 8:30 - 13:30");
-$data_sem[0]["VeranstaltungsNummer"] = "1592";
-$data_sem[1]["VeranstaltungsNummer"] = "1258";
-$data_sem[2]["VeranstaltungsNummer"] = "4732";
-$data_sem[0]["status"] = _("Seminar");
-$data_sem[1]["status"] = _("Vorlesung");
-$data_sem[2]["status"] = _("Praktikum");
-$data_sem[0]["art"] = _("Vorlesung im Hauptstudium");
-$data_sem[1]["art"] = _("Vorlesung im Grundstudium");
-$data_sem[2]["art"] = _("Praktikum im Haupstudium");
-$data_sem[0]["Ort"] = "MN13";
-$data_sem[1]["Ort"] = "ZHG107";
-$data_sem[2]["Ort"] = "R124";
-
-switch ($this->config->getValue("Main", "nameformat")) {
-    case "no_title_short" :
-        $data_sem[0]["dozent"] = _("Meyer, P.");
-        break;
-    case "no_title" :
-        $data_sem[0]["dozent"] = _("Peter Meyer");
-        break;
-    case "no_title_rev" :
-        $data_sem[0]["dozent"] = _("Meyer Peter");
-        break;
-    case "full" :
-        $data_sem[0]["dozent"] = _("Dr. Peter Meyer");
-        break;
-    case "full_rev" :
-        $data_sem[0]["dozent"] = _("Meyer, Peter, Dr.");
-        break;
-    default :
-        $data_sem[0]["dozent"] = _("Meyer, P.");
-        break;
-}
-$data_sem[1]["dozent"] = $data_sem[0]["dozent"];
-$data_sem[2]["dozent"] = $data_sem[0]["dozent"];
-
-$repeat_headrow = $this->config->getValue("Main", "repeatheadrow");
-
-$out = "";
-if ($this->config->getValue("Main", "addinfo")) {
-    $group_by_name = $this->config->getValue("Main", "aliasesgrouping");
-    $out = $this->elements["InfoCountSem"]->toString(["content" => "&nbsp;2" .
-            $this->config->getValue("Main", "textlectures") . ", " .
-            $this->config->getValue("Main", "textgrouping") .
-            $group_by_name[3]]);
-}
-
-$i = 0;
-$group2 = "";
-$first_loop = TRUE;
-foreach ($data_group as $group) {
-    $aliases_sem_type = $this->config->getValue("ReplaceTextSemType",
-            "class_{$SEM_TYPE[$group]['class']}");
-    if ($aliases_sem_type[$sem_types_position[$group] - 1])
-        $group1 = $aliases_sem_type[$sem_types_position[$group] - 1];
-    else {
-        $group1 = htmlReady($SEM_TYPE[$group]["name"]
-                ." (". $SEM_CLASS[$SEM_TYPE[$group]["class"]]["name"].")");
-    }
-
-    if ($repeat_headrow == "beneath" && ($group1 != $group2)) {
-        $out .= $this->elements["Grouping"]->toString(["content" => $group1]);
-        $out .= $this->elements["TableHeadrow"]->toString();
-        $group2 = $group1;
-    }
-
-    if($first_loop && $repeat_headrow != "beneath")
-        $out .= $this->elements["TableHeadrow"]->toString();
-
-    if ($repeat_headrow != "beneath" && ($group1 != $group2)) {
-        if ($repeat_headrow && !$first_loop)
-            $out .= $this->elements["TableHeadrow"]->toString();
-        $out .= $this->elements["Grouping"]->toString(["content" => $group1]);
-        $group2 = $group1;
-    }
-
-    $out .= $this->elements["TableRow"]->toString(["content" => $data_sem[$i++],
-            "data_fields" => $this->data_fields]);
-
-    $first_loop = FALSE;
-}
-$this->elements["TableHeader"]->printout(["content" => $out]);
-
-?>
diff --git a/lib/extern/modules/views/news.inc.php b/lib/extern/modules/views/news.inc.php
deleted file mode 100644
index 46eba77a4b1..00000000000
--- a/lib/extern/modules/views/news.inc.php
+++ /dev/null
@@ -1,124 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter003: TEST
-# Lifter007: TODO
-# Lifter010: TODO
-
-$error_message = "";
-
-// stimmt die übergebene range_id?
-$query = "SELECT 1 FROM Institute WHERE Institut_id = ?";
-$statement = DBManager::get()->prepare($query);
-$statement->execute([$this->config->range_id]);
-if (!$statement->fetchColumn()) {
-    $error_message = $GLOBALS["EXTERN_ERROR_MESSAGE"];
-}
-
-if (!$nameformat = $this->config->getValue("Main", "nameformat"))
-    $nameformat = "no_title";
-if ($nameformat == 'last') $GLOBALS['_fullname_sql']['last'] = ' Nachname ';
-
-$news = StudipNews::GetNewsByRange($this->config->range_id, true, true);
-if (!count($news))
-    $error_message = $this->config->getValue("Main", "nodatatext");
-
-if ($this->config->getValue("Main", "studiplink")) {
-    echo "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" ";
-    echo "width=\"" . $this->config->getValue("TableHeader", "table_width");
-    echo "\" align=\"" . $this->config->getValue("TableHeader", "table_align") . "\">\n";
-
-    $studip_link = URLHelper::getLink('dispatch.php/institute/overview?again=yes&cid='. $this->config->range_id);
-    if ($this->config->getValue("Main", "studiplink") == "top") {
-        $args = ["width" => "100%",
-        "height" => "40", "link" => $studip_link];
-        echo "<tr><td width=\"100%\">\n";
-        $this->elements["StudipLink"]->printout($args);
-        echo "</td></tr>";
-    }
-    $table_attr = $this->config->getAttributes("TableHeader", "table");
-    $pattern = ["/width=\"[0-9%]+\"/", "/align=\"[a-z]+\"/"];
-    $replace = ["width=\"100%\"", ""];
-    $table_attr = preg_replace($pattern, $replace, $table_attr);
-    echo "<tr><td width=\"100%\">\n<table$table_attr>\n";
-}
-else
-    echo "<table" . $this->config->getAttributes("TableHeader", "table") . ">\n";
-
-$i = 0;
-$this->elements["TableHeadrow"]->printout();
-
-// no data to print
-if ($error_message) {
-    echo "<tr" . $this->config->getAttributes("TableRow", "tr") . ">\n";
-    echo "<td" . $this->config->getAttributes("TableRow", "td") . " colspan=\"$i\">\n";
-    echo $error_message;
-    echo "</td></tr>\n</table>\n";
-}
-else {
-    $data["data_fields"] = $this->data_fields;
-    $dateform = $this->config->getValue("Main", "dateformat");
-    $show_date_author = $this->config->getValue("Main", "showdateauthor");
-    $not_author_link = $this->config->getValue("Main", "notauthorlink");
-
-    $query = "SELECT COUNT(*)
-              FROM Institute AS i
-              LEFT JOIN user_inst AS ui USING(Institut_id)
-              LEFT JOIN auth_user_md5 AS aum USING(user_id)
-              WHERE Institut_id = ? AND user_id = ? AND ui.inst_perms IN ('autor','tutor','dozent')";
-    $statement = DBManager::get()->prepare($query);
-
-    foreach($news as $news_id => $news_detail){
-        // Mitarbeiter/in am Institut
-        $statement->execute([
-            $this->config->range_id,
-            $news_detail->user_id,
-        ]);
-        $institute_user = $statement->fetchColumn() ?: 0;
-        $statement->closeCursor();
-
-        // !!! LinkInternSimple is not the type of this element,
-        // the type of this element is LinkIntern !!!
-        // this is for compatibiliy reasons only
-        if ($show_date_author !== 'date') {
-            if ($not_author_link || !$institute_user)
-                $author_name = htmlReady(get_fullname($news_detail->user_id, $nameformat));
-            else
-                $author_name = $this->elements["LinkInternSimple"]->toString([
-                    'content'   => htmlReady(get_fullname($news_detail->user_id, $nameformat)),
-                    'link_args' => 'username=' . get_username($news_detail->user_id),
-                    'module'    => 'Persondetails'
-                ]);
-        }
-
-        switch ($show_date_author) {
-            case 'date' :
-                $data["content"]["date"] = strftime($dateform, $news_detail->date);
-                break;
-            case 'author' :
-                $data["content"]["date"] = $author_name;
-                break;
-            default :
-                $data["content"]["date"] = strftime($dateform, $news_detail->date) . "<br>" . $author_name;
-        }
-
-        $data["content"]["topic"] = $this->elements["ContentNews"]->toString([
-            "content" => [
-                "topic" => htmlReady((string) $news_detail->topic),
-                "body"  => formatReady((string) $news_detail->body, TRUE, TRUE),
-            ]
-        ]);
-
-        $this->elements["TableRow"]->printout($data);
-    }
-
-    echo "\n</table>";
-}
-if ($this->config->getValue("Main", "studiplink")) {
-    if ($this->config->getValue("Main", "studiplink") == "bottom") {
-        $args = ["width" => "100%",
-        "height" => "40", "link" => $studip_link];
-        echo "</td></tr>\n<tr><td width=\"100%\">\n";
-        $this->elements["StudipLink"]->printout($args);
-    }
-    echo "</td></tr></table>\n";
-}
diff --git a/lib/extern/modules/views/news_preview.inc.php b/lib/extern/modules/views/news_preview.inc.php
deleted file mode 100644
index 668975f713a..00000000000
--- a/lib/extern/modules/views/news_preview.inc.php
+++ /dev/null
@@ -1,209 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-
-$error_message = "";
-
-$nameformat = $this->config->getValue("Main", "nameformat");
-
-if ($nameformat == "last") {
-    $query = "SELECT n.*, aum.Nachname AS name, aum.username FROM news_range nr LEFT JOIN ";
-    $query .= "news n USING(news_id) LEFT JOIN auth_user_md5 aum USING(user_id) ";
-    $query .= "WHERE range_id='{$this->config->range_id}'";
-}
-else {
-    global $_fullname_sql;
-    $query = "SELECT n.*, {$_fullname_sql[$nameformat]} AS name, ";
-    $query .= "aum.username FROM news_range nr LEFT JOIN ";
-    $query .= "news n USING(news_id) LEFT JOIN auth_user_md5 aum USING(user_id) ";
-    $query .= "LEFT JOIN user_info USING(user_id) ";
-    $query .= "WHERE range_id='{$this->config->range_id}'";
-}
-
-$now = time();
-$data = NULL;
-for ($n = 0; $n < 3; $n++) {
-    $content_data[$n]["date"] = $now - 600000 * ($n + 1);
-    $content_data[$n]["topic"] = sprintf(_("Aktuelle Nachricht Nr. %s"), $n + 1);
-    $content_data[$n]["body"] = str_repeat(sprintf(_("Beschreibung der Nachricht Nr. %s"), $n + 1) . " ", 10);
-    switch ($nameformat) {
-        case "no_title_short" :
-            $content_data[$n]["fullname"] = _("Meyer, P.");
-            break;
-        case "no_title" :
-            $content_data[$n]["fullname"] = _("Peter Meyer");
-            break;
-        case "no_title_rev" :
-            $content_data[$n]["fullname"] = _("Meyer Peter");
-            break;
-        case "full" :
-            $content_data[$n]["fullname"] = _("Dr. Peter Meyer");
-            break;
-        case "full_rev" :
-            $content_data[$n]["fullname"] = _("Meyer, Peter, Dr.");
-            break;
-        case "last" :
-            $content_data[$n]["fullname"] = _("Meyer");
-            break;
-        default :
-            $content_data[$n]["fullname"] = _("Peter Meyer");
-            break;
-    }
-}
-
-if ($this->config->getValue("Main", "studiplink")) {
-    echo "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" ";
-    echo "width=\"" . $this->config->getValue("TableHeader", "table_width");
-    echo "\" align=\"" . $this->config->getValue("TableHeader", "table_align") . "\">\n";
-
-    if ($this->config->getValue("Main", "studiplink") == "top") {
-        $args = ["width" => "100%", "height" => "40", "link" => ""];
-        echo "<tr><td width=\"100%\">\n";
-        $this->elements["StudipLink"]->printout($args);
-        echo "</td></tr>";
-    }
-    $table_attr = $this->config->getAttributes("TableHeader", "table");
-    $pattern = ["/width=\"[0-9%]+\"/", "/align=\"[a-z]+\"/"];
-    $replace = ["width=\"100%\"", ""];
-    $table_attr = preg_replace($pattern, $replace, $table_attr);
-    echo "<tr><td width=\"100%\">\n<table$table_attr>\n";
-}
-else
-    echo "<table" . $this->config->getAttributes("TableHeader", "table") . ">\n";
-
-echo "<tr" . $this->config->getAttributes("TableHeadRow", "tr") . ">\n";
-
-$rf_news = $this->config->getValue("Main", "order");
-$width = $this->config->getValue("Main", "width");
-if ($this->config->getValue("TableHeader", "width_pp") == "PERCENT")
-    $percent = "%";
-$aliases = $this->config->getValue("Main", "aliases");
-$visible = $this->config->getValue("Main", "visible");
-
-$set_1 = $this->config->getAttributes("TableHeadrow", "th");
-$set_2 = $this->config->getAttributes("TableHeadrow", "th", TRUE);
-$zebra = $this->config->getValue("TableHeadrow", "th_zebrath_");
-
-$i = 0;
-foreach($rf_news as $spalte){
-    if ($visible[$spalte]) {
-    
-        // "zebra-effect" in head-row
-        if ($zebra) {
-            if ($i % 2)
-                $set = $set_2;
-            else
-                $set = $set_1;
-        }
-        else
-            $set = $set_1;
-        
-        echo "<th$set width=\"" . $width[$spalte] . "$percent\">";
-        
-        if($aliases[$spalte] == "")
-            echo "<b>&nbsp;</b>\n";
-        else 
-            echo "<font" . $this->config->getAttributes("TableHeadrow", "font") . ">" . $aliases[$spalte] . "</font>\n";
-    
-        echo "</th>\n";
-        $i++;
-    }
-}
-echo "</tr>\n";
-
-$dateform = $this->config->getValue("Main", "dateformat");
-$attr_a = $this->config->getAttributes("LinkInternSimple", "a");
-$attr_font = $this->config->getAttributes("TableRow", "font");
-$attr_div_topic = $this->config->getAttributes("ContentNews", "divtopic");
-$attr_div_body = $this->config->getAttributes("ContentNews", "divbody");
-$attr_font_topic = $this->config->getAttributes("ContentNews", "fonttopic");
-$attr_font_body = $this->config->getAttributes("ContentNews", "fontbody");
-
-$set_1 = $this->config->getAttributes("TableRow", "td");
-$set_2 = $this->config->getAttributes("TableRow", "td", TRUE);
-$zebra = $this->config->getValue("TableRow", "td_zebratd_");
-$show_date_author = $this->config->getValue("Main", "showdateauthor");
-$not_author_link = $this->config->getValue("Main", "notauthorlink");
-
-foreach ($content_data as $dat) {
-    list ($content,$admin_msg) = explode("<admin_msg>",$dat["body"]);
-    if ($admin_msg) 
-        $content.="\n--%%{$admin_msg}%%--";
-    
-    $data['date'] = $attr_font ? "<font$attr_font>" : '';
-    
-    if ($show_date_author != 'date') {
-        if ($not_author_link)
-            $author_name = $dat["fullname"];
-        else
-            $author_name = sprintf("<a href=\"\"%s>%s</a>", $attr_a, $dat["fullname"]);
-    }
-    
-    switch ($show_date_author) {
-        case 'date' :
-            $data['date'] .= strftime($dateform, $dat["date"]);
-            break;
-        case 'author' :
-            $data['date'] .= $author_name;
-            break;
-        default:
-            $data['date'] .= strftime($dateform, $dat["date"]) . '<br>' . $author_name;
-    }
-    
-    $data['date'] .= $attr_font ? '</font>' : '';
-    
-    $data['topic'] = sprintf("<div%s><font%s>%s</font></div><div%s><font%s>%s</font></div>",
-                                                $attr_div_topic, $attr_font_topic,
-                                                $dat["topic"], $attr_div_body,
-                                                $attr_font_body, $content);
-    
-    // "horizontal zebra"
-    if ($zebra == "HORIZONTAL") {
-        if ($i % 2)
-            $set = $set_2;
-        else
-            $set = $set_1;
-    }
-    else
-        $set = $set_1;
-    
-    echo "<tr" . $this->config->getAttributes("TableRow", "tr") . ">\n";
-    
-    $j = 0;
-    foreach($rf_news as $spalte){
-        
-        // "vertical zebra"
-        if ($zebra == "VERTICAL") {
-            if ($j % 2)
-                $set = $set_2;
-            else
-                $set = $set_1;
-        }
-    
-        if ($visible[$spalte]) {
-            if($data[$this->data_fields[$spalte]] == "")
-                echo "<td$set>&nbsp;</td>\n";
-            else
-                echo "<td$set>" . $data[$this->data_fields[$spalte]] . "</td>\n";
-            $j++;
-        }
-    }
-    
-    echo "</tr>\n";
-    $i++;
-}
-
-echo "\n</table>";
-
-if ($this->config->getValue("Main", "studiplink")) {
-    if ($this->config->getValue("Main", "studiplink") == "bottom") {
-        $args = ["width" => "100%", "height" => "40", "link" => ""];
-        echo "</td></tr>\n<tr><td width=\"100%\">\n";
-        $this->elements["StudipLink"]->printout($args);
-    }
-    echo "</td></tr></table>\n";
-}
-
-?>
diff --git a/lib/extern/modules/views/newsticker.inc.php b/lib/extern/modules/views/newsticker.inc.php
deleted file mode 100644
index c77f13f6093..00000000000
--- a/lib/extern/modules/views/newsticker.inc.php
+++ /dev/null
@@ -1,76 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter003: TEST
-# Lifter005: TODO
-# Lifter007: TODO
-# Lifter010: TODO
-$js_only = $this->config->getValue("Main", "jsonly");
-if (!$js_only)
-echo "
-<script type=\"text/javascript\">
-<!--\n";
-echo "var newsticker_max = 0;
-
-function textlist() {
-    newsticker_max = textlist.arguments.length;
-    for (i = 0; i < newsticker_max; i++)
-        this[i] = textlist.arguments[i];
-}
-
-newsticker_tl = new textlist(";
-
-$topics = [];
-$query = "SELECT news.topic
-          FROM news_range
-          LEFT JOIN news USING (news_id)
-          WHERE range_id LIKE ? AND UNIX_TIMESTAMP() BETWEEN date AND date + expire
-          ORDER BY date DESC";
-$statement = DBManager::get()->prepare($query);
-$statement->execute([$this->config->range_id]);
-while ($topic = $statement->fetchColumn()) {
-    $topics[] = sprintf("'%s'", addslashes($topic));
-}
-
-if (count($topics) == 0) {
-    $topics[] = "'" . $this->config->getValue("Main", "nodatatext") . "'";
-}
-if ($this->config->getValue("Main", "endtext"))
-    $topics[] = "'" . $this->config->getValue("Main", "endtext") . "'";
-
-echo implode(", ", $topics) . ")";
-
-echo "
-var newsticker_x = 0; newsticker_pos = 0;
-var newsticker_l = newsticker_tl[0].length;
-
-function newsticker() {
-    document.tickform.tickfield.value = newsticker_tl[newsticker_x].substring(0, newsticker_pos) + \"_\";
-    if (newsticker_pos++ == newsticker_l) {
-        newsticker_pos = 0; 
-        setTimeout(\"newsticker()\", ";
-echo $this->config->getValue("Main", "pause");
-echo "); 
-        if (++newsticker_x == newsticker_max)
-            newsticker_x = 0; 
-        newsticker_l = newsticker_tl[newsticker_x].length;
-    }
-    else
-        setTimeout(\"newsticker()\", ";
-echo ceil(1000 / $this->config->getValue("Main", "frequency"));
-echo ");
-}\n";
-if (!$js_only) {
-    echo "//-->
-</script>
-<form name=\"tickform\">
-    <textarea name=\"tickfield\" rows=\"";
-    echo $this->config->getValue("Main", "rows") . "\" cols=\"";
-    echo $this->config->getValue("Main", "length") . "\" style=\"";
-    echo $this->config->getValue("Main", "style") . "\" wrap=\"virtual\">";
-    echo $this->config->getValue("Main", "starttext");
-    echo "</textarea>\n</form>\n";
-
-    if ($this->config->getValue("Main", "automaticstart"))
-        echo "<script type=\"text/javascript\">\n\tnewsticker();\n</script>\n";
-}   
-?>
diff --git a/lib/extern/modules/views/newsticker_preview.inc.php b/lib/extern/modules/views/newsticker_preview.inc.php
deleted file mode 100644
index 61677c18753..00000000000
--- a/lib/extern/modules/views/newsticker_preview.inc.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter005: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-$topics = [];
-echo "
-<script type=\"text/javascript\">
-<!--
-var newsticker_max = 0;
-
-function textlist() {
-    newsticker_max = textlist.arguments.length;
-    for (i = 0; i < newsticker_max; i++)
-        this[i] = textlist.arguments[i];
-}
-
-newsticker_tl = new textlist(";
-
-for ($i = 1; $i < 5; $i++)
-    $topics[] = sprintf("'" . _("Das ist News Nummer %s!") . "'", $i);
-if ($this->config->getValue("Main", "endtext"))
-    $topics[] = "'" . $this->config->getValue("Main", "endtext") . "'";
-echo implode(", ", $topics) . ")";
-
-echo "
-var newsticker_x = 0; newsticker_pos = 0;
-var newsticker_l = newsticker_tl[0].length;
-
-function newsticker() {
-    document.tickform.tickfield.value = newsticker_tl[newsticker_x].substring(0, newsticker_pos) + \"_\";
-    if (newsticker_pos++ == newsticker_l) {
-        newsticker_pos = 0; 
-        setTimeout(\"newsticker()\", ";
-echo $this->config->getValue("Main", "pause");
-echo "); 
-        if (++newsticker_x == newsticker_max)
-            newsticker_x = 0; 
-        newsticker_l = newsticker_tl[newsticker_x].length;
-    }
-    else
-        setTimeout(\"newsticker()\", ";
-echo ceil(1000 / $this->config->getValue("Main", "frequency"));
-echo ");
-}
-//-->
-</script>
-<form name=\"tickform\">
-    <textarea name=\"tickfield\" rows=\"";
-echo $this->config->getValue("Main", "rows") . "\" cols=\"";
-echo $this->config->getValue("Main", "length") . "\" style=\"";
-echo $this->config->getValue("Main", "style") . "\" wrap=\"virtual\">";
-echo $this->config->getValue("Main", "starttext");
-echo "</textarea>\n</form>\n";
-
-if ($this->config->getValue("Main", "automaticstart"))
-    echo "<script type=\"text/javascript\">\n\tnewsticker();\n</script>\n";
-    
-?>
diff --git a/lib/extern/modules/views/persondetails.inc.php b/lib/extern/modules/views/persondetails.inc.php
deleted file mode 100644
index cc186170f31..00000000000
--- a/lib/extern/modules/views/persondetails.inc.php
+++ /dev/null
@@ -1,707 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter003: TEST
-# Lifter007: TODO
-# Lifter010: TODO
-
-require_once 'lib/statusgruppe.inc.php';
-
-$instituts_id = $this->config->range_id;
-$username = $args['username'];
-$sem_id = $args['seminar_id'];
-
-// Mitarbeiter/in am Institut
-$ext_vis_query = get_ext_vis_query();
-$query = "SELECT 1
-          FROM Institute
-          LEFT JOIN user_inst AS ui USING (Institut_id)
-          LEFT JOIN auth_user_md5 AS aum USING (user_id)
-          WHERE Institut_id = ? AND aum.username = ?
-            AND ui.inst_perms IN ('autor', 'tutor', 'dozent') AND {$ext_vis_query}";
-$statement = DBManager::get()->prepare($query);
-$statement->execute([$instituts_id, $username]);
-$temp = $statement->fetchColumn();
-
-// Mitarbeiter/in am Heimatinstitut des Seminars
-if (!$temp && $sem_id) {
-    $query = "SELECT Institut_id
-              FROM seminare AS s
-              LEFT JOIN user_inst AS ui USING (Institut_id)
-              LEFT JOIN auth_user_md5 AS aum USING (user_id)
-              WHERE s.Seminar_id = ? AND aum.username = ?
-                AND ui.inst_perms = 'dozent' AND {$ext_vis_query}";
-    $statement = DBManager::get()->prepare($query);
-    $statement->execute([$sem_id, $username]);
-    $temp = $statement->fetchColumn();
-
-    if ($temp) {
-        $instituts_id = $temp;
-    }
-}
-
-// an beteiligtem Institut Dozent(in)
-if (!$temp && $sem_id) {
-    $query = "SELECT si.institut_id
-              FROM seminare AS s
-              LEFT JOIN seminar_inst AS si ON (s.Seminar_id = si.seminar_id)
-              LEFT JOIN user_inst AS ui ON (si.institut_id = ui.Institut_id)
-              LEFT JOIN auth_user_md5 AS aum USING (user_id)
-              WHERE s.Seminar_id = ? AND si.institut_id != ?
-                AND ui.inst_perms = 'dozent' AND aum.username = ? AND {$ext_vis_query}";
-    $statement = DBManager::get()->prepare($query);
-    $statement->execute([$sem_id, $instituts_id, $username]);
-    $temp = $statement->fetchColumn();
-
-    if ($temp) {
-        $instituts_id = $temp;
-    }
-}
-
-if (!$nameformat = $this->config->getValue('Main', 'nameformat')) {
-    $nameformat = 'full';
-}
-
-// ist zwar global Dozent, aber an keinem Institut eingetragen
-if (!$temp && $sem_id) {
-    $query = "SELECT aum.*, {$GLOBALS['_fullname_sql'][$nameformat]} AS fullname
-              FROM auth_user_md5 AS aum
-              LEFT JOIN user_info USING (user_id)
-              LEFT JOIN seminar_user su USING (user_id)
-              WHERE username = ? AND perms = 'dozent' AND su.seminar_id = ?
-                AND su.status = 'dozent' AND {$ext_vis_query}";
-    $statement = DBManager::get()->prepare($query);
-    $statement->execute([$username, $sem_id]);
-    $row = $statement->fetch(PDO::FETCH_ASSOC);
-} else {
-    $base_query = "SELECT i.Institut_id, i.Name, i.Strasse, i.Plz, i.url, ui.*, aum.*,
-                          {$GLOBALS['_fullname_sql'][$nameformat]} AS fullname,
-                          uin.user_id, uin.lebenslauf, uin.publi, uin.schwerp, uin.Home
-                   FROM Institute AS i
-                   LEFT JOIN user_inst AS ui USING (Institut_id)
-                   LEFT JOIN auth_user_md5 AS aum USING (user_id)
-                   LEFT JOIN user_info AS uin USING (user_id)
-                   WHERE ui.inst_perms IN ('autor', 'tutor', 'dozent')
-                     AND {$ext_vis_query} AND ";
-
-    if ($this->config->getValue('Contact', 'defaultadr')) {
-        $query  = $base_query;
-        $query .= "aum.username = ? AND ui.externdefault = 1";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$username]);
-        $row = $statement->fetch(PDO::FETCH_ASSOC);
-
-        if (!$row) {
-            $query  = $base_query;
-            $query .= "aum.username = ? AND i.Institut_id = ? AND ui.inst_perms IN ('autor', 'tutor', 'dozent')";
-            $statement = DBManager::get()->prepare($query);
-            $statement->execute([$username, $instituts_id]);
-            $row = $statement->fetch(PDO::FETCH_ASSOC);
-        }
-    } else {
-        $query  = $base_query;
-        $query .= "aum.username = ? AND i.Institut_id = ? AND ui.inst_perms IN ('autor', 'tutor', 'dozent')";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$username, $instituts_id]);
-        $row = $statement->fetch(PDO::FETCH_ASSOC);
-    }
-}
-
-if (!$row) {
-    die;
-}
-
-$aliases_content = $this->config->getValue("Main", "aliases");
-$visible_content = $this->config->getValue("Main", "visible");
-
-if ($margin = $this->config->getValue("TableParagraphText", "margin")) {
-    $text_div = "<div style=\"margin-left:$margin;\">";
-    $text_div_end = "</div>";
-}
-else {
-    $text_div = "";
-    $text_div_end = "";
-}
-
-echo "<table" . $this->config->getAttributes("TableHeader", "table") . ">\n";
-
-$studip_link = $GLOBALS['ABSOLUTE_URI_STUDIP'] . 'dispatch.php/settings/account';
-$studip_link .= "?username=$username&login=yes";
-if ($this->config->getValue("Main", "studiplink") == "top") {
-    $args = ["width" => "100%", "height" => "40", "link" => $studip_link];
-    echo "<tr><td width=\"100%\">\n";
-    $this->elements["StudipLink"]->printout($args);
-    echo "</td></tr>";
-}
-
-// generic data fields
-if ($generic_datafields = $this->config->getValue("Main", "genericdatafields")) {
-//  $datafields_obj =& new DataFields($row['user_id']);
-    $fieldEntries = DataFieldEntry::getDataFieldEntries($row['user_id']);
-//  $datafields = $datafields_obj->getLocalFields($row['user_id']);
-}
-
-$user_obj = User::find($row['user_id']);
-
-$order = $this->config->getValue("Main", "order");
-foreach ($order as $position) {
-
-    $data_field = $this->data_fields["content"][$position];
-
-    if ($visible_content[$position]) {
-        switch ($data_field) {
-            case 'lebenslauf' :
-            case 'schwerp' :
-            case 'publi' :
-                if ($row[$data_field] != '' && Visibility::verify($data_field, $row['user_id'])) {
-                    echo "<tr><td width=\"100%\">\n";
-                    echo "<table" . $this->config->getAttributes("TableParagraph", "table") . ">\n";
-                    echo "<tr" . $this->config->getAttributes("TableParagraphHeadline", "tr");
-                    echo "><td" . $this->config->getAttributes("TableParagraphHeadline", "td");
-                    echo "><font" . $this->config->getAttributes("TableParagraphHeadline", "font") . ">\n";
-                    echo $aliases_content[$position] . "</font></td></tr>\n";
-                    echo "<tr" . $this->config->getAttributes("TableParagraphText", "tr") . ">";
-                    echo "<td" . $this->config->getAttributes("TableParagraphText", "td") . ">";
-                    echo "$text_div<font" . $this->config->getAttributes("TableParagraphText", "font") . ">\n";
-                    echo formatReady($user_obj->$data_field, TRUE, TRUE);
-                    echo "</font>$text_div_end</td></tr>\n</table>\n</td></tr>\n";
-                }
-                break;
-            case "news" :
-            case "termine" :
-                if (Visibility::verify($data_field, $row['user_id'])) {
-                    $data_field($this, $row, $aliases_content[$position], $text_div, $text_div_end);
-                }
-                break;
-            case "kategorien" :
-            case "lehre" :
-            case "head" :
-                $data_field($this, $row, $aliases_content[$position], $text_div, $text_div_end);
-                break;
-            // generic data fields
-            default :
-                // include generic datafields
-                if (isset($fieldEntries[$data_field]) && is_object($fieldEntries[$data_field]) && $fieldEntries[$data_field]->getDisplayValue()) {
-                    echo "<tr><td width=\"100%\">\n";
-                    echo "<table" . $this->config->getAttributes("TableParagraph", "table") . ">\n";
-                    echo "<tr" . $this->config->getAttributes("TableParagraphHeadline", "tr");
-                    echo "><td" . $this->config->getAttributes("TableParagraphHeadline", "td");
-                    echo "><font" . $this->config->getAttributes("TableParagraphHeadline", "font") . ">\n";
-                    echo $aliases_content[$position] . "</font></td></tr>\n";
-                    echo "<tr" . $this->config->getAttributes("TableParagraphText", "tr") . ">";
-                    echo "<td" . $this->config->getAttributes("TableParagraphText", "td") . ">";
-                    echo "$text_div<font" . $this->config->getAttributes("TableParagraphText", "font") . ">\n";
-                    echo $fieldEntries[$data_field]->getDisplayValue();
-                    echo "</font>$text_div_end</td></tr>\n</table>\n</td></tr>\n";
-                }
-        }
-    }
-}
-
-if ($this->config->getValue("Main", "studiplink") == "bottom") {
-    $args = ["width" => "100%", "height" => "40", "link" => $studip_link];
-    echo "<tr><td width=\"100%\">\n";
-    $this->elements["StudipLink"]->printout($args);
-    echo "</td></tr>";
-}
-
-echo "</table>\n";
-
-function news (&$module, $row, $alias_content, $text_div, $text_div_end)
-{
-    if (Visibility::verify('news', $row['user_id'])) {
-        if ($margin = $module->config->getValue("TableParagraphSubHeadline", "margin")) {
-            $subheadline_div = "<div style=\"margin-left:$margin;\">";
-            $subheadline_div_end = "</div>";
-        }
-        else {
-            $subheadline_div = "";
-            $subheadline_div_end = "";
-        }
-
-        $query = "SELECT topic, body
-                  FROM news_range AS nr
-                  LEFT JOIN news AS n USING (news_id)
-                  WHERE nr.range_id = ? AND user_id = nr.range_id
-                    AND UNIX_TIMESTAMP() BETWEEN date AND date + expire";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$row['user_id']]);
-        $news = $statement->fetchAll(PDO::FETCH_ASSOC);
-
-        if (count($news) > 0) {
-            echo "<tr><td width=\"100%\">\n";
-            echo "<table" . $module->config->getAttributes("TableParagraph", "table") . ">\n";
-            echo "<tr" . $module->config->getAttributes("TableParagraphHeadline", "tr") . ">";
-            echo "<td" . $module->config->getAttributes("TableParagraphHeadline", "td") . ">";
-            echo "<font" . $module->config->getAttributes("TableParagraphHeadline", "font") . ">";
-            echo "$alias_content</font></td></tr>\n";
-
-            foreach ($news as $item) {
-                echo "<tr" . $module->config->getAttributes("TableParagraphSubHeadline", "tr") . ">";
-                echo "<td" . $module->config->getAttributes("TableParagraphSubHeadline", "td") . ">";
-                echo $subheadline_div;
-                echo "<font" . $module->config->getAttributes("TableParagraphSubHeadline", "font") . ">";
-                echo htmlReady($item['topic']);
-                echo "</font>$subheadline_div_end</td></tr>\n";
-                echo "<tr" . $module->config->getAttributes("TableParagraphText", "tr") . ">";
-                list ($content, $admin_msg) = explode("<admin_msg>", $item['body']);
-                echo "<td" . $module->config->getAttributes("TableParagraphText", "td") . ">";
-                echo "$text_div<font" . $module->config->getAttributes("TableParagraphText", "font") . ">";
-                echo formatReady($content, TRUE, TRUE);
-                echo "</font>$text_div_end</td></tr>\n";
-            }
-            echo "</table>\n</td></tr>\n";
-        }
-    }
-}
-
-function termine (&$module, $row, $alias_content, $text_div, $text_div_end)
-{
-    if (Config::get()->CALENDAR_ENABLE && Visibility::verify('dates', $row['user_id']) || 1) {
-        if ($margin = $module->config->getValue("TableParagraphSubHeadline", "margin")) {
-            $subheadline_div = "<div style=\"margin-left:$margin;\">";
-            $subheadline_div_end = "</div>";
-        }
-        else {
-            $subheadline_div = "";
-            $subheadline_div_end = "";
-        }
-
-        $event_list = SingleCalendar::getEventList($row['user_id'], time(),
-                time() + 60 * 60 * 24 * 7, null, ['class' => 'PUBLIC'],
-                ['CalendarEvent']);
-        if (sizeof($event_list)) {
-            echo "<tr><td width=\"100%\">\n";
-            echo "<table" . $module->config->getAttributes("TableParagraph", "table") . ">\n";
-            echo "<tr" . $module->config->getAttributes("TableParagraphHeadline", "tr") . ">";
-            echo "<td" . $module->config->getAttributes("TableParagraphHeadline", "td") . ">";
-            echo "<font" . $module->config->getAttributes("TableParagraphHeadline", "font") . ">";
-            echo "$alias_content</font></td></tr>\n";
-
-            foreach ($event_list as $event) {
-                echo "<tr" . $module->config->getAttributes("TableParagraphSubHeadline", "tr") . ">";
-                echo "<td" . $module->config->getAttributes("TableParagraphSubHeadline", "td") . ">";
-                echo $subheadline_div;
-                echo "<font" . $module->config->getAttributes("TableParagraphSubHeadline", "font") . ">";
-                echo strftime($module->config->getValue("Main", "dateformat") . " %H:%M", $event->getStart());
-                if (date("dmY", $event->getStart()) == date("dmY", $event->getEnd()))
-                    echo strftime(" - %H:%M", $event->getEnd());
-                else
-                    echo strftime(" - " . $module->config->getValue("Main", "dateformat") . " %H:%M", $event->getEnd());
-                echo " &nbsp;" . htmlReady($event->getTitle());
-                echo "</font>$subheadline_div_end</td></tr>\n";
-                if ($event->getDescription()) {
-                    echo "<tr" . $module->config->getAttributes("TableParagraphText", "tr") . ">";
-                    echo "<td" . $module->config->getAttributes("TableParagraphText", "td") . ">";
-                    echo "$text_div<font" . $module->config->getAttributes("TableParagraphText", "font") . ">";
-                    echo htmlReady($event->getDescription());
-                    echo "</font>$text_div_end</td></tr>\n";
-                }
-            }
-            echo "</table>\n</td></tr>\n";
-        }
-    }
-}
-
-function kategorien (&$module, $row, $alias_content, $text_div, $text_div_end)
-{
-    $query = "SELECT kategorie_id, name, content
-              FROM auth_user_md5 AS aum
-              LEFT JOIN kategorien AS k ON (k.range_id = user_id)
-              WHERE username = ?
-              ORDER BY priority";
-    $statement = DBManager::get()->prepare($query);
-    $statement->execute([$row['username']]);
-    while ($category = $statement->fetch(PDO::FETCH_ASSOC)) {
-        if (Visibility::verify('kat_'.$category['kategorie_id'], $row['user_id'])) {
-            echo "<tr><td width=\"100%\">\n";
-            echo "<table" . $module->config->getAttributes("TableParagraph", "table") . ">\n";
-            echo "<tr" . $module->config->getAttributes("TableParagraphHeadline", "tr") . ">";
-            echo "<td" . $module->config->getAttributes("TableParagraphHeadline", "td") . ">";
-            echo "<font" . $module->config->getAttributes("TableParagraphHeadline", "font") . ">";
-            echo htmlReady($category['name'], TRUE);
-            echo "</font></td></tr>\n";
-            echo "<tr" . $module->config->getAttributes("TableParagraphText", "tr") . ">";
-            echo "<td" . $module->config->getAttributes("TableParagraphText", "td") . ">";
-            echo "$text_div<font" . $module->config->getAttributes("TableParagraphText", "font") . ">";
-            echo formatReady($category['content'], TRUE, TRUE);
-            echo "</font>$text_div_end</td></tr>\n</table>\n</td></tr>\n";
-        }
-    }
-}
-
-function lehre (&$module, $row, $alias_content, $text_div, $text_div_end)
-{
-    global $attr_text_td, $end, $start;
-
-    $all_semester = Semester::findAllVisible(false);
-    // old hard coded $SEMESTER-array starts with index 1
-    array_unshift($all_semester, 0);
-
-    if ($margin = $module->config->getValue('TableParagraphSubHeadline', 'margin')) {
-        $subheadline_div     = '<div style="margin-left:' . $margin . ';">';
-        $subheadline_div_end = '</div>';
-    } else {
-        $subheadline_div     = '';
-        $subheadline_div_end = '';
-    }
-    if ($margin = $module->config->getValue('List', 'margin')) {
-        $list_div     = '<div style="margin-left:' . $margin . ';">';
-        $list_div_end = '</div>';
-    } else {
-        $list_div     = '';
-        $list_div_end = '';
-    }
-
-    $types = [];
-    $semclass = $module->config->getValue('PersondetailsLectures', 'semclass');
-    if (is_null($semclass)) {
-        $semclass = [1];
-    }
-    foreach ($GLOBALS['SEM_TYPE'] as $key => $type) {
-        if (in_array($type['class'], $semclass)) {
-            $types[] = $key;
-        }
-    }
-
-    // Is a semester switch defined?
-    $week_offset = $module->config->getValue('PersondetailsLectures', 'semswitch');
-    if (ctype_digit($week_offset)) {
-        $switch_time = strtotime("+{$week_offset} weeks 0:00:00");
-    } else {
-        $switch_time = strtotime('0:00:00');
-    }
-
-    // get current semester
-    $current_sem = get_sem_num($switch_time) + 1;
-
-    switch ($module->config->getValue('PersondetailsLectures', 'semstart')) {
-        case 'previous':
-            if (isset($all_semester[$current_sem - 1])) {
-                $current_sem -= 1;
-            }
-            break;
-        case 'next':
-            if (isset($all_semester[$current_sem + 1])) {
-                $current_sem += 1;
-            }
-            break;
-        case 'current':
-            break;
-        default:
-            if (isset($all_semester[$module->config->getValue('PersondetailsLectures', 'semstart')])) {
-                $current_sem = $module->config->getValue('PersondetailsLectures', 'semstart');
-            }
-    }
-
-    $last_sem = $current_sem - 1;
-
-    $sem_offset = $module->config->getValue('PersondetailsLectures', 'semrange');
-    if ($sem_offset && ctype_digit($sem_offset)) {
-        $last_sem += $sem_offset;
-    }
-
-    if ($last_sem < $current_sem) {
-        $last_sem = $current_sem;
-    }
-    if (!isset($all_semester[$last_sem])) {
-        $last_sem = count($all_semester) - 1;
-    }
-
-    $query = "SELECT *
-              FROM seminar_user AS su
-                  LEFT JOIN seminare AS s USING (seminar_id)
-                  LEFT JOIN semester_courses ON (s.Seminar_id = semester_courses.course_id)
-              WHERE user_id = :user_id AND su.status = 'dozent'
-                AND start_time <= :beginn
-                AND (semester_courses.semester_id IS NULL OR semester_courses.semester_id = :semester_id)
-                AND s.status IN (:types) AND s.visible = 1";
-    if (Config::get()->IMPORTANT_SEMNUMBER) {
-        $query .= " ORDER BY s.`VeranstaltungsNummer`, s.`Name`";
-    } else {
-        $query .= " ORDER BY s.`Name`";
-    }
-    $statement = DBManager::get()->prepare($query);
-    $statement->bindValue(':user_id', $row['user_id']);
-    $statement->bindValue(':types', $types ?: '');
-
-    $out = '';
-    for (;$current_sem <= $last_sem; $last_sem--) {
-        $statement->bindValue(':beginn', $all_semester[$last_sem]['beginn']);
-        $statement->bindValue(':semester_id', $all_semester[$last_sem]['semester_id']);
-        $statement->execute();
-        $data = $statement->fetchAll(PDO::FETCH_ASSOC);
-
-        if (count($data) > 0) {
-            if (!($module->config->getValue("PersondetailsLectures", "semstart") == "current"
-                    && $module->config->getValue("PersondetailsLectures", "semrange") == 1)) {
-                $out .= "<tr" . $module->config->getAttributes("TableParagraphSubHeadline", "tr") . ">";
-                $out .= "<td" . $module->config->getAttributes("TableParagraphSubHeadline", "td") . ">";
-                $out .= $subheadline_div;
-                $out .= "<font" . $module->config->getAttributes("TableParagraphSubHeadline", "font") . ">";
-                $month = date("n", $all_semester[$last_sem]['beginn']);
-                if($month > 9) {
-                    $out .= $module->config->getValue("PersondetailsLectures", "aliaswise");
-                    $out .= date(" Y/", $all_semester[$last_sem]['beginn']) . date("y", $all_semester[$last_sem]['ende']);
-                }
-                else if($month > 3 && $month < 10) {
-                    $out .= $module->config->getValue("PersondetailsLectures", "aliassose");
-                    $out .= date(" Y", $all_semester[$last_sem]['beginn']);
-                }
-                $out .= "</font>$subheadline_div_end</td></tr>\n";
-            }
-
-            $out .= "<tr" . $module->config->getAttributes("TableParagraphText", "tr") . ">";
-            $out .= "<td" . $module->config->getAttributes("TableParagraphText", "td") . ">";
-
-            if ($module->config->getValue("PersondetailsLectures", "aslist")) {
-                $out .= "$list_div<ul" . $module->config->getAttributes("List", "ul") . ">\n";
-                foreach ($data as $item) {
-                    $out .= "<li" . $module->config->getAttributes("List", "li") . ">";
-                    $name = $item['Name'];
-                    if (Config::get()->IMPORTANT_SEMNUMBER && $item['VeranstaltungsNummer']) {
-                        $name = $item['VeranstaltungsNummer'].' '.$name;
-                    }
-                    $out .= $module->elements["LinkIntern"]->toString(["module" => "Lecturedetails",
-                            "link_args" => "seminar_id=" . $item['Seminar_id'],
-                            "content" => htmlReady($name, TRUE)]);
-                    if ($item['Untertitel'] != '') {
-                        $out .= "<font" . $module->config->getAttributes("TableParagraphText", "font") . "><br>";
-                        $out .= htmlReady($item['Untertitel'], TRUE) . "</font>\n";
-                    }
-                }
-                $out .= "</ul>$list_div_end";
-            }
-            else {
-                $out .= $text_div;
-                $j = 0;
-                foreach ($data as $item) {
-                    if ($j) {
-                        $out .= '<br>';
-                    }
-                    $out .= $module->elements['LinkIntern']->toString(['module' => 'Lecturedetails',
-                            'link_args' => 'seminar_id=' . $item['Seminar_id'],
-                            'content' => htmlReady($item['Name'], TRUE)]);
-                    if ($item['Untertitel'] != '') {
-                        $out .= "<font" . $module->config->getAttributes("TableParagraphText", "font") . ">";
-                        $out .= "<br>" . htmlReady($item['Untertitel'], TRUE) . "</font>\n";
-                    }
-                    $j = 1;
-                }
-                $out .= $text_div_end;
-            }
-            $out .= "</td></tr>\n";
-        }
-    }
-
-    if ($out) {
-        $out_title = '<tr><td width="100%">' . "\n";
-        $out_title .= '<table' . $module->config->getAttributes('TableParagraph', 'table') . '>' . "\n";
-        $out_title .= '<tr' . $module->config->getAttributes('TableParagraphHeadline', 'tr') . '>';
-        $out_title .= '<td' . $module->config->getAttributes('TableParagraphHeadline', 'td') . '>';
-        $out_title .= '<font' . $module->config->getAttributes('TableParagraphHeadline', 'font') . '>';
-        $out_title .= $alias_content . '</font></td></tr>' . "\n";
-        echo $out_title . $out;
-        echo '</table>' . "\n";
-        echo '</td></tr>' . "\n";
-    }
-}
-
-function head (&$module, $row, $a) {
-    $pic_max_width = $module->config->getValue("PersondetailsHeader", "img_width");
-    $pic_max_height = $module->config->getValue("PersondetailsHeader", "img_height");
-
-    // fit size of image
-    if ($pic_max_width && $pic_max_height) {
-        $pic_size = @getimagesize(Avatar::getAvatar($row['user_id'])->getFilename(Avatar::NORMAL));
-
-        if ($pic_size[0] > $pic_max_width || $pic_size[1] > $pic_max_height) {
-            $fak_width = $pic_size[0] / $pic_max_width;
-            $fak_height = $pic_size[1] / $pic_max_height;
-            if ($fak_width > $fak_height) {
-                $pic_width = (int) ($pic_size[0] / $fak_width);
-                $pic_height = (int) ($pic_size[1] / $fak_width);
-            }
-            else {
-                $pic_height = (int) ($pic_size[1] / $fak_height);
-                $pic_width = (int) ($pic_size[0] / $fak_height);
-            }
-        }
-        else {
-            $pic_width = $pic_size[0];
-            $pic_height = $pic_size[1];
-        }
-        $pic_max_width = $pic_width;
-        $pic_max_height = $pic_height;
-    }
-
-    $module->config->config["PersondetailsHeader"]["img_width"] = $pic_max_width;
-    $module->config->config["PersondetailsHeader"]["img_height"] = $pic_max_height;
-
-    if ($module->config->getValue("Main", "showcontact")
-            && $module->config->getValue("Main", "showimage"))
-        $colspan = " colspan=\"2\"";
-    else
-        $colspan = "";
-
-    echo "<tr><td width=\"100%\">\n";
-    echo "<table" . $module->config->getAttributes("PersondetailsHeader", "table") . ">\n";
-
-    // display name as headline
-    if (!$module->config->getValue('PersondetailsHeader', 'hidename')) {
-        echo "<tr" . $module->config->getAttributes("PersondetailsHeader", "tr") . ">";
-        echo "<td$colspan width=\"100%\"";
-        echo $module->config->getAttributes("PersondetailsHeader", "headlinetd") . ">";
-        echo "<font" . $module->config->getAttributes("PersondetailsHeader", "font") . ">";
-        echo htmlReady($row['fullname'], TRUE);
-        echo "</font></td></tr>\n";
-    }
-
-    if ($module->config->getValue("Main", "showimage")
-            || $module->config->getValue("Main", "showcontact")) {
-        echo "<tr>";
-        if ($module->config->getValue("Main", "showcontact")
-                && ($module->config->getValue("Main", "showimage") == "right"
-                || !$module->config->getValue("Main", "showimage"))) {
-                echo "<td" . $module->config->getAttributes("PersondetailsHeader", "contacttd") . ">";
-                echo kontakt($module, $row) . "</td>\n";
-        }
-        if ($module->config->getValue("Main", "showimage")) {
-            echo "<td" . $module->config->getAttributes("PersondetailsHeader", "picturetd") . ">";
-            $avatar = Avatar::getAvatar($row['user_id']);
-            if ($avatar->is_customized() && Visibility::verify('picture', $row['user_id'])) {
-                echo "<img src=\"".$avatar->getURL(Avatar::NORMAL) .
-                     "\" alt=\"Foto " . htmlReady(trim($row['fullname'])) . "\"";
-                echo $module->config->getAttributes("PersondetailsHeader", "img") . "></td>";
-            }
-            else
-                echo "&nbsp;</td>";
-        }
-
-        if ($module->config->getValue("Main", "showcontact")
-                && $module->config->getValue("Main", "showimage") == "left") {
-            echo "<td" . $module->config->getAttributes("PersondetailsHeader", "contacttd") . ">";
-            echo kontakt($module, $row) . "</td>\n";
-        }
-
-        echo "</tr>\n";
-        if ($module->config->getValue('Main', 'showcontact')
-                && $module->config->getValue('Contact', 'separatelinks')) {
-            echo "<tr><td";
-            if ($module->config->getValue('Main', 'showimage'))
-                echo ' colspan="2"';
-            echo $module->config->getAttributes('PersondetailsHeader', 'contacttd') . ">\n";
-            echo kontakt($module, $row, TRUE);
-            echo "</td></tr>\n";
-        }
-    }
-
-    echo  "</table>\n</td></tr>\n";
-}
-
-function kontakt ($module, $row, $separate = FALSE) {
-    $attr_table = $module->config->getAttributes("Contact", "table");
-    $attr_tr = $module->config->getAttributes("Contact", "table");
-    $attr_td = $module->config->getAttributes("Contact", "td");
-    $attr_fonttitle = $module->config->getAttributes("Contact", "fonttitle");
-    $attr_fontcontent = $module->config->getAttributes("Contact", "fontcontent");
-
-    $out = "<table$attr_table>\n";
-    if (!$separate) {
-        $out .= "<tr$attr_tr>";
-        $out .= "<td colspan=\"2\"$attr_td>";
-        $out .= "<font$attr_fonttitle>";
-        if ($headline = $module->config->getValue("Contact", "headline"))
-            $out .= "$headline</font>\n";
-        else
-            $out .= "</font>\n";
-
-        $out .= "<font$attr_fontcontent>";
-
-        if (!$module->config->getValue("Contact", "hidepersname"))
-            $out .= "<br><br>" . htmlReady($row['fullname'], TRUE) . "\n";
-        if ($module->config->getValue('Contact', 'showinstgroup')) {
-            $allgroups = GetAllStatusgruppen($module->config->range_id, $row['user_id']);
-            array_walk($allgroups, function(&$v, $k, $user_id) {
-                $s = Statusgruppen::find($k);
-                $v['role']->name = htmlReady($s->getGenderedName($user_id));
-            }, $row['user_id']);
-            if ($gruppen = GetRoleNames($allgroups))
-                $out .= "<br>" . htmlReady(join(", ", array_values($gruppen)));
-        }
-        // display name of institution (as link)
-        if ($row['Name']) {
-            $br_out = "";
-            if ($module->config->getValue("Contact", "hideinstname") != '1') {
-                if ($module->config->getValue("Contact", "hideinstname") == 'link' && $row['url']) {
-                    $url = htmlReady(trim($row['url']));
-                    if (!mb_stristr($url, "http://"))
-                        $url = "http://$url";
-                    $out .= "<br><br><a href=\"$url\" target=\"_blank\" rel=\"noopener noreferrer\">";
-                    $out .= htmlReady($row['Name'], TRUE) . "</a><br>";
-                }
-                else
-                    $out .= "<br><br>" . htmlReady($row['Name'], TRUE) . "<br>";
-            }
-            if ($module->config->getValue("Contact", "adradd"))
-                $out .= "<br>" . $module->config->getValue("Contact", "adradd");
-        }
-
-        $out .= "<br>";
-        if ($row['Strasse']) {
-            $out .= "<br>" . htmlReady($row['Strasse'], TRUE);
-            if($row['Plz'])
-            $out .= "<br>" . htmlReady($row['Plz'], TRUE);
-        }
-      $out .= "<br><br></font></td></tr>\n";
-    }
-    $order = $module->config->getValue("Contact", "order");
-    $visible = $module->config->getValue("Contact", "visible");
-    $alias_contact = $module->config->getValue("Contact", "aliases");
-    foreach ($order as $position) {
-        $data_field = $module->data_fields["contact"][$position];
-        if (!$visible[$position] || !$row[$data_field])
-            continue;
-        switch ($data_field) {
-            case 'Email' :
-                if ($separate || !$module->config->getValue('Contact', 'separatelinks')) {
-                    $email_address = get_visible_email($row['user_id']);
-                    $out .= "<tr$attr_tr>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fonttitle>";
-                    $out .= $alias_contact[$position] . "</font></td>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fontcontent>";
-                    $mail = trim(htmlReady($email_address));
-                    $out .= "<a href=\"mailto:$mail\">$mail</a>";
-                }
-                break;
-            case 'Home' :
-                if (($separate || !$module->config->getValue('Contact', 'separatelinks')) &&
-                       Visibility::verify('homepage', $row['user_id'])) {
-                    $out .= "<tr$attr_tr>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fonttitle>";
-                    $out .= $alias_contact[$position] . "</font></td>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fontcontent>";
-                    $out .= formatLinks($row['Home']);
-                }
-                break;
-            default:
-                if (!$separate) {
-                    $out .= "<tr$attr_tr>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fonttitle>";
-                    $out .= $alias_contact[$position] . "</font></td>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fontcontent>";
-                    $out .= htmlReady($row[$data_field], TRUE);
-                }
-        }
-        if ($row[$data_field])
-            $out .= "</font></td></tr>\n";
-    }
-    $out .= "</table>\n";
-
-    return $out;
-}
diff --git a/lib/extern/modules/views/persondetails_preview.inc.php b/lib/extern/modules/views/persondetails_preview.inc.php
deleted file mode 100644
index 73f9942ce52..00000000000
--- a/lib/extern/modules/views/persondetails_preview.inc.php
+++ /dev/null
@@ -1,531 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-
-
-global $_fullname_sql;
-
-$attr_subheadline_td = preg_replace('/width\="[^"]+"/i',
-        $this->config->getAttributes("TableParagraphSubHeadline", "td"),
-        $this->config->getValue("TableParagraph", "margin"));
-
-
-$aliases_content = $this->config->getValue("Main", "aliases");
-$visible_content = $this->config->getValue("Main", "visible");
-
-if ($margin = $this->config->getValue("TableParagraphText", "margin")) {
-    $text_div = "<div style=\"margin-left:$margin;\">";
-    $text_div_end = "</div>";
-}
-else {
-    $text_div = "";
-    $text_div_end = "";
-}
-
-$first_loop = TRUE;
-$order = $this->config->getValue("Main", "order");
-foreach ($order as $position) {
-
-    $data_field = $this->data_fields["content"][$position];
-
-    if ($visible_content[$position]) {
-        $data = NULL;
-        switch ($data_field) {
-            case "lebenslauf" :
-                $data["content"] = str_repeat(_("Das ist mein Lebenslauf.") . " &nbsp;", 15);
-                break;
-            case "schwerp" :
-                $data["content"] = str_repeat(_("Das sind meine Schwerpunkte.") . " &nbsp;", 15);
-                break;
-            case "publi" :
-                $data["content"] = str_repeat(_("Das sind meine Publikationen.") . " &nbsp;", 15);
-                break;
-            case "news" :
-                $data[0]["topic"] = sprintf(_('Das ist News Nr. %u'), 1);
-                $data[0]["body"] = str_repeat(sprintf(_('News Nr. %u'), 1) . " &nbsp;", 10);
-                $data[1]["topic"] = sprintf(_('Das ist News Nr. %u'), 2);
-                $data[1]["body"] = str_repeat(sprintf(_('News Nr. %u'), 2) . " &nbsp;", 10);
-                $data[2]["topic"] = sprintf(_('Das ist News Nr. %u'), 3);
-                $data[2]["body"] = str_repeat(sprintf(_('News Nr. %u'), 3) . " &nbsp;", 10);
-                break;
-            case "termine" :
-                $now = time();
-                for ($i = 0; $i < 3; $i++) {
-                    $data[$i]["start"] = $now + 19710329 * ($i + 1);
-                    $data[$i]["end"] = $data[$i]["start"] + 1000 * ($i + 1);
-                }
-                $data[0]["title"] = _("Das ist der erste Termin");
-                $data[1]["title"] = _("Das ist der zweite Termin");
-                $data[2]["title"] = _("Das ist der dritte Termin");
-                $data[0]["content"] = str_repeat(_("Erster Termin") . " &nbsp;", 10);
-                $data[1]["content"] = str_repeat(_("Zweiter Termin") . " &nbsp;", 10);
-                $data[2]["content"] = str_repeat(_("dritter Termin ") . " &nbsp;", 10);
-                break;
-            case "kategorien" :
-                $data["headline"] = _("Eigene Kategorie");
-                $data["content"] = str_repeat(_("Eigene Kategorie") . " &nbsp;", 10);
-                break;
-            case "lehre" :
-                $now = time();
-                $data[0]["start_time"] = $now - 164160000;
-                $data[1]["start_time"] = $now;
-                $data[2]["start_time"] = $now + 164160000;
-                $data[0]["name"] = sprintf(_('Veranstaltung %u'), 1);
-                $data[1]["name"] = sprintf(_('Veranstaltung %u'), 2);
-                $data[2]["name"] = sprintf(_('Veranstaltung %u'), 3);
-                $data[0]["untertitel"] = sprintf(_('Untertitel der Veranstaltung %u'), 1);
-                $data[1]["untertitel"] = sprintf(_('Untertitel der Veranstaltung %u'), 2);
-                $data[2]["untertitel"] = sprintf(_('Untertitel der Veranstaltung %u'), 3);
-                break;
-            case "head" :
-                $nameformat = $this->config->getValue("Main", "nameformat");
-                $user = User::build([
-                    'vorname'     => 'Peter',
-                    'nachname'    => 'Meyer',
-                    'title_front' => 'Dr.',
-                ]);
-
-                $data['fullname'] = $user->getFullName($nameformat);
-                $data['instfunction'] = _("HochschullehrerIn");
-                $data["Name"] = _("Mustereinrichtung");
-                $data["Strasse"] = _("Musterstra&szlig;e 23");
-                $data["Plz"] = _("12345 Musterstadt");
-                $data["raum"] = "A 123";
-                $data["Telefon"] = "213 - 237 192";
-                $data["Fax"] = "213 - 237 191";
-                $data["Email"] = "email@email.org";
-                $data["Home"] = "http://www.studip.de";
-                $data["sprechzeiten"] = _("Mo. und Do. 12.00 - 13.00");
-                break;
-        }
-
-        if ($first_loop) {
-            echo "<table" . $this->config->getAttributes("TableHeader", "table") . ">\n";
-            if ($this->config->getValue("Main", "studiplink") == "top") {
-                $args = ["width" => "100%", "height" => "40", "link" => ""];
-                echo "<tr><td width=\"100%\">\n";
-                $this->elements["StudipLink"]->printout($args);
-                echo "</td></tr>";
-            }
-            $first_loop = FALSE;
-        }
-
-        switch ($data_field) {
-            case "lebenslauf" :
-            case "schwerp" :
-            case "publi" :
-                echo "\n<tr><td width=\"100%\">\n";
-                echo "<table" . $this->config->getAttributes("TableParagraph", "table") . ">\n";
-                echo "<tr" . $this->config->getAttributes("TableParagraphHeadline", "tr");
-                echo "><td" . $this->config->getAttributes("TableParagraphHeadline", "td");
-                echo "><font" . $this->config->getAttributes("TableParagraphHeadline", "font") . ">\n";
-                echo $aliases_content[$position] . "</font></td></tr>\n";
-                echo "<tr" . $this->config->getAttributes("TableParagraphText", "tr") . ">";
-                echo "<td" . $this->config->getAttributes("TableParagraphText", "td") . ">";
-                echo "$text_div<font" . $this->config->getAttributes("TableParagraphText", "font") . ">\n";
-                echo $data["content"];
-                echo "</font>$text_div_end</td></tr>\n</table>\n</td></tr>\n";
-                break;
-            case "news" :
-            case "termine" :
-            case "kategorien" :
-            case "lehre" :
-            case "head" :
-                $data_field($this, $data, $aliases_content[$position], $text_div, $text_div_end);
-        }
-    }
-}
-
-// fit size of image
-if ($pic_max_width && $pic_max_height) {
-    $pic_size = @getimagesize($GLOBALS['CANONICAL_RELATIVE_PATH_STUDIP'] . "user/"
-            . $db->f("user_id") . ".jpg");
-
-    if ($pic_size[0] > $pic_max_width || $pic_size[1] > $pic_max_height) {
-        $fak_width = $pic_size[0] / $pic_max_width;
-        $fak_height = $pic_size[1] / $pic_max_height;
-        if ($fak_width > $fak_height) {
-            $pic_width = (int) ($pic_size[0] / $fak_width);
-            $pic_height = (int) ($pic_size[1] / $fak_width);
-        }
-        else {
-            $pic_height = (int) ($pic_size[1] / $fak_height);
-            $pic_width = (int) ($pic_size[0] / $fak_height);
-        }
-    }
-    else {
-        $pic_width = $pic_size[0];
-        $pic_height = $pic_size[1];
-    }
-    $pic_max_width = $pic_width;
-    $pic_max_height = $pic_height;
-}
-else {
-    $pic_max_width = "";
-    $pic_max_height = "";
-}
-
-if ($this->config->getValue("Main", "studiplink") == "bottom") {
-    $args = ["width" => "100%", "height" => "40", "link" => ""];
-    echo "<tr><td width=\"100%\">\n";
-    $this->elements["StudipLink"]->printout($args);
-    echo "</td></tr>";
-}
-
-echo "</table>\n";
-
-function news (&$module, $data, $alias_content, $text_div, $text_div_end) {
-    if ($margin = $module->config->getValue("TableParagraphSubHeadline", "margin")) {
-        $subheadline_div = "<div style=\"margin-left:$margin;\">";
-        $subheadline_div_end = "</div>";
-    }
-    else {
-        $subheadline_div = "";
-        $subheadline_div_end = "";
-    }
-
-    echo "<tr><td width=\"100%\">\n";
-    echo "<table" . $module->config->getAttributes("TableParagraph", "table") . ">\n";
-    echo "<tr" . $module->config->getAttributes("TableParagraphHeadline", "tr") . ">";
-    echo "<td" . $module->config->getAttributes("TableParagraphHeadline", "td") . ">";
-    echo "<font" . $module->config->getAttributes("TableParagraphHeadline", "font") . ">";
-    echo "$alias_content</font></td></tr>\n";
-    foreach ($data as $dat) {
-        echo "<tr" . $module->config->getAttributes("TableParagraphSubHeadline", "tr") . ">";
-        echo "<td" . $module->config->getAttributes("TableParagraphSubHeadline", "td") . ">";
-        echo $subheadline_div;
-        echo "<font" . $module->config->getAttributes("TableParagraphSubHeadline", "font") . ">";
-        echo $dat["topic"];
-        echo "</font>$subheadline_div_end</td></tr>\n";
-        echo "<tr" . $module->config->getAttributes("TableParagraphText", "tr") . ">";
-        list ($content, $admin_msg) = explode("<admin_msg>", $dat["body"]);
-        echo "<td" . $module->config->getAttributes("TableParagraphText", "td") . ">";
-        echo "$text_div<font" . $module->config->getAttributes("TableParagraphText", "font") . ">";
-        echo $content;
-        echo "</font>$text_div_end</td></tr>\n";
-    }
-    echo "</table>\n</td></tr>\n";
-}
-
-function termine (&$module, $data, $alias_content, $text_div, $text_div_end) {
-    if (Config::get()->CALENDAR_ENABLE) {
-        if ($margin = $module->config->getValue("TableParagraphSubHeadline", "margin")) {
-            $subheadline_div = "<div style=\"margin-left:$margin;\">";
-            $subheadline_div_end = "</div>";
-        }
-        else {
-            $subheadline_div = "";
-            $subheadline_div_end = "";
-        }
-
-        echo "<tr><td width=\"100%\">\n";
-        echo "<table" . $module->config->getAttributes("TableParagraph", "table") . ">\n";
-        echo "<tr" . $module->config->getAttributes("TableParagraphHeadline", "tr") . ">";
-        echo "<td" . $module->config->getAttributes("TableParagraphHeadline", "td") . ">";
-        echo "<font" . $module->config->getAttributes("TableParagraphHeadline", "font") . ">";
-        echo "$alias_content</font></td></tr>\n";
-
-        foreach ($data as $dat) {
-            echo "<tr" . $module->config->getAttributes("TableParagraphSubHeadline", "tr") . ">";
-            echo "<td" . $module->config->getAttributes("TableParagraphSubHeadline", "td") . ">";
-            echo $subheadline_div;
-            echo "<font" . $module->config->getAttributes("TableParagraphSubHeadline", "font") . ">";
-            echo strftime($module->config->getValue("Main", "dateformat") . " %H.%m", $dat["start"]);
-            if (date("dmY", $dat["start"]) == date("dmY", $dat["end"]))
-                echo strftime(" - %H.%m", $dat["end"]);
-            else
-                echo strftime(" - " . $module->config->getValue("Main", "dateformat") . " %H.%m", $dat["end"]);
-            echo " &nbsp;" . $dat["title"];
-            echo "</font>$subheadline_div_end</td></tr>\n";
-            echo "<tr" . $module->config->getAttributes("TableParagraphText", "tr") . ">";
-            echo "<td" . $module->config->getAttributes("TableParagraphText", "td") . ">";
-            echo "$text_div<font" . $module->config->getAttributes("TableParagraphText", "font") . ">";
-            echo $dat["content"];
-            echo "</font>$text_div_end</td></tr>\n";
-        }
-        echo "</table>\n</td></tr>\n";
-    }
-}
-
-function kategorien (&$module, $data, $alias_content, $text_div, $text_div_end) {
-    echo "<tr><td width=\"100%\">\n";
-    echo "<table" . $module->config->getAttributes("TableParagraph", "table") . ">\n";
-    echo "<tr" . $module->config->getAttributes("TableParagraphHeadline", "tr") . ">";
-    echo "<td" . $module->config->getAttributes("TableParagraphHeadline", "td") . ">";
-    echo "<font" . $module->config->getAttributes("TableParagraphHeadline", "font") . ">";
-    echo $data["headline"];
-    echo "</font></td></tr>\n";
-    echo "<tr" . $module->config->getAttributes("TableParagraphText", "tr") . ">";
-    echo "<td" . $module->config->getAttributes("TableParagraphText", "td") . ">";
-    echo "$text_div<font" . $module->config->getAttributes("TableParagraphText", "font") . ">";
-    echo $data["content"];
-    echo "</font>$text_div_end</td></tr>\n</table>\n</td></tr>\n";
-}
-
-function lehre (&$module, $data, $alias_content, $text_div, $text_div_end)
-{
-    $all_semester = Semester::findAllVisible(false);
-    // old hard coded $SEMESTER-array starts with index 1
-    array_unshift($all_semester, 0);
-
-    if ($margin = $module->config->getValue("TableParagraphSubHeadline", "margin")) {
-        $subheadline_div = "<div style=\"margin-left:$margin;\">";
-        $subheadline_div_end = "</div>";
-    } else {
-        $subheadline_div = "";
-        $subheadline_div_end = "";
-    }
-    if ($margin = $module->config->getValue("List", "margin")) {
-        $list_div = "<div style=\"margin-left:$margin;\">";
-        $list_div_end = "</div>";
-    } else {
-        $list_div = "";
-        $list_div_end = "";
-    }
-    // sem-types in class 1 (Lehre)
-    foreach ($GLOBALS["SEM_TYPE"] as $key => $type) {
-        if ($type["class"] == 1) {
-            $types[] = $key;
-        }
-    }
-
-
-    $switch_time = mktime(0, 0, 0, date("m"),
-            date("d") + 7 * $module->config->getValue("PersondetailsLectures", "semswitch"), date("Y"));
-    // get current semester
-    $current_sem = get_sem_num($switch_time) + 1;
-
-    switch ($module->config->getValue("PersondetailsLectures", "semstart")) {
-        case "previous" :
-            if (isset($all_semester[$current_sem - 1])) {
-                $current_sem--;
-            }
-            break;
-        case "next" :
-            if (isset($all_semester[$current_sem + 1])) {
-                $current_sem++;
-            }
-            break;
-        case "current" :
-            break;
-        default :
-            if (isset($all_semester[$module->config->getValue("PersondetailsLectures", "semstart")])) {
-                $current_sem = $module->config->getValue("PersondetailsLectures", "semstart");
-            }
-    }
-
-    $last_sem = $current_sem + $module->config->getValue("PersondetailsLectures", "semrange") - 1;
-    if ($last_sem < $current_sem) {
-        $last_sem = $current_sem;
-    }
-    if (!isset($all_semester[$last_sem])) {
-        $last_sem = count($all_semester) - 1;
-    }
-
-    $out = "";
-    for (;$current_sem <= $last_sem; $last_sem--) {
-        if (!($module->config->getValue("PersondetailsLectures", "semstart") == "current"
-                && $module->config->getValue("PersondetailsLectures", "semrange") == 1)) {
-            $out .= "<tr" . $module->config->getAttributes("TableParagraphSubHeadline", "tr") . ">";
-            $out .= "<td" . $module->config->getAttributes("TableParagraphSubHeadline", "td") . ">";
-            $out .= $subheadline_div;
-            $out .= "<font" . $module->config->getAttributes("TableParagraphSubHeadline", "font") . ">";
-            $month = date("n", $all_semester[$last_sem]["beginn"]);
-            if($month > 9) {
-                $out .= $module->config->getValue("PersondetailsLectures", "aliaswise");
-                $out .= date(" Y/", $all_semester[$last_sem]["beginn"]) . date("y", $all_semester[$last_sem]["ende"]);
-            }
-            else if($month > 3 && $month < 10) {
-                $out .= $module->config->getValue("PersondetailsLectures", "aliassose");
-                $out .= date(" Y", $all_semester[$last_sem]["beginn"]);
-            }
-            $out .= "</font>$subheadline_div_end</td></tr>\n";
-        }
-
-        $out .= "<tr" . $module->config->getAttributes("TableParagraphText", "tr") . ">";
-        $out .= "<td" . $module->config->getAttributes("TableParagraphText", "td") . ">";
-
-        if ($module->config->getValue("PersondetailsLectures", "aslist")) {
-            $out .= "$list_div<ul" . $module->config->getAttributes("List", "ul") . ">\n";
-            foreach ($data as $dat) {
-                $out .= "<li" . $module->config->getAttributes("List", "li") . ">";
-                $out .= "<font" . $module->config->getAttributes("LinkIntern", "font") . ">";
-                $out .= "<a href=\"\"" . $module->config->getAttributes("LinkIntern", "a") . ">";
-                $out .= $dat["name"] . "</a></font>\n";
-                $out .= "<font" . $module->config->getAttributes("TableParagraphText", "font") . "><br>";
-                $out .= $dat["untertitel"] . "</font>\n";
-            }
-            $out .= "</ul>$list_div_end";
-        }
-        else {
-            $out .= $text_div;
-            $j = 0;
-            foreach ($data as $dat) {
-                if ($j) {
-                    $out .= "<br><br>";
-                }
-                $out .= "<font" . $module->config->getAttributes("LinkIntern", "font") . ">";
-                $out .= "<a href=\"\"" . $module->config->getAttributes("LinkIntern", "a") . ">";
-                $out .= $dat["name"] . "</a></font>\n";
-                $out .= "<font" . $module->config->getAttributes("TableParagraphText", "font") . ">";
-                $out .= "<br>" . $dat["untertitel"] . "</font>\n";
-                $j = 1;
-            }
-            $out .= $text_div_end;
-        }
-        $out .= "</td></tr>\n";
-    }
-
-    if ($out) {
-        $out_title = "<tr><td width=\"100%\">\n";
-        $out_title .= "<table" . $module->config->getAttributes("TableParagraph", "table") . ">\n";
-        $out_title .= "<tr" . $module->config->getAttributes("TableParagraphHeadline", "tr") . ">";
-        $out_title .= "<td" . $module->config->getAttributes("TableParagraphHeadline", "td") . ">";
-        $out_title .= "<font" . $module->config->getAttributes("TableParagraphHeadline", "font") . ">";
-        $out_title .= $alias_content . "</font></td></tr>\n";
-        echo $out_title . $out . "</table>\n</td></tr>\n";
-    }
-}
-
-function head (&$module, $data, $a) {
-    if ($module->config->getValue("Main", "showcontact")
-            && $module->config->getValue("Main", "showimage"))
-        $colspan = " colspan=\"2\"";
-    else
-        $colspan = "";
-
-    echo "<tr><td width=\"100%\">\n";
-    echo "<table" . $module->config->getAttributes("PersondetailsHeader", "table") . ">\n";
-    if (!$module->config->getValue('PersondetailsHeader', 'hidename')) {
-        echo "<tr" . $module->config->getAttributes("PersondetailsHeader", "tr") . ">";
-        echo "<td$colspan width=\"100%\"";
-        echo $module->config->getAttributes("PersondetailsHeader", "headlinetd") . ">";
-        echo "<font" . $module->config->getAttributes("PersondetailsHeader", "font") . ">";
-        echo $data["fullname"];
-        echo "</font></td></tr>\n";
-    }
-
-    if ($module->config->getValue("Main", "showimage")
-            || $module->config->getValue("Main", "showcontact")) {
-        echo "<tr>";
-        if ($module->config->getValue("Main", "showcontact")
-                && ($module->config->getValue("Main", "showimage") == "right"
-                || !$module->config->getValue("Main", "showimage"))) {
-                echo "<td" . $module->config->getAttributes("PersondetailsHeader", "contacttd") . ">";
-                echo kontakt($module, $data) . "</td>\n";
-        }
-
-        if ($module->config->getValue("Main", "showimage")) {
-            echo "<td" . $module->config->getAttributes("PersondetailsHeader", "picturetd") . ">";
-            echo "<img src=\"".Avatar::getNobody()->getUrl(Avatar::NORMAL)."\" alt=\"Foto " . $data["fullname"] . "\"";
-            echo $module->config->getAttributes("PersondetailsHeader", "img") . ">";
-        }
-
-        if ($module->config->getValue("Main", "showcontact")
-                && $module->config->getValue("Main", "showimage") == "left") {
-            echo "<td" . $module->config->getAttributes("PersondetailsHeader", "contacttd") . ">";
-            echo kontakt($module, $data) . "</td>\n";
-        }
-
-        echo "</tr>\n";
-        if ($module->config->getValue('Main', 'showcontact')
-                && $module->config->getValue('Contact', 'separatelinks')) {
-            echo "<tr><td";
-            if ($module->config->getValue('Main', 'showimage'))
-                echo ' colspan="2"';
-            echo $module->config->getAttributes('PersondetailsHeader', 'contacttd') . ">\n";
-            echo kontakt($module, $data, TRUE);
-            echo "</td></tr>\n";
-        }
-    }
-
-    echo "</table>\n</td></tr>\n";
-}
-
-function kontakt (&$module, $data, $separate = FALSE) {
-    $attr_table = $module->config->getAttributes("Contact", "table");
-    $attr_tr = $module->config->getAttributes("Contact", "table");
-    $attr_td = $module->config->getAttributes("Contact", "td");
-    $attr_fonttitle = $module->config->getAttributes("Contact", "fonttitle");
-    $attr_fontcontent = $module->config->getAttributes("Contact", "fontcontent");
-
-    $out = "<table$attr_table>\n";
-    if (!$separate) {
-        $out .= "<tr$attr_tr>";
-        $out .= "<td colspan=\"2\"$attr_td>";
-        $out .= "<font$attr_fonttitle>";
-        if ($headline = $module->config->getValue("Contact", "headline"))
-            $out .= "$headline</font>\n";
-        else
-            $out .= "</font>\n";
-        $out .= "<font$attr_fontcontent>";
-
-        if (!$module->config->getValue("Contact", "hidepersname"))
-            $out .= "<br><br>" . $data["fullname"] . "\n";
-        if ($module->config->getValue('Contact', 'showinstgroup'))
-            $out .= "<br>{$data['instfunction']}\n";
-
-        if ($module->config->getValue("Contact", "hideinstname") != '1') {
-            if ($module->config->getValue("Contact", "hideinstname") == 'link')
-                $out .= "<br><br><a href=\"\">" . $data["Name"] . "</a><br>";
-            else
-                $out .= "<br><br>" . $data["Name"] . "<br>";
-        }
-        if ($module->config->getValue("Contact", "adradd"))
-            $out .= "<br>" . $module->config->getValue("Contact", "adradd");
-
-        $out .= "<br><br>" . $data["Strasse"];
-        $out .= "<br>" . $data["Plz"];
-
-      $out .= "<br><br></font></td></tr>\n";
-    }
-    $order = $module->config->getValue("Contact", "order");
-    $visible = $module->config->getValue("Contact", "visible");
-    $alias_contact = $module->config->getValue("Contact", "aliases");
-    foreach ($order as $position) {
-        if (!$visible[$position])
-            continue;
-        $data_field = $module->data_fields["contact"][$position];
-        switch ($data_field) {
-            case 'Email' :
-                if ($separate || !$module->config->getValue('Contact', 'separatelinks')) {
-                    $out .= "<tr$attr_tr>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fonttitle>";
-                    $out .= $alias_contact[$position] . "</font></td>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fontcontent>";
-                    $out .= "<a href=\"mailto:{$data['Email']}\">{$data['Email']}</a>";
-                }
-                break;
-            case 'Home' :
-                if ($separate || !$module->config->getValue('Contact', 'separatelinks')) {
-                    $out .= "<tr$attr_tr>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fonttitle>";
-                    $out .= $alias_contact[$position] . "</font></td>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fontcontent>{$data['Home']}";
-                }
-                break;
-            default:
-                if (!$separate) {
-                    $out .= "<tr$attr_tr>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fonttitle>";
-                    $out .= $alias_contact[$position] . "</font></td>";
-                    $out .= "<td$attr_td>";
-                    $out .= "<font$attr_fontcontent>{$data[$data_field]}";
-                }
-        }
-        $out .= "</font></td></tr>\n";
-    }
-
-    $out .= "</table>\n";
-
-    return $out;
-}
-
-?>
diff --git a/lib/extern/modules/views/persons.inc.php b/lib/extern/modules/views/persons.inc.php
deleted file mode 100644
index d032b12273d..00000000000
--- a/lib/extern/modules/views/persons.inc.php
+++ /dev/null
@@ -1,265 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter003: TEST
-# Lifter007: TODO
-# Lifter010: TODO
-/**
-* persons.inc.php
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       persons
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// persons.inc.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-require_once 'lib/user_visible.inc.php';
-
-global $_fullname_sql;
-
-// [tlx] We are not inside a class definition, so where does $this refer to?
-$range_id = $this->config->range_id;
-
-//$all_groups = $this->config->getValue("Main", "groups");
-if (!$all_groups = get_all_statusgruppen($range_id)) {
-    die($GLOBALS['EXTERN_ERROR_MESSAGE']);
-} else {
-    $all_groups = array_keys($all_groups);
-}
-
-if (Request::get('visible_groups')) {
-    $group_ids = explode(',', Request::get('visible_groups'));
-} else {
-    $group_ids = $this->config->getValue('Main', 'groupsvisible');
-}
-if (!$group_ids) {
-    die($GLOBALS['EXTERN_ERROR_MESSAGE']);
-} else {
-    $group_ids = array_intersect($all_groups, $group_ids);
-}
-
-if (!is_array($group_ids)) {
-    die($GLOBALS['EXTERN_ERROR_MESSAGE']);
-}
-
-if (!$visible_groups = get_statusgruppen_by_id($range_id, $group_ids)) {
-    die($GLOBALS['EXTERN_ERROR_MESSAGE']);
-}
-
-$aliases_groups = $this->config->getValue('Main', 'groupsalias');
-$order          = $this->config->getValue('Main', 'order');
-$sort           = $this->config->getValue('Main', 'sort');
-
-$query_order = [];
-foreach ($sort as $key => $position) {
-    if ($position > 0) {
-        $query_order[$position] = $this->data_fields[$key];
-    }
-}
-if (count($query_order) > 0) {
-    ksort($query_order, SORT_NUMERIC);
-    $query_order = ' ORDER BY ' . implode(', ', $query_order);
-} else {
-    $query_order = '';
-}
-
-if (!$nameformat = $this->config->getValue('Main', 'nameformat')) {
-    $nameformat = 'full_rev';
-}
-
-$grouping = $this->config->getValue('Main', 'grouping');
-if (!$grouping) {
-    if (Request::get('visible_groups')) {
-        $groups_ids = [Request::get('visible_groups')];
-    } else {
-        $groups_ids = $this->config->getValue('Main', 'groupsvisible');
-    }
-    $ext_vis_query = get_ext_vis_query();
-
-    $range_ids = [$range_id];
-    if (Request::option('aggregation')) {
-        $i = Institute::find($range_id);
-        $children = $i->sub_institutes->pluck('institut_id');
-        $range_ids = array_merge($range_ids, $children);
-    }
-
-    $query = "SELECT DISTINCT ui.raum, ui.sprechzeiten, ui.Telefon, inst_perms,
-                     Email, aum.user_id, username, aum.Nachname,
-                     {$_fullname_sql[$nameformat]} AS fullname ";
-    if ($query_order) {
-        $query .= "FROM statusgruppe_user
-                   LEFT JOIN auth_user_md5 AS aum USING(user_id)
-                   LEFT JOIN user_info USING (user_id)
-                   LEFT JOIN user_inst AS ui USING (user_id) 
-                   WHERE statusgruppe_id IN (?) AND Institut_id IN (?)
-                     AND {$ext_vis_query}
-                   {$query_order}";
-    } else {
-        $query .= "FROM statusgruppen AS s
-                   LEFT JOIN statusgruppe_user AS su USING (statusgruppe_id)
-                   LEFT JOIN auth_user_md5 AS aum USING (user_id)
-                   LEFT JOIN user_info USING (user_id)
-                   LEFT JOIN user_inst AS ui USING (user_id) 
-                   WHERE su.statusgruppe_id IN (?) AND Institut_id IN (?)
-                     AND {$ext_vis_query}
-                   ORDER BY s.position ASC, su.position ASC";
-    }
-    $statement = DBManager::get()->prepare($query);
-    $statement->execute([
-        $groups_ids ?: '',
-        $range_ids
-    ]);
-    $rows = $statement->fetchAll(PDO::FETCH_ASSOC);
-
-    // Ensure the main loop will only get executed once since we already
-    // have all the neccessary data
-    $visible_groups = [''];
-}
-
-// generic data fields
-$generic_datafields = $this->config->getValue("Main", "genericdatafields"); 
-//  $datafields_obj = new DataFields();
-
-$repeat_headrow = $this->config->getValue('Main', 'repeatheadrow');
-$link_persondetails = $this->getModuleLink('Persondetails',
-                                           $this->config->getValue('LinkIntern', 'config'),
-                                           $this->config->getValue('LinkIntern', 'srilink'));
-$data['data_fields'] = $this->data_fields;
-$defaultadr = $this->config->getValue('Main', 'defaultadr');
-
-$out = '';
-$first_loop = TRUE;
-foreach ($visible_groups as $group_id => $group) {
-    if ($grouping) {
-        if (!$query_order) {
-            $query_order = ' ORDER BY su.position';
-        }
-
-        $ext_vis_query = get_ext_vis_query();
-        $query = "SELECT ui.raum, ui.sprechzeiten, ui.Telefon, inst_perms,
-                         Email, aum.user_id, username, aum.Nachname,
-                         {$_fullname_sql[$nameformat]} AS fullname 
-                  FROM statusgruppe_user AS su
-                  LEFT JOIN auth_user_md5 AS aum USING (user_id)
-                  LEFT JOIN user_info USING (user_id)
-                  LEFT JOIN user_inst AS ui USING (user_id)
-                  WHERE su.statusgruppe_id = ? AND Institut_id = ?
-                    AND {$ext_vis_query}
-                  {$query_order}";
-        $statement = DBManager::get()->prepare($query);
-        $statement->execute([$group_id, $range_id]);
-        $rows = $statement->fetchAll(PDO::FETCH_ASSOC);
-
-        $position = array_search($group_id, $all_groups);
-        if ($aliases_groups[$group_id]) {
-            $group = $aliases_groups[$group_id];
-        }
-    }
-
-    if (count($rows) > 0) {
-
-        if ($grouping && $repeat_headrow == 'beneath') {
-            $out .= $this->elements['TableGroup']->toString(['content' => htmlReady($group)]);
-        }
-
-        if ($repeat_headrow || $first_loop) {
-            $out .= $this->elements['TableHeadrow']->toString();
-        }
-
-        if ($grouping && $repeat_headrow != 'beneath') {
-            $out .= $this->elements['TableGroup']->toString(['content' => htmlReady($group)]);
-        }
-
-        $range_ids = [$range_id];
-        if (Request::option('aggregation')) {
-            $i = Institute::find($range_id);
-            $children = $i->sub_institutes->pluck('institut_id');
-            $range_ids = array_merge($range_ids, $children);
-        }
-
-        foreach ($rows as $row) {
-            if ($defaultadr) {
-                $ext_vis_query = get_ext_vis_query();
-                $query = "SELECT ui.raum, ui.sprechzeiten, ui.Telefon,
-                                 inst_perms, Email, aum.user_id, username,
-                                 {$_fullname_sql[$nameformat]} AS fullname,
-                                 aum.Nachname
-                          FROM auth_user_md5 AS aum
-                          LEFT JOIN user_info USING (user_id)
-                          LEFT JOIN user_inst AS ui USING (user_id)
-                          WHERE aum.user_id = ? AND externdefault = 1
-                            AND {$ext_vis_query}";
-                $statement = DBManager::get()->prepare($query);
-                $statement->execute([$row['user_id']]);
-                $temp = $statement->fetch(PDO::FETCH_ASSOC);
-                
-                if ($temp) {
-                    $row = $temp;
-                } else {
-                    // No default
-                    $query = "SELECT ui.raum, ui.sprechzeiten, ui.Telefon,
-                                     inst_perms,  Email, aum.user_id, username,
-                                     {$_fullname_sql[$nameformat]} AS fullname,
-                                     aum.Nachname
-                              FROM auth_user_md5 AS aum
-                              LEFT JOIN user_info USING (user_id)
-                              LEFT JOIN user_inst AS ui USING (user_id)
-                              WHERE aum.user_id = ? AND Institut_id IN (?)
-                                AND {$ext_vis_query}";
-                    $statement = DBManager::get()->prepare($query);
-                    $statement->execute([$row['user_id'], $range_ids]);
-                    $row = $statement->fetch(PDO::FETCH_ASSOC);
-                }
-            }
-
-            $email = get_visible_email($row['user_id']);
-            $data['content'] = [
-                'Nachname'     => $this->elements['LinkIntern']->toString([
-                                      'content'   => htmlReady($row['fullname']),
-                                      'module'    => 'Persondetails',
-                                      'link_args' => 'username=' . $row['username']
-                                  ]),
-                'Telefon'      => htmlReady($row['Telefon']),
-                'sprechzeiten' => htmlReady($row['sprechzeiten']),
-                'raum'         => htmlReady($row['raum']),
-                'Email'        => $this->elements['Link']->toString([
-                                      'content' => htmlReady($email),
-                                      'link'    => 'mailto:' . htmlReady($email)
-                                  ])
-            ];
-
-            // generic data fields
-            if (is_array($generic_datafields)) {
-                $localEntries = DataFieldEntry::getDataFieldEntries($row['user_id']);
-                foreach ($generic_datafields as $id) {
-                    $data['content'][$id] = is_object($localEntries[$id]) ? $localEntries[$id]->getDisplayValue() : '';
-                }
-            }
-            $out .= $this->elements['TableRow']->toString($data);
-        }
-        $first_loop = FALSE;
-    }
-}
-
-$this->elements['TableHeader']->printout(['content' => $out]);
diff --git a/lib/extern/modules/views/persons_preview.inc.php b/lib/extern/modules/views/persons_preview.inc.php
deleted file mode 100644
index 4ccdc1b6bc9..00000000000
--- a/lib/extern/modules/views/persons_preview.inc.php
+++ /dev/null
@@ -1,202 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* persons_preview.inc.php
-* 
-* 
-* 
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       persons_preview
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// persons_preview.inc.php
-// 
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-$data_name = _("Name Name");
-$data_room = _("Raum 21");
-$data_office_hours = _("jeden Tag, 13.00 - 14.00");
-$group_data[] = ["group_name" => _("Gruppe A"), "persons" => [
-["name" => $data_name, "raum" => $data_room, "sprechzeiten" => $data_office_hours,
-        "telefon" => "38-374982", "email" => "name.name@email.com"],
-["name" => $data_name, "raum" => $data_room, "sprechzeiten" => $data_office_hours,
-        "telefon" => "38-895638", "email" => "name.name@email.com"],
-["name" => $data_name, "raum" => $data_room, "sprechzeiten" => $data_office_hours,
-        "telefon" => "38-374982", "email" => "name.name@email.com"]]];
-$group_data[] =  ["group_name" => _("Gruppe B"), "persons" => [
-["name" => $data_name, "raum" => $data_room, "sprechzeiten" => $data_office_hours,
-        "telefon" => "38-374982", "email" => "name.name@email.com"],
-["name" => $data_name, "raum" => $data_room, "sprechzeiten" => $data_office_hours,
-        "telefon" => "38-374982", "email" => "name.name@email.com"],
-["name" => $data_name, "raum" => $data_room, "sprechzeiten" => $data_office_hours,
-        "telefon" => "38-374982", "email" => "name.name@email.com"]]];
-$group_data[] =  ["group_name" => "Gruppe C", "persons" => [
-["name" => $data_name, "raum" => $data_room, "sprechzeiten" => $data_office_hours,
-        "telefon" => "38-374982", "email" => "name.name@email.com"],
-["name" => $data_name, "raum" => $data_room, "sprechzeiten" => $data_office_hours,
-        "telefon" => "38-374982", "email" => "name.name@email.com"]]];
-
-$repeat_headrow = $this->config->getValue("Main", "repeatheadrow");
-$order = $this->config->getValue("Main", "order");
-$width = $this->config->getValue("Main", "width");
-$alias = $this->config->getValue("Main", "aliases");
-$visible = $this->config->getValue("Main", "visible");
-if ($this->config->getValue("TableHeader", "width_pp") == "PERCENT")
-    $percent = "%";
-else
-    $percent = "";
-$group_colspan = array_count_values($visible);
-$grouping = $this->config->getValue("Main", "grouping");
-
-$set_1 = $this->config->getAttributes("TableHeadrow", "th");
-$set_2 = $this->config->getAttributes("TableHeadrow", "th", TRUE);
-$zebra = $this->config->getValue("TableHeadrow", "th_zebrath_");
-
-$set_td_1 = $this->config->getAttributes("TableRow", "td");
-$set_td_2 = $this->config->getAttributes("TableRow", "td", TRUE);
-$zebra_td = $this->config->getValue("TableRow", "td_zebratd_");
-
-echo "<table" . $this->config->getAttributes("TableHeader", "table") . ">\n";
-
-$first_loop = TRUE;
-foreach ($group_data as $groups) {
-    $statusgruppe = $groups["group_name"];
-    
-    if ($grouping && $repeat_headrow == "beneath") {
-    echo "<tr" . $this->config->getAttributes("TableGroup", "tr") . ">";
-        echo "<td colspan=\"{$group_colspan['1']}\"" . $this->config->getAttributes("TableGroup", "td") . ">\n";
-    echo "<font" . $this->config->getAttributes("TableGroup", "font") . ">";
-        echo $statusgruppe . "</font>\n</td></tr>\n";
-    }
-    
-    if ($first_loop || ($grouping && $repeat_headrow)) {
-        echo "<tr" . $this->config->getAttributes("TableHeadrow", "tr") . ">\n";
-        $i = 0;
-        reset($order);
-        foreach ($order as $column) {
-        
-            // "zebra-effect" in head-row
-            if ($zebra) {
-                if ($i % 2)
-                    $set = $set_2;
-                else
-                    $set = $set_1;
-            }
-            else
-                $set = $set_1;
-            
-            if ($visible[$column]) {
-            echo "<th$set width=\"" . $width[$column] . $percent . "\">\n";
-                echo "<font" . $this->config->getAttributes("TableHeadrow", "font") . ">";
-                if ($alias[$column])
-                    echo $alias[$column];
-                else
-                    echo "&nbsp;";
-                echo "</font>\n</th>\n";
-            }
-            $i++;
-        }
-        echo "</tr>\n";
-    }
-    
-    if ($grouping && $repeat_headrow != "beneath") {
-    echo "<tr" . $this->config->getAttributes("TableGroup", "tr") . ">";
-        echo "<td colspan=\"{$group_colspan['1']}\"" . $this->config->getAttributes("TableGroup", "td") . ">\n";
-    echo "<font" . $this->config->getAttributes("TableGroup", "font") . ">";
-        echo $statusgruppe . "</font>\n</td></tr>\n";
-    }
-    $first_loop = FALSE;
-    
-    $i = 0;
-    foreach ($groups["persons"] as $data) {
-    
-        $wert_daten = [
-            "Nachname"         => sprintf("<a href=\"\"%s><font%s>%s</font></a>",
-                                                $this->config->getAttributes("LinkIntern", "a"),
-                                                $this->config->getAttributes("LinkIntern", "font"),
-                                                htmlReady($data["name"])),
-                                                
-            "Telefon"      => sprintf("<font%s>%s</font>",
-                                                $this->config->getAttributes("TableRow", "font"),
-                                                htmlReady($data["telefon"])),
-            
-            "sprechzeiten" => sprintf("<font%s>%s</font>",
-                                                $this->config->getAttributes("TableRow", "font"),
-                                                htmlReady($data["sprechzeiten"])),
-            
-            "raum"         => sprintf("<font%s>%s</font>",
-                                                $this->config->getAttributes("TableRow", "font"),
-                                                htmlReady($data["raum"])),
-            
-            "Email"       => sprintf("<a href=\"mailto:%s\"%s><font%s>%s</font></a>",
-                                                $data["email"],
-                                                $this->config->getAttributes("Link", "a"),
-                                                $this->config->getAttributes("Link", "font"),
-                                                $data["email"])
-        ];
-        
-        // "horizontal zebra"
-        if ($zebra_td == "HORIZONTAL") {
-            if ($i % 2)
-                $set_td = $set_td_2;
-            else
-                $set_td = $set_td_1;
-        }
-        else
-            $set_td = $set_td_1;
-        
-        echo "<tr" . $this->config->getAttributes("TableRow", "tr") . ">";
-        
-        $j = 0;
-        foreach ($order as $column) {
-            if ($visible[$column]) {
-                
-                // "vertical zebra"
-                if ($zebra_td == "VERTICAL") {
-                    if ($j % 2)
-                        $set_td = $set_td_2;
-                    else
-                        $set_td = $set_td_1;
-                }
-            
-                echo "<td$set_td>";
-                if ($wert_daten[$this->data_fields[$column]])
-                echo $wert_daten[$this->data_fields[$column]];
-                else
-                    echo "&nbsp";
-                echo "</td>\n";
-                $j++;
-            }
-        }
-        echo "</tr>\n";
-        $i++;
-    }
-}
-    
-echo "</table>\n";
-
-?>
diff --git a/lib/extern/sri.inc.php b/lib/extern/sri.inc.php
deleted file mode 100644
index cfdf38a4c62..00000000000
--- a/lib/extern/sri.inc.php
+++ /dev/null
@@ -1,198 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* sri.inc.php
-*
-* The Stud.IP-remote-include interface to extern modules.
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       extern
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// sri.inc.php
-// Stud.IP-remote-include interface to extern modules.
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-if (!Config::get()->EXTERN_SRI_ENABLE) {
-    echo $EXTERN_ERROR_MESSAGE;
-    exit;
-}
-
-if (!ini_get('allow_url_fopen')){
-    @ini_set('allow_url_fopen','1');
-}
-// this script is included in extern.inc.php
-
-$all_semester = Semester::findAllVisible(false);
-
-if ($sri_file = @file($page_url))
-    $sri_page = implode("", $sri_file);
-else {
-    echo $EXTERN_ERROR_MESSAGE;
-    exit;
-}
-
-$sri_pattern = "'(.*)(\<studip_remote_include\>.*\<\/studip_remote_include\>)(.*)'is";
-
-if (!preg_match($sri_pattern, $sri_page, $sri_matches)) {
-    echo $EXTERN_ERROR_MESSAGE;
-    exit;
-}
-
-$parser = xml_parser_create();
-xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
-xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
-xml_parse_into_struct($parser, $sri_matches[2], $xml_values, $xml_tags);
-
-$allowed_xml_tags = ["module", "range", "config", "sem", "global"];
-
-foreach ($allowed_xml_tags as $xml_tag) {
-    if ($xml_tags[$xml_tag]) {
-        $attributes = $xml_values[$xml_tags[$xml_tag][0]]["attributes"];
-        foreach ($attributes as $attribute => $value) {
-            $parameter_name = $xml_tag . "_" . $attribute;
-            $$parameter_name = $value;
-        }
-    }
-}
-
-// check given data
-// no range_id? sorry...
-if (!$range_id) {
-    echo $EXTERN_ERROR_MESSAGE;
-    exit;
-}
-
-// Is it a valid module name?
-reset($EXTERN_MODULE_TYPES);
-foreach ($EXTERN_MODULE_TYPES as $module_type => $module_data) {
-    if ($module_data["module"] == $module_name) {
-        $type = $module_type;
-        break;
-    }
-}
-// Wrong module name!
-if (!$type) {
-    echo $EXTERN_ERROR_MESSAGE;
-    exit;
-}
-
-// if there is no config_id or config_name, take the DEFAULT configuration
-if ($config_name) {
-    // check for valid configuration name and convert it into a config_id
-    if (!$config_id = ExternConfig::GetConfigurationByName($range_id, $type, $config_name)) {
-        echo $EXTERN_ERROR_MESSAGE;
-        exit;
-    }
-}
-elseif (!$config_id) {
-    // check for standard configuration
-    if ($id = ExternConfig::GetStandardConfiguration($range_id, $type)) {
-        $config_id = $id;
-    } else {
-        if (Config::get()->EXTERN_ALLOW_ACCESS_WITHOUT_CONFIG) {
-            // use default configuraion
-            $default = 'DEFAULT';
-            $config_id = '';
-        } else {
-            echo $EXTERN_ERROR_MESSAGE;
-            exit;
-        }
-    }
-}
-
-// if there is no global_id or global_name, take the DEFAULT global configuration
-if ($global_name) {
-    // check for valid configuration name and convert it into a config_id
-    if (!$global_id = ExternConfig::GetConfigurationByName($range_id, $type, $config_name)) {
-        echo $EXTERN_ERROR_MESSAGE;
-        exit;
-    }
-}
-elseif (!$global_id) {
-    // check for standard configuration
-    if ($id = ExternConfig::GetGlobalConfiguration($range_id))
-        $global_id = $id;
-    else {
-        // use no global configuration
-        $global_id = NULL;
-    }
-}
-
-// sem == -1: show data from last semester
-// sem == +1: show data from next semester
-// other values: show data from current semester
-$now = time();
-foreach ($all_semester as $key => $sem_record) {
-    if ($now >= $sem_record["beginn"] && $now <= $sem_record["ende"]) {
-        $current = $key;
-        break;
-    }
-}
-if ($sem_offset == "-1") {
-    $start = $all_semester[$current - 1]["beginn"];
-    $end = $all_semester[$current - 1]["ende"];
-} elseif ($sem_offset == "+1") {
-    $start = $all_semester[$current + 1]["beginn"];
-    $end = $all_semester[$current + 1]["ende"];
-} else {
-    $start = $all_semester[$current]["beginn"];
-    $end = $all_semester[$current]["ende"];
-}
-
-// all parameters ok, instantiate module and print data
-foreach ($EXTERN_MODULE_TYPES as $type) {
-    if ($type["module"] == $module_name) {
-        $class_name = "ExternModule" . $module_name;
-        require_once "lib/extern/modules/$class_name.class.php";
-        $module_obj = ExternModule::GetInstance($range_id, $module_name, $config_id, $default, $global_id);
-    }
-}
-// drop URL parameters from page_url
-$page_url = preg_replace('/\?.*/', '', Request::get('page_url'));
-
-$sri_url = $module_obj->config->getValue('Main', 'sriurl');
-
-if (isset($sri_url)) {
-    // drop URL parameters from sri_url
-    $sri_url = preg_replace('/\?.*/', '', $sri_url);
-}
-
-if ($page_url != $sri_url || !sri_is_enabled($module_obj->config->range_id)) {
-
-    echo $EXTERN_ERROR_MESSAGE;
-    exit;
-}
-
-$args = $module_obj->getArgs();
-foreach ($args as $arg) {
-    $arguments[$arg] = Request::quoted($arg);
-}
-
-echo $sri_matches[1];
-$module_obj->printout($arguments);
-echo $sri_matches[3];
diff --git a/lib/extern/views/ExternEditGeneric.class.php b/lib/extern/views/ExternEditGeneric.class.php
deleted file mode 100644
index 111a847adb9..00000000000
--- a/lib/extern/views/ExternEditGeneric.class.php
+++ /dev/null
@@ -1,309 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternEditGeneric.class.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternEditGeneric
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternEditGeneric.class.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-class ExternEditGeneric extends ExternEdit {
-
-    function __construct (&$config, $form_values = "", $faulty_values = "",
-             $edit_element = "") {
-        parent::__construct($config, $form_values, $faulty_values, $edit_element);
-    }
-
-    /**
-    * Prints out a form with a pull-down field for different font-faces.
-    *
-    * @param string attribute The name of the attribute (Syntax: [tag-name]_[attribute_name])
-    * @param string title The title of this form.
-    * @param string info The info text.
-    */
-    function editFaceGeneric ($attribute, $title, $info) {
-        $faces = [
-            "" => _("keine Auswahl"),
-            "Arial,Helvetica,sans-serif" => _("serifenlose Schrift"),
-          "Times,Times New Roman,serif" => _("Serifenschrift"),
-            "Courier,Courier New,monospace" => _("diktengleiche Schrift")
-        ];
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass>$title\n";
-        $out .= tooltipIcon($info);
-        $out .= "<select name=\"$form_name\" size=\"1\">\n";
-        foreach ($faces as $face_type => $face_name) {
-            if ($value == $face_type)
-                $out .= "<option selected=\"selected\" ";
-            else
-                $out .= "<option ";
-            $out .= "value=\"$face_type\">";
-            $out .= $face_name . "</option>";
-        }
-        $out .= "</select>";
-        $out .= "</label>";
-
-        return $out;
-    }
-
-    /**
-    * Prints out a form with a text field.
-    *
-    * @param string attribute The name of the attribute (Syntax: [tag-name]_[attribute_name])
-    * @param mixed title The title(s) of the textfield(s).
-    * @param string info The info text.
-    * @param int size The size (length) of this textfield.
-    * @param int maxlength The maximal length of the text.
-    */
-    function editTextfieldGeneric ($attribute, $title, $info, $size, $maxlength) {
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        if (is_array($title)) {
-            $out = "";
-            for($i = 0; $i < count($title); $i++) {
-
-                $invalidClass = $this->faulty_values[$form_name][$i] ? "class=\"invalid\" " : "";
-
-                $out .= "<label $invalidClass>{$title[$i]}\n";
-                $out .= tooltipIcon(is_array($info) ? $info[$i] : $info);
-                $out .= "<input type=\"text\" name=\"{$form_name}[]\" size=\"$size\"";
-                $out .= " maxlength=\"$maxlength\" value=\"{$value[$i]}\">";
-                $out .= "</label>";
-            }
-            return $out;
-        }
-
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass>$title\n";
-        $out .= tooltipIcon($info);
-        $out .= "<input type=\"text\" name=\"$form_name\" size=\"$size\"";
-        $out .= " maxlength=\"$maxlength\" value=\"$value\">";
-        $out .= "</label>";
-
-        return $out;
-    }
-
-    /**
-    * Prints out a Form with a textarea.
-    *
-    * @param string attribute The name of the attribute (Syntax: [tag-name]_[attribute_name])
-    * @param string title The title of this textarea.
-    * @param string info The info text.
-    * @param int rows The number of rows of this textarea.
-    * @param int cols The number of columns of this textarea.
-    */
-    function editTextareaGeneric ($attribute, $title, $info, $rows, $cols) {
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass>$title";
-        $out .= tooltipIcon($info);
-        $out .= "<textarea name=\"$form_name\" cols=\"$cols\" rows=\"$rows\" wrap=\"virtual\">";
-        $out .= $value;
-        $out .= "</textarea>";
-        $out .= "</label>";
-
-        return $out;
-    }
-
-    /**
-    * Prints out a Form with checkboxes.
-    *
-    * @param string attribute The name of the attribute (Syntax: [tag-name]_[attribute_name])
-    * @param string title The title of this form with checkboxes.
-    * @param string info The info text.
-    * @param array check_values The values of the checkboxes.
-    * @param array check_names The names of the checkboxes.
-    */
-    function editCheckboxGeneric ($attribute, $title, $info, $check_values, $check_names) {
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $size = 0;
-        if(is_array($check_values)) {
-            $size = count($check_values);
-        }
-        $out = "";
-
-        if ($size > 1) {
-        //  $form_name .= "[]";
-            if (is_array($title)) {
-                for ($i = 0; $i < $size; $i++) {
-
-                    $invalidClass = $this->faulty_values[$form_name][$i] ? "class=\"invalid\" " : "";
-
-                    $out .= "<label $invalidClass>";
-                    $out .= "<input type=\"checkbox\" name=\"{$form_name}[]\" value=\"{$check_values[$i]}\"";
-                    if (is_array($value) && in_array($check_values[$i], $value)) {
-                        $out .= " checked";
-                    }
-
-                    if ($size == 1) {
-                        $out .= ">";
-                    } else {
-                        $out .= ">{$check_names[$i]}";
-                    }
-
-                    $out .= $title[$i];
-                    $out .= tooltipIcon($info);
-                    $out .= "</label>";
-                }
-            }
-            else {
-                $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-                $out .= "<label $invalidClass>";
-                for ($i = 0; $i < $size; $i++) {
-                    $out .= "<input type=\"checkbox\" name=\"{$form_name}[]\" value=\"{$check_values[$i]}\"";
-                    if (is_array($value) && in_array($check_values[$i], $value)) {
-                        $out .= " checked";
-                    }
-
-                    if ($size == 1) {
-                        $out .= ">";
-                    } else {
-                        $out .= ">{$check_names[$i]}";
-                    }
-                }
-
-                $out .= $title;
-                $out .= tooltipIcon($info);
-                $out .= "</label>";
-            }
-        }
-        else {
-            $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-            $out .= "<label $invalidClass>";
-            $out .= "<input type=\"checkbox\" name=\"{$form_name}\" value=\"$check_values\"";
-
-            if ($value == $check_values) {
-                $out .= " checked";
-            }
-
-            $out .= ">";
-
-            $out .= $title;
-            $out .= tooltipIcon($info);
-            $out .= "</label>";
-        }
-
-        return $out;
-    }
-
-    /**
-    * Prints out a Form with radio-buttons.
-    *
-    * @param string attribute The name of the attribute (Syntax: [tag-name]_[attribute_name])
-    * @param string title The title of this form with radio-buttons.
-    * @param string info The info text.
-    * @param array radio_values The values of the radio-buttons.
-    * @param array radio_names The names of the radio-buttons.
-    */
-    function editRadioGeneric ($attribute, $title, $info, $radio_values, $radio_names) {
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass>$title\n";
-        $out .= tooltipIcon($info);
-
-        $out .= "<br>";
-        for ($i = 0; $i < count($radio_values); $i++) {
-            $out .= "<input type=\"radio\" name=\"$form_name\" value=\"{$radio_values[$i]}\"";
-            if ($value == $radio_values[$i])
-                $out .= " checked";
-            $out .= ">{$radio_names[$i]}";
-        }
-        $out .= "</label>";
-
-        return $out;
-    }
-
-    /**
-    * Prints out a Form with an option-list.
-    *
-    * @param string attribute The name of the attribute (Syntax: [tag-name]_[attribute_name])
-    * @param string title The title of this option-list.
-    * @param string info The info text.
-    * @param array radio_values The values of the options.
-    * @param array radio_names The names of the options.
-    * @param int length The visible size of the option-list (default 1, pull-down).
-    * @param boolean multiple Set this TRUE, if you want a multiple option-list (default FALSE)
-    */
-    function editOptionGeneric ($attribute, $title, $info, $option_values, $option_names,
-            $size = 1, $multiple = FALSE) {
-
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass>$title\n";
-        $out .= tooltipIcon($info);
-        if ($multiple)
-            $out .= "<select name=\"{$form_name}[]\" size=\"$size\" multiple>";
-        else
-            $out .= "<select name=\"$form_name\" size=\"$size\">";
-
-        for ($i = 0; $i < count($option_values); $i++) {
-            $out .= "<option value=\"{$option_values[$i]}\"";
-            if ($multiple) {
-                if (in_array($option_values[$i], (array) $value)) {
-                    $out .= " selected";
-                }
-            } else {
-                if ($value == $option_values[$i]) {
-                    $out .= " selected";
-                }
-            }
-            $out .= ">{$option_names[$i]}</option>\n";
-        }
-
-        $out .= "</select>";
-        $out .= "</label>";
-
-        return $out;
-    }
-
-}
diff --git a/lib/extern/views/ExternEditHtml.class.php b/lib/extern/views/ExternEditHtml.class.php
deleted file mode 100644
index 80b74a78d63..00000000000
--- a/lib/extern/views/ExternEditHtml.class.php
+++ /dev/null
@@ -1,623 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternEditHtml.class.php
-*
-* Form templates to edit values of html-tag attributes.
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternEditHtml
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternEditHtml.class.php
-// Form templates to edit values of html-tag attributes.
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once "lib/extern/views/ExternEditGeneric.class.php";
-
-
-class ExternEditHtml extends ExternEditGeneric {
-
-    function __construct (&$config, $form_values = "", $faulty_values = "",
-             $edit_element = "") {
-        parent::__construct($config, $form_values, $faulty_values, $edit_element);
-    }
-
-    /**
-    * Prints out a form for entering the height of a html-element (e.g. &lt;tr&gt;, &lt;th&gt;)
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editHeight ($attribute) {
-        $info = _("Geben Sie die Höhe der Tabellenzeile in Pixeln an.");
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass for=\"$form_name\">";
-        $out .= _("Zeilenhöhe:");
-        $out .= tooltipIcon($info);
-        $out .= "</label>";
-
-        $out .= "<section class=\"hgroup\">";
-        $out .= "<label>";
-        $out .= "<input type=\"text\" name=\"$form_name\" size=\"3\"";
-        $out .= " maxlength=\"3\" class=\"no-hint \" value=\"$value\">&nbsp;Pixel";
-        $out .= "</label>";
-        $out .= "</section>";
-
-        return $out;
-    }
-
-    /**
-    * Prints out a form for entering the border-width of a table.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editBorder ($attribute) {
-        $info = _("Geben Sie die Breite des äußeren Tabellenrahmens in Pixeln an.");
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass for=\"$form_name\">";
-        $out .= _("Rahmendicke:");
-        $out .= tooltipIcon($info);
-
-        $out .= "<section class=\"hgroup\">";
-        $out .= "<input type=\"text\" name=\"$form_name\" size=\"2\"";
-        $out .= " maxlength=\"2\" class=\"no-hint size-s \" value=\"$value\">&nbsp;Pixel";
-        $out .= "</section>";
-        $out .= "</label>";
-
-        return $out;
-    }
-
-    /**
-    * Prints out a form for entering the font-color.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editColor ($attribute) {
-        $info = _("Geben Sie einen HTML-Farbnamen oder eine Farbe im Hex-Format (#RRGGBB) in das Textfeld ein, oder wählen Sie eine Farbe aus der Auswahlliste.");
-        $titel = _("Schriftfarbe");
-
-        return $this->editColorGeneric($attribute, $titel, $info);
-    }
-
-    /**
-    * Prints out a form for entering the backgroung-color of a table- or td-tag
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editBgcolor ($attribute) {
-        $info = _("Geben Sie einen HTML-Farbnamen oder eine Farbe im Hex-Format (#RRGGBB) in das Textfeld ein, oder wählen Sie eine Farbe aus der Auswahlliste.");
-        $title = _("Hintergrundfarbe:");
-
-        return $this->editColorGeneric($attribute, $title, $info);
-    }
-
-    /**
-    * Prints out a form for entering the bordercolor of a table.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editBordercolor ($attribute) {
-        $info = _("Geben Sie einen HTML-Farbnamen oder eine Farbe im Hex-Format (#RRGGBB) in das Textfeld ein, oder wählen Sie eine Farbe aus der Auswahlliste.");
-        $title = _("Rahmenfarbe");
-
-        return $this->editColorGeneric($attribute, $title, $info);
-    }
-
-    /**
-    * Prints out a form for entering the second backgroung-color of a td- or th-tag (only for
-    * zebra-effect.
-    *
-    * @param string name The name of the text field.
-    * @param string value The value for the text pre-emption.
-    */
-
-    function editBgcolor2 ($attribute) {
-        $info = _("Geben Sie einen HTML-Farbnamen oder eine Farbe im Hex-Format (#RRGGBB) in das Textfeld ein, oder wählen Sie eine Farbe aus der Auswahlliste. ");
-        $info .= _("Diese Farbe wird als zweite Farbe bei aktiviertem Zebra-Effekt ausgegeben.");
-        $title = _("2. Hintergrundf.:");
-
-        return $this->editColorGeneric($attribute, $title, $info);
-    }
-
-    /**
-    * Prints out a form for entering the link color in the body tag
-    *
-    * @param string name The name of the text field.
-    * @param string value The value for the text pre-emption.
-    */
-
-    function editText ($attribute) {
-        $info = _("Geben Sie einen HTML-Farbnamen oder eine Farbe im Hex-Format (#RRGGBB) in das Textfeld ein, oder wählen Sie eine Farbe aus der Auswahlliste. ");
-        $info .= _("Diese Farbe wird seitenweit als Schriftfarbe benutzt.");
-        $title = _("Schriftfarbe:");
-
-        return $this->editColorGeneric($attribute, $title, $info);
-    }
-
-    /**
-    * Prints out a form for entering the link color in the body tag
-    *
-    * @param string name The name of the text field.
-    * @param string value The value for the text pre-emption.
-    */
-
-    function editLink ($attribute) {
-        $info = _("Geben Sie einen HTML-Farbnamen oder eine Farbe im Hex-Format (#RRGGBB) in das Textfeld ein, oder wählen Sie eine Farbe aus der Auswahlliste. ");
-        $info .= _("Diese Farbe wird seitenweit für Verweise zu noch nicht besuchten Zielen benutzt.");
-        $title = _("Linkfarbe (nicht besucht):");
-
-        return $this->editColorGeneric($attribute, $title, $info);
-    }
-
-    /**
-    * Prints out a form for entering the link color in the body tag
-    *
-    * @param string name The name of the text field.
-    * @param string value The value for the text pre-emption.
-    */
-
-    function editVlink ($attribute) {
-        $info = _("Geben Sie einen HTML-Farbnamen oder eine Farbe im Hex-Format (#RRGGBB) in das Textfeld ein, oder wählen Sie eine Farbe aus der Auswahlliste. ");
-        $info .= _("Diese Farbe wird seitenweit für Verweise zu bereits besuchten Zielen benutzt.");
-        $title = _("Linkfarbe (besucht):");
-
-        return $this->editColorGeneric($attribute, $title, $info);
-    }
-
-    /**
-    * Prints out a form for entering the link color in the body tag
-    *
-    * @param string name The name of the text field.
-    * @param string value The value for the text pre-emption.
-    */
-
-    function editAlink ($attribute) {
-        $info = _("Geben Sie einen HTML-Farbnamen oder eine Farbe im Hex-Format (#RRGGBB) in das Textfeld ein, oder wählen Sie eine Farbe aus der Auswahlliste. ");
-        $info .= _("Diese Farbe wird seitenweit für aktivierte Verweise benutzt.");
-        $title = _("Linkfarbe (aktiviert):");
-
-        return $this->editColorGeneric($attribute, $title, $info);
-    }
-
-    /**
-    * Prints out a text field and a selection list for entering the color of
-    * a table border.
-    *
-    * The name of the text field is given by $name. The name of the selection list
-    * is $name . "_list".
-    *
-    * @param string title the
-    * @param string name the name of the text field and selection list
-    * @param string value
-    */
-
-    function editColorGeneric ($attribute, $title, $info) {
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $colors = [_("keine Auswahl") => "", "aliceblue" => "#F0F8FF", "antiquewhite" => "#FAEBD7",
-                  "aquamarine" => "#7FFFD4", "azure" => "#F0FFFF", "beige" => "#F5F5DC",
-                            "blueviolet" => "#8A2BE2", "brown" => "#A52A2A", "burlywood" => "#DEB887",
-                            "cadetblue" => "#5F9EA0", "chartreuse" => "#7FFF00",
-                            "chocolate" => "#D2691E", "coral" => "#FF7F50",
-                            "cornflowerblue" => "#6495ED", "cornsilk" => "#FFF8DC",
-                            "crimson" => "#DC143C", "darkblue" => "#00008B", "darkcyan" => "#008B8B",
-                            "darkgoldenrod" => "#B8860B", "darkgray" => "#A9A9A9",
-                            "darkgreen" => "#006400", "darkkhaki" => "#BDB76B",
-                            "darkmagenta" => "#8B008B", "darkolivegreen" => "#556B2F",
-                            "darkorange" => "#FF8C00", "darkorchid" => "#9932CC",
-                            "darkred" => "#8B0000", "darksalmon" => "#E9967A",
-                            "darkseagreen" => "#8FBC8F", "darkslateblue" => "#483D8B",
-                            "darkslategray" => "#2F4F4F", "darkturquoise" => "#00CED1",
-                            "darkviolet" => "#9400D3", "deeppink" => "#FF1493",
-                            "deepskyblue" => "#00BFFF", "dimgray" => "#696969",
-                            "dodgerblue" => "#1E90FF", "firebrick" => "#B22222",
-                            "floralwhite" => "#FFFAF0", "forestgreen" => "#228B22",
-                            "gainsboro" => "#DCDCDC", "ghostwhite" => "#F8F8FF", "gold" => "#FFD700",
-                            "goldenrod" => "#DAA520", "greenyellow" => "#ADFF2F",
-                            "honeydew" => "#F0FFF0", "hotpink" => "#FF69B4", "indianred" => "#CD5C5C",
-                            "indigo" => "#4B0082", "ivory" => "#FFFFF0", "khaki" => "#F0E68C",
-                            "lavender" => "#E6E6FA", "lavenderblush" => "#FFF0F5",
-                            "lawngreen" => "#7CFC00", "lemonchiffon" => "#FFFACD",
-                            "lightblue" => "#ADD8E6", "lightcoral" => "#F08080",
-                            "lightcyan" => "#E0FFFF", "lightgoldenrodyellow" => "#FAFAD2",
-                            "lightgreen" => "#90EE90", "lightgrey" => "#D3D3D3",
-                            "lightpink" => "#FFB6C1", "lightsalmon" => "#FFA07A",
-                            "lightseagreen" => "#20B2AA", "lightskyblue" => "#87CEFA",
-                            "lightslategray" => "#778899", "lightsteelblue" => "#B0C4DE",
-                            "lightyellow" => "#FFFFE0", "limegreen" => "#32CD32",
-                            "linen" => "#FAF0E6", "mediumaquamarine" => "#66CDAA",
-                            "mediumblue" => "#0000CD", "mediumorchid" => "#BA55D3",
-                            "mediumpurple" => "#9370DB", "mediumseagreen" => "#3CB371",
-                            "mediumslateblue" => "#7B68EE", "mediumspringgreen" => "#00FA9A",
-                            "mediumturquoise" => "#48D1CC", "mediumvioletred" => "#C71585",
-                            "midnightblue" => "#191970", "mintcream" => "#F5FFFA",
-                            "mistyrose" => "#FFE4E1", "moccasin" => "#FFE4B5",
-                            "navajowhite" => "#FFDEAD", "oldlace" => "#FDF5E6",
-                            "olivedrab" => "#6B8E23", "orange" => "#FFA500", "orangered" => "#FF4500",
-                            "orchid" => "#DA70D6", "palegoldenrod" => "#EEE8AA", "palegreen" => "#98FB98",
-                            "paleturquoise" => "#AFEEEE", "palevioletred" => "#DB7093", "papayawhip" => "#FFEFD5",
-                            "peachpuff" => "#FFDAB9", "peru" => "#CD853F", "pink" => "#FFC0CB",
-                            "plum" => "#DDA0DD", "powderblue" => "#B0E0E6", "rosybrown" => "#BC8F8F",
-                            "royalblue" => "#4169E1", "saddlebrown" => "#8B4513", "salmon" => "#FA8072",
-                            "sandybrown" => "#F4A460", "seagreen" => "#2E8B57", "seashell" => "#FFF5EE",
-                            "sienna" => "#A0522D", "skyblue" => "#87CEEB", "slateblue" => "#6A5ACD",
-                            "slategray" => "#708090", "snow" => "#FFFAFA", "springgreen" => "#00FF7F",
-                            "steelblue" => "#4682B4", "tan" => "#D2B48C", "thistle" => "#D8BFD8",
-                            "tomato" => "#FF6347", "turquoise" => "#40E0D0", "violet" => "#EE82EE",
-                            "wheat" => "#F5DEB3", "whitesmoke" => "#F5F5F5", "yellowgreen" => "#9ACD32"];
-
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass for=\"_${form_name}\">$title";
-        $out .= tooltipIcon($info);
-        $out .= "<section class=\"hgroup\">";
-        $out .= "<input type=\"text\" name=\"$form_name\" class=\"no-hint\" ";
-        $out .= " maxlength=\"20\" value=\"$value\">\n";
-
-        $out .= "<select name=\"_{$form_name}\"";
-        $out .= "onChange=\"document.edit_form.{$form_name}.value=document.edit_form._{$form_name}.";
-        $out .= "options[document.edit_form._{$form_name}.selectedIndex].value;\" ";
-        $out .= " class=\"nested-select\">\n";
-        foreach ($colors as $color_name => $color_value) {
-            if ($value == $color_value) {
-                $out .= "<option selected=\"selected\" ";
-            } else {
-                $out .= "<option ";
-            }
-            if (!$color_value) {
-                $out .= ' class="is-placeholder" ';
-            }
-            $out .= "data-text-color=\"$color_value\" value=\"$color_value\">";
-            $out .= $color_name . "</option>";
-        }
-        $out .= "</select>";
-
-        $out .= "</section>";
-        $out .= "</label>";
-
-        return $out;
-    }
-
-    /**
-    * Prints out a form for entering the cellpadding of a table.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editCellpadding ($attribute) {
-        $info = _("Geben Sie den Abstand zwischen Zelleninhalt und Zellenrand in Pixeln an.");
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass>";
-        $out .= _("Cellpadding:");
-        $out .= tooltipIcon($info);
-        $out .= "<section class=\"hgroup\">";
-        $out .= "<input type=\"text\" name=\"$form_name\" size=\"2\"";
-        $out .= " maxlength=\"2\" class=\"no-hint size-s \" value=\"$value\">&nbsp;Pixel";
-        $out .= "</section>";
-        $out .= "</label>";
-
-        return $out;
-    }
-
-    /**
-    * Prints out a form for entering the cellspacing of a table.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editCellspacing ($attribute) {
-        $info = _("Geben Sie den Abstand zwischen benachbarten Zellen in Pixeln an.");
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label ".$invalidClass.">";
-        $out .= _("Cellspacing:");
-        $out .= tooltipIcon($info);
-        $out .= "<section class=\"hgroup\">";
-        $out .= "<input type=\"text\" name=\"$form_name\" size=\"2\"";
-        $out .= " maxlength=\"2\" class=\"no-hint size-s\" value=\"$value\">&nbsp;Pixel";
-        $out .= "</section>";
-        $out .= "</label>";
-
-        return $out;
-    }
-
-    /**
-    * Prints out a form for entering the width of a html-element (e.g. &lt;td&gt;, &lt;table&gt;).
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editWidth ($attribute) {
-        $info = _("Geben Sie die Breite des Elements in Prozent oder Pixeln an.");
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-        $value_pp = "";
-
-        if (mb_substr($value, -1) == "%") {
-            $value_pp = "%";
-            $value = mb_substr($value, 0, -1);
-        }
-
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass for=\"$form_name\">";
-        $out .= _("Breite:");
-        $out .= tooltipIcon($info);
-        $out .= "</label>";
-
-        $out .= "<section class=\"hgroup\">";
-        $out .= "<input type=\"text\" name=\"$form_name\" size=\"3\"";
-        $out .= " maxlength=\"3\" class=\"no-hint size-s\" value=\"$value\">&nbsp;\n";
-
-        $out .= "<label $invalidClass>";
-        $out .= "<input type=\"radio\" name=\"{$form_name}pp\" value=\"%\"";
-        if ($value_pp == "%")
-            $out .= " checked=\"checked\"";
-        $out .= ">";
-        $out .= _("Prozent");
-        $out .= "</label><label $invalidClass>";
-        $out .= "<input type=\"radio\" name=\"";
-        $out .= $form_name . "pp\" value=\"\"";
-        if ($value_pp == "")
-            $out .= " checked=\"checked\"";
-        $out .= ">";
-        $out .= _("Pixel");
-        $out .= "</label>";
-        $out .= "</section>";
-
-        return $out;
-    }
-
-    /**
-    * Prints out a form for entering the horizontal alignment of a html-element (e.g. &lt;td&gt;, &lt;table&gt;).
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editAlign ($attribute) {
-        $info = _("Wählen Sie aus der Auswahlliste die Art der horizontalen Ausrichtung.");
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $align_types = [
-            "" => _("keine Auswahl"),
-            "left" => _("linksbündig"),
-            "right" => _("rechtsbündig"),
-          "center" => _("zentriert")
-        ];
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass>";
-        $out .= _("horizontale Ausrichtung:")."\n";
-        $out .= tooltipIcon($info);
-        $out .= "<select name=\"$form_name\" size=\"1\">\n";
-        foreach ($align_types as $align_type => $align_name) {
-            if ($value == $align_type)
-                $out .= "<option selected=\"selected\" ";
-            else
-                $out .= "<option ";
-            $out .= "value=\"$align_type\">";
-            $out .= $align_name . "</option>";
-        }
-        $out .= "</select>";
-        $out .= "</label>";
-
-        return $out;
-    }
-    
-    /**
-    * Prints out a form for entering the vertikal alignment of a html-element (e.g. &lt;td&gt;, &lt;table&gt;).
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editValign ($attribute) {
-        $info = _("Wählen Sie aus der Auswahlliste die Art der vertikalen Ausrichtung.");
-        $form_name = $this->element_name . "_" . $attribute;
-        $value = $this->getValue($attribute);
-
-        $valign_types = [
-            "" => _("keine Auswahl"),
-            "top" => _("obenbündig"),
-            "bottom" => _("untenbündig"),
-          "center" => _("zentriert")
-        ];
-        $invalidClass = $this->faulty_values[$form_name][0] ? "class=\"invalid\" " : "";
-
-        $out = "<label $invalidClass>";
-        $out .= _("vertikale Ausrichtung:")."\n";
-        $out .= "<select name=\"$form_name\" size=\"1\">\n";
-        foreach ($valign_types as $valign_type => $valign_name) {
-            if ($value == $valign_type)
-                $out .= "<option selected=\"selected\" ";
-            else
-                $out .= "<option ";
-            $out .= "value=\"$valign_type\">";
-            $out .= $valign_name . "</option>";
-        }
-        $out .= "</select>";
-        $out .= "</label>";
-
-        return $out;
-    }
-
-    /**
-    * Prints out a form for entering the font-size.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editSize ($attribute) {
-        $info = _("Geben Sie die relative Schriftgröße an.");
-        $title = _("Schriftgröße:");
-        $values = ["", "1", "2", "3", "4", "5", "6", "7"];
-        $names = [_("keine Auswahl"), "1", "2", "3", "4", "5", "6", "7"];
-
-        return $this->editOptionGeneric($attribute, $title, $info, $values, $names, 1, FALSE);
-    }
-
-    /**
-    * Prints out a form for entering the font-face.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editFace ($attribute) {
-        $title = _("Schriftart:");
-        $info = _("Wählen Sie eine Schriftart aus.");
-
-        return $this->editFaceGeneric($attribute, $title, $info);
-    }
-
-    /**
-    * Prints out a form for entering the css-classname of a html-element.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editClass ($attribute) {
-        $info = _("Geben Sie einen CSS-Klassennamen aus Ihrer Stylesheet-Definition an.");
-        $title = _("CSS-Klasse:");
-
-        return $this->editTextfieldGeneric($attribute, $title, $info, 30, 128);
-    }
-
-    /**
-    * Prints out a form for entering css-styles of a html-element
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editStyle ($attribute) {
-        $info = _("Geben Sie Style-Sheet-Angaben ein.");
-        $title = _("Style:");
-
-        return $this->editTextfieldGeneric($attribute, $title, $info, 35, 250);
-    }
-
-    /**
-    * Prints out a form for entering the title of a html-page.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editTitle ($attribute) {
-        $info = _("Geben Sie einen Seitentitel an.");
-        $title = _("Seiten-Titel:");
-
-        return $this->editTextfieldGeneric($attribute, $title, $info, 35, 128);
-    }
-
-    /**
-    * Prints out a form for choosing between a horizontal or vertikal zebra-effect
-    * on table rows/columns.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editZebraTd ($attribute) {
-        $info = _("Aktivieren Sie einen vertikalen oder horizontalen Zebra-Effekt für Tabellenzeilen/-spalten. ");
-        $info .= _("Geben Sie hierfür eine zweite Hintergrundfarbe an.");
-        $title = _("Zebra-Effekt:");
-        $names = [_("aus"), _("horizontal"), _("vertikal")];
-        $values = ["", "HORIZONTAL", "VERTICAL"];
-
-        return $this->editRadioGeneric($attribute, $title, $info, $values, $names);
-    }
-
-    /**
-    * Prints out a form for activating a zebra-effect on th-tags.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editZebraTh ($attribute) {
-        $info = _("Aktivieren Sie einen Zebra-Effekt für die Spaltenüberschriften. ");
-        $info .= _("Geben Sie hierfür eine zweite Hintergrundfarbe an.");
-        $title = _("Zebra-Effekt:");
-        $names = [_("aus"), _("an")];
-        $values = ["", "1"];
-
-        return $this->editRadioGeneric($attribute, $title, $info, $values, $names);
-    }
-
-    /**
-    * Prints out a form for entering the URL of a background picture for the hole document.
-    *
-    * @access   public
-    * @param    string attribute The name of the attribute (syntax: HTML-TAG_HTML-ATTRIBUTE).
-    * @return   string A complete table row includes a closed table with the form.
-    */
-    function editBackground ($attribute) {
-        $info = _("Geben Sie die URL eines Bildes an, das als Hintergrundbild für die gesamte Seite dienen soll.");
-        $title = _("Hintergrundbild:");
-
-        return $this->editTextfieldGeneric($attribute, $title, $info, 35, 150);
-    }
-
-}
-
-?>
diff --git a/lib/extern/views/ExternEditModule.class.php b/lib/extern/views/ExternEditModule.class.php
deleted file mode 100644
index 2a576611f28..00000000000
--- a/lib/extern/views/ExternEditModule.class.php
+++ /dev/null
@@ -1,573 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* ExternEditModule.class.php
-*
-* basic functions for the extern interfaces
-*
-*
-* @author       Peter Thienel <thienel@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       ExternEditModule
-* @package  studip_extern
-*/
-
-use Studip\Button, Studip\LinkButton;
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// ExternEditModule.class.php
-//
-// Copyright (C) 2003 Peter Thienel <thienel@data-quest.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require_once "lib/extern/views/ExternEditHtml.class.php";
-
-class ExternEditModule extends ExternEditHtml {
-
-    function __construct (&$config, $form_values = "", $faulty_values = "",
-             $edit_element = "") {
-        parent::__construct($config, $form_values, $faulty_values, $edit_element);
-    }
-
-    function editMainSettings ($field_names, $hide_fields = "", $hide = "") {
-        // these two values are always necessary, even there is an error in the users inputs, so
-        // there arent transfered via $_POST
-        $this->form_values[$this->element_name . "_order"]
-                = $this->config->getValue($this->element_name, "order");
-        $this->form_values[$this->element_name . "_visible"]
-                = $this->config->getValue($this->element_name, "visible");
-
-        $order = $this->getValue("order");
-        $aliases = $this->getValue("aliases");
-        $visible = $this->getValue("visible");
-        $widths = $this->getValue("width");
-        $sort = $this->getValue("sort");
-        if (!is_array($hide_fields["sort"]))
-            $hide_fields["sort"] = [];
-        if (!is_array($hide_fields["aliases"]))
-            $hide_fields["aliases"] = [];
-        if (!is_array($hide))
-            $hide = [];
-
-        $out = "<table width=\"100%\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\">\n";
-        $out .= "<tr>\n";
-        $out .= "<td><b>" . _("Datenfeld") . "</b></td>\n";
-        if (!in_array('aliases', $hide))
-            $out .= "<td><b>" . _("Ãœberschrift") . "</b></td>\n";
-        if (!in_array("width", $hide))
-            $out .= "<td><b>" . _("Breite") . "</b></td>\n";
-        if (!in_array("sort", $hide))
-            $out .= "<td><b>" . _("Sortierung") . "</b></td>\n";
-        if (!in_array("visible", $hide))
-            $out .= "<td><b>" . _("Reihenfolge/<br>Sichtbarkeit") . "</b></td>\n";
-        $out .= "</tr>\n";
-
-        if (is_array($field_names)) {
-            for ($i = 0; $i < count($field_names); $i++) {
-                // name of column
-                $out .= "<tr valign=\"middle\">\n";
-                $out .= '<td>&nbsp;' . htmlReady($field_names[$order[$i]]) . '</td>';
-
-                // column headline
-                if (!in_array('aliases', $hide)) {
-                    if (!in_array($order[$i], $hide_fields["aliases"])) {
-                        $out .= "<td><input type=\"text\" name=\"{$this->element_name}_aliases[$order[$i]]\"";
-                        $out .= "\" size=\"12\" maxlength=\"50\" value=\"";
-                        $out .= $aliases[$order[$i]] . "\">";
-                        if ($this->faulty_values[$this->element_name . "_aliases"][$order[$i]])
-                            $out .= $this->error_sign;
-                        $out .= "</td>\n";
-                    } else {
-                        $out .= "<td>&nbsp;</td>\n";
-                        $out .= "<input type=\"hidden\" name=\"{$this->element_name}_aliases[$order[$i]]\" ";
-                        $out .= "value=\"\">";
-                    }
-                }
-
-                // width
-                if (!in_array("width", $hide)) {
-                    $width = str_replace("%", "", $widths[$order[$i]]);
-                    $out   .= "<td><input type=\"text\" name=\"{$this->element_name}_width[$order[$i]]";
-                    $out   .= "\" size=\"3\" maxlength=\"3\" value=\"$width\">";
-                    if ($this->faulty_values[$this->element_name . "_width"][$order[$i]])
-                        $out .= $this->error_sign;
-                    $out .= "</td>\n";
-                }
-
-                // sort
-                if (!in_array("sort", $hide)) {
-                    if (!in_array($order[$i], $hide_fields["sort"])) {
-                        $out .= "<td><select name=\"{$this->element_name}_sort[$order[$i]]\" ";
-                        $out .= "size=\"1\">\n";
-                        $out .= "<option value=\"0\"" . ($sort[$order[$i]] == 1 ? " selected" : "")
-                            . ">" . _("keine") . "</option>";
-                        for ($j = 1; $j <= (count($order) - count($hide_fields["sort"])); $j++) {
-                            if ($sort[$order[$i]] == $j)
-                                $selected = " selected";
-                            else
-                                $selected = "";
-                            $out .= "<option value=\"$j\"$selected>$j</option>";
-                        }
-                        $out .= "\n</select>\n</td>\n";
-                    } else {
-                        $out .= "<td>&nbsp;</td>\n";
-                        $out .= "<input type=\"hidden\" name=\"{$this->element_name}_sort[$order[$i]]\" ";
-                        $out .= "value=\"0\">\n";
-                    }
-                }
-
-                if (!in_array("visible", $hide)) {
-                    // move left
-                    $out .= "<td valign=\"middle\" nowrap=\"nowrap\">";
-                    $out .= Icon::create('arr_2up', 'sort', ['title' => _('Datenfeld verschieben')])->asInput(["type" => "image", "class" => "middle", "name" => $this->element_name . "_move_left[" . $i . "]"]);
-
-                    // move right
-                    $out .= "\n";
-                    $out .= Icon::create('arr_2down', 'sort', ['title' => _('Datenfeld verschieben')])->asInput(["type" => "image", "class" => "middle", "name" => $this->element_name . "_move_right[" . $i . "]"]);
-
-                    // visible
-                    if ($visible[$order[$i]]) {
-                        $out .= "\n";
-                        $out .= Icon::create('checkbox-checked', 'clickable', ['title' => _('Datenfeld ausblenden')])->asInput(["type" => "image", "class" => "middle", "name" => $this->element_name . "_hide[" . $order[$i] . "]"]);
-                    } else {
-                        $out .= "\n";
-                        $out .= Icon::create('checkbox-unchecked', 'clickable', ['title' => _('Datenfeld einblenden')])->asInput(["type" => "image", "class" => "middle", "name" => $this->element_name . "_show[" . $order[$i] . "]"]);
-                        $out .= "</td>\n";
-                    }
-                }
-            }
-        }
-
-        // width in pixels or percent
-        if (!in_array("widthpp", $hide) && !in_array('width', $hide)) {
-            $colspan = 4 - count($hide);
-            $title = _("Breite in:");
-            $info = _("Wählen Sie hier, ob die Breiten der Tabellenspalten als Prozentwerte oder Pixel interpretiert werden sollen.");
-            $width_values = ["%", ""];
-            $width_names = [_("Prozent"), _("Pixel")];
-            $out .= "<tr>\n";
-            $out .= "<td>&nbsp;$title</td>";
-            $out .= "<td colspan=\"$colspan\"><input type=\"radio\" name=\"{$this->element_name}_widthpp\" value=\"%\"";
-            if (mb_substr($widths[0], -1) == "%")
-                $out .= " checked=\"checked\"";
-            $out .= ">" . _("Prozent") . "&nbsp; &nbsp;<input type=\"radio\" name=\"";
-            $out .= "{$this->element_name}_widthpp\" value=\"\"";
-            if (mb_substr($widths[0], -1) != "%")
-                $out .= " checked=\"checked\"";
-            $out .= ">" . _("Pixel") . "&nbsp; &nbsp;\n";
-            $out .= tooltipIcon($info);
-            $out .= "</td></tr>\n";
-        }
-
-        $out .= "</table>\n";
-
-        return $out;
-    }
-
-    function editSort ($field_names, $hide_fields = NULL) {
-        if (!is_array($hide_fields)) {
-            $hide_fields = [];
-        }
-        if (!is_array($hide_fields["sort"])) {
-            $hide_fields["sort"] = [];
-        }
-        $sort = $this->getValue("sort");
-
-
-        $out = "<table width=\"100%\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\">\n";
-        $out .= "<tr>\n";
-        $out .= "<td><b>" . _("Datenfeld") . "</b></td>\n";
-        $out .= "<td><b>" . _("Sortierung") . "</b></td>\n";
-
-        if ($field_names) {
-            for ($i = 0; $i < count($field_names); $i++) {
-                $out .= "<tr valign=\"middle\">\n";
-                $out .= "<td>&nbsp;{$field_names[$i]}</td>";
-                if (!in_array($i, $hide_fields["sort"])) {
-                    $out .= "<td><select name=\"{$this->element_name}_sort[$i]\" ";
-                    $out .= "size=\"1\">\n";
-                    $out .= "<option value=\"0\"" . ($sort[$i] == 1 ? " selected" : "")
-                        . ">" . _("keine") . "</option>";
-                    for ($j = 1; $j <= (count($field_names) - count($hide_fields["sort"])); $j++) {
-                        if ($sort[$i] == $j)
-                            $selected = " selected";
-                        else
-                            $selected = "";
-                        $out .= "<option value=\"$j\"$selected>$j</option>";
-                    }
-                    $out .= "\n</select>\n</td>\n";
-                }
-                else {
-                    $out .= "<td>&nbsp;</td>\n";
-                    $out .= "<input type=\"hidden\" name=\"{$this->element_name}_sort[$i]\" ";
-                    $out .= "value=\"0\">\n";
-                }
-            }
-        }
-
-        $out .= "</table>\n";
-
-        return $out;
-    }
-
-    function editName ($attribute) {
-        $info = _("Geben Sie den Namen der Konfiguration an.");
-
-        return $this->editTextfieldGeneric($attribute, "", $info, 40, 40);
-    }
-
-    function editGroups () {
-        $groups_db = get_all_statusgruppen($this->config->range_id);
-
-        if (!$groups_db)
-            return FALSE;
-
-        $title = _("Gruppen auswählen:");
-        $info = _("Wählen Sie die Statusgruppen aus, die ausgegeben werden sollen.");
-        $groups_config = $this->getValue("groups");
-
-        // this value is always necessary, even there is an error in the users inputs, so
-        // it isn't transfered via $_POST
-        $this->form_values[$this->element_name . "_groupsvisible"]
-                = $this->config->getValue($this->element_name, "groupsvisible");
-
-        // initialize groups if this value isn't set in the config file
-        if (!$groups_config) {
-            $groups_config = array_keys($groups_db);
-        }
-
-        $groups_aliases = $this->getValue("groupsalias");
-        $groups_visible = $this->getValue("groupsvisible");
-        if (!is_array($groups_visible))
-            $groups_visible = [];
-        if (!is_array($groups_aliases))
-            $groups_aliases = [];
-        if (count(array_intersect(array_keys($groups_aliases), array_keys($groups_db)))) {
-            foreach ($groups_config as $group_config) {
-                $groups[$group_config] = $groups_aliases[$group_config];
-            }
-        } else {
-            if (is_array($groups_config)) {
-                for ($i = 0; $i < count($groups_config); $i++) {
-                    $groups[$groups_config[$i]] = $groups_aliases[$i];
-                }
-            }
-        }
-
-        $out = "<table width=\"100%\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\">\n";
-        $out .= "<tr>\n";
-        $out .= "<td width=\"42%\"><b>" . _("Gruppenname") . "</b></td>\n";
-        $out .= "<td width=\"48%\"><b>" . _("alternativer Gruppenname") . "</b></td>\n";
-        $out .= "<td width=\"1%\"><b>" . _("Sichtbarkeit") . "</b></td>\n";
-        $out .= "<td width=\"9%\">&nbsp;</td>\n";
-        $out .= "</tr>\n";
-        $i = 0;
-        foreach ($groups_db as $id => $name) {
-
-            // name of group
-            $out .= "<tr>\n";
-            $out .= "<td nowrap=\"nowrap\" style=\"max-width: 40em; overflow: hidden; text-overflow: ellipsis;\" title=\"" . htmlReady($name) . "\"><font size=\"2\">&nbsp;" . htmlReady($name) . "</font></td>";
-
-            // column headline
-            $out .= '<td nowrap="nowrap"><input type="text" name="'
-                    . $this->element_name . '_groupsalias[' . $id . ']"';
-            $out .= " size=\"25\" maxlength=\"150\" value=\"";
-            $out .= $groups[$id] . "\">";
-            if ($this->faulty_values[$this->element_name . "_groupsalias"][$id])
-                    $out .= $this->error_sign;
-            $out .= "</td>\n";
-
-            // visible
-            $out .= '<td align="center">'
-                    . '<input type="hidden" name="'
-                    . $this->element_name . '_show_group[' . $id . ']" value="0">'
-                    . '<input type="checkbox" name="'
-                    . $this->element_name . '_show_group[' . $id . ']" value="1"';
-            if (in_array($id, $groups_visible)) {
-                $out .= ' checked';
-            }
-            $out .= '></td>';
-            $out .= "<td>&nbsp;</td></tr>\n";
-            $i++;
-        }
-
-        $out .= "</table>\n";
-
-        return $out;
-    }
-
-    function editSemTypes () {
-        global $SEM_TYPE, $SEM_CLASS;
-        // these two values are always necessary, even there is an error in the users inputs, so
-        // there aren't transfered via $_POST
-        $this->form_values[$this->element_name . "_order"]
-                = $this->config->getValue($this->element_name, "order");
-        $order = $this->getValue("order");
-
-        $this->form_values[$this->element_name . '_visibility']
-                = $this->config->getValue($this->element_name, 'visibility');
-        $visibility = $this->getValue('visibility');
-
-        // compat <1.3: new attribute visibility (all SemTypes are visible)
-        if (!is_array($visibility) || !count($visibility)) {
-            $visibility = array_fill(0, count($order), 1);
-        }
-
-        if (!is_array($order)) {
-            $order = array_keys($SEM_TYPE);
-        }
-
-
-        $out = "<table width=\"100%\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\">\n";
-        $out .= "<tr>\n";
-        $out .= "<td><b>" . _("Datenfeld") . "</b></td>\n";
-        $out .= "<td><b>" . _("Ãœberschrift") . "</b></td>\n";
-        $out .= "<td align=\"center\"><b>" . _("Reihenfolge") . "</b></td>\n";
-        $out .= "<td align=\"center\"><b>" . _("Sichtbarkeit") . "</b></td>\n";
-        $out .= "</tr>\n";
-
-        foreach ($SEM_CLASS as $class_index => $foo) {
-            $i = 0;
-            foreach ($SEM_TYPE as $type_index => $type) {
-                if ($type["class"] == $class_index) {
-                    $mapping[$type_index] = $i++;
-                }
-            }
-            $classes[$class_index] = $this->getValue("class_$class_index");
-        }
-
-        if(is_array($order)) {
-            for ($i = 0; $i < count($order); $i++) {
-                if ($SEM_TYPE[$order[$i]]) {
-                    $new_order[] = $order[$i];
-                    // name of column
-                    $out .= "<tr>\n";
-                    $out .= "<td>&nbsp;";
-                    if (mb_strlen($SEM_TYPE[$order[$i]]["name"]) > 25) {
-                        $out .= htmlReady(mb_substr($SEM_TYPE[$order[$i]]["name"], 0, 22)
-                            . "... ({$SEM_CLASS[$SEM_TYPE[$order[$i]]['class']]['name']})");
-                    } else {
-                        $out .= htmlReady($SEM_TYPE[$order[$i]]["name"]
-                            . " ({$SEM_CLASS[$SEM_TYPE[$order[$i]]['class']]['name']})");
-                    }
-                    $out .= "</td>";
-
-                    // column headline
-                    $out .= "<td><input type=\"text\" name=\"{$this->element_name}_class_";
-                    $out .= $SEM_TYPE[$order[$i]]['class'] . "[{$mapping[$order[$i]]}]\"";
-                    $out .= "\" size=\"20\" maxlength=\"100\" value=\"";
-                    if (isset($classes[$SEM_TYPE[$order[$i]]['class']][$mapping[$order[$i]]])) {
-                        $out .= $classes[$SEM_TYPE[$order[$i]]['class']][$mapping[$order[$i]]] . "\">";
-                    } else {
-                        $out .= $SEM_TYPE[$order[$i]]["name"]
-                            . " ({$SEM_CLASS[$SEM_TYPE[$order[$i]]['class']]['name']})\">";
-                    }
-                    if ($this->faulty_values[$this->element_name
-                    . "_class_{$SEM_TYPE[$order[$i]]['class']}"][$mapping[$order[$i]]]) {
-                        $out .= $this->error_sign;
-                    }
-                    $out .= "</td>\n";
-
-                    // move up
-                    $out .= "<td valign=\"top\" align=\"center\" nowrap=\"nowrap\">";
-                    $out .= Icon::create('arr_2up', Icon::ROLE_SORT, ['title' => _('Datenfeld verschieben')])
-                        ->asInput(['name'=>$this->element_name.'_move_left['.$i.']','align'=>'middle',]);
-
-                    // move down
-                    $out .= Icon::create('arr_2down', Icon::ROLE_SORT, ['title' => _('Datenfeld verschieben')])
-                        ->asInput(['name'=>$this->element_name.'_move_right['.$i.']','align'=>'middle',]);
-                    $out .= "</td>\n";
-
-                    // visibility
-                    $out .= "<td valign=\"top\" align=\"center\" nowrap=\"nowrap\">";
-                    $out .= "<input type=\"checkbox\" name=\"{$this->element_name}_visibility";
-                    $out .= '[' . ($order[$i] - 1) . "]\" value=\"1\"";
-                    if ($visibility[$order[$i] - 1] == 1) {
-                        $out .= ' checked="checked"';
-                    }
-                    $out .= '>';
-
-                    $out .= "</td>\n</tr>\n";
-                }
-            }
-        }
-        $out .= "</table>\n";
-        $out .= "<input type=\"hidden\" name=\"count_semtypes\" value=\"$i\">\n";
-
-        // update order
-        if (count(array_diff($order, $new_order))) {
-            $this->config->setValue($this->element_name, 'order', $new_order);
-            $this->config->store();
-        }
-        return $out;
-    }
-
-    function editSelectSubjectAreas ($selector) {
-        $info = _("Wählen Sie die Studienbereiche aus, deren Veranstaltungen angezeigt werden sollen.");
-        $info2 = _("Sie können beliebig viele Studienbereiche auswählen.");
-        $form_name = $this->element_name . "_" . 'subjectareasselected';
-
-        if ($this->faulty_values[$form_name][0]) {
-            $error_sign = $this->error_sign;
-        } else {
-            $error_sign = '';
-        }
-
-        $selected = $this->config->getValue($this->element_name, 'subjectareasselected');
-        $selector->selected = [];
-        $selector->sem_tree_ranges = [];
-        $selector->sem_tree_ids = [];
-        if (is_array($selected) && count($selected)) {
-            foreach ($selected as $selected_id) {
-                $selector->selected[$selected_id] = TRUE;
-                $selector->sem_tree_ranges[$selector->tree->tree_data[$selected_id]['parent_id']][] = $selected_id;
-                $selector->sem_tree_ids[] = $selected_id;
-            }
-        }
-
-        $form_name_tmp = $selector->form_name;
-        $selector->form_name = 'SelectSubjectAreas';
-        $selector->doSearch();
-        $out = "<table width=\"100%\" border=\"0\" cellpadding=\"4\" cellspacing=\"0\">\n";
-        $out .= '<tr><td align="left" style="font-size: smaller;" width="100%" nowrap="nowrap" colspan="2">' . _("Suche") . ': ';
-        $out .= $selector->getSearchField(['size' => 30 ,'style' => 'vertical-align:middle;']);
-        $out .= $selector->getSearchButton(['style' => 'vertical-align:middle;']);
-        $out .= '<br><span style="font-size: 0.9em;"> (' . sprintf(_("Geben Sie '%s' ein, um alle Studienbereiche zu finden."), '%%%') . ')</span>';
-        if ($selector->num_search_result !== false){
-            $out .= "<br><span style=\"font-size:smaller;\"><a name=\"anker\">&nbsp;&nbsp;</a>"
-                    . sprintf(_("Ihre Suche ergab %s Treffer."),$selector->num_search_result)
-                    . (($selector->num_search_result) ? _(" (Suchergebnisse werden blau angezeigt)") : '')
-                    . '</span>';
-        }
-        $out .= '</td></tr>';
-        $selector->form_name = $form_name_tmp;
-        $out .= '<td nowrap="nowrap" width="80%">';
-        $out .= $selector->getChooserField(['style' => 'width:98%;','size' => 15],
-                70, 'subjectareasselected');
-        $out .= '</td><td width="20%" style="vertical-align: top;">';
-        $out .= tooltipIcon($info);
-        $out .= "<span style=\"vertical-align:top;\">$error_sign</span>";
-        $out .= "</td></tr></table>\n";
-
-        return $out;
-    }
-
-    function editMarkerDescription ($markers, $new_datafields = FALSE) {
-        $out = "<table width=\"100%\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\" style=\"font-size: 0.7em\">\n";
-        $out .= "<tr>\n";
-        $out .= '<td><b>' . _("Marker") . "</b></td>\n";
-        $out .= '<td><b>' . _("Beschreibung") . "</b></td>\n";
-        $out .= "</tr>\n";
-
-        $spacer = 0;
-        $global_vars = FALSE;
-        foreach ((array) $markers as $marker) {
-            $mark = $marker[0];
-            $description = $marker[1];
-            if ($mark == '__GLOBAL__') {
-                $out .= "<tr>\n";
-                $out .= '<td colspan="2"><strong>' . _('Globale Variablen') . '</strong></td>';
-                $spacer++;
-                $global_vars = true;
-            } else if ($mark[0] == '<') {
-                if ($global_vars) {
-                    $out .= "<tr>\n";
-                    $out .= '<td colspan="2">&nbsp;</td>';
-                    $spacer--;
-                    $global_vars = false;
-                }
-                if (mb_substr($mark, 0, 8) == '<!-- END') {
-                    $spacer--;
-                    $out .= "<tr>\n";
-                    $out .= '<td colspan="2">&nbsp;</td>';
-                    $out .= "<tr>\n";
-                    $out .= '<td nowrap="nowrap">' . str_repeat('&nbsp;', $spacer * 4);
-                    $out .= htmlReady($mark) . '</td><td>' . htmlReady($description);
-                    $out .= '</td>';
-                } else {
-                    if ($spacer > 0 && mb_substr($mark, 0, 10) != '<!-- BEGIN') {
-                        $out .= "<tr>\n";
-                        $out .= '<td colspan="2">&nbsp;</td>';
-                    }
-                    $out .= "<tr>\n";
-                    $out .= '<td nowrap="nowrap">' . str_repeat('&nbsp;', $spacer * 4);
-                    $out .= htmlReady($mark) . '</td><td>' . htmlReady($description);
-                    $out .= '</td>';
-                    $spacer++;
-                    $out .= "<tr>\n";
-                    $out .= '<td colspan="2">&nbsp;</td>';
-                }
-            } else {
-                $out .= "<tr>\n";
-                $out .= '<td>' . str_repeat('&nbsp;', $spacer * 4);
-                $out .= $mark . '</td><td>' . htmlReady($description);
-                $out .= '</td>';
-            }
-            $out .= "</tr>\n";
-        }
-        if ($new_datafields) {
-            $out .= "<tr>\n";
-            $out .= "<td colspan=\"2\">&nbsp;</td></tr>\n";
-            $out .= "<tr>\n";
-            $out .= '<td colspan="2" align="center">' . Button::create(_('Aktualisieren')). "</td></tr>\n";
-        }
-        $out .= "</table>\n";
-
-        return $out;
-    }
-
-    function editSelectInstitutes () {
-        // get all faculties
-        $stm_fak = DBManager::get()->prepare(
-            "SELECT Institut_id, Name "
-            . "FROM Institute "
-            . "WHERE fakultaets_id = Institut_id "
-            . "ORDER BY Name");
-        $stm_fak->execute();
-        $stm_inst = DBManager::get()->prepare(
-            "SELECT Institut_id, Name "
-            . "FROM Institute "
-            . "WHERE fakultaets_id = ? AND fakultaets_id != Institut_id "
-            . "ORDER BY Name");
-        $selected = $this->config->getValue($this->element_name, 'institutesselected');
-        if (!is_array($selected)) {
-            $selected = [];
-        }
-
-        $out = '<div class="selectbox" style="width: 98%;" size="15">';
-        while ($row_fak = $stm_fak->fetch(PDO::FETCH_ASSOC)) {
-            $stm_inst->execute([$row_fak['Institut_id']]);
-            $out .= sprintf('<div style="margin-top: 5px; font-weight: bold; color: red;">%s</div>', htmlReady(my_substr($row_fak['Name'], 0, 70)));
-            $out .= '<div style="font-weight: bold; color: red;">';
-            $out .= str_repeat("¯", 70);
-            $out .= '</div>';
-            while ($row_inst = $stm_inst->fetch(PDO::FETCH_ASSOC)) {
-                $is_selected = in_array($row_inst['Institut_id'], $selected);
-                $out .= sprintf('<div><label for="SelectInstitutes_institutesselected_%s"><input style="vertical-align: middle;" id="SelectInstitutes_institutesselected_%s" type="checkbox" name="SelectInstitutes_institutesselected[]" value="%s"%s>', $row_inst['Institut_id'], $row_inst['Institut_id'], $row_inst['Institut_id'], ($is_selected ? ' checked="checked"' : ''));
-                $out .= sprintf('&nbsp;<span%s>%s</span></div>', ($is_selected ? '' : ' style="color: blue;"'), htmlReady(my_substr($row_inst['Name'], 0, 70)));
-            }
-        }
-        $out .= '</div>';
-        return $out;
-    }
-}
diff --git a/lib/extern/views/extern_edit_module.inc.php b/lib/extern/views/extern_edit_module.inc.php
deleted file mode 100644
index 21c5c884622..00000000000
--- a/lib/extern/views/extern_edit_module.inc.php
+++ /dev/null
@@ -1,171 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* extern_edit_module.inc.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       extern_edit_module
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// extern_edit_module.inc.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-use Studip\Button, Studip\LinkButton;
-
-// it's forbidden to use the command "new" with a given config_id
-if (Request::option('com') == 'new') {
-    $config_id = '';
-}
-
-$module = FALSE;
-if (Request::option('com') == 'new') {
-    foreach ($GLOBALS['EXTERN_MODULE_TYPES'] as $key => $type) {
-        if ($type['module'] == Request::quoted('mod')) {
-            $configurations = ExternConfig::GetAllConfigurations($range_id, $key);
-            if (!isset($configurations[$type['module']]) || sizeof($configurations[$type['module']]) < $GLOBALS['EXTERN_MAX_CONFIGURATIONS']) {
-                $module = ExternModule::GetInstance($range_id, $type['module'], '', 'NEW');
-            }
-            else {
-                echo MessageBox::error(sprintf(_('Es wurden bereits %s Konfigurationen angelegt. Sie können für dieses Module keine weiteren Konfigurationen anlegen.')
-                    , $GLOBALS['EXTERN_MAX_CONFIGURATIONS']));
-
-                echo LinkButton::create("<< " . _("Zurück"), URLHelper::getURL('?list=TRUE'));
-                $template = $GLOBALS['template_factory']->open('layouts/base.php');
-                $template->content_for_layout = ob_get_clean();
-                echo $template->render();
-                page_close();
-                die;
-            }
-        }
-    }
-}
-else {
-    foreach ($GLOBALS['EXTERN_MODULE_TYPES'] as $type) {
-        if ($type["module"] == $mod) {
-            $module = ExternModule::GetInstance($range_id, $mod, $config_id);
-        }
-    }
-}
-
-if (!$module)
-    die("Unknown module type");
-
-$element_command = FALSE;
-$edit = Request::option('edit');
-if ($edit) {
-    $element_commands = ['show', 'hide', 'move_left', 'move_right', 'show_group', 'hide_group', 'do_search_x'];
-    foreach ($element_commands as $element_command) {
-        $element_command_form = $edit . "_" . $element_command;
-        if ($_POST[$element_command_form]) {
-            if ($element_command == 'show_group') {
-                $pos = $_POST[$element_command_form];
-            } else if (is_array($_POST[$element_command_form])) {
-                $pos_tmp = array_keys($_POST[$element_command_form]);
-                $pos = $pos_tmp[0];
-            }
-            $module->executeCommand($edit, $element_command, $pos);
-        }
-    }
-}
-
-$elements = $module->getAllElements();
-
-// the first parameter of printOutEdit() has to be an array, because it is
-// possible to open more than one element form
-$edit_open = "";
-
-foreach ($elements as $element) {
-    if ($edit == $element->getName()) {
-        $edit_open = ["$edit" => (Request::option('com') != 'close')];
-    }
-}
-if (Request::option('com') == 'new' || Request::option('com') == 'edit' || Request::option('com') == 'open' || Request::option('com') == 'close') {
-    $module->printoutEdit($edit_open, $_POST, "", $edit);
-}
-
-if (Request::option('com') == 'store') {
-
-    $faulty_values = $module->checkFormValues($edit);
-    $fault = FALSE;
-    foreach ($faulty_values as $faulty) {
-        if (in_array(TRUE, $faulty)) {
-            echo MessageBox::info(_("Bitte korrigieren Sie die mit * gekennzeichneten Werte!"));
-            $module->printoutEdit($edit_open, $_POST,
-                    $faulty_values, $edit);
-            $fault = TRUE;
-            break;
-        }
-    }
-    if (!$fault) {
-        // This is the right place to trigger some functions by special
-        // POST_VARS-values. At the moment there is only one: If the name of the
-        // configuration was changed, setup the extern_config table.
-        if ($edit == "Main" && $_POST["Main_name"] != $module->config->config_name) {
-            if (!ExternConfig::ChangeName($module->config->range_id, $module->getType(), $module->config->getId(),
-                    $module->config->config_name, $_POST["Main_name"])) {
-                PageLayout::postError(_('Der Konfigurationsname wurde bereits für eine Konfiguration dieses Moduls vergeben. Bitte geben Sie einen anderen Namen ein.'));
-                $module->printoutEdit($edit_open, "$_POST", "", $edit);
-            }
-            $module->store($edit, $_POST);
-            PageLayout::postSuccess(_('Die eingegebenen Werte wurden übernommen und der Name der Konfiguration geändert.'));
-            $module->printoutEdit($edit_open, "", "", $edit);
-        } else {
-            $module->store($edit, $_POST);
-            PageLayout::postSuccess(_('Die eingegebenen Werte wurden übernommen.'));
-            $module->printoutEdit($edit_open, "", "", $edit);
-        }
-    }
-}
-
-
-if (empty($edit_open[$edit])) {
-    echo  LinkButton::create("<< " . _("Zurück"), URLHelper::getURL('?list=TRUE'));;
-}
-
-Helpbar::get()->addPlainText(_('Information'), _('Um die Werte eines einzelnen Elements zu ändern, klicken Sie bitte den "Übernehmen"-Button innerhalb des jeweiligen Elements.'));
-
-// the type of this module is not Global
-if ($module->getType() != 0) {
-    $url = sprintf("%sextern.php?module=%s&range_id=%s&preview=1&config_id=%s",
-                   $GLOBALS['CANONICAL_RELATIVE_PATH_STUDIP'],
-                   $module->getName(),
-                   $module->config->range_id,
-                   $module->config->getId()
-    );
-    if ($global_config = ExternConfig::GetGlobalConfiguration($module->config->range_id)) {
-        $url .= "&global_id=$global_config";
-    }
-
-    $actions = new ActionsWidget();
-    $actions->addLink(_('Vorschau'), $url, Icon::create('question-circle', 'clickable', ['title' => _('Vorschau')]), ['target' => '_blank']);
-    Sidebar::get()->addWidget($actions);
-}
-
-?>
diff --git a/lib/extern/views/extern_html_templates.inc.php b/lib/extern/views/extern_html_templates.inc.php
deleted file mode 100644
index 981419271be..00000000000
--- a/lib/extern/views/extern_html_templates.inc.php
+++ /dev/null
@@ -1,145 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* extern_functions_templates.inc.php
-*
-*
-*
-*
-* @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
-* @access       public
-* @modulegroup  extern
-* @module       extern_functions_templates
-* @package  studip_extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// extern_functions_templates.inc.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-/**
-*
-*
-*/
-function table_header ($element) {
-    $out = "<table" . $element->getAttributes("table") . ">\n";
-
-    return $out;
-}
-
-/**
-*
-*
-*/
-function table_headrow ($element, $fields) {
-    $font_attributes = $element->getAttributes("font");
-
-    $out = "<tr" . $element->getAttributes("tr") . ">\n";
-    foreach ($fields as $field) {
-        if ($font_attributes)
-            $field = "<font$font_attributes>$field</font>";
-        $out .= "<td" . $element->getAttributes("td") . ">" . $field . "</td>\n";
-    }
-    $out .= "<tr>\n";
-
-    return $out;
-}
-
-/**
-*
-*
-*/
-function table_row ($element, $fields) {
-    $font_attributes = $element->getAttributes("font");
-
-    $out = "<tr" . $element->getAttributes("tr") . ">\n";
-    foreach ($fields as $field) {
-        if ($font_attributes)
-            $field = "<font$font_attributes>$field</font>";
-        $out .= "<td" . $element->getAttributes("td") . ">" . $field . "</td>\n";
-    }
-    $out .= "</tr>\n";
-
-    return $out;
-}
-
-/**
-*
-*
-*/
-function table_group ($element, $group_name) {
-    $colspan = " colspan=\"";
-    $colspan .= sizeof($element->config->getValue("main", "order")) . "\"";
-
-    if ($font_attributes = $element->getAttributes("font"))
-        $group_name = "<font$font_attributes>$group_name</font>";
-
-    $out = "<tr" . $element->getAttributes("tr") . ">\n";
-    $out .= "<td" . $element->getAttributes("td") . $colspan . ">";
-    $out .= $group_name;
-    $out .= "</td>\n</tr>\n";
-
-    return $out;
-}
-
-/**
-*
-*
-*/
-function table_footer () {
-    $out = "</table>";
-
-    return $out;
-}
-
-/**
-*
-*
-*/
-function html_header (&$config) {
-    $out = "<!DOCTYPE html>\n";
-    $out .= "<html>\n<head>\n";
-    $out .= "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n";
-    if ($copyright = $config->getValue('Main', 'copyright'))
-        $out .= "<meta name=\"copyright\" content=\"$copyright\">\n";
-    if ($author = $config->getValue('Main', 'author'))
-        $out .= "<meta name=\"author\" content=\"$author\">\n";
-    $out .= '<title>' . $config->getValue('Main', 'title') . "</title>\n";
-    if ($urlcss = $config->getValue('Main', 'urlcss'))
-        $out .= "<link rel=\"stylesheet\" type=\"text/css\" href=\"$urlcss\">\n";
-    $out .= "</head>\n" . $config->getTag('Body', 'body') . "\n";
-
-    return $out;
-}
-
-/**
-*
-*
-*/
-function html_footer () {
-
-    return "</body>\n</html>";
-}
-
-?>
diff --git a/lib/extern/views/extern_info_module.inc.php b/lib/extern/views/extern_info_module.inc.php
deleted file mode 100644
index 885ef018773..00000000000
--- a/lib/extern/views/extern_info_module.inc.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
- * extern_info_module.inc.php
- *
- *
- *
- *
- * @author       Peter Thienel <pthienel@web.de>, Suchi & Berg GmbH <info@data-quest.de>
- * @access       public
- * @modulegroup  extern
- * @module       extern_info_module
- * @package      studip_extern
- */
-
-use Studip\Button, Studip\LinkButton;
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// extern_info_module.inc.php
-//
-// Copyright (C) 2003 Peter Thienel <pthienel@web.de>,
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-$info = ExternConfig::GetInfo($range_id, $config_id);
-?>
-<table class="default">
-    <caption>
-        <?= _('Allgemeine Daten') ?>
-    </caption>
-    <tr>
-        <td><?= _('Modulname') ?></td>
-        <td><?= htmlReady($info["module_name"]) ?></td>
-    </tr>
-    <tr>
-        <td><?= _('Name der Konfiguration') ?></td>
-        <td><?= htmlReady($info["name"]) ?></td>
-    </tr>
-    <tr>
-        <td><?= _('Erstellt am') ?></td>
-        <td><?= $info["make_date"] ?></td>
-    </tr>
-    <tr>
-        <td><?= _('Letzte Änderung') ?></td>
-        <td><?= $info["change_date"] ?></td>
-    </tr>
-    <tr>
-        <td><?= _('Beschreibung') ?></td>
-        <td><?= $EXTERN_MODULE_TYPES[$info["module_type"]]["description"] ?></td>
-    </tr>
-</table>
-<?
-
-if ($info['module_type'] != 0)  :?>
-    <? if ($info['level'] == 1) : ?>
-        <p><strong><?= _('Direkter Link') ?></strong></p>
-        <blockquote><a href="<?= $info['link'] ?>" target="_blank" rel="noopener noreferrer"><?= $info['link_br'] ?></a></blockquote>
-        <p><?= _('Diese Adresse können Sie in einen Link auf Ihrer Website integrieren, um auf die Ausgabe des Moduls zu verweisen.') ?></p>
-    <? endif ?>
-
-    <? if (Config::get()->EXTERN_SRI_ENABLE && sri_is_enabled(Context::getId())) : ?>
-        <p><strong><?= _("Stud.IP-Remote-Include (SRI)  Schnittstelle") ?></strong></p>
-        <p><?= _('Der unten aufgeführte Textblock ermöglicht Ihnen den Zugriff auf die Stud.IP-Remote-Include-Schnittstelle (SRI).') ?></p>
-        <blockquote>
-            <pre><?= $info['sri'] ?></pre>
-        </blockquote>
-        <p><?= _('Kopieren Sie dieses Code-Schnipsel in eine beliebige Stelle im HTML-Quelltext einer Seite Ihrer Website.') ?></p>
-        <p><?= _('Durch eine spezielle Art des Seitenaufrufs, wird an dieser Stelle die Ausgabe des Moduls eingefügt.') ?></p>
-        <p><strong><?= _('Link zur SRI-Schnittstelle') ?></strong></p>
-        <blockquote>
-            <?= $info['link_sri'] ?>
-        </blockquote>
-        <p><?= sprintf(_('Ersetzen Sie %s durch die URL der Seite, in die Sie die Ausgabe des Moduls einfügen wollen. Diese Seite muss obigen Code-Schnipsel enthalten.'), _('URL_DER_INCLUDE_SEITE')) ?></p>
-    <? endif ?>
-<? endif ?>
-
-
-<?= LinkButton::create('<<  ' . _('Zurück'), URLHelper::getURL('', ['list' => true])); ?>
diff --git a/lib/models/ExternPageConfig.php b/lib/models/ExternPageConfig.php
new file mode 100644
index 00000000000..5259d4151f2
--- /dev/null
+++ b/lib/models/ExternPageConfig.php
@@ -0,0 +1,61 @@
+<?php
+/**
+ * ExternPageConfig.php - model class for the configuration of external pages
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author      Peter Thienel <thienel@data-quest.de>
+ * @license     http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category    Stud.IP
+ * @package     extern
+ * @since       5.4
+ *
+ * @property string $config_id database column
+ * @property string $id alias column for config_id
+ * @property string $range_id database column
+ * @property string $type database column
+ * @property string $name database column
+ * @property string $description database column
+ * @property string $conf database column
+ * @property string $template database column
+ * @property string $author_id database column
+ * @property string $editor_id database column
+ * @property int $mkdate database column
+ * @property int $chdate database column
+ * @property User $author has_one User
+ * @property User $editor has_one User
+ */
+
+class ExternPageConfig extends SimpleORMap
+{
+    /**
+     * Configures this model.
+     *
+     * @param array $config Configuration array
+     */
+    protected static function configure($config = [])
+    {
+        $config['db_table'] = 'extern_pages_configs';
+
+        $config['belongs_to']['author'] = [
+            'class_name'  => User::class,
+            'foreign_key' => 'author_id'
+        ];
+        $config['belongs_to']['editor'] = [
+            'class_name'  => User::class,
+            'foreign_key' => 'editor_id'
+        ];
+        $config['belongs_to']['range'] = [
+            'class_name'  => Institute::class,
+            'foreign_key' => 'range_id'
+        ];
+
+        $config['serialized_fields']['conf'] = JSONArrayObject::class;
+
+        parent::configure($config);
+    }
+}
+
diff --git a/lib/models/User.class.php b/lib/models/User.class.php
index 4928ed8851d..434a0487956 100644
--- a/lib/models/User.class.php
+++ b/lib/models/User.class.php
@@ -201,6 +201,11 @@ class User extends AuthUserMd5 implements Range, PrivacyObject
             'on_delete'         => 'delete',
         ];
 
+        $config['has_many']['extern_pages_configs'] = [
+            'class_name' => ExternPageConfig::class,
+            'assoc_foreign_key' => 'author_id'
+        ];
+
         $config['additional_fields']['config']['get'] = function ($user) {
             return UserConfig::get($user->id);
         };
diff --git a/lib/navigation/AdminNavigation.php b/lib/navigation/AdminNavigation.php
index 019355924f2..12bf53adfe4 100644
--- a/lib/navigation/AdminNavigation.php
+++ b/lib/navigation/AdminNavigation.php
@@ -80,7 +80,7 @@ class AdminNavigation extends Navigation
         }
 
         if (Config::get()->EXTERN_ENABLE) {
-            $navigation->addSubNavigation('external', new Navigation(_('Externe Seiten'), 'admin_extern.php?view=extern_inst'));
+            $navigation->addSubNavigation('external', new Navigation(_('Externe Seiten'), 'dispatch.php/institute/extern'));
         }
 
         if ($perm->have_perm("root") || ($perm->is_fak_admin() && Config::get()->INST_FAK_ADMIN_PERMS != 'none')) {
@@ -106,7 +106,7 @@ class AdminNavigation extends Navigation
             }
 
             if (Config::get()->EXTERN_ENABLE) {
-                $navigation->addSubNavigation('external', new Navigation(_('Externe Seiten'), 'admin_extern.php?list=TRUE&view=extern_global'));
+                $navigation->addSubNavigation('external', new Navigation(_('Externe Seiten'), 'dispatch.php/admin/extern'));
             }
 
             $navigation->addSubNavigation('sem_classes', new Navigation(_('Veranstaltungskategorien'), 'dispatch.php/admin/sem_classes/overview'));
diff --git a/lib/plugins/core/ExternPagePlugin.php b/lib/plugins/core/ExternPagePlugin.php
new file mode 100644
index 00000000000..5b407758d51
--- /dev/null
+++ b/lib/plugins/core/ExternPagePlugin.php
@@ -0,0 +1,52 @@
+<?php
+interface ExternPagePlugin
+{
+    /**
+     * Returns a Navigation-object. Only the title, description and the image will be used.
+     * The title is used as a link to open the configuration form.
+     *
+     * @return Navigation with title, description and image
+     */
+    public function getConfigurationFormNavigation(): Navigation;
+
+    /**
+     * The name is one word describing the scope of the page. This word is part of
+     * the class name of the provided ExternPage object e.g. "ExternPageModules" the
+     * name is "Modules". Do not translate this string...
+     *
+     * @return string The name of the external page.
+     */
+    public function getExternPageName(): string;
+
+    /**
+     * Returns true if this is a system-wide external page (located under "Location" ;-) )
+     *
+     * @return boolean
+     */
+    public function isSystemPage(): bool;
+
+    /**
+     * Returns true if this is an external page for institutes and faculties (located under "Institutes")
+     *
+     * @return boolean
+     */
+    public function isInstitutePage(): bool;
+
+    /**
+     * Returns an object from type ExternPage. The class name begins with "ExternPage" followed by the
+     * name of the external page.
+     * If the name is "ModuleSearch" the class name is "ExternalPageModuleSearch"
+     *
+     * @return ExternPage
+     */
+    public function getExternPage(ExternPageConfig $config): ExternPage;
+
+    /**
+     * Returns a Flexi_Template or a path to the template file. This template contains the form
+     * to configure the external page.
+     *
+     * @return string|Flexi_Template
+     */
+    public function getConfigurationFormTemplate();
+
+}
diff --git a/public/admin_extern.php b/public/admin_extern.php
deleted file mode 100644
index 7520584dad1..00000000000
--- a/public/admin_extern.php
+++ /dev/null
@@ -1,65 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* admin_extern.php
-* 
-* Extern-admin-pages-mainfile. Calls the submodules.
-*
-* @author       Peter Thienel <pthienel@data.quest.de>
-* @access       public
-* @modulegroup  extern_modules
-* @module       extern
-* @package      Extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// admin_extern.php
-//
-// Copyright (c) 2003 Peter Tienel <pthienel@data-quest.de> 
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-
-require '../lib/bootstrap.php';
-
-page_open(["sess" => "Seminar_Session", "auth" => "Seminar_Auth",
-        "perm" => "Seminar_Perm", "user" => "Seminar_User"]);
-$perm->check("admin");
-
-PageLayout::setHelpKeyword("Basis.EinrichtungenVerwaltenExterneSeiten");
-PageLayout::setTitle(_("Verwaltung externer Seiten"));
-
-if (Config::get()->EXTERN_ENABLE) {
-    include "lib/extern/admin_extern.inc.php";
-} else {
-    ob_start();
-    // Start of Output
-    PageLayout::postError(_('Die Verwaltung externer Seiten ist nicht eingebunden. Bitte aktivieren Sie diese in den Systemeinstellungen, oder wenden Sie sich an die Systemadministration.'),
-        [_("Modul \"externe Seiten\" nicht eingebunden")]);
-    $template = $GLOBALS['template_factory']->open('layouts/base.php');
-    $template->content_for_layout = ob_get_clean();
-    $template->infobox = $infobox ? ['content' => $infobox] : null;
-    echo $template->render();
-    
-    page_close();
-}
-
-?>
diff --git a/public/extern.php b/public/extern.php
deleted file mode 100644
index 174038b8084..00000000000
--- a/public/extern.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?
-# Lifter002: TODO
-# Lifter007: TODO
-# Lifter003: TODO
-# Lifter010: TODO
-/**
-* Extern-Pages-mainfile. Calls the submodules.
-*
-*
-*
-* @author       Peter Thienel <pthienel@data.quest.de>
-* @access       public
-* @modulegroup  extern_modules
-* @module       extern
-* @package      Extern
-*/
-
-// +---------------------------------------------------------------------------+
-// This file is part of Stud.IP
-// extern.php
-//
-// Copyright (c) 2003 Peter Tienel <pthienel@data-quest.de>
-// Suchi & Berg GmbH <info@data-quest.de>
-// +---------------------------------------------------------------------------+
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation; either version 2
-// of the License, or any later version.
-// +---------------------------------------------------------------------------+
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-// You should have received a copy of the GNU General Public License
-// along with this program; if not, write to the Free Software
-// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
-// +---------------------------------------------------------------------------+
-
-
-require '../lib/bootstrap.php';
-
-if (!Config::get()->EXTERN_ENABLE) {
-    echo "<br><br><br><blockquote><b>This page is not available!<br>The module \"extern\"";
-    echo " is not enabled in this Stud.IP-installation.</b></blockquote>";
-    exit;
-}
-
-include "lib/extern/extern.inc.php";
diff --git a/resources/assets/javascripts/bootstrap/external_pages.js b/resources/assets/javascripts/bootstrap/external_pages.js
new file mode 100644
index 00000000000..d434dd8a869
--- /dev/null
+++ b/resources/assets/javascripts/bootstrap/external_pages.js
@@ -0,0 +1,15 @@
+import {$gettext} from "../lib/gettext";
+
+STUDIP.domReady(function () {
+    const ExternalPage = document.querySelector('#institute-extern-edit, #admin-extern-edit');
+    if (ExternalPage !== null) {
+        jQuery('#select-study-areas').select2({
+            placeholder:  $gettext('Studienbereich suchen'),
+            minimumInputLength: 3,
+            ajax: {
+                url: STUDIP.URLHelper.getURL('dispatch.php/admin/extern/search_studyareas'),
+                dataType: 'json'
+            }
+        });
+    }
+});
diff --git a/resources/assets/javascripts/entry-base.js b/resources/assets/javascripts/entry-base.js
index 70ef84e571f..37bec894a65 100644
--- a/resources/assets/javascripts/entry-base.js
+++ b/resources/assets/javascripts/entry-base.js
@@ -85,6 +85,7 @@ import "./bootstrap/contentmodules.js"
 import "./bootstrap/responsive-navigation.js"
 import "./bootstrap/treeview.js"
 import "./bootstrap/stock-images.js"
+import "./bootstrap/external_pages.js"
 
 import "./mvv_course_wizard.js"
 import "./mvv.js"
diff --git a/templates/extern/upload_form.php b/templates/extern/upload_form.php
deleted file mode 100644
index 932dc358c5a..00000000000
--- a/templates/extern/upload_form.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?
-# Lifter010: TODO
-use Studip\Button, Studip\LinkButton;
-
-?>
-<!-- upload extern config -->
-<tr class="nohover">
-    <td colspan="10" align="center" class="<?= $class ?>">
-        <a name="upload"></a>
-
-        <form enctype="multipart/form-data" name="upload_form" action="<?= URLHelper::getLink() ?>" method="post" class="default">
-            <?= CSRFProtection::tokenTag() ?>
-            <fieldset>
-                <legend><?= _('Konfiguration hochladen') ?></legend>
-
-                <b><?= _("Maximale Größe:") ?> <?= ($max_filesize / 1024) ?></b> <?= _("Kilobyte") ?>
-
-                <label>
-		<a class="button"><?= _('Datei zum Hochladen auswählen') ?></a>
-                    <input name="the_file" type="file">
-                </label>
-
-            </fieldset>
-            <footer>
-                <?= Button::createAccept(_('Hochladen'), ['onClick' => 'return STUDIP.OldUpload.upload_start(jQuery(this).closest(\'form\'))'])?>
-                <?= LinkButton::createCancel(_('Abbrechen'), URLHelper::getURL('?cancel_x=true'))?>
-            </footer>
-
-            <input type="hidden" name="com" value="do_upload_config">
-            <input type="hidden" name="check_module" value="<?= $module ?>">
-            <input type="hidden" name="config_id" value="<?= $config_id ?>">
-        </form>
-    </td>
-</tr>
-<!-- end of upload extern config -->
-- 
GitLab