 .../Drupal/language/Plugin/Block/LanguageBlock.php |   86 ++++++++++++++++----
 1 file changed, 70 insertions(+), 16 deletions(-)

diff --git a/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php b/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php
index 49c066e..f9d6e45 100644
--- a/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php
+++ b/core/modules/language/lib/Drupal/language/Plugin/Block/LanguageBlock.php
@@ -33,6 +33,13 @@ class LanguageBlock extends BlockBase implements ContainerFactoryPluginInterface
   protected $languageManager;
 
   /**
+   * The current user.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $currentUser;
+
+  /**
    * Constructs an LanguageBlock object.
    *
    * @param array $configuration
@@ -43,10 +50,13 @@ class LanguageBlock extends BlockBase implements ContainerFactoryPluginInterface
    *   The plugin implementation definition.
    * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
    *   The language manager.
+   * @param \Drupal\Core\Session\AccountInterface $current_user
+   *   The current user.
    */
-  public function __construct(array $configuration, $plugin_id, array $plugin_definition, LanguageManagerInterface $language_manager) {
+  public function __construct(array $configuration, $plugin_id, array $plugin_definition, LanguageManagerInterface $language_manager, AccountInterface $current_user) {
     parent::__construct($configuration, $plugin_id, $plugin_definition);
     $this->languageManager = $language_manager;
+    $this->currentUser = $current_user;
   }
 
 
@@ -58,7 +68,8 @@ public static function create(ContainerInterface $container, array $configuratio
       $configuration,
       $plugin_id,
       $plugin_definition,
-      $container->get('language_manager')
+      $container->get('language_manager'),
+      $container->get('current_user')
     );
   }
 
@@ -75,23 +86,66 @@ function access(AccountInterface $account) {
    */
   public function build() {
     $build = array();
-    $path = drupal_is_front_page() ? '<front>' : current_path();
-    $type = $this->getDerivativeId();
-    $links = $this->languageManager->getLanguageSwitchLinks($type, $path);
-
-    if (isset($links->links)) {
-      $build = array(
-        '#theme' => 'links__language_block',
-        '#links' => $links->links,
-        '#attributes' => array(
-          'class' => array(
-            "language-switcher-{$links->method_id}",
+    if ($this->currentUser->isAnonymous()) {
+      $path = drupal_is_front_page() ? '<front>' : current_path();
+      $type = $this->getDerivativeId();
+      $links = $this->languageManager->getLanguageSwitchLinks($type, $path);
+
+      if (isset($links->links)) {
+        $build = array(
+          '#theme' => 'links__language_block',
+          '#links' => $links->links,
+          '#attributes' => array(
+            'class' => array(
+              "language-switcher-{$links->method_id}",
+            ),
           ),
-        ),
-        '#set_active_class' => TRUE,
-      );
+          '#set_active_class' => TRUE,
+        );
+      }
+    }
+    else {
+      // @todo Build the globally cacheable variant that depends on a redirect
+      //   plus JavaScript.
+      // @see getRequiredCacheContexts()
     }
     return $build;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function defaultConfiguration() {
+    // @todo Ensure whenever language settings change, that appropriate cache
+    //   tags are invalidated, that allows us to cache this block forever.
+    return array('cache' => array('max_age' => \Drupal\Core\Cache\Cache::PERMANENT));
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function getRequiredCacheContexts() {
+    // The 'Language switcher' block must be cached per role: for anonymous
+    // users and non-anonymous users. For anonymous users, we render the final
+    // HTML, because we assume that page caching is enabled for anonymous users.
+    // For non-anymous users, we render language links that point to a generic
+    // language redirection route, with attached JavaScript that sets the
+    // 'destination' query string on those URLs. That way, we can cache one
+    // entry for all
+    // @todo Create this new is_anonymous cache context.
+    return array('cache_context.user.is_anonymous');
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isCacheable() {
+    if ($this->currentUser->isAnonymous()) {
+      return FALSE;
+    }
+    else {
+      return parent::isCacheable();
+    }
+  }
+
 }
