diff --git a/app/code/Magento/Customer/Model/Customer/DataProvider.php b/app/code/Magento/Customer/Model/Customer/DataProvider.php
index 128ccedaf2b5277371680570b8e82fc88f95a2e2..777a78cb6fa05508712a9c07f4b8f7775ec45029 100644
--- a/app/code/Magento/Customer/Model/Customer/DataProvider.php
+++ b/app/code/Magento/Customer/Model/Customer/DataProvider.php
@@ -9,7 +9,7 @@ use Magento\Eav\Model\Config;
 use Magento\Eav\Model\Entity\Type;
 use Magento\Customer\Model\Address;
 use Magento\Customer\Model\Customer;
-use Magento\Ui\DataProvider\EavValidationRul;
+use Magento\Ui\DataProvider\EavValidationRules;
 use Magento\Customer\Model\Resource\Customer\Collection;
 use Magento\Framework\View\Element\UiComponent\DataProvider\DataProviderInterface;
 use Magento\Customer\Model\Resource\Customer\CollectionFactory as CustomerCollectionFactory;
@@ -75,7 +75,7 @@ class DataProvider implements DataProviderInterface
         'sortOrder' => 'sort_order',
         'notice' => 'note',
         'default' => 'default_value',
-        'size' => 'scope_multiline_count'
+        'size' => 'multiline_count'
     ];
 
     /**
@@ -90,9 +90,9 @@ class DataProvider implements DataProviderInterface
     ];
 
     /**
-     * @var EavValidationRul
+     * @var EavValidationRules
      */
-    protected $eavValidationRul;
+    protected $eavValidationRules;
 
     /**
      * Constructor
@@ -100,7 +100,7 @@ class DataProvider implements DataProviderInterface
      * @param string $name
      * @param string $primaryFieldName
      * @param string $requestFieldName
-     * @param EavValidationRul $eavValidationRul
+     * @param EavValidationRules $eavValidationRules
      * @param CustomerCollectionFactory $customerCollectionFactory
      * @param Config $eavConfig
      * @param array $meta
@@ -110,7 +110,7 @@ class DataProvider implements DataProviderInterface
         $name,
         $primaryFieldName,
         $requestFieldName,
-        EavValidationRul $eavValidationRul,
+        EavValidationRules $eavValidationRules,
         CustomerCollectionFactory $customerCollectionFactory,
         Config $eavConfig,
         array $meta = [],
@@ -119,7 +119,7 @@ class DataProvider implements DataProviderInterface
         $this->name = $name;
         $this->primaryFieldName = $primaryFieldName;
         $this->requestFieldName = $requestFieldName;
-        $this->eavValidationRul = $eavValidationRul;
+        $this->eavValidationRules = $eavValidationRules;
         $this->collection = $customerCollectionFactory->create();
         $this->collection->addAttributeToSelect('*');
         $this->eavConfig = $eavConfig;
@@ -223,6 +223,7 @@ class DataProvider implements DataProviderInterface
      * @param string|array $field
      * @param string|null $alias
      * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function addField($field, $alias = null)
     {
@@ -260,6 +261,7 @@ class DataProvider implements DataProviderInterface
      * @param string|null $field
      * @param bool $isAlias Alias identifier
      * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function removeField($field, $isAlias = false)
     {
@@ -369,7 +371,7 @@ class DataProvider implements DataProviderInterface
                 }
             }
 
-            $rules = $this->eavValidationRul->build($attribute, $meta[$code]);
+            $rules = $this->eavValidationRules->build($attribute, $meta[$code]);
             if (!empty($rules)) {
                 $meta[$code]['validation'] = $rules;
             }
diff --git a/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..eab40c46f84bbc63098fe6222250db2ecd9ed2d7
--- /dev/null
+++ b/app/code/Magento/Customer/Test/Unit/Model/Customer/DataProviderTest.php
@@ -0,0 +1,249 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Customer\Test\Unit\Model\Customer;
+
+use Magento\Eav\Model\Config;
+use Magento\Eav\Model\Entity\Type;
+use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
+use Magento\Ui\DataProvider\EavValidationRules;
+use Magento\Customer\Model\Customer\DataProvider;
+use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
+use Magento\Customer\Model\Resource\Customer\CollectionFactory;
+
+/**
+ * Class DataProviderTest
+ *
+ * Test for class \Magento\Customer\Model\Customer\DataProvider
+ */
+class DataProviderTest extends \PHPUnit_Framework_TestCase
+{
+    const ATTRIBUTE_CODE = 'test-code';
+    const OPTIONS_RESULT = 'test-options';
+
+    /**
+     * @var Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eavConfigMock;
+
+    /**
+     * @var CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $customerCollectionFactoryMock;
+
+    /**
+     * @var EavValidationRules|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $eavValidationRulesMock;
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->eavConfigMock = $this->getMockBuilder('Magento\Eav\Model\Config')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->customerCollectionFactoryMock = $this->getMock(
+            'Magento\Customer\Model\Resource\Customer\CollectionFactory',
+            ['create'],
+            [],
+            '',
+            false
+        );
+        $this->eavValidationRulesMock = $this
+            ->getMockBuilder('Magento\Ui\DataProvider\EavValidationRules')
+            ->disableOriginalConstructor()
+            ->getMock();
+    }
+
+    /**
+     * Run test getAttributesMeta method
+     *
+     * @param array $expected
+     * @return void
+     *
+     * @dataProvider getAttributesMetaDataProvider
+     */
+    public function testGetAttributesMetaWithOptions(array $expected)
+    {
+        $helper = new ObjectManager($this);
+        $dataProvider = $helper->getObject(
+            '\Magento\Customer\Model\Customer\DataProvider',
+            [
+                'name' => 'test-name',
+                'primaryFieldName' => 'primary-field-name',
+                'requestFieldName' => 'request-field-name',
+                'eavValidationRules' => $this->eavValidationRulesMock,
+                'customerCollectionFactory' => $this->getCustomerCollectionFactoryMock(),
+                'eavConfig' => $this->getEavConfigMock()
+            ]
+        );
+
+        $meta = $dataProvider->getMeta();
+        $this->assertNotEmpty($meta);
+        $this->assertEquals($expected, $meta);
+    }
+
+    /**
+     * Data provider for testGetAttributesMeta
+     *
+     * @return array
+     */
+    public function getAttributesMetaDataProvider()
+    {
+        return [
+            [
+                'expected' => [
+                    'customer' => [
+                        'fields' => [
+                            self::ATTRIBUTE_CODE => [
+                                'dataType' => 'frontend_input',
+                                'formElement' => 'frontend_input',
+                                'options' => 'test-options',
+                                'visible' => 'is_visible',
+                                'required' => 'is_required',
+                                'label' => 'frontend_label',
+                                'sortOrder' => 'sort_order',
+                                'notice' => 'note',
+                                'default' => 'default_value',
+                                'size' => 'multiline_count',
+                            ]
+                        ]
+                    ],
+                    'address' => [
+                        'fields' => [
+                            self::ATTRIBUTE_CODE => [
+                                'dataType' => 'frontend_input',
+                                'formElement' => 'frontend_input',
+                                'options' => 'test-options',
+                                'visible' => 'is_visible',
+                                'required' => 'is_required',
+                                'label' => 'frontend_label',
+                                'sortOrder' => 'sort_order',
+                                'notice' => 'note',
+                                'default' => 'default_value',
+                                'size' => 'multiline_count',
+                            ]
+                        ]
+                    ]
+                ]
+            ]
+        ];
+    }
+
+    /**
+     * @return CollectionFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function getCustomerCollectionFactoryMock()
+    {
+        $collectionMock = $this->getMockBuilder('Magento\Customer\Model\Resource\Customer\Collection')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $collectionMock->expects($this->once())
+            ->method('addAttributeToSelect')
+            ->with('*');
+
+        $this->customerCollectionFactoryMock->expects($this->once())
+            ->method('create')
+            ->willReturn($collectionMock);
+
+        return $this->customerCollectionFactoryMock;
+    }
+
+    /**
+     * @return Config|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function getEavConfigMock()
+    {
+        $this->eavConfigMock->expects($this->at(0))
+            ->method('getEntityType')
+            ->with('customer')
+            ->willReturn($this->getTypeCustomerMock());
+        $this->eavConfigMock->expects($this->at(1))
+            ->method('getEntityType')
+            ->with('customer_address')
+            ->willReturn($this->getTypeAddressMock());
+
+        return $this->eavConfigMock;
+    }
+
+    /**
+     * @return Type|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function getTypeCustomerMock()
+    {
+        $typeCustomerMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Type')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $typeCustomerMock->expects($this->once())
+            ->method('getAttributeCollection')
+            ->willReturn($this->getAttributeMock());
+
+        return $typeCustomerMock;
+    }
+
+    /**
+     * @return Type|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function getTypeAddressMock()
+    {
+        $typeAddressMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Type')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $typeAddressMock->expects($this->once())
+            ->method('getAttributeCollection')
+            ->willReturn($this->getAttributeMock());
+
+        return $typeAddressMock;
+    }
+
+    /**
+     * @return AbstractAttribute[]|\PHPUnit_Framework_MockObject_MockObject[]
+     */
+    protected function getAttributeMock()
+    {
+        $attributeMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\AbstractAttribute')
+            ->setMethods(['getAttributeCode', 'getDataUsingMethod', 'usesSource', 'getSource'])
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+        $sourceMock = $this->getMockBuilder('Magento\Eav\Model\Entity\Attribute\Source\AbstractSource')
+            ->disableOriginalConstructor()
+            ->getMockForAbstractClass();
+
+        $sourceMock->expects($this->any())
+            ->method('getAllOptions')
+            ->willReturn(self::OPTIONS_RESULT);
+
+        $attributeMock->expects($this->once())
+            ->method('getAttributeCode')
+            ->willReturn(self::ATTRIBUTE_CODE);
+
+        $attributeMock->expects($this->any())
+            ->method('getDataUsingMethod')
+            ->willReturnCallback(
+                function ($origName) {
+                    return $origName;
+                }
+            );
+        $attributeMock->expects($this->any())
+            ->method('usesSource')
+            ->willReturn(true);
+        $attributeMock->expects($this->any())
+            ->method('getSource')
+            ->willReturn($sourceMock);
+
+        $this->eavValidationRulesMock->expects($this->any())
+            ->method('build')
+            ->with($attributeMock, $this->logicalNot($this->isEmpty()));
+
+        return [$attributeMock];
+    }
+}
diff --git a/app/code/Magento/Payment/Gateway/Command/CommandException.php b/app/code/Magento/Payment/Gateway/Command/CommandException.php
new file mode 100644
index 0000000000000000000000000000000000000000..7c4409fb42e62ff9a8afc3a5356891e3ffd3172b
--- /dev/null
+++ b/app/code/Magento/Payment/Gateway/Command/CommandException.php
@@ -0,0 +1,13 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Gateway\Command;
+
+use Magento\Framework\Exception\LocalizedException;
+
+class CommandException extends LocalizedException
+{
+
+}
diff --git a/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php b/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php
index a6044462cded037192b2ca675ba06ce32e89549c..b04491622d4ba58b1a54b257388e38f82ba1515b 100644
--- a/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php
+++ b/app/code/Magento/Payment/Gateway/Command/GatewayCommand.php
@@ -52,8 +52,8 @@ class GatewayCommand implements CommandInterface
         BuilderInterface $requestBuilder,
         TransferFactoryInterface $transferFactory,
         ClientInterface $client,
-        HandlerInterface $handler,
-        ValidatorInterface $validator
+        HandlerInterface $handler = null,
+        ValidatorInterface $validator = null
     ) {
         $this->requestBuilder = $requestBuilder;
         $this->transferFactory = $transferFactory;
@@ -67,6 +67,7 @@ class GatewayCommand implements CommandInterface
      *
      * @param array $commandSubject
      * @return null
+     * @throws \Exception
      */
     public function execute(array $commandSubject)
     {
@@ -76,16 +77,22 @@ class GatewayCommand implements CommandInterface
         );
 
         $response = $this->client->placeRequest($transferO);
-
-        $result = $this->validator->validate(array_merge($commandSubject, ['response' => $response]));
-        if ($result !== null && !$result->isValid()) {
-            $commandSubject['payment']->getPayment()->setIsTransactionPending(true);
-            return;
+        if ($this->validator) {
+            $result = $this->validator->validate(
+                array_merge($commandSubject, ['response' => $response])
+            );
+            if (!$result->isValid()) {
+                throw new CommandException(
+                    __(implode("\n", $result->getFailsDescription()))
+                );
+            }
         }
 
-        $this->handler->handle(
-            $commandSubject,
-            $response
-        );
+        if ($this->handler) {
+            $this->handler->handle(
+                $commandSubject,
+                $response
+            );
+        }
     }
 }
diff --git a/app/code/Magento/Payment/Gateway/Config/ConfigValueHandler.php b/app/code/Magento/Payment/Gateway/Config/ConfigValueHandler.php
index 17566610aa29e171681ff4ade6829053e0a49c51..4811a6426816a538f702db7e0b1d9cfea0dd9a7c 100644
--- a/app/code/Magento/Payment/Gateway/Config/ConfigValueHandler.php
+++ b/app/code/Magento/Payment/Gateway/Config/ConfigValueHandler.php
@@ -6,6 +6,7 @@
 namespace Magento\Payment\Gateway\Config;
 
 use Magento\Payment\Gateway\ConfigInterface;
+use Magento\Payment\Gateway\Helper\SubjectReader;
 
 class ConfigValueHandler implements ValueHandlerInterface
 {
@@ -26,13 +27,13 @@ class ConfigValueHandler implements ValueHandlerInterface
     /**
      * Retrieve method configured value
      *
-     * @param string $field
+     * @param array $subject
      * @param int|null $storeId
      *
      * @return mixed
      */
-    public function handle($field, $storeId = null)
+    public function handle(array $subject, $storeId = null)
     {
-        return $this->configInterface->getValue($field, $storeId);
+        return $this->configInterface->getValue(SubjectReader::readField($subject), $storeId);
     }
 }
diff --git a/app/code/Magento/Payment/Gateway/Config/ValueHandlerInterface.php b/app/code/Magento/Payment/Gateway/Config/ValueHandlerInterface.php
index 5f857ea3cf539bceec121eb2af09120147774bb3..70e13466bfe30df92d45d4a8c8239819f497b0ea 100644
--- a/app/code/Magento/Payment/Gateway/Config/ValueHandlerInterface.php
+++ b/app/code/Magento/Payment/Gateway/Config/ValueHandlerInterface.php
@@ -10,10 +10,10 @@ interface ValueHandlerInterface
     /**
      * Retrieve method configured value
      *
-     * @param string $field
+     * @param array $subject
      * @param int|null $storeId
      *
      * @return mixed
      */
-    public function handle($field, $storeId = null);
+    public function handle(array $subject, $storeId = null);
 }
diff --git a/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php b/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php
index f01bee1d7c77ab2b4c695ea4f00229f165e29132..f9be150d4761af45d4214edc702771444b0e5a08 100644
--- a/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php
+++ b/app/code/Magento/Payment/Gateway/Data/Order/OrderAdapter.php
@@ -106,4 +106,14 @@ class OrderAdapter implements OrderAdapterInterface
     {
         return $this->order->getEntityId();
     }
+
+    /**
+     * Returns order grand total amount
+     *
+     * @return float|null
+     */
+    public function getGrandTotalAmount()
+    {
+        return $this->order->getBaseGrandTotal();
+    }
 }
diff --git a/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php b/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php
index 0d925d823a9906c6d1bedbe4f488338f33493d64..c15bf289b2bfeeb0657912aec5beea99d7e36b33 100644
--- a/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php
+++ b/app/code/Magento/Payment/Gateway/Data/OrderAdapterInterface.php
@@ -55,4 +55,11 @@ interface OrderAdapterInterface
      * @return int
      */
     public function getId();
+
+    /**
+     * Returns order grand total amount
+     *
+     * @return float
+     */
+    public function getGrandTotalAmount();
 }
diff --git a/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php b/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php
index 43a6a9ded86e61c539b5f64dfbbd89de57bc1c94..5e9ab098109729c78375d05cfbff6489e4cb1fb7 100644
--- a/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php
+++ b/app/code/Magento/Payment/Gateway/Data/Quote/QuoteAdapter.php
@@ -106,4 +106,14 @@ class QuoteAdapter implements OrderAdapterInterface
     {
         return $this->quote->getId();
     }
+
+    /**
+     * Returns order grand total amount
+     *
+     * @return null
+     */
+    public function getGrandTotalAmount()
+    {
+        return null;
+    }
 }
diff --git a/app/code/Magento/Payment/Gateway/Helper/SubjectReader.php b/app/code/Magento/Payment/Gateway/Helper/SubjectReader.php
new file mode 100644
index 0000000000000000000000000000000000000000..bef0a4e463301a4ddda60ce704ea817a85f5488a
--- /dev/null
+++ b/app/code/Magento/Payment/Gateway/Helper/SubjectReader.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Gateway\Helper;
+
+use Magento\Payment\Gateway\Data\PaymentDataObjectInterface;
+
+class SubjectReader
+{
+    /**
+     * Reads payment from subject
+     *
+     * @param array $subject
+     * @return PaymentDataObjectInterface
+     */
+    public static function readPayment(array $subject)
+    {
+        if (!isset($subject['payment'])
+            || !$subject['payment'] instanceof PaymentDataObjectInterface
+        ) {
+            throw new \InvalidArgumentException('Payment data object should be provided');
+        }
+
+        return $subject['payment'];
+    }
+
+    /**
+     * Reads amount from subject
+     *
+     * @param array $subject
+     * @return mixed
+     */
+    public static function readAmount(array $subject)
+    {
+        if (!isset($subject['amount']) || !is_numeric($subject['amount'])) {
+            throw new \InvalidArgumentException('Amount should be provided');
+        }
+
+        return $subject['amount'];
+    }
+
+    /**
+     * Reads field from subject
+     *
+     * @param array $subject
+     * @return string
+     */
+    public static function readField(array $subject)
+    {
+        if (!isset($subject['field']) || !is_string($subject['field'])) {
+            throw new \InvalidArgumentException();
+        }
+
+        return $subject['field'];
+    }
+}
diff --git a/app/code/Magento/Payment/Gateway/Http/Client/Soap.php b/app/code/Magento/Payment/Gateway/Http/Client/Soap.php
new file mode 100644
index 0000000000000000000000000000000000000000..80479f0b768b2eb618f71458678a027bb8a663e3
--- /dev/null
+++ b/app/code/Magento/Payment/Gateway/Http/Client/Soap.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Gateway\Http\Client;
+
+use Magento\Framework\Webapi\Soap\ClientFactory;
+use Magento\Payment\Gateway\Http\ClientInterface;
+use Magento\Payment\Gateway\Http\ConverterInterface;
+use Magento\Payment\Gateway\Http\TransferInterface;
+use Magento\Payment\Model\Method\Logger;
+
+class Soap implements ClientInterface
+{
+    /**
+     * @var Logger
+     */
+    private $logger;
+
+    /**
+     * @var ConverterInterface | null
+     */
+    private $converter;
+
+    /**
+     * @var ClientFactory
+     */
+    private $clientFactory;
+
+    /**
+     * @param Logger $logger
+     * @param ClientFactory $clientFactory
+     * @param ConverterInterface | null $converter
+     */
+    public function __construct(
+        Logger $logger,
+        ClientFactory $clientFactory,
+        ConverterInterface $converter = null
+    ) {
+        $this->logger = $logger;
+        $this->converter = $converter;
+        $this->clientFactory = $clientFactory;
+    }
+
+    /**
+     * Places request to gateway. Returns result as ENV array
+     *
+     * @param TransferInterface $transferObject
+     * @return array
+     * @throws \Magento\Payment\Gateway\Http\ClientException
+     * @throws \Magento\Payment\Gateway\Http\ConverterException
+     * @throws \Exception
+     */
+    public function placeRequest(TransferInterface $transferObject)
+    {
+        $this->logger->debug(['request' => $transferObject->getBody()]);
+
+        $client = $this->clientFactory->create(
+            $transferObject->getClientConfig()['wsdl'],
+            ['trace' => true]
+        );
+
+        try {
+            $client->__setSoapHeaders($transferObject->getHeaders());
+
+            $response = $client->__soapCall(
+                $transferObject->getMethod(),
+                [$transferObject->getBody()]
+            );
+
+            $result = $this->converter
+                ? $this->converter->convert(
+                    $response
+                )
+                : [$response];
+
+            $this->logger->debug(['response' => $result]);
+        } catch (\Exception $e) {
+            $this->logger->debug(['trace' => $client->__getLastRequest()]);
+            throw $e;
+        }
+
+        return $result;
+    }
+}
diff --git a/app/code/Magento/Payment/Gateway/Http/Client/Zend.php b/app/code/Magento/Payment/Gateway/Http/Client/Zend.php
index 0ea8ffbc871b8e49261c641a5bb71e3669e830d2..0415aab562b97e92f742315a48eca0ace2d56a9e 100644
--- a/app/code/Magento/Payment/Gateway/Http/Client/Zend.php
+++ b/app/code/Magento/Payment/Gateway/Http/Client/Zend.php
@@ -9,6 +9,7 @@ use Magento\Framework\HTTP\ZendClientFactory;
 use Magento\Framework\HTTP\ZendClient;
 use Magento\Payment\Gateway\Http\ClientInterface;
 use Magento\Payment\Gateway\Http\ConverterInterface;
+use Magento\Payment\Gateway\Http\TransferInterface;
 use Magento\Payment\Model\Method\Logger;
 
 class Zend implements ClientInterface
@@ -19,7 +20,7 @@ class Zend implements ClientInterface
     private $clientFactory;
 
     /**
-     * @var ConverterInterface
+     * @var ConverterInterface | null
      */
     private $converter;
 
@@ -30,13 +31,13 @@ class Zend implements ClientInterface
 
     /**
      * @param ZendClientFactory $clientFactory
-     * @param ConverterInterface $converter
      * @param Logger $logger
+     * @param ConverterInterface | null $converter
      */
     public function __construct(
         ZendClientFactory $clientFactory,
-        ConverterInterface $converter,
-        Logger $logger
+        Logger $logger,
+        ConverterInterface $converter = null
     ) {
         $this->clientFactory = $clientFactory;
         $this->converter = $converter;
@@ -46,10 +47,11 @@ class Zend implements ClientInterface
     /**
      * {inheritdoc}
      */
-    public function placeRequest(\Magento\Payment\Gateway\Http\TransferInterface $transferObject)
+    public function placeRequest(TransferInterface $transferObject)
     {
         $log = [
-            'request' => $transferObject->getBody()
+            'request' => $transferObject->getBody(),
+            'request_uri' => $transferObject->getUri()
         ];
         $result = [];
         /** @var ZendClient $client */
@@ -66,7 +68,12 @@ class Zend implements ClientInterface
                 $client->setParameterPost($transferObject->getBody());
                 break;
             default:
-                throw new \LogicException(sprintf('Unsupported HTTP method %s', $transferObject->getMethod()));
+                throw new \LogicException(
+                    sprintf(
+                        'Unsupported HTTP method %s',
+                        $transferObject->getMethod()
+                    )
+                );
         }
 
         $client->setHeaders($transferObject->getHeaders());
@@ -76,10 +83,14 @@ class Zend implements ClientInterface
         try {
             $response = $client->request();
 
-            $result = $this->converter->convert($response->getBody());
+            $result = $this->converter
+                ? $this->converter->convert($response->getBody())
+                : [$response->getBody()];
             $log['response'] = $result;
         } catch (\Zend_Http_Client_Exception $e) {
-            throw new \Magento\Payment\Gateway\Http\ClientException(__($e->getMessage()));
+            throw new \Magento\Payment\Gateway\Http\ClientException(
+                __($e->getMessage())
+            );
         } catch (\Magento\Payment\Gateway\Http\ConverterException $e) {
             throw $e;
         } finally {
diff --git a/app/code/Magento/Payment/Gateway/Http/Converter/Soap/ObjectToArrayConverter.php b/app/code/Magento/Payment/Gateway/Http/Converter/Soap/ObjectToArrayConverter.php
new file mode 100644
index 0000000000000000000000000000000000000000..e0045085417715e81b6251b719b6a326c63dcdbb
--- /dev/null
+++ b/app/code/Magento/Payment/Gateway/Http/Converter/Soap/ObjectToArrayConverter.php
@@ -0,0 +1,30 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Gateway\Http\Converter\Soap;
+
+use Magento\Payment\Gateway\Http\ConverterInterface;
+
+class ObjectToArrayConverter implements ConverterInterface
+{
+    /**
+     * Converts gateway response to ENV structure
+     *
+     * @param mixed $response
+     * @return array
+     * @throws \Magento\Payment\Gateway\Http\ConverterException
+     */
+    public function convert($response)
+    {
+        $response = (array) $response;
+        foreach ($response as $key => $value) {
+            if (is_object($value)) {
+                $response[$key] = $this->convert($value);
+            }
+        }
+
+        return $response;
+    }
+}
diff --git a/app/code/Magento/Payment/Gateway/Http/ConverterInterface.php b/app/code/Magento/Payment/Gateway/Http/ConverterInterface.php
index 776ea4b11673d8589dfca68b53c203da27986bda..673a0bbc847008af50b59bf41da2f0ed2f0f8af7 100644
--- a/app/code/Magento/Payment/Gateway/Http/ConverterInterface.php
+++ b/app/code/Magento/Payment/Gateway/Http/ConverterInterface.php
@@ -10,7 +10,7 @@ interface ConverterInterface
     /**
      * Converts gateway response to ENV structure
      *
-     * @param string $response
+     * @param mixed $response
      * @return array
      * @throws \Magento\Payment\Gateway\Http\ConverterException
      */
diff --git a/app/code/Magento/Payment/Gateway/Http/TransferInterface.php b/app/code/Magento/Payment/Gateway/Http/TransferInterface.php
index abd3d530b2ac59ff37b88ee738d29d79a864e8a8..f2150c8e083f23f8a9fa3f0440a52c884f9cfac3 100644
--- a/app/code/Magento/Payment/Gateway/Http/TransferInterface.php
+++ b/app/code/Magento/Payment/Gateway/Http/TransferInterface.php
@@ -38,7 +38,7 @@ interface TransferInterface
     /**
      * Returns request body
      *
-     * @return string
+     * @return array
      */
     public function getBody();
 
diff --git a/app/code/Magento/Payment/Gateway/Validator/AbstractValidator.php b/app/code/Magento/Payment/Gateway/Validator/AbstractValidator.php
index e82e0605445a367d1bbf528989c2081393f35c2c..b9e55ef57eca1d31ef32912e1457f8772c5520af 100644
--- a/app/code/Magento/Payment/Gateway/Validator/AbstractValidator.php
+++ b/app/code/Magento/Payment/Gateway/Validator/AbstractValidator.php
@@ -30,6 +30,11 @@ abstract class AbstractValidator implements ValidatorInterface
      */
     protected function createResult($isValid, array $fails = [])
     {
-        return $this->resultInterfaceFactory->create(['isValid' => (bool)$isValid, 'failsDescription' => $fails]);
+        return $this->resultInterfaceFactory->create(
+            [
+                'isValid' => (bool)$isValid,
+                'failsDescription' => $fails
+            ]
+        );
     }
 }
diff --git a/app/code/Magento/Payment/Gateway/Validator/CountryValidator.php b/app/code/Magento/Payment/Gateway/Validator/CountryValidator.php
index 3a0ff81186df3aff134f5e14c79d5a7f409a2e7b..0c65b09785040a45d402bed4653c4ab3b691db23 100644
--- a/app/code/Magento/Payment/Gateway/Validator/CountryValidator.php
+++ b/app/code/Magento/Payment/Gateway/Validator/CountryValidator.php
@@ -9,7 +9,7 @@ use Magento\Framework\Exception\NotFoundException;
 use Magento\Payment\Gateway\ConfigInterface;
 use Magento\Payment\Gateway\Validator\ResultInterfaceFactory;
 
-class CountryValidator implements ValidatorInterface
+class CountryValidator extends AbstractValidator
 {
     /**
      * @var \Magento\Payment\Gateway\ConfigInterface
@@ -17,20 +17,15 @@ class CountryValidator implements ValidatorInterface
     private $config;
 
     /**
-     * @var ResultInterfaceFactory
-     */
-    private $resultFactory;
-
-    /**
-     * @param \Magento\Payment\Gateway\ConfigInterface $config
      * @param ResultInterfaceFactory $resultFactory
+     * @param \Magento\Payment\Gateway\ConfigInterface $config
      */
     public function __construct(
-        ConfigInterface $config,
-        ResultInterfaceFactory $resultFactory
+        ResultInterfaceFactory $resultFactory,
+        ConfigInterface $config
     ) {
         $this->config = $config;
-        $this->resultFactory = $resultFactory;
+        parent::__construct($resultFactory);
     }
 
     /**
@@ -55,10 +50,6 @@ class CountryValidator implements ValidatorInterface
             }
         }
 
-        return $this->resultFactory->create(
-            [
-                'isValid' => $isValid
-            ]
-        );
+        return $this->createResult($isValid);
     }
 }
diff --git a/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php b/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php
index 05a476f9743c12a930052fe27c4dfcb057e54ae5..6e7c5c8c0ab5cecf0031ebc87519306289ea40e2 100644
--- a/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php
+++ b/app/code/Magento/Payment/Gateway/Validator/ValidatorComposite.php
@@ -9,18 +9,13 @@ use Magento\Framework\ObjectManager\TMap;
 use Magento\Framework\ObjectManager\TMapFactory;
 use Magento\Payment\Gateway\Validator\ResultInterfaceFactory;
 
-class ValidatorComposite implements ValidatorInterface
+class ValidatorComposite extends AbstractValidator
 {
     /**
      * @var ValidatorInterface[] | TMap
      */
     private $validators;
 
-    /**
-     * @var ResultInterfaceFactory
-     */
-    private $resultFactory;
-
     /**
      * @param ResultInterfaceFactory $resultFactory
      * @param array $validators
@@ -37,7 +32,7 @@ class ValidatorComposite implements ValidatorInterface
                 'type' => 'Magento\Payment\Gateway\Validator\ValidatorInterface'
             ]
         );
-        $this->resultFactory = $resultFactory;
+        parent::__construct($resultFactory);
     }
 
     /**
@@ -61,11 +56,6 @@ class ValidatorComposite implements ValidatorInterface
             }
         }
 
-        return $this->resultFactory->create(
-            [
-                'isValid' => $isValid,
-                'failsDescription' => $failsDescriptionAggregate
-            ]
-        );
+        return $this->createResult($isValid, $failsDescriptionAggregate);
     }
 }
diff --git a/app/code/Magento/Payment/Model/Method/Adapter.php b/app/code/Magento/Payment/Model/Method/Adapter.php
index acb0e56809e30c3c677aebc4bffc5611ac7112f1..314a03d51550fedde3cd9b9e8c795eb25b4f5061 100644
--- a/app/code/Magento/Payment/Model/Method/Adapter.php
+++ b/app/code/Magento/Payment/Model/Method/Adapter.php
@@ -7,6 +7,9 @@ namespace Magento\Payment\Model\Method;
 
 use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\Exception\NotFoundException;
+use Magento\Payment\Gateway\Command\CommandPoolInterface;
+use Magento\Payment\Gateway\Config\ValueHandlerPoolInterface;
+use Magento\Payment\Gateway\Validator\ValidatorPoolInterface;
 use Magento\Payment\Model\InfoInterface;
 use Magento\Payment\Model\MethodInterface;
 
@@ -18,17 +21,17 @@ use Magento\Payment\Model\MethodInterface;
 class Adapter implements MethodInterface
 {
     /**
-     * @var \Magento\Payment\Gateway\Config\ValueHandlerPoolInterface
+     * @var ValueHandlerPoolInterface
      */
     private $valueHandlerPool;
 
     /**
-     * @var \Magento\Payment\Gateway\Validator\ValidatorPoolInterface
+     * @var ValidatorPoolInterface
      */
     private $validatorPool;
 
     /**
-     * @var \Magento\Payment\Gateway\Command\CommandPoolInterface
+     * @var CommandPoolInterface
      */
     private $commandPool;
 
@@ -69,9 +72,9 @@ class Adapter implements MethodInterface
 
     /**
      * @param \Magento\Framework\Event\ManagerInterface $eventManager
-     * @param \Magento\Payment\Gateway\Config\ValueHandlerPoolInterface $valueHandlerPool
-     * @param \Magento\Payment\Gateway\Validator\ValidatorPoolInterface $validatorPool
-     * @param \Magento\Payment\Gateway\Command\CommandPoolInterface $commandPool
+     * @param ValueHandlerPoolInterface $valueHandlerPool
+     * @param ValidatorPoolInterface $validatorPool
+     * @param CommandPoolInterface $commandPool
      * @param \Magento\Payment\Gateway\Data\PaymentDataObjectFactory $paymentDataObjectFactory
      * @param string $code
      * @param string $formBlockType
@@ -79,9 +82,9 @@ class Adapter implements MethodInterface
      */
     public function __construct(
         \Magento\Framework\Event\ManagerInterface $eventManager,
-        \Magento\Payment\Gateway\Config\ValueHandlerPoolInterface $valueHandlerPool,
-        \Magento\Payment\Gateway\Validator\ValidatorPoolInterface $validatorPool,
-        \Magento\Payment\Gateway\Command\CommandPoolInterface $commandPool,
+        ValueHandlerPoolInterface $valueHandlerPool,
+        ValidatorPoolInterface $validatorPool,
+        CommandPoolInterface $commandPool,
         \Magento\Payment\Gateway\Data\PaymentDataObjectFactory $paymentDataObjectFactory,
         $code,
         $formBlockType,
@@ -306,7 +309,15 @@ class Adapter implements MethodInterface
     private function getConfiguredValue($field)
     {
         $handler = $this->valueHandlerPool->get($field);
-        return $handler->handle($field, $this->getStore());
+        $subject = [
+            'field' => $field
+        ];
+
+        if ($this->getInfoInstance()) {
+            $subject['payment'] = $this->paymentDataObjectFactory->create($this->getInfoInstance());
+        }
+
+        return $handler->handle($subject, $this->getStore());
     }
 
     /**
@@ -522,12 +533,6 @@ class Adapter implements MethodInterface
      */
     public function getInfoInstance()
     {
-        if (!$this->infoInstance instanceof InfoInterface) {
-            throw new LocalizedException(
-                __('We cannot retrieve the payment information object instance.')
-            );
-        }
-
         return $this->infoInstance;
     }
 
@@ -548,8 +553,16 @@ class Adapter implements MethodInterface
             return $this->getConfiguredValue($field);
         }
 
+        $subject = [
+            'field' => $field
+        ];
+
+        if ($this->getInfoInstance()) {
+            $subject['payment'] = $this->paymentDataObjectFactory->create($this->getInfoInstance());
+        }
+
         $handler = $this->valueHandlerPool->get($field);
-        return $handler->handle($field, (int)$storeId);
+        return $handler->handle($subject, (int)$storeId);
     }
 
     /**
@@ -567,6 +580,7 @@ class Adapter implements MethodInterface
 
     /**
      * {inheritdoc}
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function initialize($paymentAction, $stateObject)
     {
diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php
index 9872e20250bbe2d34c5375f22cbac5916e69cf3a..7a9d60d8acc18d9ce7fc373bdd14d56f0f0e26e6 100644
--- a/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php
+++ b/app/code/Magento/Payment/Test/Unit/Gateway/Command/GatewayCommandTest.php
@@ -5,50 +5,67 @@
  */
 namespace Magento\Payment\Test\Unit\Gateway\Command;
 
+use Magento\Payment\Gateway\Command\GatewayCommand;
+use Magento\Payment\Gateway\Http\ClientInterface;
+use Magento\Payment\Gateway\Http\TransferFactoryInterface;
+use Magento\Payment\Gateway\Request\BuilderInterface;
+use Magento\Payment\Gateway\Response\HandlerInterface;
+use Magento\Payment\Gateway\Validator\ValidatorInterface;
+
 class GatewayCommandTest extends \PHPUnit_Framework_TestCase
 {
-    /** @var \Magento\Payment\Gateway\Command\GatewayCommand */
-    protected $model;
+    /** @var GatewayCommand */
+    protected $command;
 
     /**
-     * @var \Magento\Payment\Gateway\Request\BuilderInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var BuilderInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $requestBuilderMock;
 
     /**
-     * @var \Magento\Payment\Gateway\Http\TransferFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var TransferFactoryInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $transferFactoryMock;
 
     /**
-     * @var \Magento\Payment\Gateway\Http\ClientInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $clientMock;
 
     /**
-     * @var \Magento\Payment\Gateway\Response\HandlerInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var HandlerInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $responseHandlerMock;
 
     /**
-     * @var \Magento\Payment\Gateway\Validator\ValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
+     * @var ValidatorInterface|\PHPUnit_Framework_MockObject_MockObject
      */
     protected $validatorMock;
 
     protected function setUp()
     {
-        $this->requestBuilderMock = $this->getMockBuilder('Magento\Payment\Gateway\Request\BuilderInterface')
+        $this->requestBuilderMock = $this->getMockBuilder(
+            'Magento\Payment\Gateway\Request\BuilderInterface'
+        )
             ->getMockForAbstractClass();
-        $this->transferFactoryMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\TransferFactoryInterface')
+        $this->transferFactoryMock = $this->getMockBuilder(
+            'Magento\Payment\Gateway\Http\TransferFactoryInterface'
+        )
             ->getMockForAbstractClass();
-        $this->clientMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\ClientInterface')
+        $this->clientMock = $this->getMockBuilder(
+            'Magento\Payment\Gateway\Http\ClientInterface'
+        )
             ->getMockForAbstractClass();
-        $this->responseHandlerMock = $this->getMockBuilder('Magento\Payment\Gateway\Response\HandlerInterface')
+        $this->responseHandlerMock = $this->getMockBuilder(
+            'Magento\Payment\Gateway\Response\HandlerInterface'
+        )
             ->getMockForAbstractClass();
-        $this->validatorMock = $this->getMockBuilder('Magento\Payment\Gateway\Validator\ValidatorInterface')
+        $this->validatorMock = $this->getMockBuilder(
+            'Magento\Payment\Gateway\Validator\ValidatorInterface'
+        )
             ->getMockForAbstractClass();
 
-        $this->model = new \Magento\Payment\Gateway\Command\GatewayCommand(
+        $this->command = new GatewayCommand(
             $this->requestBuilderMock,
             $this->transferFactoryMock,
             $this->clientMock,
@@ -60,12 +77,19 @@ class GatewayCommandTest extends \PHPUnit_Framework_TestCase
     public function testExecute()
     {
         $commandSubject = ['authorize'];
-        $request = ['request_field1' => 'request_value1', 'request_field2' => 'request_value2'];
+        $request = [
+            'request_field1' => 'request_value1',
+            'request_field2' => 'request_value2'
+        ];
         $response = ['response_field1' => 'response_value1'];
-        $validationResult = $this->getMockBuilder('Magento\Payment\Gateway\Validator\ResultInterface')
+        $validationResult = $this->getMockBuilder(
+            'Magento\Payment\Gateway\Validator\ResultInterface'
+        )
             ->getMockForAbstractClass();
 
-        $transferO = $this->getMockBuilder('Magento\Payment\Gateway\Http\TransferInterface')
+        $transferO = $this->getMockBuilder(
+            'Magento\Payment\Gateway\Http\TransferInterface'
+        )
             ->getMockForAbstractClass();
 
         $this->requestBuilderMock->expects(static::once())
@@ -94,6 +118,56 @@ class GatewayCommandTest extends \PHPUnit_Framework_TestCase
             ->method('handle')
             ->with($commandSubject, $response);
 
-        $this->model->execute($commandSubject);
+        $this->command->execute($commandSubject);
+    }
+
+    public function testExecuteValidationFail()
+    {
+        $this->setExpectedException(
+            'Magento\Payment\Gateway\Command\CommandException'
+        );
+
+        $commandSubject = ['authorize'];
+        $request = [
+            'request_field1' => 'request_value1',
+            'request_field2' => 'request_value2'
+        ];
+        $response = ['response_field1' => 'response_value1'];
+        $validationResult = $this->getMockBuilder(
+            'Magento\Payment\Gateway\Validator\ResultInterface'
+        )
+            ->getMockForAbstractClass();
+
+        $transferO = $this->getMockBuilder(
+            'Magento\Payment\Gateway\Http\TransferInterface'
+        )
+            ->getMockForAbstractClass();
+
+        $this->requestBuilderMock->expects(static::once())
+            ->method('build')
+            ->with($commandSubject)
+            ->willReturn($request);
+
+        $this->transferFactoryMock->expects(static::once())
+            ->method('create')
+            ->with($request)
+            ->willReturn($transferO);
+
+        $this->clientMock->expects(static::once())
+            ->method('placeRequest')
+            ->with($transferO)
+            ->willReturn($response);
+        $this->validatorMock->expects(static::once())
+            ->method('validate')
+            ->with(array_merge($commandSubject, ['response' =>$response]))
+            ->willReturn($validationResult);
+        $validationResult->expects(static::once())
+            ->method('isValid')
+            ->willReturn(false);
+        $validationResult->expects(static::once())
+            ->method('getFailsDescription')
+            ->willReturn([]);
+
+        $this->command->execute($commandSubject);
     }
 }
diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Config/ConfigValueHandlerTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Config/ConfigValueHandlerTest.php
index eebebfdadf275d0ae66013340594630543dce94e..3f1d4a280ef288d27e52458ecd3950bae936fc05 100644
--- a/app/code/Magento/Payment/Test/Unit/Gateway/Config/ConfigValueHandlerTest.php
+++ b/app/code/Magento/Payment/Test/Unit/Gateway/Config/ConfigValueHandlerTest.php
@@ -23,7 +23,8 @@ class ConfigValueHandlerTest extends \PHPUnit_Framework_TestCase
 
     protected function setUp()
     {
-        $this->configMock = $this->getMockBuilder('Magento\Payment\Gateway\ConfigInterface')->getMockForAbstractClass();
+        $this->configMock = $this->getMockBuilder('Magento\Payment\Gateway\ConfigInterface')
+            ->getMockForAbstractClass();
         $this->model = new ConfigValueHandler($this->configMock);
     }
 
@@ -38,7 +39,7 @@ class ConfigValueHandlerTest extends \PHPUnit_Framework_TestCase
             ->with($field, $storeId)
             ->willReturn($expected);
 
-        $this->assertEquals($expected, $this->model->handle($field, $storeId));
+        $this->assertEquals($expected, $this->model->handle(['field' => $field], $storeId));
     }
 
     public function testHandleWithoutStoreId()
@@ -51,6 +52,6 @@ class ConfigValueHandlerTest extends \PHPUnit_Framework_TestCase
             ->with($field, null)
             ->willReturn($expected);
 
-        $this->assertEquals($expected, $this->model->handle($field));
+        $this->assertEquals($expected, $this->model->handle(['field' => $field]));
     }
 }
diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/SoapTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/SoapTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ef4dd5be64546681d9e328223dad5e9f57386d38
--- /dev/null
+++ b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/SoapTest.php
@@ -0,0 +1,155 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Test\Unit\Gateway\Http\Client;
+
+use Magento\Payment\Gateway\Http\Client\Soap;
+
+class SoapTest extends \PHPUnit_Framework_TestCase
+{
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $logger;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $clientFactory;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $converter;
+
+    /**
+     * @var \PHPUnit_Framework_MockObject_MockObject
+     */
+    private $client;
+
+    /**
+     * @var Soap
+     */
+    private $gatewayClient;
+
+    protected function setUp()
+    {
+        $this->logger = $this->getMockBuilder(
+            'Magento\Payment\Model\Method\Logger'
+        )
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->clientFactory = $this->getMockBuilder(
+            'Magento\Framework\Webapi\Soap\ClientFactory'
+        )->getMock();
+        $this->converter = $this->getMockBuilder(
+            'Magento\Payment\Gateway\Http\ConverterInterface'
+        )->getMockForAbstractClass();
+        $this->client = $this->getMockBuilder('\SoapClient')
+            ->disableOriginalConstructor()
+            ->getMock();
+
+        $this->gatewayClient = new Soap(
+            $this->logger,
+            $this->clientFactory,
+            $this->converter
+        );
+    }
+
+    public function testPlaceRequest()
+    {
+        $expectedResult = [
+            'result' => []
+        ];
+        $soapResult = new \StdClass;
+
+        $this->logger->expects(static::at(0))
+            ->method('debug')
+            ->with(
+                ['request' => ['body']]
+            );
+        $this->clientFactory->expects(static::once())
+            ->method('create')
+            ->with('path_to_wsdl', ['trace' => true])
+            ->willReturn($this->client);
+        $transferObject = $this->getTransferObject();
+        $transferObject->expects(static::any())
+            ->method('__setSoapHeaders')
+            ->with(['headers']);
+        $this->client->expects(static::once())
+            ->method('__soapCall')
+            ->with('soapMethod', [['body']])
+            ->willReturn($soapResult);
+        $this->converter->expects(static::once())
+            ->method('convert')
+            ->with($soapResult)
+            ->willReturn($expectedResult);
+        $this->logger->expects(static::at(1))
+            ->method('debug')
+            ->with(['response' => $expectedResult]);
+
+        static::assertEquals(
+            $expectedResult,
+            $this->gatewayClient->placeRequest($transferObject)
+        );
+    }
+
+    public function testPlaceRequestSoapException()
+    {
+        $this->setExpectedException('Exception');
+
+        $this->logger->expects(static::at(0))
+            ->method('debug')
+            ->with(
+                ['request' => ['body']]
+            );
+        $this->clientFactory->expects(static::once())
+            ->method('create')
+            ->with('path_to_wsdl', ['trace' => true])
+            ->willReturn($this->client);
+        $transferObject = $this->getTransferObject();
+        $transferObject->expects(static::any())
+            ->method('__setSoapHeaders')
+            ->with(['headers']);
+        $this->client->expects(static::once())
+            ->method('__soapCall')
+            ->with('soapMethod', [['body']])
+            ->willThrowException(new \Exception);
+        $this->client->expects(static::once())
+            ->method('__getLastRequest')
+            ->willReturn('RequestTrace');
+        $this->logger->expects(static::at(1))
+            ->method('debug')
+            ->with(
+                ['trace' => 'RequestTrace']
+            );
+
+        $this->gatewayClient->placeRequest($transferObject);
+    }
+
+    /**
+     * Returns prepared transfer object
+     *
+     * @return \PHPUnit_Framework_MockObject_MockObject
+     */
+    private function getTransferObject()
+    {
+        $transferObject = $this->getMockBuilder(
+            'Magento\Payment\Gateway\Http\TransferInterface'
+        )->getMock();
+
+        $transferObject->expects(static::any())
+            ->method('getBody')
+            ->willReturn(['body']);
+        $transferObject->expects(static::any())
+            ->method('getClientConfig')
+            ->willReturn(['wsdl' => 'path_to_wsdl']);
+        $transferObject->expects(static::any())
+            ->method('getMethod')
+            ->willReturn('soapMethod');
+
+        return $transferObject;
+    }
+}
diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php
index 43f2a400ccd77100161afbd5596ddf4fdbc7b8b1..e34cb00d5a24b4822ac6de12e6a406304fc5afcc 100644
--- a/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php
+++ b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Client/ZendTest.php
@@ -65,7 +65,11 @@ class ZendTest extends \PHPUnit_Framework_TestCase
         $this->transferObjectMock = $this->getMockBuilder('Magento\Payment\Gateway\Http\TransferInterface')
             ->getMockForAbstractClass();
 
-        $this->model = new Zend($this->zendClientFactoryMock, $this->converterMock, $this->loggerMock);
+        $this->model = new Zend(
+            $this->zendClientFactoryMock,
+            $this->loggerMock,
+            $this->converterMock
+        );
     }
 
     public function testPlaceRequest()
@@ -147,7 +151,7 @@ class ZendTest extends \PHPUnit_Framework_TestCase
         $this->transferObjectMock->expects($this->once())->method('getHeaders')->willReturn($headers);
         $this->transferObjectMock->expects($this->atLeastOnce())->method('getBody')->willReturn($body);
         $this->transferObjectMock->expects($this->once())->method('shouldEncode')->willReturn($shouldEncode);
-        $this->transferObjectMock->expects($this->once())->method('getUri')->willReturn($uri);
+        $this->transferObjectMock->expects(static::atLeastOnce())->method('getUri')->willReturn($uri);
 
         $this->clientMock->expects($this->once())->method('setConfig')->with($config)->willReturnSelf();
         $this->clientMock->expects($this->once())->method('setMethod')->with($method)->willReturnSelf();
diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Http/Converter/Soap/ObjectToArrayConverterTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Converter/Soap/ObjectToArrayConverterTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c39c6dcb1d8b2f8374ba9897b062dd16320479bf
--- /dev/null
+++ b/app/code/Magento/Payment/Test/Unit/Gateway/Http/Converter/Soap/ObjectToArrayConverterTest.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Payment\Test\Unit\Gateway\Http\Converter\Soap;
+
+use Magento\Payment\Gateway\Http\Converter\Soap\ObjectToArrayConverter;
+
+class ObjectToArrayConverterTest extends \PHPUnit_Framework_TestCase
+{
+    public function testConvert()
+    {
+        $input = new \stdClass();
+        $input->property = new \stdClass();
+        $input->property2 = 'bla';
+        $input->property->property3 = new \stdClass();
+        $input->property->property4 = 'bla';
+        $input->property->property3->property5 = 'bla';
+
+        $output = [
+            'property' => [
+                'property3' => [
+                    'property5' => 'bla'
+                ],
+                'property4' => 'bla'
+            ],
+            'property2' => 'bla'
+        ];
+
+        $converter = new ObjectToArrayConverter();
+        static::assertEquals($output, $converter->convert($input));
+
+    }
+}
diff --git a/app/code/Magento/Payment/Test/Unit/Gateway/Validator/CountryValidatorTest.php b/app/code/Magento/Payment/Test/Unit/Gateway/Validator/CountryValidatorTest.php
index 38ac5d69dd3d01176e8f53c8f45a1057dc5ed17c..554b13ef74646f8e1cd6a62f8ede96b1491352ae 100644
--- a/app/code/Magento/Payment/Test/Unit/Gateway/Validator/CountryValidatorTest.php
+++ b/app/code/Magento/Payment/Test/Unit/Gateway/Validator/CountryValidatorTest.php
@@ -38,8 +38,8 @@ class CountryValidatorTest extends \PHPUnit_Framework_TestCase
             ->getMock();
 
         $this->model = new \Magento\Payment\Gateway\Validator\CountryValidator(
-            $this->configMock,
-            $this->resultFactoryMock
+            $this->resultFactoryMock,
+            $this->configMock
         );
     }
 
@@ -62,7 +62,7 @@ class CountryValidatorTest extends \PHPUnit_Framework_TestCase
 
         $this->resultFactoryMock->expects($this->once())
             ->method('create')
-            ->with(['isValid' => $isValid])
+            ->with(['isValid' => $isValid, 'failsDescription' => []])
             ->willReturn($this->resultMock);
 
         $this->assertSame($this->resultMock, $this->model->validate($validationSubject));
@@ -90,7 +90,7 @@ class CountryValidatorTest extends \PHPUnit_Framework_TestCase
 
         $this->resultFactoryMock->expects($this->once())
             ->method('create')
-            ->with(['isValid' => $isValid])
+            ->with(['isValid' => $isValid, 'failsDescription' => []])
             ->willReturn($this->resultMock);
 
         $this->assertSame($this->resultMock, $this->model->validate($validationSubject));
diff --git a/app/code/Magento/Payment/etc/payment.xml b/app/code/Magento/Payment/etc/payment.xml
index 5560a70f11b325ea8d12a85ec5fd2582b29593f1..1d52b718925cddf25f531b1b6d8ea9c941a9b901 100644
--- a/app/code/Magento/Payment/etc/payment.xml
+++ b/app/code/Magento/Payment/etc/payment.xml
@@ -35,9 +35,6 @@
         <type id="DN" order="60">
             <label>Diners</label>
         </type>
-        <type id="JC" order="70">
-            <label>JCB</label>
-        </type>
         <type id="MI" order="80">
             <label>Maestro International</label>
         </type>
diff --git a/app/code/Magento/Sales/Model/Order/Creditmemo.php b/app/code/Magento/Sales/Model/Order/Creditmemo.php
index d0c564c01bf619a5babab63eefe194733eb8242c..56d1c892985da5d8423381fa5d9080be6de2564c 100644
--- a/app/code/Magento/Sales/Model/Order/Creditmemo.php
+++ b/app/code/Magento/Sales/Model/Order/Creditmemo.php
@@ -373,6 +373,28 @@ class Creditmemo extends AbstractModel implements EntityInterface, CreditmemoInt
         return false;
     }
 
+    /**
+     * Returns assigned invoice
+     *
+     * @return Invoice|null
+     */
+    public function getInvoice()
+    {
+        return $this->getData('invoice');
+    }
+
+    /**
+     * Sets invoice
+     *
+     * @param Invoice $invoice
+     * @return $this
+     */
+    public function setInvoice(Invoice $invoice)
+    {
+        $this->setData('invoice', $invoice);
+        return $this;
+    }
+
     /**
      * Check creditmemo cancel action availability
      *
diff --git a/app/code/Magento/Sales/Model/Order/Payment.php b/app/code/Magento/Sales/Model/Order/Payment.php
index 6ecf8a298cd1a663af73808e5c79eb6b664d458a..269f9e0187798ed74eb919d31c88b6aada5a6bd5 100644
--- a/app/code/Magento/Sales/Model/Order/Payment.php
+++ b/app/code/Magento/Sales/Model/Order/Payment.php
@@ -186,6 +186,40 @@ class Payment extends Info implements OrderPaymentInterface
         return $this->_order;
     }
 
+    /**
+     * Sets transaction id for current payment
+     *
+     * @param string $transactionId
+     * @return $this
+     */
+    public function setTransactionId($transactionId)
+    {
+        $this->setData('transaction_id', $transactionId);
+        return $this;
+    }
+
+    /**
+     * Sets transaction close flag
+     *
+     * @param bool $isClosed
+     * @return $this
+     */
+    public function setIsTransactionClosed($isClosed)
+    {
+        $this->setData('is_transaction_closed', (bool)$isClosed);
+        return $this;
+    }
+
+    /**
+     * Returns transaction parent
+     *
+     * @return string
+     */
+    public function getParentTransactionId()
+    {
+        return $this->getData('parent_transaction_id');
+    }
+
     /**
      * Check order payment capture action availability
      *
@@ -655,6 +689,30 @@ class Payment extends Info implements OrderPaymentInterface
         return $this->_void(false, $amount);
     }
 
+    /**
+     * Sets creditmemo for current payment
+     *
+     * @param Creditmemo $creditmemo
+     * @return $this
+     */
+    public function setCreditmemo(Creditmemo $creditmemo)
+    {
+        $this->setData('creditmemo', $creditmemo);
+        return $this;
+    }
+
+    /**
+     * Returns Creditmemo assigned for this payment
+     *
+     * @return Creditmemo|null
+     */
+    public function getCreditmemo()
+    {
+        return $this->getData('creditmemo') instanceof Creditmemo
+            ? $this->getData('creditmemo')
+            : null;
+    }
+
     /**
      * Refund payment online or offline, depending on whether there is invoice set in the creditmemo instance
      * Updates transactions hierarchy, if required
diff --git a/app/code/Magento/Sales/Model/Order/Payment/Transaction.php b/app/code/Magento/Sales/Model/Order/Payment/Transaction.php
index 5d7a2efedd93f35bca87d852441edc3c1ac5e07a..40d528fbeb8d5fec707f059b6cb5e7a77c0c6bcc 100644
--- a/app/code/Magento/Sales/Model/Order/Payment/Transaction.php
+++ b/app/code/Magento/Sales/Model/Order/Payment/Transaction.php
@@ -614,8 +614,12 @@ class Transaction extends AbstractModel implements TransactionInterface
     {
         $this->_verifyThisTransactionExists();
         if (null === $this->_paymentObject && $shouldLoad) {
+            /** @var \Magento\Sales\Model\Order\Payment $payment */
             $payment = $this->_paymentFactory->create()->load($this->getPaymentId());
             if ($payment->getId()) {
+                if (!$payment->getOrder()) {
+                    $payment->setOrder($this->getOrder());
+                }
                 $this->setOrderPaymentObject($payment);
             }
         }
diff --git a/app/code/Magento/Ui/Component/AbstractComponent.php b/app/code/Magento/Ui/Component/AbstractComponent.php
index c7af5b3f471c7c084826bc98c45a0ab6c2610cb2..0a15bafe9915faa5aefea6f006e169ea626523db 100644
--- a/app/code/Magento/Ui/Component/AbstractComponent.php
+++ b/app/code/Magento/Ui/Component/AbstractComponent.php
@@ -8,14 +8,13 @@ namespace Magento\Ui\Component;
 use Magento\Framework\Object;
 use Magento\Framework\View\Element\UiComponentInterface;
 use Magento\Framework\View\Element\UiComponent\ContextInterface;
-use Magento\Framework\View\Element\UiComponent\JsConfigInterface;
 use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
 
 /**
  * Abstract class AbstractComponent
  * @SuppressWarnings(PHPMD.NumberOfChildren)
  */
-abstract class AbstractComponent extends Object implements UiComponentInterface, JsConfigInterface
+abstract class AbstractComponent extends Object implements UiComponentInterface
 {
     /**
      * Render context
@@ -227,6 +226,7 @@ abstract class AbstractComponent extends Object implements UiComponentInterface,
      *
      * @param array $dataSource
      * @return void
+     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
      */
     public function prepareDataSource(array & $dataSource)
     {
diff --git a/app/code/Magento/Ui/Component/Container.php b/app/code/Magento/Ui/Component/Container.php
index 6b642b9a3e04525c63ac0df53a8c6113eb44cf66..352dfdf2942bcd5d1557d1f9df5041c588f1074e 100644
--- a/app/code/Magento/Ui/Component/Container.php
+++ b/app/code/Magento/Ui/Component/Container.php
@@ -5,8 +5,6 @@
  */
 namespace Magento\Ui\Component;
 
-use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
-
 /**
  * Class Container
  */
diff --git a/app/code/Magento/Ui/Component/Form.php b/app/code/Magento/Ui/Component/Form.php
index ed0b344658a30c610169de97e9de8aaeb20d41f8..ee1e32e30e07e954786963644079ba439842ae0a 100644
--- a/app/code/Magento/Ui/Component/Form.php
+++ b/app/code/Magento/Ui/Component/Form.php
@@ -5,8 +5,6 @@
  */
 namespace Magento\Ui\Component;
 
-use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
-
 /**
  * Class Form
  */
diff --git a/app/code/Magento/Ui/Component/Form/Element/Multiline.php b/app/code/Magento/Ui/Component/Form/Element/Multiline.php
index 5f508343d4316fbf6b3f788fddab37057d669474..3669cd079a44f56e85d0c816da41f7cdb78b675e 100644
--- a/app/code/Magento/Ui/Component/Form/Element/Multiline.php
+++ b/app/code/Magento/Ui/Component/Form/Element/Multiline.php
@@ -5,6 +5,11 @@
  */
 namespace Magento\Ui\Component\Form\Element;
 
+use Magento\Ui\Component\Form\Field;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+
 /**
  * Class Multiline
  */
@@ -12,6 +17,35 @@ class Multiline extends AbstractElement
 {
     const NAME = 'multiline';
 
+    const FORM_ELEMENT = 'input';
+
+    const DATA_TYPE = 'text';
+
+    /**
+     * UI component factory
+     *
+     * @var UiComponentFactory
+     */
+    protected $uiComponentFactory;
+
+    /**
+     * Constructor
+     *
+     * @param ContextInterface $context
+     * @param UiComponentFactory $uiComponentFactory
+     * @param UiComponentInterface[] $components
+     * @param array $data
+     */
+    public function __construct(
+        ContextInterface $context,
+        UiComponentFactory $uiComponentFactory,
+        array $components = [],
+        array $data = []
+    ) {
+        $this->uiComponentFactory = $uiComponentFactory;
+        parent::__construct($context, $components, $data);
+    }
+
     /**
      * Get component name
      *
@@ -23,10 +57,37 @@ class Multiline extends AbstractElement
     }
 
     /**
-     * @return mixed|string
+     * Prepare component configuration
+     *
+     * @return void
      */
-    public function getType()
+    public function prepare()
     {
-        return $this->getData('input_type') ? $this->getData('input_type') : 'text';
+        $size = abs((int) $this->getData('config/size'));
+        $validation = [$this->getData('config/validation')];
+        while ($size--) {
+            $identifier = $this->getName() . '_' . $size;
+            $arguments = [
+                'data' => [
+                    'name' => $identifier,
+                    'config' => [
+                        'dataScope' => $size,
+                        'dataType' => static::DATA_TYPE,
+                        'formElement' => static::FORM_ELEMENT,
+                        'sortOrder' => $size,
+                    ]
+                ]
+            ];
+
+            if (!empty($validation[$size])) {
+                $arguments['data']['config']['validation'] = $validation[$size];
+            }
+
+            $component = $this->uiComponentFactory->create($identifier, Field::NAME, $arguments);
+            $component->prepare();
+
+            $this->components[$identifier] = $component;
+        }
+        parent::prepare();
     }
 }
diff --git a/app/code/Magento/Ui/Component/Form/Field.php b/app/code/Magento/Ui/Component/Form/Field.php
index 670fa9004b6752f1afad78854824a9a0b66547c3..d2ff377ae5bd4868179d4bef1db12cf640df4fb5 100644
--- a/app/code/Magento/Ui/Component/Form/Field.php
+++ b/app/code/Magento/Ui/Component/Form/Field.php
@@ -80,23 +80,23 @@ class Field extends AbstractComponent
             $formElement,
             array_merge(['context' => $this->getContext()], (array)$this->getData())
         );
+        $this->wrappedComponent->setData(
+            'config',
+            array_replace_recursive(
+                (array) $this->wrappedComponent->getData('config'),
+                (array) $this->getData('config')
+            )
+        );
         $this->wrappedComponent->prepare();
+        $this->components = $this->wrappedComponent->getChildComponents();
         // Merge JS configuration with wrapped component configuration
         $wrappedComponentConfig = $this->getJsConfig($this->wrappedComponent);
-        $jsConfig = array_replace_recursive(
-            $wrappedComponentConfig,
-            $this->getJsConfig($this)
-        );
+
+        $jsConfig = array_replace_recursive($wrappedComponentConfig, $this->getJsConfig($this));
         $jsConfig['extends'] = $this->wrappedComponent->getComponentName();
         $this->setData('js_config', $jsConfig);
 
-        $this->setData(
-            'config',
-            array_replace_recursive(
-                (array)$this->wrappedComponent->getData('config'),
-                (array)$this->getData('config')
-            )
-        );
+        $this->setData('config', $this->wrappedComponent->getData('config'));
 
         parent::prepare();
     }
diff --git a/app/code/Magento/Ui/Component/Form/Fieldset.php b/app/code/Magento/Ui/Component/Form/Fieldset.php
index 00a1b0579e9e8e6767a2fcd17e41ed46be0f2cd1..45d03c005f602734617487639dda3f1f91748d7a 100644
--- a/app/code/Magento/Ui/Component/Form/Fieldset.php
+++ b/app/code/Magento/Ui/Component/Form/Fieldset.php
@@ -5,7 +5,6 @@
  */
 namespace Magento\Ui\Component\Form;
 
-use Magento\Framework\Exception\LocalizedException;
 use Magento\Ui\Component\Container;
 use Magento\Ui\Component\AbstractComponent;
 use Magento\Framework\View\Element\UiComponentFactory;
@@ -104,7 +103,7 @@ class Fieldset extends AbstractComponent
                     'config' => $fieldData
                 ]
             ];
-            $fieldComponent = $this->uiComponentFactory->create($name, 'field', $argument);
+            $fieldComponent = $this->uiComponentFactory->create($name, Field::NAME, $argument);
             $fieldComponent->prepare();
             $this->addComponent($name, $fieldComponent);
         } else {
diff --git a/app/code/Magento/Ui/Component/Layout/Generic.php b/app/code/Magento/Ui/Component/Layout/Generic.php
index 0d8ee7d0cea07c5dcda4197b2dcf68833aa572ae..92d0a406f38e067fd5fc189ae3e1821fd788eeac 100644
--- a/app/code/Magento/Ui/Component/Layout/Generic.php
+++ b/app/code/Magento/Ui/Component/Layout/Generic.php
@@ -6,7 +6,6 @@
 namespace Magento\Ui\Component\Layout;
 
 use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
-use Magento\Framework\View\Element\UiComponent\JsConfigInterface;
 use Magento\Framework\View\Element\UiComponent\LayoutInterface;
 use Magento\Framework\View\Element\UiComponentInterface;
 
diff --git a/app/code/Magento/Ui/Component/Listing.php b/app/code/Magento/Ui/Component/Listing.php
index 7d7d7b692b26042a08d41295f7a24d6536fd1802..363144c10d29a3991d070e65299de367be2425d1 100644
--- a/app/code/Magento/Ui/Component/Listing.php
+++ b/app/code/Magento/Ui/Component/Listing.php
@@ -6,8 +6,6 @@
 namespace Magento\Ui\Component;
 
 use Magento\Ui\Component\Listing\Columns;
-use Magento\Ui\Component\Listing\Columns\Column;
-use Magento\Framework\View\Element\UiComponent\DataSourceInterface;
 
 /**
  * Class Listing
diff --git a/app/code/Magento/Ui/DataProvider/EavValidationRul.php b/app/code/Magento/Ui/DataProvider/EavValidationRules.php
similarity index 96%
rename from app/code/Magento/Ui/DataProvider/EavValidationRul.php
rename to app/code/Magento/Ui/DataProvider/EavValidationRules.php
index 1d338ec30755af34f8653ca99b65f8202b141d7a..28551180b16fb4e33da680fe0f24211639f35bd7 100644
--- a/app/code/Magento/Ui/DataProvider/EavValidationRul.php
+++ b/app/code/Magento/Ui/DataProvider/EavValidationRules.php
@@ -8,9 +8,9 @@ namespace Magento\Ui\DataProvider;
 use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
 
 /**
- * Class EavValidationRul
+ * Class EavValidationRules
  */
-class EavValidationRul
+class EavValidationRules
 {
     /**
      * @var array
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/Field/MultilineTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/Field/MultilineTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..c1e717c1525fed4c226a20a697b0e9ce5f488172
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Unit/Component/Form/Field/MultilineTest.php
@@ -0,0 +1,137 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Test\Unit\Component\Form\Field;
+
+use Magento\Ui\Component\Form\Field;
+use Magento\Ui\Component\Form\Element\Multiline;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+
+/**
+ * Class MultilineTest
+ *
+ * Test for class \Magento\Ui\Component\Form\Element\Multiline
+ */
+class MultilineTest extends \PHPUnit_Framework_TestCase
+{
+    const NAME = 'test-name';
+
+    /**
+     * @var Multiline
+     */
+    protected $multiline;
+
+    /**
+     * @var UiComponentFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $uiComponentFactoryMock;
+
+    /**
+     * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->uiComponentFactoryMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->contextMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponent\ContextInterface')
+            ->getMockForAbstractClass();
+
+        $this->multiline = new Multiline(
+            $this->contextMock,
+            $this->uiComponentFactoryMock
+        );
+    }
+
+    /**
+     * Run test for prepare method
+     *
+     * @param array $data
+     * @return void
+     *
+     * @dataProvider prepareDataProvider
+     */
+    public function testPrepare(array $data)
+    {
+        $this->uiComponentFactoryMock->expects($this->exactly($data['config']['size']))
+            ->method('create')
+            ->with($this->stringContains(self::NAME . '_'), Field::NAME, $this->logicalNot($this->isEmpty()))
+            ->willReturn($this->getComponentMock($data['config']['size']));
+
+        $this->multiline->setData($data);
+        $this->multiline->prepare();
+
+        $result = $this->multiline->getData();
+
+        $this->assertEquals($data, $result);
+    }
+
+    /**
+     * @param int $exactly
+     * @return UiComponentInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected function getComponentMock($exactly)
+    {
+        $componentMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentInterface')
+            ->getMockForAbstractClass();
+
+        $componentMock->expects($this->exactly($exactly))
+            ->method('prepare');
+
+        return $componentMock;
+    }
+
+    /**
+     * Data provider for testPrepare
+     *
+     * @return array
+     */
+    public function prepareDataProvider()
+    {
+        return [
+            [
+                'data' => [
+                    'name' => self::NAME,
+                    'config' => [
+                        'size' => 2,
+                    ]
+                ],
+            ],
+            [
+                'data' => [
+                    'name' => self::NAME,
+                    'config' => [
+                        'size' => 3,
+                    ]
+                ],
+            ],
+            [
+                'data' => [
+                    'name' => self::NAME,
+                    'config' => [
+                        'size' => 1,
+                    ]
+                ],
+            ],
+            [
+                'data' => [
+                    'name' => self::NAME,
+                    'config' => [
+                        'size' => 5,
+                    ]
+                ],
+            ],
+        ];
+    }
+}
diff --git a/app/code/Magento/Ui/Test/Unit/Component/Form/FieldTest.php b/app/code/Magento/Ui/Test/Unit/Component/Form/FieldTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..86a47115d31129abfedb6fe3ceafafc394879912
--- /dev/null
+++ b/app/code/Magento/Ui/Test/Unit/Component/Form/FieldTest.php
@@ -0,0 +1,177 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Ui\Test\Unit\Component\Form;
+
+use Magento\Ui\Component\Form\Field;
+use Magento\Framework\View\Element\UiComponentFactory;
+use Magento\Framework\View\Element\UiComponentInterface;
+use Magento\Framework\View\Element\UiComponent\ContextInterface;
+
+/**
+ * Class FieldTest
+ *
+ * Test for class \Magento\Ui\Component\Form\Field
+ */
+class FieldTest extends \PHPUnit_Framework_TestCase
+{
+    const NAME = 'test-name';
+    const COMPONENT_NAME = 'test-name';
+    const COMPONENT_NAMESPACE = 'test-name';
+
+    /**
+     * @var Field
+     */
+    protected $field;
+
+    /**
+     * @var UiComponentFactory|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $uiComponentFactoryMock;
+
+    /**
+     * @var ContextInterface|\PHPUnit_Framework_MockObject_MockObject
+     */
+    protected $contextMock;
+
+    /**
+     * @var array
+     */
+    protected $testConfigData = [
+        ['config', null, ['test-key' => 'test-value']],
+        ['js_config', null, ['test-key' => 'test-value']]
+    ];
+
+    /**
+     * Set up
+     *
+     * @return void
+     */
+    protected function setUp()
+    {
+        $this->uiComponentFactoryMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentFactory')
+            ->disableOriginalConstructor()
+            ->getMock();
+        $this->contextMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponent\ContextInterface')
+            ->getMockForAbstractClass();
+
+        $this->field = new Field(
+            $this->contextMock,
+            $this->uiComponentFactoryMock
+        );
+    }
+
+    /**
+     * Run test for prepare method
+     *
+     * @param array $data
+     * @param array $expectedData
+     * @return void
+     *
+     * @dataProvider prepareSuccessDataProvider
+     */
+    public function testPrepareSuccess(array $data, array $expectedData)
+    {
+        $this->uiComponentFactoryMock->expects($this->once())
+            ->method('create')
+            ->with(self::NAME, $data['config']['formElement'], $this->arrayHasKey('context'))
+            ->willReturn($this->getWrappedComponentMock());
+
+        $this->contextMock->expects($this->any())
+            ->method('getNamespace')
+            ->willReturn(self::COMPONENT_NAMESPACE);
+
+        $this->field->setData($data);
+        $this->field->prepare();
+        $result = $this->field->getData();
+
+        $this->assertEquals($expectedData, $result);
+    }
+
+    /**
+     * Data provider for testPrepare
+     *
+     * @return array
+     */
+    public function prepareSuccessDataProvider()
+    {
+        return [
+            [
+                'data' => [
+                    'name' => self::NAME,
+                    'config' => [
+                        'formElement' => 'test',
+                    ]
+                ],
+                'expectedData' => [
+                    'name' => self::NAME,
+                    'config' => [
+                        'test-key' => 'test-value',
+                    ],
+                    'js_config' => [
+                        'extends' => self::NAME,
+                        'test-key' => 'test-value',
+                    ]
+                ]
+            ],
+        ];
+    }
+
+    /**
+     * @return \PHPUnit_Framework_MockObject_MockObject|UiComponentInterface
+     */
+    protected function getWrappedComponentMock()
+    {
+        $wrappedComponentMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentInterface')
+            ->getMockForAbstractClass();
+
+        $wrappedComponentMock->expects($this->any())
+            ->method('getData')
+            ->willReturnMap($this->testConfigData);
+        $wrappedComponentMock->expects($this->once())
+            ->method('setData')
+            ->with('config', $this->logicalNot($this->isEmpty()));
+        $wrappedComponentMock->expects($this->once())
+            ->method('prepare');
+        $wrappedComponentMock->expects($this->once())
+            ->method('getChildComponents')
+            ->willReturn($this->getComponentsMock());
+        $wrappedComponentMock->expects($this->exactly(2))
+            ->method('getComponentName')
+            ->willReturn(self::COMPONENT_NAME);
+        $wrappedComponentMock->expects($this->once())
+            ->method('getContext')
+            ->willReturn($this->contextMock);
+
+        return $wrappedComponentMock;
+    }
+
+    /**
+     * @return \PHPUnit_Framework_MockObject_MockObject[]|UiComponentInterface[]
+     */
+    protected function getComponentsMock()
+    {
+        $componentMock = $this->getMockBuilder('Magento\Framework\View\Element\UiComponentInterface')
+            ->getMockForAbstractClass();
+
+        return [$componentMock];
+    }
+
+    /**
+     * Run test prepare method (Exception)
+     *
+     * @return void
+     *
+     * @expectedException \Magento\Framework\Exception\LocalizedException
+     * @expectedExceptionMessage The configuration parameter "formElement" is a required for "test-name" field.
+     */
+    public function testPrepareException()
+    {
+        $this->uiComponentFactoryMock->expects($this->never())
+            ->method('create');
+        $this->field->setData(['name' => self::NAME]);
+        $this->field->prepare();
+    }
+}
diff --git a/app/code/Magento/Ui/etc/ui_components.xsd b/app/code/Magento/Ui/etc/ui_components.xsd
index 86a6f5aaeca39cee9fccbc8f6714446f57d87872..17a80e2f4ac37e725e061d347aeb431e23162244 100644
--- a/app/code/Magento/Ui/etc/ui_components.xsd
+++ b/app/code/Magento/Ui/etc/ui_components.xsd
@@ -177,6 +177,15 @@
             </xs:extension>
         </xs:complexContent>
     </xs:complexType>
+    <xs:complexType name="multiline">
+        <xs:complexContent>
+            <xs:extension base="ui_element">
+                <xs:choice minOccurs="0" maxOccurs="unbounded">
+                    <xs:group ref="configurable"/>
+                </xs:choice>
+            </xs:extension>
+        </xs:complexContent>
+    </xs:complexType>
     <xs:complexType name="fieldset">
         <xs:complexContent>
             <xs:extension base="ui_element">
diff --git a/app/code/Magento/Ui/etc/ui_definition.xsd b/app/code/Magento/Ui/etc/ui_definition.xsd
index 171b3e1b7dbef8660f7cee0d70f38d39cfb3336f..f0154eecb99647f17d7bb96c9c9c7c554806f0d1 100644
--- a/app/code/Magento/Ui/etc/ui_definition.xsd
+++ b/app/code/Magento/Ui/etc/ui_definition.xsd
@@ -39,6 +39,7 @@
             <xs:element type="select" name="select"/>
             <xs:element type="multiselect" name="multiselect"/>
             <xs:element type="textarea" name="textarea"/>
+            <xs:element type="multiline" name="multiline"/>
             <xs:element type="dataTypeText" name="text"/>
             <xs:element type="dataTypeBoolean" name="boolean"/>
             <xs:element type="dataTypeNumber" name="number"/>
diff --git a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml
index 54e661645fec41aba65109bd3025aa626c27cb0b..df5cfa21eca0a080805e940d75726c60f188141f 100644
--- a/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml
+++ b/app/code/Magento/Ui/view/base/ui_component/etc/definition.xml
@@ -178,6 +178,13 @@
             </item>
         </argument>
     </textarea>
+    <multiline class="Magento\Ui\Component\Form\Element\Multiline">
+        <argument name="data" xsi:type="array">
+            <item name="js_config" xsi:type="array">
+                <item name="component" xsi:type="string">Magento_Ui/js/form/components/group</item>
+            </item>
+        </argument>
+    </multiline>
     <!-- Form elements -->
 
     <!-- Form element data types -->
diff --git a/app/code/Magento/Ui/view/base/web/js/form/components/group.js b/app/code/Magento/Ui/view/base/web/js/form/components/group.js
index aeb0ce9db858cc9f7a36dd1c7b41684476830e6b..1e0ff9ac97a3259adc764509c57b49bd379c3a0f 100644
--- a/app/code/Magento/Ui/view/base/web/js/form/components/group.js
+++ b/app/code/Magento/Ui/view/base/web/js/form/components/group.js
@@ -35,7 +35,10 @@ define([
          */
         initObservable: function () {
             this._super()
-                .observe('visible required');
+                .observe('visible')
+                .observe({
+                    required: !!+this.required
+                });
 
             return this;
         },
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 c563b677620382c5b08c868fec60488247f6d359..e342206fe0b6e802e9ccf4e216e16d0cbcddbd22 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
@@ -3657,6 +3657,8 @@ return [
     ['Magento\Centinel\Test\TestCase\CentinelPaymentsValidCcTest'],
     ['Magento\Centinel\CreateOrderTest'],
     ['Magento\Payment\Model\Checks\PaymentMethodChecksInterface', 'Magento\Payment\Model\MethodInterface'],
+    ['Magento\Ui\DataProvider\EavValidationRul', 'Magento\Ui\DataProvider\EavValidationRules'],
+    ['Magento\Framework\View\Element\UiComponent\JsConfigInterface'],
     ['Magento\GiftMessage\Model\Plugin\TotalsDataProcessorPlugin'],
     ['Magento\Catalog\Model\Product\Attribute\Backend\Startdate', 'Magento\Catalog\Model\Attribute\Backend\Startdate'],
 ];
diff --git a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php
index 7e7e27bed013d0205c3f2f00c2112b9ba635b39e..5ea6d07f40505b7aff8d8d9bfeec2bba237410c4 100644
--- a/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php
+++ b/lib/internal/Magento/Framework/View/Element/UiComponent/Config/Provider/Component/Definition.php
@@ -5,7 +5,9 @@
  */
 namespace Magento\Framework\View\Element\UiComponent\Config\Provider\Component;
 
+use Magento\Framework\Phrase;
 use Magento\Framework\Config\CacheInterface;
+use Magento\Framework\Exception\LocalizedException;
 use Magento\Framework\View\Element\UiComponent\Config\Converter;
 use Magento\Framework\View\Element\UiComponent\ArrayObjectFactory;
 use Magento\Framework\View\Element\UiComponent\Config\UiReaderInterface;
@@ -66,9 +68,18 @@ class Definition
      *
      * @param string $name
      * @return array
+     * @throws LocalizedException
      */
     public function getComponentData($name)
     {
+        if (!$this->componentData->offsetExists($name)) {
+            throw new LocalizedException(
+                new Phrase(
+                    'The requested component ("' . $name . '") is not found. '
+                    . 'Before using, you must add the implementation.'
+                )
+            );
+        }
         return (array) $this->componentData->offsetGet($name);
     }
 
diff --git a/lib/internal/Magento/Framework/Webapi/Soap/ClientFactory.php b/lib/internal/Magento/Framework/Webapi/Soap/ClientFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..42d62ab67c334df5d03979441cafad633f0b769d
--- /dev/null
+++ b/lib/internal/Magento/Framework/Webapi/Soap/ClientFactory.php
@@ -0,0 +1,25 @@
+<?php
+/**
+ * Copyright © 2015 Magento. All rights reserved.
+ * See COPYING.txt for license details.
+ */
+namespace Magento\Framework\Webapi\Soap;
+
+/**
+ * Class ClientFactory
+ * @package Magento\Framework\Webapi\Soap
+ */
+class ClientFactory
+{
+    /**
+     * Factory method for \SoapClient
+     *
+     * @param string $wsdl
+     * @param array $options
+     * @return \SoapClient
+     */
+    public function create($wsdl, array $options = [])
+    {
+        return new \SoapClient($wsdl, $options);
+    }
+}