diff --git a/core/modules/condition/condition.module b/core/modules/condition/condition.module
index d6ed5b2..6b38c54 100644
--- a/core/modules/condition/condition.module
+++ b/core/modules/condition/condition.module
@@ -1,5 +1,92 @@
 <?php
 
+use Symfony\Component\HttpFoundation\JsonResponse;
+
+/**
+ * Implements hook_menu().
+ */
+function condition_menu() {
+  $items = array();
+  $items['admin/config/system/conditions/ajax/%'] = array(
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('condition_group_configure_condition_ajax', 5),
+    'access arguments' => array('administer conditions'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['admin/config/system/conditions'] = array(
+    'title' => 'Conditions',
+    'description' => 'Administer new condition groups.',
+    'page callback' => 'condition_group_administration',
+    'access arguments' => array('administer conditions'),
+    'type' => MENU_NORMAL_ITEM,
+  );
+  $items['admin/config/system/conditions/view'] = array(
+    'title' => 'View',
+    'type' => MENU_DEFAULT_LOCAL_TASK,
+    'weight' => -10,
+  );
+  $items['admin/config/system/conditions/add'] = array(
+    'title' => 'New Condition Group',
+    'page callback' => 'system_wizard_form',
+    'page arguments' => array('condition_group', 'edit'),
+    'access arguments' => array('administer conditions'),
+    'type' => MENU_LOCAL_ACTION,
+  );
+  $items['admin/config/system/conditions/%/%'] = array(
+    'title' => 'New Condition Group',
+    'page callback' => 'system_wizard_form',
+    'page arguments' => array('condition_group', 5, 4),
+    'access arguments' => array('administer conditions'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['admin/config/system/conditions/%/configure/%/edit'] = array(
+    'title' => 'New Condition Group',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('condition_group_configure_condition_ajax', 4, 6),
+    'access arguments' => array('administer conditions'),
+    'type' => MENU_CALLBACK,
+  );
+  $items['admin/config/system/conditions/%/configure/%/delete'] = array(
+    'title' => 'New Condition Group',
+    'page callback' => 'drupal_get_form',
+    'page arguments' => array('condition_group_delete_condition', 4, 6),
+    'access arguments' => array('administer conditions'),
+    'type' => MENU_CALLBACK,
+  );
+  return $items;
+}
+
+/**
+ * Implements hook_permission().
+ */
+function condition_permission() {
+  return array(
+    'administer conditions' => array(
+      'title' => t('Administer conditions'),
+      'description' => t('Administer the available conditions and condition groups.'),
+    )
+  );
+}
+
+/**
+ * The condition_group entity list page callback.
+ */
+function condition_group_administration() {
+  return entity_list_controller('condition_group')->render();
+}
+
+/**
+ * A load callback for condition_group entities.
+ *
+ * @param $id
+ *   The primary id of the condition group to load.
+ *
+ * @return Drupal\condition\Plugin\Core\Entity\ConditionGroup object
+ */
+function condition_group_load($id) {
+  return entity_load('condition_group', $id);
+}
+
 /**
  * Creates and configures a new condition plugin instance.
  *
@@ -18,3 +105,55 @@
 function condition($plugin_id, $options = array()) {
   return drupal_container()->get('plugin.manager.condition')->createInstance($plugin_id, $options);
 }
+
+function condition_group_configure_condition_ajax($form, &$form_state, $group_id, $row = NULL) {
+  if (!empty($form_state['input']['condition_type'])) {
+    $plugin_id = $form_state['input']['condition_type'];
+    if (!in_array($plugin_id, array_keys(drupal_container()->get('plugin.manager.condition')->getDefinitions()))) {
+      throw new \Exception("You must choose a valid condition plugin.");
+    }
+    $form['condition_type'] = array(
+      '#type' => 'hidden',
+      '#value' => $plugin_id,
+    );
+    return condition($plugin_id)->form($form, $form_state);
+  }
+  if (!is_null($row)) {
+    $entity = drupal_container()->get('user.tempstore')->get('condition_group')->get($form_state['build_info']['args'][0]);
+    $plugin_info = $entity->conditions[$row];
+    $plugin_id = array_keys($plugin_info);
+    $plugin_id = $plugin_id[0];
+    return condition($plugin_id, $plugin_info[$plugin_id])->form($form, $form_state);
+  }
+}
+
+function condition_group_configure_condition_ajax_validate($form, &$form_state) {
+  $form_state['values']['condition_plugin']->validate($form, $form_state);
+}
+
+function condition_group_configure_condition_ajax_submit($form, &$form_state) {
+  $form_state['values']['condition_plugin']->submit($form, $form_state);
+  $entity = drupal_container()->get('user.tempstore')->get('condition_group')->get($form_state['build_info']['args'][0]);
+  if (!$entity instanceof Entity) {
+    // @todo throw an exception.
+  }
+  if (isset($form_state['build_info']['args'][1]) && !is_null($form_state['build_info']['args'][1])) {
+    $entity->conditions[$form_state['build_info']['args'][1]] = array($form_state['values']['condition_plugin']->getPluginId() => $form_state['values']['condition_plugin']->getConfig());
+  }
+  else {
+    $entity->conditions[] = array($form_state['values']['condition_plugin']->getPluginId() => $form_state['values']['condition_plugin']->getConfig());
+  }
+  drupal_container()->get('user.tempstore')->get('condition_group')->set($form_state['build_info']['args'][0], $entity);
+  $form_state['redirect'] = "admin/config/system/conditions/{$form_state['build_info']['args'][0]}/configure";
+}
+
+function condition_group_delete_condition($form, &$form_state, $group_id, $row) {
+  return confirm_form($form, t('Are you sure you want to delete this condition from the group?'), "admin/config/system/conditions/{$form_state['build_info']['args'][0]}/configure");
+}
+
+function condition_group_delete_condition_submit($form, &$form_state) {
+  $entity = drupal_container()->get('user.tempstore')->get('condition_group')->get($form_state['build_info']['args'][0]);
+  unset($entity->conditions[$form_state['build_info']['args'][1]]);
+  drupal_container()->get('user.tempstore')->get('condition_group')->set($form_state['build_info']['args'][0], $entity);
+  $form_state['redirect'] = "admin/config/system/conditions/{$form_state['build_info']['args'][0]}/configure";
+}
diff --git a/core/modules/condition/lib/Drupal/condition/ConditionGroupAddFormController.php b/core/modules/condition/lib/Drupal/condition/ConditionGroupAddFormController.php
new file mode 100644
index 0000000..9840258
--- /dev/null
+++ b/core/modules/condition/lib/Drupal/condition/ConditionGroupAddFormController.php
@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\condition\ConditionGroupAddFormController.
+ */
+
+namespace Drupal\condition;
+
+use Drupal\Core\Wizard\WizardFormController;
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Form controller for the Views edit form.
+ */
+class ConditionGroupAddFormController extends WizardFormController {
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::form().
+   */
+  public function form(array $form, array &$form_state, EntityInterface $group) {
+    $form = parent::form($form, $form_state, $group);
+    $form['name'] = array(
+      '#type' => 'fieldset',
+      '#attributes' => array('class' => array('fieldset-no-legend')),
+    );
+
+    $label = $group->label();
+    $form['name']['label'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Condition Group name'),
+      '#required' => TRUE,
+      '#size' => 32,
+      '#default_value' => !empty($label) ? $label : '',
+      '#maxlength' => 255,
+      '#disabled' => !empty($label),
+    );
+    $id = $group->id();
+    $form['name']['id'] = array(
+      '#type' => 'machine_name',
+      '#maxlength' => 128,
+      '#machine_name' => array(
+        'exists' => 'condition_group_load',
+        'source' => array('name', 'label'),
+      ),
+      '#description' => t('A unique machine-readable name for this View. It must only contain lowercase letters, numbers, and underscores.'),
+      '#default_value' => !empty($id) ? $id : '',
+      '#disabled' => !empty($id),
+    );
+
+    $description = $group->get('description');
+    $form['name']['description_enable'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Description'),
+      '#default_value' => !empty($description),
+    );
+    $form['name']['description'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Provide description'),
+      '#title_display' => 'invisible',
+      '#size' => 64,
+      '#default_value' => !empty($description) ? $description : '',
+      '#states' => array(
+        'visible' => array(
+          ':input[name="description_enable"]' => array('checked' => TRUE),
+        ),
+      ),
+    );
+
+    return $form;
+  }
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::actions().
+   */
+  protected function actions(array $form, array &$form_state) {
+    $actions = parent::actions($form, $form_state);
+
+    $actions['cancel'] = array(
+      '#value' => t('Cancel'),
+      '#submit' => array(
+        array($this, 'cancel'),
+      ),
+      '#limit_validation_errors' => array(),
+    );
+    return $actions;
+  }
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::validate().
+   */
+  public function validate(array $form, array &$form_state) {
+    $entity = $this->buildEntity($form, $form_state);
+    $group = condition_group_load($form_state['values']['id']);
+    if ($group && $entity->uuid != $group->uuid) {
+      form_set_error('id', t('You must choose a unique name for your condition group.'));
+    }
+  }
+
+  /**
+   * Form submission handler for the 'cancel' action.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   * @param array $form_state
+   *   A reference to a keyed array containing the current state of the form.
+   */
+  public function cancel(array $form, array &$form_state) {
+    $entity = $this->buildEntity($form, $form_state);
+    $definition = $entity->entityInfo();
+    $id = $entity->id();
+    if ($id) {
+      drupal_container()->get('user.tempstore')->get($definition['id'])->delete($id);
+    }
+    $form_state['redirect'] = $this->redirect($entity);
+  }
+
+}
diff --git a/core/modules/condition/lib/Drupal/condition/ConditionGroupConfigureFormController.php b/core/modules/condition/lib/Drupal/condition/ConditionGroupConfigureFormController.php
new file mode 100644
index 0000000..ca4261c
--- /dev/null
+++ b/core/modules/condition/lib/Drupal/condition/ConditionGroupConfigureFormController.php
@@ -0,0 +1,112 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\condition\ConditionGroupAddFormController.
+ */
+
+namespace Drupal\condition;
+
+use Drupal\Core\Wizard\WizardFormController;
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Form controller for the Views edit form.
+ */
+class ConditionGroupConfigureFormController extends WizardFormController {
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::prepareForm().
+   */
+  protected function prepareEntity(EntityInterface $view) {
+    // Do not prepare the entity while it is being added.
+  }
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::form().
+   */
+  public function form(array $form, array &$form_state, EntityInterface $group) {
+    $form = parent::form($form, $form_state, $group);
+    $conditions = drupal_container()->get('plugin.manager.condition')->getDefinitions();
+    $options = array();
+    foreach ($conditions as $condition) {
+      $options[$condition['id']] = $condition['label'];
+    }
+    $group_conditions = $group->conditions;
+    $configured_conditions = array();
+    $uri = $group->uri();
+    foreach ($group_conditions as $row => $condition) {
+      foreach ($condition as $condition_type => $config) {
+        $build = array(
+          '#type' => 'operations',
+          '#links' => $this->getOperations($group, $row),
+        );
+        $configured_condition = condition($condition_type, $config);
+        $configured_conditions[] = array(
+          $conditions[$condition_type]['label'],
+          $configured_condition->summary(),
+          drupal_render($build)
+        );
+      }
+    }
+    $form['items'] = array(
+      '#type' => 'markup',
+      '#prefix' => '<div id="configured-conditions">',
+      '#suffix' => '</div>',
+      '#theme' => 'table',
+      '#header' => array('Type', 'Summary', 'Operations'),
+      '#rows' => $configured_conditions,
+    );
+    $form['condition_type'] = array(
+      '#type' => 'select',
+      '#title' => t('Configure a condition.'),
+      '#options' => $options,
+    );
+    $form['add'] = array(
+      '#type' => 'button',
+      '#value' => t('Add condition'),
+      '#ajax' => array(
+        'dialog' => array('modal' =>TRUE, 'width' => '750px'),
+        'path' => 'admin/config/system/conditions/ajax/' . $group->id(),
+        'wrapper' => 'configured-conditions',
+        'method' => 'replace',
+        'effect' => 'fade',
+      )
+    );
+
+    return $form;
+  }
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::validate().
+   */
+  public function validate(array $form, array &$form_state) {
+
+  }
+
+  public function getOperations(EntityInterface $entity, $row) {
+    $uri = $entity->uri();
+    $operations['edit'] = array(
+      'title' => t('Edit'),
+      'href' => $uri['path'] . '/configure/' . $row . '/edit',
+      'options' => $uri['options'],
+      'weight' => 10,
+      'ajax' => array(
+        'dialog' => array('modal' =>TRUE, 'width' => '750px'),
+        'path' => $uri['path'] . '/configure/' . $row . '/edit',
+      )
+    );
+    $operations['delete'] = array(
+      'title' => t('Delete'),
+      'href' => $uri['path'] . '/configure/' . $row . '/delete',
+      'options' => $uri['options'],
+      'weight' => 100,
+      'ajax' => array(
+        'dialog' => array('modal' =>TRUE, 'width' => '750px'),
+        'path' => $uri['path'] . '/configure/' . $row . '/delete',
+      )
+    );
+    return $operations;
+  }
+
+}
diff --git a/core/modules/condition/lib/Drupal/condition/ConditionGroupDeleteFormController.php b/core/modules/condition/lib/Drupal/condition/ConditionGroupDeleteFormController.php
new file mode 100644
index 0000000..389ca7a
--- /dev/null
+++ b/core/modules/condition/lib/Drupal/condition/ConditionGroupDeleteFormController.php
@@ -0,0 +1,48 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\condition\ConditionGroupDeleteFormController.
+ */
+
+namespace Drupal\condition;
+
+use Drupal\Core\Entity\EntityFormController;
+use Drupal\Core\Entity\EntityInterface;
+
+/**
+ * Form controller for the Views edit form.
+ */
+class ConditionGroupDeleteFormController extends EntityFormController {
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::form().
+   */
+  public function form(array $form, array &$form_state, EntityInterface $group) {
+    return confirm_form($form, t('Are you sure you want to delete the @label condition group', array('@label' => $group->label())), 'admin/config/system/conditions');
+  }
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::submit().
+   */
+  public function submit(array $form, array &$form_state) {
+    $form_state['redirect'] = 'admin/config/system/conditions';
+  }
+
+  /**
+   * Overrides Drupal\Core\Entity\EntityFormController::actions().
+   */
+  protected function actions(array $form, array &$form_state) {
+    $actions = parent::actions($form, $form_state);
+    $actions['submit']['#value'] = t('Cancel');
+
+    return $actions;
+  }
+
+  public function delete(array $form, array &$form_state) {
+    $group = $this->buildEntity($form, $form_state);
+    $group->delete();
+    $form_state['redirect'] = 'admin/config/system/conditions';
+  }
+
+}
diff --git a/core/modules/condition/lib/Drupal/condition/Plugin/ConditionPluginBase.php b/core/modules/condition/lib/Drupal/condition/Plugin/ConditionPluginBase.php
index 12bb9b9..5a89992 100644
--- a/core/modules/condition/lib/Drupal/condition/Plugin/ConditionPluginBase.php
+++ b/core/modules/condition/lib/Drupal/condition/Plugin/ConditionPluginBase.php
@@ -25,6 +25,14 @@ public function form($form, &$form_state) {
       '#title' => t('Negate the condition.'),
       '#default_value' => isset($this->configuration['negate']) ? $this->configuration['negate'] : FALSE,
     );
+    $form['condition_plugin'] = array(
+      '#type' => 'value',
+      '#value' => $this,
+    );
+    $form['actions']['submit'] = array(
+      '#type' => 'submit',
+      '#value' => t('Submit'),
+    );
     return $form;
   }
 
diff --git a/core/modules/condition/lib/Drupal/condition/Plugin/Core/Entity/ConditionGroup.php b/core/modules/condition/lib/Drupal/condition/Plugin/Core/Entity/ConditionGroup.php
new file mode 100644
index 0000000..fc89360
--- /dev/null
+++ b/core/modules/condition/lib/Drupal/condition/Plugin/Core/Entity/ConditionGroup.php
@@ -0,0 +1,98 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\condition\Plugin\Core\Entity\ConditionGroup.
+ */
+
+namespace Drupal\condition\Plugin\Core\Entity;
+
+use Drupal\Core\Config\Entity\ConfigEntityBase;
+use Drupal\Core\Annotation\Plugin;
+use Drupal\Core\Annotation\Translation;
+
+/**
+ * Defines the condition entity.
+ *
+ * @Plugin(
+ *   id = "condition_group",
+ *   label = @Translation("Condition Group"),
+ *   module = "condition",
+ *   controller_class = "Drupal\Core\Config\Entity\ConfigStorageController",
+ *   list_controller_class = "Drupal\Core\Entity\EntityListController",
+ *   form_controller_class = {
+ *     "edit" = "Drupal\condition\ConditionGroupAddFormController",
+ *     "configure" = "Drupal\condition\ConditionGroupConfigureFormController",
+ *     "delete" = "Drupal\condition\ConditionGroupDeleteFormController"
+ *   },
+ *   destination = "admin/config/system/conditions",
+ *   steps = {
+ *     "edit" = @Translation("Edit details"),
+ *     "configure" = @Translation("Configure conditions"),
+ *   },
+ *   config_prefix = "condition.group",
+ *   entity_keys = {
+ *     "id" = "id",
+ *     "label" = "label",
+ *     "uuid" = "uuid"
+ *   }
+ * )
+ */
+class ConditionGroup extends ConfigEntityBase {
+
+  /**
+   * The name of the condition group.
+   *
+   * @var string
+   */
+  public $id;
+
+  /**
+   * The condition group label.
+   *
+   * @var string
+   */
+  public $label;
+
+  /**
+   * The condition group UUID.
+   *
+   * @var string
+   */
+  public $uuid;
+
+  /**
+   * The condition group description.
+   *
+   * @var string
+   */
+  public $description;
+
+  /**
+   * The condition group condition plugin_ids and configuration.
+   *
+   * @var array
+   */
+  public $conditions = array();
+
+  /**
+   * Overrides \Drupal\Core\Entity\Entity::id().
+   */
+  public function id() {
+    return $this->id;
+  }
+
+  /**
+   * Overrides \Drupal\Core\Entity\EntityInterface::uri().
+   */
+  public function uri() {
+    return array(
+      'path' => 'admin/config/system/conditions/' . $this->id(),
+      'options' => array(
+        'entity_type' => $this->entityType,
+        'entity' => $this,
+      ),
+    );
+  }
+
+}
diff --git a/core/modules/node/lib/Drupal/node/Plugin/Core/Condition/NodeType.php b/core/modules/node/lib/Drupal/node/Plugin/Core/Condition/NodeType.php
index 828c524..3824506 100644
--- a/core/modules/node/lib/Drupal/node/Plugin/Core/Condition/NodeType.php
+++ b/core/modules/node/lib/Drupal/node/Plugin/Core/Condition/NodeType.php
@@ -28,25 +28,20 @@
  *   }
  * )
  */
-
 class NodeType extends ConditionPluginBase {
 
   /**
    * Implements \Drupal\condition\Plugin\ConditionInterface::form().
    */
   public function form($form, &$form_state) {
-    $form = parent::form($form, $form_state);
-    $options = array();
-    foreach (node_type_get_types() as $type) {
-      $options[$type->type] = $type->name;
-    }
     $form['bundles'] = array(
+      '#title' => t('Choose a node bundle:'),
       '#type' => 'checkboxes',
-      '#options' => $options,
+      '#options' => node_type_get_names(),
       '#required' => TRUE,
       '#default_value' => isset($this->configuration['bundles']) ? $this->configuration['bundles'] : array(),
     );
-    return $form;
+    return parent::form($form, $form_state);
   }
 
   /**
@@ -64,7 +59,7 @@ public function validate($form, &$form_state) {
    * Implements \Drupal\condition\ConditionInterface::submit().
    */
   public function submit($form, &$form_state) {
-    $this->configuration['bundles'] = $form_state['values']['bundles'];
+    $this->configuration['bundles'] = array_filter($form_state['values']['bundles']);
     parent::submit($form, $form_state);
   }
 
@@ -76,10 +71,20 @@ public function summary() {
       $bundles = $this->configuration['bundles'];
       $last = array_pop($bundles);
       $bundles = implode(', ', $bundles);
-      return t('The node bundle is @bundles or @last', array('@bundles' => $bundles, '@last' => $last));
+      return t('The node bundle is @not@bundles or @last',
+        array(
+          '@bundles' => $bundles,
+          '@last' => $last,
+          '@not' => $this->configuration['negate'] ? 'not ' : ''
+        )
+      );
     }
-    $bundle = $this->configuration['bundles'][0];
-    return t('The node bundle is @bundle', array('@bundle' => $bundle));
+    $bundle = array_pop($this->configuration['bundles']);
+    return t('The node bundle is @not@bundle',
+      array(
+        '@bundle' => $bundle,
+        '@not' => $this->configuration['negate'] ? 'not ' : '')
+    );
   }
 
   /**
