diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index aa71f87..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,122 +0,0 @@
-# @file
-# .travis.yml - Drupal for Travis CI Integration
-#
-# Template provided by https://github.com/LionsAd/drupal_ti.
-#
-# Based for simpletest upon:
-#   https://github.com/sonnym/travis-ci-drupal-module-example
-
-language: php
-
-sudo: false
-
-php:
-  - 5.5
-  - 5.6
-  - 7
-  - hhvm
-
-matrix:
-  fast_finish: true
-  allow_failures:
-    - php: hhvm
-
-env:
-  global:
-    # add composer's global bin directory to the path
-    # see: https://github.com/drush-ops/drush#install---composer
-    - PATH="$PATH:$HOME/.composer/vendor/bin"
-
-    # Configuration variables.
-    - DRUPAL_TI_MODULE_NAME="media_entity"
-    - DRUPAL_TI_SIMPLETEST_GROUP="media_entity"
-
-    # Define runners and environment vars to include before and after the
-    # main runners / environment vars.
-    #- DRUPAL_TI_SCRIPT_DIR_BEFORE="./drupal_ti/before"
-    #- DRUPAL_TI_SCRIPT_DIR_AFTER="./drupal_ti/after"
-
-    # The environment to use, supported are: drupal-7, drupal-8
-    - DRUPAL_TI_ENVIRONMENT="drupal-8"
-    - DRUPAL_TI_CORE_BRANCH="8.1.x"
-    
-    # The installation profile to use:
-    #- DRUPAL_TI_INSTALL_PROFILE="testing"
-
-    # Drupal specific variables.
-    - DRUPAL_TI_DB="drupal_travis_db"
-    - DRUPAL_TI_DB_URL="mysql://root:@127.0.0.1/drupal_travis_db"
-    # Note: Do not add a trailing slash here.
-    - DRUPAL_TI_WEBSERVER_URL="http://127.0.0.1"
-    - DRUPAL_TI_WEBSERVER_PORT="8080"
-
-    # Simpletest specific commandline arguments, the DRUPAL_TI_SIMPLETEST_GROUP is appended at the end.
-    - DRUPAL_TI_SIMPLETEST_ARGS="--verbose --color --concurrency 4 --url $DRUPAL_TI_WEBSERVER_URL:$DRUPAL_TI_WEBSERVER_PORT"
-
-    # === Behat specific variables.
-    # This is relative to $TRAVIS_BUILD_DIR
-    - DRUPAL_TI_BEHAT_DIR="./tests/behat"
-    # These arguments are passed to the bin/behat command.
-    - DRUPAL_TI_BEHAT_ARGS=""
-    # Specify the filename of the behat.yml with the $DRUPAL_TI_DRUPAL_DIR variables.
-    - DRUPAL_TI_BEHAT_YML="behat.yml.dist"
-    # This is used to setup Xvfb.
-    - DRUPAL_TI_BEHAT_SCREENSIZE_COLOR="1280x1024x16"
-    # The version of selenium that should be used.
-    - DRUPAL_TI_BEHAT_SELENIUM_VERSION="2.48.2"
-    # Set DRUPAL_TI_BEHAT_DRIVER to "selenium" to use "firefox" or "chrome" here.
-    - DRUPAL_TI_BEHAT_DRIVER="phantomjs"
-    - DRUPAL_TI_BEHAT_BROWSER="firefox"
-
-    # PHPUnit specific commandline arguments.
-    - DRUPAL_TI_PHPUNIT_ARGS=""
-    # Specifying the phpunit-core src/ directory is useful when e.g. a vendor/
-    # directory is present in the module directory, which phpunit would then
-    # try to find tests in. This option is relative to $TRAVIS_BUILD_DIR.
-    #- DRUPAL_TI_PHPUNIT_CORE_SRC_DIRECTORY="./tests/src"
-
-    # Code coverage via coveralls.io
-    - DRUPAL_TI_COVERAGE="satooshi/php-coveralls:0.6.*"
-    # This needs to match your .coveralls.yml file.
-    - DRUPAL_TI_COVERAGE_FILE="build/logs/clover.xml"
-
-    # Debug options
-    #- DRUPAL_TI_DEBUG="-x -v"
-    # Set to "all" to output all files, set to e.g. "xvfb selenium" or "selenium",
-    # etc. to only output those channels.
-    #- DRUPAL_TI_DEBUG_FILE_OUTPUT="selenium xvfb webserver"
-
-  matrix:
-    # [[[ SELECT ANY OR MORE OPTIONS ]]]
-    #- DRUPAL_TI_RUNNERS="phpunit"
-    - DRUPAL_TI_RUNNERS="simpletest"
-    #- DRUPAL_TI_RUNNERS="behat"
-    #- DRUPAL_TI_RUNNERS="phpunit simpletest behat"
-    # Use phpunit-core to test modules with phpunit with Drupal 8 core.
-    #- DRUPAL_TI_RUNNERS="phpunit-core"
-
-mysql:
-  database: drupal_travis_db
-  username: root
-  encoding: utf8
-
-before_install:
-  - composer self-update
-  - cd ./tests
-  - composer global require "lionsad/drupal_ti:dev-master"
-  - drupal-ti before_install
-
-install:
-  - drupal-ti install
-
-before_script:
-  - drupal-ti before_script
-
-script:
-  - drupal-ti script
-
-after_script:
-  - drupal-ti after_script
-
-notifications:
-  email: false
diff --git a/CHANGELOG.txt b/CHANGELOG.txt
deleted file mode 100644
index 0fb0edc..0000000
--- a/CHANGELOG.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-Media entity 8.x-1.x-dev
---------------------------------------------------
-- Issue #2099735 by jcisio: Fix typo in Media entity annotation.
-- Issue #2099735 by slashrsm: Create basic entity type definition.
diff --git a/DEVELOPING.md b/DEVELOPING.md
deleted file mode 100644
index 8b5bf15..0000000
--- a/DEVELOPING.md
+++ /dev/null
@@ -1,4 +0,0 @@
-# Developing
-
-* Issues should be filed at http://drupal.org/project/issues/media_entity
-* Pull requests can be made against https://github.com/drupal-media/media_entity/pulls
diff --git a/README.md b/README.md
index 85315d0..3ef6a34 100644
--- a/README.md
+++ b/README.md
@@ -1,70 +1,3 @@
-## About Media entity
+## Upgrade path from Media Entity to Media (core)
 
-[![Travis](https://img.shields.io/travis/drupal-media/media_entity.svg)]() [![Scrutinizer](https://img.shields.io/scrutinizer/g/drupal-media/media_entity.svg)]()
-
-Media entity provides a 'base' entity for media. This is a very basic entity
-which can reference to all kinds of media-objects (local files, YouTube
-videos, Tweets, Instagram photos, ...). Media entity provides a relation between
-Drupal and the media resource. You can reference to/use this entity within any
-other Drupal entity.
-
-This module attempts to provide the base storage component for the Drupal 8
-media ecosystem.
-
-Project page: https://drupal.org/project/media_entity
-
-## Official documentation
-
-You will find all the documentation about this module on the [official handbook](https://drupal-media.gitbooks.io/drupal8-guide/content/modules/media_entity/intro.html).
-
-## Contribute
-
-Our current development focus can be seen in [the roadmap issue](https://www.drupal.org/node/2577453).
-
-Development is generally done via [GitHub pull requests](https://github.com/drupal-media/media_entity/pulls).
-Every pull request should be linked to an [issue in drupal.org issue queue](http://drupal.org/project/issues/media_entity)
-and vice-versa. 
-
-If you prefer usual patch-based workflow feel free to submit a patch. We started
-using GitHub mostly for easier review process. However, there are not strong opinions
-about that. Any contribution in any shape or form will be treated equally.
-
-## Media provider modules
-
-There are already several media provider modules that extend functionality of
-Media entity:
-
-- [Image](https://drupal.org/project/media_entity_image)
-- [Audio](https://drupal.org/project/media_entity_audio)
-- [Slideshow](https://drupal.org/project/media_entity_slideshow)
-- [Video embed field](https://drupal.org/project/video_embed_field)
-- [Twitter](https://drupal.org/project/media_entity_twitter)
-- [Instagram](https://drupal.org/project/media_entity_instagram)
-- [Document](https://drupal.org/project/media_entity_document)
-- [Slideshare](https://drupal.org/project/media_entity_slideshare)
-- [Video (local)](https://drupal.org/project/media_entity_video)
-- [Tumblr](https://drupal.org/project/media_entity_tumblr)
-- [Facebook](https://drupal.org/project/media_entity_facebook)
-- [Audio embed field (sandbox)](https://drupal.org/sandbox/vilepickle/2784301)
-
-## Other modules that integrate with media entity
-
-- [Entity browser](https://drupal.org/project/entity_browser): Provides entity browser
-  widget that supports uploading [Media entity images](https://drupal.org/project/media_entity_image).
-- [DropzoneJS](https://drupal.org/project/dropzonejs): Extends entity browser [image
-  upload widget](https://drupal.org/project/media_entity_image) with [DropzoneJS
-  upload library](http://www.dropzonejs.com).
-- [Slick media](https://drupal.org/project/slick_media): Provides integration
-between [Slick carousel](https://drupal.org/project/slick) and Media entity. Slick media allows richer slideshows/carousel
-  with a mix of text, image and video.
-- [Brightcove](https://github.com/dawehner/media_entity_brightcove)
-
-## Maintainers
-- Janez Urevc ([@slashrsm](https://github.com/slashrsm)) https://drupal.org/user/744628
-- Primož Hmeljak ([@primsi](https://github.com/primsi)) https://drupal.org/user/282629
-- Nguyễn Hải Nam (@jcisio) https://drupal.org/user/210762
-- Boris Gordon (@boztek) https://drupal.org/user/134410
-
-## Get in touch
-- http://groups.drupal.org/media
-- IRC: #drupal-media @ Freenode
+@TODO
diff --git a/composer.json b/composer.json
deleted file mode 100644
index 151f925..0000000
--- a/composer.json
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-  "name": "drupal/media_entity",
-  "type": "drupal-module",
-  "description": "Provides a lean and simple way to store media on Drupal 8 sites.",
-  "keywords": ["Drupal"],
-  "license": "GPL-2.0+",
-  "homepage": "https://www.drupal.org/project/media_entity",
-  "minimum-stability": "dev",
-  "support": {
-    "issues": "https://www.drupal.org/project/issues/media_entity",
-    "source": "https://www.drupal.org/project/media_entity"
-  },
-  "repositories": [
-    {
-      "type": "composer",
-      "url": "https://packagist.drupal-composer.org"
-    }
-  ],
-  "require": {
-    "drupal/core": "~8.1"
-  }
-}
diff --git a/config/install/media_entity.settings.yml b/config/install/media_entity.settings.yml
deleted file mode 100644
index 85f1c81..0000000
--- a/config/install/media_entity.settings.yml
+++ /dev/null
@@ -1 +0,0 @@
-icon_base: 'public://media-icons/generic'
diff --git a/config/install/system.action.media_delete_action.yml b/config/install/system.action.media_delete_action.yml
deleted file mode 100644
index c68b0a5..0000000
--- a/config/install/system.action.media_delete_action.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  module:
-    - media_entity
-id: media_delete_action
-label: 'Delete media'
-type: media
-plugin: media_delete_action
-configuration: {  }
diff --git a/config/install/system.action.media_publish_action.yml b/config/install/system.action.media_publish_action.yml
deleted file mode 100644
index a5b4959..0000000
--- a/config/install/system.action.media_publish_action.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  module:
-    - media_entity
-id: media_publish_action
-label: 'Publish media'
-type: media
-plugin: media_publish_action
-configuration: {  }
diff --git a/config/install/system.action.media_save_action.yml b/config/install/system.action.media_save_action.yml
deleted file mode 100644
index fecb8a2..0000000
--- a/config/install/system.action.media_save_action.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  module:
-    - media_entity
-id: media_save_action
-label: 'Save media'
-type: media
-plugin: media_save_action
-configuration: {  }
diff --git a/config/install/system.action.media_unpublish_action.yml b/config/install/system.action.media_unpublish_action.yml
deleted file mode 100644
index 1e87b11..0000000
--- a/config/install/system.action.media_unpublish_action.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  module:
-    - media_entity
-id: media_unpublish_action
-label: 'Unpublish media'
-type: media
-plugin: media_unpublish_action
-configuration: {  }
diff --git a/config/install/views.view.media.yml b/config/install/views.view.media.yml
deleted file mode 100644
index 45c8ddf..0000000
--- a/config/install/views.view.media.yml
+++ /dev/null
@@ -1,854 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  module:
-    - image
-    - media_entity
-    - user
-id: media
-label: Media
-module: views
-description: ''
-tag: ''
-base_table: media_field_data
-base_field: mid
-core: 8.x
-display:
-  default:
-    display_plugin: default
-    id: default
-    display_title: Master
-    position: 0
-    display_options:
-      access:
-        type: perm
-        options:
-          perm: 'access media overview'
-      cache:
-        type: tag
-        options: {  }
-      query:
-        type: views_query
-        options:
-          disable_sql_rewrite: false
-          distinct: false
-          replica: false
-          query_comment: ''
-          query_tags: {  }
-      exposed_form:
-        type: basic
-        options:
-          submit_button: Apply
-          reset_button: false
-          reset_button_label: Reset
-          exposed_sorts_label: 'Sort by'
-          expose_sort_order: true
-          sort_asc_label: Asc
-          sort_desc_label: Desc
-      pager:
-        type: full
-        options:
-          items_per_page: 50
-          offset: 0
-          id: 0
-          total_pages: null
-          expose:
-            items_per_page: false
-            items_per_page_label: 'Items per page'
-            items_per_page_options: '5, 10, 25, 50'
-            items_per_page_options_all: false
-            items_per_page_options_all_label: '- All -'
-            offset: false
-            offset_label: Offset
-          tags:
-            previous: '‹ Previous'
-            next: 'Next ›'
-            first: '« First'
-            last: 'Last »'
-          quantity: 9
-      style:
-        type: table
-        options:
-          grouping: {  }
-          row_class: ''
-          default_row_class: true
-          override: true
-          sticky: false
-          caption: ''
-          summary: ''
-          description: ''
-          columns:
-            name: name
-            bundle: bundle
-            changed: changed
-            uid: uid
-            status: status
-            thumbnail__target_id: thumbnail__target_id
-          info:
-            name:
-              sortable: true
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            bundle:
-              sortable: true
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            changed:
-              sortable: true
-              default_sort_order: desc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            uid:
-              sortable: false
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            status:
-              sortable: true
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-            thumbnail__target_id:
-              sortable: false
-              default_sort_order: asc
-              align: ''
-              separator: ''
-              empty_column: false
-              responsive: ''
-          default: changed
-          empty_table: false
-      row:
-        type: fields
-      fields:
-        media_bulk_form:
-          id: media_bulk_form
-          table: media
-          field: media_bulk_form
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: ''
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: false
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          action_title: Action
-          include_exclude: exclude
-          selected_actions: {  }
-          entity_type: media
-          plugin_id: media_bulk_form
-        thumbnail__target_id:
-          id: thumbnail__target_id
-          table: media_field_data
-          field: thumbnail__target_id
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: Thumbnail
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: target_id
-          type: image
-          settings:
-            image_style: thumbnail
-            image_link: ''
-          group_column: ''
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-          entity_type: media
-          entity_field: thumbnail
-          plugin_id: field
-        name:
-          id: name
-          table: media_field_data
-          field: name
-          entity_type: media
-          entity_field: media
-          alter:
-            alter_text: false
-            make_link: false
-            absolute: false
-            trim: false
-            word_boundary: false
-            ellipsis: false
-            strip_tags: false
-            html: false
-          hide_empty: false
-          empty_zero: false
-          settings:
-            link_to_entity: true
-          plugin_id: field
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: 'Media name'
-          exclude: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_alter_empty: true
-          click_sort_column: value
-          type: string
-          group_column: value
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-        bundle:
-          id: bundle
-          table: media_field_data
-          field: bundle
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: Provider
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: target_id
-          type: entity_reference_label
-          settings:
-            link: false
-          group_column: target_id
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-          entity_type: media
-          entity_field: bundle
-          plugin_id: field
-        uid:
-          id: uid
-          table: media_field_data
-          field: uid
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: Author
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: target_id
-          type: entity_reference_label
-          settings:
-            link: true
-          group_column: target_id
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-          entity_type: media
-          entity_field: uid
-          plugin_id: field
-        status:
-          id: status
-          table: media_field_data
-          field: status
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: Status
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: value
-          type: boolean
-          settings:
-            format: custom
-            format_custom_true: Published
-            format_custom_false: Unpublished
-          group_column: value
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-          entity_type: media
-          entity_field: status
-          plugin_id: field
-        changed:
-          id: changed
-          table: media_field_data
-          field: changed
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: Updated
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: value
-          type: timestamp
-          settings:
-            date_format: short
-            custom_date_format: ''
-            timezone: ''
-          group_column: value
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-          entity_type: media
-          entity_field: changed
-          plugin_id: field
-        operations:
-          id: operations
-          table: media
-          field: operations
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: Operations
-          exclude: false
-          alter:
-            alter_text: false
-            text: ''
-            make_link: false
-            path: ''
-            absolute: false
-            external: false
-            replace_spaces: false
-            path_case: none
-            trim_whitespace: false
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: false
-            max_length: 0
-            word_boundary: true
-            ellipsis: true
-            more_link: false
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: false
-            trim: false
-            preserve_tags: ''
-            html: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          destination: true
-          entity_type: media
-          plugin_id: entity_operations
-      filters:
-        status:
-          id: status
-          table: media_field_data
-          field: status
-          relationship: none
-          group_type: group
-          admin_label: ''
-          operator: '='
-          value: '1'
-          group: 1
-          exposed: true
-          expose:
-            operator_id: ''
-            label: 'True'
-            description: null
-            use_operator: false
-            operator: status_op
-            identifier: status
-            required: true
-            remember: false
-            multiple: false
-            remember_roles:
-              authenticated: authenticated
-          is_grouped: true
-          group_info:
-            label: 'Publishing status'
-            description: ''
-            identifier: status
-            optional: true
-            widget: select
-            multiple: false
-            remember: false
-            default_group: All
-            default_group_multiple: {  }
-            group_items:
-              1:
-                title: Published
-                operator: '='
-                value: '1'
-              2:
-                title: Unpublished
-                operator: '='
-                value: '0'
-          plugin_id: boolean
-          entity_type: media
-          entity_field: status
-        bundle:
-          id: bundle
-          table: media_field_data
-          field: bundle
-          relationship: none
-          group_type: group
-          admin_label: ''
-          operator: in
-          value: {  }
-          group: 1
-          exposed: true
-          expose:
-            operator_id: bundle_op
-            label: Provider
-            description: ''
-            use_operator: false
-            operator: bundle_op
-            identifier: provider
-            required: false
-            remember: false
-            multiple: false
-            remember_roles:
-              authenticated: authenticated
-              anonymous: '0'
-              administrator: '0'
-            reduce: false
-          is_grouped: false
-          group_info:
-            label: ''
-            description: ''
-            identifier: ''
-            optional: true
-            widget: select
-            multiple: false
-            remember: false
-            default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
-          entity_type: media
-          entity_field: bundle
-          plugin_id: bundle
-        name:
-          id: name
-          table: media_field_data
-          field: name
-          relationship: none
-          group_type: group
-          admin_label: ''
-          operator: contains
-          value: ''
-          group: 1
-          exposed: true
-          expose:
-            operator_id: name_op
-            label: 'Media name'
-            description: ''
-            use_operator: false
-            operator: name_op
-            identifier: name
-            required: false
-            remember: false
-            multiple: false
-            remember_roles:
-              authenticated: authenticated
-              anonymous: '0'
-              administrator: '0'
-          is_grouped: false
-          group_info:
-            label: ''
-            description: ''
-            identifier: ''
-            optional: true
-            widget: select
-            multiple: false
-            remember: false
-            default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
-          entity_type: media
-          entity_field: name
-          plugin_id: string
-        langcode:
-          id: langcode
-          table: media_field_data
-          field: langcode
-          relationship: none
-          group_type: group
-          admin_label: ''
-          operator: in
-          value: {  }
-          group: 1
-          exposed: true
-          expose:
-            operator_id: langcode_op
-            label: Language
-            description: ''
-            use_operator: false
-            operator: langcode_op
-            identifier: langcode
-            required: false
-            remember: false
-            multiple: false
-            remember_roles:
-              authenticated: authenticated
-              anonymous: '0'
-              administrator: '0'
-            reduce: false
-          is_grouped: false
-          group_info:
-            label: ''
-            description: ''
-            identifier: ''
-            optional: true
-            widget: select
-            multiple: false
-            remember: false
-            default_group: All
-            default_group_multiple: {  }
-            group_items: {  }
-          entity_type: media
-          entity_field: langcode
-          plugin_id: language
-      sorts:
-        created:
-          id: created
-          table: media_field_data
-          field: created
-          order: DESC
-          entity_type: media
-          entity_field: created
-          plugin_id: date
-          relationship: none
-          group_type: group
-          admin_label: ''
-          exposed: false
-          expose:
-            label: ''
-          granularity: second
-      title: Media
-      header: {  }
-      footer: {  }
-      empty:
-        area_text_custom:
-          id: area_text_custom
-          table: views
-          field: area_text_custom
-          relationship: none
-          group_type: group
-          admin_label: ''
-          empty: true
-          tokenize: false
-          content: 'No content available.'
-          plugin_id: text_custom
-      relationships: {  }
-      arguments: {  }
-      display_extenders: {  }
-    cache_metadata:
-      max-age: 0
-      contexts:
-        - 'languages:language_content'
-        - 'languages:language_interface'
-        - url
-        - url.query_args
-        - user.permissions
-      tags: {  }
-  media_page_list:
-    display_plugin: page
-    id: media_page_list
-    display_title: Media
-    position: 1
-    display_options:
-      display_extenders: {  }
-      path: admin/content/media
-      menu:
-        type: tab
-        title: Media
-        description: ''
-        expanded: false
-        parent: ''
-        weight: 0
-        context: '0'
-        menu_name: main
-      display_description: ''
-    cache_metadata:
-      max-age: 0
-      contexts:
-        - 'languages:language_content'
-        - 'languages:language_interface'
-        - url
-        - url.query_args
-        - user.permissions
-      tags: {  }
diff --git a/config/schema/media_entity.schema.yml b/config/schema/media_entity.schema.yml
deleted file mode 100644
index 1c1f720..0000000
--- a/config/schema/media_entity.schema.yml
+++ /dev/null
@@ -1,69 +0,0 @@
-media_entity.settings:
-  type: config_object
-  label: 'Media entity settings'
-  mapping:
-    icon_base:
-      type: string
-      label: 'Base folder for icons installation'
-
-media_entity.bundle.*:
-  type: config_entity
-  label: 'Media bundle'
-  mapping:
-    id:
-      type: string
-      label: 'Machine name'
-    label:
-      type: label
-      label: 'Label'
-    description:
-      type: text
-      label: 'Description'
-    type:
-      type: string
-      label: 'Type plugin ID'
-    queue_thumbnail_downloads:
-      type: boolean
-      label: 'Queue thumbnail downloads'
-    new_revision:
-      type: boolean
-      label: 'Whether a new revision should be created by default'
-    type_configuration:
-      type: media_entity.bundle.type.[%parent.type]
-    field_map:
-      type: sequence
-      label: 'Field map'
-      sequence:
-        type: string
-    third_party_settings:
-      type: sequence
-      label: 'Third party settings'
-      sequence:
-        type: media_entity.bundle.third_party.[%key]
-
-action.configuration.media_delete_action:
-  type: action_configuration_default
-  label: 'Delete media configuration'
-
-action.configuration.media_save_action:
-  type: action_configuration_default
-  label: 'Save media configuration'
-
-action.configuration.media_publish_action:
-  type: action_configuration_default
-  label: 'Publish media configuration'
-
-action.configuration.media_unpublish_action:
-  type: action_configuration_default
-  label: 'Unpublish media configuration'
-
-field.formatter.settings.media_thumbnail:
-  type: mapping
-  label: 'Media thumbnail field display format settings'
-  mapping:
-    image_link:
-      type: string
-      label: 'Link image to'
-    image_style:
-      type: string
-      label: 'Image style'
diff --git a/config/schema/media_entity.views.schema.yml b/config/schema/media_entity.views.schema.yml
deleted file mode 100644
index 6106249..0000000
--- a/config/schema/media_entity.views.schema.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-# Schema for the views plugins of the Media Entity module.
-
-views.field.media_bulk_form:
-  type: views_field_bulk_form
-  label: 'Media Entity bulk form'
diff --git a/js/media_bundle_form.js b/js/media_bundle_form.js
deleted file mode 100644
index 0f66229..0000000
--- a/js/media_bundle_form.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/**
- * @file
- * Javascript for the media bundle form.
- */
-
-(function ($, Drupal) {
-  'use strict';
-
-  /**
-   * Behaviors for setting summaries on media bundle form.
-   *
-   * @type {Drupal~behavior}
-   *
-   * @prop {Drupal~behaviorAttach} attach
-   *   Attaches summary behaviors on media bundle edit forms.
-   */
-  Drupal.behaviors.contentTypes = {
-    attach: function (context) {
-      var $context = $(context);
-      // Provide the vertical tab summaries.
-      $context.find('#edit-workflow').drupalSetSummary(function (context) {
-        var vals = [];
-        $(context).find('input[name^="options"]:checked').parent().each(function () {
-          vals.push(Drupal.checkPlain($(this).find('label').text()));
-        });
-        if (!$(context).find('#edit-options-status').is(':checked')) {
-          vals.unshift(Drupal.t('Not published'));
-        }
-        return vals.join(', ');
-      });
-      $('#edit-language', context).drupalSetSummary(function (context) {
-        var vals = [];
-
-        vals.push($('.js-form-item-language-configuration-langcode select option:selected', context).text());
-
-        $('input:checked', context).next('label').each(function () {
-          vals.push(Drupal.checkPlain($(this).text()));
-        });
-
-        return vals.join(', ');
-      });
-    }
-  };
-
-})(jQuery, Drupal);
diff --git a/media_entity.api.php b/media_entity.api.php
deleted file mode 100644
index c8eb7b8..0000000
--- a/media_entity.api.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-
-/**
- * @file
- * Hooks related to media entity and it's plugins.
- */
-
-/**
- * @addtogroup hooks
- * @{
- */
-
-/**
- * Alter the information provided in \Drupal\media_entity\Annotation\MediaType.
- *
- * @param array $types
- *   The array of type plugins, keyed on the machine-readable name.
- */
-function hook_media_entity_type_info_alter(&$types) {
-  $types['youtube']['label'] = t('Youtube rocks!');
-}
-
-/**
- * @} End of "addtogroup hooks".
- */
diff --git a/media_entity.drush.inc b/media_entity.drush.inc
new file mode 100644
index 0000000..62000d5
--- /dev/null
+++ b/media_entity.drush.inc
@@ -0,0 +1,154 @@
+<?php
+
+/**
+ * @file
+ * Drush integration for media_entity.
+ */
+
+use \Drush\Log\LogLevel;
+
+/**
+ * Implements drush_hook_COMMAND_validate().
+ */
+function drush_media_entity_updatedb_validate() {
+  // This hook exists because when running DB updates using drush,
+  // hook_requirements() is not enforced (see
+  // https://github.com/drush-ops/drush/pull/2708 for more info on that).
+  // Here we just re-evaluate all the checks from hook_requirements() and abort
+  // the "updatedb/updb" command by returning FALSE to this hook if any of them
+  // is not met.
+  drush_bootstrap_to_phase(DRUSH_BOOTSTRAP_DRUPAL_FULL);
+  module_load_include('install', 'media_entity');
+
+  $errors = [];
+
+  // This update only makes sense with core >= 8.4.x.
+  $version = explode('.', \Drupal::VERSION);
+  if ($version[1] < 4) {
+    $errors[] = dt('The Media Entity 2.x upgrade path only works with Drupal core >= 8.4.x');
+  }
+
+  // This update can't proceed if there already is an enabled module called
+  // "media".
+  if (\Drupal::moduleHandler()->moduleExists('media')) {
+    $errors[] = dt('In order to run the Media Entity 2.x upgrade, please uninstall and remove from the codebase the contributed "Media" module.');
+  }
+
+  // Prevent the updates from running if there is a type-provider that is
+  // still on the 1.x branch.
+  $incompatible_modules = _media_entity_get_incompatible_modules();
+  if (!empty($incompatible_modules)) {
+    $provider_modules = !empty($incompatible_modules['providers']) ? implode(", ", $incompatible_modules['providers']) : '';
+    $additional_msg_providers = !empty($provider_modules) ? ' ' . t('The following modules provide source plugins and need to be upgraded: @provider_modules.', [
+      '@provider_modules' => $provider_modules,
+    ]) : '';
+    $dependent_modules = !empty($incompatible_modules['modules']) ? implode(", ", $incompatible_modules['modules']) : '';
+    $additional_msg_dependent = !empty($dependent_modules) ? ' ' . t('The following modules depend on media entity and need to be either upgraded or uninstalled: @dependent_modules.', [
+      '@dependent_modules' => $dependent_modules,
+    ]) : '';
+    $errors[] = dt('In order to run the Media Entity updates, please make sure all modules that provide plugins for Media Entity (or depend on it) have their code updated to their respective 2.x branches. Note that you will probably need to revert to the 1.x branch of the Media Entity module if you want to uninstall existing plugin modules.') . $additional_msg_providers . $additional_msg_dependent;
+  }
+
+  if (empty($errors)) {
+    return TRUE;
+  }
+  else {
+    foreach ($errors as $error_msg) {
+      // We can't use drush_log() inside this hook.
+      drush_print($error_msg);
+    }
+    return FALSE;
+  }
+}
+
+/**
+ * Implements hook_drush_command().
+ */
+function media_entity_drush_command() {
+
+  $items['media-entity-check-upgrade'] = array(
+    'description' => 'Check upgrade requirements for Media Entity into Media in core.',
+    'aliases' => ['mecu'],
+    'core' => ['8+'],
+    'examples' => [
+      "drush mecu" => "Checks upgrade requirements for Media Entity whil upgrading to Media in core.",
+    ],
+  );
+
+  return $items;
+}
+
+/**
+ * Callback for drush commmand "media-entity-check-upgrade" (mecu).
+ */
+function drush_media_entity_check_upgrade() {
+  drush_bootstrap_to_phase(DRUSH_BOOTSTRAP_DRUPAL_FULL);
+  // This command is useless if the DB updates have already been run.
+  if (drupal_get_installed_schema_version('media_entity') >= 8004) {
+    drush_log(dt('Your site has already run the media_entity DB updates. If you believe this is not correct, you should consider rolling back your database to a previous backup and try again.'), LogLevel::WARNING);
+    return;
+  }
+  module_load_include('install', 'media_entity');
+  $errors = [];
+  $passes = [];
+
+  // Check that core version is OK.
+  $version = explode('.', \Drupal::VERSION);
+  if ($version[1] < 4) {
+    $errors[] = dt('The Media Entity 2.x upgrade path only works with Drupal core >= 8.4.x');
+  }
+  else {
+    $passes[] = dt('Drupal core is the correct version (>= 8.4.0). [@version detected]', ['@version' => \Drupal::VERSION]);
+  }
+
+  // Check that contrib "Media" is not enabled in the current site.
+  if (\Drupal::moduleHandler()->moduleExists('media')) {
+    $errors[] = dt('In order to run the Media Entity 2.x upgrade, please uninstall and remove from the codebase the contributed "Media" module.');
+  }
+  else {
+    $passes[] = dt('Successfully checked that the "Media" module is not installed.');
+  }
+
+  // If there are any generic media bundles, ensure that media_entity_generic
+  // is available.
+  $generic_types = _media_entity_get_bundles_by_plugin('generic');
+  if ($generic_types) {
+    $module_data = system_rebuild_module_data();
+    if (isset($module_data['media_entity_generic'])) {
+      $passes[] = dt('Successfully located the media_entity_generic module.');
+    }
+    else {
+      $errors[] = dt('One or more of your existing media types use the Generic source, which has been moved into a separate Media Entity Generic module. Please ensure this module is available before continuing.');
+    }
+  }
+
+  // Check dependent modules and provider plugins.
+  $incompatible_modules = _media_entity_get_incompatible_modules();
+  if (!empty($incompatible_modules)) {
+    $provider_modules = !empty($incompatible_modules['providers']) ? implode(", ", $incompatible_modules['providers']) : '';
+    $additional_msg_providers = !empty($provider_modules) ? ' ' . t('The following modules provide source plugins and need to be upgraded: @provider_modules.', [
+      '@provider_modules' => $provider_modules,
+    ]) : '';
+    $dependent_modules = !empty($incompatible_modules['modules']) ? implode(", ", $incompatible_modules['modules']) : '';
+    $additional_msg_dependent = !empty($dependent_modules) ? ' ' . t('The following modules depend on media entity and need to be either upgraded or uninstalled: @dependent_modules.', [
+      '@dependent_modules' => $dependent_modules,
+    ]) : '';
+    $errors[] = dt('In order to run the Media Entity updates, please make sure all modules that provide plugins for Media Entity (or depend on it) have their code updated to their respective 2.x branches. Note that you will probably need to revert to the 1.x branch of the Media Entity module if you want to uninstall existing plugin modules.') . $additional_msg_providers . $additional_msg_dependent;
+  }
+  else {
+    $passes[] = dt('Successfully checked that all provider plugins and modules depending on media_entity were updated.');
+  }
+
+  if (empty($errors)) {
+    drush_log(sprintf("\033[1;32;40m\033[1m%s\033[0m", '✓') . ' ' . dt('SUCCESS: All upgrade requirements are met and you can proceed with the DB updates.'), LogLevel::OK);
+  }
+  else {
+    drush_log(sprintf("\033[31;40m\033[1m%s\033[0m", '✗') . ' ' . dt('ERROR: Your site did not pass all upgrade checks. You can find more information in the error messages below.'), LogLevel::ERROR);
+  }
+  foreach ($passes as $pass_msg) {
+    drush_log($pass_msg, LogLevel::OK);
+  }
+  foreach ($errors as $error_msg) {
+    drush_log($error_msg, LogLevel::ERROR);
+  }
+}
diff --git a/media_entity.info.yml b/media_entity.info.yml
index fe5b1b0..38b000e 100644
--- a/media_entity.info.yml
+++ b/media_entity.info.yml
@@ -1,4 +1,4 @@
-name: Media entity
+name: Media entity (2.x)
 description: 'Media entity API.'
 type: module
 package: Media
@@ -7,8 +7,5 @@ dependencies:
   - drupal:image
   - drupal:user
   - drupal:views
-  - entity:entity (>=8.x-1.0-alpha3)
-  - drupal:system (>=8.1.0)
-test_dependencies:
   - entity:entity
-  - inline_entity_form:inline_entity_form
+  - drupal:system
diff --git a/media_entity.install b/media_entity.install
index b0c1415..f931ac0 100644
--- a/media_entity.install
+++ b/media_entity.install
@@ -5,6 +5,11 @@
  * Install, uninstall and update hooks for Media entity module.
  */
 
+use \Drupal\user\Entity\Role;
+use \Drupal\Core\Url;
+use \Drupal\Core\Database\Database;
+use Drupal\Core\Config\Entity\Query\QueryFactory;
+
 /**
  * Checks if required version of the Entity API is installed.
  *
@@ -23,6 +28,128 @@ function _media_entity_check_entity_version() {
 }
 
 /**
+ * Checks if all contrib modules depending on media_entity were updated.
+ *
+ * @return array
+ *   An empty array if all modules that depend on media_entity were updated, or
+ *   an array of incompatible modules otherwise. This array will be keyed by
+ *   either "providers" or "modules", depending if the incompatible module is a
+ *   contrib module that provides a type plugin (in which case it is expected to
+ *   have been upgraded to its 2.x branch) or just a module that depends on
+ *   "media_entity", respectively.
+ */
+function _media_entity_get_incompatible_modules() {
+  $incompatible_modules = [];
+  // Modules that provide provider plugins need to have ben updated and be
+  // implementing now @MediaSource instead of @MediaType plugins.
+  $old_plugins = \Drupal::service('plugin.manager.media_entity.type')->getDefinitions();
+  // The main media_entity module defines a "generic" type. We are directly
+  // handling this provider's configs in the update hook.
+  unset($old_plugins['generic']);
+  foreach ($old_plugins as $plugin => $definition) {
+    $incompatible_modules['providers'][$definition['provider']] = $definition['provider'];
+  }
+  // None of the enabled modules in the system should at this point depend on
+  // media_entity anymore.
+  /** @var \Drupal\Core\Extension\Extension[] $module_list */
+  $module_list = \Drupal::moduleHandler()->getModuleList();
+  foreach (array_keys($module_list) as $module_name) {
+    $info = system_get_info('module', $module_name);
+    foreach ($info['dependencies'] as $dependency) {
+      if ($dependency === 'media_entity' || $dependency === 'media_entity:media_entity') {
+        $incompatible_modules['modules'][$module_name] = $module_name;
+      }
+    }
+  }
+
+  // Disregard "media_entity_document" and "media_entity_image", once we will
+  // uninstall them ourselves as part of the update hook.
+  unset($incompatible_modules['providers']['media_entity_document']);
+  unset($incompatible_modules['modules']['media_entity_document']);
+  unset($incompatible_modules['providers']['media_entity_image']);
+  unset($incompatible_modules['modules']['media_entity_image']);
+  if (empty($incompatible_modules['providers'])) {
+    unset($incompatible_modules['providers']);
+  }
+  if (empty($incompatible_modules['modules'])) {
+    unset($incompatible_modules['modules']);
+  }
+
+  return $incompatible_modules;
+}
+
+/**
+ * Helper function to rename config dependencies.
+ *
+ * @param string $dependency_type
+ *   The type of the dependency, such as "module" or "config".
+ * @param string $dependency_id
+ *   The name of the dependency to be updated.
+ * @param callable $map
+ *   A callback to be passed to array_map() to actually perform the config name
+ *   substitution.
+ */
+function _media_entity_fix_dependencies($dependency_type, $dependency_id, callable $map) {
+  $dependents = \Drupal::service('config.manager')
+    ->findConfigEntityDependents($dependency_type, [$dependency_id]);
+
+  $key = 'dependencies.' . $dependency_type;
+
+  foreach (array_keys($dependents) as $config) {
+    $config = \Drupal::configFactory()->getEditable($config);
+    $dependencies = $config->get($key);
+    if (is_array($dependencies)) {
+      $config->set($key, array_map($map, $dependencies))->save();
+    }
+  }
+}
+
+/**
+ * Helper function to determine the name of a source field.
+ *
+ * @return string
+ *   The source field name. If one is already stored in configuration, it is
+ *   returned. Otherwise, a new, unused one is generated.
+ */
+function _media_get_source_field_name($plugin_id) {
+  $base_id = 'field_media_' . $plugin_id;
+  $tries = 0;
+  $storage = \Drupal::entityTypeManager()->getStorage('field_storage_config');
+
+  // Iterate at least once, until no field with the generated ID is found.
+  do {
+    $id = $base_id;
+    // If we've tried before, increment and append the suffix.
+    if ($tries) {
+      $id .= '_' . $tries;
+    }
+    $field = $storage->load('media.' . $id);
+    $tries++;
+  } while ($field);
+
+  return $id;
+}
+
+/**
+ * Gets the names of all media bundles that use a particular type plugin.
+ *
+ * @param string $plugin_id
+ *   The type plugin ID.
+ *
+ * @return string[]
+ *   The media bundle IDs which use the specified plugin.
+ */
+function _media_entity_get_bundles_by_plugin($plugin_id) {
+  $types = [];
+  foreach (\Drupal::configFactory()->listAll('media_entity.bundle') as $name) {
+    if (\Drupal::config($name)->get('type') == $plugin_id) {
+      $types[] = explode('.', $name, 3)[2];
+    }
+  }
+  return $types;
+}
+
+/**
  * Implements hook_requirements().
  */
 function media_entity_requirements($phase) {
@@ -38,6 +165,101 @@ function media_entity_requirements($phase) {
       'severity' => REQUIREMENT_ERROR,
     ];
   }
+
+  // Prevent this branch from being installed on new sites.
+  if ($phase == 'install') {
+    $requirements['media_entity_update_only'] = [
+      'title' => t('Media entity'),
+      'description' => t('This branch of Media Entity is intended for site upgrades only. Please use the 1.x branch or Drupal core >= 8.4.x if you are building a new site.'),
+      'severity' => REQUIREMENT_ERROR,
+    ];
+  }
+
+  if ($phase == 'update') {
+    // Here we want to ensure that a series of requirements are met before
+    // letting the DB updates continue. However, the batch processing of
+    // hook_update_N() triggers this validation again during the update process.
+    // Because of that, we want to make sure that these requirements checks are
+    // only evaluated once, and we use a state variable for that.
+    if (!\Drupal::state()->get('media_entity_core_upgrade_started')) {
+      // This update only makes sense with core >= 8.4.x.
+      $version = explode('.', \Drupal::VERSION);
+      if ($version[1] < 4) {
+        $requirements['media_module_core_incompatibility'] = [
+          'title' => t('Media Entity'),
+          'value' => t('The Media Entity 2.x upgrade path only works with Drupal core >= 8.4.x'),
+          'description' => t('In order to run the Media Entity 2.x upgrade, please upgrade first Drupal core to at least 8.4.x.'),
+          'severity' => REQUIREMENT_ERROR,
+        ];
+      }
+      // This update can't proceed if there is an already enabled module called
+      // "media".
+      if (\Drupal::moduleHandler()->moduleExists('media')) {
+        $requirements['media_module_exists'] = [
+          'title' => t('Media Entity'),
+          'value' => t('Existing Media module detected.'),
+          'description' => t('In order to run the Media Entity 2.x upgrade, please uninstall and remove from the codebase the contributed Media module.'),
+          'severity' => REQUIREMENT_ERROR,
+        ];
+      }
+      // Prevent the updates from running if there is a type-provider that is
+      // still on the 1.x branch.
+      $incompatible_modules = _media_entity_get_incompatible_modules();
+      if (!empty($incompatible_modules)) {
+        $provider_modules = !empty($incompatible_modules['providers']) ? implode(", ", $incompatible_modules['providers']) : '';
+        $additional_msg_providers = !empty($provider_modules) ? ' ' . t('The following modules provide source plugins and need to be upgraded: @provider_modules.', [
+          '@provider_modules' => $provider_modules,
+        ]) : '';
+        $dependent_modules = !empty($incompatible_modules['modules']) ? implode(", ", $incompatible_modules['modules']) : '';
+        $additional_msg_dependent = !empty($dependent_modules) ? ' ' . t('The following modules depend on media entity and need to be either upgraded or uninstalled: @dependent_modules.', [
+          '@dependent_modules' => $dependent_modules,
+        ]) : '';
+        $requirements['media_entity_modules_compatibility'] = [
+          'title' => t('Media entity'),
+          'value' => t('Some modules that depend on media entity were not updated or uninstalled.'),
+          'description' => t('In order to run the Media Entity updates, please make sure all modules that provide plugins for Media Entity (or depend on it) have their code updated to their respective 2.x branches. Note that you will probably need to revert to the 1.x branch of the Media Entity module if you want to uninstall existing plugin modules.') . $additional_msg_providers . $additional_msg_dependent,
+          'severity' => REQUIREMENT_ERROR,
+        ];
+      }
+
+      $generic_types = _media_entity_get_bundles_by_plugin('generic');
+      if ($generic_types) {
+        $module_data = system_rebuild_module_data();
+        if (!isset($module_data['media_entity_generic'])) {
+          $requirements['media_entity_generic'] = [
+            'title' => t('Media entity generic'),
+            'description' => t('One or more of your existing media types are using the Generic source, which has been moved into a separate Media Entity Generic module. You need to download this module before continuing.'),
+            'severity' => REQUIREMENT_ERROR,
+          ];
+        }
+      }
+    }
+
+  }
+
+  if ($phase == 'runtime') {
+    if (drupal_get_installed_schema_version('media_entity') < 8201) {
+      $requirements['media_entity_update_status'] = [
+        'title' => t('Media Entity'),
+        'value' => t('DB updates for Media Entity pending.'),
+        'description' => t('After updating the Media Entity code, you need to run the <a href=":update">database update script</a> as soon as possible.', [
+          ':update' => Url::fromRoute('system.db_update')->toString(),
+        ]),
+        'severity' => REQUIREMENT_WARNING,
+      ];
+    }
+    else {
+      $requirements['media_entity_update_status'] = [
+        'title' => t('Media Entity'),
+        'value' => t('DB updates for Media Entity were run.'),
+        // @TODO There are cases where media_entity will need to stay enabled.
+        // @TODO Tweak this message to account for that.
+        'description' => t('The Media Entity upgrade path was executed, you can now uninstall and remove the Media Entity module from the codebase.'),
+        'severity' => REQUIREMENT_OK,
+      ];
+    }
+  }
+
   return $requirements;
 }
 
@@ -101,3 +323,183 @@ function media_entity_update_8003() {
     throw new \Drupal\Core\Utility\UpdateException('Entity API >= 8.x-1.0-alpha3 (drupal.org/project/entity) module is now a dependency and needs to be installed before running updates.');
   }
 }
+
+/**
+ * Clears the module handler's hook implementation cache.
+ */
+function media_entity_update_8200() {
+  \Drupal::moduleHandler()->resetImplementations();
+}
+
+/**
+ * Replace Media Entity with Media.
+ */
+function media_entity_update_8201() {
+  $config_factory = \Drupal::configFactory();
+
+  \Drupal::state()->set('media_entity_core_upgrade_started', TRUE);
+
+  $snapshots = _media_entity_snapshot_config([
+    'core.entity_form_display.media.file.default',
+    'core.entity_form_display.media.image.default',
+    'core.entity_view_display.media.file.default',
+    'core.entity_view_display.media.image.default',
+  ], TRUE);
+
+  $install = ['media'];
+  // Install media_entity_generic if available. It stands to reason that this
+  // module will only be available if you have at least one media type that uses
+  // the generic plugin, since it has been split out into its own module and is
+  // only requested if there are media bundles that use it.
+  // See media_entity_requirements().
+  $module_data = system_rebuild_module_data();
+  if (isset($module_data['media_entity_generic'])) {
+    $install[] = 'media_entity_generic';
+  }
+  \Drupal::service('module_installer')->install($install);
+
+  foreach ($snapshots as $name => $data) {
+    $config_factory->getEditable($name)->setData($data)->save(TRUE);
+  }
+  unset($snapshots);
+
+  // Fix the schema.
+  /** @var \Drupal\Core\Field\FieldStorageDefinitionInterface[] $field_definitions */
+  $field_definitions = \Drupal::service('entity_field.manager')->getFieldStorageDefinitions('media');
+  $db = Database::getConnection()->schema();
+  $db->changeField('media_revision', 'revision_uid', 'revision_user', $field_definitions['revision_user']->getColumns()[$field_definitions['revision_user']->getMainPropertyName()]);
+  $db->changeField('media_revision', 'revision_timestamp', 'revision_created', $field_definitions['revision_created']->getColumns()[$field_definitions['revision_created']->getMainPropertyName()]);
+  $db->changeField('media_revision', 'revision_log', 'revision_log_message', $field_definitions['revision_log_message']->getColumns()[$field_definitions['revision_log_message']->getMainPropertyName()]);
+
+  // Delete file/image media types automatically created by core media.
+  $auto_created_types = \Drupal::entityTypeManager()->getStorage('media_type')
+    ->loadMultiple(['file', 'image']);
+  foreach ($auto_created_types as $created_type) {
+    $created_type->delete();
+  }
+
+  // Move all module dependencies on existing config entities from
+  // "media_entity" to "media".
+  _media_entity_fix_dependencies('module', 'media_entity', function ($module) {
+    return $module === 'media_entity' ? 'media' : $module;
+  });
+  // Move all module dependencies on existing config entities from
+  // "media_entity_document" to "media".
+  _media_entity_fix_dependencies('module', 'media_entity_document', function ($module) {
+    return $module === 'media_entity_document' ? 'media' : $module;
+  });
+  // Move all module dependencies on existing config entities from
+  // "media_entity_image" to "media".
+  _media_entity_fix_dependencies('module', 'media_entity_image', function ($module) {
+    return $module === 'media_entity_image' ? 'media' : $module;
+  });
+
+  // Move media_entity.settings to media.settings. Note that we don't read and
+  // save in bulk because the key "icon_base" moved to "icon_base_uri".
+  $config_factory->getEditable('media.settings')
+    ->set('icon_base_uri', $config_factory->get('media_entity.settings')->get('icon_base'))
+    ->save();
+  $config_factory->getEditable('media_entity.settings')->delete();
+
+  // Move all bundle configs to the new plugin namespace. This means moving all
+  // "media_entity.bundle.*" to "media.type.*".
+  foreach ($config_factory->listAll('media_entity.bundle.') as $original_name) {
+    $search = '/^media_entity\.bundle\./';
+    $replace = 'media.type.';
+
+    $new_name = preg_replace($search, $replace, $original_name);
+    $config_factory->rename($original_name, $new_name);
+
+    $config = $config_factory->getEditable($new_name);
+    $source_id = $config->get('type');
+    $config
+      ->set('source_configuration', $config->get('type_configuration'))
+      ->clear('type_configuration')
+      ->set('source', $source_id == 'document' ? 'file' : $source_id)
+      ->clear('type')
+      ->save();
+
+    _media_entity_fix_dependencies('config', $original_name, function ($bundle_id) use ($search, $replace) {
+      return preg_replace($search, $replace, $bundle_id);
+    });
+
+    /** @var \Drupal\media\MediaTypeInterface $media_type */
+    $media_type = \Drupal::entityTypeManager()->getStorage('media_type')
+      ->load($config->get('id'));
+    $media_source = $media_type->getSource();
+    $source_field = $media_source->getSourceFieldDefinition($media_type);
+    if (!$source_field) {
+      $source_field = $media_source->createSourceField($media_type);
+      $source_field->getFieldStorageDefinition()->save();
+      $source_field->save();
+
+      $media_type
+        ->set('source_configuration', [
+          'source_field' => $source_field->getName(),
+        ]);
+    }
+    $media_type->save();
+  }
+  // Clear the old UUID map.
+  \Drupal::keyValue(QueryFactory::CONFIG_LOOKUP_PREFIX . 'media_bundle')->deleteAll();
+
+  /** @var \Drupal\user\Entity\Role $role */
+  foreach (Role::loadMultiple() as $role) {
+    if ($role->hasPermission('administer media bundles')) {
+      $role
+        ->revokePermission('administer media bundles')
+        ->grantPermission('administer media types')
+        ->save();
+    }
+  }
+
+  // Disable media_entity_image and media_entity_document straight away.
+  \Drupal::service('module_installer')->uninstall([
+    'media_entity_image',
+    'media_entity_document',
+  ]);
+}
+
+/**
+ * Collects snapshots of config objects.
+ *
+ * @param string[] $names
+ *   The names of the config objects to snapshot.
+ * @param bool $delete
+ *   (optional) Whether to delete the original config objects. Defaults to
+ *   FALSE.
+ *
+ * @return array
+ *   The config data, keyed by object name.
+ */
+function _media_entity_snapshot_config(array $names, $delete = FALSE) {
+  $snapshots = [];
+  foreach ($names as $name) {
+    $config = \Drupal::configFactory()->getEditable($name);
+
+    if (!$config->isNew()) {
+      $snapshots[$name] = $config->get();
+
+      if ($delete) {
+        $config->delete();
+      }
+    }
+  }
+  return $snapshots;
+}
+
+/**
+ * Implements hook_update_dependencies().
+ */
+function media_entity_update_dependencies() {
+  $dependencies = [];
+
+  // Ensure that system_update_8402 is aware of the media entity type, which is
+  // declared dynamically in hook_entity_type_build(). We need to clear the
+  // module handler's hook implementation cache so as to guarantee that it is
+  // aware of media_entity_entity_type_build().
+  $dependencies['system'][8402]['media_entity'] = 8200;
+  $dependencies['media_entity'][8201]['system'] = 8402;
+
+  return $dependencies;
+}
diff --git a/media_entity.libraries.yml b/media_entity.libraries.yml
deleted file mode 100644
index be72e0a..0000000
--- a/media_entity.libraries.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-media_bundle_form:
-  version: VERSION
-  js:
-    'js/media_bundle_form.js': {}
-  dependencies:
-    - core/jquery
-    - core/drupal
-    - core/drupal.form
diff --git a/media_entity.links.action.yml b/media_entity.links.action.yml
deleted file mode 100644
index 87e2fa3..0000000
--- a/media_entity.links.action.yml
+++ /dev/null
@@ -1,12 +0,0 @@
-media.bundle_add:
-  route_name: entity.media_bundle.add_form
-  title: 'Add media bundle'
-  appears_on:
-    - entity.media_bundle.collection
-
-media.add:
-  route_name: entity.media.add_page
-  title: 'Add media'
-  weight: 10
-  appears_on:
-    - view.media.media_page_list
diff --git a/media_entity.links.contextual.yml b/media_entity.links.contextual.yml
deleted file mode 100644
index cce5f83..0000000
--- a/media_entity.links.contextual.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-entity.media.edit_form:
-  route_name: entity.media.edit_form
-  group: media
-  title: Edit
-entity.media.delete_form:
-  route_name: entity.media.delete_form
-  group: media
-  title: Delete
-  weight: 10
diff --git a/media_entity.links.menu.yml b/media_entity.links.menu.yml
deleted file mode 100644
index 55b2bf3..0000000
--- a/media_entity.links.menu.yml
+++ /dev/null
@@ -1,17 +0,0 @@
-entity.media_bundle.collection:
-  title: 'Media bundles'
-  parent: system.admin_structure
-  description: 'Manage media bundles.'
-  route_name: entity.media_bundle.collection
-
-entity.media.collection:
-  title: 'Media'
-  parent: system.admin_content
-  description: 'Find and manage media.'
-  route_name: view.media.media_page_list
-
-entity.media.add:
-  title: 'Add a new media'
-  parent: entity.media.collection
-  description: 'Add a new media entity.'
-  route_name: entity.media.add_page
diff --git a/media_entity.links.task.yml b/media_entity.links.task.yml
deleted file mode 100644
index c044847..0000000
--- a/media_entity.links.task.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-entity.media.canonical:
-  route_name: entity.media.canonical
-  base_route: entity.media.canonical
-  title: 'View'
-entity.media.edit_form:
-  route_name: entity.media.edit_form
-  base_route: entity.media.canonical
-  title: Edit
-entity.media.delete_form:
-  route_name: entity.media.delete_form
-  base_route: entity.media.canonical
-  title: Delete
-  weight: 10
-entity.media_bundle.edit_form:
-  title: 'Edit'
-  route_name: entity.media_bundle.edit_form
-  base_route: entity.media_bundle.edit_form
-entity.media_bundle.collection:
-  title: List
-  route_name: entity.media_bundle.collection
-  base_route: entity.media_bundle.collection
diff --git a/media_entity.module b/media_entity.module
index d54f773..9012a86 100644
--- a/media_entity.module
+++ b/media_entity.module
@@ -5,80 +5,53 @@
  * Provides media entities.
  */
 
-use Drupal\Core\Routing\RouteMatchInterface;
+// This empty file needs to be here so that drush commands that automatically
+// include .module files on enabled modules don't complain.
 
-/**
- * Implements hook_help().
- */
-function media_entity_help($route_name, RouteMatchInterface $route_match) {
-  switch ($route_name) {
-    case 'help.page.media_entity':
-      $output = '<h3>' . t('About') . '</h3>';
-      $output .= '<p>' . t('The <a href=":media_entity_url">Media Entity</a> module provides a "base" entity for media. This is a very basic entity which can reference to all kinds of media-objects (local files, YouTube videos, Tweets, Instagram photos, ...). Media entity provides a relation between your website and the media resource. You can reference to/use this entity within any other entity on your site. For more information, see the <a href=":media_entity_handbook">online documentation for the Media Entity module</a>.',
-          [
-            ':media_entity_url' => 'https://www.drupal.org/project/media_entity',
-            ':media_entity_handbook' => 'https://drupal-media.gitbooks.io/drupal8-guide/content/modules/media_entity/intro.html',
-          ]) . '</p>';
-      $output .= '<h3>' . t('Uses') . '</h3>';
-      $output .= '<p>' . t('For detailed information about the usage of this module please refer to <a href=":media_entity_handbook">the official documentation</a>.',
-          [
-            ':media_entity_handbook' => 'https://drupal-media.gitbooks.io/drupal8-guide/content/modules/media_entity/intro.html',
-          ]) . '</p>';
-
-      return $output;
-  }
-}
-
-/**
- * Implements hook_theme().
- */
-function media_entity_theme() {
-  return [
-    'media' => [
-      'render element' => 'elements',
-      'file' => 'media_entity.theme.inc',
-      'template' => 'media',
-    ],
-  ];
-}
+use Drupal\Core\Config\Entity\ConfigEntityType;
+use Drupal\Core\Entity\ContentEntityType;
+use Drupal\media_entity\Media;
+use Drupal\media_entity\MediaBundle;
 
 /**
- * Implements hook_theme_suggestions_HOOK().
+ * Implements hook_entity_type_build().
  */
-function media_entity_theme_suggestions_media(array $variables) {
-  $suggestions = [];
-  $media = $variables['elements']['#media'];
-  $sanitized_view_mode = strtr($variables['elements']['#view_mode'], '.', '_');
-
-  $suggestions[] = 'media__' . $sanitized_view_mode;
-  $suggestions[] = 'media__' . $media->bundle();
-  $suggestions[] = 'media__' . $media->bundle() . '__' . $sanitized_view_mode;
-  $suggestions[] = 'media__' . $media->id();
-  $suggestions[] = 'media__' . $media->id() . '__' . $sanitized_view_mode;
-
-  return $suggestions;
-}
-
-/**
- * Copy the media file icons to files directory for use with image styles.
- *
- * @param string $source
- *   Source folder.
- * @param string $destination
- *   Destination folder.
- *
- * @throws Exception
- */
-function media_entity_copy_icons($source, $destination) {
-  if (!file_prepare_directory($destination, FILE_CREATE_DIRECTORY | FILE_MODIFY_PERMISSIONS)) {
-    throw new Exception("Unable to create directory $destination.");
-  }
-
-  $files = file_scan_directory($source, '/.*\.(png|jpg)$/');
-  foreach ($files as $file) {
-    $result = file_unmanaged_copy($file->uri, $destination, FILE_EXISTS_REPLACE);
-    if (!$result) {
-      throw new Exception("Unable to copy {$file->uri} to $destination.");
-    }
+function media_entity_entity_type_build(array &$entity_types) {
+  if (!\Drupal::moduleHandler()->moduleExists('media')) {
+    $entity_types['media'] = new ContentEntityType([
+      'id' => 'media',
+      'provider' => 'media_entity',
+      'class' => Media::class,
+      'base_table' => 'media',
+      'data_table' => 'media_field_data',
+      'revision_table' => 'media_revision',
+      'revision_data_table' => 'media_field_revision',
+      'translatable' => TRUE,
+      'entity_keys' => [
+        'id' => 'mid',
+        'revision' => 'vid',
+        'bundle' => 'bundle',
+        'label' => 'name',
+        'langcode' => 'langcode',
+        'uuid' => 'uuid',
+        'published' => 'status',
+      ],
+      'revision_metadata_keys' => [
+        'revision_user' => 'revision_user',
+        'revision_created' => 'revision_created',
+        'revision_log_message' => 'revision_log_message',
+      ],
+      'bundle_entity_type' => 'media_bundle',
+    ]);
+    $entity_types['media_bundle'] = new ConfigEntityType([
+      'id' => 'media_bundle',
+      'provider' => 'media_entity',
+      'class' => MediaBundle::class,
+      'bundle_of' => 'media',
+      'entity_keys' => [
+        'id' => 'id',
+        'label' => 'label',
+      ],
+    ]);
   }
 }
diff --git a/media_entity.permissions.yml b/media_entity.permissions.yml
deleted file mode 100644
index 6a55f92..0000000
--- a/media_entity.permissions.yml
+++ /dev/null
@@ -1,21 +0,0 @@
-administer media:
-  title: 'Administer media'
-  restrict access: TRUE
-administer media bundles:
-  title: 'Administer media bundles'
-  restrict access: TRUE
-access media overview:
-  title: 'Access the Media overview page'
-  description: 'Get an overview of all media items.'
-view media:
-  title: 'View media'
-update media:
-  title: 'Update media'
-update any media:
-  title: 'Update any media'
-delete media:
-  title:  'Delete media'
-delete any media:
-  title:  'Delete any media'
-create media:
-  title: 'Create media'
diff --git a/media_entity.plugin_type.yml b/media_entity.plugin_type.yml
deleted file mode 100644
index ac7b953..0000000
--- a/media_entity.plugin_type.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-media_type:
-  label: 'Media type'
-  plugin_manager_service_id: plugin.manager.media_entity.type
-  plugin_definition_decorator_class: \Drupal\plugin\PluginDefinition\ArrayPluginDefinitionDecorator
-  plugin_configuration_schema_id: media_entity.bundle.type.[plugin_id]
diff --git a/media_entity.routing.yml b/media_entity.routing.yml
deleted file mode 100644
index b4c75ba..0000000
--- a/media_entity.routing.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-entity.media.multiple_delete_confirm:
-  path: '/admin/content/media/delete'
-  defaults:
-    _form: '\Drupal\media_entity\Form\DeleteMultiple'
-  requirements:
-    _permission: 'delete any media'
-
-entity.media_bundle.collection:
-  path: '/admin/structure/media'
-  defaults:
-    _entity_list: 'media_bundle'
-    _title: 'Media bundles'
-  requirements:
-    _permission: 'administer media bundles'
diff --git a/media_entity.theme.inc b/media_entity.theme.inc
deleted file mode 100644
index 605348c..0000000
--- a/media_entity.theme.inc
+++ /dev/null
@@ -1,65 +0,0 @@
-<?php
-
-/**
- * @file
- * Theme functions for the media_entity module.
- */
-
-use Drupal\Core\Render\Element;
-use Drupal\Core\Link;
-use Drupal\Component\Utility\Html;
-
-/**
- * Prepares variables for list of available media bundles.
- *
- * Default template: media-add-list.html.twig.
- *
- * @param array $variables
- *   An associative array containing:
- *   - content: An array of content types.
- */
-function template_preprocess_media_add_list(&$variables) {
-  $variables['bundles'] = [];
-  if (!empty($variables['content'])) {
-    foreach ($variables['content'] as $bundle) {
-      /** @var \Drupal\media_entity\MediaBundleInterface $bundle */
-      $variables['bundles'][$bundle->id()] = [
-        'type' => $bundle->id(),
-        'add_link' => Link::createFromRoute($bundle->label(), 'media.add', ['media_bundle' => $bundle->id()]),
-        'description' => [
-          '#markup' => $bundle->getDescription(),
-        ],
-      ];
-    }
-  }
-}
-
-/**
- * Prepares variables for media templates.
- *
- * Default template: media.html.twig.
- *
- * @param array $variables
- *   An associative array containing:
- *   - media: An individual media for display.
- */
-function template_preprocess_media(&$variables) {
-  /** @var \Drupal\media_entity\MediaInterface $media */
-  $media = $variables['elements']['#media'];
-
-  $variables['name'] = $media->label();
-
-  // Helpful $content variable for templates.
-  foreach (Element::children($variables['elements']) as $key) {
-    $variables['content'][$key] = $variables['elements'][$key];
-  }
-
-  $variables['attributes']['class'][] = 'media';
-  $variables['attributes']['class'][] = Html::getClass('media-' . $media->bundle());
-  if (!$media->isPublished()) {
-    $variables['attributes']['class'][] = 'unpublished';
-  }
-  if ($variables['elements']['#view_mode']) {
-    $variables['attributes']['class'][] = Html::getClass('view-mode-' . $variables['elements']['#view_mode']);
-  }
-}
diff --git a/media_entity.tokens.inc b/media_entity.tokens.inc
deleted file mode 100644
index 58bd861..0000000
--- a/media_entity.tokens.inc
+++ /dev/null
@@ -1,193 +0,0 @@
-<?php
-
-/**
- * @file
- * Builds placeholder replacement tokens for media_entity-related data.
- */
-
-use Drupal\Component\Utility\Html;
-use Drupal\Core\Datetime\Entity\DateFormat;
-use Drupal\Core\Language\LanguageInterface;
-use Drupal\Core\Render\BubbleableMetadata;
-use Drupal\media_entity\Entity\MediaBundle;
-
-/**
- * Implements hook_token_info().
- */
-function media_entity_token_info() {
-  $type = [
-    'name' => t('Media'),
-    'description' => t('Tokens related to individual media items.'),
-    'needs-data' => 'media',
-  ];
-
-  // Core tokens for media.
-  $media['mid'] = [
-    'name' => t("Media ID"),
-    'description' => t('The unique ID of the media item.'),
-  ];
-  $media['uuid'] = [
-    'name' => t("Media UUID"),
-    'description' => t('The unique UUID of the media item.'),
-  ];
-  $media['vid'] = [
-    'name' => t("Revision ID"),
-    'description' => t("The unique ID of the media's latest revision."),
-  ];
-  $media['bundle'] = [
-    'name' => t("Media bundle"),
-  ];
-  $media['bundle-name'] = [
-    'name' => t("Media bundle name"),
-    'description' => t("The human-readable name of the media bundle."),
-  ];
-  $media['langcode'] = [
-    'name' => t('Language code'),
-    'description' => t('The language code of the language the media is written in.'),
-  ];
-  $media['name'] = [
-    'name' => t('Name'),
-    'description' => t('The name of this media.'),
-  ];
-  $media['type'] = [
-    'name' => t("Type"),
-    'description' => t("The type of this media."),
-  ];
-  $node['author'] = [
-    'name' => t("Author"),
-    'type' => 'user',
-  ];
-  $media['url'] = [
-    'name' => t("URL"),
-    'description' => t("The URL of the media."),
-  ];
-  $media['edit-url'] = [
-    'name' => t("Edit URL"),
-    'description' => t("The URL of the media's edit page."),
-  ];
-
-  // Chained tokens for media.
-  $media['created'] = [
-    'name' => t("Date created"),
-    'type' => 'date',
-  ];
-  $media['changed'] = [
-    'name' => t("Date changed"),
-    'description' => t("The date the media was most recently updated."),
-    'type' => 'date',
-  ];
-
-  return [
-    'types' => ['media' => $type],
-    'tokens' => ['media' => $media],
-  ];
-}
-
-/**
- * Implements hook_tokens().
- */
-function media_entity_tokens($type, $tokens, array $data, array $options, BubbleableMetadata $bubbleable_metadata) {
-  $token_service = \Drupal::token();
-
-  $url_options = ['absolute' => TRUE];
-  if (isset($options['langcode'])) {
-    $url_options['language'] = \Drupal::languageManager()->getLanguage($options['langcode']);
-    $langcode = $options['langcode'];
-  }
-  else {
-    $langcode = LanguageInterface::LANGCODE_DEFAULT;
-  }
-  $sanitize = !empty($options['sanitize']);
-
-  $replacements = [];
-
-  if ($type == 'media' && !empty($data['media'])) {
-    /** @var \Drupal\media_entity\MediaInterface $media */
-    $media = \Drupal::service('entity.repository')->getTranslationFromContext($data['media'], $langcode, ['operation' => 'media_entity_tokens']);
-
-    foreach ($tokens as $name => $original) {
-      switch ($name) {
-        // Simple key values on the media_entity.
-        case 'mid':
-          $replacements[$original] = $media->id();
-          break;
-
-        case 'uuid':
-          $replacements[$original] = $media->uuid();
-          break;
-
-        case 'vid':
-          $replacements[$original] = $media->getRevisionId();
-          break;
-
-        case 'bundle':
-          $replacements[$original] = $sanitize ? Html::escape($media->bundle()) : $media->bundle();
-          break;
-
-        case 'bundle-name':
-          $bundle_name = MediaBundle::load($media->bundle())->label();
-          $replacements[$original] = $sanitize ? Html::escape($bundle_name) : $bundle_name;
-          break;
-
-        case 'langcode':
-          $replacements[$original] = $sanitize ? Html::escape($media->language()->getId()) : $media->language()->getId();
-          break;
-
-        case 'name':
-          $media_name = $media->get('name')->value;
-          $replacements[$original] = $sanitize ? Html::escape($media_name) : $media_name;
-          break;
-
-        case 'type':
-          $media_type = $media->get('name')->value;
-          $replacements[$original] = $sanitize ? Html::escape($media_type) : $media_type;
-          break;
-
-        case 'url':
-          $replacements[$original] = $media->toUrl('canonical', $url_options);
-          break;
-
-        case 'edit-url':
-          $replacements[$original] = $media->toUrl('edit-form', $url_options);
-          break;
-
-        // Default values for the chained tokens handled below.
-        case 'author':
-          /** @var \Drupal\user\UserInterface $account */
-          $account = $media->get('uid')->entity;
-          $bubbleable_metadata->addCacheableDependency($account);
-          $replacements[$original] = $sanitize ? Html::escape($account->label()) : $account->label();
-          break;
-
-        case 'created':
-          $date_format = DateFormat::load('medium');
-          $bubbleable_metadata->addCacheableDependency($date_format);
-          $replacements[$original] = \Drupal::service('date.formatter')
-            ->format($media->getCreatedTime(), 'medium', '', NULL, $langcode);
-          break;
-
-        case 'changed':
-          $date_format = DateFormat::load('medium');
-          $bubbleable_metadata->addCacheableDependency($date_format);
-          $replacements[$original] = \Drupal::service('date.formatter')
-            ->format($media->getChangedTime(), 'medium', '', NULL, $langcode);
-          break;
-      }
-    }
-
-    if ($author_tokens = $token_service->findWithPrefix($tokens, 'author')) {
-      $account = $media->get('uid')->entity;
-      $replacements += $token_service->generate('user', $author_tokens, ['user' => $account], $options, $bubbleable_metadata);
-    }
-
-    if ($created_tokens = $token_service->findWithPrefix($tokens, 'created')) {
-      $replacements += $token_service->generate('date', $created_tokens, ['date' => $media->getCreatedTime()], $options, $bubbleable_metadata);
-    }
-
-    if ($changed_tokens = $token_service->findWithPrefix($tokens, 'changed')) {
-      $replacements += $token_service->generate('date', $changed_tokens, ['date' => $media->getChangedTime()], $options, $bubbleable_metadata);
-    }
-  }
-
-  return $replacements;
-}
diff --git a/src/EmbedCodeValueTrait.php b/src/EmbedCodeValueTrait.php
deleted file mode 100644
index b9acaca..0000000
--- a/src/EmbedCodeValueTrait.php
+++ /dev/null
@@ -1,35 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\Core\Field\FieldItemInterface;
-
-/**
- * A trait to assist with handling external embed codes.
- */
-trait EmbedCodeValueTrait {
-
-  /**
-   * Extracts the raw embed code from input which may or may not be wrapped.
-   *
-   * @param mixed $value
-   *   The input value. Can be a normal string or a value wrapped by the
-   *   Typed Data API.
-   *
-   * @return string|null
-   *   The raw embed code.
-   */
-  protected function getEmbedCode($value) {
-    if (is_string($value)) {
-      return $value;
-    }
-    elseif ($value instanceof FieldItemInterface) {
-      $class = get_class($value);
-      $property = $class::mainPropertyName();
-      if ($property) {
-        return $value->$property;
-      }
-    }
-  }
-
-}
diff --git a/src/Entity/Media.php b/src/Entity/Media.php
deleted file mode 100644
index a73200a..0000000
--- a/src/Entity/Media.php
+++ /dev/null
@@ -1,487 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Entity;
-
-use Drupal\Core\Entity\ContentEntityBase;
-use Drupal\Core\Entity\EntityStorageInterface;
-use Drupal\Core\Entity\EntityTypeInterface;
-use Drupal\Core\Field\BaseFieldDefinition;
-use Drupal\media_entity\MediaInterface;
-use Drupal\Core\Entity\EntityChangedTrait;
-use Drupal\user\UserInterface;
-
-/**
- * Defines the media entity class.
- *
- * @ContentEntityType(
- *   id = "media",
- *   label = @Translation("Media"),
- *   bundle_label = @Translation("Media bundle"),
- *   handlers = {
- *     "storage" = "Drupal\media_entity\MediaStorage",
- *     "view_builder" = "Drupal\Core\Entity\EntityViewBuilder",
- *     "list_builder" = "Drupal\Core\Entity\EntityListBuilder",
- *     "access" = "Drupal\media_entity\MediaAccessController",
- *     "form" = {
- *       "default" = "Drupal\media_entity\MediaForm",
- *       "delete" = "Drupal\media_entity\Form\MediaDeleteForm",
- *       "edit" = "Drupal\media_entity\MediaForm"
- *     },
- *     "inline_form" = "Drupal\media_entity\Form\MediaInlineForm",
- *     "translation" = "Drupal\content_translation\ContentTranslationHandler",
- *     "views_data" = "Drupal\media_entity\MediaViewsData",
- *     "route_provider" = {
- *       "html" = "Drupal\Core\Entity\Routing\AdminHtmlRouteProvider",
- *     }
- *   },
- *   base_table = "media",
- *   data_table = "media_field_data",
- *   revision_table = "media_revision",
- *   revision_data_table = "media_field_revision",
- *   translatable = TRUE,
- *   render_cache = TRUE,
- *   entity_keys = {
- *     "id" = "mid",
- *     "revision" = "vid",
- *     "bundle" = "bundle",
- *     "label" = "name",
- *     "langcode" = "langcode",
- *     "uuid" = "uuid"
- *   },
- *   bundle_entity_type = "media_bundle",
- *   permission_granularity = "entity_type",
- *   admin_permission = "administer media",
- *   field_ui_base_route = "entity.media_bundle.edit_form",
- *   links = {
- *     "add-page" = "/media/add",
- *     "add-form" = "/media/add/{media_bundle}",
- *     "canonical" = "/media/{media}",
- *     "delete-form" = "/media/{media}/delete",
- *     "edit-form" = "/media/{media}/edit",
- *     "admin-form" = "/admin/structure/media/manage/{media_bundle}"
- *   }
- * )
- */
-class Media extends ContentEntityBase implements MediaInterface {
-
-  use EntityChangedTrait;
-
-  /**
-   * Value that represents the media being published.
-   */
-  const PUBLISHED = 1;
-
-  /**
-   * Value that represents the media being unpublished.
-   */
-  const NOT_PUBLISHED = 0;
-
-  /**
-   * A queue based media operation to download thumbnails is being performed.
-   *
-   * @var boolean
-   */
-  protected $queued_thumbnail_download = FALSE;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCreatedTime() {
-    return $this->get('created')->value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setCreatedTime($timestamp) {
-    $this->set('created', $timestamp);
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getChangedTime() {
-    return $this->get('changed')->value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function isPublished() {
-    return (bool) $this->get('status')->value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setPublished($published) {
-    $this->set('status', $published ? Media::PUBLISHED : Media::NOT_PUBLISHED);
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPublisher() {
-    return $this->get('uid')->entity;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setQueuedThumbnailDownload() {
-    $this->queued_thumbnail_download = TRUE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPublisherId() {
-    return $this->get('uid')->target_id;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setPublisherId($uid) {
-    $this->set('uid', $uid);
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getType() {
-    return $this->bundle->entity->getType();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function preSave(EntityStorageInterface $storage) {
-    parent::preSave($storage);
-
-    // If no revision author has been set explicitly, make the media owner the
-    // revision author.
-    if (!$this->get('revision_uid')->entity) {
-      $this->set('revision_uid', $this->getPublisherId());
-    }
-
-    // Set thumbnail.
-    if (!$this->get('thumbnail')->entity || !empty($this->queued_thumbnail_download)) {
-      $this->automaticallySetThumbnail();
-    }
-
-    // Try to set fields provided by type plugin and mapped in bundle
-    // configuration.
-    foreach ($this->bundle->entity->field_map as $source_field => $destination_field) {
-      // Only save value in entity field if empty. Do not overwrite existing
-      // data.
-      // @TODO We might modify that in the future but let's leave it like this
-      // for now.
-      if ($this->hasField($destination_field) && $this->{$destination_field}->isEmpty() && ($value = $this->getType()->getField($this, $source_field))) {
-        $this->set($destination_field, $value);
-      }
-    }
-
-    // Try to set a default name for this media, if there is no label provided.
-    if (empty($this->label())) {
-      $this->set('name', $this->getType()->getDefaultName($this));
-    }
-
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function postSave(EntityStorageInterface $storage, $update = TRUE) {
-    parent::postSave($storage, $update);
-    if (!$update && $this->bundle->entity->getQueueThumbnailDownloads()) {
-      $queue = \Drupal::queue('media_entity_thumbnail');
-      $queue->createItem(['id' => $this->id()]);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function automaticallySetThumbnail() {
-    /** @var \Drupal\media_entity\MediaBundleInterface $bundle */
-    if ($this->bundle->entity->getQueueThumbnailDownloads() && $this->isNew()) {
-      $thumbnail_uri = $this->getType()->getDefaultThumbnail();
-    }
-    else {
-      $thumbnail_uri = $this->getType()->thumbnail($this);
-    }
-    $existing = \Drupal::entityQuery('file')
-      ->condition('uri', $thumbnail_uri)
-      ->execute();
-
-    if ($existing) {
-      $this->thumbnail->target_id = reset($existing);
-    }
-    else {
-      /** @var \Drupal\file\FileInterface $file */
-      $file = $this->entityTypeManager()->getStorage('file')->create(['uri' => $thumbnail_uri]);
-      if ($publisher = $this->getPublisher()) {
-        $file->setOwner($publisher);
-      }
-      $file->setPermanent();
-      $file->save();
-      $this->thumbnail->target_id = $file->id();
-    }
-
-    // TODO - We should probably use something smarter (tokens, ...).
-    $this->thumbnail->alt = t('Thumbnail');
-    $this->thumbnail->title = $this->label();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function preSaveRevision(EntityStorageInterface $storage, \stdClass $record) {
-    parent::preSaveRevision($storage, $record);
-
-    if (!$this->isNewRevision() && isset($this->original) && (!isset($record->revision_log) || $record->revision_log === '')) {
-      // If we are updating an existing node without adding a new revision, we
-      // need to make sure $entity->revision_log is reset whenever it is empty.
-      // Therefore, this code allows us to avoid clobbering an existing log
-      // entry with an empty one.
-      $record->revision_log = $this->original->revision_log->value;
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validate() {
-    $this->getType()->attachConstraints($this);
-    return parent::validate();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
-    $fields['mid'] = BaseFieldDefinition::create('integer')
-      ->setLabel(t('Media ID'))
-      ->setDescription(t('The media ID.'))
-      ->setReadOnly(TRUE)
-      ->setSetting('unsigned', TRUE);
-
-    $fields['uuid'] = BaseFieldDefinition::create('uuid')
-      ->setLabel(t('UUID'))
-      ->setDescription(t('The media UUID.'))
-      ->setReadOnly(TRUE);
-
-    $fields['vid'] = BaseFieldDefinition::create('integer')
-      ->setLabel(t('Revision ID'))
-      ->setDescription(t('The media revision ID.'))
-      ->setReadOnly(TRUE)
-      ->setSetting('unsigned', TRUE);
-
-    $fields['bundle'] = BaseFieldDefinition::create('entity_reference')
-      ->setLabel(t('Bundle'))
-      ->setDescription(t('The media bundle.'))
-      ->setSetting('target_type', 'media_bundle')
-      ->setReadOnly(TRUE);
-
-    $fields['langcode'] = BaseFieldDefinition::create('language')
-      ->setLabel(t('Language code'))
-      ->setDescription(t('The media language code.'))
-      ->setTranslatable(TRUE)
-      ->setRevisionable(TRUE)
-      ->setDisplayOptions('view', [
-        'type' => 'hidden',
-      ])
-      ->setDisplayOptions('form', [
-        'type' => 'language_select',
-        'weight' => 2,
-      ]);
-
-    $fields['name'] = BaseFieldDefinition::create('string')
-      ->setLabel(t('Media name'))
-      ->setDescription(t('The name of this media.'))
-      ->setRequired(TRUE)
-      ->setTranslatable(TRUE)
-      ->setRevisionable(TRUE)
-      ->setDefaultValue('')
-      ->setSetting('max_length', 255)
-      ->setDisplayOptions('form', [
-        'type' => 'string_textfield',
-        'weight' => -5,
-      ])
-      ->setDisplayConfigurable('form', TRUE)
-      ->setDisplayOptions('view', [
-        'label' => 'hidden',
-        'type' => 'string',
-        'weight' => -5,
-      ])
-      ->setDisplayConfigurable('view', TRUE);
-
-    $fields['thumbnail'] = BaseFieldDefinition::create('image')
-      ->setLabel(t('Thumbnail'))
-      ->setDescription(t('The thumbnail of the media.'))
-      ->setRevisionable(TRUE)
-      ->setDisplayOptions('view', [
-        'type' => 'image',
-        'weight' => 1,
-        'label' => 'hidden',
-        'settings' => [
-          'image_style' => 'thumbnail',
-        ],
-      ])
-      ->setDisplayConfigurable('view', TRUE)
-      ->setReadOnly(TRUE);
-
-    $fields['uid'] = BaseFieldDefinition::create('entity_reference')
-      ->setLabel(t('Publisher ID'))
-      ->setDescription(t('The user ID of the media publisher.'))
-      ->setRevisionable(TRUE)
-      ->setDefaultValueCallback('Drupal\media_entity\Entity\Media::getCurrentUserId')
-      ->setSetting('target_type', 'user')
-      ->setTranslatable(TRUE)
-      ->setDisplayOptions('view', [
-        'label' => 'hidden',
-        'type' => 'author',
-        'weight' => 0,
-      ])
-      ->setDisplayConfigurable('view', TRUE)
-      ->setDisplayOptions('form', [
-        'type' => 'entity_reference_autocomplete',
-        'weight' => 5,
-        'settings' => [
-          'match_operator' => 'CONTAINS',
-          'size' => '60',
-          'autocomplete_type' => 'tags',
-          'placeholder' => '',
-        ],
-      ])
-      ->setDisplayConfigurable('form', TRUE);
-
-    $fields['status'] = BaseFieldDefinition::create('boolean')
-      ->setLabel(t('Publishing status'))
-      ->setDescription(t('A boolean indicating whether the media is published.'))
-      ->setTranslatable(TRUE)
-      ->setRevisionable(TRUE)
-      ->setDefaultValue(TRUE);
-
-    $fields['created'] = BaseFieldDefinition::create('created')
-      ->setLabel(t('Created'))
-      ->setDescription(t('The time that the media was created.'))
-      ->setTranslatable(TRUE)
-      ->setRevisionable(TRUE)
-      ->setDisplayOptions('view', [
-        'label' => 'hidden',
-        'type' => 'timestamp',
-        'weight' => 0,
-      ])
-      ->setDisplayConfigurable('view', TRUE)
-      ->setDisplayOptions('form', [
-        'type' => 'datetime_timestamp',
-        'weight' => 10,
-      ])
-      ->setDisplayConfigurable('form', TRUE);
-
-    $fields['changed'] = BaseFieldDefinition::create('changed')
-      ->setLabel(t('Changed'))
-      ->setDescription(t('The time that the media was last edited.'))
-      ->setTranslatable(TRUE)
-      ->setRevisionable(TRUE);
-
-    $fields['revision_timestamp'] = BaseFieldDefinition::create('created')
-      ->setLabel(t('Revision timestamp'))
-      ->setDescription(t('The time that the current revision was created.'))
-      ->setQueryable(FALSE)
-      ->setRevisionable(TRUE);
-
-    $fields['revision_uid'] = BaseFieldDefinition::create('entity_reference')
-      ->setLabel(t('Revision publisher ID'))
-      ->setDescription(t('The user ID of the publisher of the current revision.'))
-      ->setSetting('target_type', 'user')
-      ->setQueryable(FALSE)
-      ->setRevisionable(TRUE);
-
-    $fields['revision_log'] = BaseFieldDefinition::create('string_long')
-      ->setLabel(t('Revision Log'))
-      ->setDescription(t('The log entry explaining the changes in this revision.'))
-      ->setRevisionable(TRUE)
-      ->setTranslatable(TRUE);
-
-    return $fields;
-  }
-
-  /**
-   * Default value callback for 'uid' base field definition.
-   *
-   * @see ::baseFieldDefinitions()
-   *
-   * @return array
-   *   An array of default values.
-   */
-  public static function getCurrentUserId() {
-    return [\Drupal::currentUser()->id()];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRevisionCreationTime() {
-    return $this->revision_timestamp->value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setRevisionCreationTime($timestamp) {
-    $this->revision_timestamp->value = $timestamp;
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRevisionUser() {
-    return $this->revision_uid->entity;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setRevisionUser(UserInterface $account) {
-    $this->revision_uid->entity = $account;
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRevisionUserId() {
-    return $this->revision_user->target_id;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setRevisionUserId($user_id) {
-    $this->revision_user->target_id = $user_id;
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getRevisionLogMessage() {
-    return $this->revision_log->value;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setRevisionLogMessage($revision_log_message) {
-    $this->revision_log->value = $revision_log_message;
-    return $this;
-  }
-
-}
diff --git a/src/Entity/MediaBundle.php b/src/Entity/MediaBundle.php
deleted file mode 100644
index 8833f82..0000000
--- a/src/Entity/MediaBundle.php
+++ /dev/null
@@ -1,244 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Entity;
-
-use Drupal\Core\Entity\EntityDescriptionInterface;
-use Drupal\Core\Config\Entity\ConfigEntityBundleBase;
-use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
-use Drupal\Core\Plugin\DefaultSingleLazyPluginCollection;
-use Drupal\media_entity\MediaBundleInterface;
-use Drupal\media_entity\MediaInterface;
-
-/**
- * Defines the Media bundle configuration entity.
- *
- * @ConfigEntityType(
- *   id = "media_bundle",
- *   label = @Translation("Media bundle"),
- *   handlers = {
- *     "form" = {
- *       "add" = "Drupal\media_entity\MediaBundleForm",
- *       "edit" = "Drupal\media_entity\MediaBundleForm",
- *       "delete" = "Drupal\media_entity\Form\MediaBundleDeleteConfirm"
- *     },
- *     "list_builder" = "Drupal\media_entity\MediaBundleListBuilder",
- *     "route_provider" = {
- *       "html" = "Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider",
- *     }
- *   },
- *   admin_permission = "administer media bundles",
- *   config_prefix = "bundle",
- *   bundle_of = "media",
- *   entity_keys = {
- *     "id" = "id",
- *     "label" = "label"
- *   },
- *   config_export = {
- *     "id",
- *     "label",
- *     "description",
- *     "type",
- *     "queue_thumbnail_downloads",
- *     "new_revision",
- *     "third_party_settings",
- *     "type_configuration",
- *     "field_map",
- *     "status",
- *   },
- *   links = {
- *     "add-form" = "/admin/structure/media/add",
- *     "edit-form" = "/admin/structure/media/manage/{media_bundle}",
- *     "delete-form" = "/admin/structure/media/manage/{media_bundle}/delete",
- *     "collection" = "/admin/structure/media",
- *   }
- * )
- */
-class MediaBundle extends ConfigEntityBundleBase implements MediaBundleInterface, EntityWithPluginCollectionInterface, EntityDescriptionInterface {
-
-  /**
-   * The machine name of this media bundle.
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * The human-readable name of the media bundle.
-   *
-   * @var string
-   */
-  public $label;
-
-  /**
-   * A brief description of this media bundle.
-   *
-   * @var string
-   */
-  public $description;
-
-  /**
-   * The type plugin id.
-   *
-   * @var string
-   */
-  public $type = 'generic';
-
-  /**
-   * Are thumbnail downloads queued.
-   *
-   * @var bool
-   */
-  public $queue_thumbnail_downloads = FALSE;
-
-  /**
-   * Default value of the 'Create new revision' checkbox of this media bundle.
-   *
-   * @var bool
-   */
-  protected $new_revision = FALSE;
-
-  /**
-   * The type plugin configuration.
-   *
-   * @var array
-   */
-  public $type_configuration = [];
-
-  /**
-   * Type lazy plugin collection.
-   *
-   * @var \Drupal\Core\Plugin\DefaultSingleLazyPluginCollection
-   */
-  protected $typePluginCollection;
-
-  /**
-   * Field map. Fields provided by type plugin to be stored as entity fields.
-   *
-   * @var array
-   */
-  public $field_map = [];
-
-  /**
-   * Default status of this media bundle.
-   *
-   * @var array
-   */
-  public $status = TRUE;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function id() {
-    return $this->id;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getPluginCollections() {
-    return [
-      'type_configuration' => $this->typePluginCollection(),
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function getLabel(MediaInterface $media) {
-    $bundle = static::load($media->bundle());
-    return $bundle ? $bundle->label() : FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function exists($id) {
-    return (bool) static::load($id);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDescription() {
-    return $this->description;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setDescription($description) {
-    $this->description = $description;
-    return $this;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTypeConfiguration() {
-    return $this->type_configuration;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setTypeConfiguration($configuration) {
-    $this->type_configuration = $configuration;
-    $this->typePluginCollection = NULL;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getQueueThumbnailDownloads() {
-    return $this->queue_thumbnail_downloads;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setQueueThumbnailDownloads($queue_thumbnail_downloads) {
-    $this->queue_thumbnail_downloads = $queue_thumbnail_downloads;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getType() {
-    return $this->typePluginCollection()->get($this->type);
-  }
-
-  /**
-   * Returns type lazy plugin collection.
-   *
-   * @return \Drupal\Core\Plugin\DefaultSingleLazyPluginCollection
-   *   The tag plugin collection.
-   */
-  protected function typePluginCollection() {
-    if (!$this->typePluginCollection) {
-      $this->typePluginCollection = new DefaultSingleLazyPluginCollection(\Drupal::service('plugin.manager.media_entity.type'), $this->type, $this->type_configuration);
-    }
-    return $this->typePluginCollection;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getStatus() {
-    return $this->status;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function shouldCreateNewRevision() {
-    return $this->new_revision;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setNewRevision($new_revision) {
-    $this->new_revision = $new_revision;
-  }
-
-}
diff --git a/src/Form/DeleteMultiple.php b/src/Form/DeleteMultiple.php
deleted file mode 100644
index 2a9cc40..0000000
--- a/src/Form/DeleteMultiple.php
+++ /dev/null
@@ -1,199 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Form;
-
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\Form\ConfirmFormBase;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Url;
-use Drupal\user\PrivateTempStoreFactory;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpFoundation\RedirectResponse;
-
-/**
- * Provides a media deletion confirmation form.
- */
-class DeleteMultiple extends ConfirmFormBase {
-
-  /**
-   * The array of media entities to delete.
-   *
-   * @var string[][]
-   */
-  protected $entityInfo = [];
-
-  /**
-   * The tempstore factory.
-   *
-   * @var \Drupal\user\PrivateTempStoreFactory
-   */
-  protected $tempStoreFactory;
-
-  /**
-   * The entity storage.
-   *
-   * @var \Drupal\Core\Entity\EntityStorageInterface
-   */
-  protected $storage;
-
-  /**
-   * Constructs a DeleteMultiple form object.
-   *
-   * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
-   *   The tempstore factory.
-   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $manager
-   *   The entity manager.
-   */
-  public function __construct(PrivateTempStoreFactory $temp_store_factory, EntityTypeManagerInterface $manager) {
-    $this->tempStoreFactory = $temp_store_factory;
-    $this->storage = $manager->getStorage('media');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('user.private_tempstore'),
-      $container->get('entity_type.manager')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getFormId() {
-    return 'media_multiple_delete_confirm';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getQuestion() {
-    return $this->formatPlural(count($this->entityInfo), 'Are you sure you want to delete this item?', 'Are you sure you want to delete these items?');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCancelUrl() {
-    return new Url('system.admin_content');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getConfirmText() {
-    return $this->t('Delete');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state) {
-    $this->entityInfo = $this->tempStoreFactory->get('media_multiple_delete_confirm')->get(\Drupal::currentUser()->id());
-    if (empty($this->entityInfo)) {
-      return new RedirectResponse($this->getCancelUrl()->setAbsolute()->toString());
-    }
-    /** @var \Drupal\media_entity\MediaInterface[] $entities */
-    $entities = $this->storage->loadMultiple(array_keys($this->entityInfo));
-
-    $items = [];
-    foreach ($this->entityInfo as $id => $langcodes) {
-      foreach ($langcodes as $langcode) {
-        $entity = $entities[$id]->getTranslation($langcode);
-        $key = $id . ':' . $langcode;
-        $default_key = $id . ':' . $entity->getUntranslated()->language()->getId();
-
-        // If we have a translated entity we build a nested list of translations
-        // that will be deleted.
-        $languages = $entity->getTranslationLanguages();
-        if (count($languages) > 1 && $entity->isDefaultTranslation()) {
-          $names = [];
-          foreach ($languages as $translation_langcode => $language) {
-            $names[] = $language->getName();
-            unset($items[$id . ':' . $translation_langcode]);
-          }
-          $items[$default_key] = [
-            'label' => [
-              '#markup' => $this->t('@label (Original translation) - <em>The following media translations will be deleted:</em>', ['@label' => $entity->label()]),
-            ],
-            'deleted_translations' => [
-              '#theme' => 'item_list',
-              '#items' => $names,
-            ],
-          ];
-        }
-        elseif (!isset($items[$default_key])) {
-          $items[$key] = $entity->label();
-        }
-      }
-    }
-
-    $form['entities'] = [
-      '#theme' => 'item_list',
-      '#items' => $items,
-    ];
-    $form = parent::buildForm($form, $form_state);
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    if ($form_state->getValue('confirm') && !empty($this->entityInfo)) {
-      $total_count = 0;
-      $delete_entities = [];
-      /** @var \Drupal\Core\Entity\ContentEntityInterface[][] $delete_translations */
-      $delete_translations = [];
-      /** @var \Drupal\media_entity\MediaInterface[] $entities */
-      $entities = $this->storage->loadMultiple(array_keys($this->entityInfo));
-
-      foreach ($this->entityInfo as $id => $langcodes) {
-        foreach ($langcodes as $langcode) {
-          $entity = $entities[$id]->getTranslation($langcode);
-          if ($entity->isDefaultTranslation()) {
-            $delete_entities[$id] = $entity;
-            unset($delete_translations[$id]);
-            $total_count += count($entity->getTranslationLanguages());
-          }
-          elseif (!isset($delete_entities[$id])) {
-            $delete_translations[$id][] = $entity;
-          }
-        }
-      }
-
-      if ($delete_entities) {
-        $this->storage->delete($delete_entities);
-        $this->logger('media_entity')->notice('Deleted @count media entities.', ['@count' => count($delete_entities)]);
-      }
-
-      if ($delete_translations) {
-        $count = 0;
-        foreach ($delete_translations as $id => $translations) {
-          $entity = $entities[$id]->getUntranslated();
-          foreach ($translations as $translation) {
-            $entity->removeTranslation($translation->language()->getId());
-          }
-          $entity->save();
-          $count += count($translations);
-        }
-        if ($count) {
-          $total_count += $count;
-          $this->logger('media_entity')->notice('Deleted @count media translations.', ['@count' => $count]);
-        }
-      }
-
-      if ($total_count) {
-        drupal_set_message($this->formatPlural($total_count, 'Deleted 1 media entity.', 'Deleted @count media entities.'));
-      }
-
-      $this->tempStoreFactory->get('media_multiple_delete_confirm')->delete(\Drupal::currentUser()->id());
-    }
-
-    $form_state->setRedirect('system.admin_content');
-  }
-
-}
diff --git a/src/Form/MediaBundleDeleteConfirm.php b/src/Form/MediaBundleDeleteConfirm.php
deleted file mode 100644
index f860eb4..0000000
--- a/src/Form/MediaBundleDeleteConfirm.php
+++ /dev/null
@@ -1,59 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Form;
-
-use Drupal\Core\Entity\Query\QueryFactory;
-use Drupal\Core\Entity\EntityDeleteForm;
-use Drupal\Core\Form\FormStateInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Provides a form for media bundle deletion.
- */
-class MediaBundleDeleteConfirm extends EntityDeleteForm {
-
-  /**
-   * The query factory to create entity queries.
-   *
-   * @var \Drupal\Core\Entity\Query\QueryFactory
-   */
-  protected $queryFactory;
-
-  /**
-   * Constructs a new MediaBundleDeleteConfirm object.
-   *
-   * @param \Drupal\Core\Entity\Query\QueryFactory $query_factory
-   *   The entity query object.
-   */
-  public function __construct(QueryFactory $query_factory) {
-    $this->queryFactory = $query_factory;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('entity.query')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildForm(array $form, FormStateInterface $form_state) {
-    $num_entities = $this->queryFactory->get('media')
-      ->condition('bundle', $this->entity->id())
-      ->count()
-      ->execute();
-    if ($num_entities) {
-      $caption = '<p>' . $this->formatPlural($num_entities, '%type is used by 1 piece of content on your site. You can not remove this content type until you have removed all of the %type content.', '%type is used by @count pieces of content on your site. You may not remove %type until you have removed all of the %type content.', ['%type' => $this->entity->label()]) . '</p>';
-      $form['#title'] = $this->getQuestion();
-      $form['description'] = ['#markup' => $caption];
-      return $form;
-    }
-
-    return parent::buildForm($form, $form_state);
-  }
-
-}
diff --git a/src/Form/MediaDeleteForm.php b/src/Form/MediaDeleteForm.php
deleted file mode 100644
index d84e34a..0000000
--- a/src/Form/MediaDeleteForm.php
+++ /dev/null
@@ -1,20 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Form;
-
-use Drupal\Core\Entity\ContentEntityDeleteForm;
-use Drupal\Core\Url;
-
-/**
- * Provides a form for deleting a media.
- */
-class MediaDeleteForm extends ContentEntityDeleteForm {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getCancelUrl() {
-    return Url::fromUri('internal:/');
-  }
-
-}
diff --git a/src/Form/MediaInlineForm.php b/src/Form/MediaInlineForm.php
deleted file mode 100644
index 020414f..0000000
--- a/src/Form/MediaInlineForm.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Form;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\inline_entity_form\Form\EntityInlineForm;
-
-/**
- * Media inline form handler.
- */
-class MediaInlineForm extends EntityInlineForm {
-
-  use StringTranslationTrait;
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getTableFields($bundles) {
-    $fields = parent::getTableFields($bundles);
-
-    unset($fields['name']);
-
-    $fields['thumbnail'] = [
-      'type' => 'field',
-      'label' => $this->t('Thumbnail'),
-      'weight' => 1,
-      'display_options' => [
-        'type' => 'image',
-        'settings' => [
-          'image_style' => 'thumbnail',
-        ],
-      ],
-    ];
-
-    return $fields;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function entityFormSubmit(array &$entity_form, FormStateInterface $form_state) {
-    parent::entityFormSubmit($entity_form, $form_state);
-
-    /** @var \Drupal\media_entity\MediaInterface $entity */
-    $entity = $entity_form['#entity'];
-
-    // Make sure media thumbnail is set correctly.
-    $entity->automaticallySetThumbnail();
-
-    if ($entity_form['#save_entity']) {
-      $entity->save();
-    }
-  }
-
-}
diff --git a/src/Media.php b/src/Media.php
new file mode 100644
index 0000000..d674749
--- /dev/null
+++ b/src/Media.php
@@ -0,0 +1,113 @@
+<?php
+
+namespace Drupal\media_entity;
+
+use Drupal\Core\Entity\EditorialContentEntityBase;
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
+
+final class Media extends EditorialContentEntityBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
+    $fields = parent::baseFieldDefinitions($entity_type);
+
+    $fields['name'] = BaseFieldDefinition::create('string')
+      ->setLabel(t('Name'))
+      ->setRequired(TRUE)
+      ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE)
+      ->setDefaultValue('')
+      ->setSetting('max_length', 255)
+      ->setDisplayOptions('form', [
+        'type' => 'string_textfield',
+        'weight' => -5,
+      ])
+      ->setDisplayConfigurable('form', TRUE)
+      ->setDisplayOptions('view', [
+        'label' => 'hidden',
+        'type' => 'string',
+        'weight' => -5,
+      ]);
+
+    $fields['thumbnail'] = BaseFieldDefinition::create('image')
+      ->setLabel(t('Thumbnail'))
+      ->setDescription(t('The thumbnail of the media item.'))
+      ->setRevisionable(TRUE)
+      ->setTranslatable(TRUE)
+      ->setDisplayOptions('view', [
+        'type' => 'image',
+        'weight' => 5,
+        'label' => 'hidden',
+        'settings' => [
+          'image_style' => 'thumbnail',
+        ],
+      ])
+      ->setDisplayConfigurable('view', TRUE)
+      ->setReadOnly(TRUE);
+
+    $fields['uid'] = BaseFieldDefinition::create('entity_reference')
+      ->setLabel(t('Authored by'))
+      ->setDescription(t('The user ID of the author.'))
+      ->setRevisionable(TRUE)
+      ->setDefaultValueCallback(static::class . '::getCurrentUserId')
+      ->setSetting('target_type', 'user')
+      ->setTranslatable(TRUE)
+      ->setDisplayOptions('form', [
+        'type' => 'entity_reference_autocomplete',
+        'weight' => 5,
+        'settings' => [
+          'match_operator' => 'CONTAINS',
+          'size' => '60',
+          'autocomplete_type' => 'tags',
+          'placeholder' => '',
+        ],
+      ])
+      ->setDisplayConfigurable('form', TRUE)
+      ->setDisplayOptions('view', [
+        'label' => 'hidden',
+        'type' => 'author',
+        'weight' => 0,
+      ])
+      ->setDisplayConfigurable('view', TRUE);
+
+    $fields['status']
+      ->setDisplayOptions('form', [
+        'type' => 'boolean_checkbox',
+        'settings' => [
+          'display_label' => TRUE,
+        ],
+        'weight' => 100,
+      ])
+      ->setDisplayConfigurable('form', TRUE);
+
+    $fields['created'] = BaseFieldDefinition::create('created')
+      ->setLabel(t('Authored on'))
+      ->setDescription(t('The time the media item was created.'))
+      ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE)
+      ->setDefaultValueCallback(static::class . '::getRequestTime')
+      ->setDisplayOptions('form', [
+        'type' => 'datetime_timestamp',
+        'weight' => 10,
+      ])
+      ->setDisplayConfigurable('form', TRUE)
+      ->setDisplayOptions('view', [
+        'label' => 'hidden',
+        'type' => 'timestamp',
+        'weight' => 0,
+      ])
+      ->setDisplayConfigurable('view', TRUE);
+
+    $fields['changed'] = BaseFieldDefinition::create('changed')
+      ->setLabel(t('Changed'))
+      ->setDescription(t('The time the media item was last edited.'))
+      ->setTranslatable(TRUE)
+      ->setRevisionable(TRUE);
+
+    return $fields;
+  }
+
+}
diff --git a/src/MediaAccessController.php b/src/MediaAccessController.php
deleted file mode 100644
index 5b09787..0000000
--- a/src/MediaAccessController.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\Core\Access\AccessResult;
-use Drupal\Core\Entity\EntityAccessControlHandler;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Session\AccountInterface;
-
-/**
- * Defines an access controller for the media entity.
- */
-class MediaAccessController extends EntityAccessControlHandler {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) {
-    if ($account->hasPermission('administer media')) {
-      return AccessResult::allowed()->cachePerPermissions();
-    }
-
-    $is_owner = ($account->id() && $account->id() == $entity->getPublisherId()) ? TRUE : FALSE;
-    switch ($operation) {
-      case 'view':
-        return AccessResult::allowedIf($account->hasPermission('view media') && $entity->status->value);
-
-      case 'update':
-        return AccessResult::allowedIf(($account->hasPermission('update media') && $is_owner) || $account->hasPermission('update any media'))->cachePerPermissions()->cachePerUser()->addCacheableDependency($entity);
-
-      case 'delete':
-        return AccessResult::allowedIf(($account->hasPermission('delete media') && $is_owner) ||  $account->hasPermission('delete any media'))->cachePerPermissions()->cachePerUser()->addCacheableDependency($entity);
-    }
-
-    // No opinion.
-    return AccessResult::neutral()->cachePerPermissions();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) {
-    return AccessResult::allowedIfHasPermission($account, 'create media');
-  }
-
-}
diff --git a/src/MediaBundle.php b/src/MediaBundle.php
new file mode 100644
index 0000000..a2d11f6
--- /dev/null
+++ b/src/MediaBundle.php
@@ -0,0 +1,8 @@
+<?php
+
+namespace Drupal\media_entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+
+final class MediaBundle extends ConfigEntityBase {
+}
diff --git a/src/MediaBundleForm.php b/src/MediaBundleForm.php
deleted file mode 100644
index 014a538..0000000
--- a/src/MediaBundleForm.php
+++ /dev/null
@@ -1,385 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\Core\Ajax\AjaxResponse;
-use Drupal\Core\Ajax\ReplaceCommand;
-use Drupal\Core\Entity\EntityFieldManagerInterface;
-use Drupal\Core\Entity\EntityForm;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\language\Entity\ContentLanguageSettings;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Form controller for node type forms.
- */
-class MediaBundleForm extends EntityForm {
-
-  /**
-   * The instantiated plugin instances that have configuration forms.
-   *
-   * @var \Drupal\Core\Plugin\PluginFormInterface[]
-   */
-  protected $configurableInstances = [];
-
-  /**
-   * Manager for media entity type plugins.
-   *
-   * @var \Drupal\media_entity\MediaTypeManager
-   */
-  protected $mediaTypeManager;
-
-  /**
-   * Entity field manager service.
-   *
-   * @var \Drupal\Core\Entity\EntityFieldManagerInterface
-   */
-  protected $entityFieldManager;
-
-  /**
-   * Constructs a new class instance.
-   *
-   * @param \Drupal\media_entity\MediaTypeManager $media_type_manager
-   *   Media type manager.
-   */
-  public function __construct(MediaTypeManager $media_type_manager, EntityFieldManagerInterface $entity_field_manager) {
-    $this->mediaTypeManager = $media_type_manager;
-    $this->entityFieldManager = $entity_field_manager;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container) {
-    return new static(
-      $container->get('plugin.manager.media_entity.type'),
-      $container->get('entity_field.manager')
-    );
-  }
-
-  /**
-   * Ajax callback triggered by the type provider select element.
-   *
-   * @param array $form
-   *   The form array.
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   Current form state.
-   *
-   * @return \Drupal\Core\Ajax\AjaxResponse
-   *   The ajax response.
-   */
-  public function ajaxTypeProviderData(array $form, FormStateInterface $form_state) {
-    $response = new AjaxResponse();
-    $plugin = $this->entity->getType()->getPluginId();
-
-    $response->addCommand(new ReplaceCommand('#edit-type-configuration-plugin-wrapper', $form['type_configuration'][$plugin]));
-    $response->addCommand(new ReplaceCommand('#field-mapping-wrapper', $form['field_mapping']));
-
-    return $response;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function form(array $form, FormStateInterface $form_state) {
-    $form = parent::form($form, $form_state);
-
-    /** @var \Drupal\media_entity\MediaBundleInterface $bundle */
-    $form['#entity'] = $bundle = $this->entity;
-    $form_state->set('bundle', $bundle->id());
-
-    if ($this->operation == 'add') {
-      $form['#title'] = $this->t('Add media bundle');
-    }
-    elseif ($this->operation == 'edit') {
-      $form['#title'] = $this->t('Edit %label media bundle', ['%label' => $bundle->label()]);
-    }
-
-    $form['label'] = [
-      '#title' => $this->t('Label'),
-      '#type' => 'textfield',
-      '#default_value' => $bundle->label(),
-      '#description' => $this->t('The human-readable name of this media bundle.'),
-      '#required' => TRUE,
-      '#size' => 30,
-      '#weight' => -100,
-    ];
-
-    // @todo: '#disabled' not always FALSE.
-    $form['id'] = [
-      '#type' => 'machine_name',
-      '#default_value' => $bundle->id(),
-      '#maxlength' => 32,
-      '#disabled' => !$bundle->isNew(),
-      '#machine_name' => [
-        'exists' => ['\Drupal\media_entity\Entity\MediaBundle', 'exists'],
-        'source' => ['label'],
-      ],
-      '#description' => $this->t('A unique machine-readable name for this media bundle.'),
-      '#weight' => -90,
-    ];
-
-    $form['description'] = [
-      '#title' => $this->t('Description'),
-      '#type' => 'textarea',
-      '#default_value' => $bundle->getDescription(),
-      '#description' => $this->t('Describe this media bundle. The text will be displayed on the <em>Add new media</em> page.'),
-      '#weight' => -80,
-    ];
-
-    $plugins = $this->mediaTypeManager->getDefinitions();
-    $options = [];
-    foreach ($plugins as $plugin => $definition) {
-      $options[$plugin] = $definition['label'];
-    }
-
-    $form['type'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Type provider'),
-      '#default_value' => $bundle->getType()->getPluginId(),
-      '#options' => $options,
-      '#description' => $this->t('Media type provider plugin that is responsible for additional logic related to this media.'),
-      '#weight' => -70,
-      '#ajax' => [
-        'callback' => '::ajaxTypeProviderData',
-        'progress' => [
-          'type' => 'throbber',
-          'message' => $this->t('Updating type provider configuration form.'),
-        ],
-      ],
-    ];
-
-    // Media type plugin configuration.
-    $form['type_configuration'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Type provider configuration'),
-      '#tree' => TRUE,
-      '#weight' => -60,
-    ];
-
-    /** @var \Drupal\media_entity\MediaTypeInterface $plugin */
-    if ($plugin = $bundle->getType()) {
-      $plugin_configuration = (empty($this->configurableInstances[$plugin->getPluginId()]['plugin_config'])) ? $bundle->type_configuration : $this->configurableInstances[$plugin->getPluginId()]['plugin_config'];
-      /** @var \Drupal\media_entity\MediaTypeBase $instance */
-      $instance = $this->mediaTypeManager->createInstance($plugin->getPluginId(), $plugin_configuration);
-      // Store the configuration for validate and submit handlers.
-      $this->configurableInstances[$plugin->getPluginId()]['plugin_config'] = $plugin_configuration;
-
-      $form['type_configuration'][$plugin->getPluginId()] = [
-        '#type' => 'container',
-        '#attributes' => [
-          'id' => 'edit-type-configuration-plugin-wrapper',
-        ],
-      ];
-      $form['type_configuration'][$plugin->getPluginId()] += $instance->buildConfigurationForm([], $form_state);
-    }
-
-    // Field mapping configuration.
-    $form['field_mapping'] = [
-      '#type' => 'fieldset',
-      '#title' => $this->t('Field mapping'),
-      '#tree' => TRUE,
-      '#attributes' => ['id' => 'field-mapping-wrapper'],
-      'description' => [
-        '#type' => 'html_tag',
-        '#tag' => 'p',
-        '#value' => $this->t('Media type plugins can provide metadata fields such as title, caption, size information, credits, ... Media entity can automatically save this metadata information to entity fields, which can be configured below. Information will only be mapped if the entity field is empty.'),
-      ],
-      '#weight' => -50,
-    ];
-
-    if (empty($plugin) || empty($plugin->providedFields())) {
-      $form['field_mapping']['empty_message'] = [
-        '#prefix' => '<em>',
-        '#suffix' => '</em>',
-        '#markup' => $this->t('No metadata fields available.'),
-      ];
-    }
-    else {
-      $skipped_fields = [
-        'mid',
-        'uuid',
-        'vid',
-        'bundle',
-        'langcode',
-        'default_langcode',
-        'uid',
-        'revision_timestamp',
-        'revision_log',
-        'revision_uid',
-      ];
-      $options = ['_none' => $this->t('- Skip field -')];
-      foreach ($this->entityFieldManager->getFieldDefinitions('media', $bundle->id()) as $field_name => $field) {
-        if (!in_array($field_name, $skipped_fields)) {
-          $options[$field_name] = $field->getLabel();
-        }
-      }
-
-      foreach ($plugin->providedFields() as $field_name => $field_label) {
-        $form['field_mapping'][$field_name] = [
-          '#type' => 'select',
-          '#title' => $field_label,
-          '#options' => $options,
-          '#default_value' => isset($bundle->field_map[$field_name]) ? $bundle->field_map[$field_name] : '_none',
-        ];
-      }
-    }
-
-    $form['additional_settings'] = [
-      '#type' => 'vertical_tabs',
-      '#attached' => [
-        'library' => ['media_entity/media_bundle_form'],
-      ],
-      '#weight' => 100,
-    ];
-
-    $form['workflow'] = [
-      '#type' => 'details',
-      '#title' => $this->t('Publishing options'),
-      '#group' => 'additional_settings',
-    ];
-
-    $workflow_options = [
-      'status' => $bundle->getStatus(),
-      'new_revision' => $bundle->shouldCreateNewRevision(),
-      'queue_thumbnail_downloads' => $bundle->getQueueThumbnailDownloads(),
-    ];
-    // Prepare workflow options to be used for 'checkboxes' form element.
-    $keys = array_keys(array_filter($workflow_options));
-    $workflow_options = array_combine($keys, $keys);
-    $form['workflow']['options'] = [
-      '#type' => 'checkboxes',
-      '#title' => $this->t('Default options'),
-      '#default_value' => $workflow_options,
-      '#options' => [
-        'status' => $this->t('Published'),
-        'new_revision' => $this->t('Create new revision'),
-        'queue_thumbnail_downloads' => $this->t('Queue thumbnail downloads'),
-      ],
-    ];
-
-    $form['workflow']['options']['status']['#description'] = $this->t('Entities will be automatically published when they are created.');
-    $form['workflow']['options']['new_revision']['#description'] = $this->t('Automatically create a new revision of media entities. Users with the Administer media permission will be able to override this option.');
-    $form['workflow']['options']['queue_thumbnail_downloads']['#description'] = $this->t('Download thumbnails via a queue.');
-
-    if ($this->moduleHandler->moduleExists('language')) {
-      $form['language'] = [
-        '#type' => 'details',
-        '#title' => $this->t('Language settings'),
-        '#group' => 'additional_settings',
-      ];
-
-      $language_configuration = ContentLanguageSettings::loadByEntityTypeBundle('media', $bundle->id());
-
-      $form['language']['language_configuration'] = [
-        '#type' => 'language_configuration',
-        '#entity_information' => [
-          'entity_type' => 'media',
-          'bundle' => $bundle->id(),
-        ],
-        '#default_value' => $language_configuration,
-      ];
-    }
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateForm(array &$form, FormStateInterface $form_state) {
-    parent::validateForm($form, $form_state);
-
-    // Let the selected plugin validate its settings.
-    $plugin = $this->entity->getType()->getPluginId();
-    $plugin_configuration = !empty($this->configurableInstances[$plugin]['plugin_config']) ? $this->configurableInstances[$plugin]['plugin_config'] : [];
-    $instance = $this->mediaTypeManager->createInstance($plugin, $plugin_configuration);
-    $instance->validateConfigurationForm($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitForm(array &$form, FormStateInterface $form_state) {
-    parent::submitForm($form, $form_state);
-
-    $workflow_options = ['status', 'queue_thumbnail_downloads'];
-    foreach ($workflow_options as $option) {
-      $this->entity->$option = (bool) $form_state->getValue(['options', $option]);
-    }
-
-    $this->entity->setNewRevision((bool) $form_state->getValue(['options', 'new_revision']));
-
-    // Let the selected plugin save its settings.
-    $plugin = $this->entity->getType()->getPluginId();
-    $plugin_configuration = !empty($this->configurableInstances[$plugin]['plugin_config']) ? $this->configurableInstances[$plugin]['plugin_config'] : [];
-    $instance = $this->mediaTypeManager->createInstance($plugin, $plugin_configuration);
-    $instance->submitConfigurationForm($form, $form_state);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function actions(array $form, FormStateInterface $form_state) {
-    $actions = parent::actions($form, $form_state);
-    $actions['submit']['#value'] = $this->t('Save media bundle');
-    $actions['delete']['#value'] = $this->t('Delete media bundle');
-    $actions['delete']['#access'] = $this->entity->access('delete');
-    return $actions;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
-    $configuration = $form_state->getValue('type_configuration');
-
-    // Store previous plugin config.
-    $plugin = $entity->getType()->getPluginId();
-    $this->configurableInstances[$plugin]['plugin_config'] = empty($configuration[$plugin]) ? [] : $configuration[$plugin];
-
-    /** @var \Drupal\media_entity\MediaBundleInterface $entity */
-    parent::copyFormValuesToEntity($entity, $form, $form_state);
-
-    // Use type configuration for the plugin that was chosen.
-    $plugin = $entity->getType()->getPluginId();
-    $plugin_configuration = empty($configuration[$plugin]) ? [] : $configuration[$plugin];
-    $entity->set('type_configuration', $plugin_configuration);
-
-    // Save field mapping.
-    $entity->field_map = array_filter(
-      $form_state->getValue('field_mapping', []),
-      function ($item) { return $item != '_none'; }
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function save(array $form, FormStateInterface $form_state) {
-    /** @var \Drupal\media_entity\MediaBundleInterface $bundle */
-    $bundle = $this->entity;
-    $status = $bundle->save();
-
-    $t_args = ['%name' => $bundle->label()];
-    if ($status == SAVED_UPDATED) {
-      drupal_set_message($this->t('The media bundle %name has been updated.', $t_args));
-    }
-    elseif ($status == SAVED_NEW) {
-      drupal_set_message($this->t('The media bundle %name has been added.', $t_args));
-      $this->logger('media')->notice('Added bundle %name.', $t_args);
-    }
-
-    // Override the "status" base field default value, for this bundle.
-    $fields = $this->entityFieldManager->getFieldDefinitions('media', $bundle->id());
-    $media = $this->entityTypeManager->getStorage('media')->create(array('bundle' => $bundle->id()));
-    $value = (bool) $form_state->getValue(['options', 'status']);
-    if ($media->status->value != $value) {
-      $fields['status']->getConfig($bundle->id())->setDefaultValue($value)->save();
-    }
-
-    $form_state->setRedirectUrl($bundle->toUrl('collection'));
-  }
-
-}
diff --git a/src/MediaBundleInterface.php b/src/MediaBundleInterface.php
deleted file mode 100644
index 97e02f9..0000000
--- a/src/MediaBundleInterface.php
+++ /dev/null
@@ -1,99 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\Core\Config\Entity\ConfigEntityInterface;
-use Drupal\entity\Entity\RevisionableEntityBundleInterface;
-
-/**
- * Provides an interface defining a media bundle entity.
- */
-interface MediaBundleInterface extends ConfigEntityInterface, RevisionableEntityBundleInterface {
-
-  /**
-   * Returns the label.
-   *
-   * @param \Drupal\media_entity\MediaInterface $media
-   *   The Media entity.
-   *
-   * @return string|bool
-   *   Returns the label of the bundle that entity belongs to.
-   */
-  public static function getLabel(MediaInterface $media);
-
-  /**
-   * Checks if the bundle exists.
-   *
-   * @param int $id
-   *   The Media bundle ID.
-   *
-   * @return bool
-   *   TRUE if the bundle with the given ID exists, FALSE otherwise.
-   */
-  public static function exists($id);
-
-  /**
-   * Returns whether thumbnail downloads are queued.
-   *
-   * @return bool
-   *   Returns download now or later.
-   */
-  public function getQueueThumbnailDownloads();
-
-  /**
-   * Sets a flag to indicate that thumbnails should be downloaded via a queue.
-   *
-   * @param bool $queue_thumbnail_downloads
-   *   The queue downloads flag.
-   */
-  public function setQueueThumbnailDownloads($queue_thumbnail_downloads);
-
-  /**
-   * Returns the Media bundle description.
-   *
-   * @return string
-   *   Returns the Media bundle description.
-   */
-  public function getDescription();
-
-  /**
-   * Returns the media type plugin.
-   *
-   * @return \Drupal\media_entity\MediaTypeInterface
-   *   The type.
-   */
-  public function getType();
-
-  /**
-   * Returns the media type configuration.
-   *
-   * @return array
-   *   The type configuration.
-   */
-  public function getTypeConfiguration();
-
-  /**
-   * Sets the media type configuration.
-   *
-   * @param array $configuration
-   *   The type configuration.
-   */
-  public function setTypeConfiguration($configuration);
-
-  /**
-   * Returns the media type status.
-   *
-   * @return bool
-   *   The status.
-   */
-  public function getStatus();
-
-  /**
-   * Sets whether a new revision should be created by default.
-   *
-   * @param bool $new_revision
-   *   TRUE if a new revision should be created by default.
-   */
-  public function setNewRevision($new_revision);
-
-}
diff --git a/src/MediaBundleListBuilder.php b/src/MediaBundleListBuilder.php
deleted file mode 100644
index e5158b1..0000000
--- a/src/MediaBundleListBuilder.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\Core\Config\Entity\ConfigEntityListBuilder;
-use Drupal\Core\Entity\EntityHandlerInterface;
-use Drupal\Core\Entity\EntityInterface;
-use Drupal\Component\Utility\Xss;
-use Drupal\Core\Url;
-
-/**
- * Provides a listing of media bundles.
- */
-class MediaBundleListBuilder extends ConfigEntityListBuilder implements EntityHandlerInterface {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildHeader() {
-    $header['title'] = $this->t('Name');
-    $header['description'] = [
-      'data' => $this->t('Description'),
-      'class' => [RESPONSIVE_PRIORITY_MEDIUM],
-    ];
-    return $header + parent::buildHeader();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildRow(EntityInterface $entity) {
-    $row['title'] = [
-      'data' => $entity->label(),
-      'class' => ['menu-label'],
-    ];
-    $row['description'] = Xss::filterAdmin($entity->getDescription());
-    return $row + parent::buildRow($entity);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function render() {
-    $build = parent::render();
-    $build['#empty'] = $this->t('No media bundle available. <a href="@link">Add media bundle</a>.', [
-      '@link' => Url::fromRoute('entity.media_bundle.add_form')->toString(),
-    ]);
-    return $build;
-  }
-
-}
diff --git a/src/MediaForm.php b/src/MediaForm.php
deleted file mode 100644
index e2b4925..0000000
--- a/src/MediaForm.php
+++ /dev/null
@@ -1,154 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\entity\Form\RevisionableContentEntityForm;
-
-/**
- * Form controller for the media edit forms.
- */
-class MediaForm extends RevisionableContentEntityForm {
-
-  /**
-   * Default settings for this media bundle.
-   *
-   * @var array
-   */
-  protected $settings;
-
-  /**
-   * The entity being used by this form.
-   *
-   * @var \Drupal\media_entity\Entity\Media
-   */
-  protected $entity;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function prepareEntity() {
-    parent::prepareEntity();
-    $media = $this->entity;
-
-    // If this is a new media, fill in the default values.
-    if ($media->isNew()) {
-      $media->setPublisherId($this->currentUser()->id());
-      $media->setCreatedTime(REQUEST_TIME);
-    }
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function form(array $form, FormStateInterface $form_state) {
-    $form = parent::form($form, $form_state);
-
-    // Media author information for administrators.
-    if (isset($form['uid']) || isset($form['created'])) {
-      $form['author'] = [
-        '#type' => 'details',
-        '#title' => $this->t('Authoring information'),
-        '#group' => 'advanced',
-        '#attributes' => [
-          'class' => ['node-form-author'],
-        ],
-        '#attached' => [
-          'library' => ['node/drupal.node'],
-        ],
-        '#weight' => 90,
-        '#optional' => TRUE,
-      ];
-    }
-
-    if (isset($form['uid'])) {
-      $form['uid']['#group'] = 'author';
-    }
-
-    if (isset($form['created'])) {
-      $form['created']['#group'] = 'author';
-    }
-
-    $form['#attached']['library'][] = 'node/form';
-
-    $form['#entity_builders']['update_status'] = [$this, 'updateStatus'];
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function actions(array $form, FormStateInterface $form_state) {
-    $element = parent::actions($form, $form_state);
-    $media = $this->entity;
-
-    // Add a "Publish" button.
-    $element['publish'] = $element['submit'];
-    // If the "Publish" button is clicked, we want to update the status to
-    // "published".
-    $element['publish']['#published_status'] = TRUE;
-    $element['publish']['#dropbutton'] = 'save';
-    if ($media->isNew()) {
-      $element['publish']['#value'] = $this->t('Save and publish');
-    }
-    else {
-      $element['publish']['#value'] = $media->isPublished() ? $this->t('Save and keep published') : $this->t('Save and publish');
-    }
-    $element['publish']['#weight'] = 0;
-
-    // Add a "Unpublish" button.
-    $element['unpublish'] = $element['submit'];
-    // If the "Unpublish" button is clicked, we want to update the status to
-    // "unpublished".
-    $element['unpublish']['#published_status'] = FALSE;
-    $element['unpublish']['#dropbutton'] = 'save';
-    if ($media->isNew()) {
-      $element['unpublish']['#value'] = $this->t('Save as unpublished');
-    }
-    else {
-      $element['unpublish']['#value'] = !$media->isPublished() ? $this->t('Save and keep unpublished') : $this->t('Save and unpublish');
-    }
-    $element['unpublish']['#weight'] = 10;
-
-    // If already published, the 'publish' button is primary.
-    if ($media->isPublished()) {
-      unset($element['unpublish']['#button_type']);
-    }
-    // Otherwise, the 'unpublish' button is primary and should come first.
-    else {
-      unset($element['publish']['#button_type']);
-      $element['unpublish']['#weight'] = -10;
-    }
-
-    // Remove the "Save" button.
-    $element['submit']['#access'] = FALSE;
-
-    $element['delete']['#access'] = $media->access('delete');
-    $element['delete']['#weight'] = 100;
-
-    return $element;
-  }
-
-  /**
-   * Entity builder updating the media status with the submitted value.
-   *
-   * @param string $entity_type_id
-   *   The entity type identifier.
-   * @param \Drupal\media_entity\MediaInterface $media
-   *   The media updated with the submitted values.
-   * @param array $form
-   *   The complete form array.
-   * @param \Drupal\Core\Form\FormStateInterface $form_state
-   *   The current state of the form.
-   *
-   * @see \Drupal\media\MediaForm::form()
-   */
-  public function updateStatus($entity_type_id, MediaInterface $media, array $form, FormStateInterface $form_state) {
-    $element = $form_state->getTriggeringElement();
-    if (isset($element['#published_status'])) {
-      $media->setPublished($element['#published_status']);
-    }
-  }
-
-}
diff --git a/src/MediaInterface.php b/src/MediaInterface.php
deleted file mode 100644
index 63f7d0b..0000000
--- a/src/MediaInterface.php
+++ /dev/null
@@ -1,100 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\Core\Entity\EntityChangedInterface;
-use Drupal\Core\Entity\ContentEntityInterface;
-use Drupal\Core\Entity\RevisionLogInterface;
-
-/**
- * Provides an interface defining a media entity.
- */
-interface MediaInterface extends ContentEntityInterface, EntityChangedInterface, RevisionLogInterface {
-
-  /**
-   * Returns the media creation timestamp.
-   *
-   * @return int
-   *   Creation timestamp of the media.
-   */
-  public function getCreatedTime();
-
-  /**
-   * Sets the media creation timestamp.
-   *
-   * @param int $timestamp
-   *   The media creation timestamp.
-   *
-   * @return \Drupal\media_entity\MediaInterface
-   *   The called media entity.
-   */
-  public function setCreatedTime($timestamp);
-
-  /**
-   * Sets a flag to indicate the thumbnail will be retrieved via a queue.
-   */
-  public function setQueuedThumbnailDownload();
-
-  /**
-   * Returns the media publisher user entity.
-   *
-   * @return \Drupal\user\UserInterface
-   *   The author user entity.
-   */
-  public function getPublisher();
-
-  /**
-   * Returns the media publisher user ID.
-   *
-   * @return int
-   *   The author user ID.
-   */
-  public function getPublisherId();
-
-  /**
-   * Sets the media publisher user ID.
-   *
-   * @param int $uid
-   *   The author user id.
-   *
-   * @return \Drupal\media_entity\MediaInterface
-   *   The called media entity.
-   */
-  public function setPublisherId($uid);
-
-  /**
-   * Returns the media published status indicator.
-   *
-   * Unpublished media are only visible to their authors and to administrators.
-   *
-   * @return bool
-   *   TRUE if the media is published.
-   */
-  public function isPublished();
-
-  /**
-   * Sets the published status of a media.
-   *
-   * @param bool $published
-   *   TRUE to set this media to published, FALSE to set it to unpublished.
-   *
-   * @return \Drupal\media_entity\MediaInterface
-   *   The called media entity.
-   */
-  public function setPublished($published);
-
-  /**
-   * Returns the media type.
-   *
-   * @return \Drupal\media_entity\MediaTypeInterface
-   *   The media type.
-   */
-  public function getType();
-
-  /**
-   * Automatically determines the most appropriate thumbnail and sets
-   * "thumbnail" field.
-   */
-  public function automaticallySetThumbnail();
-
-}
diff --git a/src/MediaStorage.php b/src/MediaStorage.php
deleted file mode 100644
index ca7efbe..0000000
--- a/src/MediaStorage.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\Core\Entity\Sql\SqlContentEntityStorage;
-
-/**
- * Media storage class.
- */
-class MediaStorage extends SqlContentEntityStorage implements MediaStorageInterface {
-
-}
diff --git a/src/MediaStorageInterface.php b/src/MediaStorageInterface.php
deleted file mode 100644
index c9b6e79..0000000
--- a/src/MediaStorageInterface.php
+++ /dev/null
@@ -1,12 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\Core\Entity\EntityStorageInterface;
-
-/**
- * Provides an interface defining a media storage controller.
- */
-interface MediaStorageInterface extends EntityStorageInterface {
-
-}
diff --git a/src/MediaTypeBase.php b/src/MediaTypeBase.php
deleted file mode 100644
index a472e7d..0000000
--- a/src/MediaTypeBase.php
+++ /dev/null
@@ -1,161 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\Component\Plugin\PluginBase;
-use Drupal\Core\Config\Config;
-use Drupal\Core\Entity\EntityFieldManagerInterface;
-use Drupal\Core\Entity\EntityTypeManagerInterface;
-use Drupal\Core\StringTranslation\StringTranslationTrait;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Component\Utility\NestedArray;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Drupal\Core\Form\FormStateInterface;
-
-/**
- * Base implementation of media type plugin.
- */
-abstract class MediaTypeBase extends PluginBase implements MediaTypeInterface, ContainerFactoryPluginInterface {
-  use StringTranslationTrait;
-
-  /**
-   * Plugin label.
-   *
-   * @var string
-   */
-  protected $label;
-
-  /**
-   * The entity type manager service.
-   *
-   * @var \Drupal\Core\Entity\EntityTypeManagerInterface;
-   */
-  protected $entityTypeManager;
-
-  /**
-   * The entity field manager service.
-   *
-   * @var \Drupal\Core\Entity\EntityFieldManagerInterface;
-   */
-  protected $entityFieldManager;
-
-  /**
-   * Media entity image config object.
-   *
-   * @var \Drupal\Core\Config\Config
-   */
-  protected $config;
-
-  /**
-   * Constructs a new class instance.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin_id for the plugin instance.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
-   *   Entity type manager service.
-   * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entity_field_manager
-   *   Entity field manager service.
-   * @param \Drupal\Core\Config\Config $config
-   *   Media entity config object.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, EntityFieldManagerInterface $entity_field_manager, Config $config) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->entityTypeManager = $entity_type_manager;
-    $this->entityFieldManager = $entity_field_manager;
-    $this->config = $config;
-    $this->setConfiguration($configuration);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('entity_type.manager'),
-      $container->get('entity_field.manager'),
-      $container->get('config.factory')->get('media_entity.settings')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function setConfiguration(array $configuration) {
-    $this->configuration = NestedArray::mergeDeep(
-      $this->defaultConfiguration(),
-      $configuration
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getConfiguration() {
-    return $this->configuration;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function defaultConfiguration() {
-    return [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDefaultThumbnail() {
-    return '';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function label() {
-    return $this->label;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function attachConstraints(MediaInterface $media) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function calculateDependencies() {
-    return [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
-    return [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {}
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getDefaultName(MediaInterface $media) {
-    return 'media:' . $media->bundle() . ':' . $media->uuid();
-  }
-
-}
diff --git a/src/MediaTypeException.php b/src/MediaTypeException.php
deleted file mode 100644
index 9e3ac2c..0000000
--- a/src/MediaTypeException.php
+++ /dev/null
@@ -1,45 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-/**
- * Generic Plugin exception class to be thrown when no more specific class
- * is applicable.
- */
-class MediaTypeException extends \Exception {
-
-  /**
-   * Form element name that this exception belongs to.
-   *
-   * @var string
-   */
-  protected $element;
-
-  /**
-   * Construct the exception.
-   *
-   * @param string $element
-   *   [optional] Name of form element that exception refers to.
-   * @param string $message
-   *   [optional] The Exception message to throw.
-   * @param int $code
-   *   [optional] The Exception code.
-   * @param \Exception $previous
-   *   [optional] The previous exception used for the exception chaining.
-   */
-  public function __construct($element = NULL, $message = "", $code = 0, \Exception $previous = NULL) {
-    parent::__construct($message, $code, $previous);
-    $this->element = $element;
-  }
-
-  /**
-   * Gets element.
-   *
-   * @return string
-   *   Element name.
-   */
-  public function getElement() {
-    return $this->element;
-  }
-
-}
diff --git a/src/MediaTypeInterface.php b/src/MediaTypeInterface.php
deleted file mode 100644
index 2a171c2..0000000
--- a/src/MediaTypeInterface.php
+++ /dev/null
@@ -1,88 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\Component\Plugin\PluginInspectionInterface;
-use Drupal\Component\Plugin\ConfigurablePluginInterface;
-use Drupal\Core\Plugin\PluginFormInterface;
-
-/**
- * Defines the interface for media types.
- */
-interface MediaTypeInterface extends PluginInspectionInterface, ConfigurablePluginInterface, PluginFormInterface {
-
-  /**
-   * Returns the display label.
-   *
-   * @return string
-   *   The display label.
-   */
-  public function label();
-
-  /**
-   * Gets list of fields provided by this plugin.
-   *
-   * @return array
-   *   Associative array with field names as keys and descriptions as values.
-   */
-  public function providedFields();
-
-  /**
-   * Gets a media-related field/value.
-   *
-   * @param MediaInterface $media
-   *   Media object.
-   * @param string $name
-   *   Name of field to fetch.
-   *
-   * @return mixed
-   *   Field value or FALSE if data unavailable.
-   */
-  public function getField(MediaInterface $media, $name);
-
-  /**
-   * Attaches type-specific constraints to media.
-   *
-   * @param MediaInterface $media
-   *   Media entity.
-   */
-  public function attachConstraints(MediaInterface $media);
-
-  /**
-   * Gets thumbnail image.
-   *
-   * Media type plugin is responsible for returning URI of the generic thumbnail
-   * if no other is available. This functions should always return a valid URI.
-   *
-   * @param MediaInterface $media
-   *   Media.
-   *
-   * @return string
-   *   URI of the thumbnail.
-   */
-  public function thumbnail(MediaInterface $media);
-
-  /**
-   * Gets the default thumbnail image.
-   *
-   * @return string
-   *   Uri of the default thumbnail image.
-   */
-  public function getDefaultThumbnail();
-
-  /**
-   * Provide a default name for the media.
-   *
-   * Plugins defining media bundles are suggested to override this method and
-   * provide a default name, to be used when there is no user-defined label
-   * available.
-   *
-   * @param \Drupal\media_entity\MediaInterface $media
-   *   The media object.
-   *
-   * @return string
-   *   The string that should be used as default media name.
-   */
-  public function getDefaultName(MediaInterface $media);
-
-}
diff --git a/src/MediaViewsData.php b/src/MediaViewsData.php
deleted file mode 100644
index c13b8b2..0000000
--- a/src/MediaViewsData.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-
-namespace Drupal\media_entity;
-
-use Drupal\views\EntityViewsData;
-
-/**
- * Provides the views data for the media entity type.
- */
-class MediaViewsData extends EntityViewsData {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getViewsData() {
-    $data = parent::getViewsData();
-
-    $data['media_field_data']['table']['wizard_id'] = 'media';
-    $data['media_field_revision']['table']['wizard_id'] = 'media_revision';
-    $data['media']['media_bulk_form'] = [
-      'title' => $this->t('Media operations bulk form'),
-      'help' => $this->t('Add a form element that lets you run operations on multiple media entities.'),
-      'field' => [
-        'id' => 'media_bulk_form',
-      ],
-    ];
-
-    return $data;
-  }
-
-}
diff --git a/src/Plugin/Action/DeleteMedia.php b/src/Plugin/Action/DeleteMedia.php
deleted file mode 100644
index b2a98d2..0000000
--- a/src/Plugin/Action/DeleteMedia.php
+++ /dev/null
@@ -1,98 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Plugin\Action;
-
-use Drupal\Core\Action\ActionBase;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\user\PrivateTempStoreFactory;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Redirects to a media deletion form.
- *
- * @Action(
- *   id = "media_delete_action",
- *   label = @Translation("Delete media"),
- *   type = "media",
- *   confirm_form_route_name = "entity.media.multiple_delete_confirm"
- * )
- */
-class DeleteMedia extends ActionBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The tempstore object.
-   *
-   * @var \Drupal\user\SharedTempStore
-   */
-  protected $tempStore;
-
-  /**
-   * The current user.
-   *
-   * @var \Drupal\Core\Session\AccountInterface
-   */
-  protected $currentUser;
-
-  /**
-   * Constructs a new DeleteMedia object.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin ID for the plugin instance.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\user\PrivateTempStoreFactory $temp_store_factory
-   *   The tempstore factory.
-   * @param AccountInterface $current_user
-   *   Current user.
-   */
-  public function __construct(array $configuration, $plugin_id, $plugin_definition, PrivateTempStoreFactory $temp_store_factory, AccountInterface $current_user) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-    $this->currentUser = $current_user;
-    $this->tempStore = $temp_store_factory->get('media_multiple_delete_confirm');
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $configuration,
-      $plugin_id,
-      $plugin_definition,
-      $container->get('user.private_tempstore'),
-      $container->get('current_user')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function executeMultiple(array $entities) {
-    $info = [];
-    /** @var \Drupal\media_entity\MediaInterface $media */
-    foreach ($entities as $media) {
-      $langcode = $media->language()->getId();
-      $info[$media->id()][$langcode] = $langcode;
-    }
-    $this->tempStore->set($this->currentUser->id(), $info);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function execute($object = NULL) {
-    $this->executeMultiple(array($object));
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
-    /** @var \Drupal\media_entity\MediaInterface $object */
-    return $object->access('delete', $account, $return_as_object);
-  }
-
-}
diff --git a/src/Plugin/Action/PublishMedia.php b/src/Plugin/Action/PublishMedia.php
deleted file mode 100644
index d223bab..0000000
--- a/src/Plugin/Action/PublishMedia.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Plugin\Action;
-
-use Drupal\Core\Action\ActionBase;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\media_entity\Entity\Media;
-
-/**
- * Publishes a media entity.
- *
- * @Action(
- *   id = "media_publish_action",
- *   label = @Translation("Publish media"),
- *   type = "media"
- * )
- */
-class PublishMedia extends ActionBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function execute(Media $entity = NULL) {
-    $entity->setPublished(TRUE)->save();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
-    /** @var \Drupal\media_entity\MediaInterface $object */
-    $result = $object->access('update', $account, TRUE)
-      ->andIf($object->status->access('edit', $account, TRUE));
-
-    return $return_as_object ? $result : $result->isAllowed();
-  }
-
-}
diff --git a/src/Plugin/Action/SaveMedia.php b/src/Plugin/Action/SaveMedia.php
deleted file mode 100644
index a061cfc..0000000
--- a/src/Plugin/Action/SaveMedia.php
+++ /dev/null
@@ -1,37 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Plugin\Action;
-
-use Drupal\Core\Action\ActionBase;
-use Drupal\Core\Session\AccountInterface;
-
-/**
- * Provides an action that can save any entity.
- *
- * @Action(
- *   id = "media_save_action",
- *   label = @Translation("Save media"),
- *   type = "media"
- * )
- */
-class SaveMedia extends ActionBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function execute($entity = NULL) {
-    // We need to change at least one value, otherwise the changed timestamp
-    // will not be updated.
-    $entity->changed = 0;
-    $entity->save();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
-    /** @var \Drupal\media_entity\MediaInterface $object */
-    return $object->access('update', $account, $return_as_object);
-  }
-
-}
diff --git a/src/Plugin/Action/UnpublishMedia.php b/src/Plugin/Action/UnpublishMedia.php
deleted file mode 100644
index 59e4d2f..0000000
--- a/src/Plugin/Action/UnpublishMedia.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Plugin\Action;
-
-use Drupal\Core\Action\ActionBase;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\media_entity\Entity\Media;
-
-/**
- * Unpublishes a media entity.
- *
- * @Action(
- *   id = "media_unpublish_action",
- *   label = @Translation("Unpublish media"),
- *   type = "media"
- * )
- */
-class UnpublishMedia extends ActionBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function execute(Media $entity = NULL) {
-    $entity->setPublished(FALSE)->save();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
-    /** @var \Drupal\media_entity\MediaInterface $object */
-    $result = $object->access('update', $account, TRUE)
-      ->andIf($object->status->access('edit', $account, TRUE));
-
-    return $return_as_object ? $result : $result->isAllowed();
-  }
-
-}
diff --git a/src/Plugin/DevelGenerate/MediaDevelGenerate.php b/src/Plugin/DevelGenerate/MediaDevelGenerate.php
deleted file mode 100644
index 7558c8f..0000000
--- a/src/Plugin/DevelGenerate/MediaDevelGenerate.php
+++ /dev/null
@@ -1,458 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Plugin\DevelGenerate;
-
-use Drupal\Core\Datetime\DateFormatter;
-use Drupal\Core\Entity\EntityStorageInterface;
-use Drupal\Core\Extension\ModuleHandlerInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Language\LanguageInterface;
-use Drupal\Core\Language\LanguageManagerInterface;
-use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
-use Drupal\Core\Routing\UrlGeneratorInterface;
-use Drupal\devel_generate\DevelGenerateBase;
-use Drupal\media_entity\MediaStorageInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-
-/**
- * Provides a MediaDevelGenerate plugin.
- *
- * @DevelGenerate(
- *   id = "media",
- *   label = @Translation("media"),
- *   description = @Translation("Generate a given number of media entities."),
- *   url = "media",
- *   permission = "administer devel_generate",
- *   settings = {
- *     "num" = 50,
- *     "kill" = FALSE,
- *     "name_length" = 4
- *   }
- * )
- */
-class MediaDevelGenerate extends DevelGenerateBase implements ContainerFactoryPluginInterface {
-
-  /**
-   * The media storage.
-   *
-   * @var \Drupal\media_entity\MediaStorageInterface
-   */
-  protected $mediaStorage;
-
-  /**
-   * The media bundle storage.
-   *
-   * @var \Drupal\Core\Entity\EntityStorageInterface
-   */
-  protected $mediaBundleStorage;
-
-  /**
-   * The user storage.
-   *
-   * @var \Drupal\Core\Entity\EntityStorageInterface
-   */
-  protected $userStorage;
-
-  /**
-   * The module handler.
-   *
-   * @var \Drupal\Core\Extension\ModuleHandlerInterface
-   */
-  protected $moduleHandler;
-
-  /**
-   * The language manager.
-   *
-   * @var \Drupal\Core\Language\LanguageManagerInterface
-   */
-  protected $languageManager;
-
-  /**
-   * The url generator service.
-   *
-   * @var \Drupal\Core\Routing\UrlGeneratorInterface
-   */
-  protected $urlGenerator;
-
-  /**
-   * The date formatter service.
-   *
-   * @var \Drupal\Core\Datetime\DateFormatter
-   */
-  protected $dateFormatter;
-
-  /**
-   * Database connection.
-   *
-   * @var Connection
-   */
-  protected $database;
-
-  /**
-   * Constructs MediaDevelGenerate class.
-   *
-   * @param array $configuration
-   *   A configuration array containing information about the plugin instance.
-   * @param string $plugin_id
-   *   The plugin ID for the plugin instance.
-   * @param array $plugin_definition
-   *   The plugin definition.
-   * @param \Drupal\media_entity\MediaStorageInterface $media_storage
-   *   The media storage.
-   * @param \Drupal\Core\Entity\EntityStorageInterface $user_storage
-   *   The user storage.
-   * @param \Drupal\Core\Entity\EntityStorageInterface $media_bundle_storage
-   *   The media bundle storage.
-   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
-   *   The module handler.
-   * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
-   *   The language manager.
-   * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
-   *   The url generator service.
-   * @param \Drupal\Core\Datetime\DateFormatter $date_formatter
-   *   The date formatter service.
-   */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, MediaStorageInterface $media_storage, EntityStorageInterface $user_storage, EntityStorageInterface $media_bundle_storage, ModuleHandlerInterface $module_handler, LanguageManagerInterface $language_manager, UrlGeneratorInterface $url_generator, DateFormatter $date_formatter) {
-    parent::__construct($configuration, $plugin_id, $plugin_definition);
-
-    $this->moduleHandler = $module_handler;
-    $this->mediaStorage = $media_storage;
-    $this->mediaBundleStorage = $media_bundle_storage;
-    $this->userStorage = $user_storage;
-    $this->languageManager = $language_manager;
-    $this->urlGenerator = $url_generator;
-    $this->dateFormatter = $date_formatter;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    $entity_manager = $container->get('entity.manager');
-    return new static(
-      $configuration, $plugin_id, $plugin_definition,
-      $entity_manager->getStorage('media'),
-      $entity_manager->getStorage('user'),
-      $entity_manager->getStorage('media_bundle'),
-      $container->get('module_handler'),
-      $container->get('language_manager'),
-      $container->get('url_generator'),
-      $container->get('date.formatter')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, FormStateInterface $form_state) {
-    $bundles = $this->mediaBundleStorage->loadMultiple();
-
-    if (empty($bundles)) {
-      $create_url = $this->urlGenerator->generateFromRoute('media.bundle_add');
-      $this->setMessage($this->t('You do not have any media bundles that can be generated. <a href="@create-bundle">Go create a new media bundle</a>', ['@create-bundle' => $create_url]), 'error', FALSE);
-      return [];
-    }
-
-    $options = [];
-    foreach ($bundles as $bundle) {
-      $options[$bundle->id()] = ['bundle' => ['#markup' => $bundle->label()]];
-    }
-
-    $form['media_bundles'] = [
-      '#type' => 'tableselect',
-      '#header' => ['bundle' => $this->t('Media bundle')],
-      '#options' => $options,
-    ];
-
-    $form['kill'] = [
-      '#type' => 'checkbox',
-      '#title' => $this->t('<strong>Delete all media</strong> in these bundles before generating new media.'),
-      '#default_value' => $this->getSetting('kill'),
-    ];
-    $form['num'] = [
-      '#type' => 'number',
-      '#title' => $this->t('How many media items would you like to generate?'),
-      '#default_value' => $this->getSetting('num'),
-      '#required' => TRUE,
-      '#min' => 0,
-    ];
-
-    $options = [1 => $this->t('Now')];
-    foreach ([3600, 86400, 604800, 2592000, 31536000] as $interval) {
-      $options[$interval] = $this->dateFormatter->formatInterval($interval, 1) . ' ' . $this->t('ago');
-    }
-    $form['time_range'] = [
-      '#type' => 'select',
-      '#title' => $this->t('How far back in time should the media be dated?'),
-      '#description' => $this->t('Media creation dates will be distributed randomly from the current time, back to the selected time.'),
-      '#options' => $options,
-      '#default_value' => 604800,
-    ];
-
-    $form['name_length'] = [
-      '#type' => 'number',
-      '#title' => $this->t('Maximum number of words in names'),
-      '#default_value' => $this->getSetting('name_length'),
-      '#required' => TRUE,
-      '#min' => 1,
-      '#max' => 255,
-    ];
-
-    $options = [];
-    // We always need a language.
-    $languages = $this->languageManager->getLanguages(LanguageInterface::STATE_ALL);
-    foreach ($languages as $langcode => $language) {
-      $options[$langcode] = $language->getName();
-    }
-
-    $form['add_language'] = [
-      '#type' => 'select',
-      '#title' => $this->t('Set language on media'),
-      '#multiple' => TRUE,
-      '#description' => $this->t('Requires locale.module'),
-      '#options' => $options,
-      '#default_value' => [
-        $this->languageManager->getDefaultLanguage()->getId(),
-      ],
-    ];
-
-    $form['#redirect'] = FALSE;
-
-    return $form;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function generateElements(array $values) {
-    if ($values['num'] <= 50) {
-      $this->generateMedia($values);
-    }
-    else {
-      $this->generateBatchMedia($values);
-    }
-  }
-
-  /**
-   * Method for creating media when number of elements is less than 50.
-   *
-   * @param array $values
-   *   Array of values submitted through a form.
-   */
-  private function generateMedia($values) {
-    $values['media_bundles'] = array_filter($values['media_bundles']);
-    if (!empty($values['kill']) && $values['media_bundles']) {
-      $this->mediaKill($values);
-    }
-
-    if (!empty($values['media_bundles'])) {
-      // Generate media.
-      $this->preGenerate($values);
-      $start = time();
-      for ($i = 1; $i <= $values['num']; $i++) {
-        $this->createMediaItem($values);
-        if (function_exists('drush_log') && $i % drush_get_option('feedback', 1000) == 0) {
-          $now = time();
-          drush_log(dt('Completed !feedback media items (!rate media/min)', [
-            '!feedback' => drush_get_option('feedback', 1000),
-            '!rate' => (drush_get_option('feedback', 1000) * 60) / ($now - $start),
-          ]), 'ok');
-          $start = $now;
-        }
-      }
-    }
-    $this->setMessage($this->formatPlural($values['num'], '1 media created.', 'Finished creating @count media items.'));
-  }
-
-  /**
-   * Method for creating media when number of elements is greater than 50.
-   *
-   * @param array $values
-   *   The input values from the settings form.
-   */
-  private function generateBatchMedia($values) {
-    // Setup the batch operations and save the variables.
-    $operations[] = [
-      'devel_generate_operation',
-      [$this, 'batchPreGenerate', $values],
-    ];
-
-    // Add the kill operation.
-    if ($values['kill']) {
-      $operations[] = [
-        'devel_generate_operation',
-        [$this, 'batchMediaKill', $values],
-      ];
-    }
-
-    // Add the operations to create the media.
-    for ($num = 0; $num < $values['num']; $num++) {
-      $operations[] = [
-        'devel_generate_operation',
-        [$this, 'batchCreateMediaItem', $values],
-      ];
-    }
-
-    // Start the batch.
-    $batch = [
-      'title' => $this->t('Generating media'),
-      'operations' => $operations,
-      'finished' => 'devel_generate_batch_finished',
-      'file' => drupal_get_path('module', 'devel_generate') . '/devel_generate.batch.inc',
-    ];
-    batch_set($batch);
-  }
-
-  /**
-   * Batch version of preGenerate().
-   *
-   * @param array $vars
-   *   The input values from the settings form.
-   * @param array $context
-   *   Batch job context.
-   */
-  public function batchPreGenerate($vars, &$context) {
-    $context['results'] = $vars;
-    $context['results']['num'] = 0;
-    $this->preGenerate($context['results']);
-  }
-
-  /**
-   * Batch version of createMediaItem().
-   *
-   * @param array $vars
-   *   The input values from the settings form.
-   * @param array $context
-   *   Batch job context.
-   */
-  public function batchCreateMediaItem($vars, &$context) {
-    $this->createMediaItem($context['results']);
-    $context['results']['num']++;
-  }
-
-  /**
-   * Batch version of mediaKill().
-   *
-   * @param array $vars
-   *   The input values from the settings form.
-   * @param array $context
-   *   Batch job context.
-   */
-  public function batchMediaKill($vars, &$context) {
-    $this->mediaKill($context['results']);
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function validateDrushParams($args) {
-    $add_language = drush_get_option('languages');
-    if (!empty($add_language)) {
-      $add_language = explode(',', str_replace(' ', '', $add_language));
-      // Intersect with the enabled languages to make sure the language args
-      // passed are actually enabled.
-      $values['values']['add_language'] = array_intersect($add_language, array_keys($this->languageManager->getLanguages(LanguageInterface::STATE_ALL)));
-    }
-
-    $values['kill'] = drush_get_option('kill');
-    $values['name_length'] = drush_get_option('name_length', 6);
-    $values['num'] = array_shift($args);
-    $selected_bundles = _convert_csv_to_array(drush_get_option('bundles', []));
-
-    if (empty($selected_bundles)) {
-      return drush_set_error('DEVEL_GENERATE_NO_MEDIA_BUNDLES', dt('No media bundles available'));
-    }
-
-    $values['media_bundles'] = array_combine($selected_bundles, $selected_bundles);
-
-    return $values;
-  }
-
-  /**
-   * Deletes all media of given media bundles.
-   *
-   * @param array $values
-   *   The input values from the settings form.
-   */
-  protected function mediaKill($values) {
-    $mids = $this->mediaStorage->getQuery()
-      ->condition('bundle', $values['media_bundles'], 'IN')
-      ->execute();
-
-    if (!empty($mids)) {
-      $media = $this->mediaStorage->loadMultiple($mids);
-      $this->mediaStorage->delete($media);
-      $this->setMessage($this->t('Deleted %count media items.', ['%count' => count($mids)]));
-    }
-  }
-
-  /**
-   * Code to be run before generating items.
-   *
-   * Returns the same array passed in as parameter, but with an array of uids
-   * for the key 'users'.
-   *
-   * @param array $results
-   *   The input values from the settings form.
-   */
-  protected function preGenerate(&$results) {
-    // Get user id.
-    $users = $this->userStorage->getQuery()
-      ->range(0, 50)
-      ->execute();
-    $users = array_merge($users, ['0']);
-    $results['users'] = $users;
-  }
-
-  /**
-   * Create one media item. Used by both batch and non-batch code branches.
-   *
-   * @param array $results
-   *   The input values from the settings form.
-   */
-  protected function createMediaItem(&$results) {
-    if (!isset($results['time_range'])) {
-      $results['time_range'] = 0;
-    }
-    $users = $results['users'];
-
-    $bundle = array_rand(array_filter($results['media_bundles']));
-    $uid = $users[array_rand($users)];
-
-    $media = $this->mediaStorage->create([
-      'bundle' => $bundle,
-      'name' => $this->getRandom()->sentences(mt_rand(1, $results['name_length']), TRUE),
-      'uid' => $uid,
-      'revision' => mt_rand(0, 1),
-      'status' => TRUE,
-      'created' => REQUEST_TIME - mt_rand(0, $results['time_range']),
-      'langcode' => $this->getLangcode($results),
-    ]);
-
-    // A flag to let hook implementations know that this is a generated item.
-    $media->devel_generate = $results;
-
-    // Populate all fields with sample values.
-    $this->populateFields($media);
-
-    $media->save();
-  }
-
-  /**
-   * Determine language based on $results.
-   *
-   * @param array $results
-   *   The input values from the settings form.
-   */
-  protected function getLangcode($results) {
-    if (isset($results['add_language'])) {
-      $langcodes = $results['add_language'];
-      $langcode = $langcodes[array_rand($langcodes)];
-    }
-    else {
-      $langcode = $this->languageManager->getDefaultLanguage()->getId();
-    }
-    return $langcode;
-  }
-
-}
diff --git a/src/Plugin/Field/FieldFormatter/MediaThumbnailFormatter.php b/src/Plugin/Field/FieldFormatter/MediaThumbnailFormatter.php
deleted file mode 100644
index ca4fb6b..0000000
--- a/src/Plugin/Field/FieldFormatter/MediaThumbnailFormatter.php
+++ /dev/null
@@ -1,187 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Plugin\Field\FieldFormatter;
-
-use Drupal\Core\Field\FieldItemListInterface;
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\Core\Session\AccountInterface;
-use Drupal\image\Plugin\Field\FieldFormatter\ImageFormatter;
-use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
-use Drupal\Core\Render\RendererInterface;
-use Symfony\Component\DependencyInjection\ContainerInterface;
-use Drupal\Core\Field\FieldDefinitionInterface;
-use Drupal\Core\Entity\EntityStorageInterface;
-
-/**
- * Plugin implementation of the 'media_thumbnail' formatter.
- *
- * @FieldFormatter(
- *   id = "media_thumbnail",
- *   label = @Translation("Thumbnail"),
- *   field_types = {
- *     "entity_reference"
- *   }
- * )
- */
-class MediaThumbnailFormatter extends ImageFormatter {
-
-  /**
-   * The renderer service.
-   *
-   * @var \Drupal\Core\Render\RendererInterface
-   */
-  protected $renderer;
-
-  /**
-   * Constructs an ImageFormatter object.
-   *
-   * @param string $plugin_id
-   *   The plugin_id for the formatter.
-   * @param mixed $plugin_definition
-   *   The plugin implementation definition.
-   * @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
-   *   The definition of the field to which the formatter is associated.
-   * @param array $settings
-   *   The formatter settings.
-   * @param string $label
-   *   The formatter label display setting.
-   * @param string $view_mode
-   *   The view mode.
-   * @param array $third_party_settings
-   *   Any third party settings settings.
-   * @param \Drupal\Core\Session\AccountInterface $current_user
-   *   The current user.
-   * @param \Drupal\Core\Render\RendererInterface $renderer
-   *   The renderer service.
-   */
-  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, AccountInterface $current_user, EntityStorageInterface $image_style_storage, RendererInterface $renderer) {
-    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $current_user, $image_style_storage);
-    $this->renderer = $renderer;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
-    return new static(
-      $plugin_id,
-      $plugin_definition,
-      $configuration['field_definition'],
-      $configuration['settings'],
-      $configuration['label'],
-      $configuration['view_mode'],
-      $configuration['third_party_settings'],
-      $container->get('current_user'),
-      $container->get('entity.manager')->getStorage('image_style'),
-      $container->get('renderer')
-    );
-  }
-
-  /**
-   * {@inheritdoc}
-   *
-   * This has to be overriden because FileFormatterBase expects $item to be
-   * of type \Drupal\file\Plugin\Field\FieldType\FileItem and calls
-   * isDisplayed() which is not in FieldItemInterface.
-   */
-  protected function needsEntityLoad(EntityReferenceItem $item) {
-    return !$item->hasNewEntity();
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsForm(array $form, FormStateInterface $form_state) {
-    $element = parent::settingsForm($form, $form_state);
-
-    $link_types = [
-      'content' => $this->t('Content'),
-      'media' => $this->t('Media entity'),
-    ];
-    $element['image_link']['#options'] = $link_types;
-
-    return $element;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function settingsSummary() {
-    $summary = parent::settingsSummary();
-
-    $link_types = [
-      'content' => $this->t('Linked to content'),
-      'media' => $this->t('Linked to media entity'),
-    ];
-    // Display this setting only if image is linked.
-    $image_link_setting = $this->getSetting('image_link');
-    if (isset($link_types[$image_link_setting])) {
-      $summary[] = $link_types[$image_link_setting];
-    }
-
-    return $summary;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function viewElements(FieldItemListInterface $items, $langcode) {
-    $elements = [];
-    $media = $this->getEntitiesToView($items, $langcode);
-
-    // Early opt-out if the field is empty.
-    if (empty($media)) {
-      return $elements;
-    }
-
-    $url = NULL;
-    $image_link_setting = $this->getSetting('image_link');
-    // Check if the formatter involves a link.
-    if ($image_link_setting == 'content') {
-      $entity = $items->getEntity();
-      if (!$entity->isNew()) {
-        $url = $entity->toUrl();
-      }
-    }
-    elseif ($image_link_setting == 'media') {
-      $link_media = TRUE;
-    }
-
-    $image_style_setting = $this->getSetting('image_style');
-
-    /** @var \Drupal\media_entity\MediaInterface $media_item */
-    foreach ($media as $delta => $media_item) {
-      if (isset($link_media)) {
-        $url = $media_item->toUrl();
-      }
-
-      $elements[$delta] = [
-        '#theme' => 'image_formatter',
-        '#item' => $media_item->get('thumbnail'),
-        '#item_attributes' => [],
-        '#image_style' => $image_style_setting,
-        '#url' => $url,
-      ];
-
-      // Collect cache tags to be added for each item in the field.
-      $this->renderer->addCacheableDependency($elements[$delta], $media_item);
-    }
-
-    // Collect cache tags related to the image style setting.
-    $image_style = $this->imageStyleStorage->load($image_style_setting);
-    $this->renderer->addCacheableDependency($elements, $image_style);
-
-    return $elements;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public static function isApplicable(FieldDefinitionInterface $field_definition) {
-    // This formatter is only available for entity types that reference
-    // media entities.
-    $target_type = $field_definition->getFieldStorageDefinition()->getSetting('target_type');
-    return $target_type == 'media';
-  }
-
-}
diff --git a/src/Plugin/MediaEntity/Type/Generic.php b/src/Plugin/MediaEntity/Type/Generic.php
deleted file mode 100644
index b83ba9d..0000000
--- a/src/Plugin/MediaEntity/Type/Generic.php
+++ /dev/null
@@ -1,53 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Plugin\MediaEntity\Type;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\media_entity\MediaInterface;
-use Drupal\media_entity\MediaTypeBase;
-
-/**
- * Provides generic media type.
- *
- * @MediaType(
- *   id = "generic",
- *   label = @Translation("Generic media"),
- *   description = @Translation("Generic media type.")
- * )
- */
-class Generic extends MediaTypeBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function providedFields() {
-    return [];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getField(MediaInterface $media, $name) {
-    return FALSE;
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function thumbnail(MediaInterface $media) {
-    return $this->config->get('icon_base') . '/generic.png';
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
-    $form['text'] = [
-      '#type' => 'markup',
-      '#markup' => $this->t("This type provider doesn't need configuration."),
-    ];
-
-    return $form;
-  }
-
-}
diff --git a/src/Plugin/QueueWorker/thumbnailDownloader.php b/src/Plugin/QueueWorker/thumbnailDownloader.php
deleted file mode 100644
index 8dc5538..0000000
--- a/src/Plugin/QueueWorker/thumbnailDownloader.php
+++ /dev/null
@@ -1,31 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Plugin\QueueWorker;
-
-use Drupal\media_entity\Entity\Media;
-use Drupal\Core\Queue\QueueWorkerBase;
-
-/**
- * Download images.
- *
- * @QueueWorker(
- *   id = "media_entity_thumbnail",
- *   title = @Translation("Thumbnail downloader"),
- *   cron = {"time" = 60}
- * )
- */
-class ThumbnailDownloader extends QueueWorkerBase {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function processItem($data) {
-    if ($entity = Media::load($data['id'])) {
-      // Indicate that the entity is being processed from a queue and that
-      // thumbnail images should be downloaded.
-      $entity->setQueuedThumbnailDownload();
-      $entity->save();
-    }
-  }
-
-}
diff --git a/src/Plugin/views/field/MediaBulkForm.php b/src/Plugin/views/field/MediaBulkForm.php
deleted file mode 100644
index 3cb19a5..0000000
--- a/src/Plugin/views/field/MediaBulkForm.php
+++ /dev/null
@@ -1,21 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Plugin\views\field;
-
-use Drupal\system\Plugin\views\field\BulkForm;
-
-/**
- * Defines a media operations bulk form element.
- *
- * @ViewsField("media_bulk_form")
- */
-class MediaBulkForm extends BulkForm {
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function emptySelectedMessage() {
-    return $this->t('No media selected.');
-  }
-
-}
diff --git a/src/Plugin/views/wizard/Media.php b/src/Plugin/views/wizard/Media.php
deleted file mode 100644
index 1abf6ca..0000000
--- a/src/Plugin/views/wizard/Media.php
+++ /dev/null
@@ -1,84 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Plugin\views\wizard;
-
-use Drupal\views\Plugin\views\wizard\WizardPluginBase;
-
-/**
- * Tests creating media views with the wizard.
- *
- * @ViewsWizard(
- *   id = "media",
- *   base_table = "media_field_data",
- *   title = @Translation("Media")
- * )
- */
-class Media extends WizardPluginBase {
-
-  /**
-   * Set the created column.
-   */
-  protected $createdColumn = 'media_field_data-created';
-
-  /**
-   * Set default values for the filters.
-   */
-  protected $filters = [
-    'status' => [
-      'value' => TRUE,
-      'table' => 'media_field_data',
-      'field' => 'status',
-      'plugin_id' => 'boolean',
-      'entity_type' => 'media',
-      'entity_field' => 'status',
-    ],
-  ];
-
-  /**
-   * {@inheritdoc}
-   */
-  public function getAvailableSorts() {
-    return [
-      'media_field_data-name:DESC' => $this->t('Media name'),
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function defaultDisplayOptions() {
-    $display_options = parent::defaultDisplayOptions();
-
-    // Add permission-based access control.
-    $display_options['access']['type'] = 'perm';
-    $display_options['access']['options']['perm'] = 'access content';
-
-    // Remove the default fields, since we are customizing them here.
-    unset($display_options['fields']);
-
-    // Add the name field, so that the display has content if the user switches
-    // to a row style that uses fields.
-    /* Field: Media: Name */
-    $display_options['fields']['name']['id'] = 'name';
-    $display_options['fields']['name']['table'] = 'media_field_data';
-    $display_options['fields']['name']['field'] = 'name';
-    $display_options['fields']['name']['entity_type'] = 'media';
-    $display_options['fields']['name']['entity_field'] = 'media';
-    $display_options['fields']['name']['label'] = '';
-    $display_options['fields']['name']['alter']['alter_text'] = 0;
-    $display_options['fields']['name']['alter']['make_link'] = 0;
-    $display_options['fields']['name']['alter']['absolute'] = 0;
-    $display_options['fields']['name']['alter']['trim'] = 0;
-    $display_options['fields']['name']['alter']['word_boundary'] = 0;
-    $display_options['fields']['name']['alter']['ellipsis'] = 0;
-    $display_options['fields']['name']['alter']['strip_tags'] = 0;
-    $display_options['fields']['name']['alter']['html'] = 0;
-    $display_options['fields']['name']['hide_empty'] = 0;
-    $display_options['fields']['name']['empty_zero'] = 0;
-    $display_options['fields']['name']['settings']['link_to_entity'] = 1;
-    $display_options['fields']['name']['plugin_id'] = 'field';
-
-    return $display_options;
-  }
-
-}
diff --git a/src/Plugin/views/wizard/MediaRevision.php b/src/Plugin/views/wizard/MediaRevision.php
deleted file mode 100644
index 72bceb0..0000000
--- a/src/Plugin/views/wizard/MediaRevision.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Plugin\views\wizard;
-
-use Drupal\views\Plugin\views\wizard\WizardPluginBase;
-
-/**
- * Tests creating media revision views with the wizard.
- *
- * @ViewsWizard(
- *   id = "media_revision",
- *   base_table = "media_field_revision",
- *   title = @Translation("Media revisions")
- * )
- */
-class MediaRevision extends WizardPluginBase {
-
-  /**
-   * Set the created column.
-   */
-  protected $createdColumn = 'changed';
-
-  /**
-   * Set default values for the filters.
-   */
-  protected $filters = [
-    'status' => [
-      'value' => TRUE,
-      'table' => 'media_field_revision',
-      'field' => 'status',
-      'plugin_id' => 'boolean',
-      'entity_type' => 'media',
-      'entity_field' => 'status',
-    ],
-  ];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function defaultDisplayOptions() {
-    $display_options = parent::defaultDisplayOptions();
-
-    // Add permission-based access control.
-    $display_options['access']['type'] = 'perm';
-    $display_options['access']['options']['perm'] = 'view all revisions';
-
-    // Remove the default fields, since we are customizing them here.
-    unset($display_options['fields']);
-
-    /* Field: Media revision: Created date */
-    $display_options['fields']['changed']['id'] = 'changed';
-    $display_options['fields']['changed']['table'] = 'media_field_revision';
-    $display_options['fields']['changed']['field'] = 'changed';
-    $display_options['fields']['changed']['entity_type'] = 'media';
-    $display_options['fields']['changed']['entity_field'] = 'changed';
-    $display_options['fields']['changed']['alter']['alter_text'] = FALSE;
-    $display_options['fields']['changed']['alter']['make_link'] = FALSE;
-    $display_options['fields']['changed']['alter']['absolute'] = FALSE;
-    $display_options['fields']['changed']['alter']['trim'] = FALSE;
-    $display_options['fields']['changed']['alter']['word_boundary'] = FALSE;
-    $display_options['fields']['changed']['alter']['ellipsis'] = FALSE;
-    $display_options['fields']['changed']['alter']['strip_tags'] = FALSE;
-    $display_options['fields']['changed']['alter']['html'] = FALSE;
-    $display_options['fields']['changed']['hide_empty'] = FALSE;
-    $display_options['fields']['changed']['empty_zero'] = FALSE;
-    $display_options['fields']['changed']['plugin_id'] = 'field';
-    $display_options['fields']['changed']['type'] = 'timestamp';
-    $display_options['fields']['changed']['settings']['date_format'] = 'medium';
-    $display_options['fields']['changed']['settings']['custom_date_format'] = '';
-    $display_options['fields']['changed']['settings']['timezone'] = '';
-
-    /* Field: Media revision: Name */
-    $display_options['fields']['name']['id'] = 'name';
-    $display_options['fields']['name']['table'] = 'media_field_revision';
-    $display_options['fields']['name']['field'] = 'name';
-    $display_options['fields']['name']['entity_type'] = 'media';
-    $display_options['fields']['name']['entity_field'] = 'name';
-    $display_options['fields']['name']['label'] = '';
-    $display_options['fields']['name']['alter']['alter_text'] = 0;
-    $display_options['fields']['name']['alter']['make_link'] = 0;
-    $display_options['fields']['name']['alter']['absolute'] = 0;
-    $display_options['fields']['name']['alter']['trim'] = 0;
-    $display_options['fields']['name']['alter']['word_boundary'] = 0;
-    $display_options['fields']['name']['alter']['ellipsis'] = 0;
-    $display_options['fields']['name']['alter']['strip_tags'] = 0;
-    $display_options['fields']['name']['alter']['html'] = 0;
-    $display_options['fields']['name']['hide_empty'] = 0;
-    $display_options['fields']['name']['empty_zero'] = 0;
-    $display_options['fields']['name']['settings']['link_to_entity'] = 0;
-    $display_options['fields']['name']['plugin_id'] = 'field';
-
-    return $display_options;
-  }
-
-}
diff --git a/src/Tests/BasicTest.php b/src/Tests/BasicTest.php
deleted file mode 100644
index 2589c53..0000000
--- a/src/Tests/BasicTest.php
+++ /dev/null
@@ -1,193 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Tests;
-
-use Drupal\media_entity\Entity\Media;
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Ensures that basic functions work correctly.
- *
- * @group media_entity
- */
-class BasicTest extends WebTestBase {
-
-  use MediaTestTrait;
-
-  /**
-   * The test media bundle.
-   *
-   * @var \Drupal\media_entity\MediaBundleInterface
-   */
-  protected $testBundle;
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = ['system', 'node', 'media_entity'];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    $this->testBundle = $this->drupalCreateMediaBundle();
-  }
-
-  /**
-   * Tests creating a media bundle programmatically.
-   */
-  public function testMediaBundleCreation() {
-    $bundle = $this->drupalCreateMediaBundle();
-    /** @var \Drupal\media_entity\MediaBundleInterface $bundle_storage */
-    $bundle_storage = $this->container->get('entity.manager')->getStorage('media_bundle');
-
-    $bundle_exists = (bool) $bundle_storage->load($bundle->id());
-    $this->assertTrue($bundle_exists, 'The new media bundle has been created in the database.');
-
-    // Test default bundle created from default configuration.
-    $this->container->get('module_installer')->install(['media_entity_test_bundle']);
-    $test_bundle = $bundle_storage->load('test');
-    $this->assertTrue((bool) $test_bundle, 'The media bundle from default configuration has been created in the database.');
-    $this->assertEqual($test_bundle->get('label'), 'Test bundle', 'Correct label detected.');
-    $this->assertEqual($test_bundle->get('description'), 'Test bundle.', 'Correct description detected.');
-    $this->assertEqual($test_bundle->get('type'), 'generic', 'Correct plugin ID detected.');
-    $this->assertEqual($test_bundle->get('type_configuration'), [], 'Correct plugin configuration detected.');
-    $this->assertEqual($test_bundle->get('field_map'), [], 'Correct field map detected.');
-  }
-
-  /**
-   * Tests creating a media entity programmatically.
-   */
-  public function testMediaEntityCreation() {
-    $media = Media::create([
-      'bundle' => $this->testBundle->id(),
-      'name' => 'Unnamed',
-    ]);
-    $media->save();
-
-    $media_not_exist = (bool) Media::load(rand(1000, 9999));
-    $this->assertFalse($media_not_exist, 'The media entity does not exist.');
-
-    $media_exists = (bool) Media::load($media->id());
-    $this->assertTrue($media_exists, 'The new media entity has been created in the database.');
-    $this->assertEqual($media->bundle(), $this->testBundle->id(), 'The media was created with correct bundle.');
-    $this->assertEqual($media->label(), 'Unnamed', 'The media was corrected with correct name.');
-
-    // Test the creation of a media without user-defined label and check if a
-    // default name is provided.
-    $media = Media::create([
-      'bundle' => $this->testBundle->id(),
-    ]);
-    $media->save();
-    $expected_name = 'media' . ':' . $this->testBundle->id() . ':' . $media->uuid();
-    $this->assertEqual($media->bundle(), $this->testBundle->id(), 'The media was created with correct bundle.');
-    $this->assertEqual($media->label(), $expected_name, 'The media was correctly created with a default name.');
-
-  }
-
-  /**
-   * Runs basic tests for media_access function.
-   */
-  public function testMediaAccess() {
-    // Create users and roles.
-    $admin = $this->drupalCreateUser(['administer media'], 'editor');
-    $user = $this->drupalCreateUser([], 'user');
-
-    $permissions = [
-      'view media',
-      'create media',
-      'update media',
-      'update any media',
-      'delete media',
-      'delete any media',
-    ];
-
-    $roles = [];
-    foreach ($permissions as $permission) {
-      $roles[$permission] = $this->createRole([$permission]);
-    }
-
-    // Create media.
-    $media = Media::create([
-      'bundle' => $this->testBundle->id(),
-      'name' => 'Unnamed',
-    ]);
-    $media->save();
-
-    $user_media = Media::create([
-      'bundle' => $this->testBundle->id(),
-      'name' => 'Unnamed',
-      'uid' => $user->id(),
-    ]);
-    $user_media->save();
-
-    // Test 'administer media' permission.
-    $this->drupalLogin($admin);
-    $this->drupalGet('media/' . $user_media->id());
-    $this->assertResponse(200);
-    $this->drupalGet('media/' . $user_media->id() . '/edit');
-    $this->assertResponse(200);
-    $this->drupalGet('media/' . $user_media->id() . '/delete');
-    $this->assertResponse(200);
-
-    // Test 'view media' permission.
-    $this->drupalLogin($user);
-    $this->drupalGet('media/' . $media->id());
-    $this->assertResponse(403);
-
-    $user->addRole($roles['view media']);
-    $user->save();
-
-    $this->drupalGet('media/' . $media->id());
-    $this->assertResponse(200);
-
-    // Test 'create media' permissions.
-    $this->drupalLogin($user);
-    $this->drupalGet('media/add/' . $this->testBundle->id());
-    $this->assertResponse(403);
-
-    $user->addRole($roles['create media']);
-    $user->save();
-
-    $this->drupalGet('media/add/' . $this->testBundle->id());
-    $this->assertResponse(200);
-
-    // Test 'update media' and 'delete media' permissions.
-    $this->drupalGet('media/' . $user_media->id() . '/edit');
-    $this->assertResponse(403);
-
-    $this->drupalGet('media/' . $user_media->id() . '/delete');
-    $this->assertResponse(403);
-
-    $user->addRole($roles['update media']);
-    $user->addRole($roles['delete media']);
-    $user->save();
-
-    $this->drupalGet('media/' . $user_media->id() . '/edit');
-    $this->assertResponse(200);
-
-    $this->drupalGet('media/' . $user_media->id() . '/delete');
-    $this->assertResponse(200);
-
-    // Test 'update any media' and 'delete any media' permissions.
-    $this->drupalGet('media/' . $media->id() . '/edit');
-    $this->assertResponse(403);
-
-    $this->drupalGet('media/' . $media->id() . '/delete');
-    $this->assertResponse(403);
-
-    $user->addRole($roles['update any media']);
-    $user->addRole($roles['delete any media']);
-    $user->save();
-
-    $this->drupalGet('media/' . $media->id() . '/edit');
-    $this->assertResponse(200);
-
-    $this->drupalGet('media/' . $media->id() . '/delete');
-    $this->assertResponse(200);
-  }
-
-}
diff --git a/src/Tests/MediaTestTrait.php b/src/Tests/MediaTestTrait.php
deleted file mode 100644
index f7646aa..0000000
--- a/src/Tests/MediaTestTrait.php
+++ /dev/null
@@ -1,48 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Tests;
-
-use Drupal\media_entity\Entity\MediaBundle;
-
-/**
- * Provides common functionality for media entity test classes.
- */
-trait MediaTestTrait {
-
-  /**
-   * Creates media bundle.
-   *
-   * @param array $values
-   *   The media bundle values.
-   * @param string $type_name
-   *   (optional) The media type provider plugin that is responsible for
-   *   additional logic related to this media).
-   *
-   * @return \Drupal\Core\Entity\EntityInterface
-   *   Returns newly created media bundle.
-   */
-  protected function drupalCreateMediaBundle(array $values = [], $type_name = 'generic') {
-    if (!isset($values['bundle'])) {
-      $id = strtolower($this->randomMachineName());
-    }
-    else {
-      $id = $values['bundle'];
-    }
-    $values += [
-      'id' => $id,
-      'label' => $id,
-      'type' => $type_name,
-      'type_configuration' => [],
-      'field_map' => [],
-      'new_revision' => FALSE,
-    ];
-
-    $bundle = MediaBundle::create($values);
-    $status = $bundle->save();
-
-    $this->assertEqual($status, SAVED_NEW, t('Created media bundle %bundle.', ['%bundle' => $bundle->id()]));
-
-    return $bundle;
-  }
-
-}
diff --git a/src/Tests/MediaUITest.php b/src/Tests/MediaUITest.php
deleted file mode 100644
index 0aeccfa..0000000
--- a/src/Tests/MediaUITest.php
+++ /dev/null
@@ -1,511 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Tests;
-
-use Drupal\Component\Utility\Xss;
-use Drupal\media_entity\Entity\Media;
-use Drupal\media_entity\MediaInterface;
-use Drupal\simpletest\WebTestBase;
-
-/**
- * Ensures that media UI work correctly.
- *
- * @group media_entity
- */
-class MediaUITest extends WebTestBase {
-
-  use MediaTestTrait;
-
-  /**
-   * The test user.
-   *
-   * @var \Drupal\User\UserInterface
-   */
-  protected $adminUser;
-
-  /**
-   * A non-admin test user.
-   *
-   * @var \Drupal\User\UserInterface
-   */
-  protected $nonAdminUser;
-
-  /**
-   * Modules to enable.
-   *
-   * @var array
-   */
-  public static $modules = [
-    'media_entity',
-    'field_ui',
-    'views_ui',
-    'node',
-    'block',
-    'entity',
-  ];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    $this->drupalPlaceBlock('local_actions_block');
-    $this->drupalPlaceBlock('local_tasks_block');
-    $this->adminUser = $this->drupalCreateUser([
-      'administer media',
-      'administer media fields',
-      'administer media form display',
-      'administer media display',
-      'administer media bundles',
-      // Media entity permissions.
-      'view media',
-      'create media',
-      'update media',
-      'update any media',
-      'delete media',
-      'delete any media',
-      'access media overview',
-      // Other permissions.
-      'administer views',
-      'access content overview',
-      'view all revisions',
-    ]);
-    $this->drupalLogin($this->adminUser);
-
-    $this->nonAdminUser = $this->drupalCreateUser([
-      // Media entity permissions.
-      'view media',
-      'create media',
-      'update media',
-      'update any media',
-      'delete media',
-      'delete any media',
-      'access media overview',
-      // Other permissions.
-      'administer views',
-      'access content overview',
-    ]);
-  }
-
-  /**
-   * Tests a media bundle administration.
-   */
-  public function testMediaBundles() {
-    $this->container->get('module_installer')->install(['media_entity_test_type']);
-
-    // Test and create one media bundle.
-    $bundle = $this->createMediaBundle();
-    $bundle_id = $bundle['id'];
-    unset($bundle['id']);
-
-    // Check if all action links exist.
-    $this->assertLinkByHref('admin/structure/media/add');
-    $this->assertLinkByHref('admin/structure/media/manage/' . $bundle_id . '/fields');
-    $this->assertLinkByHref('admin/structure/media/manage/' . $bundle_id . '/form-display');
-    $this->assertLinkByHref('admin/structure/media/manage/' . $bundle_id . '/display');
-
-    // Assert that fields have expected values before editing.
-    $this->drupalGet('admin/structure/media/manage/' . $bundle_id);
-    $this->assertFieldByName('label', $bundle['label'], 'Label field has correct value.');
-    $this->assertFieldByName('description', $bundle['description'], 'Description field has a correct value.');
-    $this->assertFieldByName('type', $bundle['type'], 'Generic plugin is selected.');
-    $this->assertNoFieldChecked('edit-options-new-revision', 'Revision checkbox is not checked.');
-    $this->assertFieldChecked('edit-options-status', 'Status checkbox is checked.');
-    $this->assertNoFieldChecked('edit-options-queue-thumbnail-downloads', 'Queue thumbnail checkbox is not checked.');
-    $this->assertText('Create new revision', 'Revision checkbox label found.');
-    $this->assertText('Automatically create a new revision of media entities. Users with the Administer media permission will be able to override this option.', 'Revision help text found');
-    $this->assertText('Download thumbnails via a queue.', 'Queue thumbnails help text found');
-    $this->assertText('Entities will be automatically published when they are created.', 'Published help text found');
-    $this->assertText("This type provider doesn't need configuration.");
-    $this->assertText('No metadata fields available.');
-    $this->assertText('Media type plugins can provide metadata fields such as title, caption, size information, credits, ... Media entity can automatically save this metadata information to entity fields, which can be configured below. Information will only be mapped if the entity field is empty.');
-
-    // Try to change media type and check if new configuration sub-form appears.
-    $commands = $this->drupalPostAjaxForm(NULL, ['type' => 'test_type'], 'type');
-    // WebTestBase::drupalProcessAjaxResponse() won't correctly execute our ajax
-    // commands so we have to do it manually. Code below is based on the logic
-    // in that function.
-    $content = $this->content;
-    $dom = new \DOMDocument();
-    @$dom->loadHTML($content);
-    $xpath = new \DOMXPath($dom);
-    foreach ($commands as $command) {
-      if ($command['command'] == 'insert' && $command['method'] == 'replaceWith') {
-        $wrapperNode = $xpath->query('//*[@id="' . ltrim($command['selector'], '#') . '"]')->item(0);
-        $newDom = new \DOMDocument();
-        @$newDom->loadHTML('<div>' . $command['data'] . '</div>');
-        $newNode = @$dom->importNode($newDom->documentElement->firstChild->firstChild, TRUE);
-        $wrapperNode->parentNode->replaceChild($newNode, $wrapperNode);
-        $content = $dom->saveHTML();
-        $this->setRawContent($content);
-      }
-    }
-    $this->assertFieldByName('type_configuration[test_type][test_config_value]', 'This is default value.');
-    $this->assertText('Field 1', 'First metadata field found.');
-    $this->assertText('Field 2', 'Second metadata field found.');
-    $this->assertFieldByName('field_mapping[field_1]', '_none', 'First metadata field is not mapped by default.');
-    $this->assertFieldByName('field_mapping[field_2]', '_none', 'Second metadata field is not mapped by default.');
-
-    // Test if the edit machine name button is disabled.
-    $elements = $this->xpath('//*[@id="edit-label-machine-name-suffix"]/span[@class="admin-link"]');
-    $this->assertTrue(empty($elements), 'Edit machine name not found.');
-
-    // Edit and save media bundle form fields with new values.
-    $bundle['label'] = $this->randomMachineName();
-    $bundle['description'] = $this->randomMachineName();
-    $bundle['type'] = 'test_type';
-    $bundle['type_configuration[test_type][test_config_value]'] = 'This is new config value.';
-    $bundle['field_mapping[field_1]'] = 'name';
-    $bundle['options[new_revision]'] = TRUE;
-    $bundle['options[status]'] = FALSE;
-    $bundle['options[queue_thumbnail_downloads]'] = TRUE;
-
-    $this->drupalPostForm(NULL, $bundle, t('Save media bundle'));
-
-    // Test if edit worked and if new field values have been saved as expected.
-    $this->drupalGet('admin/structure/media/manage/' . $bundle_id);
-    $this->assertFieldByName('label', $bundle['label'], 'Label field has correct value.');
-    $this->assertFieldByName('description', $bundle['description'], 'Description field has correct value.');
-    $this->assertFieldByName('type', $bundle['type'], 'Test type is selected.');
-    $this->assertFieldChecked('edit-options-new-revision', 'Revision checkbox is checked.');
-    $this->assertFieldChecked('edit-options-queue-thumbnail-downloads', 'Queue thumbnail checkbox is checked.');
-    $this->assertNoFieldChecked('edit-options-status', 'Status checkbox is not checked.');
-    $this->assertFieldByName('type_configuration[test_type][test_config_value]', 'This is new config value.');
-    $this->assertText('Field 1', 'First metadata field found.');
-    $this->assertText('Field 2', 'Second metadata field found.');
-    $this->assertFieldByName('field_mapping[field_1]', 'name', 'First metadata field is mapped to the name field.');
-    $this->assertFieldByName('field_mapping[field_2]', '_none', 'Second metadata field is not mapped.');
-
-    /** @var \Drupal\media_entity\MediaBundleInterface $loaded_bundle */
-    $loaded_bundle = $this->container->get('entity_type.manager')
-      ->getStorage('media_bundle')
-      ->load($bundle_id);
-    $this->assertEqual($loaded_bundle->id(), $bundle_id, 'Media bundle ID saved correctly.');
-    $this->assertEqual($loaded_bundle->label(), $bundle['label'], 'Media bundle label saved correctly.');
-    $this->assertEqual($loaded_bundle->getDescription(), $bundle['description'], 'Media bundle description saved correctly.');
-    $this->assertEqual($loaded_bundle->getType()->getPluginId(), $bundle['type'], 'Media bundle type saved correctly.');
-    $this->assertEqual($loaded_bundle->getType()->getConfiguration()['test_config_value'], $bundle['type_configuration[test_type][test_config_value]'], 'Media bundle type configuration saved correctly.');
-    $this->assertTrue($loaded_bundle->shouldCreateNewRevision(), 'New revisions are configured to be created.');
-    $this->assertTrue($loaded_bundle->getQueueThumbnailDownloads(), 'Thumbnails are created through queues.');
-    $this->assertFalse($loaded_bundle->getStatus(), 'Default status is unpublished.');
-    $this->assertEqual($loaded_bundle->field_map, ['field_1' => $bundle['field_mapping[field_1]']], 'Field mapping was saved correctly.');
-
-    // Test that a media being created with default status to "FALSE" will be
-    // created unpublished.
-    /** @var MediaInterface $unpublished_media */
-    $unpublished_media = Media::create(['name' => 'unpublished test media', 'bundle' => $loaded_bundle->id()]);
-    $this->assertFalse($unpublished_media->isPublished(), 'Unpublished media correctly created.');
-
-    // Tests media bundle delete form.
-    $this->clickLink(t('Delete'));
-    $this->assertUrl('admin/structure/media/manage/' . $bundle_id . '/delete');
-    $this->drupalPostForm(NULL, [], t('Delete'));
-    $this->assertUrl('admin/structure/media');
-    $this->assertRaw(t('The media bundle %name has been deleted.', ['%name' => $bundle['label']]));
-    $this->assertNoRaw(Xss::filterAdmin($bundle['description']));
-    // Test bundle delete prevention when there is existing media.
-    $bundle2 = $this->createMediaBundle();
-    $media = Media::create(['name' => 'lorem ipsum', 'bundle' => $bundle2['id']]);
-    $media->save();
-    $this->drupalGet('admin/structure/media/manage/' . $bundle2['id']);
-    $this->clickLink(t('Delete'));
-    $this->assertUrl('admin/structure/media/manage/' . $bundle2['id'] . '/delete');
-    $this->assertNoFieldById('edit-submit');
-    $this->assertRaw(t('%type is used by 1 piece of content on your site. You can not remove this content type until you have removed all of the %type content.', ['%type' => $bundle2['label']]));
-  }
-
-  /**
-   * Tests the media actions (add/edit/delete).
-   */
-  public function testMediaWithOnlyOneBundle() {
-    /** @var \Drupal\media_entity\MediaBundleInterface $bundle */
-    $bundle = $this->drupalCreateMediaBundle();
-
-    // Assert that media item list is empty.
-    $this->drupalGet('admin/content/media');
-    $this->assertResponse(200);
-    $this->assertText('No content available.');
-
-    $this->drupalGet('media/add');
-    $this->assertResponse(200);
-    $this->assertUrl('media/add/' . $bundle->id());
-    $this->assertFieldChecked('edit-revision', 'New revision should always be created when a new entity is being created.');
-
-    // Tests media item add form.
-    $edit = [
-      'name[0][value]' => $this->randomMachineName(),
-      'revision_log' => $this->randomString(),
-    ];
-    $this->drupalPostForm('media/add', $edit, t('Save and publish'));
-    $this->assertTitle($edit['name[0][value]'] . ' | Drupal');
-    $media_id = $this->container->get('entity.query')->get('media')->execute();
-    $media_id = reset($media_id);
-    /** @var \Drupal\media_entity\MediaInterface $media */
-    $media = $this->container->get('entity_type.manager')
-      ->getStorage('media')
-      ->loadUnchanged($media_id);
-    $this->assertEqual($media->getRevisionLogMessage(), $edit['revision_log'], 'Revision log was saved.');
-
-    // Test if the media list contains exactly 1 media bundle.
-    $this->drupalGet('admin/content/media');
-    $this->assertResponse(200);
-    $this->assertText($edit['name[0][value]']);
-
-    // Tests media edit form.
-    $this->drupalGet('media/' . $media_id . '/edit');
-    $this->assertNoFieldChecked('edit-revision', 'New revisions are disabled by default.');
-    $edit['name[0][value]'] = $this->randomMachineName();
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
-    $this->assertTitle($edit['name[0][value]'] . ' | Drupal');
-
-    // Assert that the media list updates after an edit.
-    $this->drupalGet('admin/content/media');
-    $this->assertResponse(200);
-    $this->assertText($edit['name[0][value]']);
-
-    // Test that there is no empty vertical tabs element, if the container is
-    // empty (see #2750697).
-    // Make the "Publisher ID" and "Created" fields hidden.
-    $edit = [
-      'fields[created][parent]' => 'hidden',
-      'fields[uid][parent]' => 'hidden',
-    ];
-    $this->drupalPostForm('/admin/structure/media/manage/' . $bundle->id . '/form-display', $edit, t('Save'));
-    // Assure we are testing with a user without permission to manage revisions.
-    $this->drupalLogout();
-    $this->drupalLogin($this->nonAdminUser);
-    // Check the container is not present.
-    $this->drupalGet('media/' . $media_id . '/edit');
-    // An empty tab container would look like this.
-    $raw_html = '<div data-drupal-selector="edit-advanced" data-vertical-tabs-panes><input class="vertical-tabs__active-tab" data-drupal-selector="edit-advanced-active-tab" type="hidden" name="advanced__active_tab" value="" />' . "\n" . '</div>';
-    $this->assertNoRaw($raw_html);
-    // Continue testing as admin.
-    $this->drupalLogout();
-    $this->drupalLogin($this->adminUser);
-
-    // Enable revisions by default.
-    $bundle->setNewRevision(TRUE);
-    $bundle->save();
-    $this->drupalGet('media/' . $media_id . '/edit');
-    $this->assertFieldChecked('edit-revision', 'New revisions are disabled by default.');
-    $edit = [
-      'name[0][value]' => $this->randomMachineName(),
-      'revision_log' => $this->randomString(),
-    ];
-    $this->drupalPostForm(NULL, $edit, t('Save and keep published'));
-    $this->assertTitle($edit['name[0][value]'] . ' | Drupal');
-    /** @var \Drupal\media_entity\MediaInterface $media */
-    $media = $this->container->get('entity_type.manager')
-      ->getStorage('media')
-      ->loadUnchanged($media_id);
-    $this->assertEqual($media->getRevisionLogMessage(), $edit['revision_log'], 'Revision log was saved.');
-
-    // Tests media delete form.
-    $this->drupalPostForm('media/' . $media_id . '/delete', [], t('Delete'));
-    $media_id = \Drupal::entityQuery('media')->execute();
-    $this->assertFalse($media_id);
-
-    // Assert that the media list is empty after deleting the media item.
-    $this->drupalGet('admin/content/media');
-    $this->assertResponse(200);
-    $this->assertNoText($edit['name[0][value]']);
-    $this->assertText('No content available.');
-  }
-
-  /**
-   * Tests the views wizards provided by the media module.
-   */
-  public function testMediaViewsWizard() {
-    $bundle = $this->drupalCreateMediaBundle();
-    $data = [
-      'name' => $this->randomMachineName(),
-      'bundle' => $bundle->id(),
-      'type' => 'Unknown',
-      'uid' => $this->adminUser->id(),
-      'langcode' => \Drupal::languageManager()->getDefaultLanguage()->getId(),
-      'status' => Media::PUBLISHED,
-    ];
-    $media = Media::create($data);
-    $media->save();
-
-    // Test the Media wizard.
-    $this->drupalPostForm('admin/structure/views/add', [
-      'label' => 'media view',
-      'id' => 'media_test',
-      'show[wizard_key]' => 'media',
-      'page[create]' => 1,
-      'page[title]' => 'media_test',
-      'page[path]' => 'media_test',
-    ], t('Save and edit'));
-
-    $this->drupalGet('media_test');
-    $this->assertText($data['name']);
-
-    user_role_revoke_permissions('anonymous', ['access content']);
-    $this->drupalLogout();
-    $this->drupalGet('media_test');
-    $this->assertResponse(403);
-
-    $this->drupalLogin($this->adminUser);
-
-    // Test the MediaRevision wizard.
-    $this->drupalPostForm('admin/structure/views/add', [
-      'label' => 'media revision view',
-      'id' => 'media_revision',
-      'show[wizard_key]' => 'media_revision',
-      'page[create]' => 1,
-      'page[title]' => 'media_revision',
-      'page[path]' => 'media_revision',
-    ], t('Save and edit'));
-
-    $this->drupalGet('media_revision');
-    // Check only for the label of the changed field as we want to only test
-    // if the field is present and not its value.
-    $this->assertText($data['name']);
-
-    user_role_revoke_permissions('anonymous', ['view revisions']);
-    $this->drupalLogout();
-    $this->drupalGet('media_revision');
-    $this->assertResponse(403);
-  }
-
-  /**
-   * Tests the "media/add" and "admin/content/media" pages.
-   *
-   * Tests if the "media/add" page gives you a selecting option if there are
-   * multiple media bundles available.
-   */
-  public function testMediaWithMultipleBundles() {
-    // Test access to media overview page.
-    $this->drupalLogout();
-    $this->drupalGet('admin/content/media');
-    $this->assertResponse(403);
-
-    $this->drupalLogin($this->adminUser);
-    $this->drupalGet('admin/content');
-
-    // Test there is a media tab in the menu.
-    $this->clickLink('Media');
-    $this->assertResponse(200);
-    $this->assertText('No content available.');
-
-    // Tests and creates the first media bundle.
-    $first_media_bundle = $this->createMediaBundle();
-
-    // Test and create a second media bundle.
-    $second_media_bundle = $this->createMediaBundle();
-
-    // Test if media/add displays two media bundle options.
-    $this->drupalGet('media/add');
-
-    // Checks for the first media bundle.
-    $this->assertRaw($first_media_bundle['label']);
-    $this->assertRaw(Xss::filterAdmin($first_media_bundle['description']));
-
-    // Checks for the second media bundle.
-    $this->assertRaw($second_media_bundle['label']);
-    $this->assertRaw(Xss::filterAdmin($second_media_bundle['description']));
-
-    // Continue testing media bundle filter.
-    $this->doTestMediaBundleFilter($first_media_bundle, $second_media_bundle);
-  }
-
-  /**
-   * Creates and tests a new media bundle.
-   *
-   * @return array
-   *   Returns the media bundle fields.
-   */
-  public function createMediaBundle() {
-    // Generates and holds all media bundle fields.
-    $name = $this->randomMachineName();
-    $edit = [
-      'id' => strtolower($name),
-      'label' => $name,
-      'type' => 'generic',
-      'description' => $this->randomMachineName(),
-    ];
-
-    // Create new media bundle.
-    $this->drupalPostForm('admin/structure/media/add', $edit, t('Save media bundle'));
-    $this->assertText('The media bundle ' . $name . ' has been added.');
-
-    // Check if media bundle is successfully created.
-    $this->drupalGet('admin/structure/media');
-    $this->assertResponse(200);
-    $this->assertRaw($edit['label']);
-    $this->assertRaw(Xss::filterAdmin($edit['description']));
-
-    return $edit;
-  }
-
-  /**
-   * Creates a media item in the media bundle that is passed along.
-   *
-   * @param array $media_bundle
-   *   The media bundle the media item should be assigned to.
-   *
-   * @return array
-   *   Returns the
-   */
-  public function createMediaItem($media_bundle) {
-    // Define the media item name.
-    $name = $this->randomMachineName();
-    $edit = [
-      'name[0][value]' => $name,
-    ];
-    // Save it and retrieve new media item ID, then return all information.
-    $this->drupalPostForm('media/add/' . $media_bundle['id'], $edit, t('Save and publish'));
-    $this->assertTitle($edit['name[0][value]'] . ' | Drupal');
-    $media_id = \Drupal::entityQuery('media')->execute();
-    $media_id = reset($media_id);
-    $edit['id'] = $media_id;
-
-    return $edit;
-  }
-
-  /**
-   * Tests the media list filter functionality.
-   */
-  public function doTestMediaBundleFilter($first_media_bundle, $second_media_bundle) {
-    // Assert that the list is not empty and contains at least 2 media items
-    // with each a different media bundle.
-    (is_array($first_media_bundle) && is_array($second_media_bundle) ?: $this->assertTrue(FALSE));
-
-    $first_media_item = $this->createMediaItem($first_media_bundle);
-    $second_media_item = $this->createMediaItem($second_media_bundle);
-
-    // Go to media item list.
-    $this->drupalGet('admin/content/media');
-    $this->assertResponse(200);
-    $this->assertLink('Add media');
-
-    // Assert that all available media items are in the list.
-    $this->assertText($first_media_item['name[0][value]']);
-    $this->assertText($first_media_bundle['label']);
-    $this->assertText($second_media_item['name[0][value]']);
-    $this->assertText($second_media_bundle['label']);
-
-    // Filter for each bundle and assert that the list has been updated.
-    $this->drupalGet('admin/content/media', ['query' => ['provider' => $first_media_bundle['id']]]);
-    $this->assertResponse(200);
-    $this->assertText($first_media_item['name[0][value]']);
-    $this->assertText($first_media_bundle['label']);
-    $this->assertNoText($second_media_item['name[0][value]']);
-
-    $this->drupalGet('admin/content/media', ['query' => ['provider' => $second_media_bundle['id']]]);
-    $this->assertResponse(200);
-    $this->assertNoText($first_media_item['name[0][value]']);
-    $this->assertText($second_media_item['name[0][value]']);
-    $this->assertText($second_media_bundle['label']);
-
-    // Filter all and check for all items again.
-    $this->drupalGet('admin/content/media', ['query' => ['provider' => 'All']]);
-    $this->assertResponse(200);
-    $this->assertText($first_media_item['name[0][value]']);
-    $this->assertText($first_media_bundle['label']);
-    $this->assertText($second_media_item['name[0][value]']);
-    $this->assertText($second_media_bundle['label']);
-  }
-
-}
diff --git a/src/Tests/Views/BulkFormTest.php b/src/Tests/Views/BulkFormTest.php
deleted file mode 100644
index 3349dfb..0000000
--- a/src/Tests/Views/BulkFormTest.php
+++ /dev/null
@@ -1,171 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Tests\Views;
-
-use Drupal\media_entity\Tests\MediaTestTrait;
-use Drupal\media_entity\Entity\Media;
-use Drupal\views\Tests\ViewTestBase;
-use Drupal\views\Tests\ViewTestData;
-use Drupal\views\Views;
-
-/**
- * Tests a media bulk form.
- *
- * @group media_entity
- */
-class BulkFormTest extends ViewTestBase {
-
-  use MediaTestTrait;
-
-  /**
-   * Modules to be enabled.
-   *
-   * @var array
-   */
-  public static $modules = ['media_entity_test_views'];
-
-  /**
-   * Views used by this test.
-   *
-   * @var array
-   */
-  public static $testViews = ['test_media_entity_bulk_form'];
-
-  /**
-   * The test media bundle.
-   *
-   * @var \Drupal\media_entity\MediaBundleInterface
-   */
-  protected $testBundle;
-
-  /**
-   * The test media entities.
-   *
-   * @var \Drupal\media_entity\MediaInterface[]
-   */
-  protected $mediaEntities;
-
-  /**
-   * The test user.
-   *
-   * @var \Drupal\User\UserInterface
-   */
-  protected $adminUser;
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp($import_test_views = TRUE) {
-    parent::setUp($import_test_views);
-
-    if ($import_test_views) {
-      ViewTestData::createTestViews(get_class($this), ['media_entity_test_views']);
-    }
-
-    $this->testBundle = $this->drupalCreateMediaBundle();
-
-    // Create some test media entities.
-    $this->mediaEntities = [];
-    for ($i = 1; $i <= 5; $i++) {
-      $media = Media::create([
-        'bundle' => $this->testBundle->id(),
-        'name' => $this->randomMachineName(),
-      ]);
-      $media->save();
-
-      $this->mediaEntities[] = $media;
-    }
-
-    // Check that all created entities are present in the test view.
-    $view = Views::getView('test_media_entity_bulk_form');
-    $view->execute();
-    $this->assertEqual(count($view->result), 5, 'All created media entities are present in the view.');
-
-    $this->adminUser = $this->drupalCreateUser([
-      'view media',
-      'update any media',
-      'delete any media',
-    ]);
-    $this->drupalLogin($this->adminUser);
-
-    // Check the operations are accessible to the logged in user.
-    $this->drupalGet('test-media-entity-bulk-form');
-    $elements = $this->xpath('//select[@id="edit-action"]//option');
-    // Current available actions: Delete, Save, Publish, Unpublish.
-    $this->assertIdentical(count($elements), 4, 'All media operations are found.');
-  }
-
-  /**
-   * Tests the media bulk form.
-   */
-  public function testBulkForm() {
-
-    // Test unpublishing in bulk.
-    $edit = [
-      'media_bulk_form[0]' => TRUE,
-      'media_bulk_form[1]' => TRUE,
-      'media_bulk_form[2]' => TRUE,
-      'action' => 'media_unpublish_action',
-    ];
-    $this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
-    $this->assertText("Unpublish media was applied to 3 items");
-    $media1_status = $this->loadMedia(1)->isPublished();
-    $this->assertEqual(FALSE, $media1_status, 'First media entity was unpublished correctly.');
-    $media2_status = $this->loadMedia(2)->isPublished();
-    $this->assertEqual(FALSE, $media2_status, 'Second media entity was unpublished correctly.');
-    $media3_status = $this->loadMedia(3)->isPublished();
-    $this->assertEqual(FALSE, $media3_status, 'Third media entity was unpublished correctly.');
-
-    // Test publishing in bulk.
-    $edit = [
-      'media_bulk_form[0]' => TRUE,
-      'media_bulk_form[1]' => TRUE,
-      'action' => 'media_publish_action',
-    ];
-    $this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
-    $this->assertText("Publish media was applied to 2 items");
-    $media1_status = $this->loadMedia(1)->isPublished();
-    $this->assertEqual(TRUE, $media1_status, 'First media entity was published back correctly.');
-    $media2_status = $this->loadMedia(2)->isPublished();
-    $this->assertEqual(TRUE, $media2_status, 'Second media entity was published back correctly.');
-
-    // Test deletion in bulk.
-    $edit = [
-      'media_bulk_form[0]' => TRUE,
-      'media_bulk_form[1]' => TRUE,
-      'action' => 'media_delete_action',
-    ];
-    $this->drupalPostForm(NULL, $edit, t('Apply to selected items'));
-
-    $this->assertText("Are you sure you want to delete these items?");
-    $label1 = $this->loadMedia(1)->label();
-    $this->assertRaw('<li>' . $label1 . '</li>');
-    $label2 = $this->loadMedia(2)->label();
-    $this->assertRaw('<li>' . $label2 . '</li>');
-
-    $this->drupalPostForm(NULL, [], t('Delete'));
-
-    $media = $this->loadMedia(1);
-    $this->assertNull($media, 'Media 1 has been correctly deleted.');
-    $media = $this->loadMedia(2);
-    $this->assertNull($media, 'Media 2 has been correctly deleted.');
-
-    $this->assertText('Deleted 2 media entities.');
-  }
-
-  /**
-   * Load the specified media from the storage.
-   *
-   * @param int $id
-   *   The media identifier.
-   *
-   * @return \Drupal\media_entity\MediaInterface
-   *   The loaded media entity.
-   */
-  protected function loadMedia($id) {
-    /** @var \Drupal\media_entity\MediaStorage $storage */
-    $storage = $this->container->get('entity.manager')->getStorage('media');
-    return $storage->loadUnchanged($id);
-  }
-
-}
diff --git a/src/Tests/Views/WizardTest.php b/src/Tests/Views/WizardTest.php
deleted file mode 100644
index ee91ccd..0000000
--- a/src/Tests/Views/WizardTest.php
+++ /dev/null
@@ -1,94 +0,0 @@
-<?php
-
-namespace Drupal\media_entity\Tests\Views;
-
-use Drupal\views\Views;
-use Drupal\views\Tests\Wizard\WizardTestBase;
-
-/**
- * Tests the media entity type integration into the wizard.
- *
- * @group media_entity
- * @see \Drupal\media_entity\Plugin\views\wizard\Media
- * @see \Drupal\media_entity\Plugin\views\wizard\MediaRevision
- */
-class WizardTest extends WizardTestBase {
-
-  /**
-   * Modules to install.
-   *
-   * @var array
-   */
-  public static $modules = ['media_entity'];
-
-  /**
-   * Tests adding a view of media.
-   */
-  public function testMediaWizard() {
-    $view = [];
-    $view['label'] = $this->randomMachineName(16);
-    $view['id'] = strtolower($this->randomMachineName(16));
-    $view['show[wizard_key]'] = 'media';
-    $view['page[create]'] = TRUE;
-    $view['page[path]'] = $this->randomMachineName(16);
-
-    // Just triggering the saving should automatically choose a proper row
-    // plugin.
-    $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit'));
-    $this->assertUrl('admin/structure/views/view/' . $view['id'], [], 'Make sure the view saving was successful and the browser got redirected to the edit page.');
-
-    $user = $this->drupalCreateUser(['access content']);
-    $this->drupalLogin($user);
-
-    $view = Views::getView($view['id']);
-    $view->initHandlers();
-    $row = $view->display_handler->getOption('row');
-    $this->assertEqual($row['type'], 'fields');
-
-    // Check for the default filters.
-    $this->assertEqual($view->filter['status']->table, 'media_field_data');
-    $this->assertEqual($view->filter['status']->field, 'status');
-    $this->assertTrue($view->filter['status']->value);
-
-    // Check for the default fields.
-    $this->assertEqual($view->field['name']->table, 'media_field_data');
-    $this->assertEqual($view->field['name']->field, 'name');
-  }
-
-  /**
-   * Tests adding a view of media revisions.
-   */
-  public function testMediaRevisionWizard() {
-    $view = [];
-    $view['label'] = $this->randomMachineName(16);
-    $view['id'] = strtolower($this->randomMachineName(16));
-    $view['show[wizard_key]'] = 'media_revision';
-    $view['page[create]'] = TRUE;
-    $view['page[path]'] = $this->randomMachineName(16);
-
-    // Just triggering the saving should automatically choose a proper row
-    // plugin.
-    $this->drupalPostForm('admin/structure/views/add', $view, t('Save and edit'));
-    $this->assertUrl('admin/structure/views/view/' . $view['id'], [], 'Make sure the view saving was successful and the browser got redirected to the edit page.');
-
-    $user = $this->drupalCreateUser(['view all revisions']);
-    $this->drupalLogin($user);
-
-    $view = Views::getView($view['id']);
-    $view->initHandlers();
-    $row = $view->display_handler->getOption('row');
-    $this->assertEqual($row['type'], 'fields');
-
-    // Check for the default filters.
-    $this->assertEqual($view->filter['status']->table, 'media_field_revision');
-    $this->assertEqual($view->filter['status']->field, 'status');
-    $this->assertTrue($view->filter['status']->value);
-
-    // Check for the default fields.
-    $this->assertEqual($view->field['name']->table, 'media_field_revision');
-    $this->assertEqual($view->field['name']->field, 'name');
-    $this->assertEqual($view->field['changed']->table, 'media_field_revision');
-    $this->assertEqual($view->field['changed']->field, 'changed');
-  }
-
-}
diff --git a/templates/media.html.twig b/templates/media.html.twig
deleted file mode 100644
index 9d43771..0000000
--- a/templates/media.html.twig
+++ /dev/null
@@ -1,19 +0,0 @@
-{#
-/**
- * @file
- * Default theme implementation to present a media entity.
- *
- * Available variables:
- * - name: Name of the media.
- * - content: Media content.
- *
- * @see template_preprocess_media()
- *
- * @ingroup themeable
- */
-#}
-<article{{ attributes }}>
-  {% if content %}
-    {{ content }}
-  {% endif %}
-</article>
diff --git a/tests/fixtures/drupal-8.4.0-media-entity.php.gz b/tests/fixtures/drupal-8.4.0-media-entity.php.gz
new file mode 100644
index 0000000..a99de11
Binary files /dev/null and b/tests/fixtures/drupal-8.4.0-media-entity.php.gz differ
diff --git a/tests/modules/media_entity_test_bundle/config/install/media_entity.bundle.test.yml b/tests/modules/media_entity_test_bundle/config/install/media_entity.bundle.test.yml
deleted file mode 100644
index c0a0f70..0000000
--- a/tests/modules/media_entity_test_bundle/config/install/media_entity.bundle.test.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-id: test
-label: 'Test bundle'
-description: 'Test bundle.'
-type: generic
-type_configuration: {  }
-status: true
-langcode: en
-dependencies: {  }
-field_map: {  }
diff --git a/tests/modules/media_entity_test_bundle/media_entity_test_bundle.info.yml b/tests/modules/media_entity_test_bundle/media_entity_test_bundle.info.yml
deleted file mode 100644
index 9969dad..0000000
--- a/tests/modules/media_entity_test_bundle/media_entity_test_bundle.info.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: 'Media entity test bundle'
-type: module
-description: 'Provides test bundle for media entity.'
-core: 8.x
-package: Testing
-version: VERSION
diff --git a/tests/modules/media_entity_test_type/config/schema/media_entity_test_type.schema.yml b/tests/modules/media_entity_test_type/config/schema/media_entity_test_type.schema.yml
deleted file mode 100644
index 6ff7e14..0000000
--- a/tests/modules/media_entity_test_type/config/schema/media_entity_test_type.schema.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-media_entity.bundle.type.test_type:
-  type: mapping
-  label: 'Test type configuration'
-  mapping:
-    test_config_value:
-      type: string
-      label: 'Test config value'
diff --git a/tests/modules/media_entity_test_type/media_entity_test_type.info.yml b/tests/modules/media_entity_test_type/media_entity_test_type.info.yml
deleted file mode 100644
index ed82c4c..0000000
--- a/tests/modules/media_entity_test_type/media_entity_test_type.info.yml
+++ /dev/null
@@ -1,6 +0,0 @@
-name: 'Test media type'
-type: module
-description: 'Provides test media type plugin to test configuration forms.'
-core: 8.x
-package: Testing
-version: VERSION
diff --git a/tests/modules/media_entity_test_type/src/Plugin/MediaEntity/Type/TestType.php b/tests/modules/media_entity_test_type/src/Plugin/MediaEntity/Type/TestType.php
deleted file mode 100644
index 60d68a0..0000000
--- a/tests/modules/media_entity_test_type/src/Plugin/MediaEntity/Type/TestType.php
+++ /dev/null
@@ -1,51 +0,0 @@
-<?php
-
-namespace Drupal\media_entity_test_type\Plugin\MediaEntity\Type;
-
-use Drupal\Core\Form\FormStateInterface;
-use Drupal\media_entity\Plugin\MediaEntity\Type\Generic;
-
-/**
- * Provides generic media type.
- *
- * @MediaType(
- *   id = "test_type",
- *   label = @Translation("Test type"),
- *   description = @Translation("Test media type.")
- * )
- */
-class TestType extends Generic {
-
-  /**
-   * {@inheritdoc}
-   */
-  public function providedFields() {
-    return [
-      'field_1' => $this->t('Field 1'),
-      'field_2' => $this->t('Field 2'),
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function defaultConfiguration() {
-    return [
-      'test_config_value' => 'This is default value.',
-    ];
-  }
-
-  /**
-   * {@inheritdoc}
-   */
-  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
-    $form['test_config_value'] = [
-      '#type' => 'textfield',
-      '#title' => $this->t('Test config value'),
-      '#default_value' => empty($this->configuration['test_config_value']) ? NULL : $this->configuration['test_config_value'],
-    ];
-
-    return $form;
-  }
-
-}
diff --git a/tests/modules/media_entity_test_views/media_entity_test_views.info.yml b/tests/modules/media_entity_test_views/media_entity_test_views.info.yml
deleted file mode 100644
index 3c93c11..0000000
--- a/tests/modules/media_entity_test_views/media_entity_test_views.info.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-name: 'Media Entity test views'
-type: module
-description: 'Provides default views for views media entity tests.'
-package: Testing
-version: VERSION
-core: 8.x
-dependencies:
-  - media_entity
-  - views
diff --git a/tests/modules/media_entity_test_views/test_views/views.view.test_media_entity_bulk_form.yml b/tests/modules/media_entity_test_views/test_views/views.view.test_media_entity_bulk_form.yml
deleted file mode 100644
index 5c068b6..0000000
--- a/tests/modules/media_entity_test_views/test_views/views.view.test_media_entity_bulk_form.yml
+++ /dev/null
@@ -1,154 +0,0 @@
-langcode: en
-status: true
-dependencies:
-  module:
-    - media_entity
-    - user
-id: test_media_entity_bulk_form
-label: ''
-module: views
-description: ''
-tag: ''
-base_table: media_field_data
-base_field: mid
-core: 8.x
-display:
-  default:
-    display_plugin: default
-    id: default
-    display_title: Master
-    position: 0
-    display_options:
-      style:
-        type: table
-      row:
-        type: fields
-      fields:
-        media_bulk_form:
-          id: media_bulk_form
-          table: media
-          field: media_bulk_form
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: false
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          action_title: 'With selection'
-          include_exclude: exclude
-          selected_actions: {  }
-          entity_type: media
-          plugin_id: media_bulk_form
-        name:
-          id: name
-          table: media_field_data
-          field: name
-          entity_type: media
-          entity_field: media
-          hide_empty: false
-          empty_zero: false
-          settings:
-            link_to_entity: false
-          plugin_id: field
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: 'Media name'
-          exclude: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_alter_empty: true
-          click_sort_column: value
-          type: string
-          group_column: value
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-        status:
-          id: status
-          table: media_field_data
-          field: status
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: Status
-          exclude: false
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: true
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: true
-          empty: ''
-          hide_empty: false
-          empty_zero: false
-          hide_alter_empty: true
-          click_sort_column: value
-          type: boolean
-          settings:
-            format: custom
-            format_custom_true: Published
-            format_custom_false: Unpublished
-          group_column: value
-          group_columns: {  }
-          group_rows: true
-          delta_limit: 0
-          delta_offset: 0
-          delta_reversed: false
-          delta_first_last: false
-          multi_type: separator
-          separator: ', '
-          field_api_classes: false
-          entity_type: media
-          entity_field: status
-          plugin_id: field
-      sorts:
-        mid:
-          id: mid
-          table: media_field_data
-          field: mid
-          relationship: none
-          group_type: group
-          admin_label: ''
-          order: ASC
-          exposed: false
-          expose:
-            label: ''
-          entity_type: media
-          entity_field: mid
-          plugin_id: standard
-      title: 'Entity bulk form test view'
-      header: {  }
-      footer: {  }
-      empty: {  }
-      relationships: {  }
-      arguments: {  }
-      display_extenders: {  }
-  page_1:
-    display_plugin: page
-    id: page_1
-    display_title: Page
-    position: 1
-    display_options:
-      path: test-media-entity-bulk-form
diff --git a/tests/src/Functional/CoreMediaUpdatePathTest.php b/tests/src/Functional/CoreMediaUpdatePathTest.php
new file mode 100644
index 0000000..221c985
--- /dev/null
+++ b/tests/src/Functional/CoreMediaUpdatePathTest.php
@@ -0,0 +1,148 @@
+<?php
+
+namespace Drupal\Tests\media_entity\Functional;
+
+use Drupal\Core\Config\Entity\Query\QueryFactory;
+use Drupal\FunctionalTests\Update\UpdatePathTestBase;
+
+/**
+ * @group media_entity
+ */
+class CoreMediaUpdatePathTest extends UpdatePathTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setDatabaseDumpFiles() {
+    $this->databaseDumpFiles = [
+      __DIR__ . '/../../fixtures/drupal-8.4.0-media-entity.php.gz',
+    ];
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+    parent::setUp();
+
+    // All this can be removed when #2877383 lands.
+    $this->config('system.action.media_delete_action')->delete();
+    $this->config('system.action.media_publish_action')->delete();
+    $this->config('system.action.media_save_action')->delete();
+    $this->config('system.action.media_unpublish_action')->delete();
+
+    $this->config('views.view.media')
+      ->clear('display.default.display_options.fields.media_bulk_form')
+      ->save();
+  }
+
+  public function testUpdatePath() {
+    $icon_base_uri = $this->config('media_entity.settings')->get('icon_base');
+
+    $this->runUpdates();
+    $assert = $this->assertSession();
+
+    // As with all translatable, versionable content entity types, media
+    // entities should have the revision_translation_affected base field.
+    // This may have been created during the update path by system_update_8402,
+    // so we should check for it here.
+    /** @var \Drupal\Core\Entity\EntityFieldManagerInterface $field_manager */
+    $field_manager = $this->container->get('entity_field.manager');
+    $this->assertArrayHasKey('revision_translation_affected', $field_manager->getBaseFieldDefinitions('media'));
+    $field_manager->clearCachedFieldDefinitions();
+
+    $this->drupalLogin($this->rootUser);
+    $this->drupalGet('/admin/modules');
+    $assert->checkboxNotChecked('modules[media_entity_document][enable]');
+    $assert->checkboxNotChecked('modules[media_entity_image][enable]');
+    $assert->checkboxChecked('modules[media_entity_generic][enable]');
+    // Media is not currently displayed on the Modules page.
+    $this->assertArrayHasKey('media', $this->config('core.extension')->get('module'));
+
+    $this->drupalGet('/admin/structure/media/manage/file');
+    $assert->statusCodeEquals(200);
+    $assert->fieldValueEquals('source', 'file');
+    $assert->pageTextContains('File field is used to store the essential information');
+
+    $this->drupalGet('/admin/structure/media/manage/image');
+    $assert->statusCodeEquals(200);
+    $assert->fieldValueEquals('source', 'image');
+    $assert->pageTextContains('Image field is used to store the essential information');
+
+    $this->drupalGet('/admin/structure/media/manage/generic');
+    $assert->statusCodeEquals(200);
+    $assert->fieldValueEquals('source', 'generic');
+    $assert->pageTextContains('Generic media field is used to store the essential information');
+
+    $this->assertFrontPageMedia('Image 3', 'main img');
+    $this->assertFrontPageMedia('Generic 1', 'main img[src *= "/media-icons/generic/generic.png"]');
+    $this->assertFrontPageMedia('File 2', 'main img[src *= "/media-icons/generic/document.png"]');
+    $this->assertFrontPageMedia('File 3', 'main img[src *= "/media-icons/generic/document.png"]');
+    $this->assertFrontPageMedia('Image 1', 'main img');
+    $this->assertFrontPageMedia('Generic 3', 'main img[src *= "/media-icons/generic/generic.png"]');
+
+    // Assert that Media Entity's config is migrated.
+    $this->assertTrue($this->config('media_entity.settings')->isNew());
+    $this->assertEquals($icon_base_uri, $this->config('media.settings')->get('icon_base_uri'));
+    $this->assertEmpty(
+      $this->container->get('config.factory')->listAll('media_entity.bundle')
+    );
+
+    $this->activateModule();
+    /** @var \Drupal\Core\Entity\EntityStorageInterface $storage */
+    $storage = $this->container
+      ->get('entity_type.manager')
+      ->getStorage('media_type');
+
+    foreach (['file', 'image', 'generic'] as $type) {
+      $config = $this->config("media.type.$type");
+      $this->assertFalse($config->isNew());
+      $this->assertNull($config->get('type'));
+      $this->assertNull($config->get('type_configuration'));
+      $this->assertInternalType('string', $config->get('source'));
+      $this->assertInternalType('array', $config->get('source_configuration'));
+      $this->assertInternalType('string', $config->get('source_configuration.source_field'));
+
+      // Ensure that the media type can be queried by UUID.
+      $uuid = $config->get('uuid');
+      $this->assertNotEmpty($uuid);
+      $result = $storage->getQuery()->condition('uuid', $uuid)->execute();
+      $this->assertEquals($result[$type], $type);
+    }
+
+    // The UUID map for legacy media bundles should be cleared out.
+    $old_uuid_map = $this->container
+      ->get('keyvalue')
+      ->get(QueryFactory::CONFIG_LOOKUP_PREFIX . 'media_bundle')
+      ->getAll();
+    $this->assertEmpty($old_uuid_map);
+  }
+
+  protected function assertFrontPageMedia($link, $assert_selectors) {
+    $this->drupalGet('<front>');
+    $this->clickLink($link);
+
+    $assert = $this->assertSession();
+    foreach ((array) $assert_selectors as $selector) {
+      $assert->elementExists('css', $selector);
+    }
+  }
+
+  /**
+   * Activates the Media module in PHPUnit's memory space.
+   */
+  protected function activateModule() {
+    $this->container
+      ->get('module_handler')
+      ->addModule('media', 'core/modules/media');
+
+    /** @var \ArrayObject $namespaces */
+    $namespaces = $this->container->get('container.namespaces');
+    $namespaces['Drupal\\media'] = 'core/modules/media/src';
+
+    $this->container
+      ->get('entity_type.manager')
+      ->clearCachedDefinitions();
+  }
+
+}
diff --git a/tests/src/Kernel/TokensTest.php b/tests/src/Kernel/TokensTest.php
deleted file mode 100644
index 7fb843e..0000000
--- a/tests/src/Kernel/TokensTest.php
+++ /dev/null
@@ -1,81 +0,0 @@
-<?php
-
-namespace Drupal\Tests\media_entity\Kernel;
-
-use Drupal\Core\Language\Language;
-use Drupal\KernelTests\Core\Entity\EntityKernelTestBase;
-use Drupal\media_entity\Entity\Media;
-use Drupal\media_entity\Entity\MediaBundle;
-
-/**
- * Tests token handling.
- *
- * @requires module token
- * @requires module entity
- *
- * @group media_entity
- */
-class TokensTest extends EntityKernelTestBase {
-
-  /**
-   * Modules to install.
-   *
-   * @var array
-   */
-  public static $modules = [
-    'media_entity',
-    'path',
-    'file',
-    'image',
-    'entity',
-    'datetime',
-    'language',
-  ];
-
-  /**
-   * {@inheritdoc}
-   */
-  protected function setUp() {
-    parent::setUp();
-    $this->installEntitySchema('file');
-    $this->installSchema('file', 'file_usage');
-    $this->installEntitySchema('media');
-    $this->installConfig(['language', 'datetime', 'field', 'system']);
-  }
-
-  /**
-   * Tests some of the tokens provided by media_entity.
-   */
-  public function testMediaEntityTokens() {
-    // Create a generic media bundle.
-    $bundle_name = $this->randomMachineName();
-
-    MediaBundle::create([
-      'id' => $bundle_name,
-      'label' => $bundle_name,
-      'type' => 'generic',
-      'type_configuration' => [],
-      'field_map' => [],
-      'status' => 1,
-      'new_revision' => FALSE,
-    ])->save();
-
-    // Create a media entity.
-    $media = Media::create([
-      'name' => $this->randomMachineName(),
-      'bundle' => $bundle_name,
-      'uid' => '1',
-      'langcode' => Language::LANGCODE_DEFAULT,
-      'status' => Media::PUBLISHED,
-    ]);
-    $media->save();
-
-    $token_service = $this->container->get('token');
-
-    // @TODO Extend this to cover also the other tokens, if necessary.
-    $replaced_value = $token_service->replace('[media:name]', ['media' => $media]);
-    $this->assertEquals($media->label(), $replaced_value, 'Token replacement for the media label was sucessful.');
-
-  }
-
-}
