diff --git a/3rdparty/SPMediaKeyTap/SPMediaKeyTap.m b/3rdparty/SPMediaKeyTap/SPMediaKeyTap.m
index a349f59..c418e0b 100644
--- a/3rdparty/SPMediaKeyTap/SPMediaKeyTap.m
+++ b/3rdparty/SPMediaKeyTap/SPMediaKeyTap.m
@@ -98,7 +98,6 @@ static CGEventRef tapEventCallback(CGEventTapProxy proxy, CGEventType type, CGEv
 {
 	return [NSArray arrayWithObjects:
 		[[NSBundle mainBundle] bundleIdentifier], // your app
-		@"com.spotify.client",
 		@"com.apple.iTunes",
 		@"com.apple.QuickTimePlayerX",
 		@"com.apple.quicktimeplayer",
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 23070d9..f2c8b72 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -7,7 +7,6 @@ include(cmake/C++11Compat.cmake)
 include(cmake/Summary.cmake)
 include(cmake/Version.cmake)
 include(cmake/Deb.cmake)
-include(cmake/SpotifyVersion.cmake)
 include(cmake/OptionalSource.cmake)
 include(cmake/Format.cmake)
 set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
@@ -74,7 +73,6 @@ pkg_check_modules(LIBMYGPO_QT libmygpo-qt>=1.0.9)
 pkg_check_modules(LIBPULSE libpulse)
 pkg_check_modules(LIBXML libxml-2.0)
 pkg_check_modules(QJSON REQUIRED QJson)
-pkg_check_modules(SPOTIFY libspotify>=12.1.45)
 pkg_check_modules(TAGLIB REQUIRED taglib>=1.6)
 
 if (WIN32)
@@ -117,13 +115,6 @@ endif()
 if (APPLE)
   find_library(SPARKLE Sparkle)
 
-  find_library(SPOTIFY libspotify)
-  if (SPOTIFY)
-    set (SPOTIFY_FOUND ON)
-    set (SPOTIFY_INCLUDE_DIRS ${SPOTIFY})
-    set (SPOTIFY_LIBRARIES ${SPOTIFY})
-  endif (SPOTIFY)
-
   add_subdirectory(3rdparty/SPMediaKeyTap)
   set(SPMEDIAKEYTAP_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/3rdparty/SPMediaKeyTap)
   set(SPMEDIAKEYTAP_LIBRARIES SPMediaKeyTap)
@@ -254,11 +245,6 @@ optional_component(DEVICEKIT ON "Devices: DeviceKit backend"
   DEPENDS "D-Bus support" HAVE_DBUS
 )
 
-optional_component(SPOTIFY_BLOB ON "Spotify support: non-GPL binary helper"
-  DEPENDS "protobuf" PROTOBUF_FOUND PROTOBUF_PROTOC_EXECUTABLE
-  DEPENDS "libspotify" SPOTIFY_FOUND
-)
-
 optional_component(MOODBAR ON "Moodbar support"
   DEPENDS "fftw3" FFTW3_FOUND
 )
@@ -274,14 +260,6 @@ optional_component(LIBPULSE ON "Pulse audio integration"
 
 optional_component(VISUALISATIONS ON "Visualisations")
 
-if(NOT HAVE_SPOTIFY_BLOB AND NOT CRYPTOPP_FOUND)
-  message(FATAL_ERROR "Either crypto++ must be available or the non-GPL Spotify "
-          "code must be compiled in")
-elseif(CRYPTOPP_FOUND)
-  set(HAVE_CRYPTOPP ON)
-  set(HAVE_SPOTIFY_DOWNLOADER ON)
-endif()
-
 # Find DBus if it's enabled
 if (HAVE_DBUS)
   find_package(Qt4 REQUIRED QtDbus)
@@ -422,7 +400,6 @@ add_subdirectory(ext/libclementine-common)
 add_subdirectory(ext/libclementine-tagreader)
 add_subdirectory(ext/clementine-tagreader)
 add_subdirectory(ext/libclementine-remote)
-add_subdirectory(ext/libclementine-spotifyblob)
 
 option(WITH_DEBIAN OFF)
 if(WITH_DEBIAN)
@@ -433,10 +410,6 @@ if(HAVE_BREAKPAD)
   add_subdirectory(3rdparty/google-breakpad)
 endif(HAVE_BREAKPAD)
 
-if(HAVE_SPOTIFY_BLOB)
-  add_subdirectory(ext/clementine-spotifyblob)
-endif(HAVE_SPOTIFY_BLOB)
-
 if(HAVE_MOODBAR)
   add_subdirectory(gst/moodbar)
 endif()
diff --git a/data/data.qrc b/data/data.qrc
index 694eaad..caecc30 100644
--- a/data/data.qrc
+++ b/data/data.qrc
@@ -3,7 +3,6 @@
         <file>Equifax_Secure_Certificate_Authority.pem</file>
         <file>blank.ttf</file>
         <file>clementine_remote_qr.png</file>
-        <file>clementine-spotify-public.pem</file>
         <file>currenttrack_bar_left.png</file>
         <file>currenttrack_bar_mid.png</file>
         <file>currenttrack_bar_right.png</file>
@@ -280,10 +279,10 @@
         <file>lumberjacksong.txt</file>
         <file>lyrics/ultimate_providers.xml</file>
         <file>mainwindow.css</file>
+        <file>moognu.png</file>
         <file>nocover.png</file>
         <file>nomusic.png</file>
         <file>now_playing_tooltip.txt</file>
-        <file>nyancat.png</file>
         <file>oauthsuccess.html</file>
         <file>osd_background.png</file>
         <file>osd_shadow_corner.png</file>
@@ -350,7 +349,6 @@
         <file>providers/22x22/somafm.png</file>
         <file>providers/22x22/songkick.png</file>
         <file>providers/22x22/soundcloud.png</file>
-        <file>providers/22x22/spotify.png</file>
         <file>providers/22x22/subsonic.png</file>
         <file>providers/22x22/vk.png</file>
         <file>providers/22x22/wikipedia.png</file>
@@ -382,7 +380,6 @@
         <file>providers/32x32/somafm.png</file>
         <file>providers/32x32/songkick.png</file>
         <file>providers/32x32/soundcloud.png</file>
-        <file>providers/32x32/spotify.png</file>
         <file>providers/32x32/subsonic.png</file>
         <file>providers/32x32/vk.png</file>
         <file>providers/32x32/wikipedia.png</file>
@@ -414,7 +411,6 @@
         <file>providers/48x48/somafm.png</file>
         <file>providers/48x48/songkick.png</file>
         <file>providers/48x48/soundcloud.png</file>
-        <file>providers/48x48/spotify.png</file>
         <file>providers/48x48/subsonic.png</file>
         <file>providers/48x48/vk.png</file>
         <file>providers/48x48/wikipedia.png</file>
@@ -478,7 +474,6 @@
         <file>songinfo.css</file>
         <file>soundcloud-ca.pem</file>
         <file>spinner.gif</file>
-        <file>spotify-attribution.png</file>
         <file>star-off.png</file>
         <file>star-on.png</file>
         <file>tiny-pause.png</file>
diff --git a/dist/codesign.py b/dist/codesign.py
index 7c111fd..fee7345 100755
--- a/dist/codesign.py
+++ b/dist/codesign.py
@@ -33,7 +33,7 @@ def main():
     for file in files:
       if re.search(r'\.(dylib|so)$', file):
         SignPath(os.path.join(root, file), developer_id)
-      elif re.match(r'(clementine-spotifyblob|clementine-tagreader|gst-plugin-scanner)', file):
+      elif re.match(r'(clementine-tagreader|gst-plugin-scanner)', file):
         SignPath(os.path.join(root, file), developer_id)
 
   SignPath(app_bundle, developer_id, deep=False)
diff --git a/dist/macdeploy.py b/dist/macdeploy.py
index 5d83c2e..f4d7d33 100755
--- a/dist/macdeploy.py
+++ b/dist/macdeploy.py
@@ -435,10 +435,7 @@ def main():
   FixPlugin(FindGioModule('libgiolibproxy.so'), 'gio-modules')
 
   try:
-    FixPlugin('clementine-spotifyblob', '.')
     FixPlugin('clementine-tagreader', '.')
-  except:
-    print 'Failed to find blob: %s' % traceback.format_exc()
 
   for plugin in QT_PLUGINS:
     FixPlugin(FindQtPlugin(plugin), os.path.dirname(plugin))
diff --git a/dist/windows/clementine.nsi.in b/dist/windows/clementine.nsi.in
index 10ba0ff..2e1eba6 100644
--- a/dist/windows/clementine.nsi.in
+++ b/dist/windows/clementine.nsi.in
@@ -187,9 +187,6 @@ Section "Delete old files" oldfiles
   Delete "$INSTDIR\gstreamer-plugins\libgstqueue2.dll"
   Delete "$INSTDIR\gstreamer-plugins\libgstsoup.dll"
 
-  ; 1.0 prerelease
-  Delete "$INSTDIR\spotify.dll"
-
   ; 1.0
   Delete "$INSTDIR\libofa.dll"
   Delete "$INSTDIR\gstreamer-plugins\libgstofa.dll"
@@ -260,7 +257,6 @@ Section "Clementine" Clementine
 
   File "clementine.exe"
   File "clementine-tagreader.exe"
-  File "clementine-spotifyblob.exe"
   File "clementine.ico"
   File "glew32.dll"
   File "libcdio-16.dll"
@@ -314,7 +310,6 @@ Section "Clementine" Clementine
   File "libprotobuf-8.dll"
   File "libqjson.dll"
   File "libspeex-1.dll"
-  File "libspotify.dll"
   File "libsqlite3-0.dll"
   File "libstdc++-6.dll"
   File "libtag.dll"
@@ -1073,7 +1068,6 @@ Section "Uninstall"
   Delete "$INSTDIR\clementine.ico"
   Delete "$INSTDIR\clementine.exe"
   Delete "$INSTDIR\clementine-tagreader.exe"
-  Delete "$INSTDIR\clementine-spotifyblob.exe"
   Delete "$INSTDIR\glew32.dll"
   Delete "$INSTDIR\libcdio-16.dll"
   Delete "$INSTDIR\libchromaprint.dll"
@@ -1126,7 +1120,6 @@ Section "Uninstall"
   Delete "$INSTDIR\libprotobuf-8.dll"
   Delete "$INSTDIR\libqjson.dll"
   Delete "$INSTDIR\libspeex-1.dll"
-  Delete "$INSTDIR\libspotify.dll"
   Delete "$INSTDIR\libstdc++-6.dll"
   Delete "$INSTDIR\libtag.dll"
   Delete "$INSTDIR\libtasn1-6.dll"
diff --git a/ext/libclementine-common/core/logging.cpp b/ext/libclementine-common/core/logging.cpp
index ec8faa2..f76f034 100644
--- a/ext/libclementine-common/core/logging.cpp
+++ b/ext/libclementine-common/core/logging.cpp
@@ -14,10 +14,6 @@
    limitations under the License.
 */
 
-// Note: this file is licensed under the Apache License instead of GPL because
-// it is used by the Spotify blob which links against libspotify and is not GPL
-// compatible.
-
 #include <QtGlobal>
 
 #include <cxxabi.h>
diff --git a/ext/libclementine-common/core/logging.h b/ext/libclementine-common/core/logging.h
index 21eebdf..68232ca 100644
--- a/ext/libclementine-common/core/logging.h
+++ b/ext/libclementine-common/core/logging.h
@@ -14,10 +14,6 @@
    limitations under the License.
 */
 
-// Note: this file is licensed under the Apache License instead of GPL because
-// it is used by the Spotify blob which links against libspotify and is not GPL
-// compatible.
-
 #ifndef LOGGING_H
 #define LOGGING_H
 
diff --git a/ext/libclementine-common/core/messagehandler.cpp b/ext/libclementine-common/core/messagehandler.cpp
index 1ea6492..5c4e79a 100644
--- a/ext/libclementine-common/core/messagehandler.cpp
+++ b/ext/libclementine-common/core/messagehandler.cpp
@@ -14,10 +14,6 @@
    limitations under the License.
 */
 
-// Note: this file is licensed under the Apache License instead of GPL because
-// it is used by the Spotify blob which links against libspotify and is not GPL
-// compatible.
-
 #include "messagehandler.h"
 #include "core/logging.h"
 
diff --git a/ext/libclementine-common/core/messagehandler.h b/ext/libclementine-common/core/messagehandler.h
index 5a7f8f2..7df58df 100644
--- a/ext/libclementine-common/core/messagehandler.h
+++ b/ext/libclementine-common/core/messagehandler.h
@@ -14,10 +14,6 @@
    limitations under the License.
 */
 
-// Note: this file is licensed under the Apache License instead of GPL because
-// it is used by the Spotify blob which links against libspotify and is not GPL
-// compatible.
-
 #ifndef MESSAGEHANDLER_H
 #define MESSAGEHANDLER_H
 
diff --git a/ext/libclementine-common/core/override.h b/ext/libclementine-common/core/override.h
index 98c2764..ca37137 100644
--- a/ext/libclementine-common/core/override.h
+++ b/ext/libclementine-common/core/override.h
@@ -14,10 +14,6 @@
    limitations under the License.
 */
 
-// Note: this file is licensed under the Apache License instead of GPL because
-// it is used by the Spotify blob which links against libspotify and is not GPL
-// compatible.
-
 #ifndef OVERRIDE_H
 #define OVERRIDE_H
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index afe58b9..125dd75 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -56,8 +56,6 @@ include_directories(${CMAKE_SOURCE_DIR}/ext/libclementine-tagreader)
 include_directories(${CMAKE_BINARY_DIR}/ext/libclementine-tagreader)
 include_directories(${CMAKE_SOURCE_DIR}/ext/libclementine-remote)
 include_directories(${CMAKE_BINARY_DIR}/ext/libclementine-remote)
-include_directories(${CMAKE_SOURCE_DIR}/ext/libclementine-spotifyblob)
-include_directories(${CMAKE_BINARY_DIR}/ext/libclementine-spotifyblob)
 
 cmake_policy(SET CMP0011 NEW)
 include(../cmake/ParseArguments.cmake)
@@ -154,7 +152,6 @@ set(SOURCES
   globalsearch/simplesearchprovider.cpp
   globalsearch/somafmsearchprovider.cpp
   globalsearch/soundcloudsearchprovider.cpp
-  globalsearch/spotifysearchprovider.cpp
   globalsearch/suggestionwidget.cpp
   globalsearch/urlsearchprovider.cpp
 
@@ -191,9 +188,6 @@ set(SOURCES
   internet/somafm/somafmurlhandler.cpp
   internet/soundcloud/soundcloudservice.cpp
   internet/soundcloud/soundcloudsettingspage.cpp
-  internet/spotify/spotifyserver.cpp
-  internet/spotify/spotifyservice.cpp
-  internet/spotify/spotifysettingspage.cpp
   internet/subsonic/subsonicservice.cpp
   internet/subsonic/subsonicsettingspage.cpp
   internet/subsonic/subsonicurlhandler.cpp
@@ -461,7 +455,6 @@ set(HEADERS
   globalsearch/searchprovider.h
   globalsearch/simplesearchprovider.h
   globalsearch/soundcloudsearchprovider.h
-  globalsearch/spotifysearchprovider.h
   globalsearch/suggestionwidget.h
 
   internet/core/cloudfileservice.h
@@ -494,9 +487,6 @@ set(HEADERS
   internet/somafm/somafmurlhandler.h
   internet/soundcloud/soundcloudservice.h
   internet/soundcloud/soundcloudsettingspage.h
-  internet/spotify/spotifyserver.h
-  internet/spotify/spotifyservice.h
-  internet/spotify/spotifysettingspage.h
   internet/subsonic/subsonicservice.h
   internet/subsonic/subsonicsettingspage.h
   internet/subsonic/subsonicurlhandler.h
@@ -692,7 +682,6 @@ set(UI
   internet/magnatune/magnatunesettingspage.ui
   internet/core/searchboxwidget.ui
   internet/soundcloud/soundcloudsettingspage.ui
-  internet/spotify/spotifysettingspage.ui
   internet/subsonic/subsonicsettingspage.ui
 
   library/groupbydialog.ui
@@ -839,15 +828,6 @@ optional_source(HAVE_LIBLASTFM
 )
 
 
-optional_source(HAVE_SPOTIFY_DOWNLOADER
-  SOURCES
-    internet/spotify/spotifyblobdownloader.cpp
-  HEADERS
-    internet/spotify/spotifyblobdownloader.h
-  INCLUDE_DIRECTORIES
-    ${CRYPTOPP_INCLUDE_DIRS}
-)
-
 # Platform specific - OS X
 optional_source(APPLE
   INCLUDE_DIRECTORIES
@@ -1233,7 +1213,6 @@ add_dependencies(clementine_lib pot)
 
 
 target_link_libraries(clementine_lib
-  clementine-spotifyblob-messages
   libclementine-common
   libclementine-tagreader
   libclementine-remote
@@ -1303,13 +1282,6 @@ if(HAVE_BREAKPAD)
   endif (LINUX)
 endif(HAVE_BREAKPAD)
 
-if(HAVE_SPOTIFY_DOWNLOADER)
-  target_link_libraries(clementine_lib
-    ${CRYPTOPP_LIBRARIES}
-  )
-  link_directories(${CRYPTOPP_LIBRARY_DIRS})
-endif(HAVE_SPOTIFY_DOWNLOADER)
-
 if(HAVE_LIBPULSE)
   target_link_libraries(clementine_lib ${LIBPULSE_LIBRARIES})
 endif()
@@ -1394,16 +1366,6 @@ target_link_libraries(clementine
   clementine_lib
 )
 
-# macdeploy.py relies on the blob being built first.
-if(HAVE_SPOTIFY_BLOB)
-  add_dependencies(clementine clementine-spotifyblob)
-endif(HAVE_SPOTIFY_BLOB)
-add_dependencies(clementine clementine-tagreader)
-
-set_target_properties(clementine PROPERTIES
-  MACOSX_BUNDLE_INFO_PLIST "../dist/Info.plist"
-)
-
 if (APPLE)
   install(FILES ../dist/clementine.icns
     DESTINATION "${CMAKE_BINARY_DIR}/clementine.app/Contents/Resources")
diff --git a/src/analyzers/rainbowanalyzer.cpp b/src/analyzers/rainbowanalyzer.cpp
index c8aa0cf..e8eec8b 100644
--- a/src/analyzers/rainbowanalyzer.cpp
+++ b/src/analyzers/rainbowanalyzer.cpp
@@ -40,7 +40,7 @@ const int Rainbow::RainbowAnalyzer::kRainbowHeight[] = { 21, 16 };
 const int Rainbow::RainbowAnalyzer::kRainbowOverlap[] = { 13, 15 };
 const int Rainbow::RainbowAnalyzer::kSleepingHeight[] = { 24, 33 };
 
-const char* Rainbow::NyanCatAnalyzer::kName = "Nyanalyzer Cat";
+const char* Rainbow::NyanCatAnalyzer::kName = "MooGNU";
 const char* Rainbow::RainbowDashAnalyzer::kName = "Rainbow Dash";
 const float Rainbow::RainbowAnalyzer::kPixelScale = 0.02f;
 
@@ -56,7 +56,7 @@ Rainbow::RainbowAnalyzer::RainbowAnalyzer(const RainbowType& rbtype, QWidget* pa
       x_offset_(0),
       background_brush_(QColor(0x0f, 0x43, 0x73)) {
   rainbowtype = rbtype;
-  cat_dash_[0] = QPixmap(":/nyancat.png");
+  cat_dash_[0] = QPixmap(":/moognu.png");
   cat_dash_[1] = QPixmap(":/rainbowdash.png");
   memset(history_, 0, sizeof(history_));
 
@@ -192,8 +192,8 @@ void Rainbow::RainbowAnalyzer::analyze(QPainter& p, const Analyzer::Scope& s,
   // Draw the buffer on to the widget
   p.drawPixmap(0, 0, buffer_[current_buffer_], x_offset_, 0, 0, 0);
 
-  // Draw rainbow analyzer (nyan cat or rainbowdash)
-  // Nyan nyan nyan nyan dash dash dash dash.
+  // Draw rainbow analyzer (moo gnu or rainbowdash)
+  // Moo moo moo moo dash dash dash dash.
   if (!is_playing_) {
     // Ssshhh!
     p.drawPixmap(SleepingDestRect(rainbowtype), cat_dash_[rainbowtype], 
diff --git a/src/config.h.in b/src/config.h.in
index f22fe9b..92124f5 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -40,7 +40,6 @@
 #cmakedefine HAVE_SEAFILE
 #cmakedefine HAVE_SKYDRIVE
 #cmakedefine HAVE_SPARKLE
-#cmakedefine HAVE_SPOTIFY_DOWNLOADER
 #cmakedefine HAVE_VK
 #cmakedefine HAVE_WIIMOTEDEV
 #cmakedefine TAGLIB_HAS_OPUS
diff --git a/src/core/backgroundstreams.cpp b/src/core/backgroundstreams.cpp
index 2e6ac60..e62504c 100644
--- a/src/core/backgroundstreams.cpp
+++ b/src/core/backgroundstreams.cpp
@@ -28,8 +28,6 @@
 
 const char* BackgroundStreams::kSettingsGroup = "BackgroundStreams";
 const char* BackgroundStreams::kHypnotoadUrl = "hypnotoad:///";
-const char* BackgroundStreams::kRainUrl =
-    "http://data.clementine-player.org/rainymood";
 const char* BackgroundStreams::kEnterpriseUrl = "enterprise:///";
 
 BackgroundStreams::BackgroundStreams(EngineBase* engine, QObject* parent)
@@ -44,7 +42,6 @@ void BackgroundStreams::LoadStreams() {
   int version = s.value("version", 0).toInt();
   if (version < 1) {
     AddStream(QT_TR_NOOP("Hypnotoad"), QUrl(kHypnotoadUrl));
-    AddStream(QT_TR_NOOP("Rain"), QUrl(kRainUrl));
   }
 
   if (version < kVersion) {
diff --git a/src/core/timeconstants.h b/src/core/timeconstants.h
index 67d0227..49020d8 100644
--- a/src/core/timeconstants.h
+++ b/src/core/timeconstants.h
@@ -16,10 +16,6 @@
    limitations under the License.
 */
 
-// Note: this file is licensed under the Apache License instead of GPL because
-// it is used by the Spotify blob which links against libspotify and is not GPL
-// compatible.
-
 #ifndef CORE_TIMECONSTANTS_H_
 #define CORE_TIMECONSTANTS_H_
 
diff --git a/src/core/utilities.cpp b/src/core/utilities.cpp
index 739cadb..a022a47 100644
--- a/src/core/utilities.cpp
+++ b/src/core/utilities.cpp
@@ -368,9 +368,6 @@ QString GetConfigPath(ConfigPath config) {
       return QDir::homePath();
 #endif
 
-    case Path_LocalSpotifyBlob:
-      return GetConfigPath(Path_Root) + "/spotifyblob";
-
     default:
       qFatal("%s", Q_FUNC_INFO);
       return QString::null;
diff --git a/src/core/utilities.h b/src/core/utilities.h
index 5fd8fc1..36ddefe 100644
--- a/src/core/utilities.h
+++ b/src/core/utilities.h
@@ -129,7 +129,6 @@ enum ConfigPath {
   Path_NetworkCache,
   Path_GstreamerRegistry,
   Path_DefaultMusicLibrary,
-  Path_LocalSpotifyBlob,
   Path_MoodbarCache,
   Path_CacheRoot,
 };
diff --git a/src/covers/albumcoverloader.cpp b/src/covers/albumcoverloader.cpp
index 8ebf51c..c01a16e 100644
--- a/src/covers/albumcoverloader.cpp
+++ b/src/covers/albumcoverloader.cpp
@@ -34,14 +34,12 @@
 #include "core/tagreaderclient.h"
 #include "core/utilities.h"
 #include "internet/core/internetmodel.h"
-#include "internet/spotify/spotifyservice.h"
 
 AlbumCoverLoader::AlbumCoverLoader(QObject* parent)
     : QObject(parent),
       stop_requested_(false),
       next_id_(1),
-      network_(new NetworkAccessManager(this)),
-      connected_spotify_(false) {}
+      network_(new NetworkAccessManager(this)) {}
 
 QString AlbumCoverLoader::ImageCacheDir() {
   return Utilities::GetConfigPath(Utilities::Path_AlbumCovers);
@@ -176,26 +174,6 @@ AlbumCoverLoader::TryLoadResult AlbumCoverLoader::TryLoadImage(
 
     remote_tasks_.insert(reply, task);
     return TryLoadResult(true, false, QImage());
-  } else if (filename.toLower().startsWith("spotify://image/")) {
-    // HACK: we should add generic image URL handlers
-    SpotifyService* spotify = InternetModel::Service<SpotifyService>();
-
-    if (!connected_spotify_) {
-      connect(spotify, SIGNAL(ImageLoaded(QString, QImage)),
-              SLOT(SpotifyImageLoaded(QString, QImage)));
-      connected_spotify_ = true;
-    }
-
-    QString id = QUrl(filename).path();
-    if (id.startsWith('/')) {
-      id.remove(0, 1);
-    }
-    remote_spotify_tasks_.insert(id, task);
-
-    // Need to schedule this in the spotify service's thread
-    QMetaObject::invokeMethod(spotify, "LoadImage", Qt::QueuedConnection,
-                              Q_ARG(QString, id));
-    return TryLoadResult(true, false, QImage());
   }
 
   QImage image(filename);
@@ -204,16 +182,6 @@ AlbumCoverLoader::TryLoadResult AlbumCoverLoader::TryLoadImage(
       image.isNull() ? task.options.default_output_image_ : image);
 }
 
-void AlbumCoverLoader::SpotifyImageLoaded(const QString& id,
-                                          const QImage& image) {
-  if (!remote_spotify_tasks_.contains(id)) return;
-
-  Task task = remote_spotify_tasks_.take(id);
-  QImage scaled = ScaleAndPad(task.options, image);
-  emit ImageLoaded(task.id, scaled);
-  emit ImageLoaded(task.id, scaled, image);
-}
-
 void AlbumCoverLoader::RemoteFetchFinished(QNetworkReply* reply) {
   reply->deleteLater();
 
diff --git a/src/covers/albumcoverloader.h b/src/covers/albumcoverloader.h
index 4d3e4d5..5de0663 100644
--- a/src/covers/albumcoverloader.h
+++ b/src/covers/albumcoverloader.h
@@ -66,7 +66,6 @@ class AlbumCoverLoader : public QObject {
  protected slots:
   void ProcessTasks();
   void RemoteFetchFinished(QNetworkReply* reply);
-  void SpotifyImageLoaded(const QString& url, const QImage& image);
 
  protected:
   enum State { State_TryingManual, State_TryingAuto, };
@@ -103,13 +102,10 @@ class AlbumCoverLoader : public QObject {
   QMutex mutex_;
   QQueue<Task> tasks_;
   QMap<QNetworkReply*, Task> remote_tasks_;
-  QMap<QString, Task> remote_spotify_tasks_;
   quint64 next_id_;
 
   NetworkAccessManager* network_;
 
-  bool connected_spotify_;
-
   static const int kMaxRedirects = 3;
 };
 
diff --git a/src/engines/gstenginepipeline.cpp b/src/engines/gstenginepipeline.cpp
index c3fde67..39f4410 100644
--- a/src/engines/gstenginepipeline.cpp
+++ b/src/engines/gstenginepipeline.cpp
@@ -34,8 +34,6 @@
 #include "core/signalchecker.h"
 #include "core/utilities.h"
 #include "internet/core/internetmodel.h"
-#include "internet/spotify/spotifyserver.h"
-#include "internet/spotify/spotifyservice.h"
 
 const int GstEnginePipeline::kGstStateTimeoutNanosecs = 10000000;
 const int GstEnginePipeline::kFaderFudgeMsec = 2000;
@@ -152,44 +150,14 @@ bool GstEnginePipeline::ReplaceDecodeBin(GstElement* new_bin) {
 bool GstEnginePipeline::ReplaceDecodeBin(const QUrl& url) {
   GstElement* new_bin = nullptr;
 
-  if (url.scheme() == "spotify") {
-    new_bin = gst_bin_new("spotify_bin");
-
-    // Create elements
-    GstElement* src = engine_->CreateElement("tcpserversrc", new_bin);
-    GstElement* gdp = engine_->CreateElement("gdpdepay", new_bin);
-    if (!src || !gdp) return false;
-
-    // Pick a port number
-    const int port = Utilities::PickUnusedPort();
-    g_object_set(G_OBJECT(src), "host", "127.0.0.1", nullptr);
-    g_object_set(G_OBJECT(src), "port", port, nullptr);
-
-    // Link the elements
-    gst_element_link(src, gdp);
-
-    // Add a ghost pad
-    GstPad* pad = gst_element_get_static_pad(gdp, "src");
-    gst_element_add_pad(GST_ELEMENT(new_bin), gst_ghost_pad_new("src", pad));
-    gst_object_unref(GST_OBJECT(pad));
-
-    // Tell spotify to start sending data to us.
-    SpotifyServer* spotify_server = InternetModel::Service<SpotifyService>()->server();
-    // Need to schedule this in the spotify server's thread
-    QMetaObject::invokeMethod(spotify_server, "StartPlayback",
-                              Qt::QueuedConnection,
-                              Q_ARG(QString, url.toString()),
-                              Q_ARG(quint16, port));
-  } else {
-    new_bin = engine_->CreateElement("uridecodebin");
-    g_object_set(G_OBJECT(new_bin), "uri", url.toEncoded().constData(),
-                 nullptr);
-    CHECKED_GCONNECT(G_OBJECT(new_bin), "drained", &SourceDrainedCallback,
-                     this);
-    CHECKED_GCONNECT(G_OBJECT(new_bin), "pad-added", &NewPadCallback, this);
-    CHECKED_GCONNECT(G_OBJECT(new_bin), "notify::source", &SourceSetupCallback,
-                     this);
-  }
+  new_bin = engine_->CreateElement("uridecodebin");
+  g_object_set(G_OBJECT(new_bin), "uri", url.toEncoded().constData(),
+               nullptr);
+  CHECKED_GCONNECT(G_OBJECT(new_bin), "drained", &SourceDrainedCallback,
+                   this);
+  CHECKED_GCONNECT(G_OBJECT(new_bin), "pad-added", &NewPadCallback, this);
+  CHECKED_GCONNECT(G_OBJECT(new_bin), "notify::source", &SourceSetupCallback,
+                   this);
 
   return ReplaceDecodeBin(new_bin);
 }
@@ -923,17 +891,7 @@ GstPadProbeReturn GstEnginePipeline::EventHandoffCallback(GstPad*,
 void GstEnginePipeline::SourceDrainedCallback(GstURIDecodeBin* bin,
                                               gpointer self) {
   GstEnginePipeline* instance = reinterpret_cast<GstEnginePipeline*>(self);
-
-  if (instance->has_next_valid_url() &&
-      // I'm not sure why, but calling this when previous track is a local song
-      // and the next track is a Spotify song is buggy: the Spotify song will
-      // not start or with some offset. So just do nothing here: when the song
-      // finished, EndOfStreamReached/TrackEnded will be emitted anyway so
-      // NextItem will be called.
-      !(instance->url_.scheme() != "spotify" &&
-        instance->next_url_.scheme() == "spotify")) {
-    instance->TransitionToNext();
-  }
+  instance->TransitionToNext();
 }
 
 void GstEnginePipeline::SourceSetupCallback(GstURIDecodeBin* bin,
@@ -1032,24 +990,6 @@ GstState GstEnginePipeline::state() const {
 }
 
 QFuture<GstStateChangeReturn> GstEnginePipeline::SetState(GstState state) {
-  if (url_.scheme() == "spotify" && !buffering_) {
-    const GstState current_state = this->state();
-
-    if (state == GST_STATE_PAUSED && current_state == GST_STATE_PLAYING) {
-      SpotifyService* spotify = InternetModel::Service<SpotifyService>();
-
-      // Need to schedule this in the spotify service's thread
-      QMetaObject::invokeMethod(spotify, "SetPaused", Qt::QueuedConnection,
-                                Q_ARG(bool, true));
-    } else if (state == GST_STATE_PLAYING &&
-               current_state == GST_STATE_PAUSED) {
-      SpotifyService* spotify = InternetModel::Service<SpotifyService>();
-
-      // Need to schedule this in the spotify service's thread
-      QMetaObject::invokeMethod(spotify, "SetPaused", Qt::QueuedConnection,
-                                Q_ARG(bool, false));
-    }
-  }
   return ConcurrentRun::Run<GstStateChangeReturn, GstElement*, GstState>(
       &set_state_threadpool_, &gst_element_set_state, pipeline_, state);
 }
diff --git a/src/internet/core/internetmodel.cpp b/src/internet/core/internetmodel.cpp
index 597d904..a769489 100644
--- a/src/internet/core/internetmodel.cpp
+++ b/src/internet/core/internetmodel.cpp
@@ -37,7 +37,6 @@
 #include "internet/internetradio/savedradio.h"
 #include "internet/somafm/somafmservice.h"
 #include "internet/soundcloud/soundcloudservice.h"
-#include "internet/spotify/spotifyservice.h"
 #include "internet/subsonic/subsonicservice.h"
 #include "core/closure.h"
 #include "core/logging.h"
@@ -97,7 +96,6 @@ InternetModel::InternetModel(Application* app, QObject* parent)
   AddService(new RadioTunesService(app, this));
   AddService(new SomaFMService(app, this));
   AddService(new SoundCloudService(app, this));
-  AddService(new SpotifyService(app, this));
   AddService(new SubsonicService(app, this));
 #ifdef HAVE_BOX
   AddService(new BoxService(app, this));
diff --git a/src/main.cpp b/src/main.cpp
index 1a961c8..87c1f34 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -159,8 +159,6 @@ void SetEnv(const char* key, const QString& value) {
 #endif
 }
 
-// This must be done early so that the spotify blob process also picks up
-// these environment variables.
 void SetGstreamerEnvironment() {
   QString scanner_path;
   QString plugin_path;
diff --git a/src/playlist/playlistbackend.h b/src/playlist/playlistbackend.h
index f9d347c..320c0fb 100644
--- a/src/playlist/playlistbackend.h
+++ b/src/playlist/playlistbackend.h
@@ -47,8 +47,6 @@ class PlaylistBackend : public QObject {
     QString dynamic_backend;
     QByteArray dynamic_data;
 
-    // Special playlists have different behaviour, eg. the "spotify-search"
-    // type has a spotify search box at the top, replacing the ordinary filter.
     QString special_type;
   };
   typedef QList<Playlist> PlaylistList;
diff --git a/src/playlist/playlistdelegates.cpp b/src/playlist/playlistdelegates.cpp
index 11ffa42..649976a 100644
--- a/src/playlist/playlistdelegates.cpp
+++ b/src/playlist/playlistdelegates.cpp
@@ -458,9 +458,7 @@ QPixmap SongSourceDelegate::LookupPixmap(const QUrl& url,
   if (handler) {
     icon = handler->icon();
   } else {
-    if (url.scheme() == "spotify") {
-      icon = IconLoader::Load("spotify", IconLoader::Provider);
-    } else if (url.scheme() == "file") {
+    if (url.scheme() == "file") {
       icon = IconLoader::Load("folder-sound", IconLoader::Base);
     } else if (url.host() == "api.jamendo.com") {
       icon = IconLoader::Load("jamendo", IconLoader::Provider);
diff --git a/src/songinfo/echonestimages.cpp b/src/songinfo/echonestimages.cpp
index ce13645..c3e7e0e 100644
--- a/src/songinfo/echonestimages.cpp
+++ b/src/songinfo/echonestimages.cpp
@@ -27,11 +27,6 @@
 #include "core/logging.h"
 #include "core/network.h"
 
-namespace {
-static const char* kSpotifyBucket = "spotify";
-static const char* kSpotifyArtistUrl = "https://api.spotify.com/v1/artists/%1";
-}
-
 EchoNestImages::EchoNestImages() : network_(new NetworkAccessManager) {}
 
 EchoNestImages::~EchoNestImages() {}
@@ -48,19 +43,6 @@ void EchoNestImages::FetchInfo(int id, const Song& metadata) {
   NewClosure(reply, SIGNAL(finished()), this,
              SLOT(RequestFinished(QNetworkReply*, int, Echonest::Artist)),
              reply, id, artist);
-
-  // Also look up the artist id for the spotify API so we can directly request
-  // images from there too.
-  Echonest::Artist::SearchParams params;
-  params.push_back(
-      qMakePair(Echonest::Artist::Name, QVariant(metadata.artist())));
-  QNetworkReply* rosetta_reply = Echonest::Artist::search(
-      params,
-      Echonest::ArtistInformation(Echonest::ArtistInformation::NoInformation,
-                                  QStringList() << kSpotifyBucket));
-  RegisterReply(rosetta_reply, id);
-  NewClosure(rosetta_reply, SIGNAL(finished()), this,
-             SLOT(IdsFound(QNetworkReply*, int)), rosetta_reply, id);
 }
 
 void EchoNestImages::RequestFinished(QNetworkReply* reply, int id,
@@ -88,49 +70,12 @@ void EchoNestImages::IdsFound(QNetworkReply* reply, int request_id) {
     if (artists.isEmpty()) {
       return;
     }
-    const Echonest::ForeignIds& foreign_ids = artists.first().foreignIds();
-    for (const Echonest::ForeignId& id : foreign_ids) {
-      if (id.catalog.contains("spotify")) {
-        DoSpotifyImageRequest(id.foreign_id, request_id);
-      }
-    }
   } catch (Echonest::ParseError e) {
     qLog(Warning) << "Error parsing echonest reply:" << e.errorType()
                   << e.what();
   }
 }
 
-void EchoNestImages::DoSpotifyImageRequest(const QString& id, int request_id) {
-  QString artist_id = id.split(":").last();
-  QUrl url(QString(kSpotifyArtistUrl).arg(artist_id));
-  QNetworkReply* reply = network_->get(QNetworkRequest(url));
-  RegisterReply(reply, request_id);
-  NewClosure(reply, SIGNAL(finished()), [this, reply, request_id]() {
-    reply->deleteLater();
-    QJson::Parser parser;
-    QVariantMap result = parser.parse(reply).toMap();
-    QVariantList images = result["images"].toList();
-    QList<QPair<QUrl, QSize>> image_urls;
-    for (const QVariant& image : images) {
-      QVariantMap image_result = image.toMap();
-      image_urls.append(qMakePair(image_result["url"].toUrl(),
-                                  QSize(image_result["width"].toInt(),
-                                        image_result["height"].toInt())));
-    }
-    // All the images are the same just different sizes; just pick the largest.
-    std::sort(image_urls.begin(), image_urls.end(),
-              [](const QPair<QUrl, QSize>& a,
-                 const QPair<QUrl, QSize>& b) {
-      // Sorted by area ascending.
-      return (a.second.height() * a.second.width()) <
-          (b.second.height() * b.second.width());
-    });
-    if (!image_urls.isEmpty()) {
-      emit ImageReady(request_id, image_urls.last().first);
-    }
-  });
-}
-
 // Keeps track of replies and emits Finished() when all replies associated with
 // a request are finished with.
 void EchoNestImages::RegisterReply(QNetworkReply* reply, int id) {
diff --git a/src/songinfo/echonestimages.h b/src/songinfo/echonestimages.h
index 6e67e87..8cd71e4 100644
--- a/src/songinfo/echonestimages.h
+++ b/src/songinfo/echonestimages.h
@@ -42,8 +42,6 @@ class EchoNestImages : public SongInfoProvider {
   void IdsFound(QNetworkReply* reply, int id);
 
  private:
-  void DoSpotifyImageRequest(const QString& id, int request_id);
-
   void RegisterReply(QNetworkReply* reply, int id);
   QMultiMap<int, QNetworkReply*> replies_;
   std::unique_ptr<NetworkAccessManager> network_;
diff --git a/src/ui/about.cpp b/src/ui/about.cpp
index 77a05d1..a43ae4f 100644
--- a/src/ui/about.cpp
+++ b/src/ui/about.cpp
@@ -83,7 +83,6 @@ QString About::MakeHtml() const {
 
   ret += QString("<br />%1</p>").arg(tr("...and all the Amarok contributors"));
   ret += QString("<p><b>%1</b>").arg(tr("And:"));
-  ret += QString("<br /><a href=\"http://rainymood.com\">Rainy Mood</a>");
   ret += QString(
       "<br /><a href=\"http://www.smitelli.com/?page=blog&p=54\">Scott "
       "Smitelli</a>");
@@ -91,11 +90,6 @@ QString About::MakeHtml() const {
       "<br /><a href=\"http://hyperboleandahalf.blogspot.com\">Allie "
       "Brosh</a></p>");
 
-  ret +=
-      "<p>This product uses Music by Spotify but is not endorsed, certified "
-      "or otherwise approved in any way by Spotify. Spotify is the registered "
-      "trade mark of the Spotify Group.</p>";
-
   return ret;
 }
 
diff --git a/src/ui/settingsdialog.cpp b/src/ui/settingsdialog.cpp
index 2cb7e1b..8cb60e7 100644
--- a/src/ui/settingsdialog.cpp
+++ b/src/ui/settingsdialog.cpp
@@ -39,7 +39,6 @@
 #include "internet/core/internetshowsettingspage.h"
 #include "internet/magnatune/magnatunesettingspage.h"
 #include "internet/soundcloud/soundcloudsettingspage.h"
-#include "internet/spotify/spotifysettingspage.h"
 #include "internet/subsonic/subsonicsettingspage.h"
 #include "library/librarysettingspage.h"
 #include "playlist/playlistview.h"
@@ -184,7 +183,6 @@ SettingsDialog::SettingsDialog(Application* app, BackgroundStreams* streams,
 #endif
 
   AddPage(Page_SoundCloud, new SoundCloudSettingsPage(this), providers);
-  AddPage(Page_Spotify, new SpotifySettingsPage(this), providers);
 
 #ifdef HAVE_VK
   AddPage(Page_Vk, new VkSettingsPage(this), providers);
diff --git a/src/ui/settingsdialog.h b/src/ui/settingsdialog.h
index 14bb976..b543cc9 100644
--- a/src/ui/settingsdialog.h
+++ b/src/ui/settingsdialog.h
@@ -69,7 +69,6 @@ class SettingsDialog : public QDialog {
     Page_Library,
     Page_Lastfm,
     Page_SoundCloud,
-    Page_Spotify,
     Page_Magnatune,
     Page_DigitallyImported,
     Page_BackgroundStreams,