diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Type/AbstractType.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Type/AbstractType.php
index b4c8d96bbdc11a4d47cafb77d8121a9c46d40e52..734fe6bc0db2b7d667c742cf2753d8e868f2255a 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Type/AbstractType.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Type/AbstractType.php
@@ -70,13 +70,17 @@ class AbstractType extends \Magento\Backend\Block\Widget
     /**
      * Get html of Price Type select element
      *
+     * @param string $extraParams
      * @return string
      */
-    public function getPriceTypeSelectHtml()
+    public function getPriceTypeSelectHtml($extraParams = '')
     {
         if ($this->getCanEditPrice() === false) {
-            $this->getChildBlock('option_price_type')->setExtraParams('disabled="disabled"');
+            $extraParams .= ' disabled="disabled"';
+            $this->getChildBlock('option_price_type');
         }
+        $this->getChildBlock('option_price_type')->setExtraParams($extraParams);
+
         return $this->getChildHtml('option_price_type');
     }
 }
diff --git a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Type/Select.php b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Type/Select.php
index c91c09dcb9f15fe552930a1bd7a4e03bd3350deb..621420cfecec31e64c9d3b5a0ef8565c57bf8cac 100644
--- a/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Type/Select.php
+++ b/app/code/Magento/Catalog/Block/Adminhtml/Product/Edit/Tab/Options/Type/Select.php
@@ -90,8 +90,8 @@ class Select extends \Magento\Catalog\Block\Adminhtml\Product\Edit\Tab\Options\T
             'product_option_<%- data.id %>_select_<%- data.select_id %>_price_type'
         )->setName(
             'product[options][<%- data.id %>][values][<%- data.select_id %>][price_type]'
-        )->setExtraParams($extraParams);
+        );
 
-        return parent::getPriceTypeSelectHtml();
+        return parent::getPriceTypeSelectHtml($extraParams);
     }
 }
diff --git a/app/code/Magento/Catalog/Ui/Component/FilterFactory.php b/app/code/Magento/Catalog/Ui/Component/FilterFactory.php
index a32daf19149a530ad1b685b5ac9b200dc8fca28f..0cd46daccf81ceeef50d513d55dff83f2a35b68d 100644
--- a/app/code/Magento/Catalog/Ui/Component/FilterFactory.php
+++ b/app/code/Magento/Catalog/Ui/Component/FilterFactory.php
@@ -34,15 +34,19 @@ class FilterFactory
     /**
      * @param \Magento\Catalog\Api\Data\ProductAttributeInterface $attribute
      * @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context
+     * @param array $config
      * @return \Magento\Ui\Component\Listing\Columns\ColumnInterface
      */
-    public function create($attribute, $context)
+    public function create($attribute, $context, $config = [])
     {
         $columnName = $attribute->getAttributeCode();
-        $config = [
-            'dataScope' => $columnName,
-            'label' => __($attribute->getDefaultFrontendLabel()),
-        ];
+        $config = array_merge(
+            [
+                'dataScope' => $columnName,
+                'label' => __($attribute->getDefaultFrontendLabel()),
+            ],
+            $config
+        );
         if ($attribute->usesSource() && $attribute->getSourceModel()) {
             $config['options'] = $attribute->getSource()->getAllOptions();
             $config['caption'] = __('Select...');
diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/Attribute/AbstractRepository.php b/app/code/Magento/Catalog/Ui/Component/Listing/Attribute/AbstractRepository.php
new file mode 100644
index 0000000000000000000000000000000000000000..aff12f7aed976812a062ceba2c64be85aab18b6e
--- /dev/null
+++ b/app/code/Magento/Catalog/Ui/Component/Listing/Attribute/AbstractRepository.php
@@ -0,0 +1,47 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Ui\Component\Listing\Attribute;
+
+abstract class AbstractRepository implements RepositoryInterface
+{
+    /**
+     * @var null|\Magento\Catalog\Api\Data\ProductAttributeInterface[]
+     */
+    protected $attributes;
+
+    /** @var \Magento\Framework\Api\SearchCriteriaBuilder */
+    protected $searchCriteriaBuilder;
+
+    /**
+     * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $productAttributeRepository
+     * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
+     */
+    public function __construct(
+        \Magento\Catalog\Api\ProductAttributeRepositoryInterface $productAttributeRepository,
+        \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
+    ) {
+        $this->productAttributeRepository = $productAttributeRepository;
+        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    abstract protected function buildSearchCriteria();
+
+    /**
+     * @return \Magento\Catalog\Api\Data\ProductAttributeInterface[]
+     */
+    public function getList()
+    {
+        if (null == $this->attributes) {
+            $this->attributes = $this->productAttributeRepository
+                ->getList($this->buildSearchCriteria())
+                ->getItems();
+        }
+        return $this->attributes;
+    }
+}
diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/Attribute/Repository.php b/app/code/Magento/Catalog/Ui/Component/Listing/Attribute/Repository.php
new file mode 100644
index 0000000000000000000000000000000000000000..c954ec8b636df3f864961d48d3e03cd320680a95
--- /dev/null
+++ b/app/code/Magento/Catalog/Ui/Component/Listing/Attribute/Repository.php
@@ -0,0 +1,17 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Ui\Component\Listing\Attribute;
+
+class Repository extends AbstractRepository
+{
+    /**
+     * {@inheritdoc}
+     */
+    protected function buildSearchCriteria()
+    {
+        return $this->searchCriteriaBuilder->addFilter('additional_table.is_used_in_grid', 1)->create();
+    }
+}
diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/Attribute/RepositoryInterface.php b/app/code/Magento/Catalog/Ui/Component/Listing/Attribute/RepositoryInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..b65cce8055c69d079c8638c192a75fabcfc6eb39
--- /dev/null
+++ b/app/code/Magento/Catalog/Ui/Component/Listing/Attribute/RepositoryInterface.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Catalog\Ui\Component\Listing\Attribute;
+
+interface RepositoryInterface
+{
+    /**
+     * Get attributes
+     *
+     * @return \Magento\Catalog\Api\Data\ProductAttributeInterface[]
+     */
+    public function getList();
+}
diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/AttributeRepository.php b/app/code/Magento/Catalog/Ui/Component/Listing/AttributeRepository.php
deleted file mode 100644
index 4f7351a3222fb1dc87ce9152c881653b2d17c962..0000000000000000000000000000000000000000
--- a/app/code/Magento/Catalog/Ui/Component/Listing/AttributeRepository.php
+++ /dev/null
@@ -1,42 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\Catalog\Ui\Component\Listing;
-
-class AttributeRepository extends \Magento\Ui\Component\Listing\Columns
-{
-    /**
-     * @var null|\Magento\Catalog\Api\Data\ProductAttributeInterface[]
-     */
-    private $attributes;
-
-    /**
-     * @param \Magento\Catalog\Model\Resource\Product\Attribute\Collection $attributeCollection
-     * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $productAttributeRepository
-     */
-    public function __construct(
-        \Magento\Catalog\Model\Resource\Product\Attribute\Collection $attributeCollection,
-        \Magento\Catalog\Api\ProductAttributeRepositoryInterface $productAttributeRepository
-    ) {
-        $this->attributeCollection = $attributeCollection;
-        $this->productAttributeRepository = $productAttributeRepository;
-    }
-
-    /**
-     * @return \Magento\Catalog\Api\Data\ProductAttributeInterface[]
-     */
-    public function getList()
-    {
-        if (null == $this->attributes) {
-            $this->attributes = [];
-            $this->attributeCollection->addIsUsedInGridFilter();
-            foreach ($this->attributeCollection as $attribute) {
-                $attribute = $this->productAttributeRepository->get($attribute->getAttributeId());
-                $this->attributes[] = $attribute;
-            }
-        }
-        return $this->attributes;
-    }
-}
diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/Columns.php b/app/code/Magento/Catalog/Ui/Component/Listing/Columns.php
index 47b621b0bfceffec2188cbae6264d6b80d32d969..2e0243e5875aaba35f44914ba5eebc908d7d1470 100644
--- a/app/code/Magento/Catalog/Ui/Component/Listing/Columns.php
+++ b/app/code/Magento/Catalog/Ui/Component/Listing/Columns.php
@@ -12,17 +12,20 @@ class Columns extends \Magento\Ui\Component\Listing\Columns
      */
     const DEFAULT_COLUMNS_MAX_ORDER = 100;
 
+    /** @var \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface */
+    protected $attributeRepository;
+
     /**
      * @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context
      * @param \Magento\Catalog\Ui\Component\ColumnFactory $columnFactory
-     * @param AttributeRepository $attributeRepository
+     * @param \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface $attributeRepository
      * @param array $components
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\UiComponent\ContextInterface $context,
         \Magento\Catalog\Ui\Component\ColumnFactory $columnFactory,
-        \Magento\Catalog\Ui\Component\Listing\AttributeRepository $attributeRepository,
+        \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface $attributeRepository,
         array $components = [],
         array $data = []
     ) {
diff --git a/app/code/Magento/Catalog/Ui/Component/Listing/Filters.php b/app/code/Magento/Catalog/Ui/Component/Listing/Filters.php
index 9c2950a596bca51b0c183efce2708bd9a19ecc27..ba70b679b5e4e4e44781ad1a8363b07e7ce05ad6 100644
--- a/app/code/Magento/Catalog/Ui/Component/Listing/Filters.php
+++ b/app/code/Magento/Catalog/Ui/Component/Listing/Filters.php
@@ -8,21 +8,21 @@ namespace Magento\Catalog\Ui\Component\Listing;
 class Filters extends \Magento\Ui\Component\Filters
 {
     /**
-     * @var AttributeRepository
+     * @var \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface
      */
     protected $attributeRepository;
 
     /**
      * @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context
      * @param \Magento\Catalog\Ui\Component\FilterFactory $filterFactory
-     * @param AttributeRepository $attributeRepository
+     * @param \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface $attributeRepository
      * @param array $components
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\UiComponent\ContextInterface $context,
         \Magento\Catalog\Ui\Component\FilterFactory $filterFactory,
-        \Magento\Catalog\Ui\Component\Listing\AttributeRepository $attributeRepository,
+        \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface $attributeRepository,
         array $components = [],
         array $data = []
     ) {
diff --git a/app/code/Magento/Catalog/etc/adminhtml/di.xml b/app/code/Magento/Catalog/etc/adminhtml/di.xml
index 5cf13196cbd26779ea6c7619a34636e9aef6163b..295f42a5b19495d8a1548cb840c1ba06e3de6a17 100644
--- a/app/code/Magento/Catalog/etc/adminhtml/di.xml
+++ b/app/code/Magento/Catalog/etc/adminhtml/di.xml
@@ -79,4 +79,5 @@
     <type name="Magento\Catalog\Model\Product\Action">
         <plugin name="invalidate_pagecache_after_update_product_attributes" type="Magento\Catalog\Plugin\Model\Product\Action\UpdateAttributesFlushCache"/>
     </type>
+    <preference for="Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface" type="Magento\Catalog\Ui\Component\Listing\Attribute\Repository"/>
 </config>
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options.phtml
index aa49671e94509083573c814575a38a9e9af69140..67b1e95e3084663f375efad98714f295ac897c41 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options.phtml
@@ -15,7 +15,7 @@
             <span><?php /* @escapeNotVerified */ echo __('Custom Options') ?></span>
         </strong>
     </div>
-    <div class="fieldset-wrapper-content" id="product-custom-options-content">
+    <div class="fieldset-wrapper-content" id="product-custom-options-content" data-role="product-custom-options-content">
         <fieldset class="fieldset">
             <div class="messages">
                 <div class="message message-error" id="dynamic-price-warning" style="display: none;">
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/date.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/date.phtml
index dc8c8f8ce1990920d70ddf8c4d2f10753863b3e3..d8d09c8ff7758705783c1486110a99c0a50abdde 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/date.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/date.phtml
@@ -31,7 +31,9 @@
                            disabled="disabled"
                         <?php endif; ?>>
                 </td>
-                <td class="opt-price-type"><?php echo $block->getPriceTypeSelectHtml() ?><%- data.checkboxScopePrice %></td>
+                <td class="opt-price-type">
+                    <?php echo $block->getPriceTypeSelectHtml('data-attr="price-type"') ?><%- data.checkboxScopePrice %>
+                </td>
                 <?php else : ?>
                 <input id="product_option_<%- data.option_id %>_price" name="product[options][<%- data.option_id %>][price]" type="hidden">
                 <input id="product_option_<%- data.option_id %>_price_type" name="product[options][<%- data.option_id %>][price_type]" type="hidden">
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/file.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/file.phtml
index afe552f4ab82954c90fd8e00df8982f2661858e8..7be294debacf1406de7cb4ecb41db66dd0e386e5 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/file.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/file.phtml
@@ -31,7 +31,7 @@
                            disabled="disabled"
                         <?php endif; ?>>
                 </td>
-                <td class="opt-price-type"><?php echo $block->getPriceTypeSelectHtml() ?><%- data.checkboxScopePrice %></td>
+                <td class="opt-price-type"><?php echo $block->getPriceTypeSelectHtml('data-attr="price-type"') ?><%- data.checkboxScopePrice %></td>
                 <?php else : ?>
                 <input name="product[options][<%- data.option_id %>][price]" type="hidden">
                 <input id="product_option_<%- data.option_id %>_price_type" name="product[options][<%- data.option_id %>][price_type]" type="hidden">
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/select.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/select.phtml
index eae5c113215ce90382fc023da67943e5a64290de..da7b6eef24963254ac343ef300037157b25ba00b 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/select.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/select.phtml
@@ -57,7 +57,9 @@
                    disabled="disabled"
                 <?php endif; ?>>
         </td>
-        <td class="col-price-type select-opt-price-type"><?php /* @escapeNotVerified */ echo $block->getPriceTypeSelectHtml('<% if (typeof data.scopePriceDisabled != "undefined" && data.scopePriceDisabled != null) { %> disabled="disabled" <% } %>') ?><%- data.checkboxScopePrice %></td>
+        <td class="col-price-type select-opt-price-type">
+            <?php /* @escapeNotVerified */ echo $block->getPriceTypeSelectHtml('data-attr="price-type" <% if (typeof data.scopePriceDisabled != "undefined" && data.scopePriceDisabled != null) { %> disabled="disabled" <% } %>') ?><%- data.checkboxScopePrice %>
+        </td>
         <?php else : ?>
         <input id="product_option_<%- data.id %>_select_<%- data.select_id %>_price" name="product[options][<%- data.id %>][values][<%- data.select_id %>][price]" type="hidden">
         <input id="product_option_<%- data.id %>_select_<%- data.select_id %>_price_type" name="product[options][<%- data.id %>][values][<%- data.select_id %>][price_type]" type="hidden">
diff --git a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/text.phtml b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/text.phtml
index bcc6f5171dc64be5563e181f1f230f6ff58b6fe1..769c6c1749ed3fbb2611441567d717b1852c8f6f 100644
--- a/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/text.phtml
+++ b/app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/edit/options/type/text.phtml
@@ -32,7 +32,7 @@
                            disabled="disabled"
                         <?php endif; ?>>
                 </td>
-                <td class="opt-price-type"><?php echo $block->getPriceTypeSelectHtml() ?><%- data.checkboxScopePrice %></td>
+                <td class="opt-price-type"><?php echo $block->getPriceTypeSelectHtml('data-attr="price-type"') ?><%- data.checkboxScopePrice %></td>
                 <?php else : ?>
                 <input id="product_option_<%- data.option_id %>_price" name="product[options][<%- data.option_id %>][price]" type="hidden">
                 <input id="product_option_<%- data.option_id %>_price_type" name="product[options][<%- data.option_id %>][price_type]" type="hidden">
diff --git a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php
index 3f7477dbd79c7ee9ecb6c6f2153ca7e022ebc895..b156879d0f96ad98d1ee02345287f5a1ed842a57 100644
--- a/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php
+++ b/app/code/Magento/CatalogRule/Model/Indexer/IndexBuilder.php
@@ -248,7 +248,7 @@ class IndexBuilder
             ]
         );
 
-        if (!$rule->getConditions()->validate($product)) {
+        if (!$rule->validate($product)) {
             $this->connection->delete(
                 $this->resource->getTableName('catalogrule_product_price'),
                 [$this->connection->quoteInto('product_id = ?', $productId)]
diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php
index 3687d55d4710fba30b24b144e14c0691e972730f..b043c6078d21130f0709d8297d8851437742363f 100644
--- a/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php
+++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Indexer/IndexBuilderTest.php
@@ -168,7 +168,6 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase
 
         $this->rules->expects($this->any())->method('getId')->will($this->returnValue(1));
         $this->rules->expects($this->any())->method('getWebsiteIds')->will($this->returnValue([1]));
-        $this->rules->expects($this->any())->method('getConditions')->will($this->returnValue($this->combine));
         $this->rules->expects($this->any())->method('getCustomerGroupIds')->will($this->returnValue([1]));
 
         $this->ruleCollectionFactory->expects($this->any())->method('create')->will($this->returnSelf());
@@ -180,7 +179,7 @@ class IndexBuilderTest extends \PHPUnit_Framework_TestCase
         $this->product->expects($this->any())->method('getId')->will($this->returnValue(1));
         $this->product->expects($this->any())->method('getWebsiteIds')->will($this->returnValue([1]));
 
-        $this->combine->expects($this->any())->method('validate')->will($this->returnValue(true));
+        $this->rules->expects($this->any())->method('validate')->with($this->product)->willReturn(true);
         $this->attribute->expects($this->any())->method('getBackend')->will($this->returnValue($this->backend));
         $this->productFactory->expects($this->any())->method('create')->will($this->returnValue($this->product));
 
diff --git a/app/code/Magento/CatalogRuleConfigurable/LICENSE.txt b/app/code/Magento/CatalogRuleConfigurable/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..49525fd99da9c51e6d85420266d41cb3d6b7a648
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/LICENSE.txt
@@ -0,0 +1,48 @@
+
+Open Software License ("OSL") v. 3.0
+
+This Open Software License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:
+
+Licensed under the Open Software License version 3.0
+
+   1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:
+
+         1. to reproduce the Original Work in copies, either alone or as part of a collective work;
+
+         2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;
+
+         3. to distribute or communicate copies of the Original Work and Derivative Works to the public, with the proviso that copies of Original Work or Derivative Works that You distribute or communicate shall be licensed under this Open Software License;
+
+         4. to perform the Original Work publicly; and
+
+         5. to display the Original Work publicly. 
+
+   2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.
+
+   3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.
+
+   4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.
+
+   5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).
+
+   6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
+
+   7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.
+
+   8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.
+
+   9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including 'fair use' or 'fair dealing'). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).
+
+  10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
+
+  11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.
+
+  12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
+
+  13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
+
+  14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+  15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
+
+  16. Modification of This License. This License is Copyright (C) 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Open Software License" or "OSL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.
\ No newline at end of file
diff --git a/app/code/Magento/CatalogRuleConfigurable/LICENSE_AFL.txt b/app/code/Magento/CatalogRuleConfigurable/LICENSE_AFL.txt
new file mode 100644
index 0000000000000000000000000000000000000000..87943b95d43a5bb8736093275afe3cb8e1d93d26
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/LICENSE_AFL.txt
@@ -0,0 +1,48 @@
+
+Academic Free License ("AFL") v. 3.0
+
+This Academic Free License (the "License") applies to any original work of authorship (the "Original Work") whose owner (the "Licensor") has placed the following licensing notice adjacent to the copyright notice for the Original Work:
+
+Licensed under the Academic Free License version 3.0
+
+   1. Grant of Copyright License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, for the duration of the copyright, to do the following:
+
+         1. to reproduce the Original Work in copies, either alone or as part of a collective work;
+
+         2. to translate, adapt, alter, transform, modify, or arrange the Original Work, thereby creating derivative works ("Derivative Works") based upon the Original Work;
+
+         3. to distribute or communicate copies of the Original Work and Derivative Works to the public, under any license of your choice that does not contradict the terms and conditions, including Licensor's reserved rights and remedies, in this Academic Free License;
+
+         4. to perform the Original Work publicly; and
+
+         5. to display the Original Work publicly.
+
+   2. Grant of Patent License. Licensor grants You a worldwide, royalty-free, non-exclusive, sublicensable license, under patent claims owned or controlled by the Licensor that are embodied in the Original Work as furnished by the Licensor, for the duration of the patents, to make, use, sell, offer for sale, have made, and import the Original Work and Derivative Works.
+
+   3. Grant of Source Code License. The term "Source Code" means the preferred form of the Original Work for making modifications to it and all available documentation describing how to modify the Original Work. Licensor agrees to provide a machine-readable copy of the Source Code of the Original Work along with each copy of the Original Work that Licensor distributes. Licensor reserves the right to satisfy this obligation by placing a machine-readable copy of the Source Code in an information repository reasonably calculated to permit inexpensive and convenient access by You for as long as Licensor continues to distribute the Original Work.
+
+   4. Exclusions From License Grant. Neither the names of Licensor, nor the names of any contributors to the Original Work, nor any of their trademarks or service marks, may be used to endorse or promote products derived from this Original Work without express prior permission of the Licensor. Except as expressly stated herein, nothing in this License grants any license to Licensor's trademarks, copyrights, patents, trade secrets or any other intellectual property. No patent license is granted to make, use, sell, offer for sale, have made, or import embodiments of any patent claims other than the licensed claims defined in Section 2. No license is granted to the trademarks of Licensor even if such marks are included in the Original Work. Nothing in this License shall be interpreted to prohibit Licensor from licensing under terms different from this License any Original Work that Licensor otherwise would have a right to license.
+
+   5. External Deployment. The term "External Deployment" means the use, distribution, or communication of the Original Work or Derivative Works in any way such that the Original Work or Derivative Works may be used by anyone other than You, whether those works are distributed or communicated to those persons or made available as an application intended for use over a network. As an express condition for the grants of license hereunder, You must treat any External Deployment by You of the Original Work or a Derivative Work as a distribution under section 1(c).
+
+   6. Attribution Rights. You must retain, in the Source Code of any Derivative Works that You create, all copyright, patent, or trademark notices from the Source Code of the Original Work, as well as any notices of licensing and any descriptive text identified therein as an "Attribution Notice." You must cause the Source Code for any Derivative Works that You create to carry a prominent Attribution Notice reasonably calculated to inform recipients that You have modified the Original Work.
+
+   7. Warranty of Provenance and Disclaimer of Warranty. Licensor warrants that the copyright in and to the Original Work and the patent rights granted herein by Licensor are owned by the Licensor or are sublicensed to You under the terms of this License with the permission of the contributor(s) of those copyrights and patent rights. Except as expressly stated in the immediately preceding sentence, the Original Work is provided under this License on an "AS IS" BASIS and WITHOUT WARRANTY, either express or implied, including, without limitation, the warranties of non-infringement, merchantability or fitness for a particular purpose. THE ENTIRE RISK AS TO THE QUALITY OF THE ORIGINAL WORK IS WITH YOU. This DISCLAIMER OF WARRANTY constitutes an essential part of this License. No license to the Original Work is granted by this License except under this disclaimer.
+
+   8. Limitation of Liability. Under no circumstances and under no legal theory, whether in tort (including negligence), contract, or otherwise, shall the Licensor be liable to anyone for any indirect, special, incidental, or consequential damages of any character arising as a result of this License or the use of the Original Work including, without limitation, damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses. This limitation of liability shall not apply to the extent applicable law prohibits such limitation.
+
+   9. Acceptance and Termination. If, at any time, You expressly assented to this License, that assent indicates your clear and irrevocable acceptance of this License and all of its terms and conditions. If You distribute or communicate copies of the Original Work or a Derivative Work, You must make a reasonable effort under the circumstances to obtain the express assent of recipients to the terms of this License. This License conditions your rights to undertake the activities listed in Section 1, including your right to create Derivative Works based upon the Original Work, and doing so without honoring these terms and conditions is prohibited by copyright law and international treaty. Nothing in this License is intended to affect copyright exceptions and limitations (including "fair use" or "fair dealing"). This License shall terminate immediately and You may no longer exercise any of the rights granted to You by this License upon your failure to honor the conditions in Section 1(c).
+
+  10. Termination for Patent Action. This License shall terminate automatically and You may no longer exercise any of the rights granted to You by this License as of the date You commence an action, including a cross-claim or counterclaim, against Licensor or any licensee alleging that the Original Work infringes a patent. This termination provision shall not apply for an action alleging patent infringement by combinations of the Original Work with other software or hardware.
+
+  11. Jurisdiction, Venue and Governing Law. Any action or suit relating to this License may be brought only in the courts of a jurisdiction wherein the Licensor resides or in which Licensor conducts its primary business, and under the laws of that jurisdiction excluding its conflict-of-law provisions. The application of the United Nations Convention on Contracts for the International Sale of Goods is expressly excluded. Any use of the Original Work outside the scope of this License or after its termination shall be subject to the requirements and penalties of copyright or patent law in the appropriate jurisdiction. This section shall survive the termination of this License.
+
+  12. Attorneys' Fees. In any action to enforce the terms of this License or seeking damages relating thereto, the prevailing party shall be entitled to recover its costs and expenses, including, without limitation, reasonable attorneys' fees and costs incurred in connection with such action, including any appeal of such action. This section shall survive the termination of this License.
+
+  13. Miscellaneous. If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable.
+
+  14. Definition of "You" in This License. "You" throughout this License, whether in upper or lower case, means an individual or a legal entity exercising rights under, and complying with all of the terms of, this License. For legal entities, "You" includes any entity that controls, is controlled by, or is under common control with you. For purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
+
+  15. Right to Use. You may use the Original Work in all ways not otherwise restricted or conditioned by this License or by law, and Licensor promises not to interfere with or be responsible for such uses by You.
+
+  16. Modification of This License. This License is Copyright © 2005 Lawrence Rosen. Permission is granted to copy, distribute, or communicate this License without modification. Nothing in this License permits You to modify this License as applied to the Original Work or to Derivative Works. However, You may modify the text of this License and copy, distribute or communicate your modified version (the "Modified License") and apply it to other original works of authorship subject to the following conditions: (i) You may not indicate in any way that your Modified License is the "Academic Free License" or "AFL" and you may not use those names in the name of your Modified License; (ii) You must replace the notice specified in the first paragraph above with the notice "Licensed under <insert your license name here>" or with a notice of your own that is not confusingly similar to the notice in this License; and (iii) You may not claim that your original works are open source software unless your Modified License has been approved by Open Source Initiative (OSI) and You comply with its license review and certification process.
\ No newline at end of file
diff --git a/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/ConfigurableProductsProvider.php b/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/ConfigurableProductsProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..c9a049eac678545bc27a8265aa6693e32b2f8966
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/ConfigurableProductsProvider.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model;
+
+class ConfigurableProductsProvider
+{
+    /** @var \Magento\Framework\App\Resource */
+    private $resource;
+
+    /**
+     * @param \Magento\Framework\App\Resource $resource
+     */
+    public function __construct(\Magento\Framework\App\Resource $resource)
+    {
+        $this->resource = $resource;
+    }
+
+    /**
+     * @param array $ids
+     * @return array
+     */
+    public function getIds(array $ids)
+    {
+        $connection = $this->resource->getConnection();
+        return $connection->fetchCol(
+            $connection
+                ->select()
+                ->from(['e' => $this->resource->getTableName('catalog_product_entity')], ['e.entity_id'])
+                ->where('e.type_id = ?', \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE)
+                ->where('e.entity_id IN (?)', $ids)
+        );
+    }
+}
diff --git a/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/Indexer/ProductRuleReindex.php b/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/Indexer/ProductRuleReindex.php
new file mode 100644
index 0000000000000000000000000000000000000000..642736cff51c735a74201e91b5fbbc0d8245040a
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/Indexer/ProductRuleReindex.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Indexer;
+
+use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
+use Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\ConfigurableProductsProvider;
+
+/**
+ * Class ReindexProduct. Add configurable sub-products to reindex
+ */
+class ProductRuleReindex
+{
+    /** @var Configurable */
+    private $configurable;
+
+    /** @var ConfigurableProductsProvider */
+    private $configurableProductsProvider;
+
+    /**
+     * @param Configurable $configurable
+     * @param ConfigurableProductsProvider $configurableProductsProvider
+     */
+    public function __construct(
+        Configurable $configurable,
+        ConfigurableProductsProvider $configurableProductsProvider
+    ) {
+        $this->configurable = $configurable;
+        $this->configurableProductsProvider = $configurableProductsProvider;
+    }
+
+    /**
+     * @param \Magento\CatalogRule\Model\Indexer\Product\ProductRuleIndexer $subject
+     * @param \Closure $proceed
+     * @param int $id
+     *
+     * @return void
+     */
+    public function aroundExecuteRow(
+        \Magento\CatalogRule\Model\Indexer\Product\ProductRuleIndexer $subject,
+        \Closure $proceed,
+        $id
+    ) {
+        $configurableProductIds = $this->configurableProductsProvider->getIds([$id]);
+        $this->reindexSubProducts($configurableProductIds, $subject);
+        if (!$configurableProductIds) {
+            $proceed($id);
+        }
+    }
+
+    /**
+     * @param \Magento\CatalogRule\Model\Indexer\Product\ProductRuleIndexer $subject
+     * @param \Closure $proceed
+     * @param array $ids
+     *
+     * @return void
+     */
+    public function aroundExecuteList(
+        \Magento\CatalogRule\Model\Indexer\Product\ProductRuleIndexer $subject,
+        \Closure $proceed,
+        array $ids
+    ) {
+        $configurableProductIds = $this->configurableProductsProvider->getIds($ids);
+        $subProducts = $this->reindexSubProducts($configurableProductIds, $subject);
+        $ids = array_diff($ids, $configurableProductIds, $subProducts);
+        if ($ids) {
+            $proceed($ids);
+        }
+    }
+
+    /**
+     * @param array $configurableIds
+     * @param \Magento\CatalogRule\Model\Indexer\Product\ProductRuleIndexer $subject
+     *
+     * @return array
+     */
+    private function reindexSubProducts(
+        array $configurableIds,
+        \Magento\CatalogRule\Model\Indexer\Product\ProductRuleIndexer $subject
+    ) {
+        $subProducts = [];
+        if ($configurableIds) {
+            $subProducts = array_values($this->configurable->getChildrenIds($configurableIds)[0]);
+            if ($subProducts) {
+                $subject->executeList($subProducts);
+            }
+        }
+        return $subProducts;
+    }
+}
diff --git a/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/Rule/ConfigurableProductHandler.php b/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/Rule/ConfigurableProductHandler.php
new file mode 100644
index 0000000000000000000000000000000000000000..156ec7edd7ef743117ce6b61bd6259e92473b51c
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/Rule/ConfigurableProductHandler.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule;
+
+use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
+use Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\ConfigurableProductsProvider;
+
+/**
+ * Add configurable sub products to catalog rule indexer on full reindex
+ */
+class ConfigurableProductHandler
+{
+    /** @var \Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable */
+    private $configurable;
+
+    /** @var ConfigurableProductsProvider */
+    private $configurableProductsProvider;
+
+    /** @var array */
+    private $subProductsValidationResults = [];
+
+    /**
+     * @param \Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable $configurable
+     * @param ConfigurableProductsProvider $configurableProductsProvider
+     */
+    public function __construct(
+        \Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable $configurable,
+        ConfigurableProductsProvider $configurableProductsProvider
+    ) {
+        $this->configurable = $configurable;
+        $this->configurableProductsProvider = $configurableProductsProvider;
+    }
+
+    /**
+     * @param \Magento\CatalogRule\Model\Rule $rule
+     * @param array $productIds
+     * @return array
+     */
+    public function afterGetMatchingProductIds(\Magento\CatalogRule\Model\Rule $rule, array $productIds)
+    {
+        $configurableProductIds = $this->configurableProductsProvider->getIds(array_keys($productIds));
+        foreach ($configurableProductIds as $productId) {
+            $subProductsIds = $this->configurable->getChildrenIds($productId)[0];
+            $parentValidationResult = $productIds[$productId];
+            foreach ($subProductsIds as $subProductsId) {
+                $productIds[$subProductsId] = $this->getSubProductValidationResult(
+                    $rule->getId(),
+                    $subProductsId,
+                    $parentValidationResult
+                );
+            }
+            unset($productIds[$productId]);
+        }
+        return $productIds;
+    }
+
+    /**
+     * Return validation result for sub-product.
+     * If any of configurable product is valid for current rule, then their sub-product must be valid too
+     *
+     * @param int $urlId
+     * @param int $subProductsId
+     * @param array $parentValidationResult
+     * @return array
+     */
+    private function getSubProductValidationResult($urlId, $subProductsId, $parentValidationResult)
+    {
+        if (!isset($this->subProductsValidationResults[$urlId][$subProductsId])) {
+            $this->subProductsValidationResults[$urlId][$subProductsId] = array_filter($parentValidationResult);
+        } else {
+            $parentValidationResult = array_intersect_key(
+                $this->subProductsValidationResults[$urlId][$subProductsId] + $parentValidationResult,
+                $parentValidationResult
+            );
+            $this->subProductsValidationResults[$urlId][$subProductsId] = $parentValidationResult;
+        }
+        return $parentValidationResult;
+    }
+}
diff --git a/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/Rule/Validation.php b/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/Rule/Validation.php
new file mode 100644
index 0000000000000000000000000000000000000000..0419af2307d710f0a42c1fa13498be23cca148b9
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/Plugin/CatalogRule/Model/Rule/Validation.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule;
+
+use \Magento\ConfigurableProduct\Model\Product\Type\Configurable;
+
+/**
+ * Class Validation. Call validate method for configurable product instead simple product
+ */
+class Validation
+{
+    /** @var Configurable */
+    private $configurable;
+
+    /**
+     * @param \Magento\ConfigurableProduct\Model\Product\Type\Configurable $configurableType
+     */
+    public function __construct(Configurable $configurableType)
+    {
+        $this->configurable = $configurableType;
+    }
+
+    /**
+     * @param \Magento\CatalogRule\Model\Rule $rule
+     * @param \Closure $proceed
+     * @param \Magento\Framework\DataObject|\Magento\Catalog\Model\Product $product
+     * @return bool
+     */
+    public function aroundValidate(
+        \Magento\CatalogRule\Model\Rule $rule,
+        \Closure $proceed,
+        \Magento\Framework\DataObject $product
+    ) {
+        $validateResult = $proceed($product);
+        if (!$validateResult && ($configurableProducts = $this->configurable->getParentIdsByChild($product->getId()))) {
+            foreach ($configurableProducts as $configurableProductId) {
+                $validateResult = $rule->getConditions()->validateByEntityId($configurableProductId);
+                // If any of configurable product is valid for current rule, then their sub-product must be valid too
+                if ($validateResult) {
+                    break;
+                }
+            }
+        }
+        return $validateResult;
+    }
+}
diff --git a/app/code/Magento/CatalogRuleConfigurable/README.md b/app/code/Magento/CatalogRuleConfigurable/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..35c3244db5a134d5f7efe13c45698fdbf77ea0e9
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/README.md
@@ -0,0 +1 @@
+Magento_CatalogRuleConfigurable module is an extension of Magento_CatalogRule and Magento_ConfigurableProduct modules that handle catalog rule indexer for configurable product
diff --git a/app/code/Magento/CatalogRuleConfigurable/Test/Unit/Plugin/CatalogRule/Model/Rule/ConfigurableProductHandlerTest.php b/app/code/Magento/CatalogRuleConfigurable/Test/Unit/Plugin/CatalogRule/Model/Rule/ConfigurableProductHandlerTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..54ced70d8e033151a87f5afed9de8a7eea947652
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/Test/Unit/Plugin/CatalogRule/Model/Rule/ConfigurableProductHandlerTest.php
@@ -0,0 +1,122 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogRuleConfigurable\Test\Unit\Plugin\CatalogRule\Model\Rule;
+
+use Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule\ConfigurableProductHandler;
+use Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable;
+use Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\ConfigurableProductsProvider;
+
+/**
+ * Unit test for Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule\ConfigurableProductHandler
+ */
+class ConfigurableProductHandlerTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule\ConfigurableProductHandler
+     */
+    private $configurableProductHandler;
+
+    /**
+     * @var Configurable|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $configurableMock;
+
+    /**
+     * @var ConfigurableProductsProvider|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $configurableProductsProviderMock;
+
+    /** @var \Magento\CatalogRule\Model\Rule||\PHPUnit_Framework_MockObject_MockObject */
+    private $ruleMock;
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function setUp()
+    {
+        $this->configurableMock = $this->getMock(
+            'Magento\ConfigurableProduct\Model\Resource\Product\Type\Configurable',
+            ['getChildrenIds'],
+            [],
+            '',
+            false
+        );
+        $this->configurableProductsProviderMock = $this->getMock(
+            'Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\ConfigurableProductsProvider',
+            ['getIds'],
+            [],
+            '',
+            false
+        );
+        $this->ruleMock = $this->getMock('Magento\CatalogRule\Model\Rule', [], [], '', false);
+
+        $this->configurableProductHandler = new ConfigurableProductHandler(
+            $this->configurableMock,
+            $this->configurableProductsProviderMock
+        );
+    }
+
+    /**
+     * @return void
+     */
+    public function testAfterGetMatchingProductIdsWithSimpleProduct()
+    {
+        $this->configurableProductsProviderMock->expects($this->once())->method('getIds')->willReturn([]);
+        $this->configurableMock->expects($this->never())->method('getChildrenIds');
+
+        $productIds = ['product' => 'valid results'];
+        $this->assertEquals(
+            $productIds,
+            $this->configurableProductHandler->afterGetMatchingProductIds($this->ruleMock, $productIds)
+        );
+    }
+
+    /**
+     * @return void
+     */
+    public function testAfterGetMatchingProductIdsWithConfigurableProduct()
+    {
+        $this->configurableProductsProviderMock->expects($this->once())->method('getIds')
+            ->willReturn(['conf1', 'conf2']);
+        $this->configurableMock->expects($this->any())->method('getChildrenIds')->willReturnMap([
+            ['conf1', true, [ 0 => ['simple1']]],
+            ['conf2', true, [ 0 => ['simple1', 'simple2']]],
+        ]);
+
+        $this->assertEquals(
+            [
+                'simple1' => [
+                    0 => true,
+                    1 => true,
+                    3 => true,
+                    4 => false,
+                ],
+                'simple2' => [
+                    0 => false,
+                    1 => false,
+                    3 => true,
+                    4 => false,
+                ]
+            ],
+            $this->configurableProductHandler->afterGetMatchingProductIds(
+                $this->ruleMock,
+                [
+                    'conf1' => [
+                        0 => true,
+                        1 => true,
+                    ],
+                    'conf2' => [
+                        0 => false,
+                        1 => false,
+                        3 => true,
+                        4 => false,
+                    ],
+                ]
+            )
+        );
+    }
+}
diff --git a/app/code/Magento/CatalogRuleConfigurable/Test/Unit/Plugin/CatalogRule/Model/Rule/ValidationTest.php b/app/code/Magento/CatalogRuleConfigurable/Test/Unit/Plugin/CatalogRule/Model/Rule/ValidationTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a91a4b88f7fd4579516b19db4c871f4472294e84
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/Test/Unit/Plugin/CatalogRule/Model/Rule/ValidationTest.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogRuleConfigurable\Test\Unit\Plugin\CatalogRule\Model\Rule;
+
+use Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule\Validation;
+
+/**
+ * Unit test for Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule\Validation
+ */
+class ValidationTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule\Validation
+     */
+    private $validation;
+
+    /**
+     * @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable|\PHPUnit_Framework_MockObject_MockObject
+     */
+    private $configurableMock;
+
+    /** @var \Magento\CatalogRule\Model\Rule|\PHPUnit_Framework_MockObject_MockObject */
+    private $ruleMock;
+
+    /** @var \Magento\Rule\Model\Condition\Combine|\PHPUnit_Framework_MockObject_MockObject */
+    private $ruleConditionsMock;
+
+    /** @var \Magento\Framework\DataObject|\PHPUnit_Framework_MockObject_MockObject */
+    private $productMock;
+
+    /**
+     * {@inheritDoc}
+     */
+    protected function setUp()
+    {
+        $this->configurableMock = $this->getMock(
+            'Magento\ConfigurableProduct\Model\Product\Type\Configurable',
+            ['getParentIdsByChild'],
+            [],
+            '',
+            false
+        );
+
+
+        $this->ruleMock = $this->getMock('Magento\CatalogRule\Model\Rule', [], [], '', false);
+        $this->ruleConditionsMock = $this->getMock('Magento\Rule\Model\Condition\Combine', [], [], '', false);
+        $this->productMock = $this->getMock('Magento\Framework\DataObject', ['getId']);
+
+        $this->validation = new Validation(
+            $this->configurableMock
+        );
+    }
+
+    /**
+     * @param $parentsIds
+     * @param $validationResult
+     * @param $runValidateAmount
+     * @param $result
+     * @dataProvider dataProviderForValidateWithValidConfigurableProduct
+     * @return void
+     */
+    public function testAroundValidateWithValidConfigurableProduct(
+        $parentsIds,
+        $validationResult,
+        $runValidateAmount,
+        $result
+    ) {
+        $closureMock = function () {
+            return false;
+        };
+
+        $this->productMock->expects($this->once())->method('getId')->willReturn('product_id');
+        $this->configurableMock->expects($this->once())->method('getParentIdsByChild')->with('product_id')
+            ->willReturn($parentsIds);
+        $this->ruleMock->expects($this->exactly($runValidateAmount))->method('getConditions')
+            ->willReturn($this->ruleConditionsMock);
+        $this->ruleConditionsMock->expects($this->exactly($runValidateAmount))->method('validateByEntityId')
+            ->willReturnMap($validationResult);
+
+        $this->assertEquals(
+            $result,
+            $this->validation->aroundValidate($this->ruleMock, $closureMock, $this->productMock)
+        );
+    }
+
+    /**
+     * @return array
+     */
+    public function dataProviderForValidateWithValidConfigurableProduct()
+    {
+        return [
+            [
+                [1, 2, 3],
+                [
+                    [1, false],
+                    [2, true],
+                    [3, true],
+                ],
+                2,
+                true,
+            ],
+            [
+                [1, 2, 3],
+                [
+                    [1, true],
+                    [2, false],
+                    [3, true],
+                ],
+                1,
+                true,
+            ],
+            [
+                [1, 2, 3],
+                [
+                    [1, false],
+                    [2, false],
+                    [3, false],
+                ],
+                3,
+                false,
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/CatalogRuleConfigurable/composer.json b/app/code/Magento/CatalogRuleConfigurable/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..c689ed54a3ca963774116d0b90c2b13073029c6a
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/composer.json
@@ -0,0 +1,25 @@
+{
+    "name": "magento/module-catalog-rule-configurable",
+    "description": "N/A",
+    "require": {
+        "php": "~5.5.0|~5.6.0|~7.0.0",
+        "magento/module-catalog-rule": "1.0.0-beta",
+        "magento/module-configurable-product": "1.0.0-beta",
+        "magento/framework": "1.0.0-beta",
+        "magento/magento-composer-installer": "*"
+    },
+    "type": "magento2-module",
+    "version": "1.0.0-beta",
+    "license": [
+        "OSL-3.0",
+        "AFL-3.0"
+    ],
+    "extra": {
+        "map": [
+            [
+                "*",
+                "Magento/CatalogRuleConfigurable"
+            ]
+        ]
+    }
+}
diff --git a/app/code/Magento/CatalogRuleConfigurable/etc/adminhtml/di.xml b/app/code/Magento/CatalogRuleConfigurable/etc/adminhtml/di.xml
new file mode 100644
index 0000000000000000000000000000000000000000..051dd103f5d62c20ad7315ab075ed3ee7b7cd22c
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/etc/adminhtml/di.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="../../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
+    <type name="Magento\CatalogRule\Model\Rule">
+        <plugin name="addVariationsToProductRule" type="Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule\ConfigurableProductHandler"/>
+        <plugin name="configurableChildValidation" type="Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Rule\Validation"/>
+    </type>
+    <type name="Magento\CatalogRule\Model\Indexer\Product\ProductRuleIndexer">
+        <plugin name="productRuleReindex" type="Magento\CatalogRuleConfigurable\Plugin\CatalogRule\Model\Indexer\ProductRuleReindex"/>
+    </type>
+</config>
diff --git a/app/code/Magento/CatalogRuleConfigurable/etc/module.xml b/app/code/Magento/CatalogRuleConfigurable/etc/module.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ed99399ed8cc75369164307727b3e4be7b303625
--- /dev/null
+++ b/app/code/Magento/CatalogRuleConfigurable/etc/module.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/Module/etc/module.xsd">
+    <module name="Magento_CatalogRuleConfigurable" setup_version="2.0.0">
+        <sequence>
+            <module name="Magento_CatalogRule"/>
+            <module name="Magento_ConfigurableProduct"/>
+        </sequence>
+    </module>
+</config>
diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
index 500f85db85299e9b140690f3bb2911c9df46c445..456972bd31ddcfee71413f8ed0f6f4494459c11c 100644
--- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
+++ b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config.php
@@ -200,26 +200,6 @@ class Config extends Widget implements TabInterface
         return $data;
     }
 
-    /**
-     * Retrieve Grid child HTML
-     *
-     * @return string
-     */
-    public function getGridHtml()
-    {
-        return $this->getChildHtml('grid');
-    }
-
-    /**
-     * Retrieve Grid JavaScript object name
-     *
-     * @return string
-     */
-    public function getGridJsObject()
-    {
-        return $this->getChildBlock('grid')->getJsObjectName();
-    }
-
     /**
      * Retrieve Tab label
      *
@@ -301,4 +281,12 @@ class Config extends Widget implements TabInterface
     {
         return $this->image->getDefaultPlaceholderUrl('thumbnail');
     }
+
+    /**
+     * @return bool
+     */
+    public function isConfigurableProduct()
+    {
+        return $this->getProduct()->getTypeId() === Configurable::TYPE_CODE || $this->getRequest()->has('attributes');
+    }
 }
diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/AssociatedProduct.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/AssociatedProduct.php
deleted file mode 100644
index 0ba0e6577966b42359de35eda17b232358a8f3f4..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/AssociatedProduct.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-namespace Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Grid;
-
-/**
- * Associated Product Grid
- */
-class AssociatedProduct extends \Magento\Backend\Block\Widget\Grid\Container
-{
-    /**
-     * @return bool
-     */
-    public function isHasRows()
-    {
-        /** @var $grid \Magento\Backend\Block\Widget\Grid */
-        $grid = $this->getChildBlock('grid');
-        return (bool)$grid->getPreparedCollection()->getSize();
-    }
-}
diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/Filter/Inventory.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/Filter/Inventory.php
deleted file mode 100644
index 5a426635880c60f2bb4937b56af4921c96f58615..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/Filter/Inventory.php
+++ /dev/null
@@ -1,27 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-/**
- * Configurable product associated products in stock filter
- */
-namespace Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Grid\Filter;
-
-use Magento\Backend\Block\Widget\Grid\Column\Filter\Select;
-
-class Inventory extends Select
-{
-    /**
-     * @return array
-     */
-    protected function _getOptions()
-    {
-        return [
-            ['value' => '', 'label' => ''],
-            ['value' => 1, 'label' => __('In Stock')],
-            ['value' => 0, 'label' => __('Out of Stock')]
-        ];
-    }
-}
diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/Renderer/Checkbox.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/Renderer/Checkbox.php
deleted file mode 100644
index c95d0f2359d0fc11cfd80d2b2e36c5c34f6a1e2b..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/Renderer/Checkbox.php
+++ /dev/null
@@ -1,78 +0,0 @@
-<?php
-/**
- * Adminhtml catalog super product link grid checkbox renderer
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Grid\Renderer;
-
-class Checkbox extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\Checkbox
-{
-    /**
-     * @var \Magento\Framework\Json\EncoderInterface
-     */
-    protected $_jsonEncoder;
-
-    /**
-     * @param \Magento\Backend\Block\Context $context
-     * @param \Magento\Backend\Block\Widget\Grid\Column\Renderer\Options\Converter $converter
-     * @param \Magento\Framework\Json\EncoderInterface $jsonEncoder
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Context $context,
-        \Magento\Backend\Block\Widget\Grid\Column\Renderer\Options\Converter $converter,
-        \Magento\Framework\Json\EncoderInterface $jsonEncoder,
-        array $data = []
-    ) {
-        $this->_jsonEncoder = $jsonEncoder;
-        parent::__construct($context, $converter, $data);
-    }
-
-    /**
-     * Renders grid column
-     *
-     * @param \Magento\Framework\DataObject $row
-     * @return string
-     */
-    public function render(\Magento\Framework\DataObject $row)
-    {
-        $result = parent::render($row);
-        return $result . '<input type="hidden" class="value-json" value="' . htmlspecialchars(
-            $this->getAttributesJson($row)
-        ) . '" />';
-    }
-
-    /**
-     * Get attributes json
-     *
-     * @param \Magento\Framework\DataObject $row
-     * @return string
-     */
-    public function getAttributesJson(\Magento\Framework\DataObject $row)
-    {
-        if (!$this->getColumn()->getAttributes()) {
-            return '[]';
-        }
-
-        $result = [];
-        foreach ($this->getColumn()->getAttributes() as $attribute) {
-            $productAttribute = $attribute->getProductAttribute();
-            if ($productAttribute->getSourceModel()) {
-                $label = $productAttribute->getSource()->getOptionText(
-                    $row->getData($productAttribute->getAttributeCode())
-                );
-            } else {
-                $label = $row->getData($productAttribute->getAttributeCode());
-            }
-            $item = [];
-            $item['label'] = $label;
-            $item['attribute_id'] = $productAttribute->getId();
-            $item['value_index'] = $row->getData($productAttribute->getAttributeCode());
-            $result[] = $item;
-        }
-
-        return $this->_jsonEncoder->encode($result);
-    }
-}
diff --git a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/Renderer/Inventory.php b/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/Renderer/Inventory.php
deleted file mode 100644
index 8a3668cf9ac525d8bbea118d50e20fc801a89856..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/Block/Adminhtml/Product/Edit/Tab/Super/Config/Grid/Renderer/Inventory.php
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-/**
- * Configurable product assocciated products grid in stock renderer
- */
-namespace Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Grid\Renderer;
-
-class Inventory extends \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
-{
-    /**
-     * Renders grid column value
-     *
-     * @param \Magento\Framework\DataObject $row
-     * @return string
-     */
-    public function render(\Magento\Framework\DataObject $row)
-    {
-        $inStock = $this->_getValue($row);
-        return $inStock ? __('In Stock') : __('Out of Stock');
-    }
-}
diff --git a/app/code/Magento/ConfigurableProduct/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSet.php b/app/code/Magento/ConfigurableProduct/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSet.php
deleted file mode 100644
index bf4a93a77a0890ce1305a25bb39745348b167949..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSet.php
+++ /dev/null
@@ -1,109 +0,0 @@
-<?php
-/**
- * Block representing set of columns in product grid
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\ConfigurableProduct\Block\Product\Configurable\AssociatedSelector\Backend\Grid;
-
-/**
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
-class ColumnSet extends \Magento\Backend\Block\Widget\Grid\ColumnSet
-{
-    /**
-     * Registry instance
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_registryManager;
-
-    /**
-     * Product type configurable instance
-     *
-     * @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable
-     */
-    protected $_productType;
-
-    /**
-     * @param \Magento\Framework\View\Element\Template\Context $context
-     * @param \Magento\Backend\Model\Widget\Grid\Row\UrlGeneratorFactory $generatorFactory
-     * @param \Magento\Backend\Model\Widget\Grid\SubTotals $subtotals
-     * @param \Magento\Backend\Model\Widget\Grid\Totals $totals
-     * @param \Magento\ConfigurableProduct\Model\Product\Type\Configurable $productType
-     * @param \Magento\Framework\Registry $registryManager
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Framework\View\Element\Template\Context $context,
-        \Magento\Backend\Model\Widget\Grid\Row\UrlGeneratorFactory $generatorFactory,
-        \Magento\Backend\Model\Widget\Grid\SubTotals $subtotals,
-        \Magento\Backend\Model\Widget\Grid\Totals $totals,
-        \Magento\ConfigurableProduct\Model\Product\Type\Configurable $productType,
-        \Magento\Framework\Registry $registryManager,
-        array $data = []
-    ) {
-        parent::__construct($context, $generatorFactory, $subtotals, $totals, $data);
-
-        $this->_registryManager = $registryManager;
-        $this->_productType = $productType;
-    }
-
-    /**
-     * Retrieve currently edited product object
-     *
-     * @return \Magento\Catalog\Model\Product
-     */
-    public function getProduct()
-    {
-        return $this->_registryManager->registry('current_product');
-    }
-
-    /**
-     * Preparing layout
-     *
-     * @return \Magento\ConfigurableProduct\Block\Product\Configurable\AssociatedSelector\Backend\Grid\ColumnSet
-     */
-    protected function _prepareLayout()
-    {
-        parent::_prepareLayout();
-
-        $product = $this->getProduct();
-        $attributes = $this->_productType->getUsedProductAttributes($product);
-        foreach ($attributes as $attribute) {
-            /** @var $attribute \Magento\Catalog\Model\Entity\Attribute */
-            /** @var $block \Magento\Backend\Block\Widget\Grid\Column */
-            $block = $this->addChild(
-                $attribute->getAttributeCode(),
-                'Magento\Backend\Block\Widget\Grid\Column',
-                [
-                    'header' => $attribute->getStoreLabel(),
-                    'index' => $attribute->getAttributeCode(),
-                    'type' => 'options',
-                    'options' => $this->getOptions($attribute->getSource()),
-                    'sortable' => false
-                ]
-            );
-            $block->setId($attribute->getAttributeCode())->setGrid($this);
-        }
-        return $this;
-    }
-
-    /**
-     * Get option as hash
-     *
-     * @param \Magento\Eav\Model\Entity\Attribute\Source\AbstractSource $sourceModel
-     * @return array
-     */
-    private function getOptions(\Magento\Eav\Model\Entity\Attribute\Source\AbstractSource $sourceModel)
-    {
-        $result = [];
-        foreach ($sourceModel->getAllOptions() as $option) {
-            if ($option['value'] != '') {
-                $result[] = $option;
-            }
-        }
-        return $result;
-    }
-}
diff --git a/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php
index b67361c4fcc8a740dddceeadaed4fe4b4e3429a5..e2ba278cbc84bc83995ea7c44df653a7880b8670 100644
--- a/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Block/Product/View/Type/Configurable.php
@@ -216,9 +216,7 @@ class Configurable extends \Magento\Catalog\Block\Product\View\AbstractView
     {
         $prices = [];
         foreach ($this->getAllowProducts() as $product) {
-            $priceInfo = $this->getProduct()
-                ->setSelectedConfigurableOption($product)
-                ->getPriceInfo();
+            $priceInfo = $product->getPriceInfo();
 
             $prices[$product->getId()] =
                 [
diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Associated/Grid.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Associated/Grid.php
new file mode 100644
index 0000000000000000000000000000000000000000..6eb4facfee9c36125e9da543cfe8565732cdd9e8
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/Associated/Grid.php
@@ -0,0 +1,42 @@
+<?php
+/**
+ *
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\ConfigurableProduct\Controller\Adminhtml\Product\Associated;
+
+use Magento\Backend\App\Action;
+use Magento\Backend\App\Action\Context;
+use Magento\Framework\View\Result\LayoutFactory;
+
+class Grid extends Action
+{
+    /**
+     * @var LayoutFactory
+     */
+    protected $resultPageFactory;
+
+    /**
+     * @param Context $context
+     * @param LayoutFactory $resultPageFactory
+     */
+    public function __construct(
+        Context $context,
+        LayoutFactory $resultPageFactory
+    ) {
+        parent::__construct($context);
+        $this->resultPageFactory = $resultPageFactory;
+    }
+    /**
+     * Index action
+     *
+     * @return \Magento\Backend\Model\View\Result\Page
+     */
+    public function execute()
+    {
+        /** @var \Magento\Framework\View\Result\Layout $resultPage */
+        $resultPage = $this->resultPageFactory->create();
+        return $resultPage;
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/SuperConfig/Index.php b/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/SuperConfig/Index.php
deleted file mode 100644
index cd5021712d0d7411d491a77a2349c1cd0e8fa147..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/Controller/Adminhtml/Product/SuperConfig/Index.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-/**
- *
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\ConfigurableProduct\Controller\Adminhtml\Product\SuperConfig;
-
-use Magento\Backend\App\Action;
-use Magento\Catalog\Controller\Adminhtml\Product;
-
-class Index extends Action
-{
-    /**
-     * @var \Magento\Catalog\Controller\Adminhtml\Product\Builder
-     */
-    protected $productBuilder;
-
-    /**
-     * @param Action\Context $context
-     * @param Product\Builder $productBuilder
-     */
-    public function __construct(Action\Context $context, Product\Builder $productBuilder)
-    {
-        $this->productBuilder = $productBuilder;
-        parent::__construct($context);
-    }
-
-    /**
-     * @return void
-     */
-    public function execute()
-    {
-        $this->productBuilder->build($this->getRequest());
-        $this->_view->loadLayout(false);
-        $this->_view->renderLayout();
-    }
-}
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
index 4c8c10f01476eedaf6b49701fab2dd9bd4493691..46db91ca3564b3121fd87f39669eb9a4a0e7f997 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable.php
@@ -220,7 +220,7 @@ class Configurable extends \Magento\Catalog\Model\Product\Type\AbstractType
      *   group => array(ids)
      * )
      *
-     * @param  int $parentId
+     * @param  array|int $parentId
      * @param  bool $required
      * @return array
      */
diff --git a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php
index 68c5cb91c5aa8a6ce83ba418bad122064c254459..bd74b867c86103a67177628d8bef0e30609261cb 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Product/Type/Configurable/Price.php
@@ -24,10 +24,13 @@ class Price extends \Magento\Catalog\Model\Product\Type\Price
             return $product->getCalculatedFinalPrice();
         }
         if ($product->getCustomOption('simple_product')) {
-            $product->setSelectedConfigurableOption($product->getCustomOption('simple_product')->getProduct());
+            $simpleProduct = $product->getCustomOption('simple_product')->getProduct();
+            $product->setSelectedConfigurableOption($simpleProduct);
+            $priceInfo = $simpleProduct->getPriceInfo();
+        } else {
+            $priceInfo = $product->getPriceInfo();
         }
-        //TODO: MAGETWO-23739 catalogrule price must get from simple product.
-        $finalPrice = $product->getPriceInfo()->getPrice('final_price')->getAmount()->getValue();
+        $finalPrice = $priceInfo->getPrice('final_price')->getAmount()->getValue();
         $finalPrice = $this->_applyOptionsPrice($product, $qty, $finalPrice);
         $finalPrice = max(0, $finalPrice);
         $product->setFinalPrice($finalPrice);
diff --git a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Collection/AssociatedProduct.php b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Collection/AssociatedProduct.php
deleted file mode 100644
index 1859c32a207bf6e1d5486e5e7f50124aeb600c1d..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Collection/AssociatedProduct.php
+++ /dev/null
@@ -1,184 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-/**
- * Catalog compare item resource model
- */
-namespace Magento\ConfigurableProduct\Model\Resource\Product\Collection;
-
-use Magento\Customer\Api\GroupManagementInterface;
-
-/**
- * Catalog compare item resource model
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
-class AssociatedProduct extends \Magento\Catalog\Model\Resource\Product\Collection
-{
-    /**
-     * Registry instance
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_registryManager;
-
-    /**
-     * Product type configurable instance
-     *
-     * @var \Magento\ConfigurableProduct\Model\Product\Type\Configurable
-     */
-    protected $_productType;
-
-    /**
-     * Product type configuration
-     *
-     * @var \Magento\Catalog\Model\ProductTypes\ConfigInterface
-     */
-    protected $_productTypeConfig;
-
-    /**
-     * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
-     * @param \Psr\Log\LoggerInterface $logger
-     * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
-     * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Eav\Model\Config $eavConfig
-     * @param \Magento\Framework\App\Resource $resource
-     * @param \Magento\Eav\Model\EntityFactory $eavEntityFactory
-     * @param \Magento\Catalog\Model\Resource\Helper $resourceHelper
-     * @param \Magento\Framework\Validator\UniversalFactory $universalFactory
-     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
-     * @param \Magento\Framework\Module\Manager $moduleManager
-     * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState
-     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
-     * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory
-     * @param \Magento\Catalog\Model\Resource\Url $catalogUrl
-     * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
-     * @param \Magento\Customer\Model\Session $customerSession
-     * @param \Magento\Framework\Stdlib\DateTime $dateTime
-     * @param GroupManagementInterface $groupManagement
-     * @param \Magento\Framework\Registry $registryManager
-     * @param \Magento\ConfigurableProduct\Model\Product\Type\Configurable $productType
-     * @param \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig
-     * @param \Magento\Framework\DB\Adapter\AdapterInterface $connection
-     *
-     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
-     */
-    public function __construct(
-        \Magento\Framework\Data\Collection\EntityFactory $entityFactory,
-        \Psr\Log\LoggerInterface $logger,
-        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
-        \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Eav\Model\Config $eavConfig,
-        \Magento\Framework\App\Resource $resource,
-        \Magento\Eav\Model\EntityFactory $eavEntityFactory,
-        \Magento\Catalog\Model\Resource\Helper $resourceHelper,
-        \Magento\Framework\Validator\UniversalFactory $universalFactory,
-        \Magento\Store\Model\StoreManagerInterface $storeManager,
-        \Magento\Framework\Module\Manager $moduleManager,
-        \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState,
-        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
-        \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory,
-        \Magento\Catalog\Model\Resource\Url $catalogUrl,
-        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
-        \Magento\Customer\Model\Session $customerSession,
-        \Magento\Framework\Stdlib\DateTime $dateTime,
-        GroupManagementInterface $groupManagement,
-        \Magento\Framework\Registry $registryManager,
-        \Magento\ConfigurableProduct\Model\Product\Type\Configurable $productType,
-        \Magento\Catalog\Model\ProductTypes\ConfigInterface $productTypeConfig,
-        \Magento\Framework\DB\Adapter\AdapterInterface $connection = null
-    ) {
-        $this->_registryManager = $registryManager;
-        $this->_productType = $productType;
-        $this->_productTypeConfig = $productTypeConfig;
-        parent::__construct(
-            $entityFactory,
-            $logger,
-            $fetchStrategy,
-            $eventManager,
-            $eavConfig,
-            $resource,
-            $eavEntityFactory,
-            $resourceHelper,
-            $universalFactory,
-            $storeManager,
-            $moduleManager,
-            $catalogProductFlatState,
-            $scopeConfig,
-            $productOptionFactory,
-            $catalogUrl,
-            $localeDate,
-            $customerSession,
-            $dateTime,
-            $groupManagement,
-            $connection
-        );
-    }
-
-    /**
-     * Get product type
-     *
-     * @return \Magento\ConfigurableProduct\Model\Product\Type\Configurable
-     */
-    public function getProductType()
-    {
-        return $this->_productType;
-    }
-
-    /**
-     * Retrieve currently edited product object
-     *
-     * @return mixed
-     */
-    private function getProduct()
-    {
-        return $this->_registryManager->registry('current_product');
-    }
-
-    /**
-     * Add attributes to select
-     *
-     * @return $this
-     */
-    public function _initSelect()
-    {
-        parent::_initSelect();
-
-        $allowedProductTypes = $this->_productTypeConfig->getComposableTypes();
-
-        $this->addAttributeToSelect(
-            'name'
-        )->addAttributeToSelect(
-            'price'
-        )->addAttributeToSelect(
-            'sku'
-        )->addAttributeToSelect(
-            'weight'
-        )->addAttributeToSelect(
-            'image'
-        )->addFieldToFilter(
-            'type_id',
-            $allowedProductTypes
-        )->addFieldToFilter(
-            'entity_id',
-            ['neq' => $this->getProduct()->getId()]
-        )->addFilterByRequiredOptions()->joinAttribute(
-            'name',
-            'catalog_product/name',
-            'entity_id',
-            null,
-            'inner'
-        )->joinTable(
-            ['cisi' => 'cataloginventory_stock_item'],
-            'product_id=entity_id',
-            ['qty' => 'qty', 'inventory_in_stock' => 'is_in_stock'],
-            null,
-            'left'
-        );
-
-        return $this;
-    }
-}
diff --git a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php
index 2b2d6e392bb2287f22e417e2924cafca9efd9238..c90b20f34acbb78266b5fe803a6d1c1e376994d1 100644
--- a/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php
+++ b/app/code/Magento/ConfigurableProduct/Model/Resource/Product/Type/Configurable.php
@@ -90,14 +90,13 @@ class Configurable extends \Magento\Framework\Model\Resource\Db\AbstractDb
      *   group => array(ids)
      * )
      *
-     * @param int $parentId
+     * @param int|array $parentId
      * @param bool $required
      * @return array
      * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function getChildrenIds($parentId, $required = true)
     {
-        $childrenIds = [];
         $select = $this->getConnection()->select()->from(
             ['l' => $this->getMainTable()],
             ['product_id', 'parent_id']
@@ -106,7 +105,7 @@ class Configurable extends \Magento\Framework\Model\Resource\Db\AbstractDb
             'e.entity_id = l.product_id AND e.required_options = 0',
             []
         )->where(
-            'parent_id = ?',
+            'parent_id IN (?)',
             $parentId
         );
 
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php
new file mode 100644
index 0000000000000000000000000000000000000000..8a3a54d17f45b04fc586cca4033f13b2da176c04
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurablePriceResolver.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Pricing\Price;
+
+use Magento\Catalog\Model\Product;
+use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
+use Magento\Framework\Pricing\PriceCurrencyInterface;
+
+class ConfigurablePriceResolver implements PriceResolverInterface
+{
+    /** @var PriceResolverInterface */
+    protected $priceResolver;
+
+    /** @var PriceCurrencyInterface */
+    protected $priceCurrency;
+
+    /** @var Configurable */
+    protected $configurable;
+
+    /**
+     * @param PriceResolverInterface $priceResolver
+     * @param Configurable $configurable
+     * @param PriceCurrencyInterface $priceCurrency
+     */
+    public function __construct(
+        PriceResolverInterface $priceResolver,
+        Configurable $configurable,
+        PriceCurrencyInterface $priceCurrency
+    ) {
+        $this->priceResolver = $priceResolver;
+        $this->configurable = $configurable;
+        $this->priceCurrency = $priceCurrency;
+    }
+
+    /**
+     * @param \Magento\Framework\Pricing\Object\SaleableInterface $product
+     * @return float
+     */
+    public function resolvePrice(\Magento\Framework\Pricing\Object\SaleableInterface $product)
+    {
+        $selectedConfigurableOption = $product->getSelectedConfigurableOption();
+        if ($selectedConfigurableOption) {
+            $price = $this->priceResolver->resolvePrice($selectedConfigurableOption);
+        } else {
+            $price = null;
+            foreach ($this->configurable->getUsedProducts($product) as $subProduct) {
+                $productPrice = $this->priceResolver->resolvePrice($subProduct);
+                $price = $price ? min($price, $productPrice) : $productPrice;
+            }
+        }
+        $priceInCurrentCurrency = $this->priceCurrency->convertAndRound($price);
+        return $priceInCurrentCurrency ? (float)$priceInCurrentCurrency : false;
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableRegularPrice.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableRegularPrice.php
index efb7d45698271f2ca26aa4c1161e8fbcf8958240..704005ef38b8c6aecbc18ffb797f109363907358 100644
--- a/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableRegularPrice.php
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/ConfigurableRegularPrice.php
@@ -8,9 +8,7 @@ namespace Magento\ConfigurableProduct\Pricing\Price;
 
 use Magento\Catalog\Model\Product;
 use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
-use Magento\Framework\Pricing\Adjustment\CalculatorInterface;
 use Magento\Framework\Pricing\Price\AbstractPrice;
-use Magento\Framework\Pricing\PriceCurrencyInterface;
 
 /**
  * Class RegularPrice
@@ -37,6 +35,27 @@ class ConfigurableRegularPrice extends AbstractPrice implements ConfigurableRegu
      */
     protected $values = [];
 
+    /** @var PriceResolverInterface */
+    protected $priceResolver;
+
+    /**
+     * @param \Magento\Framework\Pricing\Object\SaleableInterface $saleableItem
+     * @param float $quantity
+     * @param \Magento\Framework\Pricing\Adjustment\CalculatorInterface $calculator
+     * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
+     * @param PriceResolverInterface $priceResolver
+     */
+    public function __construct(
+        \Magento\Framework\Pricing\Object\SaleableInterface $saleableItem,
+        $quantity,
+        \Magento\Framework\Pricing\Adjustment\CalculatorInterface $calculator,
+        \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
+        PriceResolverInterface $priceResolver
+    ) {
+        parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency);
+        $this->priceResolver = $priceResolver;
+    }
+
     /**
      * {@inheritdoc}
      */
@@ -45,19 +64,7 @@ class ConfigurableRegularPrice extends AbstractPrice implements ConfigurableRegu
         $selectedConfigurableOption = $this->product->getSelectedConfigurableOption();
         $productId = $selectedConfigurableOption ? $selectedConfigurableOption->getId() : $this->product->getId();
         if (!isset($this->values[$productId])) {
-            $price = null;
-            if (!$selectedConfigurableOption) {
-                foreach ($this->getUsedProducts() as $product) {
-                    if ($price === null || $price > $product->getPrice()) {
-                        $price = $product->getPrice();
-                    }
-                }
-            } else {
-                $price = $selectedConfigurableOption->getPrice();
-            }
-
-            $priceInCurrentCurrency = $this->priceCurrency->convertAndRound($price);
-            $this->values[$productId] = $priceInCurrentCurrency ? floatval($priceInCurrentCurrency) : false;
+            $this->values[$productId] = $this->priceResolver->resolvePrice($this->product);
         }
 
         return $this->values[$productId];
@@ -67,12 +74,7 @@ class ConfigurableRegularPrice extends AbstractPrice implements ConfigurableRegu
      */
     public function getAmount()
     {
-        if (false) {
-            // TODO: need to check simple product assignment
-        } else {
-            $amount = $this->getMinRegularAmount($this->product);
-        }
-        return $amount;
+        return $this->getMinRegularAmount($this->product);
     }
 
     /**
@@ -95,7 +97,6 @@ class ConfigurableRegularPrice extends AbstractPrice implements ConfigurableRegu
      */
     protected function doGetMaxRegularAmount()
     {
-        // TODO: think about quantity
         $maxAmount = null;
         foreach ($this->getUsedProducts() as $product) {
             $childPriceAmount = $product->getPriceInfo()->getPrice(self::PRICE_CODE)->getAmount();
@@ -125,7 +126,6 @@ class ConfigurableRegularPrice extends AbstractPrice implements ConfigurableRegu
      */
     protected function doGetMinRegularAmount()
     {
-        // TODO: think about quantity
         $minAmount = null;
         foreach ($this->getUsedProducts() as $product) {
             $childPriceAmount = $product->getPriceInfo()->getPrice(self::PRICE_CODE)->getAmount();
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/FinalPrice.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/FinalPrice.php
index 093de8327567283d0652789d9e1e499ebfd5e263..8a448ac045bd38be1151a935c8f79fcd2a6de8fe 100644
--- a/app/code/Magento/ConfigurableProduct/Pricing/Price/FinalPrice.php
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/FinalPrice.php
@@ -8,6 +8,32 @@ namespace Magento\ConfigurableProduct\Pricing\Price;
 
 class FinalPrice extends \Magento\Catalog\Pricing\Price\FinalPrice
 {
+    /** @var PriceResolverInterface */
+    protected $priceResolver;
+
+    /**
+     * @var array
+     */
+    protected $values = [];
+
+    /**
+     * @param \Magento\Framework\Pricing\Object\SaleableInterface $saleableItem
+     * @param float $quantity
+     * @param \Magento\Framework\Pricing\Adjustment\CalculatorInterface $calculator
+     * @param \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency
+     * @param PriceResolverInterface $priceResolver
+     */
+    public function __construct(
+        \Magento\Framework\Pricing\Object\SaleableInterface $saleableItem,
+        $quantity,
+        \Magento\Framework\Pricing\Adjustment\CalculatorInterface $calculator,
+        \Magento\Framework\Pricing\PriceCurrencyInterface $priceCurrency,
+        PriceResolverInterface $priceResolver
+    ) {
+        parent::__construct($saleableItem, $quantity, $calculator, $priceCurrency);
+        $this->priceResolver = $priceResolver;
+    }
+
     /**
      * {@inheritdoc}
      */
@@ -18,4 +44,18 @@ class FinalPrice extends \Magento\Catalog\Pricing\Price\FinalPrice
         }
         return parent::getAmount();
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getValue()
+    {
+        $selectedConfigurableOption = $this->product->getSelectedConfigurableOption();
+        $productId = $selectedConfigurableOption ? $selectedConfigurableOption->getId() : $this->product->getId();
+        if (!isset($this->values[$productId])) {
+            $this->values[$productId] = $this->priceResolver->resolvePrice($this->product);
+        }
+
+        return $this->values[$productId];
+    }
 }
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/FinalPriceResolver.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/FinalPriceResolver.php
new file mode 100644
index 0000000000000000000000000000000000000000..c55dd7cd1b2b56d54c56636b8c746fa8352269e6
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/FinalPriceResolver.php
@@ -0,0 +1,20 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Pricing\Price;
+
+class FinalPriceResolver implements PriceResolverInterface
+{
+    /**
+     * @param \Magento\Framework\Pricing\Object\SaleableInterface $product
+     * @return float
+     */
+    public function resolvePrice(\Magento\Framework\Pricing\Object\SaleableInterface $product)
+    {
+        return $product->getPriceInfo()->getPrice(\Magento\Catalog\Pricing\Price\FinalPrice::PRICE_CODE)
+            ->getAmount()->getValue();
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/PriceResolverInterface.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/PriceResolverInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..5aff5c12e16804f8d2b967833aea7eaea24a2a16
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/PriceResolverInterface.php
@@ -0,0 +1,16 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Pricing\Price;
+
+interface PriceResolverInterface
+{
+    /**
+     * @param \Magento\Framework\Pricing\Object\SaleableInterface $product
+     * @return float
+     */
+    public function resolvePrice(\Magento\Framework\Pricing\Object\SaleableInterface $product);
+}
diff --git a/app/code/Magento/ConfigurableProduct/Pricing/Price/RegularPriceResolver.php b/app/code/Magento/ConfigurableProduct/Pricing/Price/RegularPriceResolver.php
new file mode 100644
index 0000000000000000000000000000000000000000..a8ac2e6d84bf3ad7da02a8db8bbab683c8e3aa90
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Pricing/Price/RegularPriceResolver.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\ConfigurableProduct\Pricing\Price;
+
+class RegularPriceResolver implements PriceResolverInterface
+{
+    /**
+     * @param \Magento\Framework\Pricing\Object\SaleableInterface $product
+     * @return float
+     */
+    public function resolvePrice(\Magento\Framework\Pricing\Object\SaleableInterface $product)
+    {
+        return $product->getPrice();
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Ui/Component/Listing/AssociatedProduct/Attribute/Repository.php b/app/code/Magento/ConfigurableProduct/Ui/Component/Listing/AssociatedProduct/Attribute/Repository.php
new file mode 100644
index 0000000000000000000000000000000000000000..d52708b06b95557c0b661aac603585a75912158e
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Ui/Component/Listing/AssociatedProduct/Attribute/Repository.php
@@ -0,0 +1,36 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\ConfigurableProduct\Ui\Component\Listing\AssociatedProduct\Attribute;
+
+class Repository extends \Magento\Catalog\Ui\Component\Listing\Attribute\AbstractRepository
+{
+    /** @var \Magento\Framework\App\RequestInterface */
+    protected $request;
+
+    /**
+     * @param \Magento\Catalog\Api\ProductAttributeRepositoryInterface $productAttributeRepository
+     * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
+     * @param \Magento\Framework\App\RequestInterface $request
+     */
+    public function __construct(
+        \Magento\Catalog\Api\ProductAttributeRepositoryInterface $productAttributeRepository,
+        \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
+        \Magento\Framework\App\RequestInterface $request
+    ) {
+        parent::__construct($productAttributeRepository, $searchCriteriaBuilder);
+        $this->request = $request;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    protected function buildSearchCriteria()
+    {
+        return $this->searchCriteriaBuilder
+            ->addFilter('attribute_code', $this->request->getParam('attributes_codes', []), 'in')
+            ->create();
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Ui/Component/Listing/AssociatedProduct/Columns.php b/app/code/Magento/ConfigurableProduct/Ui/Component/Listing/AssociatedProduct/Columns.php
new file mode 100644
index 0000000000000000000000000000000000000000..90acb7e467a960fec5ea72089c4b4d2e78664a1d
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/Ui/Component/Listing/AssociatedProduct/Columns.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\ConfigurableProduct\Ui\Component\Listing\AssociatedProduct;
+
+class Columns extends \Magento\Ui\Component\Listing\Columns
+{
+    /** @var \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface */
+    protected $attributeRepository;
+
+    /**
+     * @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context
+     * @param \Magento\Catalog\Ui\Component\ColumnFactory $columnFactory
+     * @param \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface $attributeRepository
+     * @param array $components
+     * @param array $data
+     */
+    public function __construct(
+        \Magento\Framework\View\Element\UiComponent\ContextInterface $context,
+        \Magento\Catalog\Ui\Component\ColumnFactory $columnFactory,
+        \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface $attributeRepository,
+        array $components = [],
+        array $data = []
+    ) {
+        parent::__construct($context, $components, $data);
+        $this->columnFactory = $columnFactory;
+        $this->attributeRepository = $attributeRepository;
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function prepare()
+    {
+        foreach ($this->attributeRepository->getList() as $attribute) {
+            $column = $this->columnFactory->create($attribute, $this->getContext());
+                $column->prepare();
+                $this->addComponent($attribute->getAttributeCode(), $column);
+        }
+        parent::prepare();
+    }
+}
diff --git a/app/code/Magento/ConfigurableProduct/Ui/Component/Listing/AssociatedProduct/Filters.php b/app/code/Magento/ConfigurableProduct/Ui/Component/Listing/AssociatedProduct/Filters.php
index af27ebc05c328ce4aeaf78e787fabf88abd248bf..8ed9f3d718e21f27955c53048d57721f89f61229 100644
--- a/app/code/Magento/ConfigurableProduct/Ui/Component/Listing/AssociatedProduct/Filters.php
+++ b/app/code/Magento/ConfigurableProduct/Ui/Component/Listing/AssociatedProduct/Filters.php
@@ -7,28 +7,26 @@ namespace Magento\ConfigurableProduct\Ui\Component\Listing\AssociatedProduct;
 
 class Filters extends \Magento\Ui\Component\Filters
 {
-    /**
-     * @var \Magento\Eav\Model\Resource\Entity\Attribute\CollectionFactory
-     */
-    protected $attributeCollectionFactory;
+    /** @var \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface */
+    protected $attributeRepository;
 
     /**
      * @param \Magento\Framework\View\Element\UiComponent\ContextInterface $context
      * @param \Magento\Catalog\Ui\Component\FilterFactory $filterFactory
-     * @param \Magento\Eav\Model\Resource\Entity\Attribute\CollectionFactory $attributeCollectionFactory
+     * @param \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface $attributeRepository
      * @param array $components
      * @param array $data
      */
     public function __construct(
         \Magento\Framework\View\Element\UiComponent\ContextInterface $context,
         \Magento\Catalog\Ui\Component\FilterFactory $filterFactory,
-        \Magento\Eav\Model\Resource\Entity\Attribute\CollectionFactory $attributeCollectionFactory,
+        \Magento\Catalog\Ui\Component\Listing\Attribute\RepositoryInterface $attributeRepository,
         array $components = [],
         array $data = []
     ) {
         parent::__construct($context, $components, $data);
         $this->filterFactory = $filterFactory;
-        $this->attributeCollectionFactory = $attributeCollectionFactory;
+        $this->attributeRepository = $attributeRepository;
     }
 
     /**
@@ -36,24 +34,14 @@ class Filters extends \Magento\Ui\Component\Filters
      */
     public function prepare()
     {
-        $attributeIds = $this->context->getRequestParam('attribute_ids');
+        $attributeIds = $this->getContext()->getRequestParam('attributes_codes');
         if ($attributeIds) {
-            foreach ($this->getAttributes($attributeIds) as $attribute) {
-                $filter = $this->filterFactory->create($attribute, $this->getContext());
+            foreach ($this->attributeRepository->getList() as $attribute) {
+                $filter = $this->filterFactory->create($attribute, $this->getContext(), ['component' => '']);
                 $filter->prepare();
                 $this->addComponent($attribute->getAttributeCode(), $filter);
             }
         }
         parent::prepare();
     }
-
-    /**
-     * @param array $attributeIds
-     * @return mixed
-     */
-    protected function getAttributes($attributeIds)
-    {
-        $attributeCollection = $this->attributeCollectionFactory->create();
-        return $attributeCollection->addFieldToFilter('attribute_code', ['in' => $attributeIds]);
-    }
 }
diff --git a/app/code/Magento/ConfigurableProduct/etc/adminhtml/di.xml b/app/code/Magento/ConfigurableProduct/etc/adminhtml/di.xml
index 10ffde3a203407b971fdae1ce6775763ed6464ba..226e2f9f2a2eaf852ee09b522578925dd77870c5 100644
--- a/app/code/Magento/ConfigurableProduct/etc/adminhtml/di.xml
+++ b/app/code/Magento/ConfigurableProduct/etc/adminhtml/di.xml
@@ -24,4 +24,14 @@
     <type name="Magento\Catalog\Model\Resource\Product">
         <plugin name="reload_attributes" type="Magento\ConfigurableProduct\Plugin\Model\Resource\Product" />
     </type>
+    <type name="Magento\ConfigurableProduct\Ui\Component\Listing\AssociatedProduct\Columns">
+        <arguments>
+            <argument name="attributeRepository" xsi:type="object">Magento\ConfigurableProduct\Ui\Component\Listing\AssociatedProduct\Attribute\Repository</argument>
+        </arguments>
+    </type>
+    <type name="Magento\ConfigurableProduct\Ui\Component\Listing\AssociatedProduct\Filters">
+        <arguments>
+            <argument name="attributeRepository" xsi:type="object">Magento\ConfigurableProduct\Ui\Component\Listing\AssociatedProduct\Attribute\Repository</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/ConfigurableProduct/etc/di.xml b/app/code/Magento/ConfigurableProduct/etc/di.xml
index 7f3f4dda6d5745674bc7cebb863e9fc43e2906aa..67c0448affe6685ab131c5313787776bf3492cb6 100644
--- a/app/code/Magento/ConfigurableProduct/etc/di.xml
+++ b/app/code/Magento/ConfigurableProduct/etc/di.xml
@@ -89,4 +89,24 @@
             </argument>
         </arguments>
     </type>
+    <virtualType name="ConfigurableFinalPriceResolver" type="Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver">
+        <arguments>
+            <argument name="priceResolver" xsi:type="object">Magento\ConfigurableProduct\Pricing\Price\FinalPriceResolver</argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\ConfigurableProduct\Pricing\Price\FinalPrice">
+        <arguments>
+            <argument name="priceResolver" xsi:type="object">ConfigurableFinalPriceResolver</argument>
+        </arguments>
+    </type>
+    <virtualType name="ConfigurableRegularPriceResolver" type="Magento\ConfigurableProduct\Pricing\Price\ConfigurablePriceResolver">
+        <arguments>
+            <argument name="priceResolver" xsi:type="object">Magento\ConfigurableProduct\Pricing\Price\RegularPriceResolver</argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\ConfigurableProduct\Pricing\Price\ConfigurableRegularPrice">
+        <arguments>
+            <argument name="priceResolver" xsi:type="object">ConfigurableRegularPriceResolver</argument>
+        </arguments>
+    </type>
 </config>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_superconfig_index.xml b/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_associated_grid.xml
similarity index 52%
rename from app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_superconfig_index.xml
rename to app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_associated_grid.xml
index 7cc24820b426f9662631b12a351bcd0f50180b21..d9dc4c65e3331f03d50db1f22b96b3dff8a71513 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_superconfig_index.xml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_associated_grid.xml
@@ -6,8 +6,7 @@
  */
 -->
 <layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/layout_generic.xsd">
-    <update handle="catalog_product_superconfig_config"/>
     <container name="root">
-        <block class="Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Grid\AssociatedProduct" name="admin.product.edit.tab.super.config.grid.container"  template="Magento_ConfigurableProduct::catalog/product/edit/super/associated-product-grid.phtml"/>
+        <uiComponent name="configurable_associated_product_listing"/>
     </container>
 </layout>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_configurable.xml b/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_configurable.xml
index 5cd281b5b426b97d7b1579170b61d74d7db59f68..2a361a45de36c62309abd33455a61e65355e376f 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_configurable.xml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_configurable.xml
@@ -10,4 +10,11 @@
         <css src="Magento_ConfigurableProduct::css/configurable-product.css"/>
     </head>
     <update handle="catalog_product_superconfig_config"/>
+    <body>
+        <referenceBlock name="product_tabs">
+            <action method="removeTab">
+                <argument name="name" xsi:type="string">advanced-pricing</argument>
+            </action>
+        </referenceBlock>
+    </body>
 </page>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_superconfig_config.xml b/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_superconfig_config.xml
index 9ed318d2b3379065b44f4f7ef78c6266ad1e6f42..f7a4f779bcc314bb33fb0270c0d861d0f24b2d88 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_superconfig_config.xml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/layout/catalog_product_superconfig_config.xml
@@ -7,11 +7,6 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../../../lib/internal/Magento/Framework/View/Layout/etc/page_configuration.xsd">
     <body>
-        <referenceBlock name="admin.product.edit.tab.super.config.grid.container">
-            <block class="Magento\Backend\Block\Template" name="manual.product.grid" template="Magento_ConfigurableProduct::catalog/product/edit/super/manual-product-grid.phtml" as="grid">
-                <uiComponent name="configurable_associated_product_listing"/>
-            </block>
-        </referenceBlock>
         <referenceBlock name="product_tabs">
             <block class="Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config" name="admin.product.edit.tab.super.config.grid.container">
                 <block class="Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config" template="Magento_ConfigurableProduct::catalog/product/edit/super/generator.phtml" name="product-variations-generator" as="generator">
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/associated-product-grid.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/associated-product-grid.phtml
deleted file mode 100644
index d6c1154113a3dfe1d072cda58436657177408191..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/associated-product-grid.phtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-/* @var $block \Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Grid\AssociatedProduct */
-
-?>
-<div data-role="configurable-attribute">
-    <div data-role="messages" class="messages">
-        <div class="message ">
-            <div>
-                <?php if ($block->isHasRows()): ?>
-                    <?= /* @escapeNotVerified */  __('Choose a new product to delete and replace the current product configuration.') ?>
-                <?php else: ?>
-                    <?= /* @escapeNotVerified */   __('For better results, add attributes and attribute values to your products.') ?>
-                <?php endif ?>
-            </div>
-        </div>
-    </div>
-    <?php echo $block->getGridHtml() ?>
-</div>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml
index ec212367581008e27e8e3bf63107b0b67e0a9ef4..634f06de8c4aa20eadfde6943770451f3a0a446b 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/config.phtml
@@ -7,8 +7,6 @@
 // @codingStandardsIgnoreFile
 
  /** @var $block \Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config */
-
-use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
 ?>
 <div class="entry-edit form-inline" id="<?php /* @escapeNotVerified */ echo $block->getId() ?>">
     <div class="fieldset-wrapper admin__collapsible-block-wrapper" id="<?php /* @escapeNotVerified */ echo $block->getId() ?>-wrapper" data-panel="product-variations">
@@ -26,11 +24,6 @@ use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
                     You need to create a simple product for each configuration (Ex: a product for each color).');?>
                     </div>
                 </div>
-                <!--<div class="product-create-configuration-actions">
-                    <a class="action-menu-item" data-action="choose" onclick="jQuery('#associated-products-container').trigger('openModal');" href="#">
-                        <?/*= __('Add Products Manually');*/?>
-                    </a>
-                </div>-->
                 <div class="product-create-configuration-actions">
                     <button data-action="open-steps-wizard" title="Create Product Configurations"
                             class="action-secondary" data-bind="click: open">
@@ -43,13 +36,26 @@ use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
                         </span>
                     </button>
                 </div>
+                <div class="product-create-configuration-actions" data-bind="scope: 'configurableProductGrid'">
+                    <a class="action-menu-item" data-action="choose" data-bind="click: showManuallyGrid, visible: button">
+                        <?= /* @noEscape */ __('Add Products Manually');?>
+                    </a>
+                </div>
             </div>
             <fieldset class="fieldset">
                 <?php echo $block->getChildHtml('generator'); ?>
 
                 <!-- Select Associated Product popup -->
-                <div id="associated-products-container">
-                    <?php echo $block->getGridHtml(); ?>
+                <div data-grid-id="associated-products-container">
+                    <div class="admin__data-grid-outer-wrap" data-bind="scope: 'configurable_associated_product_listing.configurable_associated_product_listing'">
+                        <div data-role="spinner" data-component="configurable_associated_product_listing.configurable_associated_product_listing.product_columns" class="admin__data-grid-loading-mask">
+                            <div class="spinner">
+                                <span></span><span></span><span></span><span></span><span></span><span></span><span></span><span></span>
+                            </div>
+                        </div>
+                        <!-- ko template: getTemplate() --><!-- /ko -->
+
+                    </div>
                 </div>
 
                 <input type="hidden" name="affect_configurable_product_attributes" value="1" />
@@ -60,75 +66,76 @@ use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
 <script>
 require([
     'jquery',
-    'mage/template',
-    'jquery/ui',
-    'jquery/jquery.tabs',
+    'Magento_ConfigurableProduct/js/advanced-pricing-handler',
+    'Magento_ConfigurableProduct/js/options/price-type-handler',
     'mage/mage',
-    'mage/backend/menu',
     'Magento_Ui/js/modal/modal',
     'mage/translate',
     'domReady!'
-], function($, mageTemplate){
+], function($, advancedPricingHandler, priceTypeHandler){
     'use strict';
 
-    var variationsContainer = $("#<?php /* @escapeNotVerified */ echo $block->getId()?>"),
-        collapsableWrapper = $("#<?php /* @escapeNotVerified */ echo $block->getId()?>-wrapper"),
-        collapsableArea = $('> .collapse', collapsableWrapper),
-        stockAvailabilityField = $('#quantity_and_stock_status'),
-        qtyField = $('#qty'),
-        inventoryQty = $('#inventory_qty'),
-        inventoryAvailabilityField = $('#inventory_stock_availability'),
-        currentProductTemplateControl = $('#product-template-suggest-container .action-dropdown > .action-toggle'),
-        attributesInput = $("input[name='attributes[]']", variationsContainer),
-        hasVariations = <?php /* @escapeNotVerified */ echo($block->getProduct()->getTypeId() === Configurable::TYPE_CODE || $block->getRequest()->has('attributes')) ? 'true' : 'false' ?>,
-        noImageUrl = '<?= /* @escapeNotVerified */  $block->getNoImageUrl() ?>',
-        isLocked = function (element) {
-            return element.is('[data-locked]');
-        },
-        setElementDisabled = function (element, state, triggerEvent) {
-            if (!isLocked(element)) {
-                element.prop('disabled', state);
+    advancedPricingHandler.init();
+    priceTypeHandler.init();
+
+    var blockId = '#<?= /* @noEscape */ $block->getId()?>',
+        hasVariations = <?= /* @noEscape */ $block->isConfigurableProduct() ? 'true' : 'false' ?>,
+        setElementDisabled = function ($element, state, triggerEvent) {
+            if (!$element.is('[data-locked]')) {
+                $element.prop('disabled', state);
+    
                 if (triggerEvent) {
-                    element.trigger('change')
+                    $element.trigger('change');
                 }
             }
+        },
+        configurableTypeHandler = function (isConfigurable) {
+            isConfigurable = hasVariations ? true : isConfigurable;
+            $('[data-form=edit-product]').trigger("change_configurable_type", isConfigurable);
         };
 
-    collapsableArea
+
+    $(blockId + '-wrapper > .collapse')
         .on('show', function() {
-            currentProductTemplateControl
+            $('#product-template-suggest-container .action-dropdown > .action-toggle')
                 .addClass('disabled')
                 .prop('disabled', true);
-
-            attributesInput.prop('disabled', false);
-
-            inventoryQty.prop('disabled', true);
-            inventoryAvailabilityField.removeProp('disabled');
-            setElementDisabled(qtyField, true, true);
-            setElementDisabled(stockAvailabilityField, false, false);
+            $(blockId + ' input[name="attributes[]"]').prop('disabled', false);
+            $('#inventory_qty').prop('disabled', true);
+            $('#inventory_stock_availability').removeProp('disabled');
+            setElementDisabled($('#qty'), true, true);
+            setElementDisabled($('#quantity_and_stock_status'), false, false);
+            configurableTypeHandler(true);
         })
         .on('hide', function() {
-            currentProductTemplateControl
+            $('#product-template-suggest-container .action-dropdown > .action-toggle')
                 .removeClass('disabled')
                 .removeProp('disabled');
-            inventoryQty.removeProp('disabled');
-            inventoryAvailabilityField.prop('disabled', true);
-            setElementDisabled(stockAvailabilityField, true, false);
-            setElementDisabled(qtyField, false, true);
+            $('#inventory_qty').removeProp('disabled');
+            $('#inventory_stock_availability').prop('disabled', true);
+            setElementDisabled($('#quantity_and_stock_status'), true, false);
+            setElementDisabled($('#qty'), false, true);
+            configurableTypeHandler(false);
         })
         .collapse(hasVariations ? 'show' : 'hide');
-
-    var $gridDialog = $('#associated-products-container').modal({
-        title: $.mage.__('Select Associated Product'),
-        type: 'popup'
-    });
-
-    $('[data-panel=product-variations]')
-        .on('disable', '[data-role=product-variations-matrix]', function() {
-            $(this).html('');
-        })
-        .on('click', '[data-action=choose]', function(event) {
-            $gridDialog.trigger('openModal');
-        });
 });
 </script>
+<script type="text/x-magento-init">
+    {
+        "*": {
+            "Magento_Ui/js/core/app": {
+                "components": {
+                    "configurableProductGrid": {
+                        "component": "Magento_ConfigurableProduct/js/variations/product-grid",
+                        "productsFilter": "configurable_associated_product_listing.configurable_associated_product_listing.listing_top.listing_filters",
+                        "productsProvider": "configurable_associated_product_listing.data_source",
+                        "productsMassAction": "configurable_associated_product_listing.configurable_associated_product_listing.product_columns.ids",
+                        "productsColumns": "configurable_associated_product_listing.configurable_associated_product_listing.product_columns",
+                        "productsGridUrl": "<?= /* @noEscape */ $block->getUrl('catalog/product/associated_grid', ['componentJson' => true])?>",
+                        "configurableVariations": "configurableVariations"
+                    }
+                }
+            }
+        }
+    }
+</script>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/manual-product-grid.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/manual-product-grid.phtml
deleted file mode 100644
index 41c67a6f96a3e3bb04eb2e5fdaa56919808c77cf..0000000000000000000000000000000000000000
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/manual-product-grid.phtml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-// @codingStandardsIgnoreFile
-
-/* @var $block \Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Grid\ManualProduct */
-
-?>
-<div>
-    <div data-role="messages" class="messages">
-        <div class="message ">
-            <div>
-                <?= /* @escapeNotVerified */  __('Choose a new product to delete and replace the current product configuration.') ?>
-                <?= /* @escapeNotVerified */  __('For better results, add attributes and attribute values to your products.') ?>
-            </div>
-        </div>
-    </div>
-    <?= $block->getChildHtml(); ?>
-</div>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml
index 9d66be34c0d79a94e889a3d506c88d95e1c502bd..7f33ce7274d9b955716e756a69a87a491be216ad 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/templates/catalog/product/edit/super/matrix.phtml
@@ -12,6 +12,7 @@
 $variations = $block->getVariations();
 $productMatrix = [];
 $attributes = [];
+$fullAttributes = [];
 if ($variations) {
     $usedProductAttributes = $block->getUsedAttributes();
     $productByUsedAttributes = $block->getAssociatedProducts();
@@ -36,6 +37,17 @@ if ($variations) {
                         'position' => $attribute->getPosition(),
                         'chosen' => [],
                     ];
+                    foreach ($attribute->getOptions() as $option) {
+                        if (!empty($option->getValue())) {
+                            $attributes[$attribute->getAttributeId()]['options'][$option->getValue()] = [
+                                'attribute_code' => $attribute->getAttributeCode(),
+                                'attribute_label' => $attribute->getStoreLabel(0),
+                                'id' => $option->getValue(),
+                                'label' => $option->getLabel(),
+                                'value' => $option->getValue(),
+                            ];
+                        }
+                    }
                 }
                 $optionId = $variation[$attribute->getId()]['value'];
                 $variationOption = [
@@ -320,16 +332,13 @@ if ($variations) {
                 "components": {
                     "configurableVariations": {
                         "component": "Magento_ConfigurableProduct/js/variations/variations",
-                        "variations": <?= /* @escapeNotVerified */  $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($productMatrix) ?>,
-                        "productAttributes": <?= /* @escapeNotVerified */  $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($attributes) ?>,
-                        "productUrl": "<?= /* @escapeNotVerified */  $block->getUrl('catalog/product/edit', ['id' => '%id%']) ?>",
-                        "associatedProductsFilter": "configurable_associated_product_listing.configurable_associated_product_listing.listing_top.listing_filters",
-                        "associatedProductsProvider": "configurable_associated_product_listing.data_source"
-
+                        "variations": <?= /* @noEscape */ $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($productMatrix) ?>,
+                        "productAttributes": <?= /* @noEscape */ $this->helper('Magento\Framework\Json\Helper\Data')->jsonEncode($attributes) ?>,
+                        "productUrl": "<?= /* @noEscape */ $block->getUrl('catalog/product/edit', ['id' => '%id%']) ?>",
+                        "configurableProductGrid": "configurableProductGrid"
                     }
                 }
             }
         }
     }
-
 </script>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/ui_component/configurable_associated_product_listing.xml b/app/code/Magento/ConfigurableProduct/view/adminhtml/ui_component/configurable_associated_product_listing.xml
index aee041d2b5bb8e7e6198b807e51738f5c9f67e81..f8ff2b7872c7cac2898d4e1baa2c12bc03520db4 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/ui_component/configurable_associated_product_listing.xml
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/ui_component/configurable_associated_product_listing.xml
@@ -40,43 +40,33 @@
         <filters name="listing_filters" class="Magento\ConfigurableProduct\Ui\Component\Listing\AssociatedProduct\Filters">
             <argument name="data" xsi:type="array">
                 <item name="config" xsi:type="array">
-                    <item name="links" xsi:type="array">
-                        <item name="applied" xsi:type="string">not-save-filter</item>
+                    <item name="params" xsi:type="array">
+                        <item name="filters_modifier" xsi:type="array" />
                     </item>
                     <item name="displayArea" xsi:type="string">dataGridFilters</item>
                     <item name="dataScope" xsi:type="string">filters</item>
-                    <item name="storageConfig" xsi:type="array">
-                        <item name="provider" xsi:type="string">configurable_associated_product_listing.configurable_associated_product_listing.listing_top.bookmarks</item>
-                        <item name="namespace" xsi:type="string">current.filters</item>
-                    </item>
                     <item name="childDefaults" xsi:type="array">
                         <item name="provider" xsi:type="string">configurable_associated_product_listing.configurable_associated_product_listing.listing_top.listing_filters</item>
-                        <item name="imports" xsi:type="array">
-                            <item name="visible" xsi:type="string">configurable_associated_product_listing.configurable_associated_product_listing.listing_top.bookmarks:current.columns.${ $.index }.visible</item>
-                        </item>
                     </item>
                 </item>
             </argument>
-            <filterInput name="name">
+            <filterInput name="entity_id">
                 <argument name="data" xsi:type="array">
                     <item name="config" xsi:type="array">
-                        <item name="dataScope" xsi:type="string">name</item>
+                        <item name="component" xsi:type="string" />
+                        <item name="dataScope" xsi:type="string">entity_id</item>
                         <item name="label" xsi:type="string" translate="true">Name</item>
                     </item>
                 </argument>
             </filterInput>
-            <filterSelect name="attribute_set_id">
-                <argument name="optionsProvider" xsi:type="configurableObject">
-                    <argument name="class" xsi:type="string">Magento\Catalog\Model\Product\AttributeSet\Options</argument>
-                </argument>
+            <filterInput name="name">
                 <argument name="data" xsi:type="array">
                     <item name="config" xsi:type="array">
-                        <item name="dataScope" xsi:type="string">attribute_set_id</item>
-                        <item name="caption" xsi:type="string" translate="true">Select...</item>
-                        <item name="label" xsi:type="string" translate="true">Attribute Set</item>
+                        <item name="dataScope" xsi:type="string">name</item>
+                        <item name="label" xsi:type="string" translate="true">Name</item>
                     </item>
                 </argument>
-            </filterSelect>
+            </filterInput>
             <filterInput name="sku">
                 <argument name="data" xsi:type="array">
                     <item name="config" xsi:type="array">
@@ -131,10 +121,6 @@
             <argument name="data" xsi:type="array">
                 <item name="config" xsi:type="array">
                     <item name="selectProvider" xsi:type="string">configurable_associated_product_listing.configurable_associated_product_listing.product_columns.ids</item>
-                    <item name="storageConfig" xsi:type="array">
-                        <item name="provider" xsi:type="string">configurable_associated_product_listing.configurable_associated_product_listing.listing_top.bookmarks</item>
-                        <item name="namespace" xsi:type="string">current.paging</item>
-                    </item>
                     <item name="displayArea" xsi:type="string">bottom</item>
                     <item name="options" xsi:type="array">
                         <item name="20" xsi:type="array">
@@ -162,27 +148,18 @@
             </argument>
         </paging>
     </container>
-    <columns name="product_columns" class="Magento\Catalog\Ui\Component\Listing\Columns">
+    <columns name="product_columns" class="Magento\ConfigurableProduct\Ui\Component\Listing\AssociatedProduct\Columns">
         <argument name="data" xsi:type="array">
             <item name="config" xsi:type="array">
-                <item name="storageConfig" xsi:type="array">
-                    <item name="provider" xsi:type="string">configurable_associated_product_listing.configurable_associated_product_listing.listing_top.bookmarks</item>
-                    <item name="namespace" xsi:type="string">current</item>
-                </item>
                 <item name="childDefaults" xsi:type="array">
                     <item name="fieldAction" xsi:type="array">
-                        <item name="provider" xsi:type="string">configurableVariations</item>
+                        <item name="provider" xsi:type="string">configurableProductGrid</item>
                         <item name="target" xsi:type="string">selectProduct</item>
                         <item name="params" xsi:type="array">
                             <item name="0" xsi:type="string">${ $.$data.rowIndex }</item>
                         </item>
                     </item>
                     <item name="controlVisibility" xsi:type="boolean">true</item>
-                    <item name="storageConfig" xsi:type="array">
-                        <item name="provider" xsi:type="string">configurable_associated_product_listing.configurable_associated_product_listing.listing_top.bookmarks</item>
-                        <item name="root" xsi:type="string">columns.${ $.index }</item>
-                        <item name="namespace" xsi:type="string">current.${ $.storageConfig.root}</item>
-                    </item>
                 </item>
             </item>
         </argument>
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/advanced-pricing-handler.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/advanced-pricing-handler.js
new file mode 100644
index 0000000000000000000000000000000000000000..3943ac39574018ce7b10a6b4c4912d99b540e434
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/advanced-pricing-handler.js
@@ -0,0 +1,31 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+    'jquery'
+], function ($) {
+    'use strict';
+
+    return {
+        init: function () {
+            $('[data-form=edit-product]')
+                .on('change_configurable_type', function (event, isConfigurable) {
+                    var toggleDisabledAttribute = function (disabled) {
+                        $('[data-tab-panel=advanced-pricing]').find('input,select').each(
+                            function (event, element) {
+                                $(element).attr('disabled', disabled);
+                            }
+                        );
+                    };
+                    if (isConfigurable) {
+                        $('[data-ui-id=product-tabs-tab-link-advanced-pricing]').hide();
+                    } else {
+                        $('[data-ui-id=product-tabs-tab-link-advanced-pricing]').show();
+                    }
+                    toggleDisabledAttribute(isConfigurable);
+                });
+        }
+    };
+});
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/options/price-type-handler.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/options/price-type-handler.js
new file mode 100644
index 0000000000000000000000000000000000000000..fbee8e2b47873b78e6d2cc6d4c8acab5fefe2e26
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/options/price-type-handler.js
@@ -0,0 +1,79 @@
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+define([
+    'jquery',
+    'notification',
+    'mage/translate'
+], function ($) {
+    'use strict';
+
+    return {
+        isConfigurable: false,
+        messageInited: false,
+        messageSelector: '[data-role=product-custom-options-content]',
+        isPercentPriceTypeExist: function () {
+            var productOptionsContainer = $('#product_options_container_top');
+
+            return !!productOptionsContainer.length;
+        },
+        showWarning: function () {
+            if (!this.messageInited) {
+                $(this.messageSelector).notification();
+                this.messageInited = true;
+            }
+            this.hideWarning();
+            $(this.messageSelector).notification('add', {
+                message: $.mage.__('We can\'t save custom-defined options with price type "percent" for ' +
+                    'configurable product.'),
+                error: true,
+                messageContainer: this.messageSelector
+            });
+        },
+        hideWarning: function () {
+            $(this.messageSelector).notification('clear');
+        },
+        init: function () {
+            $('[data-form=edit-product]')
+                .on('change_configurable_type', function (event, isConfigurable) {
+                    this.isConfigurable = isConfigurable;
+                    if (this.isPercentPriceTypeExist()) {
+                        this.percentPriceTypeHandler();
+                    }
+                }.bind(this));
+
+            $('#product-edit-form-tabs').on('change', '.opt-type > select', function () {
+                var selected = $('.opt-type > select :selected'),
+                    optGroup = selected.parent().attr('label');
+
+                if (optGroup === 'Select') {
+                    $('#product-edit-form-tabs').on(
+                        'click',
+                        '[data-ui-id="admin-product-options-options-box-select-option-type-add-select-row-button"]',
+                        function () {
+                            this.percentPriceTypeHandler();
+                        }.bind(this)
+                    );
+                } else {
+                    this.percentPriceTypeHandler();
+                }
+            }.bind(this));
+        },
+        percentPriceTypeHandler: function () {
+            var priceType = $('[data-attr="price-type"]'),
+                optionPercentPriceType = priceType.find('option[value="percent"]');
+
+            if (this.isConfigurable) {
+                this.showWarning();
+                optionPercentPriceType.hide();
+                optionPercentPriceType.parent().val() === 'percent' ? optionPercentPriceType.parent().val('fixed') : '';
+            } else {
+                $(this.messageSelector).notification();
+                optionPercentPriceType.show();
+                this.hideWarning();
+            }
+        }
+    };
+});
\ No newline at end of file
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/product-grid.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/product-grid.js
new file mode 100644
index 0000000000000000000000000000000000000000..39267f93a149ee3247773d529e7ac8cd293e2860
--- /dev/null
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/product-grid.js
@@ -0,0 +1,344 @@
+// jscs:disable requireDotNotation
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+define([
+    'uiComponent',
+    'jquery',
+    'Magento_Ui/js/core/app',
+    'underscore',
+    'notification'
+], function (Component, $, bootstrap, _) {
+    'use strict';
+
+    return Component.extend({
+        defaults: {
+            productsGridUrl: null,
+            productAttributes: [],
+            productsModal: null,
+            button: '',
+            gridSelector: '[data-grid-id=associated-products-container]',
+            modules: {
+                productsFilter: '${ $.productsFilter }',
+                productsProvider: '${ $.productsProvider }',
+                productsMassAction: '${ $.productsMassAction }',
+                productsColumns: '${ $.productsColumns }',
+                variationsComponent: '${ $.configurableVariations }'
+            },
+            listens: {
+                '${ $.productsProvider }:data': '_showMessageAssociatedGrid _handleManualGridOpening',
+                '${ $.productsMassAction }:selected': '_handleManualGridSelect',
+                '${ $.configurableVariations }:productMatrix': '_showButtonAddManual'
+            }
+        },
+
+        /**
+         * Initialize
+         * @param {Array} options
+         */
+        initialize: function (options) {
+            this._super(options);
+            this.productsModal = $(this.gridSelector).modal({
+                title: $.mage.__('Select Associated Product'),
+                type: 'slide',
+                buttons: [
+                    {
+                        text: $.mage.__('Cancel'),
+
+                        /**
+                         * Close modal
+                         * @event
+                         */
+                        click: function () {
+                            this.closeModal();
+                        }
+                    }, {
+                        text: $.mage.__('Done'),
+                        click: this.close.bind(this, null)
+                    }
+                ]
+            });
+
+            this.productsProvider(function () {
+                this.productsModal.notification();
+            }.bind(this));
+            this.variationsComponent(function (variation) {
+                this._showButtonAddManual(variation.productMatrix());
+            }.bind(this));
+
+            this._initGrid = _.once(this._initGrid);
+        },
+
+        /**
+         * Initial observerable
+         * @returns {*}
+         */
+        initObservable: function () {
+            this._super().observe('button');
+
+            return this;
+        },
+
+        /**
+         * init Grid
+         * @private
+         */
+        _initGrid: function (filterData) {
+            $.ajax({
+                type: 'GET',
+                url: this._buildGridUrl(filterData),
+                context: $('body')
+            }).success(function (data) {
+                bootstrap(JSON.parse(data));
+            });
+        },
+
+        /**
+         * Select different product in configurations section
+         * @see configurable_associated_product_listing.xml
+         * @param {Integer} rowIndex
+         */
+        selectProduct: function (rowIndex) {
+            this.close(rowIndex);
+        },
+
+        /**
+         * Open
+         * @param {Object} filterData - filter data
+         * @param {Object|*} filterData.filters - attribute name
+         * @param {Object|*} filterData.filters_modifier - modifier value
+         * @param {String} callbackName
+         * @param {Boolean} showMassActionColumn
+         */
+        open: function (filterData, callbackName, showMassActionColumn) {
+            this.callbackName = callbackName;
+            this.productsMassAction(function (massActionComponent) {
+                this.productsColumns().elems().each(function (rowElement) {
+                    rowElement.disableAction(showMassActionColumn);
+                });
+                massActionComponent.visible(showMassActionColumn);
+            }.bind(this));
+            this._setFilter(filterData);
+            this._initGrid(filterData);
+            this.productsModal.trigger('openModal');
+        },
+
+        /**
+         * Close
+         */
+        close: function (rowIndex) {
+            try {
+                if (this.productsMassAction().selected().length) {
+                    this.variationsComponent()[this.callbackName](this.productsMassAction()
+                        .selected.map(this.getProductById.bind(this)));
+                    this.productsMassAction().selected([]);
+                } else if (!_.isNull(rowIndex)) {
+                    this.variationsComponent()[this.callbackName]([this.getProductByIndex(rowIndex)]);
+                }
+                this.productsModal.trigger('closeModal');
+            } catch (e) {
+                if (e.name === 'UserException') {
+                    this.productsModal.notification('clear');
+                    this.productsModal.notification('add', {
+                        message: e.message,
+                        messageContainer: this.gridSelector
+                    });
+                } else {
+                    throw e;
+                }
+            }
+        },
+
+        /**
+         * Get product by id
+         * @param {Integer} productId
+         * @returns {*}
+         */
+        getProductById: function (productId) {
+            return _.findWhere(this.productsProvider().data.items, {
+                'entity_id': productId
+            });
+        },
+
+        /**
+         * Get product
+         * @param {Integer} rowIndex
+         * @returns {*}
+         */
+        getProductByIndex: function (rowIndex) {
+            return this.productsProvider().data.items[rowIndex];
+        },
+
+        /**
+         * Build grid url
+         * @private
+         */
+        _buildGridUrl: function (filterData) {
+            var params = '?' + $.param({
+                'filters': filterData.filters,
+                'attributes_codes': this._getAttributesCodes(),
+                'filters_modifier': filterData['filters_modifier']
+            });
+
+            return this.productsGridUrl + params;
+        },
+
+        /**
+         * Show button add manual
+         * @param {Array} variations
+         * @returns {*}
+         * @private
+         */
+        _showButtonAddManual: function (variations) {
+            return this.button(variations.length);
+        },
+
+        /**
+         * Get attributes codes used for configurable
+         * @private
+         */
+        _getAttributesCodes: function () {
+            return this.variationsComponent().attributes.pluck('code');
+        },
+
+        /**
+         * Show data associated grid
+         * @private
+         */
+        _showMessageAssociatedGrid: function (data) {
+            this.productsModal.notification('clear');
+
+            if (data.items.length) {
+                this.productsModal.notification('add', {
+                    message: $.mage.__(
+                        'Choose a new product to delete and replace the current product configuration.'
+                    ),
+                    messageContainer: this.gridSelector
+                });
+            } else {
+                this.productsModal.notification('add', {
+                    message: $.mage.__('For better results, add attributes and attribute values to your products.'),
+                    messageContainer: this.gridSelector
+                });
+            }
+        },
+
+        /**
+         * Show manually grid
+         */
+        showManuallyGrid: function () {
+            var filterModifier = _.mapObject(_.object(this._getAttributesCodes(), []), function () {
+                    return {
+                        'condition_type': 'notnull'
+                    };
+                }),
+                usedProductIds = _.values(this.variationsComponent().productAttributesMap);
+
+            if (usedProductIds) {
+                filterModifier['entity_id'] = {
+                    'condition_type': 'nin', value: usedProductIds
+                };
+            }
+
+            this.open(
+                {
+                    'filters_modifier': filterModifier
+                },
+                'appendProducts',
+                true
+            );
+        },
+
+        /**
+         * Handle manual grid after opening
+         * @private
+         */
+        _handleManualGridOpening: function (data) {
+            if (data.items.length && this.callbackName == 'appendProducts') {
+                this.productsColumns().elems().each(function (rowElement) {
+                    rowElement.disableAction(true);
+                });
+
+                this._disableRows(data.items);
+            }
+        },
+
+        /**
+         * Disable rows in grid for products with the same variation key
+         *
+         * @param {Array} items
+         * @param {Array} selectedVariationKeys
+         * @param {Array} selected
+         * @private
+         */
+        _disableRows: function (items, selectedVariationKeys, selected) {
+            selectedVariationKeys = selectedVariationKeys === undefined ? [] : selectedVariationKeys;
+            selected = selected === undefined ? [] : selected;
+            this.productsMassAction(function (massaction) {
+                var configurableVariationKeys = _.union(
+                        selectedVariationKeys,
+                        _.pluck(this.variationsComponent().productMatrix(), 'variationKey')
+                    ),
+                    variationKeyMap = this._getVariationKeyMap(items),
+                    rowsForDisable = _.keys(_.pick(
+                        variationKeyMap,
+                        function (variationKey) {
+                            return configurableVariationKeys.indexOf(variationKey) != -1;
+                        }
+                    ));
+
+                massaction.disabled(_.difference(rowsForDisable, selected));
+            }.bind(this));
+        },
+
+        /**
+         * @private
+         */
+        _handleManualGridSelect: function (selected) {
+            if (this.callbackName == 'appendProducts') {
+                var selectedRows = _.filter(this.productsProvider().data.items, function (row) {
+                        return selected.indexOf(row['entity_id']) != -1;
+                    }),
+                    selectedVariationKeys = _.values(this._getVariationKeyMap(selectedRows));
+                this._disableRows(this.productsProvider().data.items, selectedVariationKeys, selected);
+            }
+        },
+
+        /**
+         * Get variation key map used in manual grid.
+         *
+         * @param items
+         * @returns {Array} [{entity_id: variation-key}, ...]
+         * @private
+         */
+        _getVariationKeyMap: function (items) {
+            this._variationKeyMap = {};
+            _.each(items, function (row) {
+                this._variationKeyMap[row['entity_id']] = _.values(
+                    _.pick(row, this._getAttributesCodes())
+                ).sort().join('-');
+
+            }.bind(this));
+            return this._variationKeyMap;
+        },
+
+        /**
+         * Set filter
+         * @private
+         */
+        _setFilter: function (filterData) {
+            this.productsProvider(function (provider) {
+                provider.params['filters_modifier'] = filterData['filters_modifier'];
+                provider.params['attributes_codes'] = this._getAttributesCodes();
+            }.bind(this));
+
+            this.productsFilter(function (filter) {
+                filter.set('filters', _.extend({
+                    'filters_modifier': filterData['filters_modifier']
+                }, filterData.filters))
+                    .apply();
+            });
+        }
+    });
+});
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/attributes_values.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/attributes_values.js
index fd928ca0f777904475b554dc3923e7eff93a1ee0..78eac86cb658f129ff6836571a5e19c5eff6ec42 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/attributes_values.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/attributes_values.js
@@ -2,6 +2,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+// jscs:disable jsDoc
 define([
     'uiComponent',
     'jquery',
@@ -15,16 +16,17 @@ define([
 
     //connect items with observableArrays
     ko.bindingHandlers.sortableList = {
-        init: function(element, valueAccessor) {
+        init: function (element, valueAccessor) {
             var list = valueAccessor();
 
             $(element).sortable({
                 axis: 'y',
                 handle: '[data-role="draggable"]',
                 tolerance: 'pointer',
-                update: function(event, ui) {
-                    var item = ko.contextFor(ui.item[0]).$data;
-                    var position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);
+                update: function (event, ui) {
+                    var item = ko.contextFor(ui.item[0]).$data,
+                        position = ko.utils.arrayIndexOf(ui.item.parent().children(), ui.item[0]);
+
                     if (ko.contextFor(ui.item[0]).$index() != position) {
                         if (position >= 0) {
                             list.remove(item);
@@ -38,25 +40,35 @@ define([
     };
 
     return Collapsible.extend({
-        stepInitialized: false,
-        attributes: ko.observableArray([]),
         defaults: {
             notificationMessage: {
                 text: null,
                 error: null
-            }
+            },
+            createOptionsUrl: null,
+            attributes: [],
+            stepInitialized: false
         },
         initialize: function () {
             this._super();
-            this.createAttribute = _.wrap(this.createAttribute.bind(this), function () {
-                var args = Array.prototype.slice.call(arguments);
-                return this.doInitSavedOptions.call(this, args.shift().apply(this, args));
+            this.createAttribute = _.wrap(this.createAttribute, function () {
+                var args = _.toArray(arguments),
+                    createAttribute = args.shift();
+
+                return this.doInitSavedOptions(createAttribute.apply(this, args));
             });
             this.createAttribute = _.memoize(this.createAttribute.bind(this), _.property('id'));
         },
+        initObservable: function () {
+            this._super().observe(['attributes']);
+
+            return this;
+        },
         createOption: function () {
             // this - current attribute
-            this.options.push({value: 0, label: '', id: utils.uniqueid(), attribute_id: this.id, is_new: true});
+            this.options.push({
+                value: 0, label: '', id: utils.uniqueid(), attribute_id: this.id, is_new: true
+            });
         },
         saveOption: function (option) {
             if (!_.isEmpty(option.label)) {
@@ -78,6 +90,7 @@ define([
             attribute.chosenOptions = ko.observableArray([]);
             attribute.options = ko.observableArray(_.map(attribute.options, function (option) {
                 option.id = utils.uniqueid();
+
                 return option;
             }));
             attribute.opened = ko.observable(this.initialOpened(index));
@@ -91,15 +104,19 @@ define([
         },
         saveAttribute: function () {
             var errorMessage = $.mage.__('Select options for all attributes or remove unused attributes.');
-            this.attributes.each(function(attribute) {
+            this.attributes.each(function (attribute) {
                 attribute.chosen = [];
+
                 if (!attribute.chosenOptions.getLength()) {
                     throw new Error(errorMessage);
                 }
-                attribute.chosenOptions.each(function(id) {
-                    attribute.chosen.push(attribute.options.findWhere({id:id}));
+                attribute.chosenOptions.each(function (id) {
+                    attribute.chosen.push(attribute.options.findWhere({
+                        id: id
+                    }));
                 });
             });
+
             if (!this.attributes().length) {
                 throw new Error(errorMessage);
             }
@@ -110,30 +127,37 @@ define([
         deSelectAllAttributes: function (attribute) {
             attribute.chosenOptions.removeAll();
         },
-        saveOptions: function() {
+        saveOptions: function () {
             var options = [];
 
-            this.attributes.each(function(attribute) {
-                attribute.chosenOptions.each(function(id) {
-                    var option = attribute.options.findWhere({id:id, is_new: true});
+            this.attributes.each(function (attribute) {
+                attribute.chosenOptions.each(function (id) {
+                    var option = attribute.options.findWhere({
+                        id: id, is_new: true
+                    });
 
                     if (option) {
                         options.push(option);
                     }
                 });
             });
+
             if (!options.length) {
                 return false;
             }
             $.ajax({
-                type: "POST",
+                type: 'POST',
                 url: this.createOptionsUrl,
-                data: {options: options},
+                data: {
+                    options: options
+                },
                 showLoader: true
-            }).done(function(options) {
-                this.attributes.each(function(attribute) {
-                    _.each(options, function(newOptionId, oldOptionId) {
-                        var option = attribute.options.findWhere({id:oldOptionId});
+            }).done(function (savedOptions) {
+                this.attributes.each(function (attribute) {
+                    _.each(savedOptions, function (newOptionId, oldOptionId) {
+                        var option = attribute.options.findWhere({
+                            id: oldOptionId
+                        });
 
                         if (option) {
                             attribute.options.remove(option);
@@ -148,41 +172,46 @@ define([
         },
         requestAttributes: function (attributeIds) {
             $.ajax({
-                type: "POST",
+                type: 'POST',
                 url: this.optionsUrl,
-                data: {attributes: attributeIds},
+                data: {
+                    attributes: attributeIds
+                },
                 showLoader: true
-            }).done(function(attributes){
-                attributes = _.sortBy(attributes, function(attribute) {
+            }).done(function (attributes) {
+                attributes = _.sortBy(attributes, function (attribute) {
                     return this.wizard.data.attributesIds.indexOf(attribute.id);
                 }.bind(this));
                 this.attributes(_.map(attributes, this.createAttribute));
             }.bind(this));
         },
-        doInitSavedOptions: function(attribute) {
-            var selectedAttribute = _.findWhere(this.initData.attributes, {id: attribute.id});
+        doInitSavedOptions: function (attribute) {
+            var selectedOptions, selectedOptionsIds, selectedAttribute = _.findWhere(this.initData.attributes, {
+                id: attribute.id
+            });
 
             if (selectedAttribute) {
-                var selectedOptions = _.pluck(selectedAttribute.chosen, 'value');
-                var selectedOptionsIds = _.pluck(_.filter(attribute.options(), function (option) {
+                selectedOptions = _.pluck(selectedAttribute.chosen, 'value');
+                selectedOptionsIds = _.pluck(_.filter(attribute.options(), function (option) {
                     return _.contains(selectedOptions, option.value);
                 }), 'id');
                 attribute.chosenOptions(selectedOptionsIds);
                 this.initData.attributes = _.without(this.initData.attributes, selectedAttribute);
             }
+
             return attribute;
         },
-        render: function(wizard) {
+        render: function (wizard) {
             this.wizard = wizard;
             this.requestAttributes(wizard.data.attributesIds());
         },
-        force: function(wizard) {
+        force: function (wizard) {
             this.saveOptions();
             this.saveAttribute(wizard);
 
             wizard.data.attributes = this.attributes;
         },
-        back: function(wizard) {
+        back: function (wizard) {
             wizard.data.attributesIds(this.attributes().pluck('id'));
         }
     });
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/bulk.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/bulk.js
index bf58fc27d47a4c8a17698fc1177688392edbf124..435a7ace21418d35de1bf96cf4b24b490315258b 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/bulk.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/bulk.js
@@ -4,6 +4,7 @@
  */
 /*jshint browser:true jquery:true*/
 /*global FORM_KEY*/
+// jscs:disable jsDoc
 define([
     'uiComponent',
     'jquery',
@@ -25,8 +26,8 @@ define([
             attributes: [],
             sections: {},
             images: null,
-            price: "",
-            quantity: "",
+            price: '',
+            quantity: '',
             notificationMessage: {
                 text: null,
                 error: null
@@ -34,6 +35,7 @@ define([
         },
         initObservable: function () {
             this._super().observe('countVariations attributes sections');
+
             return this;
         },
         initialize: function () {
@@ -67,13 +69,15 @@ define([
                 this.quantity = self.quantity;
             };
             this.makeImages = function (images, typePreview) {
+                var preview;
+
                 if (!images) {
                     this.images = [];
                     this.preview = self.noImage;
                     this.file = null;
                 } else {
                     this.images = images;
-                    var preview = _.find(this.images, function (image) {
+                    preview = _.find(this.images, function (image) {
                         return _.contains(image.galleryTypes, typePreview);
                     });
 
@@ -87,25 +91,27 @@ define([
                 }
             };
             this.images = new this.makeImages();
-            _.each(this.sections(), function(section) {
-                section.type.subscribe(function(newValue) {
-                   this.setWizardNotifyMessageDependOnSectionType()
+            _.each(this.sections(), function (section) {
+                section.type.subscribe(function () {
+                    this.setWizardNotifyMessageDependOnSectionType();
                 }.bind(this));
             }, this);
         },
         types: ['each', 'single', 'none'],
-        setWizardNotifyMessageDependOnSectionType: function() {
+        setWizardNotifyMessageDependOnSectionType: function () {
             var flag = false;
 
-            _.each(this.sections(), function(section) {
+            _.each(this.sections(), function (section) {
                 if (section.type() !== 'none') {
                     flag = true;
                 }
             }, this);
 
             if (flag) {
-                this.wizard.setNotificationMessage($.mage.__('Choose this option to delete and replace extension data '+
-                    'for all past configurations.'));
+                this.wizard.setNotificationMessage(
+                    $.mage.__('Choose this option to delete and replace extension data ' +
+                    'for all past configurations.')
+                );
             } else {
                 this.wizard.cleanNotificationMessage();
             }
@@ -113,7 +119,8 @@ define([
         render: function (wizard) {
             this.wizard = wizard;
             this.attributes(wizard.data.attributes());
-            if (this.mode == 'edit') {
+
+            if (this.mode === 'edit') {
                 this.setWizardNotifyMessageDependOnSectionType();
             }
             //fill option section data
@@ -130,35 +137,39 @@ define([
             this.initCountVariations();
             this.bindGalleries();
         },
-        initCountVariations: function() {
-            var variations = this.generateVariation(this.attributes());
-            var newVariations = _.map(variations, function(options) {
-                return this.variationsComponent().getVariationKey(options)
-            }.bind(this));
-            var existingVariations = _.keys(this.variationsComponent().productAttributesMap);
+        initCountVariations: function () {
+            var variations = this.generateVariation(this.attributes()),
+                newVariations = _.map(variations, function (options) {
+                    return this.variationsComponent().getVariationKey(options);
+                }.bind(this)),
+                existingVariations = _.keys(this.variationsComponent().productAttributesMap);
             this.countVariations(_.difference(newVariations, existingVariations).length);
-        } ,
+        },
+
         /**
          * @param attributes example [['b1', 'b2'],['a1', 'a2', 'a3'],['c1', 'c2', 'c3'],['d1']]
          * @returns {*} example [['b1','a1','c1','d1'],['b1','a1','c2','d1']...]
          */
         generateVariation: function (attributes) {
-            return _.reduce(attributes, function(matrix, attribute) {
+            return _.reduce(attributes, function (matrix, attribute) {
                 var tmp = [];
-                _.each(matrix, function(variations){
-                    _.each(attribute.chosen, function(option){
+                _.each(matrix, function (variations) {
+                    _.each(attribute.chosen, function (option) {
                         option.attribute_code = attribute.code;
                         option.attribute_label = attribute.label;
                         tmp.push(_.union(variations, [option]));
                     });
                 });
+
                 if (!tmp.length) {
-                    return _.map(attribute.chosen, function(option){
+                    return _.map(attribute.chosen, function (option) {
                         option.attribute_code = attribute.code;
                         option.attribute_label = attribute.label;
+
                         return [option];
                     });
                 }
+
                 return tmp;
             }, []);
         },
@@ -170,18 +181,20 @@ define([
                             return chosen.id == option.id;
                         });
                     }).sections()[section];
+
                 case 'single':
                     return this.sections()[section].value();
+
                 case 'none':
                     return this[section];
             }
         },
         getImageProperty: function (node) {
-            var types = node.find('[data-role=gallery]').productGallery('option').types;
-            var images = _.map(node.find('[data-role=image]'), function (image) {
+            var types = node.find('[data-role=gallery]').productGallery('option').types,
+                images = _.map(node.find('[data-role=image]'), function (image) {
                 var imageData = $(image).data('imageData');
                 imageData.galleryTypes = _.pluck(_.filter(types, function (type) {
-                    return type.value == imageData.file;
+                    return type.value === imageData.file;
                 }), 'code');
 
                 return imageData;
@@ -197,18 +210,20 @@ define([
                     if (this.sections().images.attribute()) {
                         this.sections().images.attribute().chosen.each(function (option) {
                             option.sections().images = new this.makeImages(
-                                this.getImageProperty($('[data-role=step-gallery-option-'+option.id+']')),
+                                this.getImageProperty($('[data-role=step-gallery-option-' + option.id + ']')),
                                 'thumbnail'
                             );
                         }, this);
                     }
                     break;
+
                 case 'single':
                     this.sections().images.value(new this.makeImages(
                         this.getImageProperty($('[data-role=step-gallery-single]')),
                         'thumbnail'
                     ));
                     break;
+
                 default:
                     this.sections().images.value(new this.makeImages());
                     break;
@@ -223,6 +238,7 @@ define([
             wizard.data.variations = this.generateVariation(this.attributes());
         },
         validate: function () {
+            var formValid;
             _.each(this.sections(), function (section) {
                 switch (section.type()) {
                     case 'each':
@@ -230,6 +246,7 @@ define([
                             throw new Error($.mage.__('Please, select attribute for the section ' + section.label));
                         }
                         break;
+
                     case 'single':
                         if (!section.value()) {
                             throw new Error($.mage.__('Please fill in the values for the section ' + section.label));
@@ -237,23 +254,25 @@ define([
                         break;
                 }
             }, this);
-            var formValid = true;
-            _.each($('[data-role=attributes-values-form]'), function(form) {
+            formValid = true;
+            _.each($('[data-role=attributes-values-form]'), function (form) {
                 formValid = $(form).valid() && formValid;
             });
+
             if (!formValid) {
                 throw new Error($.mage.__('Please, fill correct values'));
             }
         },
-        validateImage: function() {
+        validateImage: function () {
             switch (this.sections().images.type()) {
                 case 'each':
-                    _.each(this.sections()['images'].attribute().chosen, function(option) {
+                    _.each(this.sections()['images'].attribute().chosen, function (option) {
                         if (!option.sections().images.images.length) {
                             throw new Error($.mage.__('Please, select image(s) for your attribute'));
                         }
                     });
                     break;
+
                 case 'single':
                     if (this.sections().images.value().file == null) {
                         throw new Error($.mage.__('Please choose image(s)'));
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js
index b80e8332ed282b942ae870b6171e114e0c604fc0..ab242b267d7eb4c9325392e33a90714f088f0983 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/select_attributes.js
@@ -2,16 +2,17 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+// jscs:disable jsDoc
 define([
     'uiComponent',
     'jquery',
     'underscore',
     'mage/translate'
 ], function (Component, $, _) {
-    "use strict";
+    'use strict';
 
     var initNewAttributeListener = function (provider) {
-        $('[data-role=product-variations-generator]').on('add', function() {
+        $('[data-role=product-variations-generator]').on('add', function () {
             provider().reload();
         });
     };
@@ -31,7 +32,8 @@ define([
             notificationMessage: {
                 text: null,
                 error: null
-            }
+            },
+            selectedAttributes: []
         },
         initialize: function () {
             this._super();
@@ -41,6 +43,7 @@ define([
         },
         initObservable: function () {
             this._super().observe(['selectedAttributes']);
+
             return this;
         },
         render: function (wizard) {
@@ -48,28 +51,33 @@ define([
             this.setNotificationMessage();
         },
         setNotificationMessage: function () {
-            if (this.mode == 'edit') {
+            if (this.mode === 'edit') {
                 this.wizard.setNotificationMessage($.mage.__('When you remove or add an attribute, we automatically ' +
                 'update all configurations and you will need to manually recreate the current configurations.'));
             }
         },
-        doSelectSavedAttributes: function() {
-            if (false === this.stepInitialized) {
+        doSelectSavedAttributes: function () {
+            if (this.stepInitialized === false) {
                 this.stepInitialized = true;
                 //cache attributes labels, which can be present on the 2nd page
-                _.each(this.initData.attributes, function(attribute) {
+                _.each(this.initData.attributes, function (attribute) {
                     this.attributesLabels[attribute.id] = attribute.label;
                 }.bind(this));
                 this.multiselect().selected(_.pluck(this.initData.attributes, 'id'));
             }
         },
-        doSelectedAttributesLabels: function(selected) {
+        doSelectedAttributesLabels: function (selected) {
             var labels = [];
 
             this.selected = selected;
-            _.each(selected, function(attributeId) {
+            _.each(selected, function (attributeId) {
+                var attribute;
+
                 if (!this.attributesLabels[attributeId]) {
-                    var attribute = _.findWhere(this.multiselect().rows(), {attribute_id: attributeId});
+                    attribute = _.findWhere(this.multiselect().rows(), {
+                        attribute_id: attributeId
+                    });
+
                     if (attribute) {
                         this.attributesLabels[attribute.attribute_id] = attribute.frontend_label;
                     }
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js
index c04b2e9931c7c5b9804ab3ab9c63d7ce34f80ae7..0da35357808085b8fe91792cd7bdac8e523a3e37 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/steps/summary.js
@@ -2,6 +2,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+// jscs:disable jsDoc
 define([
     'uiComponent',
     'jquery',
@@ -33,42 +34,49 @@ define([
             this.gridExisting.columns = ko.observableArray();
             this.gridNew.columns = ko.observableArray();
             this.gridDeleted.columns = ko.observableArray();
+
             return this;
         },
         nextLabelText: $.mage.__('Generate Products'),
         variations: [],
         generateGrid: function (variations, getSectionValue) {
-            var productName = this.variationsComponent().getProductValue('name');
-            var productPrice = this.variationsComponent().getProductValue('price');
-            var productWeight = this.variationsComponent().getProductValue('weight');
-            var variationsKeys = [];
-            var gridExisting = [];
-            var gridNew = [];
-            var gridDeleted = [];
+            var productName = this.variationsComponent().getProductValue('name'),
+                productPrice = this.variationsComponent().getProductValue('price'),
+                productWeight = this.variationsComponent().getProductValue('weight'),
+                variationsKeys = [],
+                gridExisting = [],
+                gridNew = [],
+                gridDeleted = [];
             this.variations = [];
 
             _.each(variations, function (options) {
-                var images, sku, quantity, price;
-                var productId = this.variationsComponent().getProductIdByOptions(options);
+                var product, images, sku, quantity, price, variation,
+                    productId = this.variationsComponent().getProductIdByOptions(options);
+
                 if (productId) {
-                    var product = _.findWhere(this.variationsComponent().variations, {productId: productId});
+                    product = _.findWhere(this.variationsComponent().variations, {
+                        productId: productId
+                    });
                 }
                 images = getSectionValue('images', options);
                 sku = productName + _.reduce(options, function (memo, option) {
                     return memo + '-' + option.label;
                 }, '');
                 quantity = getSectionValue('quantity', options);
+
                 if (!quantity && productId) {
                     quantity = product.quantity;
                 }
                 price = getSectionValue('price', options);
+
                 if (!price) {
                     price = productId ? product.price : productPrice;
                 }
+
                 if (productId && !images.file) {
                     images = product.images;
                 }
-                var variation = {
+                variation = {
                     options: options,
                     images: images,
                     sku: sku,
@@ -78,6 +86,7 @@ define([
                     weight: productWeight,
                     editable: true
                 };
+
                 if (productId) {
                     variation.sku = product.sku;
                     variation.weight = product.weight;
@@ -99,7 +108,9 @@ define([
 
             _.each(_.omit(this.variationsComponent().productAttributesMap, variationsKeys), function (productId) {
                 gridDeleted.push(this.prepareRowForGrid(
-                    _.findWhere(this.variationsComponent().variations, {productId: productId})
+                    _.findWhere(this.variationsComponent().variations, {
+                        productId: productId
+                    })
                 ));
             }.bind(this));
 
@@ -108,9 +119,11 @@ define([
                 this.gridDeleted.columns(this.getColumnsName(this.variationsComponent().productAttributes));
             }
         },
-        prepareRowForGrid: function(variation) {
+        prepareRowForGrid: function (variation) {
             var row = [];
-            row.push(_.extend({images: []}, variation.images));
+            row.push(_.extend({
+                images: []
+            }, variation.images));
             row.push(variation.sku);
             row.push(variation.quantity);
             _.each(variation.options, function (option) {
@@ -120,10 +133,10 @@ define([
 
             return row;
         },
-        getGridTemplate: function() {
+        getGridTemplate: function () {
             return this.gridTemplate;
         },
-        getGridId: function() {
+        getGridId: function () {
             return _.uniqueId('grid_');
         },
         getColumnsName: function (attributes) {
@@ -144,11 +157,11 @@ define([
             this.gridDeleted([]);
             this.generateGrid(wizard.data.variations, wizard.data.sectionHelper);
         },
-        force: function (wizard) {
+        force: function () {
             this.variationsComponent().render(this.variations, this.attributes());
             $('[data-role=step-wizard-dialog]').trigger('closeModal');
         },
-        back: function (wizard) {
+        back: function () {
         }
     });
 });
diff --git a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js
index dea945abb299764a3ec86592abbf89d049e220ca..9688fb2bb08c33a6ad5327e59a24a8e3889a8739 100644
--- a/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js
+++ b/app/code/Magento/ConfigurableProduct/view/adminhtml/web/js/variations/variations.js
@@ -1,7 +1,9 @@
+// jscs:disable requireDotNotation
 /**
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+// jscs:disable jsDoc
 define([
     'uiComponent',
     'jquery',
@@ -10,6 +12,12 @@ define([
 ], function (Component, $, ko, _) {
     'use strict';
 
+    function UserException(message) {
+        this.message = message;
+        this.name = 'UserException';
+    }
+    UserException.prototype = Object.create(Error.prototype);
+
     return Component.extend({
         defaults: {
             opened: false,
@@ -17,62 +25,132 @@ define([
             productMatrix: [],
             variations: [],
             productAttributes: [],
+            fullAttributes: [],
             rowIndexToEdit: false,
             productAttributesMap: null,
             modules: {
-                associatedProductsFilter: '${ $.associatedProductsFilter }',
-                associatedProductsProvider: '${ $.associatedProductsProvider }'
+                associatedProductGrid: '${ $.configurableProductGrid }'
             }
         },
         initialize: function () {
             this._super();
+
             if (this.variations.length) {
                 this.render(this.variations, this.productAttributes);
             }
             this.initProductAttributesMap();
         },
-        /**
-         * Select different product in configurations section
-         * @param rowIndex
-         */
-        selectProduct: function (rowIndex) {
-            var productToEdit = this.productMatrix.splice(this.rowIndexToEdit, 1)[0],
-                newProduct = this.associatedProductsProvider().data.items[rowIndex];
-
-            newProduct = _.extend(productToEdit, newProduct);
-            newProduct.productId = productToEdit.entity_id;
-            newProduct.productUrl = this.buildProductUrl(newProduct.entity_id);
-            newProduct.editable = false;
-            newProduct.images = {preview: newProduct.thumbnail_src};
-            this.productAttributesMap[this.getVariationKey(newProduct.options)] = newProduct.productId;
-            this.productMatrix.splice(this.rowIndexToEdit, 0, newProduct);
-            $('#associated-products-container').trigger('closeModal');
-        },
         initObservable: function () {
             this._super().observe('actions opened attributes productMatrix');
+
             return this;
         },
+        showGrid: function (rowIndex) {
+            var product = this.productMatrix()[rowIndex],
+                attributes = JSON.parse(product.attribute);
+            this.rowIndexToEdit = rowIndex;
+
+            this.associatedProductGrid().open(
+                {
+                    'filters': attributes,
+                    'filters_modifier': product.productId ? {
+                        'entity_id': {
+                            'condition_type': 'neq', value: product.productId
+                        }
+                    } : {}
+                },
+                'changeProduct',
+                false
+            );
+        },
+        changeProduct: function (newProducts) {
+            var oldProduct = this.productMatrix()[this.rowIndexToEdit],
+                newProduct = this._makeProduct(_.extend(oldProduct, newProducts[0]));
+            this.productAttributesMap[this.getVariationKey(newProduct.options)] = newProduct.productId;
+            this.productMatrix.splice(this.rowIndexToEdit, 1, newProduct);
+        },
+        appendProducts: function (newProducts) {
+            this.productMatrix.push.apply(
+                this.productMatrix,
+                _.map(
+                    newProducts,
+                    _.wrap(
+                        this._makeProduct.bind(this),
+                        function (func, product) {
+                            var newProduct = func(product);
+                            this.productAttributesMap[this.getVariationKey(newProduct.options)] = newProduct.productId;
+
+                            return newProduct;
+                        }.bind(this)
+                    )
+                )
+            );
+        },
+        _makeProduct: function (product) {
+            var productId = product['entity_id'] || product.productId || null,
+                attributes = _.pick(product, this.attributes.pluck('code')),
+                options = _.map(attributes, function (option, attribute) {
+                    var oldOptions = _.findWhere(this.attributes(), {
+                            code: attribute
+                        }).options,
+                        result;
+
+                    if (_.isFunction(oldOptions)) {
+                        result = oldOptions.findWhere({
+                            value: option
+                        });
+                    } else {
+                        result = _.findWhere(oldOptions, {
+                            value: option
+                        });
+                    }
+
+                    return result;
+                }.bind(this));
+
+            return {
+                attribute: JSON.stringify(attributes),
+                editable: false,
+                images: {
+                    preview: product['thumbnail_src']
+                },
+                name: product.name || product.sku,
+                options: options,
+                price: parseFloat(product.price.replace(/[^\d.]+/g, '')).toFixed(4),
+                productId: productId,
+                productUrl: this.buildProductUrl(productId),
+                quantity: product.quantity || null,
+                sku: product.sku,
+                status: product.status === undefined ? 1 : parseInt(product.status, 10),
+                variationKey: this.getVariationKey(options),
+                weight: product.weight || null
+            };
+        },
         getProductValue: function (name) {
             return $('[name="product[' + name.split('/').join('][') + ']"]', this.productForm).val();
         },
         getRowId: function (data, field) {
             var key = data.variationKey;
+
             return 'variations-matrix-' + key + '-' + field;
         },
-        getVariationRowName: function(variation, field) {
+        getVariationRowName: function (variation, field) {
+            var result;
+
             if (variation.productId) {
-                return 'configurations[' + variation.productId + '][' + field.split('/').join('][') + ']';
+                result = 'configurations[' + variation.productId + '][' + field.split('/').join('][') + ']';
             } else {
-                var key = variation.variationKey;
-                return 'variations-matrix[' + key + '][' + field.split('/').join('][') + ']';
+                result = 'variations-matrix[' + variation.variationKey + '][' + field.split('/').join('][') + ']';
             }
+
+            return result;
         },
         getAttributeRowName: function (attribute, field) {
             return 'product[configurable_attributes_data][' + attribute.id + '][' + field + ']';
         },
         getOptionRowName: function (attribute, option, field) {
-            return 'product[configurable_attributes_data][' + attribute.id + '][values][' + option.value + ']['
-                + field + ']';
+            return 'product[configurable_attributes_data][' + attribute.id + '][values][' +
+                option.value + '][' + field + ']';
         },
         render: function (variations, attributes) {
             this.changeButtonWizard();
@@ -85,6 +163,14 @@ define([
             var $button = $('[data-action=open-steps-wizard] [data-role=button-label]');
             $button.text($button.attr('data-edit-label'));
         },
+
+        /**
+         * Get attributes options
+         * @see use in matrix.phtml
+         * @function
+         * @event
+         * @returns {array}
+         */
         getAttributesOptions: function () {
             return this.showVariations() ? this.productMatrix()[0].options : [];
         },
@@ -96,7 +182,8 @@ define([
             _.each(variations, function (variation) {
                 var attributes = _.reduce(variation.options, function (memo, option) {
                     var attribute = {};
-                    attribute[option.attribute_code] = option.value;
+                    attribute[option['attribute_code']] = option.value;
+
                     return _.extend(memo, attribute);
                 }, {});
                 this.productMatrix.push(_.extend(variation, {
@@ -104,10 +191,10 @@ define([
                     name: variation.name || variation.sku,
                     weight: variation.weight,
                     attribute: JSON.stringify(attributes),
-                    variationKey: _.values(attributes).join('-'),
+                    variationKey: this.getVariationKey(variation.options),
                     editable: variation.editable === undefined ? !variation.productId : variation.editable,
                     productUrl: this.buildProductUrl(variation.productId),
-                    status: variation.status === undefined ? 1 : parseInt(variation.status)
+                    status: variation.status === undefined ? 1 : parseInt(variation.status, 10)
                 }));
             }, this);
         },
@@ -116,38 +203,35 @@ define([
         },
         removeProduct: function (rowIndex) {
             this.opened(false);
-            this.productMatrix.splice(rowIndex, 1);
+            var removedProduct = this.productMatrix.splice(rowIndex, 1);
+            delete this.productAttributesMap[this.getVariationKey(removedProduct[0].options)];
+
             if (this.productMatrix().length === 0) {
-                this.attributes.each(function(attribute) {
+                this.attributes.each(function (attribute) {
                     $('[data-attribute-code="' + attribute.code + '"] select').removeProp('disabled');
                 });
             }
         },
-        showGrid: function (rowIndex) {
-            var attributes = JSON.parse(this.productMatrix()[rowIndex].attribute);
-            this.rowIndexToEdit = rowIndex;
-            this.associatedProductsProvider().params.attribute_ids = _.keys(attributes);
-            this.associatedProductsFilter().set('filters', attributes).apply();
-            $('#associated-products-container').trigger('openModal');
-        },
         toggleProduct: function (rowIndex) {
-            var productChanged = {};
+            var product, row, productChanged = {};
+
             if (this.productMatrix()[rowIndex].editable) {
-                var row = $('[data-row-number=' + rowIndex + ']');
-                _.each('name,sku,qty,weight,price'.split(','), function (column) {
+                row = $('[data-row-number=' + rowIndex + ']');
+                _.each(['name','sku','qty','weight','price'], function (column) {
                     productChanged[column] = $(
                         'input[type=text]',
                         row.find($('[data-column="%s"]'.replace('%s', column)))
                     ).val();
                 });
             }
-            var product = this.productMatrix.splice(rowIndex, 1)[0];
+            product = this.productMatrix.splice(rowIndex, 1)[0];
             product = _.extend(product, productChanged);
-            product.status = !product.status * 1;
+            product.status = +!product.status;
             this.productMatrix.splice(rowIndex, 0, product);
         },
         toggleList: function (rowIndex) {
             var state = false;
+
             if (rowIndex !== this.opened()) {
                 state = rowIndex;
             }
@@ -169,100 +253,110 @@ define([
             return this.productAttributesMap[this.getVariationKey(options)] || null;
         },
         initProductAttributesMap: function () {
-            if (null === this.productAttributesMap) {
+            if (this.productAttributesMap === null) {
                 this.productAttributesMap = {};
-                _.each(this.variations, function(product) {
+                _.each(this.variations, function (product) {
                     this.productAttributesMap[this.getVariationKey(product.options)] = product.productId;
                 }.bind(this));
             }
         },
+
+        /**
+         * Is show preview image
+         * @see use in matrix.phtml
+         * @function
+         * @event
+         * @param {object} variation
+         * @returns {*|boolean}
+         */
         isShowPreviewImage: function (variation) {
             return variation.images.preview && (!variation.editable || variation.images.file);
         },
         generateImageGallery: function (variation) {
-            var gallery = [];
-            var imageFields = ['position', 'file', 'disabled', 'label'];
+            var gallery = [],
+                imageFields = ['position', 'file', 'disabled', 'label'];
             _.each(variation.images.images, function (image) {
                 _.each(imageFields, function (field) {
                     gallery.push(
-                        '<input type="hidden" name="'
-                        + this.getVariationRowName(variation, 'media_gallery/images/' + image.file_id + '/' + field)
-                        + '" value="' + (image[field] || '') + '" />'
+                        '<input type="hidden" name="' +
+                        this.getVariationRowName(variation, 'media_gallery/images/' + image['file_id'] + '/' + field) +
+                        '" value="' + (image[field] || '') + '" />'
                     );
                 }, this);
                 _.each(image.galleryTypes, function (imageType) {
                     gallery.push(
-                        '<input type="hidden" name="' + this.getVariationRowName(variation, imageType)
-                        + '" value="' + image.file + '" />'
+                        '<input type="hidden" name="' + this.getVariationRowName(variation, imageType) +
+                        '" value="' + image.file + '" />'
                     );
                 }, this);
             }, this);
+
             return gallery.join('\n');
         },
         initImageUpload: function () {
             require([
-                "jquery",
-                "mage/template",
-                "jquery/file-uploader",
-                "mage/mage",
-                "mage/translate"
-            ], function (jQuery, mageTemplate) {
+                'mage/template',
+                'jquery/file-uploader',
+                'mage/mage',
+                'mage/translate',
+                'domReady!'
+            ], function (mageTemplate) {
 
-                jQuery(function ($) {
-                    var matrix = $('[data-role=product-variations-matrix]');
-                    matrix.find('[data-action=upload-image]').find('[name=image]').each(function () {
-                        var imageColumn = $(this).closest('[data-column=image]');
-                        if (imageColumn.find('[data-role=image]').length) {
-                            imageColumn.find('[data-toggle=dropdown]').dropdown().show();
-                        }
-                        $(this).fileupload({
-                            dataType: 'json',
-                            dropZone: $(this).closest('[data-role=row]'),
-                            acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
-                            done: function (event, data) {
-                                var tmpl;
+                var matrix = $('[data-role=product-variations-matrix]');
+                matrix.find('[data-action=upload-image]').find('[name=image]').each(function () {
+                    var imageColumn = $(this).closest('[data-column=image]');
 
-                                if (!data.result) {
-                                    return;
-                                }
-                                if (!data.result.error) {
-                                    var parentElement = $(event.target).closest('[data-column=image]'),
-                                        uploaderControl = parentElement.find('[data-action=upload-image]'),
-                                        imageElement = parentElement.find('[data-role=image]');
+                    if (imageColumn.find('[data-role=image]').length) {
+                        imageColumn.find('[data-toggle=dropdown]').dropdown().show();
+                    }
+                    $(this).fileupload({
+                        dataType: 'json',
+                        dropZone: $(this).closest('[data-role=row]'),
+                        acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i,
+                        done: function (event, data) {
+                            var tmpl, parentElement, uploaderControl, imageElement;
+
+                            if (!data.result) {
+                                return;
+                            }
 
-                                    if (imageElement.length) {
-                                        imageElement.attr('src', data.result.url);
-                                    } else {
-                                        tmpl = mageTemplate(matrix.find('[data-template-for=variation-image]').html());
+                            if (!data.result.error) {
+                                parentElement = $(event.target).closest('[data-column=image]');
+                                uploaderControl = parentElement.find('[data-action=upload-image]');
+                                imageElement = parentElement.find('[data-role=image]');
 
-                                        $(tmpl({
-                                            data: data.result
-                                        })).prependTo(uploaderControl);
-                                    }
-                                    parentElement.find('[name$="[image]"]').val(data.result.file);
-                                    parentElement.find('[data-toggle=dropdown]').dropdown().show();
+                                if (imageElement.length) {
+                                    imageElement.attr('src', data.result.url);
                                 } else {
-                                    alert($.mage.__('We don\'t recognize or support this file extension type.'));
+                                    tmpl = mageTemplate(matrix.find('[data-template-for=variation-image]').html());
+
+                                    $(tmpl({
+                                        data: data.result
+                                    })).prependTo(uploaderControl);
                                 }
-                            },
-                            start: function (event) {
-                                $(event.target).closest('[data-action=upload-image]').addClass('loading');
-                            },
-                            stop: function (event) {
-                                $(event.target).closest('[data-action=upload-image]').removeClass('loading');
+                                parentElement.find('[name$="[image]"]').val(data.result.file);
+                                parentElement.find('[data-toggle=dropdown]').dropdown().show();
+                            } else {
+                                alert($.mage.__('We don\'t recognize or support this file extension type.'));
                             }
-                        });
-                    });
-                    matrix.find('[data-action=no-image]').click(function (event) {
-                        var parentElement = $(event.target).closest('[data-column=image]');
-                        parentElement.find('[data-role=image]').remove();
-                        parentElement.find('[name$="[image]"]').val('');
-                        parentElement.find('[data-toggle=dropdown]').trigger('close.dropdown').hide();
+                        },
+                        start: function (event) {
+                            $(event.target).closest('[data-action=upload-image]').addClass('loading');
+                        },
+                        stop: function (event) {
+                            $(event.target).closest('[data-action=upload-image]').removeClass('loading');
+                        }
                     });
                 });
+                matrix.find('[data-action=no-image]').click(function (event) {
+                    var parentElement = $(event.target).closest('[data-column=image]');
+                    parentElement.find('[data-role=image]').remove();
+                    parentElement.find('[name$="[image]"]').val('');
+                    parentElement.find('[data-toggle=dropdown]').trigger('close.dropdown').hide();
+                });
             });
         },
-        disableConfigurableAttributes: function(attributes) {
+        disableConfigurableAttributes: function (attributes) {
             _.each(attributes, function (attribute) {
                 $('[data-attribute-code="' + attribute.code + '"] select').prop('disabled', true);
             });
diff --git a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml
index 4452a8b46fa6ad07c7ecdde0b47f7bb8fe9da194..b5d537a55956ad0fe2a5b10c48fe8936a04b6d1d 100644
--- a/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml
+++ b/app/code/Magento/Customer/view/frontend/templates/widget/gender.phtml
@@ -14,7 +14,7 @@
             <?php $options = $block->getGenderOptions(); ?>
             <?php $value = $block->getGender();?>
             <?php foreach ($options as $option):?>
-                <option value="<?php /* @escapeNotVerified */ echo $option->getValue() ?>"<?php if ($option->getValue() == $value) echo ' selected="selected"' ?>><?php /* @escapeNotVerified */ echo $option->getLabel() ?></option>
+                <option value="<?php /* @escapeNotVerified */ echo $option->getValue() ?>"<?php if ($option->getValue() == $value) echo ' selected="selected"' ?>><?php /* @escapeNotVerified */ echo __($option->getLabel()) ?></option>
             <?php endforeach;?>
         </select>
     </div>
diff --git a/app/code/Magento/Ui/Component/Filters/FilterModifier.php b/app/code/Magento/Ui/Component/Filters/FilterModifier.php
new file mode 100644
index 0000000000000000000000000000000000000000..d1db57a2ac49488c5f43cb516fab85de1c910185
--- /dev/null
+++ b/app/code/Magento/Ui/Component/Filters/FilterModifier.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Component\Filters;
+
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
+use Magento\Framework\App\RequestInterface;
+use Magento\Framework\Api\FilterBuilder;
+
+/**
+ * Apply modifiers to filter
+ */
+class FilterModifier
+{
+    /**
+     * Filter modifier variable name
+     */
+    const FILTER_MODIFIER = 'filters_modifier';
+
+    /** @var RequestInterface */
+    protected $request;
+
+    /** @var FilterBuilder */
+    protected $filterBuilder;
+
+    /** @var array */
+    protected $allowedConditionTypes;
+
+    /**
+     * @param RequestInterface $request
+     * @param FilterBuilder $filterBuilder
+     * @param array $allowedConditionTypes
+     */
+    public function __construct(RequestInterface $request, FilterBuilder $filterBuilder, $allowedConditionTypes = [])
+    {
+        $this->request = $request;
+        $this->filterBuilder = $filterBuilder;
+        $this->allowedConditionTypes = array_merge(
+            ['eq', 'neq', 'in', 'nin', 'null', 'notnull'],
+            $allowedConditionTypes
+        );
+    }
+
+    /**
+     * Apply modifiers for filters
+     *
+     * @param DataProviderInterface $dataProvider
+     * @param string $filterName
+     * @return void
+     * @throws \Magento\Framework\Exception\LocalizedException
+     */
+    public function applyFilterModifier(DataProviderInterface $dataProvider, $filterName)
+    {
+        $filterModifier = $this->request->getParam(self::FILTER_MODIFIER);
+        if (isset($filterModifier[$filterName]['condition_type'])) {
+            $conditionType = $filterModifier[$filterName]['condition_type'];
+            if (!in_array($conditionType, $this->allowedConditionTypes)) {
+                throw new \Magento\Framework\Exception\LocalizedException(
+                    __('Condition type "%1" is not allowed', $conditionType)
+                );
+            }
+            $value = isset($filterModifier[$filterName]['value'])
+                ? $filterModifier[$filterName]['value']
+                : null;
+            $filter = $this->filterBuilder->setConditionType($conditionType)
+                ->setField($filterName)
+                ->setValue($value)
+                ->create();
+            $dataProvider->addFilter($filter);
+        }
+    }
+}
diff --git a/app/code/Magento/Ui/Component/Filters/Type/AbstractFilter.php b/app/code/Magento/Ui/Component/Filters/Type/AbstractFilter.php
index 02b8767c3e263d3d03d27e34441be4d58fdad407..d5642acc8666b9651ea419d57b72d5b40a72e29c 100644
--- a/app/code/Magento/Ui/Component/Filters/Type/AbstractFilter.php
+++ b/app/code/Magento/Ui/Component/Filters/Type/AbstractFilter.php
@@ -9,6 +9,7 @@ use Magento\Ui\Component\AbstractComponent;
 use Magento\Framework\View\Element\UiComponentFactory;
 use Magento\Framework\View\Element\UiComponent\ContextInterface;
 use Magento\Framework\Api\FilterBuilder;
+use Magento\Ui\Component\Filters\FilterModifier;
 
 /**
  * Abstract class AbstractFilter
@@ -42,10 +43,16 @@ abstract class AbstractFilter extends AbstractComponent
      */
     protected $filterBuilder;
 
+    /**
+     * @var FilterModifier
+     */
+    protected $filterModifier;
+
     /**
      * @param ContextInterface $context
      * @param UiComponentFactory $uiComponentFactory
      * @param FilterBuilder $filterBuilder
+     * @param FilterModifier $filterModifier
      * @param array $components
      * @param array $data
      */
@@ -53,6 +60,7 @@ abstract class AbstractFilter extends AbstractComponent
         ContextInterface $context,
         UiComponentFactory $uiComponentFactory,
         FilterBuilder $filterBuilder,
+        FilterModifier $filterModifier,
         array $components = [],
         array $data = []
     ) {
@@ -60,6 +68,7 @@ abstract class AbstractFilter extends AbstractComponent
         $this->filterBuilder = $filterBuilder;
         parent::__construct($context, $components, $data);
         $this->filterData = $this->getContext()->getFiltersParams();
+        $this->filterModifier = $filterModifier;
     }
 
     /**
@@ -71,4 +80,13 @@ abstract class AbstractFilter extends AbstractComponent
     {
         return static::NAME;
     }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function prepare()
+    {
+        $this->filterModifier->applyFilterModifier($this->getContext()->getDataProvider(), $this->getName());
+        parent::prepare();
+    }
 }
diff --git a/app/code/Magento/Ui/Component/Filters/Type/Select.php b/app/code/Magento/Ui/Component/Filters/Type/Select.php
index 5b26dfc57daa514600aee606e2db588dfd46f816..8b826799993e988b673fce88702035f48042c9e8 100644
--- a/app/code/Magento/Ui/Component/Filters/Type/Select.php
+++ b/app/code/Magento/Ui/Component/Filters/Type/Select.php
@@ -9,6 +9,7 @@ use Magento\Framework\Data\OptionSourceInterface;
 use Magento\Framework\View\Element\UiComponentFactory;
 use Magento\Framework\View\Element\UiComponent\ContextInterface;
 use Magento\Ui\Component\Form\Element\Select as ElementSelect;
+use Magento\Ui\Component\Filters\FilterModifier;
 
 /**
  * Class Select
@@ -35,6 +36,7 @@ class Select extends AbstractFilter
      * @param ContextInterface $context
      * @param UiComponentFactory $uiComponentFactory
      * @param \Magento\Framework\Api\FilterBuilder $filterBuilder
+     * @param FilterModifier $filterModifier
      * @param OptionSourceInterface|null $optionsProvider
      * @param array $components
      * @param array $data
@@ -43,12 +45,13 @@ class Select extends AbstractFilter
         ContextInterface $context,
         UiComponentFactory $uiComponentFactory,
         \Magento\Framework\Api\FilterBuilder $filterBuilder,
+        FilterModifier $filterModifier,
         OptionSourceInterface $optionsProvider = null,
         array $components = [],
         array $data = []
     ) {
         $this->optionsProvider = $optionsProvider;
-        parent::__construct($context, $uiComponentFactory, $filterBuilder, $components, $data);
+        parent::__construct($context, $uiComponentFactory, $filterBuilder, $filterModifier, $components, $data);
     }
 
     /**
diff --git a/app/code/Magento/Ui/Component/Layout.php b/app/code/Magento/Ui/Component/Layout.php
index 2dd070f4f2d5445e9d8b46583a35a2b0b6ed511f..ab2a4b53a735001b5adaa8b8ee054390b48562e6 100644
--- a/app/code/Magento/Ui/Component/Layout.php
+++ b/app/code/Magento/Ui/Component/Layout.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Ui\Component;
 
-use Magento\Ui\Component\Layout\LayoutPool;
+use Magento\Framework\View\Layout\Pool as LayoutPool;
 use Magento\Framework\View\Element\Template;
 use Magento\Framework\View\Element\UiComponent\LayoutInterface;
 use Magento\Framework\View\Element\UiComponent\ContextInterface;
diff --git a/app/code/Magento/Ui/Component/Layout/Tabs.php b/app/code/Magento/Ui/Component/Layout/Tabs.php
index cd36ed90824792cdf68aaf97201d356f31a1741a..34021f0d8782d49a31647f87d92f114591304491 100644
--- a/app/code/Magento/Ui/Component/Layout/Tabs.php
+++ b/app/code/Magento/Ui/Component/Layout/Tabs.php
@@ -5,7 +5,6 @@
  */
 namespace Magento\Ui\Component\Layout;
 
-use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\View\Element\Template;
 use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
 use Magento\Ui\Component\Layout\Tabs\TabInterface;
@@ -16,7 +15,7 @@ use Magento\Framework\View\Element\UiComponent\LayoutInterface;
 /**
  * Class Tabs
  */
-class Tabs extends Generic implements LayoutInterface
+class Tabs extends \Magento\Framework\View\Layout\Generic implements LayoutInterface
 {
     /**
      * @var string
diff --git a/app/code/Magento/Ui/TemplateEngine/Xhtml/Result.php b/app/code/Magento/Ui/TemplateEngine/Xhtml/Result.php
index 8060896296318c65ead5875a90b36e04ac6cdc0c..e2138de2221a918ceeeb17f25665d6d140cc1d13 100644
--- a/app/code/Magento/Ui/TemplateEngine/Xhtml/Result.php
+++ b/app/code/Magento/Ui/TemplateEngine/Xhtml/Result.php
@@ -5,7 +5,7 @@
  */
 namespace Magento\Ui\TemplateEngine\Xhtml;
 
-use Magento\Ui\Component\Layout\Generator\Structure;
+use Magento\Framework\View\Layout\Generator\Structure;
 use Magento\Framework\View\Element\UiComponentInterface;
 use Magento\Framework\View\TemplateEngine\Xhtml\Template;
 use Magento\Framework\View\TemplateEngine\Xhtml\ResultInterface;
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php b/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a7f954bac61396b1fe69198cab98816234f29d0f
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Unit/Component/Filters/FilterModifierTest.php
@@ -0,0 +1,139 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Test\Unit\Component\Filters;
+
+use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
+
+/**
+ * Class DateRangeTest
+ */
+class FilterModifierTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\Framework\App\RequestInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $request;
+
+    /**
+     * @var DataProviderInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $dataProvider;
+
+    /**
+     * @var \Magento\Framework\Api\FilterBuilder|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filterBuilder;
+
+    /**
+     * @var \Magento\Ui\Component\Filters\FilterModifier
+     */
+    protected $unit;
+
+    /**
+     * Set up
+     */
+    public function setUp()
+    {
+        $this->request = $this->getMockForAbstractClass('Magento\Framework\App\RequestInterface');
+        $this->dataProvider = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface'
+        );
+        $this->filterBuilder = $this->getMock(
+            'Magento\Framework\Api\FilterBuilder',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->unit = (new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this))
+            ->getObject(
+                'Magento\Ui\Component\Filters\FilterModifier',
+                [
+                    'request' => $this->request,
+                    'filterBuilder' => $this->filterBuilder,
+                ]
+            );
+    }
+
+    /**
+     * @return void
+     */
+    public function testNotApplyFilterModifier()
+    {
+        $this->request->expects($this->once())->method('getParam')
+            ->with(\Magento\Ui\Component\Filters\FilterModifier::FILTER_MODIFIER)
+            ->willReturn([]);
+        $this->dataProvider->expects($this->never())->method('addFilter');
+        $this->unit->applyFilterModifier($this->dataProvider, 'test');
+    }
+
+    /**
+     * @return void
+     * @assertException \Magento\Framework\Exception\LocalizedException
+     */
+    public function testApplyFilterModifierWithNotAllowedCondition()
+    {
+        $this->request->expects($this->once())->method('getParam')
+            ->with(\Magento\Ui\Component\Filters\FilterModifier::FILTER_MODIFIER)
+            ->willReturn([
+                'filter' => [
+                    'condition_type' => 'not_allowed'
+                ]
+            ]);
+        $this->dataProvider->expects($this->never())->method('addFilter');
+        $this->unit->applyFilterModifier($this->dataProvider, 'test');
+    }
+
+    /**
+     * @param $filterModifier
+     * @param $filterName
+     * @param $conditionType
+     * @param $value
+     * @return void
+     * @dataProvider getApplyFilterModifierDataProvider
+     */
+    public function testApplyFilterModifierWith($filterModifier, $filterName, $conditionType, $value)
+    {
+        $filter = $this->getMock('Magento\Framework\Api\Filter');
+
+        $this->request->expects($this->once())->method('getParam')
+            ->with(\Magento\Ui\Component\Filters\FilterModifier::FILTER_MODIFIER)
+            ->willReturn($filterModifier);
+        $this->filterBuilder->expects($this->once())->method('setConditionType')->with($conditionType)
+            ->willReturnSelf();
+        $this->filterBuilder->expects($this->once())->method('setField')->with($filterName)->willReturnSelf();
+        $this->filterBuilder->expects($this->once())->method('setValue')->with($value)->willReturnSelf();
+        $this->filterBuilder->expects($this->once())->method('create')->with()->willReturn($filter);
+        $this->dataProvider->expects($this->once())->method('addFilter')->with($filter);
+
+        $this->unit->applyFilterModifier($this->dataProvider, $filterName);
+    }
+
+    /**
+     * @return array
+     */
+    public function getApplyFilterModifierDataProvider()
+    {
+        return [
+            [
+                [
+                    'filter1' => ['condition_type' => 'eq', 'value' => '5',]
+                ],
+                'filter1',
+                'eq',
+                '5'
+            ],
+            [
+                [
+                    'filter2' => ['condition_type' => 'notnull']
+                ],
+                'filter2',
+                'notnull',
+                null
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/DateRangeTest.php b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/DateRangeTest.php
index 36bc19158e9701bbeacaf0d642d569a29658d630..6a2a0b545678dc66181b408795e15be8bebbba4d 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/DateRangeTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/DateRangeTest.php
@@ -32,6 +32,11 @@ class DateRangeTest extends \PHPUnit_Framework_TestCase
      */
     protected $filterBuilderMock;
 
+    /**
+     * @var \Magento\Ui\Component\Filters\FilterModifier|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filterModifierMock;
+
     /**
      * Set up
      */
@@ -57,6 +62,13 @@ class DateRangeTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->filterModifierMock = $this->getMock(
+            'Magento\Ui\Component\Filters\FilterModifier',
+            ['applyFilterModifier'],
+            [],
+            '',
+            false
+        );
     }
 
     /**
@@ -70,6 +82,7 @@ class DateRangeTest extends \PHPUnit_Framework_TestCase
             $this->contextMock,
             $this->uiComponentFactory,
             $this->filterBuilderMock,
+            $this->filterModifierMock,
             []
         );
         $this->assertTrue($dateRange->getComponentName() === DateRange::NAME);
@@ -109,22 +122,22 @@ class DateRangeTest extends \PHPUnit_Framework_TestCase
             ->method('getRequestParam')
             ->with(UiContext::FILTER_VAR)
             ->willReturn($filterData);
+        $dataProvider = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
+            [],
+            '',
+            false
+        );
+        $this->contextMock->expects($this->any())
+            ->method('getDataProvider')
+            ->willReturn($dataProvider);
 
         if ($expectedCondition !== null) {
             /** @var DataProviderInterface $dataProvider */
-            $dataProvider = $this->getMockForAbstractClass(
-                'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
-                [],
-                '',
-                false
-            );
             $dataProvider->expects($this->any())
                 ->method('addFilter')
                 ->with($expectedCondition, $name);
 
-            $this->contextMock->expects($this->any())
-                ->method('getDataProvider')
-                ->willReturn($dataProvider);
 
             $uiComponent->expects($this->any())
                 ->method('getLocale')
@@ -143,6 +156,7 @@ class DateRangeTest extends \PHPUnit_Framework_TestCase
             $this->contextMock,
             $this->uiComponentFactory,
             $this->filterBuilderMock,
+            $this->filterModifierMock,
             [],
             ['name' => $name]
         );
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/DateTest.php b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/DateTest.php
index 3e76608a50743cf1e6a6f4e54f601e7b819c7d76..79af8056579f644d965f348b20302f9c8dd122b6 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/DateTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/DateTest.php
@@ -32,6 +32,11 @@ class DateTest extends \PHPUnit_Framework_TestCase
      */
     protected $filterBuilderMock;
 
+    /**
+     * @var \Magento\Ui\Component\Filters\FilterModifier|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filterModifierMock;
+
     /**
      * Set up
      */
@@ -57,6 +62,15 @@ class DateTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+
+        $this->filterModifierMock = $this->getMock(
+            'Magento\Ui\Component\Filters\FilterModifier',
+            ['applyFilterModifier'],
+            [],
+            '',
+            false
+        );
+
     }
 
     /**
@@ -70,6 +84,7 @@ class DateTest extends \PHPUnit_Framework_TestCase
             $this->contextMock,
             $this->uiComponentFactory,
             $this->filterBuilderMock,
+            $this->filterModifierMock,
             []
         );
 
@@ -110,23 +125,20 @@ class DateTest extends \PHPUnit_Framework_TestCase
             ->method('getRequestParam')
             ->with(UiContext::FILTER_VAR)
             ->willReturn($filterData);
-
+        $dataProvider = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
+            [],
+            '',
+            false
+        );
+        $this->contextMock->expects($this->any())
+            ->method('getDataProvider')
+            ->willReturn($dataProvider);
         if ($expectedCondition !== null) {
-            /** @var DataProviderInterface $dataProvider */
-            $dataProvider = $this->getMockForAbstractClass(
-                'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
-                [],
-                '',
-                false
-            );
             $dataProvider->expects($this->any())
                 ->method('addFilter')
                 ->with($expectedCondition, $name);
 
-            $this->contextMock->expects($this->any())
-                ->method('getDataProvider')
-                ->willReturn($dataProvider);
-
             $uiComponent->expects($this->any())
                 ->method('getLocale')
                 ->willReturn($expectedCondition['locale']);
@@ -144,6 +156,7 @@ class DateTest extends \PHPUnit_Framework_TestCase
             $this->contextMock,
             $this->uiComponentFactory,
             $this->filterBuilderMock,
+            $this->filterModifierMock,
             [],
             ['name' => $name]
         );
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/InputTest.php b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/InputTest.php
index cf33a86653fd73caa96f8c58934f65582c7abd53..a3736ad6bd5028bbfc4e2201253a6aaa4043a59c 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/InputTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/InputTest.php
@@ -32,6 +32,11 @@ class InputTest extends \PHPUnit_Framework_TestCase
      */
     protected $filterBuilderMock;
 
+    /**
+     * @var \Magento\Ui\Component\Filters\FilterModifier|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filterModifierMock;
+
     /**
      * Set up
      */
@@ -57,6 +62,13 @@ class InputTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->filterModifierMock = $this->getMock(
+            'Magento\Ui\Component\Filters\FilterModifier',
+            ['applyFilterModifier'],
+            [],
+            '',
+            false
+        );
     }
 
     /**
@@ -70,6 +82,7 @@ class InputTest extends \PHPUnit_Framework_TestCase
             $this->contextMock,
             $this->uiComponentFactory,
             $this->filterBuilderMock,
+            $this->filterModifierMock,
             []
         );
 
@@ -109,22 +122,19 @@ class InputTest extends \PHPUnit_Framework_TestCase
             ->method('getRequestParam')
             ->with(UiContext::FILTER_VAR)
             ->willReturn($filterData);
-
+        $dataProvider = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
+            [],
+            '',
+            false
+        );
+        $this->contextMock->expects($this->any())
+            ->method('getDataProvider')
+            ->willReturn($dataProvider);
         if ($expectedCondition !== null) {
-            /** @var DataProviderInterface $dataProvider */
-            $dataProvider = $this->getMockForAbstractClass(
-                'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
-                [],
-                '',
-                false
-            );
             $dataProvider->expects($this->any())
                 ->method('addFilter')
                 ->with($expectedCondition, $name);
-
-            $this->contextMock->expects($this->any())
-                ->method('getDataProvider')
-                ->willReturn($dataProvider);
         }
 
         $this->uiComponentFactory->expects($this->any())
@@ -136,6 +146,7 @@ class InputTest extends \PHPUnit_Framework_TestCase
             $this->contextMock,
             $this->uiComponentFactory,
             $this->filterBuilderMock,
+            $this->filterModifierMock,
             [],
             ['name' => $name]
         );
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/RangeTest.php b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/RangeTest.php
index b3da88e49eb4bddc5519d184bd67d4ced2446aa0..d28cb78ee21c9e8dd2535003786193975c1e9f45 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/RangeTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/RangeTest.php
@@ -31,6 +31,11 @@ class RangeTest extends \PHPUnit_Framework_TestCase
      */
     protected $filterBuilderMock;
 
+    /**
+     * @var \Magento\Ui\Component\Filters\FilterModifier|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filterModifierMock;
+
     /**
      * Set up
      */
@@ -57,6 +62,13 @@ class RangeTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->filterModifierMock = $this->getMock(
+            'Magento\Ui\Component\Filters\FilterModifier',
+            ['applyFilterModifier'],
+            [],
+            '',
+            false
+        );
     }
 
     /**
@@ -70,6 +82,7 @@ class RangeTest extends \PHPUnit_Framework_TestCase
             $this->contextMock,
             $this->uiComponentFactory,
             $this->filterBuilderMock,
+            $this->filterModifierMock,
             []
         );
 
@@ -97,28 +110,27 @@ class RangeTest extends \PHPUnit_Framework_TestCase
             ->method('getRequestParam')
             ->with(UiContext::FILTER_VAR)
             ->willReturn($filterData);
-
+        /** @var DataProviderInterface $dataProvider */
+        $dataProvider = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
+            [],
+            '',
+            false
+        );
+        $this->contextMock->expects($this->any())
+            ->method('getDataProvider')
+            ->willReturn($dataProvider);
         if ($expectedCondition !== null) {
-            /** @var DataProviderInterface $dataProvider */
-            $dataProvider = $this->getMockForAbstractClass(
-                'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
-                [],
-                '',
-                false
-            );
             $dataProvider->expects($this->any())
                 ->method('addFilter')
                 ->with($expectedCondition, $name);
-
-            $this->contextMock->expects($this->any())
-                ->method('getDataProvider')
-                ->willReturn($dataProvider);
         }
 
         $range = new Range(
             $this->contextMock,
             $this->uiComponentFactory,
             $this->filterBuilderMock,
+            $this->filterModifierMock,
             [],
             ['name' => $name]
         );
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/SelectTest.php b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/SelectTest.php
index 24237520a321ba1552216d01f8c4cb0dd43f56a2..45b200fc58494f0964058447e5fe04cb97a5de94 100644
--- a/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/SelectTest.php
+++ b/app/code/Magento/Ui/Test/Unit/Component/Filters/Type/SelectTest.php
@@ -32,6 +32,11 @@ class SelectTest extends \PHPUnit_Framework_TestCase
      */
     protected $filterBuilderMock;
 
+    /**
+     * @var \Magento\Ui\Component\Filters\FilterModifier|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $filterModifierMock;
+
     /**
      * Set up
      */
@@ -57,6 +62,13 @@ class SelectTest extends \PHPUnit_Framework_TestCase
             '',
             false
         );
+        $this->filterModifierMock = $this->getMock(
+            'Magento\Ui\Component\Filters\FilterModifier',
+            ['applyFilterModifier'],
+            [],
+            '',
+            false
+        );
     }
 
     /**
@@ -70,6 +82,7 @@ class SelectTest extends \PHPUnit_Framework_TestCase
             $this->contextMock,
             $this->uiComponentFactory,
             $this->filterBuilderMock,
+            $this->filterModifierMock,
             null,
             []
         );
@@ -110,22 +123,21 @@ class SelectTest extends \PHPUnit_Framework_TestCase
             ->method('getRequestParam')
             ->with(AbstractFilter::FILTER_VAR)
             ->willReturn($filterData);
+        /** @var DataProviderInterface $dataProvider */
+        $dataProvider = $this->getMockForAbstractClass(
+            'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
+            [],
+            '',
+            false
+        );
+        $this->contextMock->expects($this->any())
+            ->method('getDataProvider')
+            ->willReturn($dataProvider);
 
         if ($expectedCondition !== null) {
-            /** @var DataProviderInterface $dataProvider */
-            $dataProvider = $this->getMockForAbstractClass(
-                'Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface',
-                [],
-                '',
-                false
-            );
             $dataProvider->expects($this->any())
                 ->method('addFilter')
                 ->with($expectedCondition, $name);
-
-            $this->contextMock->expects($this->any())
-                ->method('getDataProvider')
-                ->willReturn($dataProvider);
         }
 
         /** @var \Magento\Framework\Data\OptionSourceInterface $selectOptions */
@@ -145,6 +157,7 @@ class SelectTest extends \PHPUnit_Framework_TestCase
             $this->contextMock,
             $this->uiComponentFactory,
             $this->filterBuilderMock,
+            $this->filterModifierMock,
             $selectOptions,
             [],
             ['name' => $name]
diff --git a/app/code/Magento/Ui/etc/di.xml b/app/code/Magento/Ui/etc/di.xml
index a29e842f3eaab3f48a9eca422b6f474d416e7ea4..a96eecf8ad05e1481ee9a7e1313809f7a2ffa3a4 100644
--- a/app/code/Magento/Ui/etc/di.xml
+++ b/app/code/Magento/Ui/etc/di.xml
@@ -12,7 +12,7 @@
     <preference for="Magento\Framework\Config\ConverterInterface" type="Magento\Framework\View\Element\UiComponent\Config\Converter" />
     <preference for="Magento\Framework\View\Element\UiComponent\Config\ManagerInterface" type="Magento\Ui\Model\Manager" />
     <preference for="Magento\Framework\View\Element\UiComponent\ContextInterface" type="Magento\Framework\View\Element\UiComponent\Context" />
-    <preference for="Magento\Framework\View\Element\UiComponent\LayoutInterface" type="Magento\Ui\Component\Layout\Generic"/>
+    <preference for="Magento\Framework\View\Element\UiComponent\LayoutInterface" type="Magento\Framework\View\Layout\Generic"/>
     <preference for="Magento\Authorization\Model\UserContextInterface" type="Magento\User\Model\Authorization\AdminSessionUserContext"/>
     <preference for="Magento\Ui\Api\Data\BookmarkSearchResultsInterface" type="Magento\Framework\Api\SearchResults" />
     <preference for="Magento\Ui\Api\BookmarkRepositoryInterface" type="Magento\Ui\Model\Resource\BookmarkRepository"/>
@@ -153,11 +153,11 @@
             </argument>
         </arguments>
     </type>
-    <type name="Magento\Ui\Component\Layout\LayoutPool">
+    <type name="Magento\Framework\View\Layout\Pool">
         <arguments>
             <argument name="types" xsi:type="array">
                 <item name="generic" xsi:type="array">
-                    <item name="class" xsi:type="string">Magento\Ui\Component\Layout\Generic</item>
+                    <item name="class" xsi:type="string">Magento\Framework\View\Layout\Generic</item>
                     <item name="template" xsi:type="string">templates/layout/generic</item>
                 </item>
                 <item name="tabs" xsi:type="array">
diff --git a/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js
index 80e50c62db9e598eb94ab98cf2bc840683e64aa5..905cd7d44ebf43246d26e2327392adb0fee0bc26 100644
--- a/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js
+++ b/app/code/Magento/Ui/view/base/web/js/grid/columns/multiselect.js
@@ -19,6 +19,7 @@ define([
             allSelected: false,
             indetermine: false,
             selected: [],
+            disabled: [],
             excluded: [],
             actions: [{
                 value: 'selectAll',
@@ -58,6 +59,7 @@ define([
         initObservable: function () {
             this._super()
                 .observe([
+                    'disabled',
                     'menuVisible',
                     'selected',
                     'excluded',
@@ -216,7 +218,10 @@ define([
          * @returns {Multiselect} Chainable.
          */
         selectPage: function () {
-            var selected = _.union(this.selected(), this.getIds());
+            var selected = _.difference(
+                _.union(this.selected(), this.getIds()),
+                this.disabled()
+            );
 
             this.selected(selected);
 
diff --git a/app/code/Magento/Ui/view/base/web/js/lib/step-wizard.js b/app/code/Magento/Ui/view/base/web/js/lib/step-wizard.js
index 020f1353c17564c29ea00b95509dd08c7abefd6d..af68997cdf95d217ccdb35590db951f0a5314233 100644
--- a/app/code/Magento/Ui/view/base/web/js/lib/step-wizard.js
+++ b/app/code/Magento/Ui/view/base/web/js/lib/step-wizard.js
@@ -2,24 +2,29 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
+// jscs:disable jsDoc
 define([
-    "uiRegistry",
-    "uiComponent",
-    "jquery",
-    "underscore",
-    "ko",
-    "mage/backend/notification"
+    'uiRegistry',
+    'uiComponent',
+    'jquery',
+    'underscore',
+    'ko',
+    'mage/backend/notification'
 ], function (uiRegistry, Component, $, _, ko) {
-    "use strict";
+    'use strict';
 
-    ko.utils.domNodeDisposal.cleanExternalData = _.wrap(ko.utils.domNodeDisposal.cleanExternalData,
-        function(func, node) {
+    var Wizard;
+
+    ko.utils.domNodeDisposal.cleanExternalData = _.wrap(
+        ko.utils.domNodeDisposal.cleanExternalData,
+        function (func, node) {
             if (!$(node).closest('[data-type=skipKO]').length) {
                 func(node);
             }
-    });
+        }
+    );
 
-    var Wizard = function (steps) {
+    Wizard = function (steps) {
         this.steps = steps;
         this.index = 0;
         this.data = {};
@@ -44,19 +49,23 @@ define([
         };
         this.next = function () {
             this.move(this.index + 1);
+
             return this.getStep().name;
         };
         this.prev = function () {
             this.move(this.index - 1);
+
             return this.getStep().name;
         };
-        this.preventSwitch = function(newIndex) {
+        this.preventSwitch = function (newIndex) {
             return newIndex < 0 || (newIndex - this.index) > 1;
         };
         this._next = function (newIndex) {
             newIndex = _.isNumber(newIndex) ? newIndex : this.index + 1;
+
             try {
                 this.getStep().force(this);
+
                 if (newIndex >= steps.length) {
                     return false;
                 }
@@ -91,6 +100,7 @@ define([
         this.showNotificationMessage = function () {
             if (!_.isEmpty(this.getStep())) {
                 this.hideNotificationMessage();
+
                 if (this.getStep().notificationMessage.text !== null) {
                     this.notifyMessage(
                         this.getStep().notificationMessage.text,
@@ -109,7 +119,8 @@ define([
             }
         };
         this.setNotificationMessage = function (text, error) {
-            error = typeof error !== 'undefined';
+            error = error !== undefined;
+
             if (!_.isEmpty(this.getStep())) {
                 this.getStep().notificationMessage.text = text;
                 this.getStep().notificationMessage.error = error;
@@ -189,7 +200,7 @@ define([
         showSpecificStep: function () {
             var index = _.indexOf(this.stepsNames, event.target.hash.substr(1)),
                 stepName = this.wizard.move(index);
-            
+
             this.selectedStep(stepName);
         }
     });
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/cells/multiselect.html b/app/code/Magento/Ui/view/base/web/templates/grid/cells/multiselect.html
index 4028c2210a5a16c7edb922cd0e4302984367774a..242c651f006d16896d55dcb52d0d8332bab9eb71 100644
--- a/app/code/Magento/Ui/view/base/web/templates/grid/cells/multiselect.html
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/cells/multiselect.html
@@ -5,13 +5,14 @@
  */
 -->
 
-<td class="data-grid-checkbox-cell">
+<td class="data-grid-checkbox-cell" data-bind="visible: visible">
     <label class="data-grid-checkbox-cell-inner">
         <input
             class="admin__control-checkbox"
             type="checkbox"
             data-action="select-row"
             data-bind="
+                disable: disabled.indexOf(row[indexField]) != -1,
                 checked: selected,
                 value: row[indexField],
                 attr: {
diff --git a/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html b/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html
index e30329410f28bc15a3fe9daf47d36c73751193df..a2dce41dda5f53b643fe9ca7d092dc693e7dad44 100644
--- a/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html
+++ b/app/code/Magento/Ui/view/base/web/templates/grid/columns/multiselect.html
@@ -5,7 +5,7 @@
  */
 -->
 
-<th class="data-grid-multicheck-cell">
+<th class="data-grid-multicheck-cell" data-bind="visible: visible">
     <div
         class="action-multicheck-wrap"
         data-bind="css: { '_active': menuVisible, '_disabled': !totalRecords()},
diff --git a/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_steps-wizard.less b/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_steps-wizard.less
index d4d0f23d07a1b77b8f962ddafe2a011dd85181e6..ce66c1ae77264e8f76f84e17d7888963b7262ba0 100644
--- a/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_steps-wizard.less
+++ b/app/design/adminhtml/Magento/backend/Magento_ConfigurableProduct/web/css/source/module/components/_steps-wizard.less
@@ -24,7 +24,7 @@
     .product-create-configuration-actions {
         float: right;
         text-align: right;
-        width: 50%;
+        width: 25%;
     }
 }
 
diff --git a/composer.json b/composer.json
index 0889646cdd9c7635d753b3f62a77a6ca8c75f96a..aaee3a68a7e769aa2e1eb874ae7166d9e5c2ae91 100644
--- a/composer.json
+++ b/composer.json
@@ -89,6 +89,7 @@
         "magento/module-catalog-import-export": "self.version",
         "magento/module-catalog-inventory": "self.version",
         "magento/module-catalog-rule": "self.version",
+        "magento/module-catalog-rule-configurable": "self.version",
         "magento/module-catalog-search": "self.version",
         "magento/module-catalog-url-rewrite": "self.version",
         "magento/module-catalog-widget": "self.version",
diff --git a/composer.lock b/composer.lock
index 7b9e8f0f7f2e4197432b42cf7591e3eed6f3f008..7a535537728f48501df92ac8949dc4abdccb6454 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,8 +4,8 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
         "This file is @generated automatically"
     ],
-    "hash": "ba8186cbc63f5db144177d64249726e6",
-    "content-hash": "3cd6f56bf239297dae995a6f57937f93",
+    "hash": "e0a48d8c3c8b3c4282676fee9dc9abbc",
+    "content-hash": "5354ef6633dacbab5d7c144ca116624c",
     "packages": [
         {
             "name": "braintree/braintree_php",
@@ -217,20 +217,20 @@
         },
         {
             "name": "magento/magento-composer-installer",
-            "version": "0.1.4",
+            "version": "0.1.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/magento/magento-composer-installer.git",
-                "reference": "7f03451f71e55d52c2bb07325d56a4e6df322f30"
+                "reference": "1b33917bfc3f4a0856276dcbe46ce35362f50fc3"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/magento/magento-composer-installer/zipball/7f03451f71e55d52c2bb07325d56a4e6df322f30",
-                "reference": "7f03451f71e55d52c2bb07325d56a4e6df322f30",
+                "url": "https://api.github.com/repos/magento/magento-composer-installer/zipball/1b33917bfc3f4a0856276dcbe46ce35362f50fc3",
+                "reference": "1b33917bfc3f4a0856276dcbe46ce35362f50fc3",
                 "shasum": ""
             },
             "require": {
-                "composer-plugin-api": "1.0.0"
+                "composer-plugin-api": "^1.0"
             },
             "require-dev": {
                 "composer/composer": "*@dev",
@@ -289,7 +289,7 @@
                 "composer-installer",
                 "magento"
             ],
-            "time": "2015-03-05 21:40:30"
+            "time": "2015-09-14 19:59:55"
         },
         {
             "name": "magento/zendframework1",
@@ -1017,12 +1017,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-code.git",
-                "reference": "cfd5951ff4348e4430850560416c7ddb755f95d3"
+                "reference": "0ed94f842ba60cdc900c46a61bdbd7ac95a3e140"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-code/zipball/0ed94f842ba60cdc900c46a61bdbd7ac95a3e140",
-                "reference": "cfd5951ff4348e4430850560416c7ddb755f95d3",
+                "reference": "0ed94f842ba60cdc900c46a61bdbd7ac95a3e140",
                 "shasum": ""
             },
             "require": {
@@ -1031,6 +1031,9 @@
             },
             "require-dev": {
                 "doctrine/common": ">=2.1",
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-stdlib": "self.version"
             },
             "suggest": {
@@ -1046,7 +1049,7 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Code\\": ""
+                    "Zend\\Code\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1054,12 +1057,12 @@
                 "BSD-3-Clause"
             ],
             "description": "provides facilities to generate arbitrary code using an object oriented interface",
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-code",
             "keywords": [
                 "code",
                 "zf2"
             ],
-            "time": "2015-04-01 17:59:08"
+            "time": "2015-03-31 15:39:14"
         },
         {
             "name": "zendframework/zend-config",
@@ -1067,12 +1070,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-config.git",
-                "reference": "8682fe4e2923b383bb6472fc84b5796a07589163"
+                "reference": "95f3a4b3fa85d49e6f060183122de4596fa6d29d"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-config/zipball/95f3a4b3fa85d49e6f060183122de4596fa6d29d",
-                "reference": "8682fe4e2923b383bb6472fc84b5796a07589163",
+                "reference": "95f3a4b3fa85d49e6f060183122de4596fa6d29d",
                 "shasum": ""
             },
             "require": {
@@ -1080,6 +1083,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-filter": "self.version",
                 "zendframework/zend-i18n": "self.version",
                 "zendframework/zend-json": "self.version",
@@ -1100,7 +1106,7 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Config\\": ""
+                    "Zend\\Config\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1108,12 +1114,12 @@
                 "BSD-3-Clause"
             ],
             "description": "provides a nested object property based user interface for accessing this configuration data within application code",
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-config",
             "keywords": [
                 "config",
                 "zf2"
             ],
-            "time": "2015-04-01 17:59:31"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-console",
@@ -1121,18 +1127,23 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-console.git",
-                "reference": "94ab6663b07e19f20b3319ecf317bd72b6a72dca"
+                "reference": "54823d9ba6f8ce39046384ee5a043b5b3d5f56d7"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-console/zipball/54823d9ba6f8ce39046384ee5a043b5b3d5f56d7",
-                "reference": "94ab6663b07e19f20b3319ecf317bd72b6a72dca",
+                "reference": "54823d9ba6f8ce39046384ee5a043b5b3d5f56d7",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.23",
                 "zendframework/zend-stdlib": "self.version"
             },
+            "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master"
+            },
             "suggest": {
                 "zendframework/zend-filter": "To support DefaultRouteMatcher usage",
                 "zendframework/zend-validator": "To support DefaultRouteMatcher usage"
@@ -1146,19 +1157,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Console\\": ""
+                    "Zend\\Console\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-console",
             "keywords": [
                 "console",
                 "zf2"
             ],
-            "time": "2015-04-01 17:59:48"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-crypt",
@@ -1217,12 +1228,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-di.git",
-                "reference": "0811f2a67ad0b50dfb8d602ed67cde0b82249190"
+                "reference": "b9f8de081adecf71a003a569e9ba76c0a4c00bf2"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-di/zipball/b9f8de081adecf71a003a569e9ba76c0a4c00bf2",
-                "reference": "0811f2a67ad0b50dfb8d602ed67cde0b82249190",
+                "reference": "b9f8de081adecf71a003a569e9ba76c0a4c00bf2",
                 "shasum": ""
             },
             "require": {
@@ -1231,6 +1242,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-servicemanager": "self.version"
             },
             "suggest": {
@@ -1245,19 +1259,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Di\\": ""
+                    "Zend\\Di\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-di",
             "keywords": [
                 "di",
                 "zf2"
             ],
-            "time": "2015-04-01 18:01:30"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-escaper",
@@ -1265,17 +1279,22 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-escaper.git",
-                "reference": "65b3328627362b0be1d5e9067bc846511d1fbc96"
+                "reference": "15e5769e4fcdb4bf07ebd76500810e7070e23a97"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-escaper/zipball/15e5769e4fcdb4bf07ebd76500810e7070e23a97",
-                "reference": "65b3328627362b0be1d5e9067bc846511d1fbc96",
+                "reference": "15e5769e4fcdb4bf07ebd76500810e7070e23a97",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.23"
             },
+            "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
@@ -1285,19 +1304,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Escaper\\": ""
+                    "Zend\\Escaper\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-escaper",
             "keywords": [
                 "escaper",
                 "zf2"
             ],
-            "time": "2015-04-01 18:02:07"
+            "time": "2015-03-23 18:29:14"
         },
         {
             "name": "zendframework/zend-eventmanager",
@@ -1305,18 +1324,23 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-eventmanager.git",
-                "reference": "38df5b567d4ff4d22144745c503ba0502d0d5695"
+                "reference": "58d21c95c7005a527262fd536499195f104e83f9"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/58d21c95c7005a527262fd536499195f104e83f9",
-                "reference": "38df5b567d4ff4d22144745c503ba0502d0d5695",
+                "reference": "58d21c95c7005a527262fd536499195f104e83f9",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.23",
                 "zendframework/zend-stdlib": "self.version"
             },
+            "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
@@ -1326,19 +1350,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\EventManager\\": ""
+                    "Zend\\EventManager\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-event-manager",
             "keywords": [
                 "eventmanager",
                 "zf2"
             ],
-            "time": "2015-04-01 18:05:26"
+            "time": "2015-03-23 18:29:14"
         },
         {
             "name": "zendframework/zend-filter",
@@ -1346,12 +1370,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-filter.git",
-                "reference": "b13741a88553351fc52472de529b57b580b8f6f1"
+                "reference": "6d8aed2da81b62a04747346c4370562cdbe34595"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-filter/zipball/6d8aed2da81b62a04747346c4370562cdbe34595",
-                "reference": "b13741a88553351fc52472de529b57b580b8f6f1",
+                "reference": "6d8aed2da81b62a04747346c4370562cdbe34595",
                 "shasum": ""
             },
             "require": {
@@ -1359,6 +1383,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-crypt": "self.version",
                 "zendframework/zend-servicemanager": "self.version",
                 "zendframework/zend-uri": "self.version"
@@ -1378,7 +1405,7 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Filter\\": ""
+                    "Zend\\Filter\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1386,12 +1413,12 @@
                 "BSD-3-Clause"
             ],
             "description": "provides a set of commonly needed data filters",
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-filter",
             "keywords": [
                 "filter",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:25"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-form",
@@ -1399,12 +1426,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-form.git",
-                "reference": "09f5bd46ffbf783df22281898e2175b291bd43a3"
+                "reference": "bca0db55718355d25c2c10fdd41a83561f1c94b3"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-form/zipball/bca0db55718355d25c2c10fdd41a83561f1c94b3",
-                "reference": "09f5bd46ffbf783df22281898e2175b291bd43a3",
+                "reference": "bca0db55718355d25c2c10fdd41a83561f1c94b3",
                 "shasum": ""
             },
             "require": {
@@ -1413,6 +1440,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-captcha": "self.version",
                 "zendframework/zend-code": "self.version",
                 "zendframework/zend-eventmanager": "self.version",
@@ -1443,19 +1473,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Form\\": ""
+                    "Zend\\Form\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-form",
             "keywords": [
                 "form",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:25"
+            "time": "2015-03-28 20:29:18"
         },
         {
             "name": "zendframework/zend-http",
@@ -1463,12 +1493,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-http.git",
-                "reference": "ee6220609845b32d1b2873c9ac694aef56d508f5"
+                "reference": "9c6047a0bdb3094d3ea07a215ff929cc47de4deb"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-http/zipball/9c6047a0bdb3094d3ea07a215ff929cc47de4deb",
-                "reference": "ee6220609845b32d1b2873c9ac694aef56d508f5",
+                "reference": "9c6047a0bdb3094d3ea07a215ff929cc47de4deb",
                 "shasum": ""
             },
             "require": {
@@ -1478,6 +1508,11 @@
                 "zendframework/zend-uri": "self.version",
                 "zendframework/zend-validator": "self.version"
             },
+            "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
@@ -1487,7 +1522,7 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Http\\": ""
+                    "Zend\\Http\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1495,12 +1530,12 @@
                 "BSD-3-Clause"
             ],
             "description": "provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests",
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-http",
             "keywords": [
                 "http",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:25"
+            "time": "2015-03-27 15:46:30"
         },
         {
             "name": "zendframework/zend-i18n",
@@ -1508,12 +1543,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-i18n.git",
-                "reference": "33051775d9a8c341fe3b77d1f3daa0e921e2f4bd"
+                "reference": "9aebc5287373a802540d75fe5508417f866c2e52"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-i18n/zipball/9aebc5287373a802540d75fe5508417f866c2e52",
-                "reference": "33051775d9a8c341fe3b77d1f3daa0e921e2f4bd",
+                "reference": "9aebc5287373a802540d75fe5508417f866c2e52",
                 "shasum": ""
             },
             "require": {
@@ -1521,6 +1556,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-cache": "self.version",
                 "zendframework/zend-config": "self.version",
                 "zendframework/zend-eventmanager": "self.version",
@@ -1549,19 +1587,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\I18n\\": ""
+                    "Zend\\I18n\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-i18n",
             "keywords": [
                 "i18n",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:26"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-inputfilter",
@@ -1569,12 +1607,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-inputfilter.git",
-                "reference": "16856fec61f285e41e5492235220a4dec06ab90f"
+                "reference": "4b1398f3635fae3cc5e873c5bb067274f3d10a93"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-inputfilter/zipball/4b1398f3635fae3cc5e873c5bb067274f3d10a93",
-                "reference": "16856fec61f285e41e5492235220a4dec06ab90f",
+                "reference": "4b1398f3635fae3cc5e873c5bb067274f3d10a93",
                 "shasum": ""
             },
             "require": {
@@ -1584,6 +1622,9 @@
                 "zendframework/zend-validator": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-servicemanager": "self.version"
             },
             "suggest": {
@@ -1598,19 +1639,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\InputFilter\\": ""
+                    "Zend\\InputFilter\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-input-filter",
             "keywords": [
                 "inputfilter",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:26"
+            "time": "2015-03-23 18:29:14"
         },
         {
             "name": "zendframework/zend-json",
@@ -1618,12 +1659,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-json.git",
-                "reference": "76aeb27e4baf39799e5ca3cf6f2fdd6748ee930c"
+                "reference": "2d845e151c1b9a237cf1899ac31e17fb10bd1e3f"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-json/zipball/2d845e151c1b9a237cf1899ac31e17fb10bd1e3f",
-                "reference": "76aeb27e4baf39799e5ca3cf6f2fdd6748ee930c",
+                "reference": "2d845e151c1b9a237cf1899ac31e17fb10bd1e3f",
                 "shasum": ""
             },
             "require": {
@@ -1631,6 +1672,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-http": "self.version",
                 "zendframework/zend-server": "self.version"
             },
@@ -1648,7 +1692,7 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Json\\": ""
+                    "Zend\\Json\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1656,12 +1700,12 @@
                 "BSD-3-Clause"
             ],
             "description": "provides convenience methods for serializing native PHP to JSON and decoding JSON to native PHP",
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-json",
             "keywords": [
                 "json",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:26"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-loader",
@@ -1669,17 +1713,22 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-loader.git",
-                "reference": "6868b8a0c346f17fb97724c3a63aa2cbf6b94865"
+                "reference": "65de2c7a56f8eee633c6bf1cfab73e45648880d4"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-loader/zipball/65de2c7a56f8eee633c6bf1cfab73e45648880d4",
-                "reference": "6868b8a0c346f17fb97724c3a63aa2cbf6b94865",
+                "reference": "65de2c7a56f8eee633c6bf1cfab73e45648880d4",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.23"
             },
+            "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
@@ -1689,19 +1738,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Loader\\": ""
+                    "Zend\\Loader\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-loader",
             "keywords": [
                 "loader",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:26"
+            "time": "2015-03-23 18:29:14"
         },
         {
             "name": "zendframework/zend-log",
@@ -1709,12 +1758,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-log.git",
-                "reference": "2d5d20fd45470506bdaff727c46dc25fe953146e"
+                "reference": "002e3c810cad7e31e51c9895e9e3cb6fbd312cdd"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-log/zipball/002e3c810cad7e31e51c9895e9e3cb6fbd312cdd",
-                "reference": "2d5d20fd45470506bdaff727c46dc25fe953146e",
+                "reference": "002e3c810cad7e31e51c9895e9e3cb6fbd312cdd",
                 "shasum": ""
             },
             "require": {
@@ -1723,6 +1772,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-console": "self.version",
                 "zendframework/zend-db": "self.version",
                 "zendframework/zend-escaper": "self.version",
@@ -1746,7 +1798,7 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Log\\": ""
+                    "Zend\\Log\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1754,13 +1806,13 @@
                 "BSD-3-Clause"
             ],
             "description": "component for general purpose logging",
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-log",
             "keywords": [
                 "log",
                 "logging",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:26"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-math",
@@ -1768,17 +1820,22 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-math.git",
-                "reference": "634123f83ca90b6613f132d0d100e6b5e9890a29"
+                "reference": "f41fe4acfd809c14f2a802d1aa45dec8fcd2cc73"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-math/zipball/f41fe4acfd809c14f2a802d1aa45dec8fcd2cc73",
-                "reference": "634123f83ca90b6613f132d0d100e6b5e9890a29",
+                "reference": "f41fe4acfd809c14f2a802d1aa45dec8fcd2cc73",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.23"
             },
+            "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master"
+            },
             "suggest": {
                 "ext-bcmath": "If using the bcmath functionality",
                 "ext-gmp": "If using the gmp functionality",
@@ -1794,19 +1851,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Math\\": ""
+                    "Zend\\Math\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-math",
             "keywords": [
                 "math",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:27"
+            "time": "2015-03-23 18:29:14"
         },
         {
             "name": "zendframework/zend-modulemanager",
@@ -1814,12 +1871,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-modulemanager.git",
-                "reference": "cbe16b0eafe734a062ed0182381e64b9c953dccf"
+                "reference": "af7ae3cd29a1efb73cc66ae1081e606039d5c20f"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-modulemanager/zipball/af7ae3cd29a1efb73cc66ae1081e606039d5c20f",
-                "reference": "cbe16b0eafe734a062ed0182381e64b9c953dccf",
+                "reference": "af7ae3cd29a1efb73cc66ae1081e606039d5c20f",
                 "shasum": ""
             },
             "require": {
@@ -1828,6 +1885,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-config": "self.version",
                 "zendframework/zend-console": "self.version",
                 "zendframework/zend-loader": "self.version",
@@ -1849,19 +1909,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\ModuleManager\\": ""
+                    "Zend\\ModuleManager\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-module-manager",
             "keywords": [
                 "modulemanager",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:27"
+            "time": "2015-03-23 18:29:14"
         },
         {
             "name": "zendframework/zend-mvc",
@@ -1869,12 +1929,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-mvc.git",
-                "reference": "bfff0f5f9e4d925ee13b8c159c9d6ae7e0db5412"
+                "reference": "0b4a4a829b30be510a3f215c4ff00c703ee8b431"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-mvc/zipball/0b4a4a829b30be510a3f215c4ff00c703ee8b431",
-                "reference": "bfff0f5f9e4d925ee13b8c159c9d6ae7e0db5412",
+                "reference": "0b4a4a829b30be510a3f215c4ff00c703ee8b431",
                 "shasum": ""
             },
             "require": {
@@ -1885,6 +1945,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-authentication": "self.version",
                 "zendframework/zend-console": "self.version",
                 "zendframework/zend-di": "self.version",
@@ -1933,19 +1996,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Mvc\\": ""
+                    "Zend\\Mvc\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-mvc",
             "keywords": [
                 "mvc",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:27"
+            "time": "2015-03-26 18:55:14"
         },
         {
             "name": "zendframework/zend-serializer",
@@ -1953,12 +2016,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-serializer.git",
-                "reference": "a46960854d6326f0036d98c9abc7a79e36e25928"
+                "reference": "3c531789a9882a5deb721356a7bd2642b65d4b09"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-serializer/zipball/3c531789a9882a5deb721356a7bd2642b65d4b09",
-                "reference": "a46960854d6326f0036d98c9abc7a79e36e25928",
+                "reference": "3c531789a9882a5deb721356a7bd2642b65d4b09",
                 "shasum": ""
             },
             "require": {
@@ -1968,6 +2031,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-servicemanager": "self.version"
             },
             "suggest": {
@@ -1982,7 +2048,7 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Serializer\\": ""
+                    "Zend\\Serializer\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -1990,12 +2056,12 @@
                 "BSD-3-Clause"
             ],
             "description": "provides an adapter based interface to simply generate storable representation of PHP types by different facilities, and recover",
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-serializer",
             "keywords": [
                 "serializer",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:28"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-server",
@@ -2003,12 +2069,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-server.git",
-                "reference": "fc73c34490908ba143af3c57c7e166b40c4b9f8e"
+                "reference": "d11ff0bd529d202022823d4accf5983cbd50fc49"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-server/zipball/d11ff0bd529d202022823d4accf5983cbd50fc49",
-                "reference": "fc73c34490908ba143af3c57c7e166b40c4b9f8e",
+                "reference": "d11ff0bd529d202022823d4accf5983cbd50fc49",
                 "shasum": ""
             },
             "require": {
@@ -2016,6 +2082,11 @@
                 "zendframework/zend-code": "self.version",
                 "zendframework/zend-stdlib": "self.version"
             },
+            "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
@@ -2025,19 +2096,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Server\\": ""
+                    "Zend\\Server\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-server",
             "keywords": [
                 "server",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:28"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-servicemanager",
@@ -2045,18 +2116,21 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-servicemanager.git",
-                "reference": "d3c27c708a148a30608f313a5b7a61a531bd9cb9"
+                "reference": "57cf99fa5ac08c05a135a8d0d676c52a5e450083"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-servicemanager/zipball/57cf99fa5ac08c05a135a8d0d676c52a5e450083",
-                "reference": "d3c27c708a148a30608f313a5b7a61a531bd9cb9",
+                "reference": "57cf99fa5ac08c05a135a8d0d676c52a5e450083",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.23"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-di": "self.version"
             },
             "suggest": {
@@ -2072,19 +2146,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\ServiceManager\\": ""
+                    "Zend\\ServiceManager\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-service-manager",
             "keywords": [
                 "servicemanager",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:28"
+            "time": "2015-03-23 18:29:14"
         },
         {
             "name": "zendframework/zend-soap",
@@ -2092,12 +2166,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-soap.git",
-                "reference": "e42b900798ea95a9063fa4922da976d8b3a8ab6f"
+                "reference": "a599463aba97ce247faf3fb443e3c7858b46449b"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-soap/zipball/a599463aba97ce247faf3fb443e3c7858b46449b",
-                "reference": "e42b900798ea95a9063fa4922da976d8b3a8ab6f",
+                "reference": "a599463aba97ce247faf3fb443e3c7858b46449b",
                 "shasum": ""
             },
             "require": {
@@ -2107,6 +2181,9 @@
                 "zendframework/zend-uri": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-http": "self.version"
             },
             "suggest": {
@@ -2121,19 +2198,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Soap\\": ""
+                    "Zend\\Soap\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-soap",
             "keywords": [
                 "soap",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:29"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-stdlib",
@@ -2141,18 +2218,21 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-stdlib.git",
-                "reference": "eab586f4c18af3fa63c977611939f1f4a3cf1030"
+                "reference": "cf05c5ba75606e47ffee91cedc72778da46f74c3"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/cf05c5ba75606e47ffee91cedc72778da46f74c3",
-                "reference": "eab586f4c18af3fa63c977611939f1f4a3cf1030",
+                "reference": "cf05c5ba75606e47ffee91cedc72778da46f74c3",
                 "shasum": ""
             },
             "require": {
                 "php": ">=5.3.23"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-eventmanager": "self.version",
                 "zendframework/zend-filter": "self.version",
                 "zendframework/zend-serializer": "self.version",
@@ -2173,19 +2253,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Stdlib\\": ""
+                    "Zend\\Stdlib\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-stdlib",
             "keywords": [
                 "stdlib",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:29"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-text",
@@ -2193,12 +2273,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-text.git",
-                "reference": "35f519e20e575a331c2ee554e5a555a59ce4b9e2"
+                "reference": "d962ea25647b20527f3ca34ae225bbc885dabfc7"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-text/zipball/d962ea25647b20527f3ca34ae225bbc885dabfc7",
-                "reference": "35f519e20e575a331c2ee554e5a555a59ce4b9e2",
+                "reference": "d962ea25647b20527f3ca34ae225bbc885dabfc7",
                 "shasum": ""
             },
             "require": {
@@ -2206,6 +2286,11 @@
                 "zendframework/zend-servicemanager": "self.version",
                 "zendframework/zend-stdlib": "self.version"
             },
+            "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
@@ -2215,19 +2300,19 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Text\\": ""
+                    "Zend\\Text\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
             "license": [
                 "BSD-3-Clause"
             ],
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-text",
             "keywords": [
                 "text",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:29"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-uri",
@@ -2235,12 +2320,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-uri.git",
-                "reference": "53f5b162b293f80de8b951eece8e08be83c4fe16"
+                "reference": "bd9e625639415376f6a82551c73328448d7bc7d1"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-uri/zipball/bd9e625639415376f6a82551c73328448d7bc7d1",
-                "reference": "53f5b162b293f80de8b951eece8e08be83c4fe16",
+                "reference": "bd9e625639415376f6a82551c73328448d7bc7d1",
                 "shasum": ""
             },
             "require": {
@@ -2248,6 +2333,11 @@
                 "zendframework/zend-escaper": "self.version",
                 "zendframework/zend-validator": "self.version"
             },
+            "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master"
+            },
             "type": "library",
             "extra": {
                 "branch-alias": {
@@ -2257,7 +2347,7 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Uri\\": ""
+                    "Zend\\Uri\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -2265,12 +2355,12 @@
                 "BSD-3-Clause"
             ],
             "description": "a component that aids in manipulating and validating » Uniform Resource Identifiers (URIs)",
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-uri",
             "keywords": [
                 "uri",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:29"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-validator",
@@ -2278,12 +2368,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-validator.git",
-                "reference": "eb678d20256f120a72ca27276bbb2875841701ab"
+                "reference": "45fac2545a0f2eb66d71cb7966feee481e7c475f"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-validator/zipball/45fac2545a0f2eb66d71cb7966feee481e7c475f",
-                "reference": "eb678d20256f120a72ca27276bbb2875841701ab",
+                "reference": "45fac2545a0f2eb66d71cb7966feee481e7c475f",
                 "shasum": ""
             },
             "require": {
@@ -2291,6 +2381,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-db": "self.version",
                 "zendframework/zend-filter": "self.version",
                 "zendframework/zend-i18n": "self.version",
@@ -2318,7 +2411,7 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\Validator\\": ""
+                    "Zend\\Validator\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -2326,12 +2419,12 @@
                 "BSD-3-Clause"
             ],
             "description": "provides a set of commonly needed validators",
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-validator",
             "keywords": [
                 "validator",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:30"
+            "time": "2015-03-25 20:55:48"
         },
         {
             "name": "zendframework/zend-view",
@@ -2339,12 +2432,12 @@
             "source": {
                 "type": "git",
                 "url": "https://github.com/zendframework/zend-view.git",
-                "reference": "e119b4b5f082af58a96eb206e782b62c193227bf"
+                "reference": "37beb1ad46e530f627b4b6c3716efd728e976ba9"
             },
             "dist": {
                 "type": "zip",
                 "url": "https://api.github.com/repos/zendframework/zend-view/zipball/37beb1ad46e530f627b4b6c3716efd728e976ba9",
-                "reference": "e119b4b5f082af58a96eb206e782b62c193227bf",
+                "reference": "37beb1ad46e530f627b4b6c3716efd728e976ba9",
                 "shasum": ""
             },
             "require": {
@@ -2354,6 +2447,9 @@
                 "zendframework/zend-stdlib": "self.version"
             },
             "require-dev": {
+                "fabpot/php-cs-fixer": "1.7.*",
+                "phpunit/phpunit": "~4.0",
+                "satooshi/php-coveralls": "dev-master",
                 "zendframework/zend-authentication": "self.version",
                 "zendframework/zend-escaper": "self.version",
                 "zendframework/zend-feed": "self.version",
@@ -2392,7 +2488,7 @@
             },
             "autoload": {
                 "psr-4": {
-                    "Zend\\View\\": ""
+                    "Zend\\View\\": "src/"
                 }
             },
             "notification-url": "https://packagist.org/downloads/",
@@ -2400,12 +2496,12 @@
                 "BSD-3-Clause"
             ],
             "description": "provides a system of helpers, output filters, and variable escaping",
-            "homepage": "https://github.com/zendframework/zf2",
+            "homepage": "https://github.com/zendframework/zend-view",
             "keywords": [
                 "view",
                 "zf2"
             ],
-            "time": "2015-04-01 18:09:30"
+            "time": "2015-03-25 20:55:48"
         }
     ],
     "packages-dev": [
@@ -2568,16 +2664,16 @@
         },
         {
             "name": "lusitanian/oauth",
-            "version": "v0.5.4",
+            "version": "v0.5.5",
             "source": {
                 "type": "git",
                 "url": "https://github.com/Lusitanian/PHPoAuthLib.git",
-                "reference": "824e1389151e458555995faa70a89428f9f6ddeb"
+                "reference": "916cff8e02df5d52e67aaddd57aa618205dd93c2"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/Lusitanian/PHPoAuthLib/zipball/824e1389151e458555995faa70a89428f9f6ddeb",
-                "reference": "824e1389151e458555995faa70a89428f9f6ddeb",
+                "url": "https://api.github.com/repos/Lusitanian/PHPoAuthLib/zipball/916cff8e02df5d52e67aaddd57aa618205dd93c2",
+                "reference": "916cff8e02df5d52e67aaddd57aa618205dd93c2",
                 "shasum": ""
             },
             "require": {
@@ -2631,7 +2727,7 @@
                 "oauth",
                 "security"
             ],
-            "time": "2015-09-17 00:54:25"
+            "time": "2015-09-20 00:14:11"
         },
         {
             "name": "pdepend/pdepend",
@@ -2674,28 +2770,28 @@
         },
         {
             "name": "phpmd/phpmd",
-            "version": "2.2.3",
+            "version": "2.3.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/phpmd/phpmd.git",
-                "reference": "5eeb5a4d39c8304910b33ae49f8813905346cc35"
+                "reference": "246b254505951508bea08db5dde44322264f75fe"
             },
             "dist": {
                 "type": "zip",
-                "url": "https://api.github.com/repos/phpmd/phpmd/zipball/5eeb5a4d39c8304910b33ae49f8813905346cc35",
-                "reference": "5eeb5a4d39c8304910b33ae49f8813905346cc35",
+                "url": "https://api.github.com/repos/phpmd/phpmd/zipball/246b254505951508bea08db5dde44322264f75fe",
+                "reference": "246b254505951508bea08db5dde44322264f75fe",
                 "shasum": ""
             },
             "require": {
                 "pdepend/pdepend": "~2.0",
                 "php": ">=5.3.0",
-                "symfony/config": ">=2.4",
-                "symfony/dependency-injection": ">=2.4",
-                "symfony/filesystem": ">=2.4"
+                "symfony/config": "^2.4",
+                "symfony/dependency-injection": "^2.4",
+                "symfony/filesystem": "^2.4"
             },
             "require-dev": {
-                "phpunit/phpunit": "*",
-                "squizlabs/php_codesniffer": "*"
+                "phpunit/phpunit": "^4.0",
+                "squizlabs/php_codesniffer": "^2.0"
             },
             "bin": [
                 "src/bin/phpmd"
@@ -2715,12 +2811,18 @@
                     "name": "Manuel Pichler",
                     "email": "github@manuel-pichler.de",
                     "homepage": "https://github.com/manuelpichler",
-                    "role": "Project founder"
+                    "role": "Project Founder"
                 },
                 {
                     "name": "Other contributors",
                     "homepage": "https://github.com/phpmd/phpmd/graphs/contributors",
                     "role": "Contributors"
+                },
+                {
+                    "name": "Marc Würth",
+                    "email": "ravage@bluewin.ch",
+                    "homepage": "https://github.com/ravage84",
+                    "role": "Project Maintainer"
                 }
             ],
             "description": "PHPMD is a spin-off project of PHP Depend and aims to be a PHP equivalent of the well known Java tool PMD.",
@@ -2732,7 +2834,7 @@
                 "phpmd",
                 "pmd"
             ],
-            "time": "2015-05-27 18:16:57"
+            "time": "2015-09-22 05:16:44"
         },
         {
             "name": "phpunit/php-code-coverage",
diff --git a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml
index 2579101e6dfd3a790e54d407ac965309a7436956..6dc0342a5e44e5ab234c8ff2e5a3a7e2f2ab65b7 100644
--- a/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml
+++ b/dev/tests/functional/tests/app/Magento/ConfigurableProduct/Test/Repository/ConfigurableProduct/CheckoutData.xml
@@ -142,9 +142,9 @@
             </field>
             <field name="qty" xsi:type="string">1</field>
             <field name="cartItem" xsi:type="array">
-                <item name="price" xsi:type="string">9</item>
+                <item name="price" xsi:type="string">1</item>
                 <item name="qty" xsi:type="string">1</item>
-                <item name="subtotal" xsi:type="string">9</item>
+                <item name="subtotal" xsi:type="string">1</item>
             </field>
         </dataset>
 
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSetTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSetTest.php
deleted file mode 100644
index c3f810b5034b8c4cd4c91f76284e7a788eb50396..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Block/Product/Configurable/AssociatedSelector/Backend/Grid/ColumnSetTest.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\ConfigurableProduct\Block\Product\Configurable\AssociatedSelector\Backend\Grid;
-
-class ColumnSetTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * Testing adding column with configurable attribute to column set
-     *
-     * @magentoAppArea adminhtml
-     * @magentoAppIsolation enabled
-     * @magentoDataFixture Magento/ConfigurableProduct/_files/product_configurable.php
-     */
-    public function testPrepareSelect()
-    {
-        $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Catalog\Model\Product'
-        );
-        $product->load(1);
-        // fixture
-        /** @var $objectManager \Magento\TestFramework\ObjectManager */
-        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $objectManager->get('Magento\Framework\Registry')->register('current_product', $product);
-
-        /** @var $layout \Magento\Framework\View\Layout */
-        $layout = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
-            'Magento\Framework\View\LayoutInterface'
-        );
-        /** @var $block ColumnSet */
-        $block = $layout->createBlock(
-            'Magento\ConfigurableProduct\Block\Product\Configurable\AssociatedSelector\Backend\Grid\ColumnSet',
-            'block'
-        );
-        $assertBlock = $block->getLayout()->getBlock('block.test_configurable');
-        $this->assertEquals('Test Configurable', $assertBlock->getHeader());
-        $this->assertEquals('test_configurable', $assertBlock->getId());
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Resource/Product/Collection/AssociatedProductTest.php b/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Resource/Product/Collection/AssociatedProductTest.php
deleted file mode 100644
index 20e4e21e4061ce7fc7911e0c2d6ab14bd56cec01..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/ConfigurableProduct/Model/Resource/Product/Collection/AssociatedProductTest.php
+++ /dev/null
@@ -1,56 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\ConfigurableProduct\Model\Resource\Product\Collection;
-
-class AssociatedProductTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @magentoAppIsolation enabled
-     * @magentoDataFixture Magento/Catalog/_files/product_associated.php
-     */
-    public function testPrepareSelect()
-    {
-        $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Catalog\Model\Product'
-        );
-        $product->load(1);
-        // fixture
-        $product->setId(10);
-        /** @var $objectManager \Magento\TestFramework\ObjectManager */
-        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $objectManager->get('Magento\Framework\Registry')->register('current_product', $product);
-        $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\ConfigurableProduct\Model\Resource\Product\Collection\AssociatedProduct'
-        );
-        $collectionProduct = $collection->getFirstItem();
-        $this->assertEquals($product->getName(), $collectionProduct->getName());
-        $this->assertEquals($product->getSku(), $collectionProduct->getSku());
-        $this->assertEquals($product->getPrice(), $collectionProduct->getPrice());
-        $this->assertEquals($product->getWeight(), $collectionProduct->getWeight());
-        $this->assertEquals($product->getTypeId(), $collectionProduct->getTypeId());
-        $this->assertEquals($product->getAttributeSetId(), $collectionProduct->getAttributeSetId());
-    }
-
-    /**
-     * @magentoAppIsolation enabled
-     * @magentoDataFixture Magento/Catalog/_files/product_associated.php
-     */
-    public function testPrepareSelectForSameProduct()
-    {
-        $product = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\Catalog\Model\Product'
-        );
-        $product->load(1);
-        // fixture
-        /** @var $objectManager \Magento\TestFramework\ObjectManager */
-        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $objectManager->get('Magento\Framework\Registry')->register('current_product', $product);
-        $collection = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
-            'Magento\ConfigurableProduct\Model\Resource\Product\Collection\AssociatedProduct'
-        );
-        $this->assertEmpty($collection->count());
-    }
-}
diff --git a/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/LayoutFilesTest.php b/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/LayoutFilesTest.php
index 38c0d46aae2e4971ab47f0026e6b5df0447bc868..1c8ed4acb2d3bd9359147653798f0177f5d60379 100644
--- a/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/LayoutFilesTest.php
+++ b/dev/tests/integration/testsuite/Magento/Test/Integrity/Modular/LayoutFilesTest.php
@@ -88,10 +88,6 @@ class LayoutFilesTest extends \PHPUnit_Framework_TestCase
                 $typeAttr => 'object',
                 'value' => 'Magento\GroupedProduct\Model\Resource\Product\Type\Grouped\AssociatedProductsCollection',
             ],
-            [
-                $typeAttr => 'object',
-                'value' => 'Magento\ConfigurableProduct\Model\Resource\Product\Collection\AssociatedProduct'
-            ],
             [$typeAttr => 'object', 'value' => 'Magento\Solr\Model\Resource\Search\Grid\Collection'],
             [$typeAttr => 'object', 'value' => 'Magento\Wishlist\Model\Resource\Item\Collection\Grid'],
             [
diff --git a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
index 137c50c4765e6b60cea535f4bcd5a006a8926dbe..6bea00df5021f30e174e41125635d5c524d199aa 100755
--- a/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
+++ b/dev/tests/static/testsuite/Magento/Test/Legacy/_files/obsolete_classes.php
@@ -3847,4 +3847,9 @@ return [
     ['Magento\Setup\Model\SampleData', 'Magento\SampleData\Model\SampleData'],
     ['Magento\Customer\Controller\Account\ResetPassword'],
     ['Magento\Customer\Controller\Account'],
+    ['Magento\ConfigurableProduct\Block\Product\Configurable\AssociatedSelector\Backend\Grid\ColumnSet'],
+    ['Magento\ConfigurableProduct\Model\Resource\Product\Collection\AssociatedProduct'],
+    ['Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Grid\Renderer\Inventory'],
+    ['Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Grid\Renderer\Checkbox'],
+    ['Magento\ConfigurableProduct\Block\Adminhtml\Product\Edit\Tab\Super\Config\Grid\Filter\Inventory'],
 ];
diff --git a/lib/internal/Magento/Framework/Api/SearchCriteriaBuilder.php b/lib/internal/Magento/Framework/Api/SearchCriteriaBuilder.php
index 82c08f3e5cf8fb0be701535d5207018d7c2c2045..8d078203c0d2c87fb687aafb5c6e3fd065a7a55e 100644
--- a/lib/internal/Magento/Framework/Api/SearchCriteriaBuilder.php
+++ b/lib/internal/Magento/Framework/Api/SearchCriteriaBuilder.php
@@ -18,18 +18,26 @@ class SearchCriteriaBuilder extends AbstractSimpleObjectBuilder
      */
     protected $_filterGroupBuilder;
 
+    /**
+     * @var \Magento\Framework\Api\FilterBuilder
+     */
+    protected $filterBuilder;
+
     /**
      * @param ObjectFactory $objectFactory
      * @param FilterGroupBuilder $filterGroupBuilder
+     * @param FilterBuilder $filterBuilder
      */
     public function __construct(
         ObjectFactory $objectFactory,
-        FilterGroupBuilder $filterGroupBuilder
+        FilterGroupBuilder $filterGroupBuilder,
+        FilterBuilder $filterBuilder
     ) {
         parent::__construct(
             $objectFactory
         );
         $this->_filterGroupBuilder = $filterGroupBuilder;
+        $this->filterBuilder = $filterBuilder;
     }
 
     /**
@@ -58,6 +66,23 @@ class SearchCriteriaBuilder extends AbstractSimpleObjectBuilder
         return $this;
     }
 
+    /**
+     * @param string $field
+     * @param mixed $value
+     * @param string $conditionType
+     * @return $this
+     */
+    public function addFilter($field, $value, $conditionType = 'eq')
+    {
+        $this->addFilters([
+            $this->filterBuilder->setField($field)
+                ->setValue($value)
+                ->setConditionType($conditionType)
+                ->create()
+        ]);
+        return $this;
+    }
+
     /**
      * Set filter groups
      *
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Json.php b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Json.php
index 6af04342a3a6c7e37af552809ae0348d7820e6d0..abcd9be5823f5c8a8635271ebdb6b6d071c4b07b 100644
--- a/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Json.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/ContentType/Json.php
@@ -9,6 +9,7 @@ use Magento\Framework\Json\Encoder;
 use Magento\Framework\View\FileSystem;
 use Magento\Framework\View\TemplateEnginePool;
 use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Layout\Generator\Structure;
 
 /**
  * Class Json
@@ -16,6 +17,15 @@ use Magento\Framework\View\Element\UiComponentInterface;
 class Json extends AbstractContentType
 {
     /**
+     * Generator structure instance
+     *
+     * @var Structure
+     */
+    private $structure;
+
+    /**
+     * Encoder
+     *
      * @var Encoder
      */
     private $encoder;
@@ -26,14 +36,17 @@ class Json extends AbstractContentType
      * @param FileSystem $filesystem
      * @param TemplateEnginePool $templateEnginePool
      * @param Encoder $encoder
+     * @param Structure $structure
      */
     public function __construct(
         FileSystem $filesystem,
         TemplateEnginePool $templateEnginePool,
-        Encoder $encoder
+        Encoder $encoder,
+        Structure $structure
     ) {
         parent::__construct($filesystem, $templateEnginePool);
         $this->encoder = $encoder;
+        $this->structure = $structure;
     }
 
     /**
@@ -47,9 +60,15 @@ class Json extends AbstractContentType
      */
     public function render(UiComponentInterface $component, $template = '')
     {
-        $data = $component->getContext()->getDataSourceData($component);
-        $data = reset($data);
-
-        return $this->encoder->encode($data['config']['data']);
+        $context = $component->getContext();
+        $isComponent = $context->getRequestParam('componentJson');
+        if ($isComponent) {
+            $data = $this->structure->generate($component);
+            return $this->encoder->encode($data);
+        } else {
+            $data = $component->getContext()->getDataSourceData($component);
+            $data = reset($data);
+            return $this->encoder->encode($data['config']['data']);
+        }
     }
 }
diff --git a/app/code/Magento/Ui/Component/Layout/Generator/Structure.php b/lib/internal/Magento/Framework/View/Layout/Generator/Structure.php
similarity index 90%
rename from app/code/Magento/Ui/Component/Layout/Generator/Structure.php
rename to lib/internal/Magento/Framework/View/Layout/Generator/Structure.php
index c26b9c40664a3bd93122a7f6bee509264fcb8049..49431962a86b2a46568771d437cedd46aef016ef 100644
--- a/app/code/Magento/Ui/Component/Layout/Generator/Structure.php
+++ b/lib/internal/Magento/Framework/View/Layout/Generator/Structure.php
@@ -3,9 +3,9 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Ui\Component\Layout\Generator;
+namespace Magento\Framework\View\Layout\Generator;
 
-use Magento\Ui\Component\Layout\LayoutPool;
+use Magento\Framework\View\Layout\Pool as LayoutPool;
 use Magento\Framework\View\Element\UiComponentInterface;
 use Magento\Framework\View\Element\UiComponent\LayoutInterface;
 
diff --git a/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php b/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php
index d5a8fcda61c2a164f1da15f4f9f3482112d18fe1..a1d81de2f22f6b8a3f63b2deca2d333714c9a754 100644
--- a/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php
+++ b/lib/internal/Magento/Framework/View/Layout/Generator/UiComponent.php
@@ -7,7 +7,7 @@ namespace Magento\Framework\View\Layout\Generator;
 
 use Magento\Framework\View\Layout;
 use Magento\Framework\View\Element\BlockFactory;
-use Magento\Framework\View\Layout\Data\Structure;
+use Magento\Framework\View\Layout\Data\Structure as DataStructure;
 use Magento\Framework\View\Layout\GeneratorInterface;
 use Magento\Framework\View\Element\UiComponentFactory;
 use Magento\Framework\View\Element\UiComponentInterface;
@@ -102,13 +102,13 @@ class UiComponent implements GeneratorInterface
     /**
      * Create component object
      *
-     * @param Structure $structure
+     * @param DataStructure $structure
      * @param string $elementName
      * @param string $data
      * @param LayoutInterface $layout
      * @return ContainerInterface
      */
-    protected function generateComponent(Structure $structure, $elementName, $data, LayoutInterface $layout)
+    protected function generateComponent(DataStructure $structure, $elementName, $data, LayoutInterface $layout)
     {
         $attributes = $data['attributes'];
         if (!empty($attributes['group'])) {
diff --git a/app/code/Magento/Ui/Component/Layout/Generic.php b/lib/internal/Magento/Framework/View/Layout/Generic.php
similarity index 98%
rename from app/code/Magento/Ui/Component/Layout/Generic.php
rename to lib/internal/Magento/Framework/View/Layout/Generic.php
index 92d0a406f38e067fd5fc189ae3e1821fd788eeac..a64af6ec44b46ccc2eb0324f51a2c600995fb1e3 100644
--- a/app/code/Magento/Ui/Component/Layout/Generic.php
+++ b/lib/internal/Magento/Framework/View/Layout/Generic.php
@@ -3,7 +3,7 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Ui\Component\Layout;
+namespace Magento\Framework\View\Layout;
 
 use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
 use Magento\Framework\View\Element\UiComponent\LayoutInterface;
diff --git a/app/code/Magento/Ui/Component/Layout/LayoutPool.php b/lib/internal/Magento/Framework/View/Layout/Pool.php
similarity index 90%
rename from app/code/Magento/Ui/Component/Layout/LayoutPool.php
rename to lib/internal/Magento/Framework/View/Layout/Pool.php
index b15a513ff42c604797718731bb16798f670b95a4..d9d785a85884ed15879f37e3961f3211b156c2e3 100644
--- a/app/code/Magento/Ui/Component/Layout/LayoutPool.php
+++ b/lib/internal/Magento/Framework/View/Layout/Pool.php
@@ -3,17 +3,17 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-namespace Magento\Ui\Component\Layout;
+namespace Magento\Framework\View\Layout;
 
 use Magento\Framework\ObjectManagerInterface;
 use Magento\Framework\View\Element\UiComponent\LayoutInterface;
 
 /**
- * Class LayoutPool
+ * Class Pool
  */
-class LayoutPool
+class Pool
 {
-    const DEFAULT_CLASS = 'Magento\Ui\Component\Layout\Generic';
+    const DEFAULT_CLASS = 'Magento\Framework\View\Layout\Generic';
 
     /**
      * Layouts pool