diff --git a/app/code/Magento/CatalogRule/Api/Data/ConditionInterface.php b/app/code/Magento/CatalogRule/Api/Data/ConditionInterface.php
new file mode 100644
index 0000000000000000000000000000000000000000..f7a473a2e9dcd8a92acc4ea247db8b6381d4d738
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Api/Data/ConditionInterface.php
@@ -0,0 +1,125 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRule\Api\Data;
+
+/**
+ * @api
+ */
+interface ConditionInterface extends \Magento\Framework\Api\CustomAttributesDataInterface
+{
+    /**#@+
+     * Constants defined for keys of data array
+     */
+    const TYPE = 'type';
+
+    const ATTRIBUTE = 'attribute';
+
+    const OPERATOR = 'operator';
+
+    const VALUE = 'value';
+
+    const IS_VALUE_PARSED = 'is_value_parsed';
+
+    const AGGREGATOR = 'aggregator';
+
+    const CONDITIONS = 'conditions';
+    /**#@-*/
+
+    /**
+     * @param string $type
+     * @return $this
+     */
+    public function setType($type);
+
+    /**
+     * @return string
+     */
+    public function getType();
+
+    /**
+     * @param string $attribute
+     * @return $this
+     */
+    public function setAttribute($attribute);
+
+    /**
+     * @return string
+     */
+    public function getAttribute();
+
+    /**
+     * @param string $operator
+     * @return $this
+     */
+    public function setOperator($operator);
+
+    /**
+     * @return string
+     */
+    public function getOperator();
+
+    /**
+     * @param string $value
+     * @return $this
+     */
+    public function setValue($value);
+
+    /**
+     * @return string
+     */
+    public function getValue();
+
+    /**
+     * @param bool $isValueParsed
+     * @return $this
+     */
+    public function setIsValueParsed($isValueParsed);
+
+    /**
+     * @return bool|null
+     * @SuppressWarnings(PHPMD.BooleanGetMethodName)
+     */
+    public function getIsValueParsed();
+
+    /**
+     * @param string $aggregator
+     * @return $this
+     */
+    public function setAggregator($aggregator);
+
+    /**
+     * @return string
+     */
+    public function getAggregator();
+
+    /**
+     * @param \Magento\CatalogRule\Api\Data\ConditionInterface[] $conditions
+     * @return $this
+     */
+    public function setConditions($conditions);
+
+    /**
+     * @return \Magento\CatalogRule\Api\Data\ConditionInterface[]|null
+     */
+    public function getConditions();
+
+    /**
+     * Retrieve existing extension attributes object or create a new one.
+     *
+     * @return \Magento\CatalogRule\Api\Data\ConditionExtensionInterface|null
+     */
+    public function getExtensionAttributes();
+
+    /**
+     * Set an extension attributes object.
+     *
+     * @param \Magento\CatalogRule\Api\Data\ConditionExtensionInterface $extensionAttributes
+     * @return $this
+     */
+    public function setExtensionAttributes(
+        \Magento\CatalogRule\Api\Data\ConditionExtensionInterface $extensionAttributes
+    );
+}
diff --git a/app/code/Magento/CatalogRule/Api/Data/RuleInterface.php b/app/code/Magento/CatalogRule/Api/Data/RuleInterface.php
index 9ef340990dfc4705f598843458bfce42657e703f..473304dad9e42c52c982ed53ad00f0f20b38f193 100644
--- a/app/code/Magento/CatalogRule/Api/Data/RuleInterface.php
+++ b/app/code/Magento/CatalogRule/Api/Data/RuleInterface.php
@@ -21,10 +21,6 @@ interface RuleInterface extends \Magento\Framework\Api\CustomAttributesDataInter
 
     const IS_ACTIVE = 'is_active';
 
-    const CONDITIONS_SERIALIZED = 'conditions_serialized';
-
-    const ACTIONS_SERIALIZED = 'actions_serialized';
-
     const STOP_RULES_PROCESSING = 'stop_rules_processing';
 
     const SORT_ORDER = 'sort_order';
@@ -38,7 +34,7 @@ interface RuleInterface extends \Magento\Framework\Api\CustomAttributesDataInter
     /**
      * Returns rule id field
      *
-     * @return int
+     * @return int|null
      */
     public function getRuleId();
 
@@ -64,7 +60,7 @@ interface RuleInterface extends \Magento\Framework\Api\CustomAttributesDataInter
     /**
      * Returns rule description
      *
-     * @return string
+     * @return string|null
      */
     public function getDescription();
 
@@ -88,35 +84,22 @@ interface RuleInterface extends \Magento\Framework\Api\CustomAttributesDataInter
     public function setIsActive($isActive);
 
     /**
-     * Returns serialized rule condition
-     *
-     * @return string
-     */
-    public function getConditionsSerialized();
-
-    /**
-     * @param string $conditions
-     * @return $this
-     */
-    public function setConditionsSerialized($conditions);
-
-    /**
-     * Returns serialized rule actions
+     * Returns rule condition
      *
-     * @return string
+     * @return \Magento\CatalogRule\Api\Data\ConditionInterface|null
      */
-    public function getActionsSerialized();
+    public function getRuleCondition();
 
     /**
-     * @param string $actions
+     * @param \Magento\CatalogRule\Api\Data\ConditionInterface $condition
      * @return $this
      */
-    public function setActionsSerialized($actions);
+    public function setRuleCondition($condition);
 
     /**
      * Returns stop rule processing flag
      *
-     * @return int
+     * @return int|null
      */
     public function getStopRulesProcessing();
 
@@ -129,7 +112,7 @@ interface RuleInterface extends \Magento\Framework\Api\CustomAttributesDataInter
     /**
      * Returns rule sort order
      *
-     * @return int
+     * @return int|null
      */
     public function getSortOrder();
 
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/DeleteButton.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/DeleteButton.php
new file mode 100644
index 0000000000000000000000000000000000000000..89696ae8f4988d02e73a648749ea71b604e7afb8
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/DeleteButton.php
@@ -0,0 +1,34 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRule\Block\Adminhtml\Edit;
+
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
+
+/**
+ * Class DeleteButton
+ */
+class DeleteButton extends GenericButton implements ButtonProviderInterface
+{
+    /**
+     * @return array
+     */
+    public function getButtonData()
+    {
+        $data = [];
+        $ruleId = $this->getRuleId();
+        if ($ruleId && $this->canRender('delete')) {
+            $data = [
+                'label' => __('Delete Rule'),
+                'class' => 'delete',
+                'on_click' => 'deleteConfirm(\'' . __(
+                    'Are you sure you want to do this?'
+                ) . '\', \'' . $this->urlBuilder->getUrl('*/*/delete', ['id' => $ruleId]) . '\')',
+                'sort_order' => 20,
+            ];
+        }
+        return $data;
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/GenericButton.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/GenericButton.php
new file mode 100644
index 0000000000000000000000000000000000000000..0b651eb67c7304f491bf046e5ec2e4b9442c2d09
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/GenericButton.php
@@ -0,0 +1,74 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogRule\Block\Adminhtml\Edit;
+
+use Magento\CatalogRule\Controller\RegistryConstants;
+
+class GenericButton
+{
+    /**
+     * Url Builder
+     *
+     * @var \Magento\Framework\UrlInterface
+     */
+    protected $urlBuilder;
+
+    /**
+     * Registry
+     *
+     * @var \Magento\Framework\Registry
+     */
+    protected $registry;
+
+    /**
+     * Constructor
+     *
+     * @param \Magento\Backend\Block\Widget\Context $context
+     * @param \Magento\Framework\Registry $registry
+     */
+    public function __construct(
+        \Magento\Backend\Block\Widget\Context $context,
+        \Magento\Framework\Registry $registry
+    ) {
+        $this->urlBuilder = $context->getUrlBuilder();
+        $this->registry = $registry;
+    }
+
+    /**
+     * Return the current Catalog Rule Id.
+     *
+     * @return int|null
+     */
+    public function getRuleId()
+    {
+        $catalogRule = $this->registry->registry(RegistryConstants::CURRENT_CATALOG_RULE_ID);
+        return $catalogRule ? $catalogRule->getId() : null;
+    }
+
+    /**
+     * Generate url by route and parameters
+     *
+     * @param   string $route
+     * @param   array $params
+     * @return  string
+     */
+    public function getUrl($route = '', $params = [])
+    {
+        return $this->urlBuilder->getUrl($route, $params);
+    }
+
+    /**
+     * Check where button can be rendered
+     *
+     * @param string $name
+     * @return string
+     */
+    public function canRender($name)
+    {
+        return $name;
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/ResetButton.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/ResetButton.php
new file mode 100644
index 0000000000000000000000000000000000000000..8fbfde5dc97f17790f7a4a92b07549d76744fdfd
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/ResetButton.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogRule\Block\Adminhtml\Edit;
+
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
+
+class ResetButton extends GenericButton implements ButtonProviderInterface
+{
+    /**
+     * @return array
+     * @codeCoverageIgnore
+     */
+    public function getButtonData()
+    {
+        $data = [];
+        if ($this->canRender('reset')) {
+            $data = [
+                'label' => __('Reset'),
+                'class' => 'reset',
+                'on_click' => 'location.reload();',
+                'sort_order' => 30,
+            ];
+        }
+        return $data;
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/SaveAndApplyButton.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/SaveAndApplyButton.php
new file mode 100644
index 0000000000000000000000000000000000000000..3ee2311628fe7634c302fbfc76ed228c0a10e8f1
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/SaveAndApplyButton.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogRule\Block\Adminhtml\Edit;
+
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
+
+class SaveAndApplyButton extends GenericButton implements ButtonProviderInterface
+{
+    /**
+     * @return array
+     * @codeCoverageIgnore
+     */
+    public function getButtonData()
+    {
+        $data = [];
+        if ($this->canRender('save_apply')) {
+            $data = [
+                'label' => __('Save and Apply'),
+                'class' => 'save',
+                'on_click' => '',
+                'sort_order' => 80,
+            ];
+        }
+        return $data;
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/SaveAndContinueButton.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/SaveAndContinueButton.php
new file mode 100644
index 0000000000000000000000000000000000000000..dd4abb6a67fde2fcb0d7a33e45143cb7673128aa
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/SaveAndContinueButton.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogRule\Block\Adminhtml\Edit;
+
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
+
+class SaveAndContinueButton extends GenericButton implements ButtonProviderInterface
+{
+    /**
+     * @return array
+     * @codeCoverageIgnore
+     */
+    public function getButtonData()
+    {
+        $data = [];
+        if ($this->canRender('save_and_continue_edit')) {
+            $data = [
+                'label' => __('Save and Continue Edit'),
+                'class' => 'save',
+                'on_click' => '',
+                'sort_order' => 90,
+            ];
+        }
+        return $data;
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/SaveButton.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/SaveButton.php
new file mode 100644
index 0000000000000000000000000000000000000000..18c496ed3b8976d58e21aa2b4583d93fbb677e85
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Block/Adminhtml/Edit/SaveButton.php
@@ -0,0 +1,29 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogRule\Block\Adminhtml\Edit;
+
+use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
+
+class SaveButton extends GenericButton implements ButtonProviderInterface
+{
+    /**
+     * @return array
+     * @codeCoverageIgnore
+     */
+    public function getButtonData()
+    {
+        $data = [];
+        if ($this->canRender('save')) {
+            $data = [
+                'label' => __('Save'),
+                'class' => 'save primary',
+                'on_click' => '',
+            ];
+        }
+        return $data;
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit.php
deleted file mode 100644
index 7fa26b258728cddbfa443a0296eba2edd81a9234..0000000000000000000000000000000000000000
--- a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit.php
+++ /dev/null
@@ -1,95 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-/**
- * Catalog rule edit form block
- */
-namespace Magento\CatalogRule\Block\Adminhtml\Promo\Catalog;
-
-class Edit extends \Magento\Backend\Block\Widget\Form\Container
-{
-    /**
-     * Core registry
-     *
-     * @var \Magento\Framework\Registry
-     */
-    protected $_coreRegistry = null;
-
-    /**
-     * @param \Magento\Backend\Block\Widget\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Widget\Context $context,
-        \Magento\Framework\Registry $registry,
-        array $data = []
-    ) {
-        $this->_coreRegistry = $registry;
-        parent::__construct($context, $data);
-    }
-
-    /**
-     * Initialize form
-     * Add standard buttons
-     * Add "Save and Apply" button
-     * Add "Save and Continue" button
-     *
-     * @return void
-     */
-    protected function _construct()
-    {
-        $this->_objectId = 'id';
-        $this->_blockGroup = 'Magento_CatalogRule';
-        $this->_controller = 'adminhtml_promo_catalog';
-
-        parent::_construct();
-
-        $this->buttonList->add(
-            'save_apply',
-            [
-                'class' => 'save',
-                'label' => __('Save and Apply'),
-                'data_attribute' => [
-                    'mage-init' => [
-                        'button' => [
-                            'event' => 'save',
-                            'target' => '#edit_form',
-                            'eventData' => ['action' => ['args' => ['auto_apply' => 1]]],
-                        ],
-                    ],
-                ]
-            ]
-        );
-
-        $this->buttonList->add(
-            'save_and_continue_edit',
-            [
-                'class' => 'save',
-                'label' => __('Save and Continue Edit'),
-                'data_attribute' => [
-                    'mage-init' => ['button' => ['event' => 'saveAndContinueEdit', 'target' => '#edit_form']],
-                ]
-            ],
-            10
-        );
-    }
-
-    /**
-     * Getter for form header text
-     *
-     * @return \Magento\Framework\Phrase
-     */
-    public function getHeaderText()
-    {
-        $rule = $this->_coreRegistry->registry('current_promo_catalog_rule');
-        if ($rule->getRuleId()) {
-            return __("Edit Rule '%1'", $this->escapeHtml($rule->getName()));
-        } else {
-            return __('New Rule');
-        }
-    }
-}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Form.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Form.php
deleted file mode 100644
index f084792edb7abe61e12a4f494d36e4375dc24cc2..0000000000000000000000000000000000000000
--- a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Form.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-/**
- * description
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit;
-
-use Magento\Backend\Block\Widget\Form as WidgetForm;
-
-class Form extends \Magento\Backend\Block\Widget\Form\Generic
-{
-    /**
-     * @return void
-     */
-    protected function _construct()
-    {
-        parent::_construct();
-        $this->setId('promo_catalog_form');
-        $this->setTitle(__('Rule Information'));
-    }
-
-    /**
-     * @return WidgetForm
-     */
-    protected function _prepareForm()
-    {
-        /** @var \Magento\Framework\Data\Form $form */
-        $form = $this->_formFactory->create(
-            [
-                'data' => [
-                    'id' => 'edit_form',
-                    'action' => $this->getUrl('catalog_rule/promo_catalog/save'),
-                    'method' => 'post',
-                ],
-            ]
-        );
-        $form->setUseContainer(true);
-        $this->setForm($form);
-        return parent::_prepareForm();
-    }
-}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Js.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Js.php
deleted file mode 100644
index 89069e0063662e212af96cc94852b98ae111fd16..0000000000000000000000000000000000000000
--- a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Js.php
+++ /dev/null
@@ -1,16 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-/**
- * description
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit;
-
-class Js extends \Magento\Backend\Block\Template
-{
-}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Actions.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Actions.php
deleted file mode 100644
index 6f98f46c62d3aec1f51d0e8f8add61acf74ad068..0000000000000000000000000000000000000000
--- a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Actions.php
+++ /dev/null
@@ -1,126 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab;
-
-use Magento\Backend\Block\Widget\Form;
-use Magento\Backend\Block\Widget\Form\Generic;
-use Magento\Backend\Block\Widget\Tab\TabInterface;
-
-class Actions extends Generic implements TabInterface
-{
-    /**
-     * Prepare content for tab
-     *
-     * @return \Magento\Framework\Phrase
-     * @codeCoverageIgnore
-     */
-    public function getTabLabel()
-    {
-        return __('Actions');
-    }
-
-    /**
-     * Prepare title for tab
-     *
-     * @return \Magento\Framework\Phrase
-     * @codeCoverageIgnore
-     */
-    public function getTabTitle()
-    {
-        return __('Actions');
-    }
-
-    /**
-     * Returns status flag about this tab can be showen or not
-     *
-     * @return bool
-     * @codeCoverageIgnore
-     */
-    public function canShowTab()
-    {
-        return true;
-    }
-
-    /**
-     * Returns status flag about this tab hidden or not
-     *
-     * @return bool
-     * @codeCoverageIgnore
-     */
-    public function isHidden()
-    {
-        return false;
-    }
-
-    /**
-     * @return Form
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
-    protected function _prepareForm()
-    {
-        $model = $this->_coreRegistry->registry('current_promo_catalog_rule');
-
-        /** @var \Magento\Framework\Data\Form $form */
-        $form = $this->_formFactory->create();
-        $form->setHtmlIdPrefix('rule_');
-
-        $fieldset = $form->addFieldset(
-            'action_fieldset',
-            ['legend' => __('Pricing Structure Rules')]
-        );
-
-        $fieldset->addField(
-            'simple_action',
-            'select',
-            [
-                'label' => __('Apply'),
-                'name' => 'simple_action',
-                'options' => [
-                    'by_percent' => __('Apply as percentage of original'),
-                    'by_fixed' => __('Apply as fixed amount'),
-                    'to_percent' => __('Adjust final price to this percentage'),
-                    'to_fixed' => __('Adjust final price to discount value'),
-                ]
-            ]
-        );
-
-        $fieldset->addField(
-            'discount_amount',
-            'text',
-            [
-                'name' => 'discount_amount',
-                'required' => true,
-                'class' => 'validate-not-negative-number',
-                'label' => __('Discount Amount')
-            ]
-        );
-
-        $fieldset->addField(
-            'stop_rules_processing',
-            'select',
-            [
-                'label' => __('Discard subsequent rules'),
-                'title' => __('Discard subsequent rules'),
-                'name' => 'stop_rules_processing',
-                'options' => ['1' => __('Yes'), '0' => __('No')]
-            ]
-        );
-
-        $form->setValues($model->getData());
-
-        //$form->setUseContainer(true);
-
-        if ($model->isReadonly()) {
-            foreach ($fieldset->getElements() as $element) {
-                $element->setReadonly(true, true);
-            }
-        }
-
-        $this->setForm($form);
-
-        return parent::_prepareForm();
-    }
-}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Conditions.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Conditions.php
index 478a5556997cdd03d62195d3039ca35e3ae40f22..1b94454cd932073f3a1237eca3a6bb274ca45514 100644
--- a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Conditions.php
+++ b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Conditions.php
@@ -7,7 +7,7 @@ namespace Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab;
 
 use Magento\Backend\Block\Widget\Form;
 use Magento\Backend\Block\Widget\Form\Generic;
-use Magento\Backend\Block\Widget\Tab\TabInterface;
+use Magento\Ui\Component\Layout\Tabs\TabInterface;
 
 class Conditions extends Generic implements TabInterface
 {
@@ -86,6 +86,39 @@ class Conditions extends Generic implements TabInterface
         return false;
     }
 
+    /**
+     * Tab class getter
+     *
+     * @return string
+     * @codeCoverageIgnore
+     */
+    public function getTabClass()
+    {
+        return null;
+    }
+
+    /**
+     * Return URL link to Tab content
+     *
+     * @return string
+     * @codeCoverageIgnore
+     */
+    public function getTabUrl()
+    {
+        return null;
+    }
+
+    /**
+     * Tab should be loaded trough Ajax call
+     *
+     * @return bool
+     * @codeCoverageIgnore
+     */
+    public function isAjaxLoaded()
+    {
+        return false;
+    }
+
     /**
      * @return Form
      */
@@ -113,7 +146,13 @@ class Conditions extends Generic implements TabInterface
         $fieldset->addField(
             'conditions',
             'text',
-            ['name' => 'conditions', 'label' => __('Conditions'), 'title' => __('Conditions'), 'required' => true]
+            [
+                'name' => 'conditions',
+                'label' => __('Conditions'),
+                'title' => __('Conditions'),
+                'required' => true,
+                'data-form-part' => 'catalog_rule_form'
+            ]
         )->setRule(
             $model
         )->setRenderer(
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Main.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Main.php
deleted file mode 100644
index c9d538a0920543a57912259a0198fbfbe0217e3b..0000000000000000000000000000000000000000
--- a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/Main.php
+++ /dev/null
@@ -1,235 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-/**
- * Catalog Rule General Information Tab
- *
- * @author Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab;
-
-use Magento\Backend\Block\Widget\Form;
-use Magento\Backend\Block\Widget\Form\Generic;
-use Magento\Backend\Block\Widget\Tab\TabInterface;
-
-class Main extends Generic implements TabInterface
-{
-    /**
-     * @var \Magento\Store\Model\System\Store
-     */
-    protected $_systemStore;
-
-    /**
-     * @var \Magento\Customer\Api\GroupRepositoryInterface
-     */
-    protected $_groupRepository;
-
-    /**
-     * @var \Magento\Framework\Api\SearchCriteriaBuilder
-     */
-    protected $_searchCriteriaBuilder;
-
-    /**
-     * @var \Magento\Framework\Convert\DataObject
-     */
-    protected $_objectConverter;
-
-    /**
-     * @param \Magento\Backend\Block\Template\Context $context
-     * @param \Magento\Framework\Registry $registry
-     * @param \Magento\Framework\Data\FormFactory $formFactory
-     * @param \Magento\Customer\Api\GroupRepositoryInterface $groupRepository
-     * @param \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder
-     * @param \Magento\Framework\Convert\DataObject $objectConverter
-     * @param \Magento\Store\Model\System\Store $systemStore
-     * @param array $data
-     */
-    public function __construct(
-        \Magento\Backend\Block\Template\Context $context,
-        \Magento\Framework\Registry $registry,
-        \Magento\Framework\Data\FormFactory $formFactory,
-        \Magento\Customer\Api\GroupRepositoryInterface $groupRepository,
-        \Magento\Framework\Api\SearchCriteriaBuilder $searchCriteriaBuilder,
-        \Magento\Framework\Convert\DataObject $objectConverter,
-        \Magento\Store\Model\System\Store $systemStore,
-        array $data = []
-    ) {
-        $this->_systemStore = $systemStore;
-        $this->_groupRepository = $groupRepository;
-        $this->_searchCriteriaBuilder = $searchCriteriaBuilder;
-        $this->_objectConverter = $objectConverter;
-        parent::__construct($context, $registry, $formFactory, $data);
-    }
-
-    /**
-     * Prepare content for tab
-     *
-     * @return \Magento\Framework\Phrase
-     * @codeCoverageIgnore
-     */
-    public function getTabLabel()
-    {
-        return __('Rule Information');
-    }
-
-    /**
-     * Prepare title for tab
-     *
-     * @return \Magento\Framework\Phrase
-     * @codeCoverageIgnore
-     */
-    public function getTabTitle()
-    {
-        return __('Rule Information');
-    }
-
-    /**
-     * Returns status flag about this tab can be showed or not
-     *
-     * @return bool
-     * @codeCoverageIgnore
-     */
-    public function canShowTab()
-    {
-        return true;
-    }
-
-    /**
-     * Returns status flag about this tab hidden or not
-     *
-     * @return bool
-     * @codeCoverageIgnore
-     */
-    public function isHidden()
-    {
-        return false;
-    }
-
-    /**
-     * @return Form
-     * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
-     */
-    protected function _prepareForm()
-    {
-        $model = $this->_coreRegistry->registry('current_promo_catalog_rule');
-
-        /** @var \Magento\Framework\Data\Form $form */
-        $form = $this->_formFactory->create();
-        $form->setHtmlIdPrefix('rule_');
-
-        $fieldset = $form->addFieldset('base_fieldset', ['legend' => __('General Information')]);
-
-        if ($model->getId()) {
-            $fieldset->addField('rule_id', 'hidden', ['name' => 'rule_id']);
-        }
-
-        $fieldset->addField(
-            'name',
-            'text',
-            ['name' => 'name', 'label' => __('Rule Name'), 'title' => __('Rule Name'), 'required' => true]
-        );
-
-        $fieldset->addField(
-            'description',
-            'textarea',
-            [
-                'name' => 'description',
-                'label' => __('Description'),
-                'title' => __('Description'),
-                'style' => 'height: 100px;'
-            ]
-        );
-
-        $fieldset->addField(
-            'is_active',
-            'select',
-            [
-                'label' => __('Status'),
-                'title' => __('Status'),
-                'name' => 'is_active',
-                'required' => true,
-                'options' => ['1' => __('Active'), '0' => __('Inactive')]
-            ]
-        );
-
-        if ($this->_storeManager->isSingleStoreMode()) {
-            $websiteId = $this->_storeManager->getStore(true)->getWebsiteId();
-            $fieldset->addField('website_ids', 'hidden', ['name' => 'website_ids[]', 'value' => $websiteId]);
-            $model->setWebsiteIds($websiteId);
-        } else {
-            $field = $fieldset->addField(
-                'website_ids',
-                'multiselect',
-                [
-                    'name' => 'website_ids[]',
-                    'label' => __('Websites'),
-                    'title' => __('Websites'),
-                    'required' => true,
-                    'values' => $this->_systemStore->getWebsiteValuesForForm()
-                ]
-            );
-            $renderer = $this->getLayout()->createBlock(
-                'Magento\Backend\Block\Store\Switcher\Form\Renderer\Fieldset\Element'
-            );
-            $field->setRenderer($renderer);
-        }
-
-        $customerGroups = $this->_groupRepository->getList($this->_searchCriteriaBuilder->create())->getItems();
-        $fieldset->addField(
-            'customer_group_ids',
-            'multiselect',
-            [
-                'name' => 'customer_group_ids[]',
-                'label' => __('Customer Groups'),
-                'title' => __('Customer Groups'),
-                'required' => true,
-                'values' => $this->_objectConverter->toOptionArray($customerGroups, 'id', 'code')
-            ]
-        );
-
-        $dateFormat = $this->_localeDate->getDateFormat(
-            \IntlDateFormatter::SHORT
-        );
-        $fieldset->addField(
-            'from_date',
-            'date',
-            [
-                'name' => 'from_date',
-                'label' => __('From'),
-                'title' => __('From'),
-                'input_format' => \Magento\Framework\Stdlib\DateTime::DATE_INTERNAL_FORMAT,
-                'date_format' => $dateFormat
-            ]
-        );
-        $fieldset->addField(
-            'to_date',
-            'date',
-            [
-                'name' => 'to_date',
-                'label' => __('To'),
-                'title' => __('To'),
-                'input_format' => \Magento\Framework\Stdlib\DateTime::DATE_INTERNAL_FORMAT,
-                'date_format' => $dateFormat
-            ]
-        );
-
-        $fieldset->addField('sort_order', 'text', ['name' => 'sort_order', 'label' => __('Priority')]);
-
-        $form->setValues($model->getData());
-
-        if ($model->isReadonly()) {
-            foreach ($fieldset->getElements() as $element) {
-                $element->setReadonly(true, true);
-            }
-        }
-
-        $this->setForm($form);
-
-        $this->_eventManager->dispatch('adminhtml_promo_catalog_edit_tab_main_prepare_form', ['form' => $form]);
-
-        return parent::_prepareForm();
-    }
-}
diff --git a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tabs.php b/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tabs.php
deleted file mode 100644
index d174027385cf056064bd283028c461b0b2772b90..0000000000000000000000000000000000000000
--- a/app/code/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tabs.php
+++ /dev/null
@@ -1,26 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-
-/**
- * description
- *
- * @author      Magento Core Team <core@magentocommerce.com>
- */
-namespace Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit;
-
-class Tabs extends \Magento\Backend\Block\Widget\Tabs
-{
-    /**
-     * @return void
-     */
-    protected function _construct()
-    {
-        parent::_construct();
-        $this->setId('promo_catalog_edit_tabs');
-        $this->setDestElementId('edit_form');
-        $this->setTitle(__('Catalog Price Rule'));
-    }
-}
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php
index fe2584859107304448cc0959aa456dcf91292b1e..d167580ca68a8c2945ddf333fad2b140da0b86e5 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Delete.php
@@ -19,7 +19,7 @@ class Delete extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
         if ($id) {
             try {
                 /** @var \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface $ruleRepository */
-                $ruleRepository = $this->_objectManager->create(
+                $ruleRepository = $this->_objectManager->get(
                     'Magento\CatalogRule\Api\CatalogRuleRepositoryInterface'
                 );
                 $ruleRepository->deleteById($id);
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Edit.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Edit.php
index 82b356da5884b96c3c18917d4860bb1c6164041e..b589f7f9d900360598d489a192046175a6c69f4e 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Edit.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Edit.php
@@ -15,11 +15,8 @@ class Edit extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
     {
         $id = $this->getRequest()->getParam('id');
 
-        /** @var \Magento\CatalogRule\Model\Rule $model */
-        $model = $this->_objectManager->create('Magento\CatalogRule\Model\Rule');
-
         /** @var \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface $ruleRepository */
-        $ruleRepository = $this->_objectManager->create(
+        $ruleRepository = $this->_objectManager->get(
             'Magento\CatalogRule\Api\CatalogRuleRepositoryInterface'
         );
 
@@ -31,6 +28,9 @@ class Edit extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
                 $this->_redirect('catalog_rule/*');
                 return;
             }
+        } else {
+            /** @var \Magento\CatalogRule\Model\Rule $model */
+            $model = $this->_objectManager->create('Magento\CatalogRule\Model\Rule');
         }
 
         // set entered data if was error when we do save
@@ -39,6 +39,7 @@ class Edit extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
             $model->addData($data);
         }
         $model->getConditions()->setJsFormObject('rule_conditions_fieldset');
+        $model->getConditions()->setFormName('catalog_rule_form');
 
         $this->_coreRegistry->register('current_promo_catalog_rule', $model);
 
@@ -47,9 +48,6 @@ class Edit extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
         $this->_view->getPage()->getConfig()->getTitle()->prepend(
             $model->getRuleId() ? $model->getName() : __('New Catalog Price Rule')
         );
-        $this->_view->getLayout()
-            ->getBlock('promo_catalog_edit')
-            ->setData('action', $this->getUrl('catalog_rule/promo_catalog/save'));
 
         $breadcrumb = $id ? __('Edit Rule') : __('New Rule');
         $this->_addBreadcrumb($breadcrumb, $breadcrumb);
diff --git a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php
index 6aaf1216d3e18b6e891312aeeec8287958554448..e55b9a9588c79bce5da0a3dea9a8c0bf4811c574 100644
--- a/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php
+++ b/app/code/Magento/CatalogRule/Controller/Adminhtml/Promo/Catalog/Save.php
@@ -19,7 +19,7 @@ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
         if ($this->getRequest()->getPostValue()) {
 
             /** @var \Magento\CatalogRule\Api\CatalogRuleRepositoryInterface $ruleRepository */
-            $ruleRepository = $this->_objectManager->create(
+            $ruleRepository = $this->_objectManager->get(
                 'Magento\CatalogRule\Api\CatalogRuleRepositoryInterface'
             );
 
@@ -32,12 +32,6 @@ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
                     ['request' => $this->getRequest()]
                 );
                 $data = $this->getRequest()->getPostValue();
-                $inputFilter = new \Zend_Filter_Input(
-                    ['from_date' => $this->_dateFilter, 'to_date' => $this->_dateFilter],
-                    [],
-                    $data
-                );
-                $data = $inputFilter->getUnescaped();
                 $id = $this->getRequest()->getParam('rule_id');
                 if ($id) {
                     $model = $ruleRepository->get($id);
@@ -53,8 +47,10 @@ class Save extends \Magento\CatalogRule\Controller\Adminhtml\Promo\Catalog
                     return;
                 }
 
-                $data['conditions'] = $data['rule']['conditions'];
-                unset($data['rule']);
+                if (isset($data['rule'])) {
+                    $data['conditions'] = $data['rule']['conditions'];
+                    unset($data['rule']);
+                }
 
                 $model->loadPost($data);
 
diff --git a/app/code/Magento/CatalogRule/Controller/RegistryConstants.php b/app/code/Magento/CatalogRule/Controller/RegistryConstants.php
new file mode 100644
index 0000000000000000000000000000000000000000..43f156b12103c1e78cb6a49b122cfc4d192cae99
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Controller/RegistryConstants.php
@@ -0,0 +1,19 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+
+namespace Magento\CatalogRule\Controller;
+
+/**
+ * Declarations of core registry keys used by the CatalogRule module
+ *
+ */
+class RegistryConstants
+{
+    /**
+     * Key for current catalog rule in registry
+     */
+    const CURRENT_CATALOG_RULE_ID = 'current_promo_catalog_rule';
+}
diff --git a/app/code/Magento/CatalogRule/Model/Data/Condition.php b/app/code/Magento/CatalogRule/Model/Data/Condition.php
new file mode 100644
index 0000000000000000000000000000000000000000..f76bb0249fa0efb189938451e39de9a836426951
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Model/Data/Condition.php
@@ -0,0 +1,144 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRule\Model\Data;
+
+use Magento\Framework\Model\AbstractExtensibleModel;
+
+/**
+ * Class Condition
+ * @codeCoverageIgnore
+ */
+class Condition extends AbstractExtensibleModel implements \Magento\CatalogRule\Api\Data\ConditionInterface
+{
+    /**
+     * {@inheritdoc}
+     */
+    public function setType($type)
+    {
+        return $this->setData(self::TYPE, $type);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getType()
+    {
+        return $this->getData(self::TYPE);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setAttribute($attribute)
+    {
+        return $this->setData(self::ATTRIBUTE, $attribute);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getAttribute()
+    {
+        return $this->getData(self::ATTRIBUTE);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setOperator($operator)
+    {
+        return $this->setData(self::OPERATOR, $operator);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getOperator()
+    {
+        return $this->getData(self::OPERATOR);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setValue($value)
+    {
+        return $this->setData(self::VALUE, $value);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getValue()
+    {
+        return $this->getData(self::VALUE);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setIsValueParsed($isValueParsed)
+    {
+        return $this->setData(self::IS_VALUE_PARSED, $isValueParsed);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getIsValueParsed()
+    {
+        return $this->getData(self::IS_VALUE_PARSED);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setAggregator($aggregator)
+    {
+        return $this->setData(self::AGGREGATOR, $aggregator);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getAggregator()
+    {
+        return $this->getData(self::AGGREGATOR);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setConditions($conditions)
+    {
+        return $this->setData(self::CONDITIONS, $conditions);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getConditions()
+    {
+        return $this->getData(self::CONDITIONS);
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function getExtensionAttributes()
+    {
+        return $this->_getExtensionAttributes();
+    }
+
+    /**
+     * {@inheritdoc}
+     */
+    public function setExtensionAttributes(
+        \Magento\CatalogRule\Api\Data\ConditionExtensionInterface $extensionAttributes
+    ) {
+        return $this->_setExtensionAttributes($extensionAttributes);
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Model/Data/Condition/Converter.php b/app/code/Magento/CatalogRule/Model/Data/Condition/Converter.php
new file mode 100644
index 0000000000000000000000000000000000000000..37dfbb9c4ecf0691b2a58f09cc045338c730a0f3
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Model/Data/Condition/Converter.php
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRule\Model\Data\Condition;
+
+class Converter
+{
+    /**
+     * @var \Magento\CatalogRule\Api\Data\ConditionInterfaceFactory
+     */
+    protected $ruleConditionFactory;
+
+    /**
+     * @param \Magento\CatalogRule\Api\Data\ConditionInterfaceFactory $ruleConditionFactory
+     */
+    public function __construct(\Magento\CatalogRule\Api\Data\ConditionInterfaceFactory $ruleConditionFactory)
+    {
+        $this->ruleConditionFactory = $ruleConditionFactory;
+    }
+
+    /**
+     * @param \Magento\CatalogRule\Api\Data\ConditionInterface $dataModel
+     * @return array
+     */
+    public function dataModelToArray(\Magento\CatalogRule\Api\Data\ConditionInterface $dataModel)
+    {
+        $conditionArray = [
+            'type' => $dataModel->getType(),
+            'attribute' => $dataModel->getAttribute(),
+            'operator' => $dataModel->getOperator(),
+            'value' => $dataModel->getValue(),
+            'is_value_processed' => $dataModel->getIsValueParsed(),
+            'aggregator' => $dataModel->getAggregator()
+        ];
+
+        foreach ((array)$dataModel->getConditions() as $condition) {
+            $conditionArray['conditions'][] = $this->dataModelToArray($condition);
+        }
+
+        return $conditionArray;
+    }
+
+    /**
+     * @param array $conditionArray
+     * @return \Magento\CatalogRule\Api\Data\ConditionInterface
+     * @SuppressWarnings(PHPMD.NPathComplexity)
+     */
+    public function arrayToDataModel(array $conditionArray)
+    {
+        /** @var \Magento\CatalogRule\Api\Data\ConditionInterface $ruleCondition */
+        $ruleCondition = $this->ruleConditionFactory->create();
+
+        $ruleCondition->setType($conditionArray['type']);
+        $ruleCondition->setAggregator(isset($conditionArray['aggregator']) ? $conditionArray['aggregator'] : false);
+        $ruleCondition->setAttribute(isset($conditionArray['attribute']) ? $conditionArray['attribute'] : false);
+        $ruleCondition->setOperator(isset($conditionArray['operator']) ? $conditionArray['operator'] : false);
+        $ruleCondition->setValue(isset($conditionArray['value']) ? $conditionArray['value'] : false);
+        $ruleCondition->setIsValueParsed(
+            isset($conditionArray['is_value_parsed']) ? $conditionArray['is_value_parsed'] : false
+        );
+
+        if (isset($conditionArray['conditions']) && is_array($conditionArray['conditions'])) {
+            $conditions = [];
+            foreach ($conditionArray['conditions'] as $condition) {
+                $conditions[] = $this->arrayToDataModel($condition);
+            }
+            $ruleCondition->setConditions($conditions);
+        }
+        return $ruleCondition;
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Model/Rule.php b/app/code/Magento/CatalogRule/Model/Rule.php
index 023a5dbfe9fd6272a20230b6f5cfd660c60491f6..b96ee8e8c62e304148fa8e2cf4b9ded4de1d74a7 100644
--- a/app/code/Magento/CatalogRule/Model/Rule.php
+++ b/app/code/Magento/CatalogRule/Model/Rule.php
@@ -124,6 +124,11 @@ class Rule extends \Magento\Rule\Model\AbstractModel implements \Magento\Catalog
      */
     protected $_ruleProductProcessor;
 
+    /**
+     * @var Data\Condition\Converter
+     */
+    protected $ruleConditionConverter;
+
     /**
      * @param \Magento\Framework\Model\Context $context
      * @param \Magento\Framework\Registry $registry
@@ -141,6 +146,7 @@ class Rule extends \Magento\Rule\Model\AbstractModel implements \Magento\Catalog
      * @param \Magento\CatalogRule\Helper\Data $catalogRuleData
      * @param \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList
      * @param Indexer\Rule\RuleProductProcessor $ruleProductProcessor
+     * @param Data\Condition\Converter $ruleConditionConverter
      * @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
      * @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
      * @param array $relatedCacheTypes
@@ -165,6 +171,7 @@ class Rule extends \Magento\Rule\Model\AbstractModel implements \Magento\Catalog
         \Magento\CatalogRule\Helper\Data $catalogRuleData,
         \Magento\Framework\App\Cache\TypeListInterface $cacheTypesList,
         \Magento\CatalogRule\Model\Indexer\Rule\RuleProductProcessor $ruleProductProcessor,
+        \Magento\CatalogRule\Model\Data\Condition\Converter $ruleConditionConverter,
         \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
         \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
         array $relatedCacheTypes = [],
@@ -181,6 +188,8 @@ class Rule extends \Magento\Rule\Model\AbstractModel implements \Magento\Catalog
         $this->_cacheTypesList = $cacheTypesList;
         $this->_relatedCacheTypes = $relatedCacheTypes;
         $this->_ruleProductProcessor = $ruleProductProcessor;
+        $this->ruleConditionConverter = $ruleConditionConverter;
+
         parent::__construct(
             $context,
             $registry,
@@ -631,33 +640,20 @@ class Rule extends \Magento\Rule\Model\AbstractModel implements \Magento\Catalog
     /**
      * {@inheritdoc}
      */
-    public function getConditionsSerialized()
+    public function getRuleCondition()
     {
-        return $this->getData(self::CONDITIONS_SERIALIZED);
+        return $this->ruleConditionConverter->arrayToDataModel($this->getConditions()->asArray());
     }
 
     /**
      * {@inheritdoc}
      */
-    public function setConditionsSerialized($conditions)
+    public function setRuleCondition($condition)
     {
-        return $this->setData(self::CONDITIONS_SERIALIZED, $conditions);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function getActionsSerialized()
-    {
-        return $this->getData(self::ACTIONS_SERIALIZED);
-    }
-
-    /**
-     * {@inheritdoc}
-     */
-    public function setActionsSerialized($actions)
-    {
-        return $this->setData(self::ACTIONS_SERIALIZED, $actions);
+        $this->getConditions()
+            ->setConditions([])
+            ->loadArray($this->ruleConditionConverter->dataModelToArray($condition));
+        return $this;
     }
 
     /**
diff --git a/app/code/Magento/CatalogRule/Model/Rule/DataProvider.php b/app/code/Magento/CatalogRule/Model/Rule/DataProvider.php
new file mode 100644
index 0000000000000000000000000000000000000000..1ffff11f07b3138895abd2571ebfe41f24210744
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Model/Rule/DataProvider.php
@@ -0,0 +1,151 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRule\Model\Rule;
+
+use Magento\CatalogRule\Model\ResourceModel\Rule\Collection;
+use Magento\CatalogRule\Model\ResourceModel\Rule\CollectionFactory;
+use Magento\CatalogRule\Model\Rule;
+use Magento\Framework\View\Element\UiComponent\DataProvider\FilterPool;
+use Magento\Store\Model\System\Store;
+use Magento\Customer\Api\GroupRepositoryInterface;
+use Magento\Framework\Api\SearchCriteriaBuilder;
+use Magento\Framework\Convert\DataObject;
+
+/**
+ * Class DataProvider
+ */
+class DataProvider extends \Magento\Ui\DataProvider\AbstractDataProvider
+{
+    /**
+     * @var Collection
+     */
+    protected $collection;
+
+    /**
+     * @var array
+     */
+    protected $loadedData;
+
+    /**
+     * @var Store
+     */
+    protected $store;
+
+    /**
+     * @var GroupRepositoryInterface
+     */
+    protected $groupRepository;
+
+    /**
+     * @var SearchCriteriaBuilder
+     */
+    protected $searchCriteriaBuilder;
+
+    /**
+     * @var DataObject
+     */
+    protected $objectConverter;
+
+    /**
+     * DataProvider constructor.
+     * @param string $name
+     * @param string $primaryFieldName
+     * @param string $requestFieldName
+     * @param CollectionFactory $collectionFactory
+     * @param Store $store
+     * @param GroupRepositoryInterface $groupRepository
+     * @param SearchCriteriaBuilder $searchCriteriaBuilder
+     * @param DataObject $objectConverter
+     * @param array $meta
+     * @param array $data
+     *
+     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
+     */
+    public function __construct(
+        $name,
+        $primaryFieldName,
+        $requestFieldName,
+        CollectionFactory $collectionFactory,
+        Store $store,
+        GroupRepositoryInterface $groupRepository,
+        SearchCriteriaBuilder $searchCriteriaBuilder,
+        DataObject $objectConverter,
+        array $meta = [],
+        array $data = []
+    ) {
+        parent::__construct($name, $primaryFieldName, $requestFieldName, $meta, $data);
+        $this->collection = $collectionFactory->create();
+        $this->store = $store;
+        $this->groupRepository = $groupRepository;
+        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
+        $this->objectConverter = $objectConverter;
+        $this->initMeta();
+    }
+
+    /**
+     * @return void
+     */
+    protected function initMeta()
+    {
+        $customerGroups = $this->groupRepository->getList($this->searchCriteriaBuilder->create())->getItems();
+        $applyOptions = [
+            ['label' => __('Apply as percentage of original'), 'value' => 'by_percent'],
+            ['label' => __('Apply as fixed amount'), 'value' => 'by_fixed'],
+            ['label' => __('Adjust final price to this percentage'), 'value' => 'to_percent'],
+            ['label' => __('Adjust final price to discount value'), 'value' => 'to_fixed']
+        ];
+
+        $this->meta = [
+            'rule_information' => [
+                'fields' => [
+                    'website_ids' => [
+                        'options' => $this->store->getWebsiteValuesForForm()
+                    ],
+                    'is_active' => [
+                        'options' => [
+                            ['label' => __('Active'), 'value' => '1'],
+                            ['label' => __('Inactive'), 'value' => '0']
+                        ]
+                    ],
+                    'customer_group_ids' => [
+                        'options' => $this->objectConverter->toOptionArray($customerGroups, 'id', 'code')
+                    ]
+                ]
+            ],
+            'actions' => [
+                'fields' => [
+                    'simple_action' => [
+                        'options' => $applyOptions
+                    ],
+                    'stop_rules_processing' => [
+                        'options' => [
+                            ['label' => __('Yes'), 'value' => '1'],
+                            ['label' => __('No'), 'value' => '0']
+                        ]
+                    ],
+                ]
+            ]
+        ];
+    }
+
+    /**
+     * @return array
+     */
+    public function getData()
+    {
+        if (isset($this->loadedData)) {
+            return $this->loadedData;
+        }
+        $items = $this->collection->getItems();
+        /** @var Rule $rule */
+        foreach ($items as $rule) {
+            $rule->load($rule->getId());
+            $this->loadedData[$rule->getId()] = $rule->getData();
+        }
+
+        return $this->loadedData;
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Test/Unit/Block/Adminhtml/Edit/DeleteButtonTest.php b/app/code/Magento/CatalogRule/Test/Unit/Block/Adminhtml/Edit/DeleteButtonTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..a46e330af5647e2c769c6ef4ba7bd0d7323ba3f0
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Test/Unit/Block/Adminhtml/Edit/DeleteButtonTest.php
@@ -0,0 +1,72 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRule\Test\Unit\Block\Adminhtml\Edit;
+
+use Magento\CatalogRule\Controller\RegistryConstants;
+
+class DeleteButtonTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogRule\Block\Adminhtml\Edit\DeleteButton
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $registryMock;
+
+    protected function setUp()
+    {
+        $this->urlBuilderMock = $this->getMock('\Magento\Framework\UrlInterface', [], [], '', false);
+        $this->registryMock = $this->getMock('\Magento\Framework\Registry', [], [], '', false);
+        $contextMock = $this->getMock('\Magento\Backend\Block\Widget\Context', [], [], '', false);
+
+        $contextMock->expects($this->once())->method('getUrlBuilder')->willReturn($this->urlBuilderMock);
+
+        $this->model = new \Magento\CatalogRule\Block\Adminhtml\Edit\DeleteButton(
+            $contextMock,
+            $this->registryMock
+        );
+    }
+
+    public function testGetButtonData()
+    {
+        $ruleId = 42;
+        $deleteUrl = 'http://magento.com/rule/delete/' . $ruleId;
+        $ruleMock = new \Magento\Framework\DataObject(['id' => $ruleId]);
+
+        $this->registryMock->expects($this->once())
+            ->method('registry')
+            ->with(RegistryConstants::CURRENT_CATALOG_RULE_ID)
+            ->willReturn($ruleMock);
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with('*/*/delete', ['id' => $ruleId])
+            ->willReturn($deleteUrl);
+
+        $data = [
+            'label' => __('Delete Rule'),
+            'class' => 'delete',
+            'on_click' => 'deleteConfirm(\'' . __(
+                'Are you sure you want to do this?'
+            ) . '\', \'' . $deleteUrl . '\')',
+            'sort_order' => 20,
+        ];
+
+        $this->assertEquals($data, $this->model->getButtonData());
+    }
+
+    public function testGetButtonDataWithoutRule()
+    {
+        $this->assertEquals([], $this->model->getButtonData());
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Test/Unit/Block/Adminhtml/Edit/GenericButtonTest.php b/app/code/Magento/CatalogRule/Test/Unit/Block/Adminhtml/Edit/GenericButtonTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c43cb4c64eb2bc9dec773282d5e8dfb50a54388a
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Test/Unit/Block/Adminhtml/Edit/GenericButtonTest.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRule\Test\Unit\Block\Adminhtml\Edit;
+
+use Magento\CatalogRule\Controller\RegistryConstants;
+
+class GenericButtonTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogRule\Block\Adminhtml\Edit\GenericButton
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $urlBuilderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $registryMock;
+
+    protected function setUp()
+    {
+        $this->urlBuilderMock = $this->getMock('\Magento\Framework\UrlInterface', [], [], '', false);
+        $this->registryMock = $this->getMock('\Magento\Framework\Registry', [], [], '', false);
+        $contextMock = $this->getMock('\Magento\Backend\Block\Widget\Context', [], [], '', false);
+
+        $contextMock->expects($this->once())->method('getUrlBuilder')->willReturn($this->urlBuilderMock);
+
+        $this->model = new \Magento\CatalogRule\Block\Adminhtml\Edit\GenericButton(
+            $contextMock,
+            $this->registryMock
+        );
+    }
+
+    public function testCanRender()
+    {
+        $name = "Catalog Rule";
+        $this->assertEquals($name, $this->model->canRender($name));
+    }
+
+    public function testGetUrl()
+    {
+        $url = "http://magento.com/catalogRule/";
+        $route = 'button';
+        $params = ['unit' => 'test'];
+
+        $this->urlBuilderMock->expects($this->once())
+            ->method('getUrl')
+            ->with($route, $params)
+            ->willReturn($url);
+
+        $this->assertEquals($url, $this->model->getUrl($route, $params));
+    }
+
+    public function testGetRuleId()
+    {
+        $ruleId = 42;
+        $ruleMock = new \Magento\Framework\DataObject(['id' => $ruleId]);
+        $this->registryMock->expects($this->once())
+            ->method('registry')
+            ->with(RegistryConstants::CURRENT_CATALOG_RULE_ID)
+            ->willReturn($ruleMock);
+
+        $this->assertEquals($ruleId, $this->model->getRuleId());
+    }
+
+    public function testGetRuleIdWithoutRule()
+    {
+        $this->assertNull($this->model->getRuleId());
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Data/Condition/ConverterTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Data/Condition/ConverterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..86a88a1fd4903facbe6199375c6eb51df0805095
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Data/Condition/ConverterTest.php
@@ -0,0 +1,116 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRule\Test\Unit\Model\Data\Condition;
+
+class ConverterTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject|\Magento\CatalogRule\Api\Data\ConditionInterfaceFactory
+     */
+    protected $conditionFactoryMock;
+
+    /**
+     * @var \Magento\CatalogRule\Model\Data\Condition\Converter
+     */
+    protected $model;
+
+    protected function setUp()
+    {
+        $this->conditionFactoryMock = $this->getMock(
+            '\Magento\CatalogRule\Api\Data\ConditionInterfaceFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->model = new \Magento\CatalogRule\Model\Data\Condition\Converter($this->conditionFactoryMock);
+    }
+
+    public function testDataModelToArray()
+    {
+        $childConditionMock = $this->getMock('\Magento\CatalogRule\Api\Data\ConditionInterface');
+        $childConditionMock->expects($this->once())->method('getType')->willReturn('child-type');
+        $childConditionMock->expects($this->once())->method('getAttribute')->willReturn('child-attr');
+        $childConditionMock->expects($this->once())->method('getOperator')->willReturn('child-operator');
+        $childConditionMock->expects($this->once())->method('getValue')->willReturn('child-value');
+        $childConditionMock->expects($this->once())->method('getIsValueParsed')->willReturn(true);
+        $childConditionMock->expects($this->once())->method('getAggregator')->willReturn('all');
+        $childConditionMock->expects($this->once())->method('getConditions')->willReturn([]);
+
+        $dataModelMock = $this->getMock('\Magento\CatalogRule\Api\Data\ConditionInterface');
+        $dataModelMock->expects($this->once())->method('getType')->willReturn('type');
+        $dataModelMock->expects($this->once())->method('getAttribute')->willReturn('attr');
+        $dataModelMock->expects($this->once())->method('getOperator')->willReturn('operator');
+        $dataModelMock->expects($this->once())->method('getValue')->willReturn('value');
+        $dataModelMock->expects($this->once())->method('getIsValueParsed')->willReturn(true);
+        $dataModelMock->expects($this->once())->method('getAggregator')->willReturn('all');
+        $dataModelMock->expects($this->once())->method('getConditions')->willReturn([$childConditionMock]);
+
+        $expectedResult = [
+            'type' => 'type',
+            'attribute' => 'attr',
+            'operator' => 'operator',
+            'value' => 'value',
+            'is_value_processed' => true,
+            'aggregator' => 'all',
+            'conditions' => [
+                [
+                    'type' => 'child-type',
+                    'attribute' => 'child-attr',
+                    'operator' => 'child-operator',
+                    'value' => 'child-value',
+                    'is_value_processed' => 1,
+                    'aggregator' => 'all',
+                ]
+            ]
+        ];
+        $this->assertEquals($expectedResult, $this->model->dataModelToArray($dataModelMock));
+    }
+
+    public function testArrayToDataModel()
+    {
+        $array = [
+            'type' => 'type',
+            'attribute' => 'attr',
+            'operator' => 'operator',
+            'value' => 'value',
+            'is_value_parsed' => true,
+            'aggregator' => 'all',
+            'conditions' => [
+                [
+                    'type' => 'child-type',
+                    'attribute' => 'child-attr',
+                    'operator' => 'child-operator',
+                    'value' => 'child-value',
+                    'is_value_parsed' => false,
+                    'aggregator' => 'any',
+                ]
+            ]
+        ];
+
+        $conditionMock = $this->getMock('\Magento\CatalogRule\Api\Data\ConditionInterface');
+        $conditionChildMock = $this->getMock('\Magento\CatalogRule\Api\Data\ConditionInterface');
+
+        $this->conditionFactoryMock->expects($this->at(0))->method('create')->willReturn($conditionMock);
+        $this->conditionFactoryMock->expects($this->at(1))->method('create')->willReturn($conditionChildMock);
+
+        $conditionMock->expects($this->once())->method('setType')->with('type')->willReturnSelf();
+        $conditionMock->expects($this->once())->method('setAggregator')->with('all')->willReturnSelf();
+        $conditionMock->expects($this->once())->method('setAttribute')->with('attr')->willReturnSelf();
+        $conditionMock->expects($this->once())->method('setOperator')->with('operator')->willReturnSelf();
+        $conditionMock->expects($this->once())->method('setIsValueParsed')->with(true)->willReturnSelf();
+        $conditionMock->expects($this->once())->method('setConditions')->with([$conditionChildMock])->willReturnSelf();
+
+        $conditionChildMock->expects($this->once())->method('setType')->with('child-type')->willReturnSelf();
+        $conditionChildMock->expects($this->once())->method('setAggregator')->with('any')->willReturnSelf();
+        $conditionChildMock->expects($this->once())->method('setAttribute')->with('child-attr')->willReturnSelf();
+        $conditionChildMock->expects($this->once())->method('setOperator')->with('child-operator')->willReturnSelf();
+        $conditionChildMock->expects($this->once())->method('setIsValueParsed')->with(false)->willReturnSelf();
+
+
+        $this->assertEquals($conditionMock, $this->model->arrayToDataModel($array));
+    }
+}
diff --git a/app/code/Magento/CatalogRule/Test/Unit/Model/Rule/DataProviderTest.php b/app/code/Magento/CatalogRule/Test/Unit/Model/Rule/DataProviderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..22c6b0326ca9ed28f5b1794344c543c8cf04efa7
--- /dev/null
+++ b/app/code/Magento/CatalogRule/Test/Unit/Model/Rule/DataProviderTest.php
@@ -0,0 +1,119 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\CatalogRule\Test\Unit\Model\Rule;
+
+class DataProviderTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \Magento\CatalogRule\Model\Rule\DataProvider
+     */
+    protected $model;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $collectionFactoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $storeMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $groupRepositoryMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $searchCriteriaBuilderMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $dataObjectMock;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $collectionMock;
+
+    protected function setUp()
+    {
+        $this->collectionFactoryMock = $this->getMock(
+            'Magento\CatalogRule\Model\ResourceModel\Rule\CollectionFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->searchCriteriaBuilderMock = $this->getMock(
+            'Magento\Framework\Api\SearchCriteriaBuilder',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->storeMock = $this->getMock('Magento\Store\Model\System\Store', [], [], '', false);
+        $this->groupRepositoryMock = $this->getMock('Magento\Customer\Api\GroupRepositoryInterface', [], [], '', false);
+        $this->dataObjectMock = $this->getMock('Magento\Framework\Convert\DataObject', [], [], '', false);
+
+        $this->collectionMock = $this->getMock(
+            'Magento\CatalogRule\Model\ResourceModel\Rule\Collection',
+            [],
+            [],
+            '',
+            false
+        );
+        $this->collectionFactoryMock->expects($this->once())->method('create')->willReturn($this->collectionMock);
+        $searchCriteriaMock = $this->getMock('Magento\Framework\Api\SearchCriteriaInterface', [], [], '', false);
+        $groupSearchResultsMock = $this->getMock(
+            'Magento\Customer\Api\Data\GroupSearchResultsInterface',
+            [],
+            [],
+            '',
+            false
+        );
+        $groupsMock = $this->getMock('Magento\Customer\Api\Data\GroupInterface', [], [], '', false);
+
+        $this->searchCriteriaBuilderMock->expects($this->once())->method('create')->willReturn($searchCriteriaMock);
+        $this->groupRepositoryMock->expects($this->once())->method('getList')->with($searchCriteriaMock)
+            ->willReturn($groupSearchResultsMock);
+        $groupSearchResultsMock->expects($this->once())->method('getItems')->willReturn([$groupsMock]);
+        $this->storeMock->expects($this->once())->method('getWebsiteValuesForForm')->willReturn([]);
+        $this->dataObjectMock->expects($this->once())->method('toOptionArray')->with([$groupsMock], 'id', 'code')
+            ->willReturn([]);
+
+        $this->model = new \Magento\CatalogRule\Model\Rule\DataProvider(
+            'Name',
+            'Primary',
+            'Request',
+            $this->collectionFactoryMock,
+            $this->storeMock,
+            $this->groupRepositoryMock,
+            $this->searchCriteriaBuilderMock,
+            $this->dataObjectMock
+        );
+    }
+
+    public function testGetData()
+    {
+        $ruleId = 42;
+        $ruleData = ['name' => 'Catalog Price Rule'];
+
+        $ruleMock = $this->getMock('Magento\CatalogRule\Model\Rule', [], [], '', false);
+        $this->collectionMock->expects($this->once())->method('getItems')->willReturn([$ruleMock]);
+
+        $ruleMock->expects($this->atLeastOnce())->method('getId')->willReturn($ruleId);
+        $ruleMock->expects($this->once())->method('load')->willReturnSelf();
+        $ruleMock->expects($this->once())->method('getData')->willReturn($ruleData);
+
+        $this->assertEquals([$ruleId => $ruleData], $this->model->getData());
+        // Load from object-cache the second time
+        $this->assertEquals([$ruleId => $ruleData], $this->model->getData());
+    }
+}
diff --git a/app/code/Magento/CatalogRule/composer.json b/app/code/Magento/CatalogRule/composer.json
index c8f8dd69cc7ed3b3b110bcc7f44f2d43ff65953e..7d952f9cdd5769479087b68064c9aa7b58dab83e 100644
--- a/app/code/Magento/CatalogRule/composer.json
+++ b/app/code/Magento/CatalogRule/composer.json
@@ -9,6 +9,7 @@
         "magento/module-customer": "100.0.*",
         "magento/module-backend": "100.0.*",
         "magento/module-eav": "100.0.*",
+        "magento/module-ui": "100.0.*",
         "magento/framework": "100.0.*"
     },
     "suggest": {
diff --git a/app/code/Magento/CatalogRule/etc/di.xml b/app/code/Magento/CatalogRule/etc/di.xml
index e5244cb01dda1bc59ecb10574e85d845ebbb8272..cf0657e61702188b72ceb449835a8d117ec2f829 100644
--- a/app/code/Magento/CatalogRule/etc/di.xml
+++ b/app/code/Magento/CatalogRule/etc/di.xml
@@ -100,4 +100,32 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\View\Element\UiComponent\DataProvider\CollectionFactory">
+        <arguments>
+            <argument name="collections" xsi:type="array">
+                <item name="catalog_rule_data_source" xsi:type="string">catalogRuleSearchResult</item>
+            </argument>
+        </arguments>
+    </type>
+    <virtualType name="catalogRuleSearchResult" type="Magento\Framework\View\Element\UiComponent\DataProvider\SearchResult">
+        <arguments>
+            <argument name="mainTable" xsi:type="string">catalogrule</argument>
+            <argument name="resourceModel" xsi:type="string">\Magento\CatalogRule\Model\ResourceModel\Rule</argument>
+        </arguments>
+    </virtualType>
+    <type name="Magento\CatalogRule\Model\Rule\Condition\Combine">
+        <arguments>
+            <argument name="data" xsi:type="array">
+                <item name="form_name" xsi:type="string">catalog_rule_form</item>
+            </argument>
+        </arguments>
+    </type>
+    <type name="Magento\CatalogRule\Model\Rule\Condition\Product">
+        <arguments>
+            <argument name="data" xsi:type="array">
+                <item name="form_name" xsi:type="string">catalog_rule_form</item>
+            </argument>
+        </arguments>
+    </type>
+    <preference for="Magento\CatalogRule\Api\Data\ConditionInterface" type="Magento\CatalogRule\Model\Data\Condition" />
 </config>
diff --git a/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_edit.xml b/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_edit.xml
index 879963b295409ee03df5194274d13461cd5e0489..102eeea6f5b3217d66cf2d1c067908a80da23fc1 100644
--- a/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_edit.xml
+++ b/app/code/Magento/CatalogRule/view/adminhtml/layout/catalog_rule_promo_catalog_edit.xml
@@ -7,30 +7,22 @@
 -->
 <page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="admin-2columns-left" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
     <body>
-        <referenceContainer name="left">
-            <block class="Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tabs" name="promo_catalog_edit_tabs">
-                <block class="Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab\Main" name="promo_catalog_edit_tab_main"/>
-                <block class="Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab\Conditions" name="promo_catalog_edit_tab_conditions"/>
-                <block class="Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab\Actions" name="promo_catalog_edit_tab_actions"/>
-                <action method="addTab">
-                    <argument name="name" xsi:type="string">main_section</argument>
-                    <argument name="block" xsi:type="string">promo_catalog_edit_tab_main</argument>
-                </action>
-                <action method="addTab">
-                    <argument name="name" xsi:type="string">conditions_section</argument>
-                    <argument name="block" xsi:type="string">promo_catalog_edit_tab_conditions</argument>
-                </action>
-                <action method="addTab">
-                    <argument name="name" xsi:type="string">actions_section</argument>
-                    <argument name="block" xsi:type="string">promo_catalog_edit_tab_actions</argument>
-                </action>
-            </block>
-        </referenceContainer>
         <referenceContainer name="content">
-            <block class="Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit" name="promo_catalog_edit"/>
-        </referenceContainer>
-        <referenceContainer name="js">
-            <block class="Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Js" template="promo/js.phtml"/>
+            <referenceBlock name="catalog_rule_form">
+                <block class="Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab\Conditions" name="promo_catalog_edit_tab_conditions">
+                    <arguments>
+                    <argument name="config" xsi:type="array">
+                        <item name="label" xsi:type="string" translate="true">Conditions</item>
+                        <item name="collapsible" xsi:type="boolean">true</item>
+                        <item name="opened" xsi:type="boolean">false</item>
+                        <item name="sortOrder" xsi:type="string">1</item>
+                        <item name="canShow" xsi:type="boolean">true</item>
+                        <item name="componentType" xsi:type="string">fieldset</item>
+                    </argument>
+                </arguments>
+                </block>
+            </referenceBlock>
+            <uiComponent name="catalog_rule_form"/>
         </referenceContainer>
     </body>
 </page>
diff --git a/app/code/Magento/CatalogRule/view/adminhtml/templates/promo/js.phtml b/app/code/Magento/CatalogRule/view/adminhtml/templates/promo/js.phtml
deleted file mode 100644
index 1feb2f1cc693fdc3b65d7805f1f7e956de4f4ea2..0000000000000000000000000000000000000000
--- a/app/code/Magento/CatalogRule/view/adminhtml/templates/promo/js.phtml
+++ /dev/null
@@ -1,25 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-?>
-<script>
-require(["jquery", "prototype"], function(jQuery){
-
-function changeValidationForDiscountPercent()
-{
-    if ($('rule_simple_action').value == 'by_percent' || $('rule_simple_action').value == 'to_percent') {
-        $('rule_discount_amount').addClassName('validate-number-range number-range-0.00-100.00');
-    } else {
-        $('rule_discount_amount').removeClassName('validate-number-range').removeClassName('number-range-0.00-100.00');
-    }
-
-    return true;
-}
-
-jQuery(document).ready(changeValidationForDiscountPercent);
-jQuery(document).on('change', '#rule_simple_action', changeValidationForDiscountPercent);
-window.changeValidationForDiscountPercent = changeValidationForDiscountPercent;
-});
-</script>
diff --git a/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml b/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f20cbbb6187388bf4a39fdfcfa5da3556f88655c
--- /dev/null
+++ b/app/code/Magento/CatalogRule/view/adminhtml/ui_component/catalog_rule_form.xml
@@ -0,0 +1,290 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+-->
+<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
+    <argument name="data" xsi:type="array">
+        <item name="js_config" xsi:type="array">
+            <item name="provider" xsi:type="string">catalog_rule_form.catalog_rule_form_data_source</item>
+            <item name="deps" xsi:type="string">catalog_rule_form.catalog_rule_form_data_source</item>
+        </item>
+        <item name="label" xsi:type="string" translate="true">Catalog Price Rule</item>
+        <item name="config" xsi:type="array">
+            <item name="dataScope" xsi:type="string">data</item>
+            <item name="namespace" xsi:type="string">catalog_rule_form</item>
+        </item>
+        <item name="template" xsi:type="string">templates/form/collapsible</item>
+        <item name="buttons" xsi:type="array">
+            <item name="back" xsi:type="array">
+                <item name="name" xsi:type="string">back</item>
+                <item name="label" xsi:type="string" translate="true">Back</item>
+                <item name="class" xsi:type="string">back</item>
+                <item name="url" xsi:type="string">*/*/</item>
+            </item>
+            <item name="save" xsi:type="string">Magento\CatalogRule\Block\Adminhtml\Edit\SaveButton</item>
+            <item name="reset" xsi:type="string">Magento\CatalogRule\Block\Adminhtml\Edit\ResetButton</item>
+            <item name="save_and_continue" xsi:type="string">Magento\CatalogRule\Block\Adminhtml\Edit\SaveAndContinueButton</item>
+            <item name="save_and_apply" xsi:type="string">Magento\CatalogRule\Block\Adminhtml\Edit\SaveAndApplyButton</item>
+            <item name="delete" xsi:type="string">Magento\CatalogRule\Block\Adminhtml\Edit\DeleteButton</item>
+        </item>
+    </argument>
+    <dataSource name="catalog_rule_form_data_source">
+        <argument name="dataProvider" xsi:type="configurableObject">
+            <argument name="class" xsi:type="string">Magento\CatalogRule\Model\Rule\DataProvider</argument>
+            <argument name="name" xsi:type="string">catalog_rule_form_data_source</argument>
+            <argument name="primaryFieldName" xsi:type="string">rule_id</argument>
+            <argument name="requestFieldName" xsi:type="string">id</argument>
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="submit_url" xsi:type="url" path="catalog_rule/promo_catalog/save"/>
+                </item>
+            </argument>
+        </argument>
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/provider</item>
+            </item>
+        </argument>
+    </dataSource>
+    <fieldset name="rule_information">
+        <argument name="data" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <!--<item name="dataScope" xsi:type="string">data</item>-->
+                <item name="label" xsi:type="string" translate="true">Rule Information</item>
+                <item name="collapsible" xsi:type="boolean">true</item>
+                <item name="sort_order" xsi:type="string">10</item>
+            </item>
+        </argument>
+        <field name="rule_id">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="visible" xsi:type="boolean">false</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">rule_id</item>
+                </item>
+            </argument>
+        </field>
+        <field name="name">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">Rule Name</item>
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">name</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="description">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">Description</item>
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">textarea</item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">description</item>
+                </item>
+            </argument>
+        </field>
+        <field name="is_active">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">Status</item>
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">number</item>
+                    <item name="formElement" xsi:type="string">select</item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">is_active</item>
+                </item>
+            </argument>
+        </field>
+        <field name="website_ids">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">Websites</item>
+                    <item name="dataType" xsi:type="string">number</item>
+                    <item name="formElement" xsi:type="string">multiselect</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">website_ids</item>
+                    <item name="tooltip" xsi:type="array">
+                        <item name="link" xsi:type="string">http://www.magentocommerce.com/knowledge-base/entry/understanding-store-scopes</item>
+                        <item name="description" xsi:type="string">What is this?</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="customer_group_ids">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">Customer Groups</item>
+                    <item name="dataType" xsi:type="string">number</item>
+                    <item name="formElement" xsi:type="string">multiselect</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">customer_group_ids</item>
+                </item>
+            </argument>
+        </field>
+        <field name="from_date">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">From</item>
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">date</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="validate-date" xsi:type="boolean">true</item>
+                    </item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">from_date</item>
+                </item>
+            </argument>
+        </field>
+        <field name="to_date">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">To</item>
+                    <item name="visible" xsi:type="boolean">true</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">date</item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">to_date</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="validate-date" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="sort_order">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">Priority</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">sort_order</item>
+                </item>
+            </argument>
+        </field>
+    </fieldset>
+    <fieldset name="actions">
+        <argument name="data" xsi:type="array">
+            <item name="config" xsi:type="array">
+                <!--<item name="dataScope" xsi:type="string">data</item>-->
+                <item name="label" xsi:type="string" translate="true">Actions</item>
+                <item name="collapsible" xsi:type="boolean">true</item>
+                <item name="sort_order" xsi:type="string">30</item>
+            </item>
+        </argument>
+        <field name="simple_action">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">Apply</item>
+                    <item name="dataType" xsi:type="string">number</item>
+                    <item name="formElement" xsi:type="string">select</item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">simple_action</item>
+                    <item name="switcherConfig" xsi:type="array">
+                        <item name="enabled" xsi:type="boolean">true</item>
+                        <item name="rules" xsi:type="array">
+                            <item name="0" xsi:type="array">
+                                <item name="value" xsi:type="string">by_percent</item>
+                                <item name="actions" xsi:type="array">
+                                    <item name="0" xsi:type="array">
+                                        <item name="target" xsi:type="string">catalog_rule_form.catalog_rule_form.actions.discount_amount</item>
+                                        <item name="callback" xsi:type="string">setValidation</item>
+                                        <item name="params" xsi:type="array">
+                                            <item name="0" xsi:type="string">validate-number-range</item>
+                                            <item name="1" xsi:type="string">0.00-100.00</item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                            <item name="1" xsi:type="array">
+                                <item name="value" xsi:type="string">to_percent</item>
+                                <item name="actions" xsi:type="array">
+                                    <item name="0" xsi:type="array">
+                                        <item name="target" xsi:type="string">catalog_rule_form.catalog_rule_form.actions.discount_amount</item>
+                                        <item name="callback" xsi:type="string">setValidation</item>
+                                        <item name="params" xsi:type="array">
+                                            <item name="0" xsi:type="string">validate-number-range</item>
+                                            <item name="1" xsi:type="string">0.00-100.00</item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                            <item name="2" xsi:type="array">
+                                <item name="value" xsi:type="string">by_fixed</item>
+                                <item name="actions" xsi:type="array">
+                                    <item name="0" xsi:type="array">
+                                        <item name="target" xsi:type="string">catalog_rule_form.catalog_rule_form.actions.discount_amount</item>
+                                        <item name="callback" xsi:type="string">setValidation</item>
+                                        <item name="params" xsi:type="array">
+                                            <item name="0" xsi:type="string">validate-number-range</item>
+                                            <item name="1" xsi:type="string">false</item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                            <item name="3" xsi:type="array">
+                                <item name="value" xsi:type="string">to_fixed</item>
+                                <item name="actions" xsi:type="array">
+                                    <item name="0" xsi:type="array">
+                                        <item name="target" xsi:type="string">catalog_rule_form.catalog_rule_form.actions.discount_amount</item>
+                                        <item name="callback" xsi:type="string">setValidation</item>
+                                        <item name="params" xsi:type="array">
+                                            <item name="0" xsi:type="string">validate-number-range</item>
+                                            <item name="1" xsi:type="string">false</item>
+                                        </item>
+                                    </item>
+                                </item>
+                            </item>
+                        </item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="discount_amount">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">Discount Amount</item>
+                    <item name="dataType" xsi:type="string">text</item>
+                    <item name="formElement" xsi:type="string">input</item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">discount_amount</item>
+                    <item name="validation" xsi:type="array">
+                        <item name="required-entry" xsi:type="boolean">true</item>
+                    </item>
+                </item>
+            </argument>
+        </field>
+        <field name="stop_rules_processing">
+            <argument name="data" xsi:type="array">
+                <item name="config" xsi:type="array">
+                    <item name="label" xsi:type="string">Discard subsequent rules</item>
+                    <item name="fieldGroup" xsi:type="string">bool</item>
+                    <item name="dataType" xsi:type="string">number</item>
+                    <item name="formElement" xsi:type="string">select</item>
+                    <item name="value" xsi:type="string">0</item>
+                    <item name="source" xsi:type="string">catalog_rule</item>
+                    <item name="dataScope" xsi:type="string">stop_rules_processing</item>
+                </item>
+            </argument>
+        </field>
+    </fieldset>
+</form>
diff --git a/app/code/Magento/Checkout/Block/Cart/LayoutProcessor.php b/app/code/Magento/Checkout/Block/Cart/LayoutProcessor.php
index c9b60879c9dfe345ebe3cda5bd2c3353c80c3dea..04b0ac10be1a3ce66b808fc3ffee32196287f88d 100644
--- a/app/code/Magento/Checkout/Block/Cart/LayoutProcessor.php
+++ b/app/code/Magento/Checkout/Block/Cart/LayoutProcessor.php
@@ -85,7 +85,7 @@ class LayoutProcessor implements \Magento\Checkout\Block\Checkout\LayoutProcesso
                 'visible' => true,
                 'formElement' => 'select',
                 'label' => __('Country'),
-                'options' => $this->countryCollection->load()->toOptionArray(),
+                'options' => $this->countryCollection->loadByStore()->toOptionArray(),
                 'value' => null
             ],
             'region_id' => [
diff --git a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
index 260e04335a8d2c868cb5bd046c7d7e707642c996..f87be9fc75672394cba39f49c13ad6759e3462a2 100644
--- a/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
+++ b/app/code/Magento/Checkout/Model/ShippingInformationManagement.php
@@ -117,6 +117,7 @@ class ShippingInformationManagement implements \Magento\Checkout\Api\ShippingInf
         /** @var \Magento\Quote\Model\Quote $quote */
         $quote = $this->quoteRepository->getActive($cartId);
         $this->validateQuote($quote);
+        $quote->setIsMultiShipping(false);
 
         $saveInAddressBook = $address->getSaveInAddressBook() ? 1 : 0;
         $sameAsBilling = $address->getSameAsBilling() ? 1 : 0;
diff --git a/app/code/Magento/Checkout/Test/Unit/Block/Cart/LayoutProcessorTest.php b/app/code/Magento/Checkout/Test/Unit/Block/Cart/LayoutProcessorTest.php
index 774fe8f1a56b4604edd18242b44eaa870d743607..6d79a98183a7d093a15a2a4936018355e266bedc 100644
--- a/app/code/Magento/Checkout/Test/Unit/Block/Cart/LayoutProcessorTest.php
+++ b/app/code/Magento/Checkout/Test/Unit/Block/Cart/LayoutProcessorTest.php
@@ -66,7 +66,7 @@ class LayoutProcessorTest extends \PHPUnit_Framework_TestCase
         $layoutPointer = &$layout['components']['block-summary']['children']['block-shipping']
         ['children']['address-fieldsets']['children'];
 
-        $this->countryCollection->expects($this->once())->method('load')->willReturnSelf();
+        $this->countryCollection->expects($this->once())->method('loadByStore')->willReturnSelf();
         $this->countryCollection->expects($this->once())->method('toOptionArray')->willReturn($countries);
 
         $this->regionCollection->expects($this->once())->method('load')->willReturnSelf();
diff --git a/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php b/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
index 19fb868580e17ebaa070224509f1b01c7d4e8ac0..606d5c51fe68ea2f1c9a0a3204b7bfd15d4884f1 100644
--- a/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
+++ b/app/code/Magento/Checkout/Test/Unit/Model/ShippingInformationManagementTest.php
@@ -130,6 +130,7 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase
                 'isVirtual',
                 'getItemsCount',
                 'getIsMultiShipping',
+                'setIsMultiShipping',
                 'validateMinimumAmount',
                 'getStoreId',
                 'setShippingAddress',
@@ -423,6 +424,7 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase
         $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
         $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(5);
         $this->quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(true);
+        $this->quoteMock->expects($this->once())->method('setIsMultiShipping')->with(false)->willReturnSelf();
         $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->with(true)->willReturn(false);
         $this->quoteMock->expects($this->once())->method('getStoreId')->willReturn($storeId);
 
@@ -507,6 +509,7 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase
         $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
         $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(5);
         $this->quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(true);
+        $this->quoteMock->expects($this->once())->method('setIsMultiShipping')->with(false)->willReturnSelf();
         $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->with(true)->willReturn(true);
         $this->quoteMock->expects($this->once())->method('collectTotals')->willReturnSelf();
 
@@ -587,6 +590,7 @@ class ShippingInformationManagementTest extends \PHPUnit_Framework_TestCase
         $this->quoteMock->expects($this->once())->method('isVirtual')->willReturn(false);
         $this->quoteMock->expects($this->once())->method('getItemsCount')->willReturn(5);
         $this->quoteMock->expects($this->once())->method('getIsMultiShipping')->willReturn(true);
+        $this->quoteMock->expects($this->once())->method('setIsMultiShipping')->with(false)->willReturnSelf();
         $this->quoteMock->expects($this->once())->method('validateMinimumAmount')->with(true)->willReturn(true);
         $this->quoteMock->expects($this->once())->method('collectTotals')->willReturnSelf();
 
diff --git a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
index ab0116ee968bcf74262fb88bc1599848c64e76f1..9322100b6417b54d2b9aa7a176204962515556d6 100644
--- a/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
+++ b/app/code/Magento/Checkout/view/frontend/web/js/sidebar.js
@@ -5,14 +5,15 @@
 /*jshint browser:true jquery:true*/
 /*global confirm:true*/
 define([
-    "jquery",
+    'jquery',
     'Magento_Customer/js/model/authentication-popup',
     'Magento_Customer/js/customer-data',
     'Magento_Ui/js/modal/alert',
     'Magento_Ui/js/modal/confirm',
-    "jquery/ui",
-    "mage/decorate"
-], function($, authenticationPopup, customerData, alert, confirm){
+    'jquery/ui',
+    'mage/decorate',
+    'mage/collapsible'
+], function ($, authenticationPopup, customerData, alert, confirm) {
 
     $.widget('mage.sidebar', {
         options: {
@@ -44,11 +45,11 @@ define([
 
             this.element.decorate('list', this.options.isRecursive);
 
-            events['click ' + this.options.button.close] = function(event) {
+            events['click ' + this.options.button.close] = function (event) {
                 event.stopPropagation();
                 $(self.options.targetElement).dropdownDialog("close");
             };
-            events['click ' + this.options.button.checkout] = $.proxy(function() {
+            events['click ' + this.options.button.checkout] = $.proxy(function () {
                 var cart = customerData.get('cart'),
                     customer = customerData.get('customer');
 
@@ -109,9 +110,9 @@ define([
             }
         },
 
-        _showItemButton: function(elem) {
-            var itemId = elem.data('cart-item');
-            var itemQty = elem.data('item-qty');
+        _showItemButton: function (elem) {
+            var itemId = elem.data('cart-item'),
+                itemQty = elem.data('item-qty');
             if (this._isValidQty(itemQty, elem.val())) {
                 $('#update-cart-item-' + itemId).show('fade', 300);
             } else if (elem.val() == 0) {
@@ -197,10 +198,10 @@ define([
                 type: 'post',
                 dataType: 'json',
                 context: this,
-                beforeSend: function() {
+                beforeSend: function () {
                     elem.attr('disabled', 'disabled');
                 },
-                complete: function() {
+                complete: function () {
                     elem.attr('disabled', null);
                 }
             })
@@ -226,13 +227,14 @@ define([
          *
          * @private
          */
-        _calcHeight: function() {
+        _calcHeight: function () {
             var self = this,
                 height = 0,
                 counter = this.options.maxItemsVisible,
                 target = $(this.options.minicart.list);
 
             target.children().each(function () {
+                $(this).collapsible();
                 var outerHeight = $(this).outerHeight();
 
                 if (counter-- > 0) {
diff --git a/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html b/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html
index 9aedd4e7ffeebb46fbf852252537e59aea1bae6d..e140ebf6d82bdec1843ddaf521bd55ce06d34530 100644
--- a/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html
+++ b/app/code/Magento/Checkout/view/frontend/web/template/minicart/item/default.html
@@ -41,10 +41,10 @@
                         <!-- ko foreach: { data: options, as: 'option' } -->
                         <dt class="label"><!-- ko text: option.label --><!-- /ko --></dt>
                         <dd class="values">
-                            <!-- ko if: Array.isArray(option) -->
+                            <!-- ko if: Array.isArray(option.value) -->
                                 <span data-bind="html: option.value.join('<br>')"></span>
                             <!-- /ko -->
-                            <!-- ko ifnot: Array.isArray(option) -->
+                            <!-- ko ifnot: Array.isArray(option.value) -->
                                 <span data-bind="html: option.value"></span>
                             <!-- /ko -->
                         </dd>
diff --git a/app/code/Magento/Rule/Block/Editable.php b/app/code/Magento/Rule/Block/Editable.php
index 9a69bb0a5f40533f861b45e2247d5ad4fc6cc656..7c4f42037a12c3a48f6969824ec66fcf85e3d889 100644
--- a/app/code/Magento/Rule/Block/Editable.php
+++ b/app/code/Magento/Rule/Block/Editable.php
@@ -53,6 +53,8 @@ class Editable extends AbstractBlock implements RendererInterface
                 $element->getName() .
                 '" value="' .
                 $element->getValue() .
+                '" data-form-part="' .
+                $element->getDataFormPart() .
                 '"/> ' .
                 htmlspecialchars(
                     $valueName
diff --git a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
index d429ff09d46622007f447f0ff8a40fa9619fdb6e..5e3bb80d77d0996ed527078f3d63c49a971eb1c7 100644
--- a/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
+++ b/app/code/Magento/Rule/Model/Condition/AbstractCondition.php
@@ -8,6 +8,8 @@
  * Abstract Rule condition data model
  *
  * @method string getOperator()
+ * @method string getFormName()
+ * @method setFormName()
  */
 namespace Magento\Rule\Model\Condition;
 
@@ -496,7 +498,8 @@ abstract class AbstractCondition extends \Magento\Framework\DataObject implement
                 'name' => $this->elementName . '[' . $this->getPrefix() . '][' . $this->getId() . '][type]',
                 'value' => $this->getType(),
                 'no_span' => true,
-                'class' => 'hidden'
+                'class' => 'hidden',
+                'data-form-part' => $this->getFormName()
             ]
         );
     }
@@ -527,7 +530,8 @@ abstract class AbstractCondition extends \Magento\Framework\DataObject implement
                 'name' => $this->elementName . '[' . $this->getPrefix() . '][' . $this->getId() . '][attribute]',
                 'values' => $this->getAttributeSelectOptions(),
                 'value' => $this->getAttribute(),
-                'value_name' => $this->getAttributeName()
+                'value_name' => $this->getAttributeName(),
+                'data_form_part' => $this->getFormName()
             ]
         )->setRenderer(
             $this->_layout->getBlockSingleton('Magento\Rule\Block\Editable')
@@ -567,7 +571,8 @@ abstract class AbstractCondition extends \Magento\Framework\DataObject implement
                 'name' => $elementName,
                 'values' => $options,
                 'value' => $this->getOperator(),
-                'value_name' => $this->getOperatorName()
+                'value_name' => $this->getOperatorName(),
+                'data-form-part' => $this->getFormName()
             ]
         );
         $element->setRenderer($this->_layout->getBlockSingleton('Magento\Rule\Block\Editable'));
@@ -617,6 +622,7 @@ abstract class AbstractCondition extends \Magento\Framework\DataObject implement
             'value_name' => $this->getValueName(),
             'after_element_html' => $this->getValueAfterElementHtml(),
             'explicit_apply' => $this->getExplicitApply(),
+            'data-form-part' => $this->getFormName()
         ];
         if ($this->getInputType() == 'date') {
             // date format intentionally hard-coded
diff --git a/app/code/Magento/Rule/Model/Condition/Combine.php b/app/code/Magento/Rule/Model/Condition/Combine.php
index 2e42b60bd6510e383e7288aebb3b2984a45bf1ce..590e21cfe38b44423f8cd94b7f85e8d6dfaefaf4 100644
--- a/app/code/Magento/Rule/Model/Condition/Combine.php
+++ b/app/code/Magento/Rule/Model/Condition/Combine.php
@@ -97,7 +97,8 @@ class Combine extends AbstractCondition
                 'name' => $this->elementName . '[' . $this->getPrefix() . '][' . $this->getId() . '][aggregator]',
                 'values' => $this->getAggregatorSelectOptions(),
                 'value' => $this->getAggregator(),
-                'value_name' => $this->getAggregatorName()
+                'value_name' => $this->getAggregatorName(),
+                'data-form-part' => $this->getFormName()
             ]
         )->setRenderer(
             $this->_layout->getBlockSingleton('Magento\Rule\Block\Editable')
@@ -268,7 +269,8 @@ class Combine extends AbstractCondition
             [
                 'name' => $this->elementName . '[' . $this->getPrefix() . '][' . $this->getId() . '][new_child]',
                 'values' => $this->getNewChildSelectOptions(),
-                'value_name' => $this->getNewChildName()
+                'value_name' => $this->getNewChildName(),
+                'data-form-part' => $this->getFormName()
             ]
         )->setRenderer(
             $this->_layout->getBlockSingleton('Magento\Rule\Block\Newchild')
diff --git a/app/code/Magento/Rule/Model/ResourceModel/AbstractResource.php b/app/code/Magento/Rule/Model/ResourceModel/AbstractResource.php
index 0e92eb3ffe60bcd6a9c141df6149341a95293908..fbf8fe169549b524f9cd7dfdf61068e23a39de68 100644
--- a/app/code/Magento/Rule/Model/ResourceModel/AbstractResource.php
+++ b/app/code/Magento/Rule/Model/ResourceModel/AbstractResource.php
@@ -43,24 +43,27 @@ abstract class AbstractResource extends \Magento\Framework\Model\ResourceModel\D
      */
     public function _beforeSave(\Magento\Framework\Model\AbstractModel $object)
     {
-        $fromDate = $object->getData('from_date');
-        if ($fromDate instanceof \DateTime) {
-            $object->setFromDate($fromDate->format('Y-m-d H:i:s'));
-        } elseif (!is_string($fromDate) || empty($fromDate)) {
-            $object->setFromDate(null);
-        }
-
-        $toDate = $object->getData('to_date');
-        if ($toDate instanceof \DateTime) {
-            $object->setToDate($toDate->format('Y-m-d H:i:s'));
-        } elseif (!is_string($toDate) || empty($toDate)) {
-            $object->setToDate(null);
-        }
-
+        $this->resolveDate($object, 'from_date');
+        $this->resolveDate($object, 'to_date');
         parent::_beforeSave($object);
         return $this;
     }
 
+    /**
+     * @param \Magento\Framework\Model\AbstractModel $object
+     * @param string $dateIdentifier
+     * @return void
+     */
+    private function resolveDate(\Magento\Framework\Model\AbstractModel $object, $dateIdentifier)
+    {
+        $date = $object->getData($dateIdentifier);
+        if ($date instanceof \DateTime) {
+            $object->setData($dateIdentifier, $date->format('Y-m-d H:i:s'));
+        } elseif (!is_string($date) || empty($date)) {
+            $object->setData($dateIdentifier, null);
+        }
+    }
+
     /**
      * Bind specified rules to entities
      *
diff --git a/app/code/Magento/Ui/Component/Layout/Tabs.php b/app/code/Magento/Ui/Component/Layout/Tabs.php
index 97a1521c9f3702f8b249b1c8b4fe9b25dafcdfd7..2afd2afdc6e53adc815b600d674f352a2bef7d9a 100644
--- a/app/code/Magento/Ui/Component/Layout/Tabs.php
+++ b/app/code/Magento/Ui/Component/Layout/Tabs.php
@@ -144,9 +144,16 @@ class Tabs extends \Magento\Framework\View\Layout\Generic implements LayoutInter
 
             $tabComponent = $this->createTabComponent($childComponent, $name);
 
+            if (isset($structure[$name]['dataScope']) && $structure[$name]['dataScope']) {
+                $dataScope = $structure[$name]['dataScope'];
+                unset($structure[$name]['dataScope']);
+            } else {
+                $dataScope = 'data.' . $name;
+            }
+
             $childrenAreas[$name] = [
                 'type' => $tabComponent->getComponentName(),
-                'dataScope' => 'data.' . $name,
+                'dataScope' => $dataScope,
                 'config' => $config,
                 'insertTo' => [
                     $this->namespace . '.sections' => [
diff --git a/app/code/Magento/Ui/view/base/web/js/form/adapter.js b/app/code/Magento/Ui/view/base/web/js/form/adapter.js
index 4406a6395628b847be1a59f4bee8bf6dac17dbc5..26634588725d53103629f8818f1dd49fbdd0c8c9 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/adapter.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/adapter.js
@@ -9,9 +9,10 @@ define([
     'use strict';
 
     var buttons = {
-            'reset':            '#reset',
-            'save':             '#save',
-            'saveAndContinue':  '#save_and_continue'
+        'reset':            '#reset',
+        'save':             "#save",
+        'saveAndContinue':  '#save_and_continue',
+        'saveAndApply':     '#save_and_apply'
         },
         selectorPrefix = '',
         eventPrefix;
diff --git a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js
index 0c4a3a592edf440e8e1992fa445def8311ee2e74..a4851f9511ce02dbe59dc768b93f89655f62b3aa 100755
--- a/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/element/abstract.js
@@ -6,9 +6,10 @@
 define([
     'underscore',
     'mageUtils',
+    'uiLayout',
     'uiElement',
     'Magento_Ui/js/lib/validation/validator'
-], function (_, utils, Element, validator) {
+], function (_, utils, layout, Element, validator) {
     'use strict';
 
     return Element.extend({
@@ -29,7 +30,12 @@ define([
             notice: '',
             customScope: '',
             additionalClasses: {},
-
+            switcherConfig: {
+                component: 'Magento_Ui/js/form/switcher',
+                name: '${ $.name }_switcher',
+                target: '${ $.name }',
+                property: 'value'
+            },
             listens: {
                 visible: 'setPreview',
                 '${ $.provider }:data.reset': 'reset',
@@ -51,7 +57,8 @@ define([
 
             this._super()
                 .setInitialValue()
-                ._setClasses();
+                ._setClasses()
+                .initSwicher();
 
             return this;
         },
@@ -98,6 +105,19 @@ define([
             return this;
         },
 
+        /**
+         * Initializes switcher element instance.
+         *
+         * @returns {Abstract} Chainable.
+         */
+        initSwicher: function () {
+            if (this.switcherConfig.enabled) {
+                layout([this.switcherConfig]);
+            }
+
+            return this;
+        },
+
         /**
          * Sets initial value of the element and subscribes to it's changes.
          *
@@ -172,6 +192,76 @@ define([
             return this;
         },
 
+        /**
+         * Show element.
+         *
+         * @returns {Abstract} Chainable.
+         */
+        show: function () {
+            this.visible(true);
+
+            return this;
+        },
+
+        /**
+         * Hide element.
+         *
+         * @returns {Abstract} Chainable.
+         */
+        hide: function () {
+            this.visible(false);
+
+            return this;
+        },
+
+        /**
+         * Disable element.
+         *
+         * @returns {Abstract} Chainable.
+         */
+        disable: function() {
+            this.disabled(true);
+
+            return this;
+        },
+
+        /**
+         * Enable element.
+         *
+         * @returns {Abstract} Chainable.
+         */
+        enable: function() {
+            this.disabled(false);
+
+            return this;
+        },
+
+        /**
+         *
+         * @param {(String|Object)} rule
+         * @param {(Object|Boolean)} [options]
+         * @returns {Abstract} Chainable.
+         */
+        setValidation: function (rule, options) {
+            var rules =  utils.copy(this.validation),
+                changed;
+
+            if (_.isObject(rule)) {
+                _.extend(this.validation, rule)
+            } else {
+                this.validation[rule] = options;
+            }
+
+            changed = utils.compare(rules, this.validation).equal;
+
+            if (changed) {
+                this.required(!!rules['required-entry']);
+                this.validate();
+            }
+
+            return this;
+        },
+
         /**
          * Returnes unwrapped preview observable.
          *
diff --git a/app/code/Magento/Ui/view/base/web/js/form/form.js b/app/code/Magento/Ui/view/base/web/js/form/form.js
index 54d5b6a9db574e88a7b15a4f0ab82c0e2250b6eb..6452789df6e254ff3c4df20240228cfc765ca401 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/form.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/form.js
@@ -91,7 +91,8 @@ define([
             adapter.on({
                 'reset': this.reset.bind(this),
                 'save': this.save.bind(this, true, {}),
-                'saveAndContinue': this.save.bind(this, false, {})
+                'saveAndContinue': this.save.bind(this, false, {}),
+                'saveAndApply': this.saveAndApply.bind(this, true, {})
             }, this.selectorPrefix, this.eventPrefix);
 
             return this;
@@ -187,6 +188,7 @@ define([
             this.source.trigger('data.validate');
         },
 
+
         /**
          * Trigger reset form data.
          */
@@ -194,6 +196,18 @@ define([
             this.source.trigger('data.reset');
         },
 
+        /**
+         * Save form and apply data
+         */
+        saveAndApply: function (redirect) {
+            this.validate();
+
+            if (!this.source.get('params.invalid')) {
+                this.source.set('data.auto_apply', 1);
+                this.submit(redirect);
+            }
+        },
+
         /**
          * Trigger overload form data.
          */
diff --git a/app/code/Magento/Ui/view/base/web/js/form/switcher.js b/app/code/Magento/Ui/view/base/web/js/form/switcher.js
new file mode 100644
index 0000000000000000000000000000000000000000..98586b170c79dd974707ac4fcad60dee6a0ac502
--- /dev/null
+++ b/app/code/Magento/Ui/view/base/web/js/form/switcher.js
@@ -0,0 +1,109 @@
+define([
+    'underscore',
+    'uiRegistry',
+    'uiClass'
+], function (_, registry, Class) {
+    'use strict';
+
+    return Class.extend({
+        defaults: {
+            rules: []
+        },
+
+        /**
+         * Initializes instance of a DataSwitcher.
+         *
+         * @returns {DataSwitcher} Chainable.
+         */
+        initialize: function () {
+            this._super()
+                .initRules();
+
+            return this;
+        },
+
+        /**
+         *
+         * @returns {DataSwitcher} Chainable.
+         */
+        initRules: function () {
+            this.rules.forEach(this.initRule, this);
+
+            return this;
+        },
+
+        /**
+         *
+         * @param {Object} rule - Rule definition.
+         * @returns {DataSwitcher} Chainable.
+         */
+        initRule: function (rule) {
+            var handler = this.onValueChange.bind(this, rule);
+
+            if (!rule.target) {
+                rule.target = this.target;
+            }
+
+            if (!rule.property) {
+                rule.property = this.property;
+            }
+
+            registry.get(rule.target, function (target) {
+                this.applyRule(rule, target.get(rule.property));
+                target.on(rule.property, handler);
+            }.bind(this));
+
+            return this;
+        },
+
+        /**
+         *
+         * @param {Object} rule - Rule definition.
+         * @returns {DataSwitcher} Chainable.
+         */
+        addRule: function (rule) {
+            this.rules.push(rule);
+            this.initRule(rule);
+
+            return this;
+        },
+
+        /**
+         *
+         * @param {Object} rule - Rule object.
+         * @param {*} value - Current value associated with a rule.
+         */
+        applyRule: function (rule, value) {
+            var actions = rule.actions;
+
+            if (rule.value !== value) {
+                return;
+            } else if (rule.strict && rule.value !== value) {
+                return;
+            }
+
+            actions.forEach(this.applyAction, this);
+        },
+
+        /**
+         *
+         * @param {Object} action - Action object.
+         */
+        applyAction: function (action) {
+            registry.get(action.target, function (target) {
+                var callback = target[action.callback];
+
+                callback.apply(target, action.params || []);
+            });
+        },
+
+        /**
+         *
+         * @param {Object} rule - Rules object.
+         * @param {*} value - Current value associated with a rule.
+         */
+        onValueChange: function (rule, value) {
+            this.applyRule(rule, value);
+        }
+    });
+});
diff --git a/app/etc/di.xml b/app/etc/di.xml
index dd65652634a3ee87d4811a2aa7e401fc74fbb5a7..7f28ed45c5e273b013b6ad1ddc0fb978d2a7fb0e 100755
--- a/app/etc/di.xml
+++ b/app/etc/di.xml
@@ -1156,4 +1156,16 @@
             </argument>
         </arguments>
     </type>
+    <type name="Magento\Framework\Model\OrchestratorPool">
+        <arguments>
+            <argument name="operations" xsi:type="array">
+                <item name="default" xsi:type="array">
+                    <item name="read" xsi:type="object">Magento\Framework\Model\Operation\Read</item>
+                    <item name="create" xsi:type="object">Magento\Framework\Model\Operation\Write\Create</item>
+                    <item name="update" xsi:type="object">Magento\Framework\Model\Operation\Write\Update</item>
+                    <item name="delete" xsi:type="object">Magento\Framework\Model\Operation\Write\Delete</item>
+                </item>
+            </argument>
+        </arguments>
+    </type>
 </config>
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.php
index 61f1337eb849692efef46e0d488576be4b61ead4..1f4cfa2a52298182016495e56ce32d5255452bab 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.php
@@ -6,14 +6,14 @@
 
 namespace Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit;
 
-use Magento\Backend\Test\Block\Widget\FormTabs;
+use \Magento\Ui\Test\Block\Adminhtml\FormSections;
 use Magento\Mtf\Client\Element\SimpleElement;
 use Magento\Mtf\Fixture\FixtureInterface;
 
 /**
  * Form for creation of a Catalog Price Rule.
  */
-class PromoForm extends FormTabs
+class PromoForm extends FormSections
 {
     /**
      * Fill form with tabs.
@@ -21,15 +21,15 @@ class PromoForm extends FormTabs
      * @param FixtureInterface $fixture
      * @param SimpleElement $element
      * @param array $replace
-     * @return $this|FormTabs
+     * @return $this
      */
     public function fill(FixtureInterface $fixture, SimpleElement $element = null, array $replace = null)
     {
-        $tabs = $this->getFixtureFieldsByContainers($fixture);
+        $sections = $this->getFixtureFieldsByContainers($fixture);
         if ($replace) {
-            $tabs = $this->prepareData($tabs, $replace);
+            $sections = $this->prepareData($sections, $replace);
         }
-        $this->fillTabs($tabs, $element);
+        return $this->fillContainers($sections, $element);
     }
 
     /**
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml
index 1b940ba5bab4e4f1d33b46c4bdb110b0aa4ec264..6e54935e8323e6a731922e728de8ba88237e029b 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/PromoForm.xml
@@ -5,29 +5,29 @@
  * See COPYING.txt for license details.
  */
 -->
-<tabs>
+<sections>
     <rule_information>
-        <class>\Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Tab\RuleInformation</class>
-        <selector>#promo_catalog_edit_tabs_main_section</selector>
-        <strategy>css selector</strategy>
+        <class>\Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Section\RuleInformation</class>
+        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::input[@name='name']]</selector>
+        <strategy>xpath</strategy>
         <fields>
             <is_active>
                 <input>select</input>
             </is_active>
             <website_ids>
-                <selector>[name='website_ids[]']</selector>
+                <selector>[name='website_ids']</selector>
                 <input>multiselect</input>
             </website_ids>
             <customer_group_ids>
-                <selector>[name='customer_group_ids[]']</selector>
+                <selector>[name='customer_group_ids']</selector>
                 <input>multiselect</input>
             </customer_group_ids>
         </fields>
     </rule_information>
     <conditions>
-        <class>Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Tab\Conditions</class>
-        <selector>#promo_catalog_edit_tabs_conditions_section</selector>
-        <strategy>css selector</strategy>
+        <class>\Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Section\Conditions</class>
+        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::div[@class='rule-tree']]</selector>
+        <strategy>xpath</strategy>
         <fields>
             <conditions>
                 <selector>#rule_conditions_fieldset</selector>
@@ -36,13 +36,13 @@
         </fields>
     </conditions>
     <actions>
-        <class>\Magento\Backend\Test\Block\Widget\Tab</class>
-        <selector>#promo_catalog_edit_tabs_actions_section</selector>
-        <strategy>css selector</strategy>
+        <class>\Magento\Ui\Test\Block\Adminhtml\Section</class>
+        <selector>//div[contains(@class,'admin__collapsible-block-wrapper')][descendant::select[@name='simple_action']]</selector>
+        <strategy>xpath</strategy>
         <fields>
             <simple_action>
                 <input>select</input>
             </simple_action>
         </fields>
     </actions>
-</tabs>
+</sections>
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Tab/Conditions.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Section/Conditions.php
similarity index 87%
rename from dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Tab/Conditions.php
rename to dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Section/Conditions.php
index 049cde37bf28979b6a34c01448fe9d70eada3c44..8a2bea37714bfeb077e4048bfa51ff8655e5aba2 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Tab/Conditions.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Section/Conditions.php
@@ -3,17 +3,16 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
-namespace Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Tab;
+namespace Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Section;
 
 use Magento\Catalog\Test\Fixture\CatalogProductAttribute;
 use Magento\Mtf\Client\Locator;
-use Magento\Backend\Test\Block\Widget\Tab;
+use Magento\Ui\Test\Block\Adminhtml\Section;
 
 /**
- * Form Tab for specifying catalog price rule conditions.
+ * Form section for specifying catalog price rule conditions.
  */
-class Conditions extends Tab
+class Conditions extends Section
 {
     /**
      * Add button.
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Tab/RuleInformation.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Section/RuleInformation.php
similarity index 85%
rename from dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Tab/RuleInformation.php
rename to dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Section/RuleInformation.php
index e4beb9105661c5c6c1e8017c7908869e2c1a3b07..d56cbf0b0b7bd43a53157cdd835a40e643142143 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Tab/RuleInformation.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Block/Adminhtml/Promo/Catalog/Edit/Section/RuleInformation.php
@@ -3,16 +3,15 @@
  * Copyright © 2015 Magento. All rights reserved.
  * See COPYING.txt for license details.
  */
-
-namespace Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Tab;
+namespace Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Section;
 
 use Magento\Customer\Test\Fixture\CustomerGroup;
-use Magento\Backend\Test\Block\Widget\Tab;
+use Magento\Ui\Test\Block\Adminhtml\Section;
 
 /**
- * Rule Information tab.
+ * Rule Information section.
  */
-class RuleInformation extends Tab
+class RuleInformation extends Section
 {
     /**
      * Locator for Customer Group element.
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleInGrid.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleInGrid.php
index a6a6ad91f07f7e0ce8e82ba8710d99c432d77ea9..32fc3fe4fd0c7ed9434f88d45e3fcfb595faab6d 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleInGrid.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertCatalogPriceRuleInGrid.php
@@ -15,6 +15,12 @@ use Magento\Mtf\Constraint\AbstractConstraint;
  */
 class AssertCatalogPriceRuleInGrid extends AbstractConstraint
 {
+    /**
+     * Fields used to filter rows in the grid.
+     * @var array
+     */
+    protected $fieldsToFilter = ['name', 'is_active'];
+
     /**
      * Assert that data in grid on Catalog Price Rules page according to fixture
      *
@@ -31,10 +37,11 @@ class AssertCatalogPriceRuleInGrid extends AbstractConstraint
         $data = ($catalogPriceRuleOriginal === null)
             ? $catalogPriceRule->getData()
             : array_merge($catalogPriceRuleOriginal->getData(), $catalogPriceRule->getData());
-        $filter = [
-            'name' => $data['name'],
-            'is_active' => $data['is_active'],
-        ];
+
+        $filter = [];
+        foreach ($this->fieldsToFilter as $field) {
+            $filter[$field] = $data[$field];
+        }
         //add ruleWebsite to filter if there is one
         if ($catalogPriceRule->getWebsiteIds() != null) {
             $ruleWebsite = $catalogPriceRule->getWebsiteIds();
diff --git a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertProductAttributeIsUsedPromoRules.php b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertProductAttributeIsUsedPromoRules.php
index 89b72240318f5d7da2592cd1b2dce55f2ab8baf1..d144df64e748b50a98fc5ff7ddc77b43ba1df9ba 100644
--- a/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertProductAttributeIsUsedPromoRules.php
+++ b/dev/tests/functional/tests/app/Magento/CatalogRule/Test/Constraint/AssertProductAttributeIsUsedPromoRules.php
@@ -8,12 +8,12 @@ namespace Magento\CatalogRule\Test\Constraint;
 
 use Magento\Mtf\Constraint\AbstractConstraint;
 use Magento\Catalog\Test\Fixture\CatalogProductAttribute;
-use Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Tab\Conditions;
+use Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Section\Conditions;
 use Magento\CatalogRule\Test\Page\Adminhtml\CatalogRuleNew;
 use Magento\CatalogRule\Test\Page\Adminhtml\CatalogRuleIndex;
 
 /**
- * Create a Catalog Price Rules and check whether this attribute visible in Dropdown on Conditions tab.
+ * Create a Catalog Price Rules and check whether this attribute visible in Dropdown in Conditions section.
  */
 class AssertProductAttributeIsUsedPromoRules extends AbstractConstraint
 {
@@ -32,12 +32,12 @@ class AssertProductAttributeIsUsedPromoRules extends AbstractConstraint
     ) {
         $catalogRuleIndex->open();
         $catalogRuleIndex->getGridPageActions()->addNew();
-        $catalogRuleNew->getEditForm()->openTab('conditions');
+        $catalogRuleNew->getEditForm()->openSection('conditions');
 
-        /** @var Conditions $conditionsTab */
-        $conditionsTab = $catalogRuleNew->getEditForm()->getTab('conditions');
+        /** @var Conditions $conditionsSection */
+        $conditionsSection = $catalogRuleNew->getEditForm()->getSection('conditions');
         \PHPUnit_Framework_Assert::assertTrue(
-            $conditionsTab->isAttributeInConditions($attribute),
+            $conditionsSection->isAttributeInConditions($attribute),
             'Product attribute can\'t be used on promo rules conditions.'
         );
     }
diff --git a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupOnCatalogPriceRuleForm.php b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupOnCatalogPriceRuleForm.php
index 15fac430dc6855fd60efe6d53e38f54d32bd58e3..74a176c341203072100dd70f1f4cef2203792d2c 100644
--- a/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupOnCatalogPriceRuleForm.php
+++ b/dev/tests/functional/tests/app/Magento/Customer/Test/Constraint/AssertCustomerGroupOnCatalogPriceRuleForm.php
@@ -10,7 +10,7 @@ use Magento\CatalogRule\Test\Page\Adminhtml\CatalogRuleIndex;
 use Magento\CatalogRule\Test\Page\Adminhtml\CatalogRuleNew;
 use Magento\Customer\Test\Fixture\CustomerGroup;
 use Magento\Mtf\Constraint\AbstractConstraint;
-use Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Tab\RuleInformation;
+use Magento\CatalogRule\Test\Block\Adminhtml\Promo\Catalog\Edit\Section\RuleInformation;
 
 /**
  * Assert that customer group find on catalog price rule page.
@@ -34,12 +34,13 @@ class AssertCustomerGroupOnCatalogPriceRuleForm extends AbstractConstraint
         $catalogRuleIndex->getGridPageActions()->addNew();
         $catalogRuleNew->getEditForm()->openTab('rule_information');
 
-        /** @var RuleInformation $ruleInformationTab */
-        $ruleInformationTab = $catalogRuleNew->getEditForm()->getTab('rule_information');
+        /** @var RuleInformation $ruleInformationSection */
+        $ruleInformationSection = $catalogRuleNew->getEditForm()->getSection('rule_information');
         \PHPUnit_Framework_Assert::assertTrue(
-            $ruleInformationTab->isVisibleCustomerGroup($customerGroup),
+            $ruleInformationSection->isVisibleCustomerGroup($customerGroup),
             "Customer group {$customerGroup->getCustomerGroupCode()} not in catalog price rule page."
         );
+
     }
 
     /**
diff --git a/dev/tests/integration/testsuite/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/MainTest.php b/dev/tests/integration/testsuite/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/MainTest.php
deleted file mode 100644
index e8218c041f68fabc8fab048b18cea3c06495e0e5..0000000000000000000000000000000000000000
--- a/dev/tests/integration/testsuite/Magento/CatalogRule/Block/Adminhtml/Promo/Catalog/Edit/Tab/MainTest.php
+++ /dev/null
@@ -1,47 +0,0 @@
-<?php
-/**
- * Copyright © 2015 Magento. All rights reserved.
- * See COPYING.txt for license details.
- */
-namespace Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab;
-
-/**
- * Test class for \Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab\Main
- *
- * @magentoAppArea adminhtml
- */
-class MainTest extends \PHPUnit_Framework_TestCase
-{
-    /**
-     * @magentoAppIsolation enabled
-     */
-    public function testPrepareForm()
-    {
-        /** @var $objectManager \Magento\TestFramework\ObjectManager */
-        $objectManager = \Magento\TestFramework\Helper\Bootstrap::getObjectManager();
-        $objectManager->get(
-            'Magento\Framework\View\DesignInterface'
-        )->setArea(
-            \Magento\Backend\App\Area\FrontNameResolver::AREA_CODE
-        )->setDefaultDesignTheme();
-        $rule = $objectManager->create('Magento\CatalogRule\Model\Rule');
-        $objectManager->get('Magento\Framework\Registry')->register('current_promo_catalog_rule', $rule);
-
-        $block = $objectManager->create('Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab\Main');
-        $block->setLayout($objectManager->create('Magento\Framework\View\Layout'));
-        $prepareFormMethod = new \ReflectionMethod(
-            'Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab\Main',
-            '_prepareForm'
-        );
-        $prepareFormMethod->setAccessible(true);
-        $prepareFormMethod->invoke($block);
-
-        $form = $block->getForm();
-        foreach (['customer_group_ids', 'from_date', 'to_date'] as $id) {
-            $element = $form->getElement($id);
-            $this->assertNotNull($element);
-            $actual = ($id == 'customer_group_ids') ? $element->getValues() : $element->getDateFormat();
-            $this->assertNotEmpty($actual);
-        }
-    }
-}
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 04984323d775479c91698fbed729871fd2d93e2c..134249ed5892769ca18baad76cd4d4f1cbbeb1e4 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
@@ -4129,4 +4129,10 @@ return [
         'Magento\Catalog\Model\ResourceModel\Product\Attribute\Backend\Media',
         'Magento\Catalog\Model\ResourceModel\Product\Gallery'
     ],
+    ['Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab\Actions'],
+    ['Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tab\Main'],
+    ['Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Form'],
+    ['Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Js'],
+    ['Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit\Tabs'],
+    ['Magento\CatalogRule\Block\Adminhtml\Promo\Catalog\Edit']
 ];
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/SearchResult.php b/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/SearchResult.php
index bbc21e655c8769e22ffe1be38c9bfa9f7867bf54..346cee13ea63007602118773d8171df6a6981326 100644
--- a/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/SearchResult.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/DataProvider/SearchResult.php
@@ -14,8 +14,8 @@ use Magento\Framework\Data\Collection\EntityFactoryInterface as EntityFactory;
 use Psr\Log\LoggerInterface as Logger;
 
 /**
- * Class Collection
- * Collection for order related documents to display grids on order view page
+ * Class SearchResult
+ * Generic Search Result
  */
 class SearchResult extends AbstractCollection implements Api\Search\SearchResultInterface
 {