From 20240b2aacb15ab3264afbfbbc9dae952db4bb63 Mon Sep 17 00:00:00 2001
From: Elmar Ludwig <elmar.ludwig@uni-osnabrueck.de>
Date: Wed, 11 May 2022 07:19:42 +0000
Subject: [PATCH] convert old core plugins to new model, re #814

Merge request studip/studip!440
---
 .gitignore                                    |   1 -
 app/controllers/activityfeed.php              |  95 ++++++++++
 .../controllers/course/forum}/admin.php       |   5 +-
 .../controllers/course/forum}/area.php        |   8 +-
 .../course/forum}/forum_controller.php        |  26 +--
 .../controllers/course/forum}/index.php       |  86 ++++-----
 .../controllers/course}/messenger.php         |  12 +-
 app/controllers/news.php                      |  14 ++
 app/controllers/quickselection.php            |  45 +++++
 app/routes/Forum.php                          |   8 -
 .../views/activityfeed/configuration.php      |   2 +-
 .../views/course/forum}/admin/childs.php      |   0
 .../views/course/forum}/admin/index.php       |   4 +-
 .../course/forum}/area/_add_area_form.php     |   4 +-
 .../course/forum}/area/_edit_area_form.php    |   4 +-
 .../forum}/area/_edit_category_form.php       |   4 +-
 .../course/forum}/area/_js_templates.php      |   0
 .../views/course/forum}/area/add.php          |  14 +-
 .../views/course/forum}/index/_abo_link.php   |   2 +-
 .../views/course/forum}/index/_areas.php      |  14 +-
 .../views/course/forum}/index/_breadcrumb.php |   4 +-
 .../views/course/forum}/index/_favorite.php   |   4 +-
 .../course/forum}/index/_js_templates.php     |   0
 .../views/course/forum}/index/_last_post.php  |   2 +-
 .../views/course/forum}/index/_like.php       |   4 +-
 .../course/forum}/index/_new_category.php     |   2 +-
 .../views/course/forum}/index/_new_entry.php  |   4 +-
 .../views/course/forum}/index/_post.php       |  28 +--
 .../views/course/forum}/index/_postings.php   |   2 +-
 .../views/course/forum}/index/_preview.php    |   0
 .../course/forum}/index/_smiley_favorites.php |   0
 .../views/course/forum}/index/_threads.php    |  20 +-
 .../views/course/forum}/index/index.php       |  50 ++---
 .../views/course/forum}/messages.php          |   0
 app/views/course/statusgroups/groupinfo.php   |   2 +-
 .../views/quickselection/configuration.php    |   2 +-
 db/migrations/5.2.6_update_core_plugins.php   |  48 +++++
 lib/activities/ForumProvider.php              |   4 +-
 .../calendar}/CalendarWidgetView.php          |   0
 .../Forum/models => lib/classes}/ForumAbo.php |   9 +-
 .../models => lib/classes}/ForumActivity.php  |   0
 .../models => lib/classes}/ForumBulkMail.php  |   2 -
 .../models => lib/classes}/ForumEntry.php     |   0
 .../models => lib/classes}/ForumFavorite.php  |   0
 .../models => lib/classes}/ForumHelpers.php   |   0
 .../models => lib/classes}/ForumIssue.php     |   2 -
 .../models => lib/classes}/ForumLike.php      |   4 +-
 .../models => lib/classes}/ForumPerm.php      |   0
 .../models => lib/classes}/ForumVisit.php     |   0
 .../JsonApi/Routes/Forum/ForumAuthority.php   |   2 -
 .../Routes/Forum/ForumCategoriesShow.php      |   2 -
 lib/classes/Privacy.php                       |   2 -
 .../globalsearch/GlobalSearchForum.php        |   4 +-
 lib/models/BlubberThread.php                  |   2 +-
 .../core/Forum => lib}/models/ForumCat.php    |   0
 lib/modules/ActivityFeed.php                  |  77 ++++++++
 .../Blubber => lib/modules}/Blubber.class.php |  37 ++--
 .../modules}/ContentsWidget.php               |  12 +-
 .../Forum => lib/modules}/CoreForum.class.php |  60 +++---
 .../modules}/EvaluationsWidget.php            |   9 +-
 .../NewsWidget => lib/modules}/NewsWidget.php |  32 +---
 lib/modules/QuickSelection.php                |  57 ++++++
 .../modules}/ScheduleWidget.php               |  11 +-
 .../modules}/TerminWidget.php                 |   9 +-
 lib/plugins/engine/PluginManager.class.php    |   2 +-
 public/plugins.php                            |  11 +-
 .../core/ActivityFeed/ActivityFeed.php        | 171 ------------------
 .../ActivityFeed/javascript/activityfeed.js   | 127 -------------
 .../core/ActivityFeed/plugin.manifest         |   7 -
 .../core/Blubber/plugin.manifest              |  16 --
 .../core/Blubber/views/messenger/course.php   |   1 -
 .../core/ContentsWidget/plugin.manifest       |   6 -
 .../core/EvaluationsWidget/plugin.manifest    |   6 -
 .../core/Forum/plugin.manifest                |  17 --
 .../core/NewsWidget/plugin.manifest           |   6 -
 .../core/QuickSelection/QuickSelection.php    |  99 ----------
 .../core/QuickSelection/plugin.manifest       |   6 -
 .../core/ScheduleWidget/plugin.manifest       |   6 -
 .../core/TerminWidget/plugin.manifest         |   6 -
 resources/assets/javascripts/init.js          |   4 +
 .../assets/javascripts/lib/activityfeed.js    | 127 +++++++++++++
 resources/assets/javascripts/lib/forum.js     |  38 ++--
 .../assets/javascripts/lib/quick_selection.js |   7 +-
 .../assets/stylesheets/less/activityfeed.less |   2 -
 resources/assets/stylesheets/studip.less      |   1 +
 .../mail/forum_notification.php               |   4 +-
 templates/online/user.php                     |   2 +-
 .../start}/_jstemplates.php                   |   0
 .../start/activityfeed.php                    |   2 +-
 .../index.php => templates/start/contents.php |   0
 .../start/quickselection.php                  |   0
 tests/jsonapi/ForumEntriesShowTest.php        |   1 -
 92 files changed, 751 insertions(+), 781 deletions(-)
 create mode 100644 app/controllers/activityfeed.php
 rename {public/plugins_packages/core/Forum/controllers => app/controllers/course/forum}/admin.php (97%)
 rename {public/plugins_packages/core/Forum/controllers => app/controllers/course/forum}/area.php (92%)
 rename {public/plugins_packages/core/Forum/controllers => app/controllers/course/forum}/forum_controller.php (67%)
 rename {public/plugins_packages/core/Forum/controllers => app/controllers/course/forum}/index.php (88%)
 rename {public/plugins_packages/core/Blubber/controllers => app/controllers/course}/messenger.php (82%)
 create mode 100644 app/controllers/quickselection.php
 rename public/plugins_packages/core/ActivityFeed/templates/edit.php => app/views/activityfeed/configuration.php (88%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/admin/childs.php (100%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/admin/index.php (91%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/area/_add_area_form.php (76%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/area/_edit_area_form.php (60%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/area/_edit_category_form.php (62%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/area/_js_templates.php (100%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/area/add.php (82%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_abo_link.php (94%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_areas.php (82%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_breadcrumb.php (69%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_favorite.php (52%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_js_templates.php (100%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_last_post.php (86%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_like.php (80%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_new_category.php (79%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_new_entry.php (91%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_post.php (89%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_postings.php (70%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_preview.php (100%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_smiley_favorites.php (100%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/_threads.php (88%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/index/index.php (81%)
 rename {public/plugins_packages/core/Forum/views => app/views/course/forum}/messages.php (100%)
 rename public/plugins_packages/core/QuickSelection/templates/edit.php => app/views/quickselection/configuration.php (87%)
 create mode 100644 db/migrations/5.2.6_update_core_plugins.php
 rename {public/plugins_packages/core/ScheduleWidget => lib/calendar}/CalendarWidgetView.php (100%)
 rename {public/plugins_packages/core/Forum/models => lib/classes}/ForumAbo.php (94%)
 rename {public/plugins_packages/core/Forum/models => lib/classes}/ForumActivity.php (100%)
 rename {public/plugins_packages/core/Forum/models => lib/classes}/ForumBulkMail.php (99%)
 rename {public/plugins_packages/core/Forum/models => lib/classes}/ForumEntry.php (100%)
 rename {public/plugins_packages/core/Forum/models => lib/classes}/ForumFavorite.php (100%)
 rename {public/plugins_packages/core/Forum/models => lib/classes}/ForumHelpers.php (100%)
 rename {public/plugins_packages/core/Forum/models => lib/classes}/ForumIssue.php (97%)
 rename {public/plugins_packages/core/Forum/models => lib/classes}/ForumLike.php (95%)
 rename {public/plugins_packages/core/Forum/models => lib/classes}/ForumPerm.php (100%)
 rename {public/plugins_packages/core/Forum/models => lib/classes}/ForumVisit.php (100%)
 rename {public/plugins_packages/core/Forum => lib}/models/ForumCat.php (100%)
 create mode 100644 lib/modules/ActivityFeed.php
 rename {public/plugins_packages/core/Blubber => lib/modules}/Blubber.class.php (63%)
 rename {public/plugins_packages/core/ContentsWidget => lib/modules}/ContentsWidget.php (55%)
 rename {public/plugins_packages/core/Forum => lib/modules}/CoreForum.class.php (66%)
 rename {public/plugins_packages/core/EvaluationsWidget => lib/modules}/EvaluationsWidget.php (90%)
 rename {public/plugins_packages/core/NewsWidget => lib/modules}/NewsWidget.php (73%)
 create mode 100644 lib/modules/QuickSelection.php
 rename {public/plugins_packages/core/ScheduleWidget => lib/modules}/ScheduleWidget.php (84%)
 rename {public/plugins_packages/core/TerminWidget => lib/modules}/TerminWidget.php (83%)
 delete mode 100644 public/plugins_packages/core/ActivityFeed/ActivityFeed.php
 delete mode 100644 public/plugins_packages/core/ActivityFeed/javascript/activityfeed.js
 delete mode 100644 public/plugins_packages/core/ActivityFeed/plugin.manifest
 delete mode 100644 public/plugins_packages/core/Blubber/plugin.manifest
 delete mode 100644 public/plugins_packages/core/Blubber/views/messenger/course.php
 delete mode 100644 public/plugins_packages/core/ContentsWidget/plugin.manifest
 delete mode 100644 public/plugins_packages/core/EvaluationsWidget/plugin.manifest
 delete mode 100644 public/plugins_packages/core/Forum/plugin.manifest
 delete mode 100644 public/plugins_packages/core/NewsWidget/plugin.manifest
 delete mode 100644 public/plugins_packages/core/QuickSelection/QuickSelection.php
 delete mode 100644 public/plugins_packages/core/QuickSelection/plugin.manifest
 delete mode 100644 public/plugins_packages/core/ScheduleWidget/plugin.manifest
 delete mode 100644 public/plugins_packages/core/TerminWidget/plugin.manifest
 create mode 100644 resources/assets/javascripts/lib/activityfeed.js
 rename public/plugins_packages/core/QuickSelection/js/QuickSelection.js => resources/assets/javascripts/lib/quick_selection.js (55%)
 rename public/plugins_packages/core/ActivityFeed/css/style.less => resources/assets/stylesheets/less/activityfeed.less (99%)
 rename public/plugins_packages/core/Forum/views/index/_mail_notification.php => templates/mail/forum_notification.php (88%)
 rename {public/plugins_packages/core/ActivityFeed/templates => templates/start}/_jstemplates.php (100%)
 rename public/plugins_packages/core/ActivityFeed/templates/activity_feed.php => templates/start/activityfeed.php (90%)
 rename public/plugins_packages/core/ContentsWidget/templates/index.php => templates/start/contents.php (100%)
 rename public/plugins_packages/core/QuickSelection/templates/list.php => templates/start/quickselection.php (100%)

diff --git a/.gitignore b/.gitignore
index 8ff70233ff2..3791bd154a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,7 +34,6 @@ public/pictures/smile/*.jpg
 public/pictures/smile/*.png
 public/pictures/user/[0-9a-f]*.png
 public/plugins_packages/*
-!public/plugins_packages/core
 
 tests/_log
 tests/_helpers/CodeGuy.php
diff --git a/app/controllers/activityfeed.php b/app/controllers/activityfeed.php
new file mode 100644
index 00000000000..1ea00a06db1
--- /dev/null
+++ b/app/controllers/activityfeed.php
@@ -0,0 +1,95 @@
+<?php
+
+use \Studip\Activity\ActivityProvider;
+
+class ActivityfeedController extends AuthenticatedController
+{
+    public function save_action()
+    {
+        if (Config::get()->ACTIVITY_FEED === NULL) {
+            Config::get()->create('ACTIVITY_FEED', [
+                'range' => 'user',
+                'type' => 'array',
+                'description' => 'Einstellungen des Activity-Widgets']
+            );
+        }
+
+        $provider = Request::getArray('provider');
+
+        WidgetHelper::addWidgetUserConfig($GLOBALS['user']->id, 'ACTIVITY_FEED', $provider);
+
+        $this->response->add_header('X-Dialog-Close', 1);
+        $this->response->add_header('X-Dialog-Execute', 'STUDIP.ActivityFeed.updateFilter');
+
+        $this->render_json($provider);
+    }
+
+    /**
+     * return a list for all providers for every context
+     *
+     * @return array
+     */
+    private function getAllModules()
+    {
+        $modules = [];
+
+        $modules['system'] = [
+            'news'         => _('Ankündigungen'),
+            'blubber'      => _('Blubber')
+        ];
+
+        $modules[Context::COURSE] = [
+            'forum'        => _('Forum'),
+            'participants' => _('Teilnehmende'),
+            'documents'    => _('Dateien'),
+            'wiki'         => _('Wiki'),
+            'schedule'     => _('Ablaufplan'),
+            'news'         => _('Ankündigungen'),
+            'blubber'      => _('Blubber'),
+            'courseware'   => _('Courseware')
+        ];
+
+        $modules[Context::INSTITUTE] = $modules[Context::COURSE];
+        unset($modules[Context::INSTITUTE]['participants']);
+        unset($modules[Context::INSTITUTE]['schedule']);
+
+        $standard_plugins = PluginManager::getInstance()->getPlugins("StandardPlugin");
+        foreach ($standard_plugins as $plugin) {
+            if ($plugin instanceof ActivityProvider) {
+                $modules[Context::COURSE][$plugin->getPluginName()] = $plugin->getPluginName();
+                $modules[Context::INSTITUTE][$plugin->getPluginName()] = $plugin->getPluginName();
+            }
+        }
+
+        $modules[Context::USER] = [
+            'message'      => _('Nachrichten'),
+            'news'         => _('Ankündigungen'),
+            'blubber'      => _('Blubber'),
+        ];
+
+        $homepage_plugins = PluginEngine::getPlugins('HomepagePlugin');
+        foreach ($homepage_plugins as $plugin) {
+            if ($plugin->isActivated($GLOBALS['user']->id, 'user')) {
+                if ($plugin instanceof ActivityProvider) {
+                    $modules[Context::USER][] = $plugin;
+                }
+            }
+        }
+
+        return $modules;
+    }
+
+    public function configuration_action()
+    {
+        $this->config = WidgetHelper::getWidgetUserConfig($GLOBALS['user']->id, 'ACTIVITY_FEED');
+        $this->modules = $this->getAllModules();
+        $this->context_translations = [
+            Context::COURSE    => _('Veranstaltungen'),
+            Context::INSTITUTE => _('Einrichtungen'),
+            Context::USER      => _('Persönlich'),
+            'system'            => _('Global')
+        ];
+
+        PageLayout::setTitle(_('Aktivitäten konfigurieren'));
+    }
+}
diff --git a/public/plugins_packages/core/Forum/controllers/admin.php b/app/controllers/course/forum/admin.php
similarity index 97%
rename from public/plugins_packages/core/Forum/controllers/admin.php
rename to app/controllers/course/forum/admin.php
index 765c2b88b27..a7fff7196e3 100644
--- a/public/plugins_packages/core/Forum/controllers/admin.php
+++ b/app/controllers/course/forum/admin.php
@@ -8,7 +8,10 @@
  * published by the Free Software Foundation; either version 2 of
  * the License, or (at your option) any later version.
  */
-class AdminController extends ForumController
+
+require_once 'forum_controller.php';
+
+class Course_Forum_AdminController extends ForumController
 {
     /* * * * * * * * * * * * * * * * * * * * */
     /* * *   A D M I N   M E T H O D S   * * */
diff --git a/public/plugins_packages/core/Forum/controllers/area.php b/app/controllers/course/forum/area.php
similarity index 92%
rename from public/plugins_packages/core/Forum/controllers/area.php
rename to app/controllers/course/forum/area.php
index df119124e0e..a93860aa5c5 100644
--- a/public/plugins_packages/core/Forum/controllers/area.php
+++ b/app/controllers/course/forum/area.php
@@ -9,7 +9,9 @@
  * the License, or (at your option) any later version.
  */
 
-class AreaController extends ForumController
+require_once 'forum_controller.php';
+
+class Course_Forum_AreaController extends ForumController
 {
     function add_action($category_id)
     {
@@ -38,7 +40,7 @@ class AreaController extends ForumController
             $this->entry = array_pop($entries);
             $this->visitdate = ForumVisit::getLastVisit($this->getId());
         } else {
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/'));
+            $this->redirect('course/forum/index/index/');
         }
     }
 
@@ -52,7 +54,7 @@ class AreaController extends ForumController
         } else {
             ForumEntry::update($area_id, Request::get('name'), Request::get('content'));
             $this->flash['messages'] = ['success' => _('Die Änderungen am Bereich wurden gespeichert.')];
-            $this->redirect(PluginEngine::getLink('coreforum/index/index'));
+            $this->redirect('course/forum/index/index');
         }
 
     }
diff --git a/public/plugins_packages/core/Forum/controllers/forum_controller.php b/app/controllers/course/forum/forum_controller.php
similarity index 67%
rename from public/plugins_packages/core/Forum/controllers/forum_controller.php
rename to app/controllers/course/forum/forum_controller.php
index d25aa554c60..1812be94e7d 100644
--- a/public/plugins_packages/core/Forum/controllers/forum_controller.php
+++ b/app/controllers/course/forum/forum_controller.php
@@ -1,24 +1,7 @@
 <?php
-class ForumController extends StudipController {
-    var $lastlogin = 0;
-
-    // customized #url_for for plugins
-    function url_for($to = '')
-    {
-        $args = func_get_args();
-
-        # find params
-        $params = [];
-        if (is_array(end($args))) {
-            $params = array_pop($args);
-        }
 
-        # urlencode all but the first argument
-        $args = array_map('urlencode', $args);
-        $args[0] = $to;
-
-        return PluginEngine::getURL($this->dispatcher->current_plugin, $params, join('/', $args));
-    }
+class ForumController extends StudipController {
+    protected $with_session = true;
 
     /* * * * * * * * * * * * * * * * * * * * * * * * * */
     /* * * * * H E L P E R   F U N C T I O N S * * * * */
@@ -50,11 +33,6 @@ class ForumController extends StudipController {
         $this->time_format_string = "%a %d. %B %Y, %H:%M";
         $this->time_format_string_short = "%d.%m.%Y, %H:%M";
 
-        $this->template_factory =
-            new Flexi_TemplateFactory(dirname(__FILE__) . '/../templates');
-
-        //$this->check_token();
-
         //$this->getId() depends on Context::get()
         checkObject();
         ForumVisit::setVisit($this->getId());
diff --git a/public/plugins_packages/core/Forum/controllers/index.php b/app/controllers/course/forum/index.php
similarity index 88%
rename from public/plugins_packages/core/Forum/controllers/index.php
rename to app/controllers/course/forum/index.php
index c149e133599..c3b665ead1b 100644
--- a/public/plugins_packages/core/Forum/controllers/index.php
+++ b/app/controllers/course/forum/index.php
@@ -9,7 +9,9 @@
  * the License, or (at your option) any later version.
  */
 
-class IndexController extends ForumController
+require_once 'forum_controller.php';
+
+class Course_Forum_IndexController extends ForumController
 {
     /* * * * * * * * * * * * * * * * * * * * * * * * * */
     /*  V   I   E   W   -   A   C   T   I   O   N   S  */
@@ -22,9 +24,9 @@ class IndexController extends ForumController
     function enter_seminar_action() {
         if (ForumPerm::has('fav_entry', $this->getId())
             && ForumVisit::getCount($this->getId(), ForumVisit::getVisit($this->getId())) > 0) {
-            $this->redirect(PluginEngine::getLink('coreforum/index/newest'));
+            $this->redirect('course/forum/index/newest');
         } else {
-            $this->redirect(PluginEngine::getLink('coreforum/index/index'));
+            $this->redirect('course/forum/index/index');
         }
     }
 
@@ -195,10 +197,6 @@ class IndexController extends ForumController
         $this->number_of_entries = $list['count'];
         $this->show_full_path    = true;
 
-        // set default layout
-        $layout = $GLOBALS['template_factory']->open('layouts/base');
-        $this->set_layout($layout);
-
         if (empty($this->postings)) {
             $this->no_entries = true;
         }
@@ -233,10 +231,6 @@ class IndexController extends ForumController
         $this->number_of_entries = $list['count'];
         $this->show_full_path    = true;
 
-        // set default layout
-        $layout = $GLOBALS['template_factory']->open('layouts/base');
-        $this->set_layout($layout);
-
         if (empty($this->postings)) {
             $this->no_entries = true;
         }
@@ -268,10 +262,6 @@ class IndexController extends ForumController
         $this->number_of_entries = $list['count'];
         $this->show_full_path    = true;
 
-        // set default layout
-        $layout = $GLOBALS['template_factory']->open('layouts/base');
-        $this->set_layout($layout);
-
         if (empty($this->postings)) {
             $this->no_entries = true;
         }
@@ -330,10 +320,6 @@ class IndexController extends ForumController
             }
         }
 
-        // set default layout
-        $layout = $GLOBALS['template_factory']->open('layouts/base');
-        $this->set_layout($layout);
-
         // exploit the visitdate for this view
         $this->visitdate = ForumVisit::getLastVisit($this->getId());
 
@@ -414,7 +400,7 @@ class IndexController extends ForumController
 
         $this->flash['notify'] = $new_id;
 
-        $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $new_id .'#'. $new_id));
+        $this->redirect('course/forum/index/index/' . $new_id .'#'. $new_id);
     }
 
     /**
@@ -442,8 +428,8 @@ class IndexController extends ForumController
                 } else {
                     $this->flash['messages'] = ['info_html' =>
                         sprintf(_('Sind sie sicher dass Sie den Eintrag %s löschen möchten?'), $topic['name'])
-                        . '<br>'. \Studip\LinkButton::createAccept(_('Ja'), PluginEngine::getUrl('coreforum/index/delete_entry/'. $topic_id .'?approve_delete=1'))
-                        . \Studip\LinkButton::createCancel(_('Nein'), PluginEngine::getUrl('coreforum/index/index/'. ForumEntry::getParentTopicId($topic_id) .'/'. $page))
+                        . '<br>'. \Studip\LinkButton::createAccept(_('Ja'), $this->url_for('course/forum/index/delete_entry/'. $topic_id .'?approve_delete=1'))
+                        . \Studip\LinkButton::createCancel(_('Nein'), $this->url_for('course/forum/index/index/'. ForumEntry::getParentTopicId($topic_id) .'/'. $page))
                     ];
                 }
             } else {
@@ -452,10 +438,10 @@ class IndexController extends ForumController
         }
 
         if (Request::isXhr()) {
-            $this->render_template('messages');
+            $this->render_template('course/forum/messages');
             $this->flash['messages'] = null;
         } else {
-            $this->redirect('index/index/' . $parent['id'] .'/'. $page);
+            $this->redirect('course/forum/index/index/' . $parent['id'] .'/'. $page);
         }
     }
 
@@ -486,7 +472,7 @@ class IndexController extends ForumController
                 'content' => formatReady($content)
             ]));
         } else {
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $topic_id .'#'. $topic_id));
+            $this->redirect('course/forum/index/index/' . $topic_id .'#'. $topic_id);
         }
     }
 
@@ -504,7 +490,7 @@ class IndexController extends ForumController
 
         ForumEntry::move($thread_id, $destination);
 
-        $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $current_area .'/'. ForumHelpers::getPage()));
+        $this->redirect('course/forum/index/index/' . $current_area .'/'. ForumHelpers::getPage());
     }
 
     /**
@@ -521,9 +507,9 @@ class IndexController extends ForumController
         if (Request::isXhr()) {
             $this->topic_id = $topic_id;
             $this->favorite = true;
-            $this->render_template('index/_favorite');
+            $this->render_template('course/forum/index/_favorite');
         } else {
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $topic_id .'#'. $topic_id));
+            $this->redirect('course/forum/index/index/' . $topic_id .'#'. $topic_id);
         }
     }
 
@@ -540,9 +526,9 @@ class IndexController extends ForumController
         if (Request::isXhr()) {
             $this->topic_id = $topic_id;
             $this->favorite = false;
-            $this->render_template('index/_favorite');
+            $this->render_template('course/forum/index/_favorite');
         } else {
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $topic_id .'#'. $topic_id));
+            $this->redirect('course/forum/index/index/' . $topic_id .'#'. $topic_id);
         }
     }
 
@@ -558,7 +544,7 @@ class IndexController extends ForumController
     {
         switch ($section) {
             case 'index':
-                $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $topic_id .'/'. (int)$page .'#'. $topic_id));
+                $this->redirect('course/forum/index/index/' . $topic_id .'/'. (int)$page .'#'. $topic_id);
                 break;
 
             case 'search':
@@ -570,12 +556,12 @@ class IndexController extends ForumController
                     }
                 }
 
-                $this->redirect(PluginEngine::getURL('coreforum/index/'. $section .'/'. (int)$page
-                    .'/?searchfor='. Request::get('searchfor') .'&'. implode('&', $optionlist)));
+                $this->redirect('course/forum/index/'. $section .'/'. (int)$page
+                    .'/?searchfor='. Request::get('searchfor') .'&'. implode('&', $optionlist));
                 break;
 
             default:
-                $this->redirect(PluginEngine::getLink('coreforum/index/'. $section .'/'. (int)$page));
+                $this->redirect('course/forum/index/'. $section .'/'. (int)$page);
                 break;
         }
     }
@@ -593,9 +579,9 @@ class IndexController extends ForumController
 
         if (Request::isXhr()) {
             $this->topic_id   = $topic_id;
-            $this->render_template('index/_like');
+            $this->render_template('course/forum/index/_like');
         } else {
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $topic_id .'#'. $topic_id));
+            $this->redirect('course/forum/index/index/' . $topic_id .'#'. $topic_id);
         }
     }
 
@@ -612,9 +598,9 @@ class IndexController extends ForumController
 
         if (Request::isXhr()) {
             $this->topic_id   = $topic_id;
-            $this->render_template('index/_like');
+            $this->render_template('course/forum/index/_like');
         } else {
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $topic_id .'#'. $topic_id));
+            $this->redirect('course/forum/index/index/' . $topic_id .'#'. $topic_id);
         }
     }
 
@@ -637,7 +623,7 @@ class IndexController extends ForumController
             $this->render_text(MessageBox::success($success_text));
         } else {
             $this->flash['messages'] = ['success' => $success_text];
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $redirect . '/' . $page));
+            $this->redirect('course/forum/index/index/' . $redirect . '/' . $page);
         }
     }
 
@@ -660,7 +646,7 @@ class IndexController extends ForumController
             $this->render_text(MessageBox::success($success_text));
         } else {
             $this->flash['messages'] = ['success' => $success_text];
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $redirect . '/' . $page));
+            $this->redirect('course/forum/index/index/' . $redirect . '/' . $page);
         }
     }
 
@@ -683,7 +669,7 @@ class IndexController extends ForumController
             $this->render_text(MessageBox::success($success_text));
         } else {
             $this->flash['messages'] = ['success' => $success_text];
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $redirect . '/' . $page));
+            $this->redirect('course/forum/index/index/' . $redirect . '/' . $page);
         }
     }
 
@@ -706,7 +692,7 @@ class IndexController extends ForumController
             $this->render_text(MessageBox::success($success_text));
         } else {
             $this->flash['messages'] = ['success' => $success_text];
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $redirect . '/' . $page));
+            $this->redirect('course/forum/index/index/' . $redirect . '/' . $page);
         }
     }
 
@@ -727,7 +713,7 @@ class IndexController extends ForumController
 
         ForumPerm::checkCategoryId($this->getId(), $category_id);
 
-        $this->redirect(PluginEngine::getLink('coreforum/index#cat_'. $category_id));
+        $this->redirect('course/forum/index#cat_'. $category_id);
     }
 
     /*
@@ -744,9 +730,9 @@ class IndexController extends ForumController
         ForumCat::remove($category_id, $this->getId());
 
         if (Request::isXhr()) {
-            $this->render_template('messages');
+            $this->render_template('course/forum/messages');
         } else {
-            $this->redirect(PluginEngine::getLink('coreforum/index/index'));
+            $this->redirect('course/forum/index/index');
         }
 
     }
@@ -768,7 +754,7 @@ class IndexController extends ForumController
         } else {
             ForumCat::setName($category_id, Request::get('name'));
             $this->flash['messages'] = ['success' => _('Der Name der Kategorie wurde geändert.')];
-            $this->redirect(PluginEngine::getLink('coreforum/index/index#cat_' . $category_id));
+            $this->redirect('course/forum/index/index#cat_' . $category_id);
         }
 
     }
@@ -803,7 +789,7 @@ class IndexController extends ForumController
         $this->constraint = ForumEntry::getConstraints($topic_id);
 
         if (Request::isXhr()) {
-            $this->render_template('index/_abo_link');
+            $this->render_template('course/forum/index/_abo_link');
         } else {
             switch ($this->constraint['depth']) {
                 case 0:  $msg = _('Sie haben das gesamte Forum abonniert!');break;
@@ -811,7 +797,7 @@ class IndexController extends ForumController
                 default: $msg = _('Sie haben dieses Thema abonniert');break;
             }
             $this->flash['messages'] = ['success' => $msg .' '. _('Sie werden nun über jeden neuen Beitrag informiert.')];
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $topic_id));
+            $this->redirect('course/forum/index/index/' . $topic_id);
         }
     }
 
@@ -828,10 +814,10 @@ class IndexController extends ForumController
 
         if (Request::isXhr()) {
             $this->constraint = ForumEntry::getConstraints($topic_id);
-            $this->render_template('index/_abo_link');
+            $this->render_template('course/forum/index/_abo_link');
         } else {
             $this->flash['messages'] = ['success' => _('Abonnement aufgehoben.')];
-            $this->redirect(PluginEngine::getLink('coreforum/index/index/' . $topic_id));
+            $this->redirect('course/forum/index/index/' . $topic_id);
         }
     }
 
diff --git a/public/plugins_packages/core/Blubber/controllers/messenger.php b/app/controllers/course/messenger.php
similarity index 82%
rename from public/plugins_packages/core/Blubber/controllers/messenger.php
rename to app/controllers/course/messenger.php
index 8f6a0d2a2fb..0bfd3f5e2c3 100644
--- a/public/plugins_packages/core/Blubber/controllers/messenger.php
+++ b/app/controllers/course/messenger.php
@@ -1,10 +1,9 @@
 <?php
-class MessengerController extends PluginController
+class Course_MessengerController extends AuthenticatedController
 {
     public function before_filter(&$action, &$args)
     {
         parent::before_filter($action, $args);
-        $this->assets_url = $this->plugin->getPluginURL() . '/assets/';
 
         PageLayout::setBodyElementId('blubber-index');
         PageLayout::setHelpKeyword("Basis/InteraktionBlubber");
@@ -44,17 +43,12 @@ class MessengerController extends PluginController
         }
         $this->buildSidebar();
 
-        $tf = new Flexi_TemplateFactory($GLOBALS['STUDIP_BASE_PATH']."/app/views");
         if (Request::isDialog()) {
             PageLayout::setTitle($this->thread->getName());
-            $template = $tf->open("blubber/dialog");
+            $this->render_template('blubber/dialog');
         } else {
-            $template = $tf->open("blubber/index");
-            $template->set_layout($GLOBALS['template_factory']->open("layouts/base"));
+            $this->render_template('blubber/index', $this->layout);
         }
-
-        $template->set_attributes($this->get_assigned_variables());
-        $this->render_text($template->render());
     }
 
     protected function buildSidebar()
diff --git a/app/controllers/news.php b/app/controllers/news.php
index 4244b883167..acb43991faa 100644
--- a/app/controllers/news.php
+++ b/app/controllers/news.php
@@ -165,6 +165,20 @@ class NewsController extends StudipController
         $this->render_nothing();
     }
 
+    public function visit_all_action()
+    {
+        $global_news = StudipNews::GetNewsByRange('studip', true);
+
+        if ($GLOBALS['user']->id && $GLOBALS['user']->id !== 'nobody') {
+            foreach ($global_news as $news) {
+                object_add_view($news['news_id']);
+                object_set_visit($news['news_id'], 'news');
+            }
+        }
+
+        $this->render_nothing();
+    }
+
     /**
      * Builds news dialog for editing / adding news
      *
diff --git a/app/controllers/quickselection.php b/app/controllers/quickselection.php
new file mode 100644
index 00000000000..88d24f0c729
--- /dev/null
+++ b/app/controllers/quickselection.php
@@ -0,0 +1,45 @@
+<?php
+
+class QuickselectionController extends AuthenticatedController
+{
+    public function save_action()
+    {
+        if (Config::get()->QUICK_SELECTION === null) {
+            Config::get()->create('QUICK_SELECTION', [
+                'range'       => 'user',
+                'type'        => 'array',
+                'description' => 'Einstellungen des QuickSelection-Widgets',
+            ]);
+        }
+
+        $add_removes = Request::optionArray('add_removes');
+
+        // invert add_removes so that only unchecked values are stored into config
+        $names = [];
+
+        $navigation = Navigation::getItem('/start');
+        foreach ($navigation as $name => $nav) {
+            if (!in_array($name, $add_removes)) {
+                $names[$name] = 'deactivated';
+            }
+
+        }
+
+        WidgetHelper::addWidgetUserConfig($GLOBALS['user']->id, 'QUICK_SELECTION', $names);
+
+        $template = PluginEngine::getPlugin('QuickSelection')->getPortalTemplate();
+
+        $this->response->add_header('X-Dialog-Close', 1);
+        $this->response->add_header('X-Dialog-Execute', 'STUDIP.QuickSelection.update');
+
+        $this->render_template($template);
+    }
+
+    public function configuration_action()
+    {
+        $this->links = Navigation::getItem('/start');
+        $this->config = WidgetHelper::getWidgetUserConfig($GLOBALS['user']->id, 'QUICK_SELECTION');
+
+        PageLayout::setTitle(_('Schnellzugriff konfigurieren'));
+    }
+}
diff --git a/app/routes/Forum.php b/app/routes/Forum.php
index 8d02727e971..d5fd341b6ca 100644
--- a/app/routes/Forum.php
+++ b/app/routes/Forum.php
@@ -10,14 +10,6 @@ namespace RESTAPI\Routes;
  */
 class Forum extends \RESTAPI\RouteMap
 {
-
-    public static function before()
-    {
-        require_once 'public/plugins_packages/core/Forum/models/ForumCat.php';
-        require_once 'public/plugins_packages/core/Forum/models/ForumEntry.php';
-        require_once 'public/plugins_packages/core/Forum/models/ForumPerm.php';
-    }
-
     /**
      * List all categories of a forum
      *
diff --git a/public/plugins_packages/core/ActivityFeed/templates/edit.php b/app/views/activityfeed/configuration.php
similarity index 88%
rename from public/plugins_packages/core/ActivityFeed/templates/edit.php
rename to app/views/activityfeed/configuration.php
index 4fab911351b..945f109fe4c 100644
--- a/public/plugins_packages/core/ActivityFeed/templates/edit.php
+++ b/app/views/activityfeed/configuration.php
@@ -1,5 +1,5 @@
 <div id="activityEdit">
-    <form id="configure_activity" action="<?= PluginEngine::getLink($plugin, [], 'save') ?>" method="post" class="default" data-dialog>
+    <form id="configure_activity" action="<?= $controller->link_for('activityfeed/save') ?>" method="post" class="default" data-dialog>
         <h1><?= _("Anzuzeigende Bereiche:") ?></h1>
 
     <? foreach ($modules as $context => $provider): ?>
diff --git a/public/plugins_packages/core/Forum/views/admin/childs.php b/app/views/course/forum/admin/childs.php
similarity index 100%
rename from public/plugins_packages/core/Forum/views/admin/childs.php
rename to app/views/course/forum/admin/childs.php
diff --git a/public/plugins_packages/core/Forum/views/admin/index.php b/app/views/course/forum/admin/index.php
similarity index 91%
rename from public/plugins_packages/core/Forum/views/admin/index.php
rename to app/views/course/forum/admin/index.php
index 7082e2268cf..154e44c757e 100644
--- a/public/plugins_packages/core/Forum/views/admin/index.php
+++ b/app/views/course/forum/admin/index.php
@@ -21,11 +21,11 @@ Helpbar::get()->addPlainText(
             </a>    
             <br>
 
-            <?= $this->render_partial('admin/childs', compact('entries')) ?>
+            <?= $this->render_partial('course/forum/admin/childs', compact('entries')) ?>
         </li>
     <? endforeach ?>
     </ul>
 </div>
 <noscript>
     <?= MessageBox::error(_('Die Forenadministration funktioniert nur mit eingeschaltetem JavaScript!')) ?>
-</noscript>
\ No newline at end of file
+</noscript>
diff --git a/public/plugins_packages/core/Forum/views/area/_add_area_form.php b/app/views/course/forum/area/_add_area_form.php
similarity index 76%
rename from public/plugins_packages/core/Forum/views/area/_add_area_form.php
rename to app/views/course/forum/area/_add_area_form.php
index f445569cf68..4dd6781d778 100644
--- a/public/plugins_packages/core/Forum/views/area/_add_area_form.php
+++ b/app/views/course/forum/area/_add_area_form.php
@@ -1,13 +1,13 @@
 <tr class="new_area">
     <td class="areaentry"></td>
     <td class="areaentry">
-        <form class="add_area_form" method="post" action="<?= PluginEngine::getLink('coreforum/area/add/' . $category_id) ?>" class="default">
+        <form class="add_area_form" method="post" action="<?= $controller->link_for('course/forum/area/add/' . $category_id) ?>" class="default">
             <?= CSRFProtection::tokenTag() ?>
             <input type="text" name="name" class="size-l no-hint" maxlength="255" placeholder="<?= _('Name des neuen Bereiches') ?>" required><br>
             <textarea name="content" class="size-l" style="height: 3em;" placeholder="<?= _('Optionale Beschreibung des neuen Bereiches') ?>"></textarea>
 
             <?= Studip\Button::create(_('Bereich hinzufügen')) ?>
-            <?= Studip\LinkButton::createCancel(_('Abbrechen'), PluginEngine::getLink('coreforum/index/index#cat_'. $category_id)) ?>
+            <?= Studip\LinkButton::createCancel(_('Abbrechen'), $controller->url_for('course/forum/index/index#cat_'. $category_id)) ?>
         </form>
     </td>
     <td class="postings">0</td>
diff --git a/public/plugins_packages/core/Forum/views/area/_edit_area_form.php b/app/views/course/forum/area/_edit_area_form.php
similarity index 60%
rename from public/plugins_packages/core/Forum/views/area/_edit_area_form.php
rename to app/views/course/forum/area/_edit_area_form.php
index 860406485d8..9919d6986e9 100644
--- a/public/plugins_packages/core/Forum/views/area/_edit_area_form.php
+++ b/app/views/course/forum/area/_edit_area_form.php
@@ -1,7 +1,7 @@
-<form method="post" action="<?= PluginEngine::getLink('coreforum/area/edit/' . $entry['topic_id']) ?>" class="default">
+<form method="post" action="<?= $controller->link_for('course/forum/area/edit/' . $entry['topic_id']) ?>" class="default">
     <input type="text" name="name" class="size-l no-hint" maxlength="255" value="<?= $entry['name_raw'] ?>" onClick="jQuery(this).focus()"><br>
     <textarea name="content" class="size-l" style="height: 3em;" onClick="jQuery(this).focus()"><?= $entry['content_raw'] ?></textarea>
 
     <?= Studip\Button::createAccept(_('Speichern')) ?>
-    <?= Studip\LinkButton::createCancel(_('Abbrechen'), PluginEngine::getLink('coreforum/index')) ?>
+    <?= Studip\LinkButton::createCancel(_('Abbrechen'), $controller->url_for('course/forum/index')) ?>
 </form>
diff --git a/public/plugins_packages/core/Forum/views/area/_edit_category_form.php b/app/views/course/forum/area/_edit_category_form.php
similarity index 62%
rename from public/plugins_packages/core/Forum/views/area/_edit_category_form.php
rename to app/views/course/forum/area/_edit_category_form.php
index 79d9d8756c3..054c8d6a1b5 100644
--- a/public/plugins_packages/core/Forum/views/area/_edit_category_form.php
+++ b/app/views/course/forum/area/_edit_category_form.php
@@ -1,8 +1,8 @@
-<form method="post" action="<?= PluginEngine::getLink('coreforum/index/edit_category/' . $category_id) ?>" class="default">
+<form method="post" action="<?= $controller->link_for('course/forum/index/edit_category/' . $category_id) ?>" class="default">
     <input type="text" required name="name" class="size-m" maxlength="255" value="<?= htmlReady($categories[$category_id]) ?>">
 
     <?= Studip\Button::createAccept(_('Kategorie speichern'), '',
         ['onClick' => "javascript:STUDIP.Forum.saveCategoryName('". $category_id ."'); return false;"]) ?>
-    <?= Studip\LinkButton::createCancel(_('Abbrechen'), PluginEngine::getLink('coreforum/index/index#cat_'. $category_id),
+    <?= Studip\LinkButton::createCancel(_('Abbrechen'), $controller->url_for('course/forum/index/index#cat_'. $category_id),
         ['onClick' => "STUDIP.Forum.cancelEditCategoryName('". $category_id ."'); return false;"]) ?>
 </form>
diff --git a/public/plugins_packages/core/Forum/views/area/_js_templates.php b/app/views/course/forum/area/_js_templates.php
similarity index 100%
rename from public/plugins_packages/core/Forum/views/area/_js_templates.php
rename to app/views/course/forum/area/_js_templates.php
diff --git a/public/plugins_packages/core/Forum/views/area/add.php b/app/views/course/forum/area/add.php
similarity index 82%
rename from public/plugins_packages/core/Forum/views/area/add.php
rename to app/views/course/forum/area/add.php
index ba777fb0534..01cf3dc95ef 100644
--- a/public/plugins_packages/core/Forum/views/area/add.php
+++ b/app/views/course/forum/area/add.php
@@ -4,7 +4,7 @@
         <?= Assets::img('anfasser_48.png', ['class' => 'handle js']) ?>
     <? endif ?>
 
-        <a href="<?= $controller->link_for("index/index/{$entry['topic_id']}#{$entry['topic_id']}") ?>">
+        <a href="<?= $controller->link_for("course/forum/index/index/{$entry['topic_id']}#{$entry['topic_id']}") ?>">
         <? if ($entry['chdate'] >= $visitdate && $entry['user_id'] !== $GLOBALS['user']->id): ?>
             <?= Icon::create('forum+new', Icon::ROLE_ATTENTION)->asImg([
                 'title' => _('Dieser Eintrag ist neu!'),
@@ -23,7 +23,7 @@
         <div style="position: relative;<?= Request::get('edit_area') == $entry['topic_id'] ? 'height: auto;' : '' ?>">
 
             <span class="areadata" <?= Request::get('edit_area') != $entry['topic_id'] ? '' : 'style="display: none;"' ?>>
-                <a href="<?= $controller->link_for("index/index/{$entry['topic_id']}#{$entry['topic_id']}") ?>">
+                <a href="<?= $controller->link_for("course/forum/index/index/{$entry['topic_id']}#{$entry['topic_id']}") ?>">
                     <span class="areaname"><?= htmlReady($entry['name_raw']) ?></span>
                 </a>
                 <div class="areacontent" data-content="<?= htmlReady($entry['content_raw']) ?>">
@@ -36,7 +36,7 @@
             <? if (ForumPerm::has('edit_area', $seminar_id) && Request::get('edit_area') == $entry['topic_id']) : ?>
             <span style="text-align: center;">
                 <div style="width: 90%">
-                    <?= $this->render_partial('area/_edit_area_form', compact('entry')) ?>
+                    <?= $this->render_partial('course/forum/area/_edit_area_form', compact('entry')) ?>
                 </div>
             </span>
             <? endif ?>
@@ -48,12 +48,12 @@
     </td>
 
     <td class="answer hidden-tiny-down">
-        <?= $this->render_partial('index/_last_post.php', compact('entry')) ?>
+        <?= $this->render_partial('course/forum/index/_last_post.php', compact('entry')) ?>
     </td>
 
     <td class="actions">
         <?= ActionMenu::get()->addLink(
-            $controller->url_for("index/index/{$entry['last_posting']['topic_id']}#{$entry['last_posting']['topic_id']}"),
+            $controller->url_for("course/forum/index/index/{$entry['last_posting']['topic_id']}#{$entry['last_posting']['topic_id']}"),
             _('Zur letzten Antwort'),
             Icon::create('forum'),
             is_array($entry['last_posting']) ? ['class' => 'hidden-small-up'] : ['disabled' => '']
@@ -65,7 +65,7 @@
             ['title' => _('Dieser Bereich ist einem Thema zugeordnet und kann hier nicht editiert werden. Die Angaben können im Ablaufplan angepasst werden.')]
         )->condition(ForumPerm::has('edit_area', $seminar_id) && !$issue_id)
         ->addLink(
-            $controller->url_for('index', ['edit_area' => $entry['topic_id']]),
+            $controller->url_for('course/forum/index', ['edit_area' => $entry['topic_id']]),
             _('Name/Beschreibung des Bereichs ändern'),
             Icon::create('edit'),
             [
@@ -74,7 +74,7 @@
             ]
         )->condition(ForumPerm::has('remove_area', $seminar_id))
         ->addLink(
-            $controller->url_for("index/delete_entry/{$entry['topic_id']}"),
+            $controller->url_for("course/forum/index/delete_entry/{$entry['topic_id']}"),
             _('Bereich mitsamt allen Einträgen löschen!'),
             Icon::create('trash'),
             [
diff --git a/public/plugins_packages/core/Forum/views/index/_abo_link.php b/app/views/course/forum/index/_abo_link.php
similarity index 94%
rename from public/plugins_packages/core/Forum/views/index/_abo_link.php
rename to app/views/course/forum/index/_abo_link.php
index fee4559994d..ccd689a5ddd 100644
--- a/public/plugins_packages/core/Forum/views/index/_abo_link.php
+++ b/app/views/course/forum/index/_abo_link.php
@@ -2,7 +2,7 @@
          . (ForumAbo::has($constraint['topic_id']) ? 'remove_' : '') 
          . 'abo/'. $constraint['topic_id'] ."'); return false;";
 
-    $url = PluginEngine::getUrl('coreforum/index/'
+    $url = $controller->url_for('course/forum/index/'
          . (ForumAbo::has($constraint['topic_id']) ? 'remove_' : '') 
          . 'abo/'. $constraint['topic_id']);
 ?>
diff --git a/public/plugins_packages/core/Forum/views/index/_areas.php b/app/views/course/forum/index/_areas.php
similarity index 82%
rename from public/plugins_packages/core/Forum/views/index/_areas.php
rename to app/views/course/forum/index/_areas.php
index e5f7171e04b..20aa3458f69 100644
--- a/public/plugins_packages/core/Forum/views/index/_areas.php
+++ b/app/views/course/forum/index/_areas.php
@@ -16,14 +16,14 @@
                     . ' Für Autor/innen taucht sie allerdings nur auf, wenn sie Bereiche enthält.')) ?>
             <? else : ?>
                 <? if (ForumPerm::has('edit_category', $seminar_id)) : ?>
-                <a href="<?= PluginEngine::getLink('coreforum/index/?edit_category=' . $category_id) ?>"
+                <a href="<?= $controller->link_for('course/forum/index/?edit_category=' . $category_id) ?>"
                     onClick="javascript:STUDIP.Forum.editCategoryName('<?= $category_id ?>'); return false;">
                     <?= Icon::create('edit', Icon::ROLE_CLICKABLE, ['title' => 'Name der Kategorie ändern'])->asImg() ?>
                 </a>
                 <? endif ?>
 
                 <? if(ForumPerm::has('remove_category', $seminar_id)) : ?>
-                <a href="<?= PluginEngine::getLink('coreforum/index/remove_category/' . $category_id) ?>"
+                <a href="<?= $controller->link_for('course/forum/index/remove_category/' . $category_id) ?>"
                     onClick="STUDIP.Forum.deleteCategory('<?= $category_id ?>'); return false;">
                     <?= Icon::create('trash', Icon::ROLE_CLICKABLE, ['title' => 'Kategorie entfernen'])->asImg() ?>
                 </a>
@@ -34,7 +34,7 @@
 
         <span id="tutorCategory" class="category_name">
             <? if (Request::get('edit_category') == $category_id) : ?>
-                <?= $this->render_partial('area/_edit_category_form', compact('category_id', 'categories')) ?>
+                <?= $this->render_partial('course/forum/area/_edit_category_form', compact('category_id', 'categories')) ?>
             <? else : ?>
                 <?= htmlReady($categories[$category_id]) ?>
             <? endif ?>
@@ -64,11 +64,11 @@
     <tbody class="sortable">
 
     <? if (!empty($entries)) foreach ($entries as $entry) : ?>
-        <?= $this->render_partial('area/add', compact('entry')) ?>
+        <?= $this->render_partial('course/forum/area/add', compact('entry')) ?>
     <? endforeach; ?>
 
     <? if ($category_id && ForumPerm::has('add_area', $seminar_id) && Request::get('add_area') == $category_id) : ?>
-        <?= $this->render_partial('area/_add_area_form') ?>
+        <?= $this->render_partial('course/forum/area/_add_area_form') ?>
     <? endif ?>
 
     <? if (!$entries): ?>
@@ -84,7 +84,7 @@
     <? if (Request::get('add_area') != $category_id) : ?>
     <tr class="add_area">
         <td colspan="5" onClick="STUDIP.Forum.addArea('<?= $category_id ?>'); return false;" class="add_area">
-            <a href="<?= $controller->link_for('index/index/?add_area=' . $category_id)?>#cat_<?= $category_id ?>"  title="<?= _('Neuen Bereich zu dieser Kategorie hinzufügen.') ?>">
+            <a href="<?= $controller->link_for('course/forum/index/index/?add_area=' . $category_id)?>#cat_<?= $category_id ?>"  title="<?= _('Neuen Bereich zu dieser Kategorie hinzufügen.') ?>">
                 <span><?= _('Bereich hinzufügen') ?></span>
                 <?= Icon::create('add')->asImg(["id" => 'tutorAddArea']) ?>
             </a>
@@ -99,4 +99,4 @@
 <? endforeach ?>
 </div>
 
-<?= $this->render_partial('area/_js_templates') ?>
+<?= $this->render_partial('course/forum/area/_js_templates') ?>
diff --git a/public/plugins_packages/core/Forum/views/index/_breadcrumb.php b/app/views/course/forum/index/_breadcrumb.php
similarity index 69%
rename from public/plugins_packages/core/Forum/views/index/_breadcrumb.php
rename to app/views/course/forum/index/_breadcrumb.php
index 2f7738bd35b..0b3a9b4b51f 100644
--- a/public/plugins_packages/core/Forum/views/index/_breadcrumb.php
+++ b/app/views/course/forum/index/_breadcrumb.php
@@ -1,13 +1,13 @@
 <? if ($section == 'index' || !$section) : ?>
 <div id="tutorBreadcrumb">
     <? $path = ForumEntry::getPathToPosting($topic_id) ?>
-    <a href="<?= PluginEngine::getURL('coreforum/index') ?>" title="<?= _('Übersicht') ?>">
+    <a href="<?= $controller->link_for('course/forum/index') ?>" title="<?= _('Übersicht') ?>">
         <?= Icon::create('forum', 'clickable') ?>
     </a>
 
     <? foreach ($path as $path_part) : ?>
         <? if (sizeof($path) > 1) :?>/<? endif ?>
-        <a href="<?= PluginEngine::getLink('coreforum/index/index/' . $path_part['id']) ?>">
+        <a href="<?= $controller->link_for('course/forum/index/index/' . $path_part['id']) ?>">
             <?= htmlReady(ForumEntry::killFormat($path_part['name'])) ?>
         </a>
         <? $first = false ?>
diff --git a/public/plugins_packages/core/Forum/views/index/_favorite.php b/app/views/course/forum/index/_favorite.php
similarity index 52%
rename from public/plugins_packages/core/Forum/views/index/_favorite.php
rename to app/views/course/forum/index/_favorite.php
index f6bd4cbbb49..63da1166a17 100644
--- a/public/plugins_packages/core/Forum/views/index/_favorite.php
+++ b/app/views/course/forum/index/_favorite.php
@@ -2,11 +2,11 @@
 
 <!-- set/unset favorite -->
 <? if (!$favorite) : ?>
-    <a href="<?= PluginEngine::getLink('coreforum/index/set_favorite/'. $topic_id) ?>" onClick="STUDIP.Forum.setFavorite('<?= $topic_id ?>');return false;">
+    <a href="<?= $controller->link_for('course/forum/index/set_favorite/'. $topic_id) ?>" onClick="STUDIP.Forum.setFavorite('<?= $topic_id ?>');return false;">
         <?= Icon::create('staple', 'clickable', ['title' => _('Beitrag merken')])->asImg() ?>
     </a>
 <? else : ?>
-    <a href="<?= PluginEngine::getLink('coreforum/index/unset_favorite/'. $topic_id) ?>" onClick="STUDIP.Forum.unsetFavorite('<?= $topic_id ?>');return false;">
+    <a href="<?= $controller->link_for('course/forum/index/unset_favorite/'. $topic_id) ?>" onClick="STUDIP.Forum.unsetFavorite('<?= $topic_id ?>');return false;">
         <?= Icon::create('staple', 'attention', ['title' => _('Beitrag nicht mehr merken')])->asImg() ?>
     </a>
 <? endif ?>
diff --git a/public/plugins_packages/core/Forum/views/index/_js_templates.php b/app/views/course/forum/index/_js_templates.php
similarity index 100%
rename from public/plugins_packages/core/Forum/views/index/_js_templates.php
rename to app/views/course/forum/index/_js_templates.php
diff --git a/public/plugins_packages/core/Forum/views/index/_last_post.php b/app/views/course/forum/index/_last_post.php
similarity index 86%
rename from public/plugins_packages/core/Forum/views/index/_last_post.php
rename to app/views/course/forum/index/_last_post.php
index 956c6c1403a..50c5eb204b2 100644
--- a/public/plugins_packages/core/Forum/views/index/_last_post.php
+++ b/app/views/course/forum/index/_last_post.php
@@ -11,7 +11,7 @@
     <br>
     <?= _('am') ?>
     <?= strftime($time_format_string_short, (int) $entry['last_posting']['date']) ?>
-    <a href="<?= $controller->link_for("index/index/{$entry['last_posting']['topic_id']}#{$entry['last_posting']['topic_id']}") ?>">
+    <a href="<?= $controller->link_for("course/forum/index/index/{$entry['last_posting']['topic_id']}#{$entry['last_posting']['topic_id']}") ?>">
         <?= Icon::create('link-intern')->asImg([
             'title' => _('Direkt zum Beitrag...'),
         ]) ?>
diff --git a/public/plugins_packages/core/Forum/views/index/_like.php b/app/views/course/forum/index/_like.php
similarity index 80%
rename from public/plugins_packages/core/Forum/views/index/_like.php
rename to app/views/course/forum/index/_like.php
index c876311b3f7..eac19a27636 100644
--- a/public/plugins_packages/core/Forum/views/index/_like.php
+++ b/app/views/course/forum/index/_like.php
@@ -37,11 +37,11 @@ endif ?>
 
 <!-- like/dislike links -->
 <? if (!in_array($GLOBALS['user']->id, $likes)) : ?>
-    <a href="<?= PluginEngine::getLink('coreforum/index/like/'. $topic_id) ?>" onClick="jQuery('#like_<?= $topic_id ?>').load('<?= PluginEngine::getLink('coreforum/index/like/'. $topic_id) ?>'); return false;">
+    <a href="<?= $controller->link_for('course/forum/index/like/'. $topic_id) ?>" onClick="jQuery('#like_<?= $topic_id ?>').load('<?= $controller->link_for('course/forum/index/like/'. $topic_id) ?>'); return false;">
         <?= _('Gefällt mir!'); ?>
     </a>
 <? else : ?>
-    <a href="<?= PluginEngine::getLink('coreforum/index/dislike/'. $topic_id) ?>" onClick="jQuery('#like_<?= $topic_id ?>').load('<?= PluginEngine::getLink('coreforum/index/dislike/'. $topic_id) ?>'); return false;">
+    <a href="<?= $controller->link_for('course/forum/index/dislike/'. $topic_id) ?>" onClick="jQuery('#like_<?= $topic_id ?>').load('<?= $controller->link_for('course/forum/index/dislike/'. $topic_id) ?>'); return false;">
         <?= _('Gefällt mir nicht mehr!'); ?>
     </a>
 <? endif ?>
diff --git a/public/plugins_packages/core/Forum/views/index/_new_category.php b/app/views/course/forum/index/_new_category.php
similarity index 79%
rename from public/plugins_packages/core/Forum/views/index/_new_category.php
rename to app/views/course/forum/index/_new_category.php
index f633d44db2c..7048a6c09e1 100644
--- a/public/plugins_packages/core/Forum/views/index/_new_category.php
+++ b/app/views/course/forum/index/_new_category.php
@@ -1,6 +1,6 @@
 <? if (ForumPerm::has('add_category', $seminar_id)) : ?>
 <a name="create"></a>
-<form action="<?= PluginEngine::getLink('coreforum/index/add_category') ?>" method="post" id="tutorAddCategory" class="default">
+<form action="<?= $controller->link_for('course/forum/index/add_category') ?>" method="post" id="tutorAddCategory" class="default">
     <?= CSRFProtection::tokenTag() ?>
     <fieldset>
         <legend><?= _('Neue Kategorie erstellen') ?></legend>
diff --git a/public/plugins_packages/core/Forum/views/index/_new_entry.php b/app/views/course/forum/index/_new_entry.php
similarity index 91%
rename from public/plugins_packages/core/Forum/views/index/_new_entry.php
rename to app/views/course/forum/index/_new_entry.php
index a926a3f3cee..7c2a9abe39e 100644
--- a/public/plugins_packages/core/Forum/views/index/_new_entry.php
+++ b/app/views/course/forum/index/_new_entry.php
@@ -2,7 +2,7 @@
 <script type="text/html" class="new_entry_box">
     <div class="forum_new_entry" data-id="<%- topic_id %>">
         <a name="create"></a>
-        <form action="<?= PluginEngine::getLink('coreforum/index/add_entry') ?>" method="post" id="forum_new_entry" onSubmit="$(window).off('beforeunload')" class="default">
+        <form action="<?= $controller->link_for('course/forum/index/add_entry') ?>" method="post" id="forum_new_entry" onSubmit="$(window).off('beforeunload')" class="default">
             <fieldset>
                 <legend>
                     <? if ($constraint['depth'] == 1) : ?>
@@ -61,7 +61,7 @@
             <?= CSRFProtection::tokenTag() ?>
         </form>
 
-        <?= $this->render_partial('index/_preview', ['preview_id' => 'new_entry_preview']) ?>
+        <?= $this->render_partial('course/forum/index/_preview', ['preview_id' => 'new_entry_preview']) ?>
         <br>
     </div>
 </script>
diff --git a/public/plugins_packages/core/Forum/views/index/_post.php b/app/views/course/forum/index/_post.php
similarity index 89%
rename from public/plugins_packages/core/Forum/views/index/_post.php
rename to app/views/course/forum/index/_post.php
index 21a2dc3e854..2e78b113425 100644
--- a/public/plugins_packages/core/Forum/views/index/_post.php
+++ b/app/views/course/forum/index/_post.php
@@ -14,11 +14,11 @@
 <!-- Anker, um zu diesem Posting springen zu können -->
 <a name="<?= $post['topic_id'] ?>"></a>
 
-<form method="post" data-topicid="<?= $post['topic_id'] ?>" action="<?= PluginEngine::getLink('coreforum/index/update_entry/' . $post['topic_id']) ?>">
+<form method="post" data-topicid="<?= $post['topic_id'] ?>" action="<?= $controller->link_for('course/forum/index/update_entry/' . $post['topic_id']) ?>">
     <?= CSRFProtection::tokenTag() ?>
 
 <div class="real_posting posting<?= $highlight_topic == $post['topic_id'] ? ' highlight' : '' ?>" style="position: relative;" id="forumposting_<?= htmlReady($post['topic_id']) ?>">
-    <a class="marked" href="<?= PluginEngine::getLink('coreforum/index/unset_favorite/'. $post['topic_id']) ?>"
+    <a class="marked" href="<?= $controller->link_for('course/forum/index/unset_favorite/'. $post['topic_id']) ?>"
             onClick="STUDIP.Forum.unsetFavorite('<?= $post['topic_id'] ?>'); return false;" title="<?= _('Beitrag nicht mehr merken') ?>"
             <?= ($post['fav']) ?: 'style="display: none;"' ?> data-topic-id="<?= $post['topic_id'] ?>">
         <div></div>
@@ -70,7 +70,7 @@
             <? endif ?>
 
             <span data-show-topic="<?= $post['topic_id'] ?>">
-                <a href="<?= PluginEngine::getLink('coreforum/index/index/' . $post['topic_id'] .'?'. http_build_query(['highlight' => $highlight]) ) ?>#<?= $post['topic_id'] ?>">
+                <a href="<?= $controller->link_for('course/forum/index/index/' . $post['topic_id'] .'?'. http_build_query(['highlight' => $highlight]) ) ?>#<?= $post['topic_id'] ?>">
                 <? if ($show_full_path) : ?>
                     <?= ForumHelpers::highlight(htmlReady(implode(' >> ', ForumEntry::getFlatPathToPosting($post['topic_id']))), $highlight) ?>
                 <? elseif ($post['depth'] < 3) : ?>
@@ -105,7 +105,7 @@
             <?= Studip\Button::createAccept(_('Änderungen speichern'), '',
                 ['onClick' => "STUDIP.Forum.saveEntry('". $post['topic_id'] ."'); return false;"]) ?>
 
-            <?= Studip\LinkButton::createCancel(_('Abbrechen'), PluginEngine::getLink('coreforum/index/index/'. $post['topic_id'] .'#'. $post['topic_id']),
+            <?= Studip\LinkButton::createCancel(_('Abbrechen'), $controller->link_for('course/forum/index/index/'. $post['topic_id'] .'#'. $post['topic_id']),
                 ['onClick' => "STUDIP.Forum.cancelEditEntry('". $post['topic_id'] ."'); return false;"]) ?>
 
             <?= Studip\LinkButton::create(_('Vorschau'), "javascript:STUDIP.Forum.preview('". $post['topic_id'] ."', 'preview_". $post['topic_id'] ."');") ?>
@@ -116,7 +116,7 @@
 
 
             <? if (ForumPerm::has('add_entry', $constraint['seminar_id'])) : ?>
-                <?= Studip\LinkButton::create(_('Beitrag zitieren'), PluginEngine::getURL('coreforum/index/index/' . $post['topic_id'] .'?cite=1'), [
+                <?= Studip\LinkButton::create(_('Beitrag zitieren'), $controller->url_for('course/forum/index/index/' . $post['topic_id'] .'?cite=1'), [
                     'onClick' => "javascript:STUDIP.Forum.citeEntry('". $post['topic_id'] ."'); return false;",
                     'class'   => !$perms['edit_closed'] ? 'hideWhenClosed' : '',
                     'style'   => !$can_edit_closed ? 'display: none' : ''
@@ -124,7 +124,7 @@
             <? endif ?>
 
             <? if ($perms['edit']) : ?>
-                <?= Studip\LinkButton::create(_('Beitrag bearbeiten'), PluginEngine::getUrl('coreforum/index/index/'
+                <?= Studip\LinkButton::create(_('Beitrag bearbeiten'), $controller->url_for('course/forum/index/index/'
                       . $post['topic_id'] .'/?edit_posting=' . $post['topic_id']), [
                           'onClick' => "STUDIP.Forum.editEntry('". $post['topic_id'] ."'); return false;",
                           'class'   => !$perms['edit_closed'] ? 'hideWhenClosed' : '',
@@ -134,8 +134,8 @@
 
             <span <?= (!$perms['edit_close'] && !$perms['remove_entry']) ? 'class="hideWhenClosed"': '' ?>
                 <?= (!$perms['edit'] && !$perms['remove_entry']) ? 'style="display: none"' : '' ?>>
-                <? $confirmLink = PluginEngine::getURL('coreforum/index/delete_entry/' . $post['topic_id'])  ?>
-                <? $confirmLinkApproved = PluginEngine::getURL('coreforum/index/delete_entry/' .
+                <? $confirmLink = $controller->url_for('course/forum/index/delete_entry/' . $post['topic_id'])  ?>
+                <? $confirmLinkApproved = $controller->url_for('course/forum/index/delete_entry/' .
                     $post['topic_id'] . '?approve_delete=1&section=' . $section .'&page=' . ForumHelpers::getPage())  ?>
                 <? if ($constraint['depth'] == $post['depth']) : /* this is not only a posting, but a thread */ ?>
                     <? $confirmText = _('Wenn Sie diesen Beitrag löschen wird ebenfalls das gesamte Thema gelöscht. Sind Sie sicher, dass Sie das tun möchten?')  ?>
@@ -163,7 +163,7 @@
         <dl class="postprofile">
             <dt>
                 <? if (!Config::get()->WYSIWYG): ?>
-                    <?= $this->render_partial('index/_smiley_favorites', ['textarea_id' => $post['topic_id']]) ?>
+                    <?= $this->render_partial('course/forum/index/_smiley_favorites', ['textarea_id' => $post['topic_id']]) ?>
                 <? endif; ?>
             </dt>
         </dl>
@@ -232,23 +232,23 @@
             <dd class="posting_icons">
                 <!-- Favorit -->
                 <span id="favorite_<?= $post['topic_id'] ?>">
-                    <?= $this->render_partial('index/_favorite', ['topic_id' => $post['topic_id'], 'favorite' => $post['fav']]) ?>
+                    <?= $this->render_partial('course/forum/index/_favorite', ['topic_id' => $post['topic_id'], 'favorite' => $post['fav']]) ?>
                 </span>
 
                 <!-- Permalink -->
-                <a href="<?= PluginEngine::getLink('coreforum/index/index/' . $post['topic_id'] .'#'. $post['topic_id']) ?>">
+                <a href="<?= $controller->link_for('course/forum/index/index/' . $post['topic_id'] .'#'. $post['topic_id']) ?>">
                     <?= Icon::create('group', 'clickable', ['title' => _('Link zu diesem Beitrag')])->asImg() ?>
                 </a>
                 <br>
 
                 <!-- Like -->
                 <span class="likes" id="like_<?= $post['topic_id'] ?>">
-                    <?= $this->render_partial('index/_like', ['topic_id' => $post['topic_id']]) ?>
+                    <?= $this->render_partial('course/forum/index/_like', ['topic_id' => $post['topic_id']]) ?>
                 </span>
             </dd>
 
             <? foreach (PluginEngine::sendMessage('PostingApplet', 'getHTML', $post['name_raw'], $post['content_raw'],
-                    PluginEngine::getLink('coreforum/index/index/' . $post['topic_id'] .'#'. $post['topic_id']),
+                    $controller->link_for('course/forum/index/index/' . $post['topic_id'] .'#'. $post['topic_id']),
                     $post['user_id']) as $applet_data) : ?>
             <dd>
                 <?= $applet_data ?>
@@ -267,4 +267,4 @@
 </div>
 </form>
 
-<?= $this->render_partial('index/_preview', ['preview_id' => 'preview_' . $post['topic_id']]) ?>
+<?= $this->render_partial('course/forum/index/_preview', ['preview_id' => 'preview_' . $post['topic_id']]) ?>
diff --git a/public/plugins_packages/core/Forum/views/index/_postings.php b/app/views/course/forum/index/_postings.php
similarity index 70%
rename from public/plugins_packages/core/Forum/views/index/_postings.php
rename to app/views/course/forum/index/_postings.php
index a2ca6d2f0fe..1888ae07fa6 100644
--- a/public/plugins_packages/core/Forum/views/index/_postings.php
+++ b/app/views/course/forum/index/_postings.php
@@ -6,7 +6,7 @@ if (!$section) $section = 'index';
 
 foreach ($postings as $post) :
     // show the line only once and do not show it before the first posting of a thread
-    echo $this->render_partial('index/_post', compact('post', 'visitdate', 'section'));
+    echo $this->render_partial('course/forum/index/_post', compact('post', 'visitdate', 'section'));
 
     $posting_num++;
 endforeach
diff --git a/public/plugins_packages/core/Forum/views/index/_preview.php b/app/views/course/forum/index/_preview.php
similarity index 100%
rename from public/plugins_packages/core/Forum/views/index/_preview.php
rename to app/views/course/forum/index/_preview.php
diff --git a/public/plugins_packages/core/Forum/views/index/_smiley_favorites.php b/app/views/course/forum/index/_smiley_favorites.php
similarity index 100%
rename from public/plugins_packages/core/Forum/views/index/_smiley_favorites.php
rename to app/views/course/forum/index/_smiley_favorites.php
diff --git a/public/plugins_packages/core/Forum/views/index/_threads.php b/app/views/course/forum/index/_threads.php
similarity index 88%
rename from public/plugins_packages/core/Forum/views/index/_threads.php
rename to app/views/course/forum/index/_threads.php
index d3ca4a228de..97f0c4c1dd6 100644
--- a/public/plugins_packages/core/Forum/views/index/_threads.php
+++ b/app/views/course/forum/index/_threads.php
@@ -38,7 +38,7 @@
                 <tr data-area-id="<?= $entry['topic_id'] ?>">
 
                     <td class="icon">
-                        <a href="<?= $controller->link_for("index/index/{$jump_to_topic_id}#{$jump_to_topic_id}") ?>">
+                        <a href="<?= $controller->link_for("course/forum/index/index/{$jump_to_topic_id}#{$jump_to_topic_id}") ?>">
                             <? if ($entry['chdate'] >= $visitdate && $entry['user_id'] != $GLOBALS['user']->id): ?>
                                 <?= Icon::create('forum+new', Icon::ROLE_ATTENTION)->asImg([
                                     'title' => _('Dieser Eintrag ist neu!'),
@@ -68,7 +68,7 @@
 
                     <td class="areaentry">
                         <div style="position: relative;">
-                            <a href="<?= $controller->link_for('index/index/' . $entry['topic_id'] . '#' . $entry['topic_id']) ?>">
+                            <a href="<?= $controller->link_for('course/forum/index/index/' . $entry['topic_id'] . '#' . $entry['topic_id']) ?>">
                                 <span class="areaname"><?= htmlReady($entry['name_raw'] ?: _('Ohne Titel')) ?></span>
                             </a>
 
@@ -93,13 +93,13 @@
                     </td>
 
                     <td class="answer hidden-tiny-down">
-                        <?= $this->render_partial('index/_last_post.php', compact('entry')) ?>
+                        <?= $this->render_partial('course/forum/index/_last_post.php', compact('entry')) ?>
                     </td>
 
                     <td class="actions">
                         <?= ActionMenu::get()
                             ->addLink(
-                                $controller->url_for("index/index/{$entry['last_posting']['topic_id']}#{$entry['last_posting']['topic_id']}"),
+                                $controller->url_for("course/forum/index/index/{$entry['last_posting']['topic_id']}#{$entry['last_posting']['topic_id']}"),
                                 _('Zur letzten Antwort'),
                                 Icon::create('forum'),
                                 ['class' => 'hidden-small-up']
@@ -108,14 +108,14 @@
                             ->conditionAll(ForumPerm::has('make_sticky', $seminar_id) && $constraint['depth'] >= 1)
                             ->condition(!$entry['sticky'])
                             ->addLink(
-                                $controller->url_for('index/make_sticky', $entry['topic_id'], $constraint['topic_id'], 0),
+                                $controller->url_for('course/forum/index/make_sticky', $entry['topic_id'], $constraint['topic_id'], 0),
                                 _('Thema hervorheben'),
                                 Icon::create('staple'),
                                 ['id' => "stickyButton-{$entry['topic_id']}"]
                             )
                             ->condition($entry['sticky'])
                             ->addLink(
-                                $controller->url_for('index/make_unsticky', $entry['topic_id'], $constraint['topic_id'], 0),
+                                $controller->url_for('course/forum/index/make_unsticky', $entry['topic_id'], $constraint['topic_id'], 0),
                                 _('Hervorhebung aufheben'),
                                 Icon::create('staple'),
                                 ['id' => "stickyButton-{$entry['topic_id']}"]
@@ -133,7 +133,7 @@
                             ->conditionAll(ForumPerm::has('close_thread', $seminar_id) && $constraint['depth'] >= 1)
                             ->condition(!$entry['closed'])
                             ->addLink(
-                                $controller->url_for('index/close_thread', $entry['topic_id'], $constraint['topic_id'], ForumHelpers::getPage()),
+                                $controller->url_for('course/forum/index/close_thread', $entry['topic_id'], $constraint['topic_id'], ForumHelpers::getPage()),
                                 _('Thema schließen'),
                                 Icon::create('lock-locked'),
                                 [
@@ -143,7 +143,7 @@
                             )
                             ->condition($entry['closed'])
                             ->addLink(
-                                $controller->url_for('index/open_thread', $entry['topic_id'], $constraint['topic_id'], ForumHelpers::getPage()),
+                                $controller->url_for('course/forum/index/open_thread', $entry['topic_id'], $constraint['topic_id'], ForumHelpers::getPage()),
                                 _('Thema öffnen'),
                                 Icon::create('lock-unlocked'),
                                 [
@@ -159,7 +159,7 @@
                                 _('Dieses Thema löschen'),
                                 Icon::create('trash'),
                                 [
-                                    'formaction' => $controller->url_for("index/delete_entry/{$entry['topic_id']}"),
+                                    'formaction' => $controller->url_for("course/forum/index/delete_entry/{$entry['topic_id']}"),
                                     'data-confirm' => sprintf(
                                         _('Sind sie sicher dass Sie den Eintrag %s löschen möchten?'),
                                         htmlReady($entry['name'])
@@ -178,7 +178,7 @@
                                 <? foreach ($areas['list'] as $area_id => $area): ?>
                                     <? if ($area_id != $parent['id']) : ?>
                                         <div style="font-size: 16px; margin-bottom: 5px;">
-                                            <a href="<?= PluginEngine::getLink('coreforum/index/move_thread/' . $entry['topic_id'] . '/' . $area_id) ?>">
+                                            <a href="<?= $controller->link_for('course/forum/index/move_thread/' . $entry['topic_id'] . '/' . $area_id) ?>">
                                                 <?= Icon::create('arr_2right', Icon::ROLE_SORT) ?>
                                                 <?= htmlReady($area['name_raw']) ?>
                                             </a>
diff --git a/public/plugins_packages/core/Forum/views/index/index.php b/app/views/course/forum/index/index.php
similarity index 81%
rename from public/plugins_packages/core/Forum/views/index/index.php
rename to app/views/course/forum/index/index.php
index d1b9ecc8916..69f4b946734 100644
--- a/public/plugins_packages/core/Forum/views/index/index.php
+++ b/app/views/course/forum/index/index.php
@@ -6,7 +6,7 @@
     });
 </script>
 
-<?= $this->render_partial('index/_js_templates') ?>
+<?= $this->render_partial('course/forum/index/_js_templates') ?>
 
 <!-- set a CSS "namespace" for Forum -->
 <div id="forum">
@@ -15,7 +15,7 @@
 $sidebar = Sidebar::get();
 
 if (ForumPerm::has('search', $seminar_id)) {
-    $search = new SearchWidget(PluginEngine::getURL('coreforum/index/search?backend=search'));
+    $search = new SearchWidget($controller->url_for('course/forum/index/search?backend=search'));
     $search->setId('tutorSearchInfobox');
     $search->addNeedle(_('Beiträge durchsuchen'), 'searchfor', true);
     $search->addFilter(_('Titel'), 'search_title');
@@ -30,7 +30,7 @@ if ($section == 'index') {
     if (ForumPerm::has('abo', $seminar_id)) {
         if (ForumAbo::has($constraint['topic_id'])) :
             $abo_text = _('Nicht mehr abonnieren');
-            $abo_url = PluginEngine::getURL('coreforum/index/remove_abo/' . $constraint['topic_id']);
+            $abo_url = $controller->url_for('course/forum/index/remove_abo/' . $constraint['topic_id']);
         else :
             switch ($constraint['depth']) {
                 case '0': $abo_text = _('Komplettes Forum abonnieren');break;
@@ -38,7 +38,7 @@ if ($section == 'index') {
                 default: $abo_text = _('Dieses Thema abonnieren');break;
             }
 
-            $abo_url = PluginEngine::getURL('coreforum/index/abo/' . $constraint['topic_id']);
+            $abo_url = $controller->url_for('course/forum/index/abo/' . $constraint['topic_id']);
         endif;
 
         $actions->addLink($abo_text, $abo_url, Icon::create('link-intern', 'clickable'));
@@ -46,7 +46,7 @@ if ($section == 'index') {
 
     if (ForumPerm::has('close_thread', $seminar_id) && $constraint['depth'] > 1) {
         if ($constraint['closed'] == 0) {
-            $close_url = PluginEngine::getURL('coreforum/index/close_thread/'
+            $close_url = $controller->url_for('course/forum/index/close_thread/'
                             . $constraint['topic_id'] .'/'. $constraint['topic_id'] .'/'. ForumHelpers::getPage());
             $close = new LinkElement(
                 _('Thema schließen'),
@@ -60,7 +60,7 @@ if ($section == 'index') {
             );
             $actions->addElement($close, 'closethread');
         } else {
-            $open_url = PluginEngine::getURL('coreforum/index/open_thread/'
+            $open_url = $controller->url_for('course/forum/index/open_thread/'
                             . $constraint['topic_id'] .'/'. $constraint['topic_id'] .'/'. ForumHelpers::getPage());
             $open = new LinkElement(
                 _('Thema öffnen'),
@@ -78,7 +78,7 @@ if ($section == 'index') {
 
     if (ForumPerm::has('make_sticky', $seminar_id) && $constraint['depth'] > 1) {
         if ($constraint['sticky'] == 0) {
-            $emphasize_url = PluginEngine::getURL('coreforum/index/make_sticky/'
+            $emphasize_url = $controller->url_for('course/forum/index/make_sticky/'
                                 . $constraint['topic_id'] .'/'. $constraint['topic_id'] .'/'. ForumHelpers::getPage());
             $emphasize = new LinkElement(
                 _('Thema hervorheben'),
@@ -92,7 +92,7 @@ if ($section == 'index') {
             );
             $actions->addElement($emphasize, 'emphasize');
         } else {
-            $unemphasize_url = PluginEngine::getURL('coreforum/index/make_unsticky/'
+            $unemphasize_url = $controller->url_for('course/forum/index/make_unsticky/'
                                 . $constraint['topic_id'] .'/'. $constraint['topic_id'] .'/'. ForumHelpers::getPage());
             $emphasize = new LinkElement(
                 _('Hervorhebung aufheben'),
@@ -118,14 +118,14 @@ $sidebar->addWidget($actions);
 if ($section === 'index' && ForumPerm::has('pdfexport', $seminar_id)) {
     $export = new ExportWidget();
     $export->addLink(_('Beiträge als PDF exportieren'),
-                     $controller->url_for('index/pdfexport/' . $constraint['topic_id']),
+                     $controller->url_for('course/forum/index/pdfexport/' . $constraint['topic_id']),
                      Icon::create('file-pdf', 'clickable'));
     $sidebar->addWidget($export);
 }
 ?>
 
 <!-- Breadcrumb navigation -->
-<?= $this->render_partial('index/_breadcrumb') ?>
+<?= $this->render_partial('course/forum/index/_breadcrumb') ?>
 
 <!-- Seitenwähler (bei Bedarf) am oberen Rand anzeigen -->
 <? if ($number_of_entries > ForumEntry::POSTINGS_PER_PAGE) : ?>
@@ -135,7 +135,7 @@ if ($section === 'index' && ForumPerm::has('pdfexport', $seminar_id)) {
         'page'         => ForumHelpers::getPage(),
         'num_postings' => $number_of_entries,
         'perPage'      => ForumEntry::POSTINGS_PER_PAGE,
-        'pagelink'     => str_replace('%%s', '%s', str_replace('%', '%%', PluginEngine::getURL('coreforum/index/goto_page/'. $topic_id .'/'. $section
+        'pagelink'     => str_replace('%%s', '%s', str_replace('%', '%%', $controller->url_for('course/forum/index/goto_page/'. $topic_id .'/'. $section
             .'/%s/?searchfor=' . $searchfor . (!empty($options) ? '&'. http_build_query($options) : '' ))))
     ]); ?>
     <? endif ?>
@@ -145,7 +145,7 @@ if ($section === 'index' && ForumPerm::has('pdfexport', $seminar_id)) {
 
 <!-- Message area -->
 <div id="message_area" style="clear: both">
-    <?= $this->render_partial('messages') ?>
+    <?= $this->render_partial('course/forum/messages') ?>
 </div>
 
 <? if ($no_entries) : ?>
@@ -154,14 +154,14 @@ if ($section === 'index' && ForumPerm::has('pdfexport', $seminar_id)) {
 
 <!-- Bereiche / Themen darstellen -->
 <? if ($constraint['depth'] == 0) : ?>
-    <?= $this->render_partial('index/_areas') ?>
+    <?= $this->render_partial('course/forum/index/_areas') ?>
 <? elseif ($constraint['depth'] == 1) : ?>
-    <?= $this->render_partial('index/_threads') ?>
+    <?= $this->render_partial('course/forum/index/_threads') ?>
 <? endif ?>
 
 <? if (!empty($postings)) : ?>
     <!-- Beiträge für das ausgewählte Thema darstellen -->
-    <?= $this->render_partial('index/_postings') ?>
+    <?= $this->render_partial('course/forum/index/_postings') ?>
 <? endif ?>
 
 <!-- Seitenwähler (bei Bedarf) am unteren Rand anzeigen -->
@@ -177,18 +177,18 @@ if ($section === 'index' && ForumPerm::has('pdfexport', $seminar_id)) {
         <div class="button-group">
             <? if (ForumPerm::has('abo', $seminar_id) && $section == 'index') : ?>
             <span id="abolink">
-                <?= $this->render_partial('index/_abo_link', compact('constraint')) ?>
+                <?= $this->render_partial('course/forum/index/_abo_link', compact('constraint')) ?>
             </span>
             <? endif ?>
 
             <? if (ForumPerm::has('pdfexport', $seminar_id) && $section == 'index') : ?>
-                <?= Studip\LinkButton::create(_('Beiträge als PDF exportieren'), PluginEngine::getURL('coreforum/index/pdfexport'), ['target' => '_blank']) ?>
+                <?= Studip\LinkButton::create(_('Beiträge als PDF exportieren'), $controller->url_for('course/forum/index/pdfexport'), ['target' => '_blank']) ?>
             <? endif ?>
         </div>
     </div>
 
     <? if ($section == 'index' && $constraint['depth'] == 0 && ForumPerm::has('add_category', $seminar_id)) : ?>
-        <?= $this->render_partial('index/_new_category') ?>
+        <?= $this->render_partial('course/forum/index/_new_category') ?>
     <? endif ?>
 <? else : ?>
     <? if (!$flash['edit_entry'] && ForumPerm::has('add_entry', $seminar_id)) : ?>
@@ -197,13 +197,13 @@ if ($section === 'index' && ForumPerm::has('pdfexport', $seminar_id)) {
         <div style="clear: right; text-align: center">
             <div class="button-group">
                 <? if ($constraint['depth'] <= 1 || ($constraint['closed'] == 0)) : ?>
-                    <?= Studip\LinkButton::create($button_face, PluginEngine::getURL('coreforum/index/index/'. $topic_id .'?answer=1'),
+                    <?= Studip\LinkButton::create($button_face, $controller->url_for('course/forum/index/index/'. $topic_id .'?answer=1'),
                         ['onClick' => 'STUDIP.Forum.answerEntry(); return false;',
                         'class' => 'hideWhenClosed',]) ?>
                 <? endif ?>
 
                 <? if ($constraint['depth'] > 1 && ($constraint['closed'] == 1)) : ?>
-                    <?= Studip\LinkButton::create($button_face, PluginEngine::getURL('coreforum/index/index/' . $topic_id. '?answer=1'),
+                    <?= Studip\LinkButton::create($button_face, $controller->url_for('course/forum/index/index/' . $topic_id. '?answer=1'),
                         ['onClick' => 'STUDIP.Forum.answerEntry(); return false;',
                             'class' => 'hideWhenClosed',
                             'style' => 'display:none;'
@@ -213,13 +213,13 @@ if ($section === 'index' && ForumPerm::has('pdfexport', $seminar_id)) {
                 <? if (ForumPerm::has('close_thread', $seminar_id) && $constraint['depth'] > 1) : ?>
                     <? if ($constraint['closed'] == 0): ?>
                     <?= Studip\LinkButton::create(_('Thema schließen'),
-                            PluginEngine::getURL('coreforum/index/close_thread/' . $topic_id .'/'. $topic_id .'/'. ForumHelpers::getPage()), [
+                            $controller->url_for('course/forum/index/close_thread/' . $topic_id .'/'. $topic_id .'/'. ForumHelpers::getPage()), [
                                 'onClick' => 'STUDIP.Forum.closeThreadFromThread("'. $topic_id .'"); return false;',
                                 'class' => 'closeButtons']
                         ) ?>
                     <? else: ?>
                     <?= Studip\LinkButton::create(_('Thema öffnen'),
-                        PluginEngine::getURL('coreforum/index/open_thread/' . $topic_id .'/'. $topic_id .'/'. ForumHelpers::getPage()), [
+                        $controller->url_for('course/forum/index/open_thread/' . $topic_id .'/'. $topic_id .'/'. ForumHelpers::getPage()), [
                             'onClick' => 'STUDIP.Forum.openThreadFromThread("'. $topic_id .'"); return false;',
                             'class' => 'closeButtons']
                         ) ?>
@@ -228,12 +228,12 @@ if ($section === 'index' && ForumPerm::has('pdfexport', $seminar_id)) {
 
                 <? if ($constraint['depth'] > 0 && ForumPerm::has('abo', $seminar_id)) : ?>
                 <span id="abolink">
-                    <?= $this->render_partial('index/_abo_link', compact('constraint')) ?>
+                    <?= $this->render_partial('course/forum/index/_abo_link', compact('constraint')) ?>
                 </span>
                 <? endif ?>
 
                 <? if (ForumPerm::has('pdfexport', $seminar_id)) : ?>
-                <?= Studip\LinkButton::create(_('Beiträge als PDF exportieren'), PluginEngine::getURL('coreforum/index/pdfexport/' . $topic_id), ['target' => '_blank']) ?>
+                <?= Studip\LinkButton::create(_('Beiträge als PDF exportieren'), $controller->url_for('course/forum/index/pdfexport/' . $topic_id), ['target' => '_blank']) ?>
                 <? endif ?>
             </div>
         </div>
@@ -245,7 +245,7 @@ if ($section === 'index' && ForumPerm::has('pdfexport', $seminar_id)) {
 
 <? if ( (ForumPerm::has('add_area', $this->seminar_id))
     || ($constraint['depth'] >= 1 && ForumPerm::has('add_entry', $seminar_id)) ): ?>
-        <?= $this->render_partial('index/_new_entry') ?>
+        <?= $this->render_partial('course/forum/index/_new_entry') ?>
     <? endif ?>
 </div>
 
diff --git a/public/plugins_packages/core/Forum/views/messages.php b/app/views/course/forum/messages.php
similarity index 100%
rename from public/plugins_packages/core/Forum/views/messages.php
rename to app/views/course/forum/messages.php
diff --git a/app/views/course/statusgroups/groupinfo.php b/app/views/course/statusgroups/groupinfo.php
index 32890bf26df..3fff472af56 100644
--- a/app/views/course/statusgroups/groupinfo.php
+++ b/app/views/course/statusgroups/groupinfo.php
@@ -59,7 +59,7 @@
     <?php if ($thread = $group->blubberthread) : ?>
         <p>
             <?= formatReady(sprintf(_('Zu dieser Gruppe gehört ein [Blubberthread]%s .'),
-                URLHelper::getURL('plugins.php/blubber/messenger/course/' . $thread->id, [
+                URLHelper::getURL('dispatch.php/course/messenger/course/' . $thread->id, [
                     'cid' => $course_id,
                 ]))) ?>
         </p>
diff --git a/public/plugins_packages/core/QuickSelection/templates/edit.php b/app/views/quickselection/configuration.php
similarity index 87%
rename from public/plugins_packages/core/QuickSelection/templates/edit.php
rename to app/views/quickselection/configuration.php
index 6608ee0c453..8f25f4b9d3b 100644
--- a/public/plugins_packages/core/QuickSelection/templates/edit.php
+++ b/app/views/quickselection/configuration.php
@@ -1,5 +1,5 @@
 <div id="quickSelectionEdit">
-    <form id="configure_quickselection" action="<?= PluginEngine::getLink($plugin, [], 'save') ?>" method="post" class="default" data-dialog>
+    <form id="configure_quickselection" action="<?= $controller->link_for('quickselection/save') ?>" method="post" class="default" data-dialog>
         <fieldset>
             <legend><?= _("Inhalte des Schnellzugriff-Widget:") ?></legend>
             <fieldset>
diff --git a/db/migrations/5.2.6_update_core_plugins.php b/db/migrations/5.2.6_update_core_plugins.php
new file mode 100644
index 00000000000..a9f504899b2
--- /dev/null
+++ b/db/migrations/5.2.6_update_core_plugins.php
@@ -0,0 +1,48 @@
+<?php
+
+class UpdateCorePlugins extends Migration
+{
+    private static $core_widgets = [
+        'core/ActivityFeed' => 'ActivityFeed',
+        'core/Blubber' => 'Blubber',
+        'core/ContentsWidget' => 'ContentsWidget',
+        'core/Forum' => 'CoreForum',
+        'core/EvaluationsWidget' => 'EvaluationsWidget',
+        'core/NewsWidget' => 'NewsWidget',
+        'core/QuickSelection' => 'QuickSelection',
+        'core/ScheduleWidget' => 'ScheduleWidget',
+        'core/TerminWidget' => 'TerminWidget'
+    ];
+
+    public function description()
+    {
+        return 'convert old core plugins into new core pugins';
+    }
+
+    public function up()
+    {
+        $db = DBManager::get();
+        $stmt = $db->prepare('UPDATE plugins SET pluginpath = ? WHERE pluginclassname = ?');
+
+        foreach (self::$core_widgets as $core_widget) {
+            $stmt->execute(['', $core_widget]);
+        }
+
+        $db->exec("UPDATE help_content SET route = REPLACE(route, 'plugins.php/coreforum', 'dispatch.php/course/forum')");
+        $db->exec("UPDATE help_tour_steps SET route = REPLACE(route, 'plugins.php/coreforum', 'dispatch.php/course/forum')");
+    }
+
+    public function down()
+    {
+        $db = DBManager::get();
+
+        $stmt = $db->prepare('UPDATE plugins SET pluginpath = ? WHERE pluginclassname = ?');
+
+        foreach (self::$core_widgets as $pluginpath => $core_widget) {
+            $stmt->execute([$pluginpath, $core_widget]);
+        }
+
+        $db->exec("UPDATE help_content SET route = REPLACE(route, 'dispatch.php/course/forum', 'plugins.php/coreforum')");
+        $db->exec("UPDATE help_tour_steps SET route = REPLACE(route, 'dispatch.php/course/forum', 'plugins.php/coreforum')");
+    }
+}
diff --git a/lib/activities/ForumProvider.php b/lib/activities/ForumProvider.php
index 49260c3a7bc..f5439470d81 100644
--- a/lib/activities/ForumProvider.php
+++ b/lib/activities/ForumProvider.php
@@ -9,8 +9,6 @@
 
 namespace Studip\Activity;
 
-require_once 'public/plugins_packages/core/Forum/models/ForumEntry.php';
-
 class ForumProvider implements ActivityProvider
 {
     /**
@@ -28,7 +26,7 @@ class ForumProvider implements ActivityProvider
 
         $activity->content = formatReady($post['content']);
 
-        $url = \PluginEngine::getURL('CoreForum', [], 'index/index/' . $post['topic_id']
+        $url = \URLHelper::getURL('dispatch.php/course/forum/index/index/' . $post['topic_id']
                     .'?cid='. $post['seminar_id'] .'&highlight_topic='. $post['topic_id']
                     .'#'. $post['topic_id']);
 
diff --git a/public/plugins_packages/core/ScheduleWidget/CalendarWidgetView.php b/lib/calendar/CalendarWidgetView.php
similarity index 100%
rename from public/plugins_packages/core/ScheduleWidget/CalendarWidgetView.php
rename to lib/calendar/CalendarWidgetView.php
diff --git a/public/plugins_packages/core/Forum/models/ForumAbo.php b/lib/classes/ForumAbo.php
similarity index 94%
rename from public/plugins_packages/core/Forum/models/ForumAbo.php
rename to lib/classes/ForumAbo.php
index 6aee6478505..fa84a487284 100644
--- a/public/plugins_packages/core/Forum/models/ForumAbo.php
+++ b/lib/classes/ForumAbo.php
@@ -13,8 +13,6 @@
  * @category    Stud.IP
  */
 
-require_once('lib/messaging.inc.php');
-
 class ForumAbo
 {
     /**
@@ -97,8 +95,7 @@ class ForumAbo
         // get details for topic
         $topic = ForumEntry::getConstraints($topic_id);
 
-        $template_factory = new Flexi_TemplateFactory(dirname(__FILE__) . '/../views');
-        $template = $template_factory->open('index/_mail_notification');
+        $template = $GLOBALS['template_factory']->open('mail/forum_notification');
 
         // notify users
         while ($data = $stmt->fetch(PDO::FETCH_ASSOC)) {
@@ -129,8 +126,8 @@ class ForumAbo
 
             PersonalNotifications::add(
                 $user_id,
-                UrlHelper::getUrl(
-                    'plugins.php/coreforum/index/index/' . $topic['topic_id'] . '#' . $topic['topic_id'],
+                URLHelper::getURL(
+                    'dispatch.php/course/forum/index/index/' . $topic['topic_id'] . '#' . $topic['topic_id'],
                     ['cid' => $topic['seminar_id']],
                     true
                 ),
diff --git a/public/plugins_packages/core/Forum/models/ForumActivity.php b/lib/classes/ForumActivity.php
similarity index 100%
rename from public/plugins_packages/core/Forum/models/ForumActivity.php
rename to lib/classes/ForumActivity.php
diff --git a/public/plugins_packages/core/Forum/models/ForumBulkMail.php b/lib/classes/ForumBulkMail.php
similarity index 99%
rename from public/plugins_packages/core/Forum/models/ForumBulkMail.php
rename to lib/classes/ForumBulkMail.php
index abde3666f72..ec18de9ae03 100644
--- a/public/plugins_packages/core/Forum/models/ForumBulkMail.php
+++ b/lib/classes/ForumBulkMail.php
@@ -12,8 +12,6 @@
  * @category    Stud.IP
  */
 
-require_once 'lib/messaging.inc.php';
-
 class ForumBulkMail extends Messaging {
     var $bulk_mail;
 
diff --git a/public/plugins_packages/core/Forum/models/ForumEntry.php b/lib/classes/ForumEntry.php
similarity index 100%
rename from public/plugins_packages/core/Forum/models/ForumEntry.php
rename to lib/classes/ForumEntry.php
diff --git a/public/plugins_packages/core/Forum/models/ForumFavorite.php b/lib/classes/ForumFavorite.php
similarity index 100%
rename from public/plugins_packages/core/Forum/models/ForumFavorite.php
rename to lib/classes/ForumFavorite.php
diff --git a/public/plugins_packages/core/Forum/models/ForumHelpers.php b/lib/classes/ForumHelpers.php
similarity index 100%
rename from public/plugins_packages/core/Forum/models/ForumHelpers.php
rename to lib/classes/ForumHelpers.php
diff --git a/public/plugins_packages/core/Forum/models/ForumIssue.php b/lib/classes/ForumIssue.php
similarity index 97%
rename from public/plugins_packages/core/Forum/models/ForumIssue.php
rename to lib/classes/ForumIssue.php
index 7f98c7d4151..8be894f5177 100644
--- a/public/plugins_packages/core/Forum/models/ForumIssue.php
+++ b/lib/classes/ForumIssue.php
@@ -12,8 +12,6 @@
  * @category    Stud.IP
  */
 
-NotificationCenter::addObserver('ForumIssue', 'unlinkIssue', 'ForumBeforeDelete');
-
 class ForumIssue
 {
     /**
diff --git a/public/plugins_packages/core/Forum/models/ForumLike.php b/lib/classes/ForumLike.php
similarity index 95%
rename from public/plugins_packages/core/Forum/models/ForumLike.php
rename to lib/classes/ForumLike.php
index 735d7b5528a..24cb478524e 100644
--- a/public/plugins_packages/core/Forum/models/ForumLike.php
+++ b/lib/classes/ForumLike.php
@@ -35,7 +35,7 @@ class ForumLike {
         restoreLanguage();
         
         PersonalNotifications::add(
-            $data['user_id'], PluginEngine::getURL('coreforum/index/index/' . $topic_id .'?highlight_topic='. $topic_id .'#'. $topic_id),
+            $data['user_id'], URLHelper::getURL('dispatch.php/course/forum/index/index/' . $topic_id .'?highlight_topic='. $topic_id .'#'. $topic_id),
             $notification, $topic_id,
             Icon::create('forum', 'clickable')
         );
@@ -96,4 +96,4 @@ class ForumLike {
 
         return $entries[$user_id];
     }
-}
\ No newline at end of file
+}
diff --git a/public/plugins_packages/core/Forum/models/ForumPerm.php b/lib/classes/ForumPerm.php
similarity index 100%
rename from public/plugins_packages/core/Forum/models/ForumPerm.php
rename to lib/classes/ForumPerm.php
diff --git a/public/plugins_packages/core/Forum/models/ForumVisit.php b/lib/classes/ForumVisit.php
similarity index 100%
rename from public/plugins_packages/core/Forum/models/ForumVisit.php
rename to lib/classes/ForumVisit.php
diff --git a/lib/classes/JsonApi/Routes/Forum/ForumAuthority.php b/lib/classes/JsonApi/Routes/Forum/ForumAuthority.php
index c895a7b9749..acc5d2afd28 100644
--- a/lib/classes/JsonApi/Routes/Forum/ForumAuthority.php
+++ b/lib/classes/JsonApi/Routes/Forum/ForumAuthority.php
@@ -8,8 +8,6 @@ class ForumAuthority
 {
     public static function has(\User $user, $perm, \Course $course, ForumEntry $topic = null)
     {
-        require_once 'public/plugins_packages/core/Forum/models/ForumPerm.php';
-
         if (!\ForumPerm::has($perm, $course->id, $user->id)) {
             return false;
         }
diff --git a/lib/classes/JsonApi/Routes/Forum/ForumCategoriesShow.php b/lib/classes/JsonApi/Routes/Forum/ForumCategoriesShow.php
index 9e935e074ef..190efb2445d 100644
--- a/lib/classes/JsonApi/Routes/Forum/ForumCategoriesShow.php
+++ b/lib/classes/JsonApi/Routes/Forum/ForumCategoriesShow.php
@@ -2,8 +2,6 @@
 
 namespace JsonApi\Routes\Forum;
 
-// require_once 'public/plugins_packages/core/Forum/models/ForumCat.php';
-
 use Psr\Http\Message\ServerRequestInterface as Request;
 use Psr\Http\Message\ResponseInterface as Response;
 use JsonApi\Errors\AuthorizationFailedException;
diff --git a/lib/classes/Privacy.php b/lib/classes/Privacy.php
index 90ba9f7d93a..bb3bcddc60a 100644
--- a/lib/classes/Privacy.php
+++ b/lib/classes/Privacy.php
@@ -85,8 +85,6 @@ class Privacy
      */
     public static function getUserdataInformation($user_id, $section = null)
     {
-        //workaround make Forum Model available
-        PluginEngine::getPlugin('CoreForum');
         $storage = new StoredUserData($user_id);
 
         if ($section && !isset(self::$privacy_classes[$section])) {
diff --git a/lib/classes/globalsearch/GlobalSearchForum.php b/lib/classes/globalsearch/GlobalSearchForum.php
index 83558bdf296..37efd26930b 100644
--- a/lib/classes/globalsearch/GlobalSearchForum.php
+++ b/lib/classes/globalsearch/GlobalSearchForum.php
@@ -144,7 +144,7 @@ class GlobalSearchForum extends GlobalSearchModule implements GlobalSearchFullte
                 'id'          => $data['topic_id'],
                 'name'        => $name,
                 'url'         => URLHelper::getURL(
-                    "plugins.php/coreforum/index/index/{$data['topic_id']}#{$data['topic_id']}",
+                    "dispatch.php/course/forum/index/index/{$data['topic_id']}#{$data['topic_id']}",
                     ['cid' => $data['seminar_id'], 'highlight_topic' => $data['topic_id']],
                     true
                 ),
@@ -152,7 +152,7 @@ class GlobalSearchForum extends GlobalSearchModule implements GlobalSearchFullte
                 'date'        => strftime('%x', $data['chdate']),
                 'description' => self::mark($filtered_content, $search, true),
                 'additional'  => htmlReady($additional),
-                'expand' => URLHelper::getURL('plugins.php/coreforum/index/search', [
+                'expand' => URLHelper::getURL('dispatch.php/course/forum/index/search', [
                     'cid'            => $data['seminar_id'],
                     'backend'        => 'search',
                     'searchfor'      => $search,
diff --git a/lib/models/BlubberThread.php b/lib/models/BlubberThread.php
index 0be5cd2676a..430950fdccc 100644
--- a/lib/models/BlubberThread.php
+++ b/lib/models/BlubberThread.php
@@ -593,7 +593,7 @@ class BlubberThread extends SimpleORMap implements PrivacyObject
     public function getURL()
     {
         if (($this['context_type'] === "course") || ($this['context_type'] === "institute")) {
-            return URLHelper::getURL('plugins.php/blubber/messenger/course/' . $this->getId(), ['cid' => $this['context_id']]);
+            return URLHelper::getURL('dispatch.php/course/messenger/course/' . $this->getId(), ['cid' => $this['context_id']]);
         }
         return URLHelper::getURL('dispatch.php/blubber/index/' . $this->getId());
     }
diff --git a/public/plugins_packages/core/Forum/models/ForumCat.php b/lib/models/ForumCat.php
similarity index 100%
rename from public/plugins_packages/core/Forum/models/ForumCat.php
rename to lib/models/ForumCat.php
diff --git a/lib/modules/ActivityFeed.php b/lib/modules/ActivityFeed.php
new file mode 100644
index 00000000000..6fa9ce3c21d
--- /dev/null
+++ b/lib/modules/ActivityFeed.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * @author      André Klaßen <klassen@elan-ev.de>
+ * @author      Till Glöggler <tgloeggl@uos.de>
+ * @license     GPL 2 or later
+ */
+class ActivityFeed extends CorePlugin implements PortalPlugin
+{
+    public function getPluginName()
+    {
+        return _('Aktivitäten');
+    }
+
+    public function getMetadata()
+    {
+        return [
+            'description' => _('Mit diesem Widget haben Sie alle Aktivitäten im Überblick.')
+        ];
+    }
+
+    public function getPortalTemplate()
+    {
+        $template = $GLOBALS['template_factory']->open('start/activityfeed');
+
+        $template->user_id = $GLOBALS['user']->id;
+        $template->scrolledfrom = strtotime('+1 day');
+        $template->config = WidgetHelper::getWidgetUserConfig($GLOBALS['user']->id, 'ACTIVITY_FEED');
+
+        $navigation = new Navigation('', 'dispatch.php/activityfeed/configuration');
+        $navigation->setImage(Icon::create('edit', 'clickable', ["title" => _('Konfigurieren')]), ['data-dialog'=>'size=auto']);
+        $icons[] = $navigation;
+
+        $navigation = new Navigation('', '#', ['cid' => null]);
+        $navigation->setImage(Icon::create('headache+visibility-visible', 'clickable'));
+        $navigation->setLinkAttributes([
+            'id'    => 'toggle-user-activities',
+            'title' => _('Eigene Aktivitäten ein-/ausblenden'),
+        ]);
+        $icons[] = $navigation;
+
+        $navigation = new Navigation('', '#', ['cid' => null]);
+        $navigation->setImage(Icon::create('no-activity', 'clickable'));
+        $navigation->setLinkAttributes([
+            'id'    => 'toggle-all-activities',
+            'title' => _('Aktivitätsdetails ein-/ausblenden'),
+        ]);
+        $icons[] = $navigation;
+
+        $template->icons = $icons;
+
+        return $template;
+    }
+
+    public static function onEnable($pluginId)
+    {
+        $errors = [];
+        if (!Config::get()->API_ENABLED) {
+            $errors[] = sprintf(
+                _('Die REST-API ist nicht aktiviert (%s "API_ENABLED")'),
+                formatReady(sprintf('[%s]%s',
+                    _('Konfiguration'),
+                    URLHelper::getLink('dispatch.php/admin/configuration/configuration')
+                ))
+            );
+        } elseif (!RESTAPI\ConsumerPermissions::get('global')->check('/user/:user_id/activitystream', 'get')) {
+            $errors[] = sprintf(
+                _('Die REST-API-Route ist nicht aktiviert (%s "/user/:user_id/activitystream"")'),
+                formatReady(sprintf('[%s]%s',
+                    _('Konfiguration'),
+                    URLHelper::getLink('dispatch.php/admin/api/permissions')
+                ))
+            );
+        }
+
+        return count($errors) === 0;
+    }
+}
diff --git a/public/plugins_packages/core/Blubber/Blubber.class.php b/lib/modules/Blubber.class.php
similarity index 63%
rename from public/plugins_packages/core/Blubber/Blubber.class.php
rename to lib/modules/Blubber.class.php
index ce317ad24ba..d9b5579fafd 100644
--- a/public/plugins_packages/core/Blubber/Blubber.class.php
+++ b/lib/modules/Blubber.class.php
@@ -12,16 +12,8 @@
  * Class Blubber - the Blubber-plugin
  * This is only used to manage blubber within a course.
  */
-class Blubber extends StudIPPlugin implements StandardPlugin
+class Blubber extends CorePlugin implements StudipModule
 {
-    /**
-     * Plugin URL for CorePlugins is ABSOLUTE_URI_STUDIP.
-     */
-    public function getPluginURL()
-    {
-        return $GLOBALS['ABSOLUTE_URI_STUDIP'];
-    }
-
     /**
      * Returns a navigation for the tab displayed in the course.
      * @param string $course_id of the course
@@ -31,7 +23,7 @@ class Blubber extends StudIPPlugin implements StandardPlugin
     {
         $tab = new Navigation(
             _('Blubber'),
-            PluginEngine::getURL($this, [], 'messenger/course')
+            'dispatch.php/course/messenger/course'
         );
         $tab->setImage(Icon::create('blubber', Icon::ROLE_INFO_ALT));
         return ['blubber' => $tab];
@@ -50,7 +42,7 @@ class Blubber extends StudIPPlugin implements StandardPlugin
         $user_id || $user_id = $GLOBALS['user']->id;
         $icon = new Navigation(
             _('Blubber'),
-            PluginEngine::getURL($this, [], 'messenger/course')
+            'dispatch.php/course/messenger/course'
         );
         $icon->setImage(Icon::create('blubber', Icon::ROLE_CLICKABLE, ['title' => _('Blubber-Messenger')]));
 
@@ -71,7 +63,7 @@ class Blubber extends StudIPPlugin implements StandardPlugin
                 $icon->setImage(Icon::create('blubber', Icon::ROLE_NEW, ['title' => _('Es gibt neue Blubber')]));
                 $icon->setTitle(_('Es gibt neue Blubber'));
                 $icon->setBadgeNumber(count($comments));
-                $icon->setURL(PluginEngine::getURL($this, ['thread' => 'new'], 'messenger/course'));
+                $icon->setURL('dispatch.php/course/messenger/course', ['thread' => 'new']);
                 break;
             }
         }
@@ -110,4 +102,25 @@ class Blubber extends StudIPPlugin implements StandardPlugin
     {
         return null;
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadata()
+    {
+        return [
+            'summary' => _('Schneller und einfacher Austausch von Informationen in Gesprächsform'),
+            'description' => _('Blubber ist eine Kommunikationsform mit Ähnlichkeiten zu einem Forum, in dem aber in Echtzeit miteinander kommuniziert werden kann und das durch den etwas informelleren Charakter eher einem Chat anmutet. Anders als im Forum ist es nicht notwendig, die Seiten neu zu laden, um die neuesten Einträge (z. B. Antworten auf eigene Postings) sehen zu können: Die Seite aktualisiert sich selbst bei neuen Einträgen. Dateien (z.B. Fotos, Audiodateien, Links) können per Drag and Drop in das Feld gezogen und somit verlinkt werden. Auch Textformatierungen und das Verwenden von Smileys sind möglich.'),
+            'descriptionlong' => _('Kommunikationsform mit Ähnlichkeiten zu einem Forum. Im Gegensatz zum Forum kann mit Blubber jedoch in Echtzeit miteinander kommuniziert werden. Das Tool ähnelt durch den etwas informelleren Charakter einem Messenger. Anders als im Forum ist es nicht notwendig, die Seiten neu zu laden, um die neuesten Einträge (z. B. Antworten auf eigene Postings) sehen zu können. Dateien (z. B. Fotos, Audiodateien, Links) können per drag and drop in das Feld gezogen und somit verlinkt werden. Auch Textformatierungen und das Verwenden von Smileys sind möglich.'),
+            'category' => _('Kommunikation und Zusammenarbeit'),
+            'keywords' => _('Einfach Text schreiben und mit <Enter> abschicken; Direktes Kontaktieren anderer Stud.IP-NutzerInnen (@Vorname Nachname); Setzen von und Suche nach Stichworten über Hashtags (#Stichwort); Einbinden von Dateien per drag and drop'),
+            'icon' => Icon::create('blubber', Icon::ROLE_INFO),
+            'screenshots' => [
+                'path' => 'assets/images/plus/screenshots/Blubber',
+                'pictures' => [
+                    ['source' => 'blubberscreenshot.png', 'title' => 'Blubbern']
+                ]
+            ]
+        ];
+    }
 }
diff --git a/public/plugins_packages/core/ContentsWidget/ContentsWidget.php b/lib/modules/ContentsWidget.php
similarity index 55%
rename from public/plugins_packages/core/ContentsWidget/ContentsWidget.php
rename to lib/modules/ContentsWidget.php
index 40610811f40..1907ba668dc 100644
--- a/public/plugins_packages/core/ContentsWidget/ContentsWidget.php
+++ b/lib/modules/ContentsWidget.php
@@ -7,17 +7,23 @@
  * @since   Stud.IP 5.0
  */
 
-class ContentsWidget extends StudIPPlugin implements PortalPlugin
+class ContentsWidget extends CorePlugin implements PortalPlugin
 {
     public function getPluginName()
     {
         return _('Mein Arbeitsplatz');
     }
 
+    public function getMetadata()
+    {
+        return [
+            'description' => _('Mit diesem Widget haben Sie einen Überblick über Ihre Inhalte.')
+        ];
+    }
+
     public function getPortalTemplate()
     {
-        $template_factory = new Flexi_TemplateFactory(__DIR__ . '/templates');
-        $template = $template_factory->open('index');
+        $template = $GLOBALS['template_factory']->open('start/contents');
         $template->tiles = Navigation::getItem('/contents');
         return $template;
     }
diff --git a/public/plugins_packages/core/Forum/CoreForum.class.php b/lib/modules/CoreForum.class.php
similarity index 66%
rename from public/plugins_packages/core/Forum/CoreForum.class.php
rename to lib/modules/CoreForum.class.php
index 9ab7b4f05d1..88dd5ddc7f7 100644
--- a/public/plugins_packages/core/Forum/CoreForum.class.php
+++ b/lib/modules/CoreForum.class.php
@@ -13,48 +13,35 @@
  * @category    Stud.IP
  */
 
-require_once 'controllers/forum_controller.php';
-require_once 'lib/activities/Activity.php';
-require_once 'models/ForumEntry.php';
-
-// Setup autoloader
-StudipAutoloader::addAutoloadPath(__DIR__ . '/models');
-
 // Notifications
-NotificationCenter::addObserver('CoreForum', 'overviewDidClear', "OverviewDidClear");
+NotificationCenter::addObserver('CoreForum', 'overviewDidClear', 'OverviewDidClear');
 NotificationCenter::addObserver('CoreForum', 'removeAbosForUserAndCourse', 'UserDidLeaveCourse');
 
 NotificationCenter::addObserver('ForumActivity', 'newEntry', 'ForumAfterInsert');
 NotificationCenter::addObserver('ForumActivity', 'updateEntry', 'ForumAfterUpdate');
 NotificationCenter::addObserver('ForumActivity', 'deleteEntry', 'ForumBeforeDelete');
 
-class CoreForum extends StudipPlugin implements ForumModule
-{
-    /**
-     * Plugin URL for CorePlugins is ABSOLUTE_URI_STUDIP.
-     */
-    public function getPluginURL()
-    {
-        return $GLOBALS['ABSOLUTE_URI_STUDIP'];
-    }
+NotificationCenter::addObserver('ForumIssue', 'unlinkIssue', 'ForumBeforeDelete');
 
+class CoreForum extends CorePlugin implements ForumModule
+{
     /* interface method */
     public function getTabNavigation($course_id)
     {
-        $navigation = new Navigation(_('Forum'), PluginEngine::getURL($this, [], 'index'));
+        $navigation = new Navigation(_('Forum'), 'dispatch.php/course/forum/index');
         $navigation->setImage(Icon::create('forum', 'info_alt'));
 
         // add main third-level navigation-item
-        $navigation->addSubNavigation('index', new Navigation(_('Übersicht'), PluginEngine::getURL($this, [], 'index')));
+        $navigation->addSubNavigation('index', new Navigation(_('Übersicht'), 'dispatch.php/course/forum/index'));
 
         if (ForumPerm::has('fav_entry', $course_id)) {
-            $navigation->addSubNavigation('newest', new Navigation(_("Neue Beiträge"), PluginEngine::getURL($this, [], 'index/newest')));
-            $navigation->addSubNavigation('latest', new Navigation(_("Letzte Beiträge"), PluginEngine::getURL($this, [], 'index/latest')));
-            $navigation->addSubNavigation('favorites', new Navigation(_('Gemerkte Beiträge'), PluginEngine::getURL($this, [], 'index/favorites')));
+            $navigation->addSubNavigation('newest', new Navigation(_("Neue Beiträge"), 'dispatch.php/course/forum/index/newest'));
+            $navigation->addSubNavigation('latest', new Navigation(_("Letzte Beiträge"), 'dispatch.php/course/forum/index/latest'));
+            $navigation->addSubNavigation('favorites', new Navigation(_('Gemerkte Beiträge'), 'dispatch.php/course/forum/index/favorites'));
 
             // mass-administrate the forum
             if (ForumPerm::has('admin', $course_id)) {
-                $navigation->addSubNavigation('admin', new Navigation(_('Administration'), PluginEngine::getURL($this, [], 'admin')));
+                $navigation->addSubNavigation('admin', new Navigation(_('Administration'), 'dispatch.php/course/forum/admin'));
             }
         }
 
@@ -72,7 +59,7 @@ class CoreForum extends StudipPlugin implements ForumModule
             $text = 'Forum';
         }
 
-        $navigation = new Navigation('forum', PluginEngine::getURL($this, [], 'index/enter_seminar'));
+        $navigation = new Navigation('forum', 'dispatch.php/course/forum/index/enter_seminar');
         $navigation->setBadgeNumber($num_entries);
 
         if ($num_entries > 0) {
@@ -125,7 +112,7 @@ class CoreForum extends StudipPlugin implements ForumModule
     public function getLinkToThread($issue_id)
     {
         if ($topic_id = ForumIssue::getThreadIdForIssue($issue_id)) {
-            return PluginEngine::getLink($this, [], '/index/index/' . $topic_id);
+            return URLHelper::getLink('dispatch.php/course/forum/index/index/' . $topic_id);
         }
 
         return false;
@@ -196,4 +183,27 @@ class CoreForum extends StudipPlugin implements ForumModule
             'Veranstaltungsthemen Fragen stellen, die von den Studierenden '.
             'per Meinungsaustausch besprochen werden.');
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getMetadata()
+    {
+        return [
+            'summary' => _('Veranstaltungsbegleitender Meinungsaustausch zu bestimmten Themen'),
+            'description' => _('Textbasierte zeit- und ortsunabhängige Möglichkeit zum Austausch von Gedanken, Meinungen und Erfahrungen. Lehrende und/oder Studierende können parallel zu Veranstaltungsthemen Fragen stellen, die in Form von Textbeiträgen besprochen werden können. Diese Beiträge können von allen Teilnehmenden der Veranstaltung gemerkt, verlinkt, positiv bewertet (sog. "Gefällt mir") und editiert werden (Letzeres nur von Lehrenden). Lehrende können zusätzlich Themen in Bereiche gliedern, zwischen den Bereichen verschiebe, im Bereich hervorheben und diesen öffnen und schließen.'),
+            'descriptionlong' => _('Textbasierte zeit- und ortsunabhängige Möglichkeit zum Austausch von Gedanken, Meinungen und Erfahrungen. Lehrende und/oder Studierende können parallel zu Veranstaltungsthemen Fragen stellen, die in Form von Textbeiträgen besprochen werden können. Diese Beiträge können von allen Teilnehmenden der Veranstaltung gemerkt, verlinkt, positiv bewertet (sog. "Gefällt mir") und editiert werden (Letzeres nur von Lehrenden). Lehrende können zusätzlich Themen in Bereiche gliedern, zwischen den Bereichen verschieben, im Bereich hervorheben und diesen öffnen und schließen.'),
+            'category' => _('Kommunikation und Zusammenarbeit'),
+            'keywords' => _('Möglichkeit zum intensiven, nachhaltigen textbasierten Austausch; (nachträgliche) Strukturierung der Beiträge; Editierfunktion für Lehrende'),
+            'icon' => Icon::create('forum', Icon::ROLE_INFO),
+            'screenshots' => [
+                'path' => 'assets/images/plus/screenshots/Forum',
+                'pictures' => [
+                    ['source' => 'Lehrendensicht_-_Kategorien_mit_Bereichen_und_Beitraegen.jpg'],
+                    ['source' => 'Studentische_Sicht_-_Kategorien_mit_Bereichen_und_Beitraegen.jpg'],
+                    ['source' => 'Einen_Forumsbeitrag_erstellen.jpg'],
+                ]
+            ]
+        ];
+    }
 }
diff --git a/public/plugins_packages/core/EvaluationsWidget/EvaluationsWidget.php b/lib/modules/EvaluationsWidget.php
similarity index 90%
rename from public/plugins_packages/core/EvaluationsWidget/EvaluationsWidget.php
rename to lib/modules/EvaluationsWidget.php
index 1dd7d3b0710..4c902c7047e 100644
--- a/public/plugins_packages/core/EvaluationsWidget/EvaluationsWidget.php
+++ b/lib/modules/EvaluationsWidget.php
@@ -9,13 +9,20 @@
  * the License, or (at your option) any later version.
  */
 
-class EvaluationsWidget extends StudIPPlugin implements PortalPlugin
+class EvaluationsWidget extends CorePlugin implements PortalPlugin
 {
     public function getPluginName()
     {
         return _('Fragebögen');
     }
 
+    public function getMetadata()
+    {
+        return [
+            'description' => _('Mit diesem Widget haben Sie Zugriff auf systemweite Umfragen.')
+        ];
+    }
+
     /**
      * Returns the portal widget template.
      *
diff --git a/public/plugins_packages/core/NewsWidget/NewsWidget.php b/lib/modules/NewsWidget.php
similarity index 73%
rename from public/plugins_packages/core/NewsWidget/NewsWidget.php
rename to lib/modules/NewsWidget.php
index 8dd150bec88..60af752ba83 100644
--- a/public/plugins_packages/core/NewsWidget/NewsWidget.php
+++ b/lib/modules/NewsWidget.php
@@ -11,13 +11,20 @@
 
 require_once 'app/controllers/news.php';
 
-class NewsWidget extends StudIPPlugin implements PortalPlugin
+class NewsWidget extends CorePlugin implements PortalPlugin
 {
     public function getPluginName()
     {
         return _('Ankündigungen');
     }
 
+    public function getMetadata()
+    {
+        return [
+            'description' => _('Mit diesem Widget haben Sie Zugriff auf systemweite Ankündigungen.')
+        ];
+    }
+
     function getPortalTemplate()
     {
         $dispatcher = new StudipDispatcher();
@@ -27,7 +34,7 @@ class NewsWidget extends StudIPPlugin implements PortalPlugin
         $template->content = $response->body;
 
         if (StudipNews::CountUnread() > 0) {
-            $navigation = new Navigation('', PluginEngine::getLink($this, [], 'read_all'));
+            $navigation = new Navigation('', 'dispatch.php/news/visit_all');
             $navigation->setImage(Icon::create('refresh', 'clickable', ["title" => _('Alle als gelesen markieren')]));
             $icons[] = $navigation;
         }
@@ -55,25 +62,4 @@ class NewsWidget extends StudIPPlugin implements PortalPlugin
 
         return $template;
     }
-
-
-    public function perform($unconsumed)
-    {
-        if ($unconsumed !== 'read_all') {
-            return;
-        }
-
-        $global_news = StudipNews::GetNewsByRange('studip', true);
-        foreach ($global_news as $news) {
-            object_add_view($news['news_id']);
-            object_set_visit($news['news_id'], 'news');
-        }
-
-        if (Request::isXhr()) {
-            echo json_encode(true);
-        } else {
-            PageLayout::postMessage(MessageBox::success(_('Alle Ankündigungen wurden als gelesen markiert.')));
-            header('Location: '. URLHelper::getLink('dispatch.php/start'));
-        }
-    }
 }
diff --git a/lib/modules/QuickSelection.php b/lib/modules/QuickSelection.php
new file mode 100644
index 00000000000..f1a7a2c9415
--- /dev/null
+++ b/lib/modules/QuickSelection.php
@@ -0,0 +1,57 @@
+<?php
+/*
+ * QuickSelection.php - widget plugin for start page
+ *
+ * Copyright (C) 2014 - Nadine Werner <nadwerner@uos.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 (at your option) any later version.
+ */
+
+class QuickSelection extends CorePlugin implements PortalPlugin
+{
+    public function getPluginName()
+    {
+        return _('Schnellzugriff');
+    }
+
+    public function getMetadata()
+    {
+        return [
+            'description' => _('Mit dem Schnellzugriff-Widget können Sie Links zu bestimmten Bereichen in Stud.IP verwalten.')
+        ];
+    }
+
+    public function getPortalTemplate()
+    {
+        $names = WidgetHelper::getWidgetUserConfig($GLOBALS['user']->id, 'QUICK_SELECTION');
+
+        $template = $GLOBALS['template_factory']->open('start/quickselection');
+        $template->navigation = $this->getFilteredNavigation($names);
+
+        $navigation = new Navigation('', 'dispatch.php/quickselection/configuration');
+        $navigation->setImage(Icon::create('edit', 'clickable', ["title" => _('Konfigurieren')]), ['data-dialog'=>'size=auto']);
+
+        $template->icons = [$navigation];
+
+        return $template;
+    }
+
+    private function getFilteredNavigation($items)
+    {
+        $result = [];
+
+        $navigation = Navigation::getItem('/start');
+        foreach ($navigation as $name => $nav) {
+            // if config is new (key:value) display values which are not in config array
+            // otherwise hide items which are not in config array
+            // This is important for patching.
+            if (!isset($items[$name]) || $items[$name] !== 'deactivated') {
+                $result[] = $nav;
+            }
+        }
+
+        return $result;
+    }
+}
diff --git a/public/plugins_packages/core/ScheduleWidget/ScheduleWidget.php b/lib/modules/ScheduleWidget.php
similarity index 84%
rename from public/plugins_packages/core/ScheduleWidget/ScheduleWidget.php
rename to lib/modules/ScheduleWidget.php
index 72343e74a32..339beb3f87f 100644
--- a/public/plugins_packages/core/ScheduleWidget/ScheduleWidget.php
+++ b/lib/modules/ScheduleWidget.php
@@ -13,9 +13,7 @@
  * @category    Stud.IP
  */
 
-require_once __DIR__ . '/CalendarWidgetView.php';
-
-class ScheduleWidget extends StudIPPlugin implements PortalPlugin
+class ScheduleWidget extends CorePlugin implements PortalPlugin
 {
     /**
      * Returns the name of the plugin/widget.
@@ -27,6 +25,13 @@ class ScheduleWidget extends StudIPPlugin implements PortalPlugin
         return _('Mein Stundenplan');
     }
 
+    public function getMetadata()
+    {
+        return [
+            'description' => _('Mit diesem Widget haben Sie eine Übersicht Ihres aktuellen Stundenplans.')
+        ];
+    }
+
     /**
      * Return the template for the widget.
      *
diff --git a/public/plugins_packages/core/TerminWidget/TerminWidget.php b/lib/modules/TerminWidget.php
similarity index 83%
rename from public/plugins_packages/core/TerminWidget/TerminWidget.php
rename to lib/modules/TerminWidget.php
index 0206597d79b..c92f1d201e0 100644
--- a/public/plugins_packages/core/TerminWidget/TerminWidget.php
+++ b/lib/modules/TerminWidget.php
@@ -12,13 +12,20 @@
 
 require_once 'app/controllers/calendar/contentbox.php';
 
-class TerminWidget extends StudIPPlugin implements PortalPlugin
+class TerminWidget extends CorePlugin implements PortalPlugin
 {
     public function getPluginName()
     {
         return _('Meine aktuellen Termine');
     }
 
+    public function getMetadata()
+    {
+        return [
+            'description' => _('Mit diesem Widget haben Sie ihre aktuellen Termine im Überlick.')
+        ];
+    }
+
     public function getPortalTemplate()
     {
         $dispatcher = new StudipDispatcher();
diff --git a/lib/plugins/engine/PluginManager.class.php b/lib/plugins/engine/PluginManager.class.php
index ee5b43fdaca..7193f317f6b 100644
--- a/lib/plugins/engine/PluginManager.class.php
+++ b/lib/plugins/engine/PluginManager.class.php
@@ -83,7 +83,7 @@ class PluginManager
                 'enabled'                 => $plugin['enabled'] === 'yes',
                 'position'                => $plugin['navigationpos'],
                 'depends'                 => (int) $plugin['dependentonid'],
-                'core'                    => $plugin['pluginpath'] === '' || strpos($plugin['pluginpath'], 'core/') === 0,
+                'core'                    => $plugin['pluginpath'] === '',
                 'automatic_update_url'    => $plugin['automatic_update_url'],
                 'automatic_update_secret' => $plugin['automatic_update_secret']
             ];
diff --git a/public/plugins.php b/public/plugins.php
index 97aee039095..1488118720b 100644
--- a/public/plugins.php
+++ b/public/plugins.php
@@ -27,9 +27,15 @@ try {
     require_once 'lib/seminar_open.php';
 
     // get plugin class from request
-    $dispatch_to = isset($_SERVER['PATH_INFO']) ?$_SERVER['PATH_INFO'] : '';
+    $dispatch_to = isset($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';
     list($plugin_class, $unconsumed) = PluginEngine::routeRequest($dispatch_to);
 
+    // handle legacy forum plugin URLs
+    if ($plugin_class === 'coreforum') {
+        header('Location: ' . URLHelper::getURL('dispatch.php/course/forum/' . $unconsumed));
+        die();
+    }
+
     // retrieve corresponding plugin info
     $plugin_manager = PluginManager::getInstance();
     $plugin_info = $plugin_manager->getPluginInfo($plugin_class);
@@ -46,8 +52,9 @@ try {
     // set default page title
     PageLayout::setTitle($plugin->getPluginName());
 
+    // deprecated, the plugin should override perform() instead
     if (is_callable([$plugin, 'initialize'])) {
-      $plugin->initialize();
+        $plugin->initialize();
     }
 
     // let the show begin
diff --git a/public/plugins_packages/core/ActivityFeed/ActivityFeed.php b/public/plugins_packages/core/ActivityFeed/ActivityFeed.php
deleted file mode 100644
index f42b34b2731..00000000000
--- a/public/plugins_packages/core/ActivityFeed/ActivityFeed.php
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-use \Studip\Activity\ActivityProvider;
-
-/**
- * @author      André Klaßen <klassen@elan-ev.de>
- * @author      Till Glöggler <tgloeggl@uos.de>
- * @license     GPL 2 or later
- */
-class ActivityFeed extends StudIPPlugin implements PortalPlugin
-{
-    public function getPluginName()
-    {
-        return _('Aktivitäten');
-    }
-
-    public function getPortalTemplate()
-    {
-        $this->addStylesheet('css/style.less');
-        PageLayout::addScript($this->getPluginUrl() . '/javascript/activityfeed.js');
-
-        $template_factory = new Flexi_TemplateFactory(__DIR__ . '/templates');
-        $template = $template_factory->open('activity_feed');
-
-        $template->user_id = $GLOBALS['user']->id;
-        $template->scrolledfrom = strtotime('+1 day');
-        $template->config = WidgetHelper::getWidgetUserConfig($GLOBALS['user']->id, 'ACTIVITY_FEED');
-
-        $navigation = new Navigation('', PluginEngine::getLink($this, [], 'configuration'));
-        $navigation->setImage(Icon::create('edit', 'clickable', ["title" => _('Konfigurieren')]), ['data-dialog'=>'size=auto']);
-        $icons[] = $navigation;
-
-        $navigation = new Navigation('', '#', ['cid' => null]);
-        $navigation->setImage(Icon::create('headache+visibility-visible', 'clickable'));
-        $navigation->setLinkAttributes([
-            'id'    => 'toggle-user-activities',
-            'title' => _('Eigene Aktivitäten ein-/ausblenden'),
-        ]);
-        $icons[] = $navigation;
-
-        $navigation = new Navigation('', '#', ['cid' => null]);
-        $navigation->setImage(Icon::create('no-activity', 'clickable'));
-        $navigation->setLinkAttributes([
-            'id'    => 'toggle-all-activities',
-            'title' => _('Aktivitätsdetails ein-/ausblenden'),
-        ]);
-        $icons[] = $navigation;
-
-        $template->icons = $icons;
-
-        return $template;
-    }
-
-    public static function onEnable($pluginId)
-    {
-        $errors = [];
-        if (!Config::get()->API_ENABLED) {
-            $errors[] = sprintf(
-                _('Die REST-API ist nicht aktiviert (%s "API_ENABLED")'),
-                formatReady(sprintf('[%s]%s',
-                    _('Konfiguration'),
-                    URLHelper::getLink('dispatch.php/admin/configuration/configuration')
-                ))
-            );
-        } elseif (!RESTAPI\ConsumerPermissions::get('global')->check('/user/:user_id/activitystream', 'get')) {
-            $errors[] = sprintf(
-                _('Die REST-API-Route ist nicht aktiviert (%s "/user/:user_id/activitystream"")'),
-                formatReady(sprintf('[%s]%s',
-                    _('Konfiguration'),
-                    URLHelper::getLink('dispatch.php/admin/api/permissions')
-                ))
-            );
-        }
-
-        return count($errors) === 0;
-    }
-
-    public function save_action()
-    {
-        if (Config::get()->ACTIVITY_FEED === NULL) {
-            Config::get()->create('ACTIVITY_FEED', [
-                'range' => 'user',
-                'type' => 'array',
-                'description' => 'Einstellungen des Activity-Widgets']
-            );
-        }
-
-        $provider = Request::getArray('provider');
-
-        WidgetHelper::addWidgetUserConfig($GLOBALS['user']->id, 'ACTIVITY_FEED', $provider);
-
-        header('X-Dialog-Close: 1');
-        header('X-Dialog-Execute: STUDIP.ActivityFeed.updateFilter');
-
-        echo json_encode($provider);
-    }
-
-    /**
-     * return a list for all providers for every context
-     *
-     * @return array
-     */
-    private function getAllModules()
-    {
-        $modules = [];
-
-        $modules['system'] = [
-            'news'         => _('Ankündigungen'),
-            'blubber'      => _('Blubber')
-        ];
-
-        $modules[\Context::COURSE] = [
-            'forum'        => _('Forum'),
-            'participants' => _('Teilnehmende'),
-            'documents'    => _('Dateien'),
-            'wiki'         => _('Wiki'),
-            'schedule'     => _('Ablaufplan'),
-            'news'         => _('Ankündigungen'),
-            'blubber'      => _('Blubber'),
-            'courseware'   => _('Courseware')
-        ];
-
-        $modules[\Context::INSTITUTE] = $modules[\Context::COURSE];
-        unset($modules[\Context::INSTITUTE]['participants']);
-        unset($modules[\Context::INSTITUTE]['schedule']);
-
-        $standard_plugins = \PluginManager::getInstance()->getPlugins("StandardPlugin");
-        foreach ($standard_plugins as $plugin) {
-            if ($plugin instanceof ActivityProvider) {
-                $modules[\Context::COURSE][$plugin->getPluginName()] = $plugin->getPluginName();
-                $modules[\Context::INSTITUTE][$plugin->getPluginName()] = $plugin->getPluginName();
-            }
-        }
-
-        $modules[\Context::USER] = [
-            'message'      => _('Nachrichten'),
-            'news'         => _('Ankündigungen'),
-            'blubber'      => _('Blubber'),
-        ];
-
-        $homepage_plugins = \PluginEngine::getPlugins('HomepagePlugin');
-        foreach ($homepage_plugins as $plugin) {
-            if ($plugin->isActivated($GLOBALS['user']->id, 'user')) {
-                if ($plugin instanceof ActivityProvider) {
-                    $modules[\Context::USER][] = $plugin;
-                }
-            }
-        }
-
-        return $modules;
-    }
-
-    public function configuration_action()
-    {
-        $template_factory = new Flexi_TemplateFactory(__DIR__ . '/templates');
-        $template = $template_factory->open('edit');
-        $template->config = WidgetHelper::getWidgetUserConfig($GLOBALS['user']->id, 'ACTIVITY_FEED');
-        $template->plugin = $this;
-        $template->modules = $this->getAllModules();
-        $template->context_translations = [
-            \Context::COURSE    => _('Veranstaltungen'),
-            \Context::INSTITUTE => _('Einrichtungen'),
-            \Context::USER      => _('Persönlich'),
-            'system'            => _('Global')
-        ];
-
-        PageLayout::setTitle(_('Aktivitäten konfigurieren'));
-        header('X-Title: ' . rawurlencode(PageLayout::getTitle()));
-
-        echo $template->render();
-    }
-}
diff --git a/public/plugins_packages/core/ActivityFeed/javascript/activityfeed.js b/public/plugins_packages/core/ActivityFeed/javascript/activityfeed.js
deleted file mode 100644
index 876db4e5019..00000000000
--- a/public/plugins_packages/core/ActivityFeed/javascript/activityfeed.js
+++ /dev/null
@@ -1,127 +0,0 @@
-(function($, STUDIP) {
-    STUDIP.ActivityFeed = {
-        user_id : null,
-        polling: null,
-        initial: true,
-        scrolledfrom: null,
-        maxheight: null,
-        filter: null,
-
-        init: function() {
-            STUDIP.ActivityFeed.maxheight = parseInt($('#stream-container').css('max-height').replace(/[^-\d\.]/g, ''));
-
-            STUDIP.ActivityFeed.loadFeed(STUDIP.ActivityFeed.filter);
-
-            $('#stream-container').scroll(function () {
-                var scrollBottom = $('#stream-container').scrollTop() + $('#stream-container').height() + 250;
-
-                if ($('#stream-container').prop('scrollHeight') < scrollBottom) {
-                    STUDIP.ActivityFeed.loadFeed(STUDIP.ActivityFeed.filter);
-                }
-            });
-
-
-            $(document).on('click', '.provider_circle', function () {
-                $(this).parent().parent().children('.activity-content').toggle();
-            }).on('click', '#toggle-all-activities,#toggle-user-activities', function () {
-                var toggled = $(this).is(':not(.toggled)');
-                $(this).toggleClass('toggled', toggled);
-
-                STUDIP.ActivityFeed.setToggleStatus();
-
-                return false;
-            });
-        },
-
-        getTemplate: _.memoize(function(name) {
-            return _.template($("script." + name).html());
-        }),
-
-        loadFeed: function(filtertype) {
-            if (STUDIP.ActivityFeed.user_id === null) {
-                console.log('Could not retrieve activities, no valid user id found!');
-                return false;
-            }
-
-            if (STUDIP.ActivityFeed.polling || !STUDIP.ActivityFeed.scrolledfrom) {
-                return false;
-            }
-
-            STUDIP.ActivityFeed.polling = true;
-
-            STUDIP.api.GET(['user', STUDIP.ActivityFeed.user_id, 'activitystream'], {
-                data: {
-                    filtertype: filtertype,
-                    scrollfrom: STUDIP.ActivityFeed.scrolledfrom
-                }
-            }).done(function (activities) {
-                var stream        = STUDIP.ActivityFeed.getTemplate('activity_stream');
-                var activity      = STUDIP.ActivityFeed.getTemplate('activity');
-                var activity_urls = STUDIP.ActivityFeed.getTemplate('activity-urls');
-                var num_entries   = Object.keys(activities).length;
-                var lastelem      = $(activities).last();
-
-                if (lastelem[0]) {
-                    STUDIP.ActivityFeed.scrolledfrom  = lastelem[0].mkdate;
-                } else {
-                    STUDIP.ActivityFeed.scrolledfrom = false;
-                }
-
-                STUDIP.ActivityFeed.writeToStream(stream({
-                    stream        : activities,
-                    num_entries   : num_entries,
-                    activity      : activity,
-                    activity_urls : activity_urls,
-                    user_id       :  STUDIP.ActivityFeed.user_id
-                }));
-
-                STUDIP.ActivityFeed.setToggleStatus();
-
-                if ($('#stream-container').height() < STUDIP.ActivityFeed.maxheight) {
-                    STUDIP.ActivityFeed.loadFeed('');
-                }
-            }).fail(function () {
-                var template = STUDIP.ActivityFeed.getTemplate('activity-load-error');
-                STUDIP.ActivityFeed.writeToStream(template());
-            }).always(function () {
-                STUDIP.ActivityFeed.polling = false;
-            });
-        },
-
-        writeToStream: function (html) {
-            if (STUDIP.ActivityFeed.initial) {
-                // replace data in DOM
-                $('#stream-container').html('');
-
-                STUDIP.ActivityFeed.initial = false;
-            }
-
-            $('#stream-container').append(html);
-        },
-
-        setToggleStatus: function() {
-            var show_details = $('#toggle-all-activities').is('.toggled'),
-                show_own     = $('#toggle-user-activities').is('.toggled');
-
-            // update toggle status fir activity contents
-            $('.activity-content').toggle(show_details);
-
-            // update toggle status for user's own activities
-            $('.activity:has(.provider_circle.right)').toggle(show_own);
-        },
-
-        updateFilter: function(filter) {
-            STUDIP.ActivityFeed.filter = filter;
-            STUDIP.ActivityFeed.initial = true;
-            STUDIP.ActivityFeed.scrolledfrom = Math.floor(Date.now() / 1000);
-
-            $('#stream-container').html('<div class="loading-indicator">'
-                + '<span class="load-1"></span>'
-                + '<span class="load-2"></span>'
-                + '<span class="load-3"></span>'
-                + '</div>');
-
-            STUDIP.ActivityFeed.init();
-        }
-    };
-})(jQuery, STUDIP);
diff --git a/public/plugins_packages/core/ActivityFeed/plugin.manifest b/public/plugins_packages/core/ActivityFeed/plugin.manifest
deleted file mode 100644
index e763516e651..00000000000
--- a/public/plugins_packages/core/ActivityFeed/plugin.manifest
+++ /dev/null
@@ -1,7 +0,0 @@
-pluginclassname=ActivityFeed
-pluginname=ActivityFeed
-origin=core
-version=1.0
-studipMinVersion=3.4
-plugincontext=Startseite
-description=Mit diesem Widget haben Sie alle Aktivitäten im Überblick.
diff --git a/public/plugins_packages/core/Blubber/plugin.manifest b/public/plugins_packages/core/Blubber/plugin.manifest
deleted file mode 100644
index 3cfbf1d5925..00000000000
--- a/public/plugins_packages/core/Blubber/plugin.manifest
+++ /dev/null
@@ -1,16 +0,0 @@
-pluginclassname=Blubber
-pluginname=Blubber
-origin=core
-version=3
-summary=Schneller und einfacher Austausch von Informationen
-description=Blubber ist eine Kommunikationsform mit Ähnlichkeiten zu einem Forum, in dem aber in Echtzeit miteinander kommuniziert werden kann und das durch den etwas informelleren Charakter eher einem Chat anmutet. Anders als im Forum ist es nicht notwendig, die Seiten neu zu laden, um die neuesten Einträge (z. B. Antworten auf eigene Postings) sehen zu können: Die Seite aktualisiert sich selbst bei neuen Einträgen. Dateien (z.B. Fotos, Audiodateien, Links) können per Drag and Drop in das Feld gezogen und somit verlinkt werden. Auch Textformatierungen und das Verwenden von Smileys sind möglich.
-
-screenshots = assets/images/plus/screenshots/Blubber
-screenshots.blubberscreenshot.png = Blubbern
-
-displayname = Blubber
-icon = assets/images/icons/black/blubber.svg
-keywords = Einfach Text schreiben und mit <Enter> abschicken; Direktes Kontaktieren anderer Stud.IP-NutzerInnen (@Vorname Nachname); Setzen von und Suche nach Stichworten über Hashtags (#Stichwort); Einbinden von Dateien per drag and drop
-category = Kommunikation und Zusammenarbeit
-descriptionshort = Schneller und einfacher Austausch von Informationen in Gesprächsform
-descriptionlong = Kommunikationsform mit Ähnlichkeiten zu einem Forum. Im Gegensatz zum Forum kann mit Blubber jedoch in Echtzeit miteinander kommuniziert werden. Das Tool ähnelt durch den etwas informelleren Charakter einem Messenger. Anders als im Forum ist es nicht notwendig, die Seiten neu zu laden, um die neuesten Einträge (z. B. Antworten auf eigene Postings) sehen zu können. Dateien (z. B. Fotos, Audiodateien, Links) können per drag and drop in das Feld gezogen und somit verlinkt werden. Auch Textformatierungen und das Verwenden von Smileys sind möglich.
diff --git a/public/plugins_packages/core/Blubber/views/messenger/course.php b/public/plugins_packages/core/Blubber/views/messenger/course.php
deleted file mode 100644
index 2b31011cf9d..00000000000
--- a/public/plugins_packages/core/Blubber/views/messenger/course.php
+++ /dev/null
@@ -1 +0,0 @@
-hey
\ No newline at end of file
diff --git a/public/plugins_packages/core/ContentsWidget/plugin.manifest b/public/plugins_packages/core/ContentsWidget/plugin.manifest
deleted file mode 100644
index b05cd4b52e1..00000000000
--- a/public/plugins_packages/core/ContentsWidget/plugin.manifest
+++ /dev/null
@@ -1,6 +0,0 @@
-pluginclassname=ContentsWidget
-pluginname=ContentsWidget
-origin=core
-version=1.0
-plugincontext=Startseite
-description=Mit diesem Widget haben Sie einen Überblick über Ihre Inhalte
diff --git a/public/plugins_packages/core/EvaluationsWidget/plugin.manifest b/public/plugins_packages/core/EvaluationsWidget/plugin.manifest
deleted file mode 100644
index f25701c99a5..00000000000
--- a/public/plugins_packages/core/EvaluationsWidget/plugin.manifest
+++ /dev/null
@@ -1,6 +0,0 @@
-pluginclassname=EvaluationsWidget
-pluginname=EvaluationsWidget
-origin=core
-version=1.0
-studipMinVersion=3.1
-description=Mit diesem Widget haben Sie Zugriff auf systemweite Umfragen.
diff --git a/public/plugins_packages/core/Forum/plugin.manifest b/public/plugins_packages/core/Forum/plugin.manifest
deleted file mode 100644
index 10df6d76f0b..00000000000
--- a/public/plugins_packages/core/Forum/plugin.manifest
+++ /dev/null
@@ -1,17 +0,0 @@
-pluginclassname=CoreForum
-pluginname=Forum
-origin=core
-version=3.0.3
-summary=Diskussionen und veranstaltungsbegleitender Meinungsaustausch
-description=Textbasierte zeit- und ortsunabhängige Möglichkeit zum Austausch von Gedanken, Meinungen und Erfahrungen. Lehrende und/oder Studierende können parallel zu Veranstaltungsthemen Fragen stellen, die in Form von Textbeiträgen besprochen werden können. Diese Beiträge können von allen Teilnehmenden der Veranstaltung gemerkt, verlinkt, positiv bewertet (sog. "Gefällt mir") und editiert werden (Letzeres nur von Lehrenden). Lehrende können zusätzlich Themen in Bereiche gliedern, zwischen den Bereichen verschiebe, im Bereich hervorheben und diesen öffnen und schließen.
-
-displayname = Forum
-icon = assets/images/icons/black/forum.svg
-keywords = Möglichkeit zum intensiven, nachhaltigen textbasierten Austausch; (nachträgliche) Strukturierung der Beiträge; Editierfunktion für Lehrende
-category = Kommunikation und Zusammenarbeit
-descriptionshort = Veranstaltungsbegleitender Meinungsaustausch zu bestimmten Themen
-descriptionlong = Textbasierte zeit- und ortsunabhängige Möglichkeit zum Austausch von Gedanken, Meinungen und Erfahrungen. Lehrende und/oder Studierende können parallel zu Veranstaltungsthemen Fragen stellen, die in Form von Textbeiträgen besprochen werden können. Diese Beiträge können von allen Teilnehmenden der Veranstaltung gemerkt, verlinkt, positiv bewertet (sog. "Gefällt mir") und editiert werden (Letzeres nur von Lehrenden). Lehrende können zusätzlich Themen in Bereiche gliedern, zwischen den Bereichen verschieben, im Bereich hervorheben und diesen öffnen und schließen.
-
-screenshot = assets/images/plus/screenshots/Forum/Lehrendensicht_-_Kategorien_mit_Bereichen_und_Beitraegen.jpg
-screenshot = assets/images/plus/screenshots/Forum/Studentische_Sicht_-_Kategorien_mit_Bereichen_und_Beitraegen.jpg
-screenshot = assets/images/plus/screenshots/Forum/Einen_Forumsbeitrag_erstellen.jpg
diff --git a/public/plugins_packages/core/NewsWidget/plugin.manifest b/public/plugins_packages/core/NewsWidget/plugin.manifest
deleted file mode 100644
index 406309aa890..00000000000
--- a/public/plugins_packages/core/NewsWidget/plugin.manifest
+++ /dev/null
@@ -1,6 +0,0 @@
-pluginclassname=NewsWidget
-pluginname=NewsWidget
-origin=core
-version=1.0
-studipMinVersion=3.1
-description=Mit diesem Widget haben Sie Zugriff auf systemweite Ankündigungen.
diff --git a/public/plugins_packages/core/QuickSelection/QuickSelection.php b/public/plugins_packages/core/QuickSelection/QuickSelection.php
deleted file mode 100644
index 70590b2340a..00000000000
--- a/public/plugins_packages/core/QuickSelection/QuickSelection.php
+++ /dev/null
@@ -1,99 +0,0 @@
-<?php
-/*
- * QuickSelection.php - widget plugin for start page
- *
- * Copyright (C) 2014 - Nadine Werner <nadwerner@uos.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 (at your option) any later version.
- */
-
-class QuickSelection extends StudIPPlugin implements PortalPlugin
-{
-    public function getPluginName()
-    {
-        return _('Schnellzugriff');
-    }
-
-    public function getPortalTemplate()
-    {
-        PageLayout::addScript($this->getPluginUrl() . '/js/QuickSelection.js');
-        $names = WidgetHelper::getWidgetUserConfig($GLOBALS['user']->id, 'QUICK_SELECTION');
-
-        $template_factory = new Flexi_TemplateFactory(__DIR__ . '/templates');
-        $template = $template_factory->open('list');
-        $template->navigation = $this->getFilteredNavigation($names);
-
-        $navigation = new Navigation('', PluginEngine::getLink($this, [], 'configuration'));
-        $navigation->setImage(Icon::create('edit', 'clickable', ["title" => _('Konfigurieren')]), ['data-dialog'=>'size=auto']);
-
-        $template->icons = [$navigation];
-
-        return $template;
-    }
-
-    private function getFilteredNavigation($items)
-    {
-        $result = [];
-
-        $navigation = Navigation::getItem('/start');
-        foreach ($navigation as $name => $nav) {
-            // if config is new (key:value) display values which are not in config array
-            // otherwise hide items which are not in config array
-            // This is important for patching.
-            if (!isset($items[$name]) || $items[$name] !== 'deactivated') {
-                $result[] = $nav;
-            }
-        }
-
-        return $result;
-    }
-
-    public function save_action()
-    {
-        if (Config::get()->QUICK_SELECTION === null) {
-            Config::get()->create('QUICK_SELECTION', [
-                'range'       => 'user',
-                'type'        => 'array',
-                'description' => 'Einstellungen des QuickSelection-Widgets',
-            ]);
-        }
-
-        $add_removes = Request::optionArray('add_removes');
-
-        // invert add_removes so that only unchecked values are stored into config
-        $names = [];
-
-        $navigation = Navigation::getItem('/start');
-        foreach ($navigation as $name => $nav) {
-            if (!in_array($name, $add_removes)) {
-                $names[$name] = 'deactivated';
-            }
-
-        }
-
-        WidgetHelper::addWidgetUserConfig($GLOBALS['user']->id, 'QUICK_SELECTION', $names);
-
-        $template_factory = new Flexi_TemplateFactory(__DIR__ . '/templates');
-        $template = $template_factory->open('list');
-        $template->navigation = $this->getFilteredNavigation($names);
-
-        header('X-Dialog-Close: 1');
-        header('X-Dialog-Execute: STUDIP.QuickSelection.update');
-
-        echo $template->render();
-    }
-
-    public function configuration_action()
-    {
-        $template_factory = new Flexi_TemplateFactory(__DIR__ . '/templates');
-        $template = $template_factory->open('edit');
-        $template->links = Navigation::getItem('/start');
-        $template->config = WidgetHelper::getWidgetUserConfig($GLOBALS['user']->id, 'QUICK_SELECTION');
-        $template->plugin = $this;
-
-        header('X-Title: ' . _('Schnellzugriff konfigurieren'));
-        echo $template->render();
-    }
-}
diff --git a/public/plugins_packages/core/QuickSelection/plugin.manifest b/public/plugins_packages/core/QuickSelection/plugin.manifest
deleted file mode 100644
index 00280f006d8..00000000000
--- a/public/plugins_packages/core/QuickSelection/plugin.manifest
+++ /dev/null
@@ -1,6 +0,0 @@
-pluginclassname=QuickSelection
-pluginname=QuickSelection
-origin=core
-version=1.0
-studipMinVersion=3.1
-description=Mit dem Schnellzugriff-Widget können Sie Links zu bestimmten Bereichen in Stud.IP verwalten.
diff --git a/public/plugins_packages/core/ScheduleWidget/plugin.manifest b/public/plugins_packages/core/ScheduleWidget/plugin.manifest
deleted file mode 100644
index 3b7a03e0162..00000000000
--- a/public/plugins_packages/core/ScheduleWidget/plugin.manifest
+++ /dev/null
@@ -1,6 +0,0 @@
-pluginclassname=ScheduleWidget
-pluginname=ScheduleWidget
-origin=core
-version=3.0
-plugincontext=Startseite
-description=Mit diesem Widget haben Sie eine Übersicht Ihres aktuellen Stundenplans.
diff --git a/public/plugins_packages/core/TerminWidget/plugin.manifest b/public/plugins_packages/core/TerminWidget/plugin.manifest
deleted file mode 100644
index ed0e091e046..00000000000
--- a/public/plugins_packages/core/TerminWidget/plugin.manifest
+++ /dev/null
@@ -1,6 +0,0 @@
-pluginclassname=TerminWidget
-pluginname=TerminWidget
-origin=core
-version=3.0
-plugincontext=Startseite
-description=Mit diesem Widget haben Sie ihre aktuellen Termine im Überlick.
diff --git a/resources/assets/javascripts/init.js b/resources/assets/javascripts/init.js
index a1000e0a888..f7c3dda3cea 100644
--- a/resources/assets/javascripts/init.js
+++ b/resources/assets/javascripts/init.js
@@ -1,6 +1,7 @@
 import Vue from './lib/studip-vue.js';
 
 import ActionMenu from './lib/actionmenu.js';
+import ActivityFeed from './lib/activityfeed.js';
 import admin_sem_class from './lib/admin_sem_class.js';
 import Admission from './lib/admission.js';
 import Arbeitsgruppen from './lib/arbeitsgruppen.js';
@@ -56,6 +57,7 @@ import Plus from './lib/plus.js';
 import QRCode from './lib/qr_code.js';
 import Questionnaire from './lib/questionnaire.js';
 import QuickSearch from './lib/quick_search.js';
+import QuickSelection from './lib/quick_selection.js';
 import Raumzeit from './lib/raumzeit.js';
 import {ready, domReady, dialogReady} from './lib/ready.js';
 import register from './lib/register.js';
@@ -87,6 +89,7 @@ const URLHelper = createURLHelper(configURLHelper);
 
 window.STUDIP = _.assign(window.STUDIP || {}, {
     ActionMenu,
+    ActivityFeed,
     admin_sem_class,
     Admission,
     api,
@@ -143,6 +146,7 @@ window.STUDIP = _.assign(window.STUDIP || {}, {
     QRCode,
     Questionnaire,
     QuickSearch,
+    QuickSelection,
     Raumzeit,
     register,
     Report,
diff --git a/resources/assets/javascripts/lib/activityfeed.js b/resources/assets/javascripts/lib/activityfeed.js
new file mode 100644
index 00000000000..95145cb6512
--- /dev/null
+++ b/resources/assets/javascripts/lib/activityfeed.js
@@ -0,0 +1,127 @@
+const ActivityFeed = {
+    user_id : null,
+    polling: null,
+    initial: true,
+    scrolledfrom: null,
+    maxheight: null,
+    filter: null,
+
+    init: function() {
+        STUDIP.ActivityFeed.maxheight = parseInt($('#stream-container').css('max-height').replace(/[^-\d\.]/g, ''));
+
+        STUDIP.ActivityFeed.loadFeed(STUDIP.ActivityFeed.filter);
+
+        $('#stream-container').scroll(function () {
+            var scrollBottom = $('#stream-container').scrollTop() + $('#stream-container').height() + 250;
+
+            if ($('#stream-container').prop('scrollHeight') < scrollBottom) {
+                STUDIP.ActivityFeed.loadFeed(STUDIP.ActivityFeed.filter);
+            }
+        });
+
+
+        $(document).on('click', '.provider_circle', function () {
+            $(this).parent().parent().children('.activity-content').toggle();
+        }).on('click', '#toggle-all-activities,#toggle-user-activities', function () {
+            var toggled = $(this).is(':not(.toggled)');
+            $(this).toggleClass('toggled', toggled);
+
+            STUDIP.ActivityFeed.setToggleStatus();
+
+            return false;
+        });
+    },
+
+    getTemplate: _.memoize(function(name) {
+        return _.template($("script." + name).html());
+    }),
+
+    loadFeed: function(filtertype) {
+        if (STUDIP.ActivityFeed.user_id === null) {
+            console.log('Could not retrieve activities, no valid user id found!');
+            return false;
+        }
+
+        if (STUDIP.ActivityFeed.polling || !STUDIP.ActivityFeed.scrolledfrom) {
+            return false;
+        }
+
+        STUDIP.ActivityFeed.polling = true;
+
+        STUDIP.api.GET(['user', STUDIP.ActivityFeed.user_id, 'activitystream'], {
+            data: {
+                filtertype: filtertype,
+                scrollfrom: STUDIP.ActivityFeed.scrolledfrom
+            }
+        }).done(function (activities) {
+            var stream        = STUDIP.ActivityFeed.getTemplate('activity_stream');
+            var activity      = STUDIP.ActivityFeed.getTemplate('activity');
+            var activity_urls = STUDIP.ActivityFeed.getTemplate('activity-urls');
+            var num_entries   = Object.keys(activities).length;
+            var lastelem      = $(activities).last();
+
+            if (lastelem[0]) {
+                STUDIP.ActivityFeed.scrolledfrom  = lastelem[0].mkdate;
+            } else {
+                STUDIP.ActivityFeed.scrolledfrom = false;
+            }
+
+            STUDIP.ActivityFeed.writeToStream(stream({
+                stream        : activities,
+                num_entries   : num_entries,
+                activity      : activity,
+                activity_urls : activity_urls,
+                user_id       :  STUDIP.ActivityFeed.user_id
+            }));
+
+            STUDIP.ActivityFeed.setToggleStatus();
+
+            if ($('#stream-container').height() < STUDIP.ActivityFeed.maxheight) {
+                STUDIP.ActivityFeed.loadFeed('');
+            }
+        }).fail(function () {
+            var template = STUDIP.ActivityFeed.getTemplate('activity-load-error');
+            STUDIP.ActivityFeed.writeToStream(template());
+        }).always(function () {
+            STUDIP.ActivityFeed.polling = false;
+        });
+    },
+
+    writeToStream: function (html) {
+        if (STUDIP.ActivityFeed.initial) {
+            // replace data in DOM
+            $('#stream-container').html('');
+
+            STUDIP.ActivityFeed.initial = false;
+        }
+
+        $('#stream-container').append(html);
+    },
+
+    setToggleStatus: function() {
+        var show_details = $('#toggle-all-activities').is('.toggled'),
+            show_own     = $('#toggle-user-activities').is('.toggled');
+
+        // update toggle status fir activity contents
+        $('.activity-content').toggle(show_details);
+
+        // update toggle status for user's own activities
+        $('.activity:has(.provider_circle.right)').toggle(show_own);
+    },
+
+    updateFilter: function(filter) {
+        STUDIP.ActivityFeed.filter = filter;
+        STUDIP.ActivityFeed.initial = true;
+        STUDIP.ActivityFeed.scrolledfrom = Math.floor(Date.now() / 1000);
+
+        $('#stream-container').html('<div class="loading-indicator">'
+            + '<span class="load-1"></span>'
+            + '<span class="load-2"></span>'
+            + '<span class="load-3"></span>'
+            + '</div>');
+
+        STUDIP.ActivityFeed.init();
+    }
+};
+
+export default ActivityFeed;
diff --git a/resources/assets/javascripts/lib/forum.js b/resources/assets/javascripts/lib/forum.js
index 9a6ff176deb..776352720f2 100644
--- a/resources/assets/javascripts/lib/forum.js
+++ b/resources/assets/javascripts/lib/forum.js
@@ -30,7 +30,7 @@ const Forum = {
 
                 jQuery.ajax({
                     type: 'POST',
-                    url: STUDIP.URLHelper.getURL('plugins.php/coreforum/index/savecats?cid=' + STUDIP.Forum.seminar_id),
+                    url: STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/savecats?cid=' + STUDIP.Forum.seminar_id),
                     data: categories
                 });
             }
@@ -69,7 +69,7 @@ const Forum = {
             STUDIP.Forum.closeDialog();
 
             // ajax call to make the deletion permanent
-            jQuery.ajax(STUDIP.URLHelper.getURL('plugins.php/coreforum/index/delete_entry/'
+            jQuery.ajax(STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/delete_entry/'
                 + STUDIP.Forum.current_area_id + '?cid=' + STUDIP.Forum.seminar_id), {
                 method: 'post',
                 data: {'security_token' : STUDIP.CSRF_TOKEN.value},
@@ -92,7 +92,7 @@ const Forum = {
             });
 
             // ajax call to make the deletion permanent
-            jQuery.ajax(STUDIP.URLHelper.getURL('plugins.php/coreforum/index/remove_category/'
+            jQuery.ajax(STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/remove_category/'
                 + STUDIP.Forum.current_category_id + '?cid=' + STUDIP.Forum.seminar_id), {
                 method: 'post',
                 data: {'security_token' : STUDIP.CSRF_TOKEN.value},
@@ -150,7 +150,7 @@ const Forum = {
         jQuery('table[data-category-id=' + category_id + '] span.edit_category').remove();
         jQuery('table[data-category-id=' + category_id + '] span.category_name').show();
 
-        jQuery.ajax(STUDIP.URLHelper.getURL('plugins.php/coreforum/index/edit_category/' + category_id + '?cid=' + STUDIP.Forum.seminar_id), {
+        jQuery.ajax(STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/edit_category/' + category_id + '?cid=' + STUDIP.Forum.seminar_id), {
             type: 'POST',
             data: name
         });
@@ -173,7 +173,7 @@ const Forum = {
 
         jQuery.ajax({
             type: 'POST',
-            url: STUDIP.URLHelper.getURL('plugins.php/coreforum/area/save_order?cid=' + STUDIP.Forum.seminar_id),
+            url: STUDIP.URLHelper.getURL('dispatch.php/course/forum/area/save_order?cid=' + STUDIP.Forum.seminar_id),
             data: areas
         });
     },
@@ -209,7 +209,7 @@ const Forum = {
         // disable submit and cancel buttons, there is no turning back now
         $('.button', this).prop('disabled', true);
 
-        jQuery.ajax(STUDIP.URLHelper.getURL('plugins.php/coreforum/area/add/' + values.category_id + '?cid=' + STUDIP.Forum.seminar_id), {
+        jQuery.ajax(STUDIP.URLHelper.getURL('dispatch.php/course/forum/area/add/' + values.category_id + '?cid=' + STUDIP.Forum.seminar_id), {
             type: 'POST',
             data: values,
             success: function(data) {
@@ -269,7 +269,7 @@ const Forum = {
         jQuery('tr[data-area-id=' + area_id + '] div.areacontent').data('content', name.content);
 
         // store the modified area and get formatted content-text from server
-        jQuery.ajax(STUDIP.URLHelper.getURL('plugins.php/coreforum/area/edit/' + area_id + '?cid=' + STUDIP.Forum.seminar_id), {
+        jQuery.ajax(STUDIP.URLHelper.getURL('dispatch.php/course/forum/area/edit/' + area_id + '?cid=' + STUDIP.Forum.seminar_id), {
             type: 'POST',
             data: name,
             success: function(data)  {
@@ -315,7 +315,7 @@ const Forum = {
         // remember current textarea value
         textarea.data('reset', textarea.val());
 
-        jQuery.ajax(STUDIP.URLHelper.getURL('plugins.php/coreforum/index/update_entry/' + topic_id + '?cid=' + STUDIP.Forum.seminar_id), {
+        jQuery.ajax(STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/update_entry/' + topic_id + '?cid=' + STUDIP.Forum.seminar_id), {
             type: 'POST',
             data: jQuery('form[data-topicid='+ topic_id +']').serializeObject(),
 
@@ -489,7 +489,7 @@ const Forum = {
                     + nl + nl
                     + $gettext('Link zum Beitrag: ')
                     + nl
-                    + STUDIP.URLHelper.getURL('plugins.php/coreforum/index/index/'
+                    + STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/index/'
                     + topic_id + '?cid=' + STUDIP.Forum.seminar_id + '&again=yes#' + topic_id)
                     + nl + nl
                     + content
@@ -543,7 +543,7 @@ const Forum = {
             posting.posting = STUDIP.wysiwyg.markAsHtml(posting.posting);
         }
 
-        jQuery.ajax(STUDIP.URLHelper.getURL('plugins.php/coreforum/index/preview?cid=' + STUDIP.Forum.seminar_id), {
+        jQuery.ajax(STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/preview?cid=' + STUDIP.Forum.seminar_id), {
             type: 'POST',
             data: posting,
             success: function (html) {
@@ -556,7 +556,7 @@ const Forum = {
     },
 
     loadAction: function(element, action) {
-        jQuery(element).load(STUDIP.URLHelper.getURL('plugins.php/coreforum/index/'
+        jQuery(element).load(STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/'
             + action + '?cid=' + STUDIP.Forum.seminar_id))
     },
 
@@ -578,14 +578,14 @@ const Forum = {
     },
 
     setFavorite: function(topic_id) {
-        jQuery('#favorite_' + topic_id).load(STUDIP.URLHelper.getURL('plugins.php/coreforum/index/set_favorite/'
+        jQuery('#favorite_' + topic_id).load(STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/set_favorite/'
             + topic_id + '?cid=' + STUDIP.Forum.seminar_id));
         jQuery('a.marked[data-topic-id=' + topic_id +']').show();
         return false;
     },
 
     unsetFavorite: function(topic_id) {
-        jQuery('#favorite_' + topic_id).load(STUDIP.URLHelper.getURL('plugins.php/coreforum/index/unset_favorite/'
+        jQuery('#favorite_' + topic_id).load(STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/unset_favorite/'
             + topic_id + '?cid=' + STUDIP.Forum.seminar_id));
         jQuery('a.marked[data-topic-id=' + topic_id +']').hide();
         return false;
@@ -601,7 +601,7 @@ const Forum = {
         // jQuery('li[data-id=' + topic_id + '] > a.tooltip2').showAjaxNotification();
 
         // load children from server and show them
-        jQuery.ajax(STUDIP.URLHelper.getURL('plugins.php/coreforum/admin/childs/' + topic_id), {
+        jQuery.ajax(STUDIP.URLHelper.getURL('dispatch.php/course/forum/admin/childs/' + topic_id), {
             dataType: 'html',
             success: function(response) {
                 jQuery('li[data-id=' + topic_id + ']').append(response);
@@ -664,7 +664,7 @@ const Forum = {
     paste: function(topic_id) {
         // jQuery('li[data-id=' + topic_id + '] > a.tooltip2').showAjaxNotification();
 
-        jQuery.ajax(STUDIP.URLHelper.getURL('plugins.php/coreforum/admin/move/' + topic_id), {
+        jQuery.ajax(STUDIP.URLHelper.getURL('dispatch.php/course/forum/admin/move/' + topic_id), {
             data : {
                 'topics' : STUDIP.Forum.clipboard
             },
@@ -742,7 +742,7 @@ const Forum = {
     openThread: function(topic_id, redirect, page, showSuccessMessage) {
         jQuery.ajax({
             type: 'GET',
-            url: STUDIP.URLHelper.getURL('plugins.php/coreforum/index/open_thread/' + topic_id + '/' + redirect + '/' + page),
+            url: STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/open_thread/' + topic_id + '/' + redirect + '/' + page),
             success: function(data) {
                 if (showSuccessMessage == true) {
                     jQuery('#message_area').html(data);
@@ -786,7 +786,7 @@ const Forum = {
 
         jQuery.ajax({
             type: 'GET',
-            url: STUDIP.URLHelper.getURL('plugins.php/coreforum/index/close_thread/' + topic_id + '/' + redirect + '/' + page),
+            url: STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/close_thread/' + topic_id + '/' + redirect + '/' + page),
             success: function(data) {
                 if (showSuccessMessage == true) {
                     jQuery('#message_area').html(data);
@@ -800,7 +800,7 @@ const Forum = {
     makeThreadStickyFromThread: function(topic_id) {
         jQuery.ajax({
             type: 'GET',
-            url: STUDIP.URLHelper.getURL('plugins.php/coreforum/index/make_sticky/' + topic_id + '/' + topic_id + '/0'),
+            url: STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/make_sticky/' + topic_id + '/' + topic_id + '/0'),
             success: function(data) {
                 jQuery('#message_area').html(data);
                 var linkText = $gettext('Hervorhebung aufheben');
@@ -815,7 +815,7 @@ const Forum = {
     makeThreadUnstickyFromThread: function(topic_id) {
         jQuery.ajax({
             type: 'GET',
-            url: STUDIP.URLHelper.getURL('plugins.php/coreforum/index/make_unsticky/' + topic_id + '/' + topic_id + '/0'),
+            url: STUDIP.URLHelper.getURL('dispatch.php/course/forum/index/make_unsticky/' + topic_id + '/' + topic_id + '/0'),
             success: function(data) {
                 jQuery('#message_area').html(data);
                 var linkText = $gettext('Thema hervorheben');
diff --git a/public/plugins_packages/core/QuickSelection/js/QuickSelection.js b/resources/assets/javascripts/lib/quick_selection.js
similarity index 55%
rename from public/plugins_packages/core/QuickSelection/js/QuickSelection.js
rename to resources/assets/javascripts/lib/quick_selection.js
index c15676b8579..7fd0399b4cb 100644
--- a/public/plugins_packages/core/QuickSelection/js/QuickSelection.js
+++ b/resources/assets/javascripts/lib/quick_selection.js
@@ -1,8 +1,7 @@
-/*jslint browser: true */
-/*global jQuery, STUDIP */
-
-STUDIP.QuickSelection = {
+const QuickSelection = {
     update: function (html) {
         jQuery('#quickSelectionWrap').replaceWith(html);
     }
 };
+
+export default QuickSelection;
diff --git a/public/plugins_packages/core/ActivityFeed/css/style.less b/resources/assets/stylesheets/less/activityfeed.less
similarity index 99%
rename from public/plugins_packages/core/ActivityFeed/css/style.less
rename to resources/assets/stylesheets/less/activityfeed.less
index a1ca7adf8c2..75fe917216e 100644
--- a/public/plugins_packages/core/ActivityFeed/css/style.less
+++ b/resources/assets/stylesheets/less/activityfeed.less
@@ -1,5 +1,3 @@
-// out: style.css
-
 #stream-container {
     padding: 5px;
     margin: 5px;
diff --git a/resources/assets/stylesheets/studip.less b/resources/assets/stylesheets/studip.less
index a88e7306f89..03f3f29eb04 100644
--- a/resources/assets/stylesheets/studip.less
+++ b/resources/assets/stylesheets/studip.less
@@ -66,6 +66,7 @@
 @import "less/profile.less";
 @import "less/consultation.less";
 
+@import "less/activityfeed.less";
 @import "less/mobile.less";
 @import "less/pagination.less";
 @import "less/enrolment.less";
diff --git a/public/plugins_packages/core/Forum/views/index/_mail_notification.php b/templates/mail/forum_notification.php
similarity index 88%
rename from public/plugins_packages/core/Forum/views/index/_mail_notification.php
rename to templates/mail/forum_notification.php
index 9ce1d420776..dc446496011 100644
--- a/public/plugins_packages/core/Forum/views/index/_mail_notification.php
+++ b/templates/mail/forum_notification.php
@@ -11,9 +11,9 @@ $message = [
     ),
     'title' => $topic['name'] ? '**' . $topic['name'] ."** \n\n" : '',
     'content' => $topic['content'],
-    'url' => _('Beitrag im Forum ansehen:') .' '. UrlHelper::getUrl(
+    'url' => _('Beitrag im Forum ansehen:') .' '. URLHelper::getURL(
         $GLOBALS['ABSOLUTE_URI_STUDIP']
-        . 'plugins.php/coreforum/index/index/'
+        . 'dispatch.php/course/forum/index/index/'
         . $topic['topic_id']
         .'?cid='
         . $topic['seminar_id']
diff --git a/templates/online/user.php b/templates/online/user.php
index 82d82130c1b..931aaabf3af 100644
--- a/templates/online/user.php
+++ b/templates/online/user.php
@@ -35,7 +35,7 @@
 
     <td width="3%" align="center">
         <? if (class_exists("Blubber")) : ?>
-        <a href="<?= URLHelper::getLink('plugins.php/blubber/streams/global', ['mention' => $tmp_online_uname]) ?>">
+        <a href="<?= URLHelper::getLink('dispatch.php/course/streams/global', ['mention' => $tmp_online_uname]) ?>">
             <?= Icon::create('blubber', 'clickable', ['title' => _("Blubber diesen Nutzer an"), 'class' => 'text-bottom'])->asImg() ?>
         </a>
         <? endif ?>
diff --git a/public/plugins_packages/core/ActivityFeed/templates/_jstemplates.php b/templates/start/_jstemplates.php
similarity index 100%
rename from public/plugins_packages/core/ActivityFeed/templates/_jstemplates.php
rename to templates/start/_jstemplates.php
diff --git a/public/plugins_packages/core/ActivityFeed/templates/activity_feed.php b/templates/start/activityfeed.php
similarity index 90%
rename from public/plugins_packages/core/ActivityFeed/templates/activity_feed.php
rename to templates/start/activityfeed.php
index c6bae300fe0..6d86cf16fa5 100644
--- a/public/plugins_packages/core/ActivityFeed/templates/activity_feed.php
+++ b/templates/start/activityfeed.php
@@ -15,5 +15,5 @@
     </div>
 </div>
 
-<?= $this->render_partial('_jstemplates'); ?>
+<?= $this->render_partial('start/_jstemplates'); ?>
 </div>
diff --git a/public/plugins_packages/core/ContentsWidget/templates/index.php b/templates/start/contents.php
similarity index 100%
rename from public/plugins_packages/core/ContentsWidget/templates/index.php
rename to templates/start/contents.php
diff --git a/public/plugins_packages/core/QuickSelection/templates/list.php b/templates/start/quickselection.php
similarity index 100%
rename from public/plugins_packages/core/QuickSelection/templates/list.php
rename to templates/start/quickselection.php
diff --git a/tests/jsonapi/ForumEntriesShowTest.php b/tests/jsonapi/ForumEntriesShowTest.php
index 2443fa64de9..e8238428e9d 100644
--- a/tests/jsonapi/ForumEntriesShowTest.php
+++ b/tests/jsonapi/ForumEntriesShowTest.php
@@ -1,6 +1,5 @@
 <?php
 
-require_once 'public/plugins_packages/core/Forum/models/ForumEntry.php';
 require_once 'ForumTestHelper.php';
 
 use JsonApi\Models\ForumEntry as ForumEntryModel;
-- 
GitLab