diff --git a/composer.json b/composer.json
index 3a5517af80e813265074eb3178bea644b263bbbb..60f572292026e037561b58802fdb5cb990a9e6a9 100644
--- a/composer.json
+++ b/composer.json
@@ -71,7 +71,8 @@
 		"typo3/class-alias-loader": {
 			"always-add-alias-loader": true,
 			"class-alias-maps": [
-				"typo3/sysext/fluid/Migrations/Code/ClassAliasMap.php"
+				"typo3/sysext/fluid/Migrations/Code/ClassAliasMap.php",
+				"typo3/sysext/version/Migrations/Code/ClassAliasMap.php"
 			]
 		},
 		"branch-alias": {
diff --git a/composer.lock b/composer.lock
index 653a4e97a0cbc5e6e2413b8056ecf4b6d5629ff7..2bdf653fc73a733e35413c6458c131e92c84b9b4 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,8 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "bd45a31718f3f2b434d0701affeacd7f",
-    "content-hash": "dccbff898b61e7232d2909a7d4754802",
+    "hash": "3877a0f2b3b3699c2a35a483f16f828d",
+    "content-hash": "04d35a4e2c2b4ff439218676f6f30058",
     "packages": [
         {
             "name": "cogpowered/finediff",
diff --git a/typo3/sysext/version/Classes/Task/AutoPublishTask.php b/typo3/sysext/version/Classes/Task/AutoPublishTask.php
deleted file mode 100644
index 40b3a5f09d3e2520d6064e1612dd8cd604b0be74..0000000000000000000000000000000000000000
--- a/typo3/sysext/version/Classes/Task/AutoPublishTask.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-namespace TYPO3\CMS\Version\Task;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-/**
- * This class provides a wrapper around the autopublication
- * mechanism of workspaces, as a Scheduler task
- */
-class AutoPublishTask extends \TYPO3\CMS\Scheduler\Task\AbstractTask
-{
-    /**
-     * Method executed from the Scheduler.
-     * Call on the workspace logic to publish workspaces whose publication date
-     * is in the past
-     *
-     * @return void
-     */
-    public function execute()
-    {
-        // Load the workspace library class and instatiate it
-        $autopubObj = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Version\Utility\WorkspacesUtility::class);
-        // Publish the workspaces that need to be
-        $autopubObj->autoPublishWorkspaces();
-        // There's no feedback from the publishing process,
-        // so there can't be any failure.
-        // @todo This could certainly be improved.
-        return true;
-    }
-}
diff --git a/typo3/sysext/version/Classes/Utility/WorkspacesUtility.php b/typo3/sysext/version/Classes/Utility/WorkspacesUtility.php
deleted file mode 100644
index 89b02b000f2b42163b8c32244235656845b3b155..0000000000000000000000000000000000000000
--- a/typo3/sysext/version/Classes/Utility/WorkspacesUtility.php
+++ /dev/null
@@ -1,206 +0,0 @@
-<?php
-namespace TYPO3\CMS\Version\Utility;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Database\ConnectionPool;
-use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
-use TYPO3\CMS\Core\Database\Query\Restriction\RootLevelRestriction;
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-/**
- * Library with Workspace related functionality
- */
-class WorkspacesUtility
-{
-    /**
-     * Building tcemain CMD-array for swapping all versions in a workspace.
-     *
-     * @param int $wsid Real workspace ID, cannot be ONLINE (zero).
-     * @param bool $doSwap If set, then the currently online versions are swapped into the workspace in exchange for the offline versions. Otherwise the workspace is emptied.
-     * @param int $pageId
-     * @return array Command array for tcemain
-     */
-    public function getCmdArrayForPublishWS($wsid, $doSwap, $pageId = 0)
-    {
-        $wsid = (int)$wsid;
-        $cmd = [];
-        if ($wsid >= -1 && $wsid !== 0) {
-            // Define stage to select:
-            $stage = -99;
-            if ($wsid > 0) {
-                $workspaceRec = BackendUtility::getRecord('sys_workspace', $wsid);
-                if ($workspaceRec['publish_access'] & 1) {
-                    $stage = 10;
-                }
-            }
-            // Select all versions to swap:
-            $versions = $this->selectVersionsInWorkspace($wsid, 0, $stage, $pageId ? $pageId : -1);
-            // Traverse the selection to build CMD array:
-            foreach ($versions as $table => $records) {
-                foreach ($records as $rec) {
-                    // Build the cmd Array:
-                    $cmd[$table][$rec['t3ver_oid']]['version'] = [
-                        'action' => 'swap',
-                        'swapWith' => $rec['uid'],
-                        'swapIntoWS' => $doSwap ? 1 : 0
-                    ];
-                }
-            }
-        }
-        return $cmd;
-    }
-
-    /**
-     * Select all records from workspace pending for publishing
-     * Used from backend to display workspace overview
-     * User for auto-publishing for selecting versions for publication
-     *
-     * @param int $wsid Workspace ID. If -99, will select ALL versions from ANY workspace. If -98 will select all but ONLINE. >=-1 will select from the actual workspace
-     * @param int $filter Lifecycle filter: 1 = select all drafts (never-published), 2 = select all published one or more times (archive/multiple), anything else selects all.
-     * @param int $stage Stage filter: -99 means no filtering, otherwise it will be used to select only elements with that stage. For publishing, that would be "10
-     * @param int $pageId Page id: Live page for which to find versions in workspace!
-     * @return array Array of all records uids etc. First key is table name, second key incremental integer. Records are associative arrays with uid and t3ver_oid fields. The REAL pid of the online record is found as "realpid
-     */
-    public function selectVersionsInWorkspace($wsid, $filter = 0, $stage = -99, $pageId = -1)
-    {
-        $wsid = (int)$wsid;
-        $filter = (int)$filter;
-        $pageId = (int)$pageId;
-        $stage = (int)$stage;
-        $output = [];
-        // Traversing all tables supporting versioning:
-        foreach ($GLOBALS['TCA'] as $table => $cfg) {
-            if ($GLOBALS['TCA'][$table]['ctrl']['versioningWS']) {
-                // Select all records from this table in the database from the workspace
-                // This joins the online version with the offline version as tables A and B
-                $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
-                    ->getQueryBuilderForTable($table);
-                $queryBuilder->getRestrictions()
-                    ->removeAll()
-                    ->add(GeneralUtility::makeInstance(DeletedRestriction::class));
-
-                $queryBuilder
-                    ->select('A.uid', 'A.t3ver_oid', 'B.pid AS realpid')
-                    ->from($table, 'A')
-                    ->from($table, 'B')
-                    ->where(
-                        $queryBuilder->expr()->eq('A.pid', -1),
-                        $queryBuilder->expr()->gt('B.pid', 0),
-                        $queryBuilder->expr()->eq('A.t3ver_oid', $queryBuilder->quoteIdentifier('B.uid'))
-                    );
-
-                if ($pageId !== -1) {
-                    if ($table === 'pages') {
-                        $queryBuilder->andWhere($queryBuilder->expr()->eq('B.uid', $pageId));
-                    } else {
-                        $queryBuilder->andWhere($queryBuilder->expr()->eq('B.pid', $pageId));
-                    }
-                }
-
-                if ($wsid > -98) {
-                    $queryBuilder->andWhere($queryBuilder->expr()->eq('A.t3ver_wsid', $wsid));
-                } elseif ($wsid === -98) {
-                    $queryBuilder->andWhere($queryBuilder->expr()->neq('A.t3ver_wsid', 0));
-                }
-
-                if ($stage !== -99) {
-                    $queryBuilder->andWhere($queryBuilder->expr()->eq('A.t3ver_stage', $stage));
-                }
-
-                if ($filter === 1) {
-                    $queryBuilder->andWhere($queryBuilder->expr()->eq('A.t3ver_count', 0));
-                } elseif ($filter === 2) {
-                    $queryBuilder->andWhere($queryBuilder->expr()->gt('A.t3ver_count', 0));
-                }
-
-                $rows = $queryBuilder->execute()->fetchAll();
-                if (!empty($rows)) {
-                    $output[$table] = $rows;
-                }
-            }
-        }
-        return $output;
-    }
-
-    /****************************
-     *
-     * Scheduler methods
-     *
-     ****************************/
-    /**
-     * This method is called by the Scheduler task that triggers
-     * the autopublication process
-     * It searches for workspaces whose publication date is in the past
-     * and publishes them
-     *
-     * @return void
-     */
-    public function autoPublishWorkspaces()
-    {
-        // Temporarily set admin rights
-        // @todo once workspaces are cleaned up a better solution should be implemented
-        $currentAdminStatus = $GLOBALS['BE_USER']->user['admin'];
-        $GLOBALS['BE_USER']->user['admin'] = 1;
-        // Select all workspaces that needs to be published / unpublished:
-        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
-            ->getQueryBuilderForTable('sys_workspace');
-        $queryBuilder->getRestrictions()
-            ->removeAll()
-            ->add(GeneralUtility::makeInstance(DeletedRestriction::class))
-            ->add(GeneralUtility::makeInstance(RootLevelRestriction::class));
-
-        $result = $queryBuilder
-            ->select('uid', 'swap_modes', 'publish_time', 'unpublish_time')
-            ->from('sys_workspace')
-            ->where(
-                $queryBuilder->expr()->orX(
-                    $queryBuilder->expr()->andX(
-                        $queryBuilder->expr()->neq('publish_time', 0),
-                        $queryBuilder->expr()->lte('publish_time', (int)$GLOBALS['EXEC_TIME'])
-
-                    ),
-                    $queryBuilder->expr()->andX(
-                        $queryBuilder->expr()->eq('publish_time', 0),
-                        $queryBuilder->expr()->neq('unpublish_time', 0),
-                        $queryBuilder->expr()->lte('unpublish_time', (int)$GLOBALS['EXEC_TIME'])
-                    )
-                )
-            )
-            ->execute();
-
-        $connection = GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable('sys_workspace');
-        while ($rec = $result->fetch()) {
-            // First, clear start/end time so it doesn't get select once again:
-            $fieldArray = $rec['publish_time'] != 0 ? ['publish_time' => 0] : ['unpublish_time' => 0];
-
-            $connection->update(
-                'sys_workspace',
-                $fieldArray,
-                ['uid' => (int)$rec['uid']]
-            );
-
-            // Get CMD array:
-            $cmd = $this->getCmdArrayForPublishWS($rec['uid'], $rec['swap_modes'] == 1);
-            // $rec['swap_modes']==1 means that auto-publishing will swap versions, not just publish and empty the workspace.
-            // Execute CMD array:
-            $tce = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
-            $tce->start([], $cmd);
-            $tce->process_cmdmap();
-        }
-        // Restore admin status
-        $GLOBALS['BE_USER']->user['admin'] = $currentAdminStatus;
-    }
-}
diff --git a/typo3/sysext/version/Migrations/Code/ClassAliasMap.php b/typo3/sysext/version/Migrations/Code/ClassAliasMap.php
new file mode 100644
index 0000000000000000000000000000000000000000..3ee44cae5004adfd155cd1c7adc31da51c3a5d33
--- /dev/null
+++ b/typo3/sysext/version/Migrations/Code/ClassAliasMap.php
@@ -0,0 +1,5 @@
+<?php
+return [
+    'TYPO3\\CMS\\Version\\Task\\AutoPublishTask' => \TYPO3\CMS\Workspaces\Task\AutoPublishTask::class,
+    'TYPO3\\CMS\\Version\\Utility\\WorkspacesUtility' => \TYPO3\CMS\Workspaces\Service\WorkspaceService::class
+];