diff --git a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AbstractModifierTest.php b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AbstractModifierTest.php
index 218507d0dd1457c3d1d6fe2cebc49af8da90b195..1bdad7d3147f56e7f9c0d9450030ec08f8abe855 100644
--- a/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AbstractModifierTest.php
+++ b/app/code/Magento/Catalog/Test/Unit/Ui/DataProvider/Product/Form/Modifier/AbstractModifierTest.php
@@ -77,7 +77,7 @@ abstract class AbstractModifierTest extends \PHPUnit_Framework_TestCase
             ->willReturnArgument(1);
         $this->arrayManagerMock->expects($this->any())
             ->method('get')
-            ->willReturnArgument(3);
+            ->willReturnArgument(2);
         $this->arrayManagerMock->expects($this->any())
             ->method('set')
             ->willReturnArgument(1);
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php
index 1418967884a5006ff9e340ec12950bb532d4b867..25280559e543a942949d1a89910f94d306171549 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/AdvancedPricing.php
@@ -122,9 +122,6 @@ class AdvancedPricing extends AbstractModifier
     {
         $this->meta = $meta;
 
-        $this->preparePriceFields(ProductAttributeInterface::CODE_PRICE);
-        $this->preparePriceFields(ProductAttributeInterface::CODE_SPECIAL_PRICE);
-        $this->preparePriceFields(ProductAttributeInterface::CODE_COST);
         $this->specialPriceDataToInline();
         $this->customizeTierPrice();
 
@@ -182,7 +179,7 @@ class AdvancedPricing extends AbstractModifier
         $tierPricePath = $this->getElementArrayPath($this->meta, ProductAttributeInterface::CODE_TIER_PRICE);
 
         if ($tierPricePath) {
-            $this->meta = $this->arrayManager->set(
+            $this->meta = $this->arrayManager->merge(
                 $tierPricePath,
                 $this->meta,
                 $this->getTierPriceStructure($tierPricePath)
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php
index 7ae19a786104878d3c47704a9684ce86c9ba434a..9370390ad7bec3fbb6c5ed0c0e95e4848734acd2 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php
@@ -20,6 +20,7 @@ use Magento\Framework\Api\SearchCriteriaBuilder;
 use Magento\Framework\Api\SortOrderBuilder;
 use Magento\Framework\App\RequestInterface;
 use Magento\Framework\Filter\Translit;
+use Magento\Framework\Stdlib\ArrayManager;
 use Magento\Store\Model\StoreManagerInterface;
 use Magento\Ui\Component\Form\Field;
 use Magento\Ui\Component\Form\Fieldset;
@@ -129,6 +130,11 @@ class Eav extends AbstractModifier
      */
     private $translitFilter;
 
+    /**
+     * @var ArrayManager
+     */
+    private $arrayManager;
+
     /**
      * @var ScopeOverriddenValue
      */
@@ -150,8 +156,6 @@ class Eav extends AbstractModifier
     private $attributesToEliminate;
 
     /**
-     * Initialize dependencies
-     *
      * @param LocatorInterface $locator
      * @param EavValidationRules $eavValidationRules
      * @param Config $eavConfig
@@ -166,6 +170,7 @@ class Eav extends AbstractModifier
      * @param SortOrderBuilder $sortOrderBuilder
      * @param EavAttributeFactory $eavAttributeFactory
      * @param Translit $translitFilter
+     * @param ArrayManager $arrayManager
      * @param ScopeOverriddenValue $scopeOverriddenValue
      * @param array $attributesToDisable
      * @param array $attributesToEliminate
@@ -186,6 +191,7 @@ class Eav extends AbstractModifier
         SortOrderBuilder $sortOrderBuilder,
         EavAttributeFactory $eavAttributeFactory,
         Translit $translitFilter,
+        ArrayManager $arrayManager,
         ScopeOverriddenValue $scopeOverriddenValue,
         $attributesToDisable = [],
         $attributesToEliminate = []
@@ -204,6 +210,7 @@ class Eav extends AbstractModifier
         $this->sortOrderBuilder = $sortOrderBuilder;
         $this->eavAttributeFactory = $eavAttributeFactory;
         $this->translitFilter = $translitFilter;
+        $this->arrayManager = $arrayManager;
         $this->scopeOverriddenValue = $scopeOverriddenValue;
         $this->attributesToDisable = $attributesToDisable;
         $this->attributesToEliminate = $attributesToEliminate;
@@ -239,68 +246,75 @@ class Eav extends AbstractModifier
      * @param string $groupCode
      * @return array
      * @throws \Magento\Framework\Exception\LocalizedException
-     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
-     * @SuppressWarnings(PHPMD.NPathComplexity)
      */
     protected function getAttributesMeta(array $attributes, $groupCode)
     {
         $meta = [];
 
-        foreach ($attributes as $sortKey => $attribute) {
+        foreach ($attributes as $sortOrder => $attribute) {
             if (in_array($attribute->getFrontendInput(), $this->bannedInputTypes)) {
                 continue;
             }
 
-            $code = $attribute->getAttributeCode();
-            if (in_array($code, $this->attributesToEliminate)) {
+            if (in_array($attribute->getAttributeCode(), $this->attributesToEliminate)) {
                 continue;
             }
 
-            $child = $this->setupMetaProperties($attribute);
-            $meta[static::CONTAINER_PREFIX . $code] = [
-                'arguments' => [
-                    'data' => [
-                        'config' => [
-                            'formElement' => 'container',
-                            'componentType' => 'container',
-                            'breakLine' => false,
-                            'label' => __('%1', $attribute->getDefaultFrontendLabel()),
-                            'sortOrder' => $sortKey * self::SORT_ORDER_MULTIPLIER,
-                            'required' => $attribute->getIsRequired(),
-                            'scopeLabel' => $this->getScopeLabel($attribute),
-                        ],
-                    ],
-                ],
-            ];
-
-            if ($attribute->getIsWysiwygEnabled()) {
-                $meta[static::CONTAINER_PREFIX . $code]['arguments']['data']['config']['component'] =
-                    'Magento_Ui/js/form/components/group';
+            if (!($attributeContainer = $this->setupAttributeContainerMeta($attribute))) {
+                continue;
             }
 
-            $child['arguments']['data']['config']['code'] = $code;
-            $child['arguments']['data']['config']['source'] = $groupCode;
-            $child['arguments']['data']['config']['scopeLabel'] = $this->getScopeLabel($attribute);
-            $child['arguments']['data']['config']['globalScope'] = $this->isScopeGlobal($attribute);
-            $child['arguments']['data']['config']['sortOrder'] = $sortKey * self::SORT_ORDER_MULTIPLIER;
+            $attributeContainer = $this->addContainerChildren($attributeContainer, $attribute, $groupCode, $sortOrder);
 
-            if (!isset($child['arguments']['data']['config']['componentType'])) {
-                $child['arguments']['data']['config']['componentType'] = Field::NAME;
-            }
+            $meta[static::CONTAINER_PREFIX . $attribute->getAttributeCode()] = $attributeContainer;
+        }
 
-            if (in_array($code, $this->attributesToDisable)) {
-                $child['arguments']['data']['config']['disabled'] = true;
-            }
-            // TODO: getAttributeModel() should not be used when MAGETWO-48284 is complete
-            $childData = $child['arguments']['data']['config'];
-            if (($rules = $this->eavValidationRules->build($this->getAttributeModel($attribute), $childData))) {
-                $child['arguments']['data']['config']['validation'] = $rules;
-            }
+        return $meta;
+    }
 
-            $meta[static::CONTAINER_PREFIX . $code]['children'][$code] = $child;
+    /**
+     * Add container children
+     *
+     * @param array $attributeContainer
+     * @param ProductAttributeInterface $attribute
+     * @param string $groupCode
+     * @param int $sortOrder
+     * @return array
+     */
+    public function addContainerChildren(
+        array $attributeContainer,
+        ProductAttributeInterface $attribute,
+        $groupCode,
+        $sortOrder
+    ) {
+        foreach ($this->getContainerChildren($attribute, $groupCode, $sortOrder) as $childCode => $child) {
+            $attributeContainer['children'][$childCode] = $child;
         }
 
-        return $meta;
+        $attributeContainer = $this->arrayManager->merge(
+            ltrim(static::META_CONFIG_PATH, ArrayManager::DEFAULT_PATH_DELIMITER),
+            $attributeContainer,
+            ['sortOrder' => $sortOrder * self::SORT_ORDER_MULTIPLIER]
+        );
+
+        return $attributeContainer;
+    }
+
+    /**
+     * Retrieve container child fields
+     *
+     * @param ProductAttributeInterface $attribute
+     * @param string $groupCode
+     * @param int $sortOrder
+     * @return array
+     */
+    public function getContainerChildren(ProductAttributeInterface $attribute, $groupCode, $sortOrder)
+    {
+        if (!($child = $this->setupAttributeMeta($attribute, $groupCode, $sortOrder))) {
+            return [];
+        }
+
+        return [$attribute->getAttributeCode() => $child];
     }
 
     /**
@@ -308,13 +322,18 @@ class Eav extends AbstractModifier
      */
     public function modifyData(array $data)
     {
+        $productId = $this->locator->getProduct()->getId();
+
         /** @var string $groupCode */
         foreach (array_keys($this->getGroups()) as $groupCode) {
+            /** @var ProductAttributeInterface[] $attributes */
             $attributes = !empty($this->getAttributes()[$groupCode]) ? $this->getAttributes()[$groupCode] : [];
 
-            /* @var EavAttribute $attribute */
             foreach ($attributes as $attribute) {
-                $data = $this->setAttributeValueToData($data, $attribute->getAttributeCode());
+                if (null !== ($attributeValue = $this->setupAttributeData($attribute))) {
+                    $data[$productId][self::DATA_SOURCE_DEFAULT][$attribute->getAttributeCode()] = $attributeValue;
+                }
+
             }
         }
 
@@ -455,43 +474,85 @@ class Eav extends AbstractModifier
      * Initial meta setup
      *
      * @param ProductAttributeInterface $attribute
+     * @param string $groupCode
+     * @param int $sortOrder
      * @return array
      * @throws \Magento\Framework\Exception\LocalizedException
+     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
      */
-    protected function setupMetaProperties(ProductAttributeInterface $attribute)
+    public function setupAttributeMeta(ProductAttributeInterface $attribute, $groupCode, $sortOrder)
     {
-        $meta = [
-            'arguments' => [
-                'data' => [
-                    'config' => [
-                        'dataType' => $attribute->getFrontendInput(),
-                        'formElement' => $this->getFormElementsMapValue($attribute->getFrontendInput()),
-                        'visible' => $attribute->getIsVisible(),
-                        'required' => $attribute->getIsRequired(),
-                        'notice' => $attribute->getNote(),
-                        'default' => $attribute->getDefaultValue(),
-                        'label' => __('%1', $attribute->getDefaultFrontendLabel()),
-                    ],
-                ],
-            ],
-        ];
-        foreach ($meta as $key => $value) {
-            if ($value === null) {
-                unset($meta[$key]);
-            }
-        }
+        $configPath = ltrim(static::META_CONFIG_PATH, ArrayManager::DEFAULT_PATH_DELIMITER);
+
+        $meta = $this->arrayManager->set($configPath, [], [
+            'dataType' => $attribute->getFrontendInput(),
+            'formElement' => $this->getFormElementsMapValue($attribute->getFrontendInput()),
+            'visible' => $attribute->getIsVisible(),
+            'required' => $attribute->getIsRequired(),
+            'notice' => $attribute->getNote(),
+            'default' => $attribute->getDefaultValue(),
+            'label' => $attribute->getDefaultFrontendLabel(),
+            'code' => $attribute->getAttributeCode(),
+            'source' => $groupCode,
+            'scopeLabel' => $this->getScopeLabel($attribute),
+            'globalScope' => $this->isScopeGlobal($attribute),
+            'sortOrder' => $sortOrder * self::SORT_ORDER_MULTIPLIER,
+        ]);
 
         // TODO: Refactor to $attribute->getOptions() when MAGETWO-48289 is done
         $attributeModel = $this->getAttributeModel($attribute);
         if ($attributeModel->usesSource()) {
-            $meta['arguments']['data']['config']['options'] = $attributeModel->getSource()->getAllOptions();
+            $meta = $this->arrayManager->merge($configPath, $meta, [
+                'options' => $attributeModel->getSource()->getAllOptions(),
+            ]);
+        }
+
+        if ($this->canDisplayUseDefault($attribute)) {
+            $meta = $this->arrayManager->merge($configPath, $meta, [
+                'service' => [
+                    'template' => 'ui/form/element/helper/service',
+                ]
+            ]);
+        }
+
+        if (!$this->arrayManager->exists($configPath . '/componentType', $meta)) {
+            $meta = $this->arrayManager->merge($configPath, $meta, [
+                'componentType' => Field::NAME,
+            ]);
+        }
+
+        if (in_array($attribute->getAttributeCode(), $this->attributesToDisable)) {
+            $meta = $this->arrayManager->merge($configPath, $meta, [
+                'disabled' => true,
+            ]);
+        }
+
+        // TODO: getAttributeModel() should not be used when MAGETWO-48284 is complete
+        $childData = $this->arrayManager->get($configPath, $meta, []);
+        if (($rules = $this->eavValidationRules->build($this->getAttributeModel($attribute), $childData))) {
+            $meta = $this->arrayManager->merge($configPath, $meta, [
+                'validation' => $rules,
+            ]);
         }
 
-        $meta = $this->addWysiwyg($attribute, $meta);
-        $meta = $this->customizeCheckbox($attribute, $meta);
-        $meta = $this->customizePriceAttribute($attribute, $meta);
         $meta = $this->addUseDefaultValueCheckbox($attribute, $meta);
 
+        switch ($attribute->getFrontendInput()) {
+            case 'boolean':
+                $meta = $this->customizeCheckbox($attribute, $meta);
+                break;
+            case 'textarea':
+                $meta = $this->customizeWysiwyg($attribute, $meta);
+                break;
+            case 'price':
+                $meta = $this->customizePriceAttribute($attribute, $meta);
+                break;
+            case 'gallery':
+                // Gallery attribute is being handled by "Images And Videos Tab"
+                $meta = [];
+                break;
+        }
+
         return $meta;
     }
 
@@ -518,6 +579,60 @@ class Eav extends AbstractModifier
         return $meta;
     }
 
+    /**
+     * Setup attribute container meta
+     *
+     * @param ProductAttributeInterface $attribute
+     * @return array
+     */
+    public function setupAttributeContainerMeta(ProductAttributeInterface $attribute)
+    {
+        $containerMeta = $this->arrayManager->set(
+            'arguments/data/config',
+            [],
+            [
+                'formElement' => 'container',
+                'componentType' => 'container',
+                'breakLine' => false,
+                'label' => $attribute->getDefaultFrontendLabel(),
+                'required' => $attribute->getIsRequired(),
+            ]
+        );
+
+        if ($attribute->getIsWysiwygEnabled()) {
+            $containerMeta = $this->arrayManager->merge(
+                'arguments/data/config',
+                $containerMeta,
+                [
+                    'component' => 'Magento_Ui/js/form/components/group'
+                ]
+            );
+        }
+
+        return $containerMeta;
+    }
+
+    /**
+     * Setup attribute data
+     *
+     * @param ProductAttributeInterface $attribute
+     * @return mixed|null
+     */
+    public function setupAttributeData(ProductAttributeInterface $attribute)
+    {
+        $product = $this->locator->getProduct();
+        $productId = $product->getId();
+        $prevSetId = $this->getPrevSetId();
+        $notUsed = !$prevSetId
+            || ($prevSetId && !in_array($attribute->getAttributeCode(), $this->getPrevSetAttributes()));
+
+        if ($productId && $notUsed) {
+            return $this->getValue($attribute);
+        }
+
+        return null;
+    }
+
     /**
      * Customize checkboxes
      *
@@ -563,7 +678,7 @@ class Eav extends AbstractModifier
      * @param array $meta
      * @return array
      */
-    private function addWysiwyg(ProductAttributeInterface $attribute, array $meta)
+    private function customizeWysiwyg(ProductAttributeInterface $attribute, array $meta)
     {
         if (!$attribute->getIsWysiwygEnabled()) {
             return $meta;
@@ -588,41 +703,18 @@ class Eav extends AbstractModifier
         return isset($valueMap[$value]) ? $valueMap[$value] : $value;
     }
 
-    /**
-     * Set attribute to loaded data
-     *
-     * @param array $data
-     * @param string $attributeCode
-     * @return $this
-     */
-    protected function setAttributeValueToData(array $data, $attributeCode)
-    {
-        $product = $this->locator->getProduct();
-        $productId = $product->getId();
-        $prevSetId = $this->getPrevSetId();
-        $notUsed = !$prevSetId || ($prevSetId && !in_array($attributeCode, $this->getPrevSetAttributes()));
-
-        if ($productId && $notUsed) {
-            if (null !== ($value = $this->getValue($attributeCode))) {
-                $data[$productId][self::DATA_SOURCE_DEFAULT][$attributeCode] = $value;
-            }
-        }
-
-        return $data;
-    }
-
     /**
      * Retrieve attribute value
      *
-     * @param string $attributeCode
+     * @param ProductAttributeInterface $attribute
      * @return mixed
      */
-    protected function getValue($attributeCode)
+    protected function getValue(ProductAttributeInterface $attribute)
     {
         /** @var Product $product */
         $product = $this->locator->getProduct();
 
-        return $product->getData($attributeCode);
+        return $product->getData($attribute->getAttributeCode());
     }
 
     /**
diff --git a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php
index f39c5c69a2be72c7467b62b2ef08218b64d9ca3c..3552ce8a0c20be79186964833e54601c98c275d4 100644
--- a/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php
+++ b/app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Related.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\Catalog\Ui\DataProvider\Product\Form\Modifier;
 
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Catalog\Api\Data\ProductLinkInterface;
 use Magento\Catalog\Api\ProductLinkRepositoryInterface;
 use Magento\Catalog\Api\ProductRepositoryInterface;
 use Magento\Catalog\Model\Locator\LocatorInterface;
@@ -185,18 +187,7 @@ class Related extends AbstractModifier
                     false,
                     $this->locator->getStore()->getId()
                 );
-                $data[$productId]['links'][$dataScope][] = [
-                    'id' => $linkedProduct->getId(),
-                    'thumbnail' => $this->imageHelper->init($linkedProduct, 'product_listing_thumbnail')->getUrl(),
-                    'name' => $linkedProduct->getName(),
-                    'status' => $this->status->getOptionText($linkedProduct->getStatus()),
-                    'attribute_set' => $this->attributeSetRepository
-                        ->get($linkedProduct->getAttributeSetId())
-                        ->getAttributeSetName(),
-                    'sku' => $linkItem->getLinkedProductSku(),
-                    'price' => $linkedProduct->getPrice(),
-                    'position' => $linkItem->getPosition(),
-                ];
+                $data[$productId]['links'][$dataScope][] = $this->fillData($linkedProduct, $linkItem);
             }
         }
 
@@ -206,6 +197,29 @@ class Related extends AbstractModifier
         return $data;
     }
 
+    /**
+     * Prepare data column
+     *
+     * @param ProductInterface $linkedProduct
+     * @param ProductLinkInterface $linkItem
+     * @return array
+     */
+    protected function fillData(ProductInterface $linkedProduct, ProductLinkInterface $linkItem)
+    {
+        return [
+            'id' => $linkedProduct->getId(),
+            'thumbnail' => $this->imageHelper->init($linkedProduct, 'product_listing_thumbnail')->getUrl(),
+            'name' => $linkedProduct->getName(),
+            'status' => $this->status->getOptionText($linkedProduct->getStatus()),
+            'attribute_set' => $this->attributeSetRepository
+                ->get($linkedProduct->getAttributeSetId())
+                ->getAttributeSetName(),
+            'sku' => $linkItem->getLinkedProductSku(),
+            'price' => $linkedProduct->getPrice(),
+            'position' => $linkItem->getPosition(),
+        ];
+    }
+
     /**
      * Retrieve all data scopes
      *
@@ -529,56 +543,66 @@ class Related extends AbstractModifier
                             ],
                         ],
                     ],
-                    'children' => [
-                        'id' => $this->getTextColumn('id', false, 'ID', 0),
-                        'thumbnail' => [
-                            'arguments' => [
-                                'data' => [
-                                    'config' => [
-                                        'componentType' => Field::NAME,
-                                        'formElement' => Input::NAME,
-                                        'elementTmpl' => 'ui/dynamic-rows/cells/thumbnail',
-                                        'dataType' => Text::NAME,
-                                        'dataScope' => 'thumbnail',
-                                        'fit' => true,
-                                        'label' => __('Thumbnail'),
-                                        'sortOrder' => 10,
-                                    ],
-                                ],
-                            ],
+                    'children' => $this->fillMeta(),
+                ],
+            ],
+        ];
+    }
+
+    /**
+     * Retrieve meta column
+     *
+     * @return array
+     */
+    protected function fillMeta()
+    {
+        return [
+            'id' => $this->getTextColumn('id', false, __('ID'), 0),
+            'thumbnail' => [
+                'arguments' => [
+                    'data' => [
+                        'config' => [
+                            'componentType' => Field::NAME,
+                            'formElement' => Input::NAME,
+                            'elementTmpl' => 'ui/dynamic-rows/cells/thumbnail',
+                            'dataType' => Text::NAME,
+                            'dataScope' => 'thumbnail',
+                            'fit' => true,
+                            'label' => __('Thumbnail'),
+                            'sortOrder' => 10,
                         ],
-                        'name' => $this->getTextColumn('name', false, 'Name', 20),
-                        'status' => $this->getTextColumn('status', true, 'Status', 30),
-                        'attribute_set' => $this->getTextColumn('attribute_set', false, 'Attribute Set', 40),
-                        'sku' => $this->getTextColumn('sku', true, 'SKU', 50),
-                        'price' => $this->getTextColumn('price', true, 'Price', 60),
-                        'actionDelete' => [
-                            'arguments' => [
-                                'data' => [
-                                    'config' => [
-                                        'additionalClasses' => 'data-grid-actions-cell',
-                                        'componentType' => 'actionDelete',
-                                        'dataType' => Text::NAME,
-                                        'label' => __('Actions'),
-                                        'sortOrder' => 70,
-                                        'fit' => true,
-                                    ],
-                                ],
-                            ],
+                    ],
+                ],
+            ],
+            'name' => $this->getTextColumn('name', false, __('Name'), 20),
+            'status' => $this->getTextColumn('status', true, __('Status'), 30),
+            'attribute_set' => $this->getTextColumn('attribute_set', false, __('Attribute Set'), 40),
+            'sku' => $this->getTextColumn('sku', true, __('SKU'), 50),
+            'price' => $this->getTextColumn('price', true, __('Price'), 60),
+            'actionDelete' => [
+                'arguments' => [
+                    'data' => [
+                        'config' => [
+                            'additionalClasses' => 'data-grid-actions-cell',
+                            'componentType' => 'actionDelete',
+                            'dataType' => Text::NAME,
+                            'label' => __('Actions'),
+                            'sortOrder' => 70,
+                            'fit' => true,
                         ],
-                        'position' => [
-                            'arguments' => [
-                                'data' => [
-                                    'config' => [
-                                        'dataType' => Number::NAME,
-                                        'formElement' => Input::NAME,
-                                        'componentType' => Field::NAME,
-                                        'dataScope' => 'position',
-                                        'sortOrder' => 80,
-                                        'visible' => false,
-                                    ],
-                                ],
-                            ],
+                    ],
+                ],
+            ],
+            'position' => [
+                'arguments' => [
+                    'data' => [
+                        'config' => [
+                            'dataType' => Number::NAME,
+                            'formElement' => Input::NAME,
+                            'componentType' => Field::NAME,
+                            'dataScope' => 'position',
+                            'sortOrder' => 80,
+                            'visible' => false,
                         ],
                     ],
                 ],
@@ -591,11 +615,11 @@ class Related extends AbstractModifier
      *
      * @param string $dataScope
      * @param bool $fit
-     * @param string $label
+     * @param Phrase $label
      * @param int $sortOrder
      * @return array
      */
-    protected function getTextColumn($dataScope, $fit, $label, $sortOrder)
+    protected function getTextColumn($dataScope, $fit, Phrase $label, $sortOrder)
     {
         $column = [
             'arguments' => [
diff --git a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php
index 24396c0df730735077ca1671392396168625025b..35b9be0305019f09ede3048ae2e5a38cebf7eb4d 100644
--- a/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php
+++ b/app/code/Magento/GroupedProduct/Ui/DataProvider/Product/Form/Modifier/Grouped.php
@@ -5,6 +5,8 @@
  */
 namespace Magento\GroupedProduct\Ui\DataProvider\Product\Form\Modifier;
 
+use Magento\Catalog\Api\Data\ProductInterface;
+use Magento\Catalog\Api\Data\ProductLinkInterface;
 use Magento\Catalog\Model\Locator\LocatorInterface;
 use Magento\Catalog\Ui\DataProvider\Product\Form\Modifier\AbstractModifier;
 use Magento\Framework\Phrase;
@@ -127,8 +129,6 @@ class Grouped extends AbstractModifier
         $modelId = $product->getId();
         if ($modelId) {
             $storeId = $this->locator->getStore()->getId();
-            /** @var \Magento\Framework\Currency $currency */
-            $currency = $this->localeCurrency->getCurrency($this->locator->getBaseCurrencyCode());
             $data[$product->getId()]['links'][self::LINK_TYPE] = [];
             foreach ($this->productLinkRepository->getList($product) as $linkItem) {
                 if ($linkItem->getLinkType() !== self::LINK_TYPE) {
@@ -136,26 +136,41 @@ class Grouped extends AbstractModifier
                 }
                 /** @var \Magento\Catalog\Api\Data\ProductInterface $linkedProduct */
                 $linkedProduct = $this->productRepository->get($linkItem->getLinkedProductSku(), false, $storeId);
-                $data[$modelId]['links'][self::LINK_TYPE][] = [
-                    'id' => $linkedProduct->getId(),
-                    'name' => $linkedProduct->getName(),
-                    'sku' => $linkItem->getLinkedProductSku(),
-                    'price' => $currency->toCurrency(sprintf("%f", $linkedProduct->getPrice())),
-                    'qty' => $linkItem->getExtensionAttributes()->getQty(),
-                    'position' => $linkItem->getPosition(),
-                    'thumbnail' => $this->imageHelper->init($linkedProduct, 'product_listing_thumbnail')->getUrl(),
-                    'type_id' => $linkedProduct->getTypeId(),
-                    'status' => $this->status->getOptionText($linkedProduct->getStatus()),
-                    'attribute_set' => $this->attributeSetRepository
-                        ->get($linkedProduct->getAttributeSetId())
-                        ->getAttributeSetName(),
-                ];
+                $data[$modelId]['links'][self::LINK_TYPE][] = $this->fillData($linkedProduct, $linkItem);
             }
             $data[$modelId][self::DATA_SOURCE_DEFAULT]['current_store_id'] = $storeId;
         }
         return $data;
     }
 
+    /**
+     * Fill data column
+     *
+     * @param ProductInterface $linkedProduct
+     * @param ProductLinkInterface $linkItem
+     * @return array
+     */
+    protected function fillData(ProductInterface $linkedProduct, ProductLinkInterface $linkItem)
+    {
+        /** @var \Magento\Framework\Currency $currency */
+        $currency = $this->localeCurrency->getCurrency($this->locator->getBaseCurrencyCode());
+
+        return [
+            'id' => $linkedProduct->getId(),
+            'name' => $linkedProduct->getName(),
+            'sku' => $linkItem->getLinkedProductSku(),
+            'price' => $currency->toCurrency(sprintf("%f", $linkedProduct->getPrice())),
+            'qty' => $linkItem->getExtensionAttributes()->getQty(),
+            'position' => $linkItem->getPosition(),
+            'thumbnail' => $this->imageHelper->init($linkedProduct, 'product_listing_thumbnail')->getUrl(),
+            'type_id' => $linkedProduct->getTypeId(),
+            'status' => $this->status->getOptionText($linkedProduct->getStatus()),
+            'attribute_set' => $this->attributeSetRepository
+                ->get($linkedProduct->getAttributeSetId())
+                ->getAttributeSetName(),
+        ];
+    }
+
     /**
      * {@inheritdoc}
      */
@@ -452,74 +467,84 @@ class Grouped extends AbstractModifier
                         ],
                     ],
                 ],
-                'children' => [
-                    'id' => $this->getTextColumn('id', true, __('ID'), 10),
-                    'thumbnail' => [
-                        'arguments' => [
-                            'data' => [
-                                'config' => [
-                                    'componentType' => Form\Field::NAME,
-                                    'formElement' => Form\Element\Input::NAME,
-                                    'elementTmpl' => 'ui/dynamic-rows/cells/thumbnail',
-                                    'dataType' => Form\Element\DataType\Text::NAME,
-                                    'dataScope' => 'thumbnail',
-                                    'fit' => true,
-                                    'label' => __('Thumbnail'),
-                                    'sortOrder' => 20,
-                                ],
-                            ],
+                'children' => $this->fillMeta(),
+            ],
+        ];
+    }
+
+    /**
+     * Fill meta columns
+     *
+     * @return array
+     */
+    protected function fillMeta()
+    {
+        return [
+            'id' => $this->getTextColumn('id', true, __('ID'), 10),
+            'thumbnail' => [
+                'arguments' => [
+                    'data' => [
+                        'config' => [
+                            'componentType' => Form\Field::NAME,
+                            'formElement' => Form\Element\Input::NAME,
+                            'elementTmpl' => 'ui/dynamic-rows/cells/thumbnail',
+                            'dataType' => Form\Element\DataType\Text::NAME,
+                            'dataScope' => 'thumbnail',
+                            'fit' => true,
+                            'label' => __('Thumbnail'),
+                            'sortOrder' => 20,
                         ],
                     ],
-                    'name' => $this->getTextColumn('name', false, __('Name'), 30),
-                    'attribute_set' => $this->getTextColumn('attribute_set', false, __('Attribute Set'), 40),
-                    'status' => $this->getTextColumn('status', true, __('Status'), 50),
-                    'sku' => $this->getTextColumn('sku', false, __('SKU'), 60),
-                    'price' => $this->getTextColumn('price', true, __('Price'), 70),
-                    'qty' => [
-                        'arguments' => [
-                            'data' => [
-                                'config' => [
-                                    'dataType' => Form\Element\DataType\Number::NAME,
-                                    'formElement' => Form\Element\Input::NAME,
-                                    'componentType' => Form\Field::NAME,
-                                    'dataScope' => 'qty',
-                                    'label' => __('Default Quantity'),
-                                    'fit' => true,
-                                    'additionalClasses' => 'admin__field-small',
-                                    'sortOrder' => 80,
-                                    'validation' => [
-                                        'validate-zero-or-greater' => true
-                                    ],
-                                ],
+                ],
+            ],
+            'name' => $this->getTextColumn('name', false, __('Name'), 30),
+            'attribute_set' => $this->getTextColumn('attribute_set', false, __('Attribute Set'), 40),
+            'status' => $this->getTextColumn('status', true, __('Status'), 50),
+            'sku' => $this->getTextColumn('sku', false, __('SKU'), 60),
+            'price' => $this->getTextColumn('price', true, __('Price'), 70),
+            'qty' => [
+                'arguments' => [
+                    'data' => [
+                        'config' => [
+                            'dataType' => Form\Element\DataType\Number::NAME,
+                            'formElement' => Form\Element\Input::NAME,
+                            'componentType' => Form\Field::NAME,
+                            'dataScope' => 'qty',
+                            'label' => __('Default Quantity'),
+                            'fit' => true,
+                            'additionalClasses' => 'admin__field-small',
+                            'sortOrder' => 80,
+                            'validation' => [
+                                'validate-number' => true,
                             ],
                         ],
                     ],
-                    'actionDelete' => [
-                        'arguments' => [
-                            'data' => [
-                                'config' => [
-                                    'additionalClasses' => 'data-grid-actions-cell',
-                                    'componentType' => 'actionDelete',
-                                    'dataType' => Form\Element\DataType\Text::NAME,
-                                    'label' => __('Actions'),
-                                    'sortOrder' => 90,
-                                    'fit' => true,
-                                ],
-                            ],
+                ],
+            ],
+            'actionDelete' => [
+                'arguments' => [
+                    'data' => [
+                        'config' => [
+                            'additionalClasses' => 'data-grid-actions-cell',
+                            'componentType' => 'actionDelete',
+                            'dataType' => Form\Element\DataType\Text::NAME,
+                            'label' => __('Actions'),
+                            'sortOrder' => 90,
+                            'fit' => true,
                         ],
                     ],
-                    'position' => [
-                        'arguments' => [
-                            'data' => [
-                                'config' => [
-                                    'dataType' => Form\Element\DataType\Number::NAME,
-                                    'formElement' => Form\Element\Input::NAME,
-                                    'componentType' => Form\Field::NAME,
-                                    'dataScope' => 'position',
-                                    'sortOrder' => 100,
-                                    'visible' => false,
-                                ],
-                            ],
+                ],
+            ],
+            'position' => [
+                'arguments' => [
+                    'data' => [
+                        'config' => [
+                            'dataType' => Form\Element\DataType\Number::NAME,
+                            'formElement' => Form\Element\Input::NAME,
+                            'componentType' => Form\Field::NAME,
+                            'dataScope' => 'position',
+                            'sortOrder' => 100,
+                            'visible' => false,
                         ],
                     ],
                 ],
diff --git a/lib/internal/Magento/Framework/Stdlib/ArrayManager.php b/lib/internal/Magento/Framework/Stdlib/ArrayManager.php
index d759d2a42c778a6a9068dfe51ec69c0726d0f1b9..51897c0edfcf9305924fd443c8b1582c4d503f9c 100644
--- a/lib/internal/Magento/Framework/Stdlib/ArrayManager.php
+++ b/lib/internal/Magento/Framework/Stdlib/ArrayManager.php
@@ -43,11 +43,11 @@ class ArrayManager
      *
      * @param string $path
      * @param array $data
-     * @param string $delimiter
      * @param null $defaultValue
+     * @param string $delimiter
      * @return mixed|null
      */
-    public function get($path, array $data, $delimiter = self::DEFAULT_PATH_DELIMITER, $defaultValue = null)
+    public function get($path, array $data, $defaultValue = null, $delimiter = self::DEFAULT_PATH_DELIMITER)
     {
         return $this->find($path, $data, $delimiter) ? $this->parentNode[$this->nodeIndex] : $defaultValue;
     }
@@ -88,6 +88,33 @@ class ArrayManager
         return $data;
     }
 
+    /**
+     * Move value from one location to another
+     *
+     * @param string $path
+     * @param string $targetPath
+     * @param array $data
+     * @param bool $overwrite
+     * @param string $delimiter
+     * @return array
+     */
+    public function move($path, $targetPath, array $data, $overwrite = false, $delimiter = self::DEFAULT_PATH_DELIMITER)
+    {
+        if ($this->find($path, $data, $delimiter)) {
+            $parentNode = &$this->parentNode;
+            $nodeIndex = &$this->nodeIndex;
+
+            if ((!$this->find($targetPath, $data, $delimiter) || $overwrite)
+                && $this->find($targetPath, $data, $delimiter, true)
+            ) {
+                $this->parentNode[$this->nodeIndex] = $parentNode[$nodeIndex];
+                unset($parentNode[$nodeIndex]);
+            }
+        }
+
+        return $data;
+    }
+
     /**
      * Merge value with node and return modified data
      *
@@ -109,6 +136,21 @@ class ArrayManager
         return $data;
     }
 
+    /**
+     * Populate nested array if possible and needed
+     *
+     * @param string $path
+     * @param array $data
+     * @param string $delimiter
+     * @return array
+     */
+    public function populate($path, array $data, $delimiter = self::DEFAULT_PATH_DELIMITER)
+    {
+        $this->find($path, $data, $delimiter, true);
+
+        return $data;
+    }
+
     /**
      * Remove node and return modified data
      *
diff --git a/lib/internal/Magento/Framework/Stdlib/Test/Unit/ArrayManagerTest.php b/lib/internal/Magento/Framework/Stdlib/Test/Unit/ArrayManagerTest.php
index 40a3bdacc0e9e6f1d547e436a07bed1e27a48138..8967a6f488b85542172833d4760acb08e97d76c5 100644
--- a/lib/internal/Magento/Framework/Stdlib/Test/Unit/ArrayManagerTest.php
+++ b/lib/internal/Magento/Framework/Stdlib/Test/Unit/ArrayManagerTest.php
@@ -182,6 +182,56 @@ class ArrayManagerTest extends \PHPUnit_Framework_TestCase
         ];
     }
 
+    /**
+     * @param string $path
+     * @param string $targetPath
+     * @param array $data
+     * @param bool $overwrite
+     * @param array $result
+     * @dataProvider moveDataProvider
+     */
+    public function testMove($path, $targetPath, array $data, $overwrite, array $result)
+    {
+        $this->assertSame($result, $this->arrayManager->move($path, $targetPath, $data, $overwrite));
+    }
+
+    /**
+     * @return array
+     */
+    public function moveDataProvider()
+    {
+        return [
+            0 => [
+                'path' => 'not/valid/path',
+                'targetPath' => 'target/path',
+                'data' => ['valid' => ['path' => 'value']],
+                'overwrite' => false,
+                'result' => ['valid' => ['path' => 'value']]
+            ],
+            1 => [
+                'path' => 'valid/path',
+                'targetPath' => 'target/path',
+                'data' => ['valid' => ['path' => 'value']],
+                'overwrite' => false,
+                'result' => ['valid' => [], 'target' => ['path' => 'value']]
+            ],
+            2 => [
+                'path' => 'valid/path',
+                'targetPath' => 'target/path',
+                'data' => ['valid' => ['path' => 'value'], 'target' => ['path' => 'exists']],
+                'overwrite' => false,
+                'result' => ['valid' => ['path' => 'value'], 'target' => ['path' => 'exists']]
+            ],
+            3 => [
+                'path' => 'valid/path',
+                'targetPath' => 'target/path',
+                'data' => ['valid' => ['path' => 'value'], 'target' => ['path' => 'exists']],
+                'overwrite' => true,
+                'result' => ['valid' => [], 'target' => ['path' => 'value']]
+            ]
+        ];
+    }
+
     /**
      * @param string $path
      * @param array $data
@@ -221,6 +271,41 @@ class ArrayManagerTest extends \PHPUnit_Framework_TestCase
         ];
     }
 
+    /**
+     * @param string $path
+     * @param array $data
+     * @param array $result
+     * @dataProvider populateDataProvider
+     */
+    public function testPopulate($path, $data, $result)
+    {
+        $this->assertSame($result, $this->arrayManager->populate($path, $data));
+    }
+
+    /**
+     * @return array
+     */
+    public function populateDataProvider()
+    {
+        return [
+            0 => [
+                'path' => 'some/is/not/array',
+                'data' => ['some' => true],
+                'result' => ['some' => true]
+            ],
+            1 => [
+                'path' => 0,
+                'data' => [],
+                'result' => [[]]
+            ],
+            2 => [
+                'path' => 'nested/1/array',
+                'data' => ['nested' => [true]],
+                'result' => ['nested' => [true, ['array' => []]]]
+            ]
+        ];
+    }
+
     /**
      * @param string $path
      * @param array $data