diff --git a/composer.json b/composer.json
index 109adf8dcbe49517e4b0d15157d935090b0db285..4b850020f0cc6a93f6b034216ebda598fbf1e7d8 100644
--- a/composer.json
+++ b/composer.json
@@ -6,7 +6,7 @@
         "php": ">=7.3",
         "ext-json": "*",
         "api-platform/core": "^2.6",
-        "dbp/relay-core-bundle": "^0.1.35",
+        "dbp/relay-core-bundle": "dev-main as 0.1.36",
         "symfony/config": "^5.4",
         "symfony/framework-bundle": "^5.4",
         "symfony/security-bundle": "^5.4",
diff --git a/composer.lock b/composer.lock
index dcfb675be7291afdd4f2120d91b5d565fdfc78e9..396aeca9e703cd941a128e1fe32f2a87503c722a 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "fd4590971a60339582f751c46725be9f",
+    "content-hash": "2ca7ac7fd502090cb757d89983e9bdb7",
     "packages": [
         {
             "name": "api-platform/core",
@@ -169,17 +169,11 @@
         },
         {
             "name": "dbp/relay-core-bundle",
-            "version": "v0.1.36",
+            "version": "dev-main",
             "source": {
                 "type": "git",
-                "url": "https://gitlab.tugraz.at/dbp/relay/dbp-relay-core-bundle.git",
-                "reference": "e271903213daaf1ae2b1f144ac39df05bf6627cc"
-            },
-            "dist": {
-                "type": "zip",
-                "url": "https://gitlab.tugraz.at/api/v4/projects/dbp%2Frelay%2Fdbp-relay-core-bundle/repository/archive.zip?sha=e271903213daaf1ae2b1f144ac39df05bf6627cc",
-                "reference": "e271903213daaf1ae2b1f144ac39df05bf6627cc",
-                "shasum": ""
+                "url": "git@gitlab.tugraz.at:dbp/relay/dbp-relay-core-bundle.git",
+                "reference": "8d46b8ae30a35a0853335ea550b03287fc5a21e8"
             },
             "require": {
                 "api-platform/core": "^2.6.6",
@@ -221,6 +215,7 @@
                 "symfony/phpunit-bridge": "^5.3",
                 "vimeo/psalm": "^4.4"
             },
+            "default-branch": true,
             "type": "symfony-bundle",
             "extra": {
                 "hooks": {
@@ -274,11 +269,7 @@
                 "AGPL-3.0-or-later"
             ],
             "description": "The core bundle of the Relay API gateway",
-            "support": {
-                "source": "https://gitlab.tugraz.at/dbp/relay/dbp-relay-core-bundle/-/tree/v0.1.36",
-                "issues": "https://gitlab.tugraz.at/dbp/relay/dbp-relay-core-bundle/-/issues"
-            },
-            "time": "2022-05-11T10:49:59+02:00"
+            "time": "2022-06-02T08:07:57+00:00"
         },
         {
             "name": "doctrine/annotations",
@@ -10042,9 +10033,18 @@
             "time": "2015-12-17T08:42:14+00:00"
         }
     ],
-    "aliases": [],
+    "aliases": [
+        {
+            "package": "dbp/relay-core-bundle",
+            "version": "dev-main",
+            "alias": "0.1.36",
+            "alias_normalized": "0.1.36.0"
+        }
+    ],
     "minimum-stability": "stable",
-    "stability-flags": [],
+    "stability-flags": {
+        "dbp/relay-core-bundle": 20
+    },
     "prefer-stable": false,
     "prefer-lowest": false,
     "platform": {
@@ -10055,5 +10055,5 @@
     "platform-overrides": {
         "php": "7.3"
     },
-    "plugin-api-version": "2.3.0"
+    "plugin-api-version": "2.2.0"
 }
diff --git a/src/API/CourseProviderInterface.php b/src/API/CourseProviderInterface.php
index b08634d29ffc278719c98017cc38399b3282a4ae..da917ad57917d97f78e522ae521a73c2bb436b34 100644
--- a/src/API/CourseProviderInterface.php
+++ b/src/API/CourseProviderInterface.php
@@ -5,8 +5,8 @@ declare(strict_types=1);
 namespace Dbp\Relay\BaseCourseBundle\API;
 
 use Dbp\Relay\BaseCourseBundle\Entity\Course;
-use Dbp\Relay\BaseCourseBundle\Entity\CourseAttendee;
 use Dbp\Relay\CoreBundle\Exception\ApiError;
+use Dbp\Relay\CoreBundle\Pagination\Paginator;
 
 interface CourseProviderInterface
 {
@@ -16,30 +16,22 @@ interface CourseProviderInterface
     public function getCourseById(string $identifier, array $options = []): Course;
 
     /**
-     * @return Course[]
-     *
      * @throws ApiError
      */
-    public function getCourses(array $options = []): array;
+    public function getCourses(array $options = []): Paginator;
 
     /**
-     * @return Course[]
-     *
      * @throws ApiError
      */
-    public function getCoursesByOrganization(string $orgUnitId, array $options = []): array;
+    public function getCoursesByOrganization(string $orgUnitId, array $options = []): Paginator;
 
     /**
-     * @return Course[]
-     *
      * @throws ApiError
      */
-    public function getCoursesByLecturer(string $lecturerId, array $options = []): array;
+    public function getCoursesByLecturer(string $lecturerId, array $options = []): Paginator;
 
     /**
-     * @return CourseAttendee[]
-     *
      * @throws ApiError
      */
-    public function getAttendeesByCourse(string $courseId, array $options = []): array;
+    public function getAttendeesByCourse(string $courseId, array $options = []): Paginator;
 }
diff --git a/src/DataProvider/CourseCollectionDataProvider.php b/src/DataProvider/CourseCollectionDataProvider.php
index 5e904e201a196541372fb15672a1d754a9eef3c2..b44a363f830450175a629a33daf21a588424bdcd 100644
--- a/src/DataProvider/CourseCollectionDataProvider.php
+++ b/src/DataProvider/CourseCollectionDataProvider.php
@@ -8,17 +8,22 @@ use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
 use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
 use Dbp\Relay\BaseCourseBundle\API\CourseProviderInterface;
 use Dbp\Relay\BaseCourseBundle\Entity\Course;
-use Dbp\Relay\CoreBundle\Helpers\ArrayFullPaginator;
 use Dbp\Relay\CoreBundle\LocalData\LocalData;
+use Dbp\Relay\CoreBundle\Pagination\Pagination;
 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
 
 final class CourseCollectionDataProvider extends AbstractController implements CollectionDataProviderInterface, RestrictedDataProviderInterface
 {
+    /** @var CourseProviderInterface */
     private $courseProvider;
 
-    public function __construct(CourseProviderInterface $courseProvider)
+    /** @var Pagination */
+    private $pagination;
+
+    public function __construct(CourseProviderInterface $courseProvider, Pagination $pagination)
     {
         $this->courseProvider = $courseProvider;
+        $this->pagination = $pagination;
     }
 
     public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
@@ -26,7 +31,7 @@ final class CourseCollectionDataProvider extends AbstractController implements C
         return Course::class === $resourceClass;
     }
 
-    public function getCollection(string $resourceClass, string $operationName = null, array $context = []): ArrayFullPaginator
+    public function getCollection(string $resourceClass, string $operationName = null, array $context = []): iterable
     {
         $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');
 
@@ -35,45 +40,50 @@ final class CourseCollectionDataProvider extends AbstractController implements C
         $options = [];
         $options['lang'] = $filters['lang'] ?? 'de';
 
+        if ($search = ($filters['search'] ?? null)) {
+            $options['search'] = $search;
+        }
+
         if ($term = ($filters['term'] ?? null)) {
             $options['term'] = $term;
         }
 
-        $options[LocalData::INCLUDE_PARAMETER_NAME] = LocalData::getIncludeParameter($filters);
+        if ($includeParameter = LocalData::getIncludeParameter($filters)) {
+            $options[LocalData::INCLUDE_PARAMETER_NAME] = $includeParameter;
+        }
 
-        $organizationId = $filters['organization'] ?? null;
-        $lecturerId = $filters['lecturer'] ?? null;
+        $organizationId = $filters['organization'] ?? '';
+        $lecturerId = $filters['lecturer'] ?? '';
 
-        $courses = null;
-        if (!empty($organizationId) || !empty($lecturerId)) {
-            if (!empty($organizationId)) {
-                $courses = $this->courseProvider->getCoursesByOrganization($organizationId, $options);
+        $filterByOrganizationId = $organizationId !== '';
+        $filterByLecturerId = $lecturerId !== '';
+
+        if (!($filterByOrganizationId && $filterByLecturerId)) {
+            $this->pagination->addPaginationOptions($options, $resourceClass, $operationName, $context);
+        } // else -> request the whole set of results
+
+        $coursePaginator = null;
+        if ($filterByOrganizationId || $filterByLecturerId) {
+            if ($filterByOrganizationId) {
+                $coursePaginator = $this->courseProvider->getCoursesByOrganization($organizationId, $options);
             }
-            if (!empty($lecturerId)) {
-                $coursesByPerson = $this->courseProvider->getCoursesByLecturer($lecturerId, $options);
-                if (!empty($organizationId)) {
-                    $courses = array_uintersect($courses, $coursesByPerson,
-                        'Dbp\Relay\BaseCourseBundle\DataProvider\CourseCollectionDataProvider::compareCourses');
-                    $courses = array_values($courses);
+            if ($filterByLecturerId) {
+                $coursesByPersonPaginator = $this->courseProvider->getCoursesByLecturer($lecturerId, $options);
+
+                if (!$filterByOrganizationId) {
+                    $coursePaginator = $coursesByPersonPaginator;
                 } else {
-                    $courses = $coursesByPerson;
+                    $intersection = array_uintersect($coursePaginator->getItems(), $coursesByPersonPaginator->getItems(),
+                        'Dbp\Relay\BaseCourseBundle\DataProvider\CourseCollectionDataProvider::compareCourses');
+                    $courses = array_values($intersection);
+                    $coursePaginator = $this->pagination->createWholeResultPaginator($courses, $resourceClass, $operationName, $context);
                 }
             }
         } else {
-            $courses = $this->courseProvider->getCourses($options);
-        }
-
-        $page = 1;
-        if (isset($filters['page'])) {
-            $page = (int) $filters['page'];
-        }
-
-        $perPage = 30;
-        if (isset($filters['perPage'])) {
-            $perPage = (int) $filters['perPage'];
+            $coursePaginator = $this->courseProvider->getCourses($options);
         }
 
-        return new ArrayFullPaginator($courses, $page, $perPage);
+        return $coursePaginator ?? [];
     }
 
     public static function compareCourses(Course $a, Course $b): int
diff --git a/src/Entity/Course.php b/src/Entity/Course.php
index 07071fe6abecc1baf746461bbacab69b3ae83459..25147fa64ea9306aa5c11a49fef078fac27d523a 100644
--- a/src/Entity/Course.php
+++ b/src/Entity/Course.php
@@ -16,6 +16,7 @@ use Dbp\Relay\CoreBundle\LocalData\LocalDataAwareTrait;
  *             "openapi_context" = {
  *                 "tags" = {"BaseCourse"},
  *                 "parameters" = {
+ *                     {"name" = "search", "in" = "query", "description" = "Search for a course", "type" = "string", "required" = false},
  *                     {"name" = "lang", "in" = "query", "description" = "Language of result", "type" = "string", "enum" = {"de", "en"}, "example" = "de"},
  *                     {"name" = "term", "in" = "query", "description" = "Teaching term", "type" = "string", "enum" = {"W", "S"}, "example" = "W"},
  *                     {"name" = "organization", "in" = "query", "description" = "Get courses of an organization (ID of BaseOrganization resource)", "required" = false, "type" = "string", "example" = "1190"},
diff --git a/src/Service/DummyCourseProvider.php b/src/Service/DummyCourseProvider.php
index 2de0a9dad1661ec1c794be3a5d3f982a04045926..ac7ec3a8567503d0421c05517077df30ff8eb7c6 100644
--- a/src/Service/DummyCourseProvider.php
+++ b/src/Service/DummyCourseProvider.php
@@ -7,6 +7,8 @@ namespace Dbp\Relay\BaseCourseBundle\Service;
 use Dbp\Relay\BaseCourseBundle\API\CourseProviderInterface;
 use Dbp\Relay\BaseCourseBundle\Entity\Course;
 use Dbp\Relay\BaseCourseBundle\Entity\CourseAttendee;
+use Dbp\Relay\CoreBundle\Pagination\FullPaginator;
+use Dbp\Relay\CoreBundle\Pagination\Paginator;
 
 class DummyCourseProvider implements CourseProviderInterface
 {
@@ -19,20 +21,20 @@ class DummyCourseProvider implements CourseProviderInterface
         return $course;
     }
 
-    public function getCourses(array $options = []): array
+    public function getCourses(array $options = []): Paginator
     {
-        $course = $this->getCourseById('123', $options);
-        assert($course !== null);
+        $courses = [];
+        $courses[] = $this->getCourseById('123', $options);
 
-        return [$course];
+        return new FullPaginator($courses, 1, count($courses), count($courses));
     }
 
-    public function getCoursesByOrganization(string $orgUnitId, array $options = []): array
+    public function getCoursesByOrganization(string $orgUnitId, array $options = []): Paginator
     {
         return $this->getCourses($options);
     }
 
-    public function getAttendeesByCourse(string $courseId, array $options = []): array
+    public function getAttendeesByCourse(string $courseId, array $options = []): Paginator
     {
         $attendee = new CourseAttendee();
         $attendee->setIdentifier('aeinstein');
@@ -40,10 +42,10 @@ class DummyCourseProvider implements CourseProviderInterface
         $attendee->setFamilyName('Einstein');
         $attendee->setEmail('info@einstein.com');
 
-        return [$attendee];
+        return new FullPaginator($attendees = [$attendee], 1, count($attendees), count($attendees));
     }
 
-    public function getCoursesByLecturer(string $lecturerId, array $options = []): array
+    public function getCoursesByLecturer(string $lecturerId, array $options = []): Paginator
     {
         return $this->getCourses($options);
     }