/**
  * Preprocess theme hook variables.
  *
  * @param array $variables
  *   The variables array, passed by reference.
  * @param string $hook
  *   The name of the theme hook.
  * @param array $info
  *   The theme hook info.
  */
 public static function preprocess(array &$variables, $hook, array $info)
 {
     static $theme;
     if (!isset($theme)) {
         $theme = self::getTheme();
     }
     static $preprocess_manager;
     if (!isset($preprocess_manager)) {
         $preprocess_manager = new PreprocessManager($theme);
     }
     // Ensure that any default theme hook variables exist. Due to how theme
     // hook suggestion alters work, the variables provided are from the
     // original theme hook, not the suggestion.
     if (isset($info['variables'])) {
         $variables = NestedArray::mergeDeepArray([$info['variables'], $variables], TRUE);
     }
     // Add extra variables to all theme hooks.
     foreach (Materialize::extraVariables() as $key => $value) {
         if (!isset($variables[$key])) {
             $variables[$key] = $value;
         }
     }
     // Add active theme context.
     // @see https://www.drupal.org/node/2630870
     if (!isset($variables['theme'])) {
         $variables['theme'] = $theme->getInfo();
         $variables['theme']['name'] = $theme->getName();
         $variables['theme']['path'] = $theme->getPath();
         $variables['theme']['title'] = $theme->getTitle();
         $variables['theme']['settings'] = $theme->settings()->get();
     }
     // Invoke necessary preprocess plugin.
     if (isset($info['bootstrap preprocess'])) {
         if ($preprocess_manager->hasDefinition($info['bootstrap preprocess'])) {
             $class = $preprocess_manager->createInstance($info['bootstrap preprocess'], ['theme' => $theme]);
             /** @var \Drupal\bootstrap\Plugin\Preprocess\PreprocessInterface $class */
             $class->preprocess($variables, $hook, $info);
         }
     }
 }