diff --git a/batch_example/batch_example.info.yml b/batch_example/batch_example.info.yml
new file mode 100644
index 0000000..db1669f
--- /dev/null
+++ b/batch_example/batch_example.info.yml
@@ -0,0 +1,7 @@
+name: Batch example
+type: module
+description: An example outlining how a module can define batch operations.
+package: Example modules
+core: 8.x
+dependencies:
+  - node
diff --git a/batch_example/batch_example.module b/batch_example/batch_example.module
new file mode 100644
index 0000000..9f1e4f0
--- /dev/null
+++ b/batch_example/batch_example.module
@@ -0,0 +1,321 @@
+<?php
+
+/**
+ * @file
+ * Outlines how a module can use the Batch API.
+ */
+
+/**
+ * @defgroup batch_example Example: Batch API
+ * @ingroup examples
+ * @{
+ * Outlines how a module can use the Batch API.
+ *
+ * Batches allow heavy processing to be spread out over several page
+ * requests, ensuring that the processing does not get interrupted
+ * because of a PHP timeout, while allowing the user to receive feedback
+ * on the progress of the ongoing operations. It also can reduce out of memory
+ * situations.
+ *
+ * The @link batch_example.install .install file @endlink also shows how the
+ * Batch API can be used to handle long-running hook_update_N() functions.
+ *
+ * Two harmless batches are defined:
+ * - batch 1: Load the node with the lowest nid 100 times.
+ * - batch 2: Load all nodes, 20 times and uses a progressive op, loading nodes
+ *   by groups of 5.
+ *
+ * @see batch
+ */
+
+/**
+ * Implements hook_menu().
+ */
+function batch_example_menu() {
+  $items['examples/batch_example'] = array(
+    'title' => 'Batch example',
+    'description' => 'Example of Drupal batch processing',
+    'route name' => 'batch_example.form',
+  );
+
+  return $items;
+}
+
+/**
+ * Form builder function to allow choice of which batch to run.
+ */
+//function batch_example_simple_form() {
+//  $form['description'] = array(
+//    '#type' => 'markup',
+//    '#markup' => t('This example offers two different batches. The first does 1000 identical operations, each completed in on run; the second does 20 operations, but each takes more than one run to operate if there are more than 5 nodes.'),
+//  );
+//  $form['batch'] = array(
+//    '#type' => 'select',
+//    '#title' => 'Choose batch',
+//    '#options' => array(
+//      'batch_1' => t('batch 1 - 1000 operations, each loading the same node'),
+//      'batch_2' => t('batch 2 - 20 operations. each one loads all nodes 5 at a time'),
+//    ),
+//  );
+//  $form['submit'] = array(
+//    '#type' => 'submit',
+//    '#value' => 'Go',
+//  );
+//
+//  // If no nodes, prevent submission.
+//  // Find out if we have a node to work with. Otherwise it won't work.
+//  $nid = batch_example_lowest_nid();
+//  if (empty($nid)) {
+//    drupal_set_message(t("You don't currently have any nodes, and this example requires a node to work with. As a result, this form is disabled."));
+//    $form['submit']['#disabled'] = TRUE;
+//  }
+//  return $form;
+//}
+//
+///**
+// * Submit handler.
+// *
+// * @param array $form
+// *   Form API form.
+// * @param array $form_state
+// *   Form API form.
+// */
+//function batch_example_simple_form_submit($form, &$form_state) {
+//  $function = 'batch_example_' . $form_state['values']['batch'];
+//
+//  // Reset counter for debug information.
+//  $_SESSION['http_request_count'] = 0;
+//
+//  // Execute the function named batch_example_1 or batch_example_2.
+//  $batch = $function();
+//  batch_set($batch);
+//}
+//
+//
+///**
+// * Batch 1 definition: Load the node with the lowest nid 1000 times.
+// *
+// * This creates an operations array defining what batch 1 should do, including
+// * what it should do when it's finished. In this case, each operation is the
+// * same and by chance even has the same $nid to operate on, but we could have
+// * a mix of different types of operations in the operations array.
+// */
+//function batch_example_batch_1() {
+//  $nid = batch_example_lowest_nid();
+//  $num_operations = 1000;
+//  drupal_set_message(t('Creating an array of @num operations', array('@num' => $num_operations)));
+//
+//  $operations = array();
+//  // Set up an operations array with 1000 elements, each doing function
+//  // batch_example_op_1.
+//  // Each operation in the operations array means at least one new HTTP request,
+//  // running Drupal from scratch to accomplish the operation. If the operation
+//  // returns with $context['finished'] != TRUE, then it will be called again.
+//  // In this example, $context['finished'] is always TRUE.
+//  for ($i = 0; $i < $num_operations; $i++) {
+//    // Each operation is an array consisting of
+//    // - The function to call.
+//    // - An array of arguments to that function.
+//    $operations[] = array(
+//      'batch_example_op_1',
+//      array(
+//        $nid,
+//        t('(Operation @operation)', array('@operation' => $i)),
+//      ),
+//    );
+//  }
+//  $batch = array(
+//    'operations' => $operations,
+//    'finished' => 'batch_example_finished',
+//  );
+//  return $batch;
+//}
+
+/**
+ * Batch operation for batch 1: load a node.
+ *
+ * This is the function that is called on each operation in batch 1.
+ */
+function batch_example_op_1($nid, $operation_details, &$context) {
+  $node = node_load($nid, NULL, TRUE);
+
+  // Store some results for post-processing in the 'finished' callback.
+  // The contents of 'results' will be available as $results in the
+  // 'finished' function (in this example, batch_example_finished()).
+  $title = $node->title;
+  $context['results'][] = $node->nid() . ' : ' . check_plain($title);
+
+  // Optional message displayed under the progressbar.
+  $context['message'] = t('Loading node "@title"', array('@title' => $title)) . ' ' . $operation_details;
+
+  _batch_example_update_http_requests();
+}
+
+///**
+// * Batch 2 : Prepare a batch definition that will load all nodes 20 times.
+// */
+//function batch_example_batch_2() {
+//  $num_operations = 20;
+//
+//  // Give helpful information about how many nodes are being operated on.
+//  $node_count = db_query('SELECT COUNT(DISTINCT nid) FROM {node}')->fetchField();
+//  drupal_set_message(
+//    t('There are @node_count nodes so each of the @num operations will require @count HTTP requests.',
+//      array(
+//        '@node_count' => $node_count,
+//        '@num' => $num_operations,
+//        '@count' => ceil($node_count / 5),
+//      )
+//    )
+//  );
+//
+//  $operations = array();
+//  // 20 operations, each one loads all nodes.
+//  for ($i = 0; $i < $num_operations; $i++) {
+//    $operations[] = array(
+//      'batch_example_op_2',
+//      array(t('(Operation @operation)', array('@operation' => $i))),
+//    );
+//  }
+//  $batch = array(
+//    'operations' => $operations,
+//    'finished' => 'batch_example_finished',
+//    // Message displayed while processing the batch. Available placeholders are:
+//    // @current, @remaining, @total, @percentage, @estimate and @elapsed.
+//    // These placeholders are replaced with actual values in _batch_process(),
+//    // using strtr() instead of t(). The values are determined based on the
+//    // number of operations in the 'operations' array (above), NOT by the number
+//    // of nodes that will be processed. In this example, there are 20
+//    // operations, so @total will always be 20, even though there are multiple
+//    // nodes per operation.
+//    // Defaults to t('Completed @current of @total.').
+//    'title' => t('Processing batch 2'),
+//    'init_message' => t('Batch 2 is starting.'),
+//    'progress_message' => t('Processed @current out of @total.'),
+//    'error_message' => t('Batch 2 has encountered an error.'),
+//  );
+//  return $batch;
+//}
+//
+///**
+// * Batch operation for batch 2 : load all nodes, 5 by five.
+// *
+// * After each group of 5 control is returned to the batch API for later
+// * continuation.
+// */
+//function batch_example_op_2($operation_details, &$context) {
+//  // Use the $context['sandbox'] at your convenience to store the
+//  // information needed to track progression between successive calls.
+//  if (empty($context['sandbox'])) {
+//    $context['sandbox'] = array();
+//    $context['sandbox']['progress'] = 0;
+//    $context['sandbox']['current_node'] = 0;
+//
+//    // Save node count for the termination message.
+//    $context['sandbox']['max'] = db_query('SELECT COUNT(DISTINCT nid) FROM {node}')->fetchField();
+//  }
+//
+//  // Process nodes by groups of 5 (arbitrary value).
+//  // When a group of five is processed, the batch update engine determines
+//  // whether it should continue processing in the same request or provide
+//  // progress feedback to the user and wait for the next request.
+//  // That way even though we're already processing at the operation level
+//  // the operation itself is interruptible.
+//  $limit = 5;
+//
+//  // Retrieve the next group of nids.
+//  $result = db_select('node', 'n')
+//    ->fields('n', array('nid'))
+//    ->orderBy('n.nid', 'ASC')
+//    ->where('n.nid > :nid', array(':nid' => $context['sandbox']['current_node']))
+//    ->extend('PagerDefault')
+//    ->limit($limit)
+//    ->execute();
+//  foreach ($result as $row) {
+//    // Here we actually perform our dummy 'processing' on the current node.
+//    $node = node_load($row->nid, NULL, TRUE);
+//
+//    // Store some results for post-processing in the 'finished' callback.
+//    // The contents of 'results' will be available as $results in the
+//    // 'finished' function (in this example, batch_example_finished()).
+//    $context['results'][] = $node->nid . ' : ' . check_plain($node->title) . ' ' . $operation_details;
+//
+//    // Update our progress information.
+//    $context['sandbox']['progress']++;
+//    $context['sandbox']['current_node'] = $node->nid;
+//    $context['message'] = check_plain($node->title);
+//  }
+//
+//  // Inform the batch engine that we are not finished,
+//  // and provide an estimation of the completion level we reached.
+//  if ($context['sandbox']['progress'] != $context['sandbox']['max']) {
+//    $context['finished'] = ($context['sandbox']['progress'] >= $context['sandbox']['max']);
+//  }
+//  _batch_example_update_http_requests();
+//}
+
+/**
+ * Batch 'finished' callback used by both batch 1 and batch 2.
+ */
+function batch_example_finished($success, $results, $operations) {
+  if ($success) {
+    // Here we could do something meaningful with the results.
+    // We just display the number of nodes we processed...
+    drupal_set_message(t('@count results processed in @requests HTTP requests.', array('@count' => count($results), '@requests' => _batch_example_get_http_requests())));
+    drupal_set_message(t('The final result was "%final"', array('%final' => end($results))));
+  }
+  else {
+    // An error occurred.
+    // $operations contains the operations that remained unprocessed.
+    $error_operation = reset($operations);
+    drupal_set_message(
+      t('An error occurred while processing @operation with arguments : @args',
+        array(
+          '@operation' => $error_operation[0],
+          '@args' => print_r($error_operation[0], TRUE),
+        )
+      )
+    );
+  }
+}
+
+///**
+// * Utility function - simply queries and loads the lowest nid.
+// *
+// * @return int|NULL
+// *   A nid or NULL if there are no nodes.
+// */
+//function batch_example_lowest_nid() {
+//  $select = db_select('node', 'n')
+//  ->fields('n', array('nid'))
+//  ->orderBy('n.nid', 'ASC')
+//  ->extend('PagerDefault')
+//  ->limit(1);
+//  $nid = $select->execute()->fetchField();
+//  return $nid;
+//}
+
+/**
+ * Utility function to increment HTTP requests in a session variable.
+ */
+function _batch_example_update_http_requests() {
+//  $session = \Drupal::request()->getSession();
+//  $count = $session->get('http_request_count');
+//  $session->set('http_request_count', ++$count);
+}
+
+/**
+ * Utility function to count the HTTP requests in a session variable.
+ * 
+ * @return int
+ *   Number of requests.
+ */
+function _batch_example_get_http_requests() {
+//  $session = \Drupal::request()->getSession();
+//  return $session->get('http_request_count');
+  return 0;
+}
+
+/**
+ * @} End of "defgroup batch_example".
+ */
diff --git a/batch_example/batch_example.old_install b/batch_example/batch_example.old_install
new file mode 100644
index 0000000..3fa1d64
--- /dev/null
+++ b/batch_example/batch_example.old_install
@@ -0,0 +1,85 @@
+<?php
+
+/**
+ * @file
+ * Install, update, and uninstall functions for the batch_example module.
+ */
+
+/**
+ * Example of batch-driven update function.
+ *
+ * Because some update functions may require the batch API, the $sandbox
+ * provides a place to store state. When $standbox['#finished'] == TRUE,
+ * calls to this update function are completed.
+ *
+ * The $sandbox param provides a way to store data during multiple invocations.
+ * When the $sandbox['#finished'] == 1, execution is complete.
+ *
+ * This dummy 'update' function changes no state in the system. It simply
+ * loads each node.
+ *
+ * To make this update function run again and again, execute the query
+ * "update system set schema_version = 0 where name = 'batch_example';"
+ * and then run /update.php.
+ *
+ * @ingroup batch_example
+ */
+function batch_example_update_7100(&$sandbox) {
+  $ret = array();
+
+  // Use the sandbox at your convenience to store the information needed
+  // to track progression between successive calls to the function.
+  if (!isset($sandbox['progress'])) {
+    // The count of nodes visited so far.
+    $sandbox['progress'] = 0;
+    // Total nodes that must be visited.
+    $sandbox['max'] = db_query('SELECT COUNT(nid) FROM {node}')->fetchField();
+    // A place to store messages during the run.
+    $sandbox['messages'] = array();
+    // Last node read via the query.
+    $sandbox['current_node'] = -1;
+  }
+
+  // Process nodes by groups of 10 (arbitrary value).
+  // When a group is processed, the batch update engine determines
+  // whether it should continue processing in the same request or provide
+  // progress feedback to the user and wait for the next request.
+  $limit = 10;
+
+  // Retrieve the next group of nids.
+  $result = db_select('node', 'n')
+    ->fields('n', array('nid'))
+    ->orderBy('n.nid', 'ASC')
+    ->where('n.nid > :nid', array(':nid' => $sandbox['current_node']))
+    ->extend('PagerDefault')
+    ->limit($limit)
+    ->execute();
+  foreach ($result as $row) {
+    // Here we actually perform a dummy 'update' on the current node.
+    $node = db_query('SELECT nid FROM {node} WHERE nid = :nid', array(':nid' => $row->nid))->fetchField();
+
+    // Update our progress information.
+    $sandbox['progress']++;
+    $sandbox['current_node'] = $row->nid;
+  }
+
+  // Set the "finished" status, to tell batch engine whether this function
+  // needs to run again. If you set a float, this will indicate the progress
+  // of the batch so the progress bar will update.
+  $sandbox['#finished'] = ($sandbox['progress'] >= $sandbox['max']) ? TRUE : ($sandbox['progress'] / $sandbox['max']);
+
+  // Set up a per-run message; Make a copy of $sandbox so we can change it.
+  // This is simply a debugging stanza to illustrate how to capture status
+  // from each pass through hook_update_N().
+  $sandbox_status = $sandbox;
+  // Don't want them in the output.
+  unset($sandbox_status['messages']);
+  $sandbox['messages'][] = t('$sandbox=') . print_r($sandbox_status, TRUE);
+
+  if ($sandbox['#finished']) {
+    // hook_update_N() may optionally return a string which will be displayed
+    // to the user.
+    $final_message = '<ul><li>' . implode('</li><li>', $sandbox['messages']) . "</li></ul>";
+    return t('The batch_example demonstration update did what it was supposed to do: @message', array('@message' => $final_message));
+  }
+}
diff --git a/batch_example/batch_example.routing.yml b/batch_example/batch_example.routing.yml
new file mode 100644
index 0000000..df3568f
--- /dev/null
+++ b/batch_example/batch_example.routing.yml
@@ -0,0 +1,6 @@
+batch_example.form:
+  path: '/examples/batch_example'
+  defaults:
+    _form: '\Drupal\batch_example\Forms\BatchExampleForm'
+  requirements:
+    _access: 'TRUE'
diff --git a/batch_example/lib/Drupal/batch_example/Forms/BatchExampleForm.php b/batch_example/lib/Drupal/batch_example/Forms/BatchExampleForm.php
new file mode 100644
index 0000000..afb8b8b
--- /dev/null
+++ b/batch_example/lib/Drupal/batch_example/Forms/BatchExampleForm.php
@@ -0,0 +1,349 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\batch_example\Form\BatchExampleForm
+ */
+
+namespace Drupal\batch_example\Forms;
+
+use Drupal\Core\Form\FormBase;
+use Symfony\Component\HttpFoundation\Session\Session;
+
+/**
+ * Form with examples on how to use cache.
+ */
+class BatchExampleForm extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'batch_example_form';
+  }
+
+  /**
+   * Utility function - simply queries and loads the lowest nid.
+   *
+   * @return int|NULL
+   *   A nid or NULL if there are no nodes.
+   */
+  protected function lowestNid() {
+    $select = db_select('node', 'n')
+    ->fields('n', array('nid'))
+    ->orderBy('n.nid', 'ASC')
+    ->range(0,1);
+    $nid = $select->execute()->fetchField();
+    return $nid;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+
+    $form['description'] = array(
+      '#type' => 'markup',
+      '#markup' => t('This example offers two different batches. The first does 1000 identical operations, each completed in on run; the second does 20 operations, but each takes more than one run to operate if there are more than 5 nodes.'),
+    );
+    $form['batch'] = array(
+      '#type' => 'select',
+      '#title' => 'Choose batch',
+      '#options' => array(
+        'batch_1' => t('batch 1 - 1000 operations, each loading the same node'),
+        'batch_2' => t('batch 2 - 20 operations. each one loads all nodes 5 at a time'),
+      ),
+    );
+    $form['submit'] = array(
+      '#type' => 'submit',
+      '#value' => 'Go',
+    );
+  
+    // If no nodes, prevent submission.
+    // Find out if we have a node to work with. Otherwise it won't work.
+    $nid = $this->lowestNid();
+    if (empty($nid)) {
+      drupal_set_message(t("You don't currently have any nodes, and this example requires a node to work with. As a result, this form is disabled."));
+      $form['submit']['#disabled'] = TRUE;
+    }      
+    return $form;
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {
+    // Reset our session-based counter so we have some information to display.
+//    $request = \Drupal::request();
+//    if ($request->hasPreviousSession()) {
+//      $session = $request->getSession();
+//    }
+//    else {
+//      $session = new Session();
+//      //$session->start();
+//      $request->setSession($session);
+//    }
+//    $session->set('http_request_count', 0);
+
+    // Gather our form value.
+    $value = $form_state['values']['batch'];
+    // Set the batch, using convenience methods.
+    $batch = array();
+    switch ($value) {
+      case 'batch_1':
+        $batch = $this->generateBatch1();
+        break;
+      case 'batch_2':
+        //$batch = $this->generateBatch2();
+    }
+    batch_set($batch);
+  }
+
+
+  /**
+   * Generate Batch 1.
+   *
+   * Batch 1 will load the node with the lowest nid 1000 times.
+   *
+   * This creates an operations array defining what batch 1 should do, including
+   * what it should do when it's finished. In this case, each operation is the
+   * same and by chance even has the same $nid to operate on, but we could have
+   * a mix of different types of operations in the operations array.
+   */
+  public function generateBatch1() {
+    $nid = $this->lowestNid();
+    $num_operations = 1000;
+    drupal_set_message(t('Creating an array of @num operations', array('@num' => $num_operations)));
+  
+    $operations = array();
+    // Set up an operations array with 1000 elements, each doing function
+    // batch_example_op_1.
+    // Each operation in the operations array means at least one new HTTP request,
+    // running Drupal from scratch to accomplish the operation. If the operation
+    // returns with $context['finished'] != TRUE, then it will be called again.
+    // In this example, $context['finished'] is always TRUE.
+    for ($i = 0; $i < $num_operations; $i++) {
+      // Each operation is an array consisting of
+      // - The function to call.
+      // - An array of arguments to that function.
+      $operations[] = array(
+        'batch_example_op_1',
+        array(
+          $nid,
+          t('(Operation @operation)', array('@operation' => $i)),
+        ),
+      );
+    }
+    $batch = array(
+      'operations' => $operations,
+      'finished' => 'batch_example_finished',
+    );
+    return $batch;
+  }
+
+
+//    // Log execution time.
+//    $start_time = microtime(TRUE);
+//
+//    // Try to load the files count from cache. This function will accept two
+//    // arguments:
+//    // - cache object name (cid)
+//    // - cache bin, the (optional) cache bin (most often a database table) where
+//    //   the object is to be saved.
+//    //
+//    // cache_get() returns the cached object or FALSE if object does not exist.
+//    if ($cache = \Drupal::cache()->get('cache_example_files_count')) {
+//      /*
+//       * Get cached data. Complex data types will be unserialized automatically.
+//       */
+//      $files_count = $cache->data;
+//    }
+//    else {
+//      // If there was no cached data available we have to search filesystem.
+//      // Recursively get all files from Drupal's folder.
+//      $files_count = count(file_scan_directory('.', '/.*/'));
+//
+//      // Since we have recalculated, we now need to store the new data into
+//      // cache. Complex data types will be automatically serialized before
+//      // being saved into cache.
+//      // Here we use the default setting and create an unexpiring cache item.
+//      // See below for an example that creates an expiring cache item.
+//      \Drupal::cache()->set('cache_example_files_count', $files_count, CacheBackendInterface::CACHE_PERMANENT);
+//    }
+//
+//    $end_time = microtime(TRUE);
+//    $duration = $end_time - $start_time;
+//
+//    // Format intro message.
+//    $intro_message = '<p>' . t('This example will search the entire drupal folder and display a count of the files in it.') . ' ';
+//    $intro_message .= t('This can take a while, since there are a lot of files to be searched.') . ' ';
+//    $intro_message .= t('We will search filesystem just once and save output to the cache. We will use cached data for later requests.') . '</p>';
+//    $intro_message .= '<p>' . t('<a href="@url">Reload this page</a> to see cache in action.', array('@url' => request_uri())) . ' ';
+//    $intro_message .= t('You can use the button below to remove cached data.') . '</p>';
+//
+//    $form['file_search'] = array(
+//      '#type' => 'fieldset',
+//      '#title' => t('File search caching'),
+//    );
+//    $form['file_search']['introduction'] = array(
+//      '#markup' => $intro_message,
+//    );
+//
+//    $color = empty($cache) ? 'red' : 'green';
+//    $retrieval = empty($cache) ? t('calculated by traversing the filesystem') : t('retrieved from cache');
+//
+//    $form['file_search']['statistics'] = array(
+//      '#type' => 'item',
+//      '#markup' => t('%count files exist in this Drupal installation; @retrieval in @time ms. <br/>(Source: <span style="color:@color;">@source</span>)',
+//        array(
+//          '%count' => $files_count,
+//          '@retrieval' => $retrieval,
+//          '@time' => number_format($duration * 1000, 2),
+//          '@color' => $color,
+//          '@source' => empty($cache) ? t('actual file search') : t('cached'),
+//        )
+//      ),
+//    );
+//    $form['file_search']['remove_file_count'] = array(
+//      '#type' => 'submit',
+//      '#submit' => array(array($this, 'expireFiles')),
+//      '#value' => t('Explicitly remove cached file count'),
+//    );
+//
+//    $form['expiration_demo'] = array(
+//      '#type' => 'fieldset',
+//      '#title' => t('Cache expiration settings'),
+//    );
+//    $form['expiration_demo']['explanation'] = array(
+//      '#markup' => t('A cache item can be set as CACHE_PERMANENT, meaning that it will only be removed when explicitly cleared, or it can have an expiration time (a Unix timestamp).'),
+//    );
+//
+//    $expiring_item = \Drupal::cache()->get('cache_example_expiring_item', TRUE);
+//    $item_status = $expiring_item ?
+//      t('Cache item exists and is set to expire at %time', array('%time' => $expiring_item->data)) :
+//      t('Cache item does not exist');
+//    $form['expiration_demo']['current_status'] = array(
+//      '#type' => 'item',
+//      '#title' => t('Current status of cache item "cache_example_expiring_item"'),
+//      '#markup' => $item_status,
+//    );
+//    $form['expiration_demo']['expiration'] = array(
+//      '#type' => 'select',
+//      '#title' => t('Time before cache expiration'),
+//      '#options' => array(
+//        'never_remove' => t('CACHE_PERMANENT'),
+//        -10 => t('Immediate expiration'),
+//        10 => t('10 seconds from form submission'),
+//        60 => t('1 minute from form submission'),
+//        300 => t('5 minutes from form submission'),
+//      ),
+//      '#default_value' => -10,
+//      '#description' => t('Any cache item can be set to only expire when explicitly cleared, or to expire at a given time.'),
+//    );
+//    $form['expiration_demo']['create_cache_item'] = array(
+//      '#type' => 'submit',
+//      '#value' => t('Create a cache item with this expiration'),
+//      '#submit' => array(array($this, 'createExpiringItem')),
+//    );
+//
+//    $form['cache_clearing'] = array(
+//      '#type' => 'fieldset',
+//      '#title' => t('Expire and remove options'),
+//      '#description' => t("We have APIs to expire cached items and also to just remove them. Unfortunately, they're all the same API, cache_clear_all"),
+//    );
+//    $form['cache_clearing']['cache_clear_type'] = array(
+//      '#type' => 'radios',
+//      '#title' => t('Type of cache clearing to do'),
+//      '#options' => array(
+//        'expire' => t('Remove items from the "cache" bin that have expired'),
+//        'remove_all' => t('Remove all items from the "cache" bin regardless of expiration'),
+//        'remove_tag' => t('Remove all items in the "cache" bin with the tag "cache_example" set to 1'),
+//      ),
+//      '#default_value' => 'expire',
+//    );
+//    // Submit button to clear cached data.
+//    $form['cache_clearing']['clear_expired'] = array(
+//      '#type' => 'submit',
+//      '#value' => t('Clear or expire cache'),
+//      '#submit' => array(array($this, 'cacheClearing')),
+//      '#access' => \Drupal::currentUser()->hasPermission('administer site configuration'),
+//    );
+//
+//    return $form;
+//  }
+
+  /**
+   * Submit handler that explicitly clears cache_example_files_count from cache.
+   */
+  public function expireFiles($form, &$form_state) {
+    // Clear cached data. This function will delete cached object from cache
+    // bin.
+    //
+    // The first argument is cache id to be deleted. Since we've provided it
+    // explicitly, it will be removed whether or not it has an associated
+    // expiration time. The second argument (required here) is the cache bin.
+    // Using cache_clear_all() explicitly in this way
+    // forces removal of the cached item.
+    \Drupal::cache()->delete('cache_example_files_count');
+
+    // Display message to the user.
+    drupal_set_message(t('Cached data key "cache_example_files_count" was cleared.'), 'status');
+  }
+
+  /**
+   * Submit handler to create a new cache item with specified expiration.
+   */
+  public function createExpiringItem($form, &$form_state) {
+
+    $tags = array(
+      'cache_example' => array(1),
+    );
+
+    $interval = $form_state['values']['expiration'];
+    if ($interval == 'never_remove') {
+      $expiration = CacheBackendInterface::CACHE_PERMANENT;
+      $expiration_friendly = t('Never expires');
+    }
+    else {
+      $expiration = time() + $interval;
+      $expiration_friendly = format_date($expiration);
+    }
+    // Set the expiration to the actual Unix timestamp of the end of the
+    // required interval. Also add a tag to it to be able to clear caches more
+    // precise.
+    \Drupal::cache()->set('cache_example_expiring_item', $expiration_friendly, $expiration, $tags);
+    drupal_set_message(t('cache_example_expiring_item was set to expire at %time', array('%time' => $expiration_friendly)));
+  }
+
+  /**
+   * Submit handler to demonstrate the various uses of cache_clear_all().
+   */
+  public function cacheClearing($form, &$form_state) {
+    switch ($form_state['values']['cache_clear_type']) {
+      case 'expire':
+        // Here we'll remove all cache keys in the 'cache' bin that have
+        // expired.
+        \Drupal::cache()->garbageCollection();
+        drupal_set_message(t('\Drupal::cache()->garbageCollection() was called, removing any expired cache items.'));
+        break;
+
+      case 'remove_all':
+        // This removes all keys in a bin using a super-wildcard. This
+        // has nothing to do with expiration. It's just brute-force removal.
+        \Drupal::cache()->deleteAll();
+        drupal_set_message(t('ALL entries in the "cache" bin were removed with \Drupal::cache()->deleteAll().'));
+        break;
+
+      case 'remove_tag':
+        // This removes cache entries with the tag "cache_example" set to 1 in
+        // the "cache".
+        $tags = array(
+          'cache_example' => array(1),
+        );
+        \Drupal::cache()->deleteTags($tags);
+        drupal_set_message(t('Cache entries with the tag "cache_example" set to 1 in the "cache" bin were removed with \Drupal::cache()->deleteTags($tags).'));
+        break;
+    }
+  }
+
+}
diff --git a/batch_example/lib/Drupal/batch_example/Tests/BatchExampleTestCaseTest.php b/batch_example/lib/Drupal/batch_example/Tests/BatchExampleTestCaseTest.php
new file mode 100644
index 0000000..dd21fbb
--- /dev/null
+++ b/batch_example/lib/Drupal/batch_example/Tests/BatchExampleTestCaseTest.php
@@ -0,0 +1,58 @@
+<?php
+
+/**
+ * @file
+ * Test case for Testing the batch example module.
+ *
+ * This file contains the test cases to check if module is performing as
+ * expected.
+ */
+
+namespace Drupal\batch_example\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Functional tests for the Batch Example module.
+ *
+ * @ingroup batch_example
+ */
+class BatchExampleTestCaseTest extends WebTestBase {
+
+  // Define module dependencies.
+  public static $modules = array('node', 'batch_example');
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'name' => 'Batch example functionality',
+      'description' => 'Verify the defined batches.',
+      'group' => 'Examples',
+    );
+  }
+
+  /**
+   * Login user, create 30 nodes and test both batch examples.
+   */
+  public function testBatchExampleBasic() {
+    // Login the admin user.
+    $this->drupalLogin($this->drupalCreateUser(array('access content')));
+
+    // Create 30 nodes.
+    for ($count = 0; $count < 30; $count++) {
+      $node = $this->drupalCreateNode();
+    }
+
+    // Launch Batch 1
+    $result = $this->drupalPostForm('examples/batch_example', array('batch' => 'batch_1'), t('Go'));
+    // Check that 1000 operations were performed.
+    $this->assertText('1000 results processed');
+
+    // Launch Batch 2
+    $result = $this->drupalPostForm('examples/batch_example', array('batch' => 'batch_2'), t('Go'));
+    // Check that 600 operations were performed.
+    $this->assertText('600 results processed');
+  }
+}
