diff --git a/form_example/form_example.info.yml b/form_example/form_example.info.yml
new file mode 100644
index 0000000..2232340
--- /dev/null
+++ b/form_example/form_example.info.yml
@@ -0,0 +1,5 @@
+name: Form example
+type: module
+description: 'Demonstrates hook_form() and related features'
+package: Example modules
+core: 8.x
diff --git a/form_example/form_example.local_tasks.yml b/form_example/form_example.local_tasks.yml
new file mode 100644
index 0000000..a738ebf
--- /dev/null
+++ b/form_example/form_example.local_tasks.yml
@@ -0,0 +1,50 @@
+form_example.tutorial_1_tab:
+  route_name: form_example.tutorial_1
+  tab_root_id: form_example.tutorial_tab_1
+  title: '#1'
+  weight: 0
+form_example.tutorial_2_tab:
+  route_name: form_example.tutorial_2
+  tab_root_id: form_example.tutorial_tab_1
+  title: '#2'
+  weight: 5
+form_example.tutorial_3_tab:
+  route_name: form_example.tutorial_3
+  tab_root_id: form_example.tutorial_tab_1
+  title: '#3'
+  weight: 10
+form_example.tutorial_4_tab:
+  route_name: form_example.tutorial_4
+  tab_root_id: form_example.tutorial_tab_1
+  title: '#4'
+  weight: 15
+form_example.tutorial_5_tab:
+  route_name: form_example.tutorial_5
+  tab_root_id: form_example.tutorial_tab_1
+  title: '#5'
+  weight: 20
+form_example.tutorial_6_tab:
+  route_name: form_example.tutorial_6
+  tab_root_id: form_example.tutorial_tab_1
+  title: '#6'
+  weight: 25
+form_example.tutorial_7_tab:
+  route_name: form_example.tutorial_7
+  tab_root_id: form_example.tutorial_tab_1
+  title: '#7'
+  weight: 30
+form_example.tutorial_8_tab:
+  route_name: form_example.tutorial_8
+  tab_root_id: form_example.tutorial_tab_1
+  title: '#8'
+  weight: 35
+form_example.tutorial_9_tab:
+  route_name: form_example.tutorial_9
+  tab_root_id: form_example.tutorial_tab_1
+  title: '#9'
+  weight: 45
+form_example.tutorial_10_tab:
+  route_name: form_example.tutorial_10
+  tab_root_id: form_example.tutorial_tab_1
+  title: '#10'
+  weight: 45
diff --git a/form_example/form_example.module b/form_example/form_example.module
new file mode 100644
index 0000000..155c6a7
--- /dev/null
+++ b/form_example/form_example.module
@@ -0,0 +1,125 @@
+<?php
+/**
+ * @file
+ * Examples demonstrating the Drupal Form API.
+ */
+
+/**
+ * @defgroup form_example Example: Form API
+ * @ingroup examples
+ * @{
+ * Examples demonstrating the Drupal Form API.
+ *
+ * The Form Example module is a part of the Examples for Developers Project
+ * and provides various Drupal Form API Examples. You can download and
+ * experiment with this code at the
+ * @link http://drupal.org/project/examples Examples for Developers project page. @endlink
+ */
+
+/**
+ * Implements hook_menu().
+ *
+ * Here we set up the URLs (menu entries) for the
+ * form examples. Note that most of the menu items
+ * have page callbacks and page arguments set, with
+ * page arguments set to be functions in external files.
+ */
+function form_example_menu() {
+  $items = array();
+  $items['examples/form_example'] = array(
+    'title' => 'Form Example',
+    'route_name' => 'form_example',
+    'access callback' => TRUE,
+    'expanded' => TRUE,
+  );
+  $items['examples/form_example/tutorial'] = array(
+    'title' => 'Form Tutorial',
+    'route_name' => array('form_example.tutorial'),
+    'access callback' => TRUE,
+    'description' => 'A set of ten tutorials',
+  );
+  $items['examples/form_example/tutorial/1'] = array(
+    'title' => '#1',
+    'route_name' => array('form_example.tutorial_1'),
+    'access callback' => TRUE,
+    'description' => 'Tutorial 1: Simplest form',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
+  $items['examples/form_example/tutorial/2'] = array(
+    'title' => '#2',
+    'route_name' => array('form_example.tutorial_2'),
+    'access callback' => TRUE,
+    'description' => 'Tutorial 2: Form with a submit button',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
+  $items['examples/form_example/tutorial/3'] = array(
+    'title' => '#3',
+    'route_name' => array('form_example.tutorial_3'),
+    'access callback' => TRUE,
+    'description' => 'Tutorial 3: Form with a submit button',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
+  $items['examples/form_example/tutorial/3'] = array(
+    'title' => '#3',
+    'route_name' => array('form_example.tutorial_3'),
+    'access callback' => TRUE,
+    'description' => 'Tutorial 3: Form with a submit button',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
+  $items['examples/form_example/tutorial/4'] = array(
+    'title' => '#4',
+    'route_name' => array('form_example.tutorial_4'),
+    'access callback' => TRUE,
+    'description' => 'Tutorial 4: Form with a submit button',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
+  $items['examples/form_example/tutorial/5'] = array(
+    'title' => '#5',
+    'route_name' => array('form_example.tutorial_5'),
+    'access callback' => TRUE,
+    'description' => 'Tutorial 5: Form with a submit button',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
+  $items['examples/form_example/tutorial/6'] = array(
+    'title' => '#6',
+    'route_name' => array('form_example.tutorial_6'),
+    'access callback' => TRUE,
+    'description' => 'Tutorial 6: Form with a submit button',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
+  $items['examples/form_example/tutorial/7'] = array(
+    'title' => '#7',
+    'route_name' => array('form_example.tutorial_7'),
+    'access callback' => TRUE,
+    'description' => 'Tutorial 7: Form with a submit button',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
+  $items['examples/form_example/tutorial/8'] = array(
+    'title' => '#8',
+    'route_name' => array('form_example.tutorial_8'),
+    'access callback' => TRUE,
+    'description' => 'Tutorial 8: Form with a submit button',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
+  $items['examples/form_example/tutorial/9'] = array(
+    'title' => '#9',
+    'route_name' => array('form_example.tutorial_9'),
+    'access callback' => TRUE,
+    'description' => 'Tutorial 9: Form with a submit button',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
+  $items['examples/form_example/tutorial/10'] = array(
+    'title' => '#10',
+    'route_name' => array('form_example.tutorial_10'),
+    'access callback' => TRUE,
+    'description' => 'Tutorial 10: Form with a submit button',
+    'type' => MENU_VISIBLE_IN_BREADCRUMB,
+  );
+  $items['examples/form_example/wizard'] = array(
+    'title' => 'Extensible Wizard: Step 1',
+    'route_name' => array('form_example.wizard'),
+    'access callback' => TRUE,
+    'description' => 'A general approach to a wizard multistep form.',
+  );
+  return $items;
+}
diff --git a/form_example/form_example.routing.yml b/form_example/form_example.routing.yml
new file mode 100644
index 0000000..782e7e5
--- /dev/null
+++ b/form_example/form_example.routing.yml
@@ -0,0 +1,80 @@
+form_example:
+  path: 'examples/form_example'
+  defaults:
+    _content: '\Drupal\form_example\Controller\FormExampleController::description'
+    _title: 'Form Example'
+  requirements:
+    _access: 'TRUE'
+form_example.tutorial:
+  path: 'examples/form_example/tutorial'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleTutorial'
+  requirements:
+    _access: 'TRUE'
+form_example.tutorial_1:
+  path: 'examples/form_example/tutorial/1'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleTutorial'
+  requirements:
+    _access: 'TRUE'
+form_example.tutorial_2:
+  path: 'examples/form_example/tutorial/2'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleTutorial2'
+  requirements:
+    _access: 'TRUE'
+form_example.tutorial_3:
+  path: 'examples/form_example/tutorial/3'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleTutorial3'
+  requirements:
+    _access: 'TRUE'
+form_example.tutorial_4:
+  path: 'examples/form_example/tutorial/4'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleTutorial4'
+  requirements:
+    _access: 'TRUE'
+form_example.tutorial_5:
+  path: 'examples/form_example/tutorial/5'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleTutorial5'
+  requirements:
+    _access: 'TRUE'
+form_example.tutorial_6:
+  path: 'examples/form_example/tutorial/6'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleTutorial6'
+  requirements:
+    _access: 'TRUE'
+form_example.tutorial_7:
+  path: 'examples/form_example/tutorial/7'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleTutorial7'
+  requirements:
+    _access: 'TRUE'
+form_example.tutorial_8:
+  path: 'examples/form_example/tutorial/8'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleTutorial8'
+  requirements:
+    _access: 'TRUE'
+form_example.tutorial_9:
+  path: 'examples/form_example/tutorial/9'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleTutorial9'
+  requirements:
+    _access: 'TRUE'
+form_example.tutorial_10:
+  path: 'examples/form_example/tutorial/10'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleTutorial10'
+  requirements:
+    _access: 'TRUE'
+form_example.wizard:
+  path: 'examples/form_example/wizard'
+  description: 'A general approach to a wizard multistep form.'
+  defaults:
+    _form: '\Drupal\form_example\Forms\FormExampleWizard'
+  requirements:
+    _access: 'TRUE'
diff --git a/form_example/lib/Drupal/form_example/Controller/FormExampleController.php b/form_example/lib/Drupal/form_example/Controller/FormExampleController.php
new file mode 100644
index 0000000..9ed0f61
--- /dev/null
+++ b/form_example/lib/Drupal/form_example/Controller/FormExampleController.php
@@ -0,0 +1,31 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\page_example\Controller\FormExampleController.
+ */
+
+namespace Drupal\form_example\Controller;
+
+use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
+
+/**
+ * Main Form tutorial page.
+ *
+ * @ingroup form_example
+ */
+class FormExampleController {
+
+  /**
+   * Text for our general info page.
+   *
+   * Our router maps this method to the path 'examples/form_example'.
+   */
+  function description() {
+    $build = array(
+      '#markup' => t('<p>The form example module provides a tutorial, extensible multistep example, an element example, and a #states example</p>')
+    );
+
+    return $build;
+  }
+}
diff --git a/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial.php b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial.php
new file mode 100644
index 0000000..560bf63
--- /dev/null
+++ b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial.php
@@ -0,0 +1,57 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\form_example\Form\FormExampleTutorial
+ */
+namespace Drupal\form_example\Forms;
+
+use Drupal\Core\Form\FormBase;
+
+/**
+ * This first form function is from the @link http://drupal.org/node/717722 Form Tutorial handbook page @endlink
+ *
+ * It just creates a very basic form with a textfield.
+ *
+ * This function is called the "form constructor function". It builds the form.
+ * It takes a two arguments, $form and $form_state, but if drupal_get_form()
+ * sends additional arguments, they will be provided after $form_state.
+ *
+ * @ingroup form_example
+ */
+class FormExampleTutorial extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'form_example';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+
+    $form['description'] = array(
+      '#type' => 'item',
+      '#title' => t('A form with nothing but a textfield'),
+    );
+    // This is the first form element. It's a textfield with a label, "Name"
+    $form['name'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Name'),
+    );
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, array &$form_state) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {}
+}
diff --git a/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial2.php b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial2.php
new file mode 100644
index 0000000..26d5aa4
--- /dev/null
+++ b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial2.php
@@ -0,0 +1,59 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\form_example\Form\FormExampleTutorial2
+ */
+namespace Drupal\form_example\Forms;
+
+use Drupal\Core\Form\FormBase;
+
+/**
+ * This is Example 2, a basic form with a submit button.
+ *
+ * @see http://drupal.org/node/717726
+ * @ingroup form_example
+ */
+class FormExampleTutorial2 extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'form_example_tutorial_2';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+
+    $form['description'] = array(
+      '#type' => 'item',
+      '#title' => t('A simple form with a submit button'),
+    );
+
+    $form['name'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Name'),
+    );
+
+    // Adds a simple submit button that refreshes the form and clears its
+    // contents. This is the default behavior for forms.
+    $form['submit'] = array(
+      '#type' => 'submit',
+      '#value' => 'Submit',
+    );
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, array &$form_state) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {}
+}
diff --git a/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial3.php b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial3.php
new file mode 100644
index 0000000..1140225
--- /dev/null
+++ b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial3.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\form_example\Form\FormExampleTutorial3
+ */
+namespace Drupal\form_example\Forms;
+
+use Drupal\Core\Form\FormBase;
+
+/**
+ * Example 3: A basic form with fieldsets.
+ *
+ * We establish a fieldset element and then place two text fields within
+ * it, one for a first name and one for a last name. This helps us group
+ * related content.
+ *
+ * Study the code below and you'll notice that we renamed the array of the first
+ * and last name fields by placing them under the $form['name']
+ * array. This tells Form API these fields belong to the $form['name'] fieldset.
+ *
+ * @ingroup form_example
+ */
+class FormExampleTutorial3 extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'form_example_tutorial_3';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+    $form['description'] = array(
+      '#type' => 'item',
+      '#title' => t('A form with a fieldset'),
+    );
+
+    $form['name'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Name'),
+      // Make the fieldset collapsible.
+      '#collapsible' => TRUE, // Added
+      '#collapsed' => FALSE,  // Added
+    );
+
+     $form['name']['first'] = array(
+      '#type' => 'textfield',
+      '#title' => t('First Name'),
+      '#default_value' => '',
+      '#placeholder' => t('First Name'),
+      '#required' => false,
+    );
+     $form['name']['last'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Last Name'),
+      '#default_value' => '',
+      '#placeholder' => t('Last Name'),
+      '#required' => false,
+    );
+    $form['name']['actions']['#type'] = 'actions';
+    $form['name']['actions']['submit'] = array(
+      '#name' => 'op',
+      '#type' => 'submit',
+      '#value' => t('Submit'),
+      '#button_type' => 'primary',
+    );
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, array &$form_state) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {}
+}
diff --git a/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial4.php b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial4.php
new file mode 100644
index 0000000..686088d
--- /dev/null
+++ b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial4.php
@@ -0,0 +1,75 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\form_example\Form\FormExampleTutorial4
+ */
+namespace Drupal\form_example\Forms;
+
+use Drupal\Core\Form\FormBase;
+
+/**
+ * Example 4: Basic form with required fields.
+ *
+ * @ingroup form_example
+ */
+class FormExampleTutorial4 extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'form_example_tutorial_4';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+    $form['description'] = array(
+      '#type' => 'item',
+      '#title' => t('A form with required fields'),
+    );
+
+    $form['name'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Name'),
+      // Make the fieldset collapsible.
+      '#collapsible' => TRUE, // Added
+      '#collapsed' => FALSE,  // Added
+    );
+
+     $form['name']['first'] = array(
+      '#type' => 'textfield',
+      '#title' => t('First Name'),
+      '#default_value' => '',
+      '#placeholder' => t('First Name'),
+      '#required' => TRUE,
+    );
+     $form['name']['last'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Last Name'),
+      '#default_value' => '',
+      '#placeholder' => t('Last Name'),
+      '#required' => TRUE,
+    );
+    $form['name']['actions']['#type'] = 'actions';
+    $form['name']['actions']['submit'] = array(
+      '#name' => 'op',
+      '#type' => 'submit',
+      '#value' => t('Submit'),
+      '#button_type' => 'primary',
+    );
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, array &$form_state) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {}
+}
diff --git a/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial5.php b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial5.php
new file mode 100644
index 0000000..8765460
--- /dev/null
+++ b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial5.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\form_example\Form\FormExampleTutorial4
+ */
+namespace Drupal\form_example\Forms;
+
+use Drupal\Core\Form\FormBase;
+
+/**
+ * Example 5: Basic form with additional element attributes.
+ *
+ * This demonstrates additional attributes of text form fields.
+ *
+ * For a more extensive example on element types
+ * @see http://drupal.org/node/751826
+ *
+ * See the @link http://api.drupal.org/api/file/developer/topics/forms_api.html complete form reference @endlink
+ *
+ * @ingroup form_example
+ */
+class FormExampleTutorial5 extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'form_example_tutorial_5';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+    $form['description'] = array(
+      '#type' => 'item',
+      '#title' => t('A form with additional attributes'),
+      '#description' => t('This one adds #default_value and #description'),
+    );
+
+    $form['name'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Name'),
+      // Make the fieldset collapsible.
+      '#collapsible' => TRUE, // Added
+      '#collapsed' => FALSE,  // Added
+    );
+
+    $form['name']['first'] = array(
+      '#type' => 'textfield',
+      '#title' => t('First name'),
+      '#required' => TRUE,
+      '#default_value' => "First name", // added default value.
+      '#description' => "Please enter your first name.", // added description
+      '#placeholder' => t('Last Name'),
+      '#size' => 20, // added
+      '#maxlength' => 20, // added
+    );
+     $form['name']['last'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Last Name'),
+      '#default_value' => '',
+      '#placeholder' => t('Last Name'),
+      '#required' => TRUE,
+    );
+    $form['name']['actions']['#type'] = 'actions';
+    $form['name']['actions']['submit'] = array(
+      '#name' => 'op',
+      '#type' => 'submit',
+      '#value' => t('Submit'),
+      '#button_type' => 'primary',
+    );
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function validateForm(array &$form, array &$form_state) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {}
+}
diff --git a/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial6.php b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial6.php
new file mode 100644
index 0000000..3785109
--- /dev/null
+++ b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial6.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\form_example\Form\FormExampleTutorial6
+ */
+namespace Drupal\form_example\Forms;
+
+use Drupal\Core\Form\FormBase;
+
+/**
+ * Example 6: A basic form with a validate handler.
+ *
+ * From http://drupal.org/node/717736
+ */
+class FormExampleTutorial6 extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'form_example_tutorial_6';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+    $form['description'] = array(
+      '#type' => 'item',
+      '#title' => t('A form with a validation handler'),
+    );
+
+    $form['name'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Name'),
+      '#collapsible' => TRUE,
+      '#collapsed' => FALSE,
+    );
+    $form['name']['first'] = array(
+      '#type' => 'textfield',
+      '#title' => t('First name'),
+      '#required' => TRUE,
+      '#default_value' => "First name",
+      '#description' => "Please enter your first name.",
+      '#size' => 20,
+      '#maxlength' => 20,
+    );
+    $form['name']['last'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Last name'),
+      '#required' => TRUE,
+    );
+
+    // New form field added to permit entry of year of birth.
+    // The data entered into this field will be validated with
+    // the default validation function.
+    $form['year_of_birth'] = array(
+      '#type' => 'textfield',
+      '#title' => "Year of birth",
+      '#description' => 'Format is "YYYY"',
+    );
+
+    $form['submit'] = array(
+      '#type' => 'submit',
+      '#value' => 'Submit',
+    );
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  /**
+   * Now we add a handler/function to validate the data entered into the
+   * "year of birth" field to make sure it's between the values of 1900
+   * and 2000. If not, it displays an error. The value report is
+   * $form_state['values'] (see http://drupal.org/node/144132#form-state).
+   *
+   * Notice the name of the function. It is simply the name of the form
+   * followed by '_validate'. This is always the name of the default validation
+   * function. An alternate list of validation functions could have been provided
+   * in $form['#validate'].
+   */
+  public function validateForm(array &$form, array &$form_state) {
+    $year_of_birth = $form_state['values']['year_of_birth'];
+    if ($year_of_birth && ($year_of_birth < 1900 || $year_of_birth > 2000)) {
+      form_set_error('year_of_birth', t('Enter a year between 1900 and 2000.'));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {}
+}
diff --git a/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial7.php b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial7.php
new file mode 100644
index 0000000..14a5123
--- /dev/null
+++ b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial7.php
@@ -0,0 +1,96 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\form_example\Form\FormExampleTutorial7
+ */
+namespace Drupal\form_example\Forms;
+
+use Drupal\Core\Form\FormBase;
+
+/**
+ * Example 7: A basic form with a validate handler.
+ *
+ * From http://drupal.org/node/717736
+ */
+class FormExampleTutorial7 extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'form_example_tutorial_7';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+    $form['description'] = array(
+      '#type' => 'item',
+      '#title' => t('A form with a validation handler'),
+    );
+
+    $form['name'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Name'),
+      '#collapsible' => TRUE,
+      '#collapsed' => FALSE,
+    );
+    $form['name']['first'] = array(
+      '#type' => 'textfield',
+      '#title' => t('First name'),
+      '#required' => TRUE,
+      '#default_value' => "First name",
+      '#description' => "Please enter your first name.",
+      '#size' => 20,
+      '#maxlength' => 20,
+    );
+    $form['name']['last'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Last name'),
+      '#required' => TRUE,
+    );
+
+    // New form field added to permit entry of year of birth.
+    // The data entered into this field will be validated with
+    // the default validation function.
+    $form['year_of_birth'] = array(
+      '#type' => 'textfield',
+      '#title' => "Year of birth",
+      '#description' => 'Format is "YYYY"',
+    );
+
+    $form['submit'] = array(
+      '#type' => 'submit',
+      '#value' => 'Submit',
+    );
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  /**
+   * Now we add a handler/function to validate the data entered into the
+   * "year of birth" field to make sure it's between the values of 1900
+   * and 2000. If not, it displays an error. The value report is
+   * $form_state['values'] (see http://drupal.org/node/144132#form-state).
+   *
+   * Notice the name of the function. It is simply the name of the form
+   * followed by '_validate'. This is always the name of the default validation
+   * function. An alternate list of validation functions could have been provided
+   * in $form['#validate'].
+   */
+  public function validateForm(array &$form, array &$form_state) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {
+    if ($form_state['values']['op'] == t('Submit')) {
+        drupal_set_message(t('The form has been submitted. name="@first @last", year of birth=@year_of_birth',
+    array('@first' => $form_state['values']['first'], '@last' => $form_state['values']['last'], '@year_of_birth' => $form_state['values']['year_of_birth'])));
+    }
+  }
+}
diff --git a/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial8.php b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial8.php
new file mode 100644
index 0000000..7d878e4
--- /dev/null
+++ b/form_example/lib/Drupal/form_example/Forms/FormExampleTutorial8.php
@@ -0,0 +1,171 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\form_example\Form\FormExampleTutorial8
+ */
+namespace Drupal\form_example\Forms;
+
+use Drupal\Core\Form\FormBase;
+
+/**
+ * Example 8: A simple multistep form with a Next and a Back button.
+ *
+ * Handbook page: http://drupal.org/node/717750.
+ *
+ * For more extensive multistep forms, see
+ * @link form_example_wizard.inc form_example_wizard.inc @endlink
+ *
+ *
+ * Adds logic to our form builder to give it two pages.
+ * The @link ajax_example_wizard AJAX Example's Wizard Example @endlink
+ * gives an AJAX version of this same idea.
+ *
+ * @ingroup form_example
+ */
+class FormExampleTutorial8 extends FormBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getFormID() {
+    return 'form_example_tutorial_8';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function buildForm(array $form, array &$form_state) {
+    // Display page 2 if $form_state['page_num'] == 2
+    if (!empty($form_state['page_num']) && $form_state['page_num'] == 2) {
+      return form_example_tutorial_8_page_two($form, $form_state);
+    }
+
+    // Otherwise we build page 1.
+    $form_state['page_num'] = 1;
+
+    $form['description'] = array(
+      '#type' => 'item',
+      '#title' => t('A basic multistep form (page 1)'),
+    );
+
+    $form['first'] = array(
+      '#type' => 'textfield',
+      '#title' => t('First name'),
+      '#description' => "Please enter your first name.",
+      '#size' => 20,
+      '#maxlength' => 20,
+      '#required' => TRUE,
+      '#default_value' => !empty($form_state['values']['first']) ? $form_state['values']['first'] : '',
+    );
+    $form['last'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Last name'),
+      '#default_value' => !empty($form_state['values']['last']) ? $form_state['values']['last'] : '',
+    );
+    $form['year_of_birth'] = array(
+      '#type' => 'textfield',
+      '#title' => "Year of birth",
+      '#description' => 'Format is "YYYY"',
+      '#default_value' => !empty($form_state['values']['year_of_birth']) ? $form_state['values']['year_of_birth'] : '',
+    );
+    $form['next'] = array(
+      '#type' => 'submit',
+      '#value' => 'Next >>',
+      '#submit' => array('form_example_tutorial_8_next_submit'),
+      '#validate' => array('form_example_tutorial_8_next_validate'),
+    );
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  /**
+   * Now we add a handler/function to validate the data entered into the
+   * "year of birth" field to make sure it's between the values of 1900
+   * and 2000. If not, it displays an error. The value report is
+   * $form_state['values'] (see http://drupal.org/node/144132#form-state).
+   *
+   * Notice the name of the function. It is simply the name of the form
+   * followed by '_validate'. This is always the name of the default validation
+   * function. An alternate list of validation functions could have been provided
+   * in $form['#validate'].
+   */
+  public function validateForm(array &$form, array &$form_state) {}
+
+  /**
+   * {@inheritdoc}
+   */
+  public function submitForm(array &$form, array &$form_state) {
+    if ($form_state['values']['op'] == t('Submit')) {
+        drupal_set_message(t('The form has been submitted. name="@first @last", year of birth=@year_of_birth',
+    array('@first' => $form_state['values']['first'], '@last' => $form_state['values']['last'], '@year_of_birth' => $form_state['values']['year_of_birth'])));
+    }
+  }
+}
+
+
+/**
+ * Returns the form for the second page of form_example_tutorial_8().
+ */
+function form_example_tutorial_8_page_two($form, &$form_state) {
+  $form['description'] = array(
+    '#type' => 'item',
+    '#title' => t('A basic multistep form (page 2)'),
+  );
+
+  $form['color'] = array(
+    '#type' => 'textfield',
+    '#title' => t('Favorite color'),
+    '#required' => TRUE,
+    '#default_value' => !empty($form_state['values']['color']) ? $form_state['values']['color'] : '',
+  );
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Submit'),
+    '#submit' => array('form_example_tutorial_8_page_two_submit'),
+  );
+  $form['back'] = array(
+    '#type' => 'submit',
+    '#value' => t('<< Back'),
+    '#submit' => array('form_example_tutorial_8_page_two_back'),
+    // We won't bother validating the required 'color' field, since they
+    // have to come back to this page to submit anyway.
+    '#limit_validation_errors' => array(),
+  );
+  return $form;
+}
+
+
+/**
+ * Validate handler for the next button on first page.
+ */
+function form_example_tutorial_8_next_validate($form, &$form_state) {
+  $year_of_birth = $form_state['values']['year_of_birth'];
+  if ($year_of_birth && ($year_of_birth < 1900 || $year_of_birth > 2000)) {
+    form_set_error('year_of_birth', t('Enter a year between 1900 and 2000.'));
+  }
+}
+
+/**
+ * Submit handler for form_example_tutorial_8() next button.
+ *
+ * Capture the values from page one and store them away so they can be used
+ * at final submit time.
+ */
+function form_example_tutorial_8_next_submit($form, &$form_state) {
+
+  // Values are saved for each page.
+  // to carry forward to subsequent pages in the form.
+  // and we tell FAPI to rebuild the form.
+  $form_state['page_values'][1] = $form_state['values'];
+
+  if (!empty($form_state['page_values'][2])) {
+    $form_state['values'] = $form_state['page_values'][2];
+  }
+
+  // When form rebuilds, it will look at this to figure which page to build.
+  $form_state['page_num'] = 2;
+  $form_state['rebuild'] = TRUE;
+}
diff --git a/form_example/lib/Drupal/form_example/Tests/FormExampleTestCase.php b/form_example/lib/Drupal/form_example/Tests/FormExampleTestCase.php
new file mode 100644
index 0000000..8760714
--- /dev/null
+++ b/form_example/lib/Drupal/form_example/Tests/FormExampleTestCase.php
@@ -0,0 +1,89 @@
+<?php
+/**
+ * @file
+ * Test case for testing the cron example module.
+ */
+
+/**
+ * @addtogroup cron_example
+ * @{
+ */
+namespace Drupal\form_example\Tests;
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * form_example test class
+ */
+class FormExampleTestCase extends WebTestBase {
+  public static $modules = array('form_example');
+  protected $web_user;
+
+  public static function getInfo() {
+    return array(
+      'name' => 'Cron example functionality',
+      'description' => 'Test the functionality of the Cron Example.',
+      'group' => 'Examples',
+    );
+  }
+
+  /**
+   * Enable modules and create user with specific permissions.
+   */
+  function setUp() {
+    parent::setUp();
+    // Create user. Search content permission granted for the search block to
+    // be shown.
+    $this->web_user = $this->drupalCreateUser(array('administer site configuration'));
+    $this->drupalLogin($this->web_user);
+  }
+
+  /**
+   * Login user, create an example node, and test block functionality through
+   * the admin and user interfaces.
+   */
+  function testFormExampleBasic() {
+    // Pretend that cron has never been run (even though simpletest seems to
+    // run it once...)
+    variable_set('form_example_next_execution', 0);
+    $this->drupalGet('examples/form_example');
+
+    // Initial run should cause form_example_cron() to fire.
+    $post = array();
+    $this->drupalPostForm('examples/form_example', $post, t('Run cron now'));
+    $this->assertText(t('form_example executed at'));
+
+    // Forcing should also cause form_example_cron() to fire.
+    $post['form_reset'] = TRUE;
+    $this->drupalPostForm(NULL, $post, t('Run cron now'));
+    $this->assertText(t('form_example executed at'));
+
+    // But if followed immediately and not forced, it should not fire.
+    $post['form_reset'] = FALSE;
+    $this->drupalPostForm(NULL, $post, t('Run cron now'));
+    $this->assertNoText(t('form_example executed at'));
+
+
+    $this->assertText(t('There are currently 0 items in queue 1 and 0 items in queue 2'));
+    $post = array(
+      'num_items' => 5,
+      'queue' => 'form_example_queue_1',
+    );
+    $this->drupalPostForm(NULL, $post, t('Add jobs to queue'));
+    $this->assertText('There are currently 5 items in queue 1 and 0 items in queue 2');
+    $post = array(
+      'num_items' => 100,
+      'queue' => 'form_example_queue_2',
+    );
+    $this->drupalPostForm(NULL, $post, t('Add jobs to queue'));
+    $this->assertText('There are currently 5 items in queue 1 and 100 items in queue 2');
+
+    $post = array();
+    $this->drupalPostForm('examples/form_example', $post, t('Run cron now'));
+    $this->assertPattern('/Queue 1 worker processed item with sequence 5 /');
+    $this->assertPattern('/Queue 2 worker processed item with sequence 100 /');
+  }
+}
+
+/**
+ * @} End of "addtogroup form_example".
+ */
