/**
  * {@inheritdoc}
  */
 public function addChild($productSku, $optionId, \Magento\Bundle\Service\V1\Data\Product\Link $linkedProduct)
 {
     /** @var \Magento\Catalog\Model\Product $product */
     $product = $this->productRepository->get($productSku);
     if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) {
         throw new InputException('Product with specified sku: "%1" is not a bundle product', [$productSku]);
     }
     $options = $this->optionCollection->create();
     $options->setProductIdFilter($product->getId())->joinValues($this->storeManager->getStore()->getId());
     $isNewOption = true;
     /** @var \Magento\Bundle\Model\Option $option */
     foreach ($options as $option) {
         if ($option->getOptionId() == $optionId) {
             $isNewOption = false;
             break;
         }
     }
     if ($isNewOption) {
         throw new InputException('Product with specified sku: "%1" does not contain option: "%2"', [$productSku, $optionId]);
     }
     /* @var $resource \Magento\Bundle\Model\Resource\Bundle */
     $resource = $this->bundleFactory->create();
     $selections = $resource->getSelectionsData($product->getId());
     /** @var \Magento\Catalog\Model\Product $linkProductModel */
     $linkProductModel = $this->productRepository->get($linkedProduct->getSku());
     if ($linkProductModel->isComposite()) {
         throw new InputException('Bundle product could not contain another composite product');
     }
     if ($selections) {
         foreach ($selections as $selection) {
             if ($selection['option_id'] = $optionId && $selection['product_id'] == $linkProductModel->getId()) {
                 throw new CouldNotSaveException('Child with specified sku: "%1" already assigned to product: "%2"', [$linkedProduct->getSku(), $productSku]);
             }
         }
     }
     $selectionModel = $this->bundleSelection->create();
     $selectionModel->setOptionId($optionId)->setPosition($linkedProduct->getPosition())->setSelectionQty($linkedProduct->getQty())->setSelectionPriceType($linkedProduct->getPriceType())->setSelectionPriceValue($linkedProduct->getPrice())->setSelectionCanChangeQty($linkedProduct->getCanChangeQuantity())->setProductId($linkProductModel->getId())->setParentProductId($product->getId())->setIsDefault($linkedProduct->isDefault())->setWebsiteId($this->storeManager->getStore()->getWebsiteId());
     try {
         $selectionModel->save();
     } catch (\Exception $e) {
         throw new CouldNotSaveException('Could not save child: "%1"', [$e->getMessage()], $e);
     }
     return $selectionModel->getId();
 }
 protected function setup()
 {
     $helper = new ObjectManager($this);
     $this->productRepository = $this->getMockBuilder('Magento\\Catalog\\Model\\ProductRepository')->setMethods(['get'])->disableOriginalConstructor()->getMock();
     $this->productData = $this->getMockBuilder('Magento\\Catalog\\Service\\V1\\Data\\Product')->setMethods(['getSku', 'getTypeId', '__wakeup', 'getCustomAttribute'])->disableOriginalConstructor()->getMock();
     $this->product = $this->getMockBuilder('Magento\\Catalog\\Model\\Product')->setMethods(['getSku', 'getTypeId', '__wakeup'])->disableOriginalConstructor()->getMock();
     $this->productLink1 = $this->getMockBuilder('Magento\\Bundle\\Service\\V1\\Data\\Product\\Link')->disableOriginalConstructor()->setMethods(['getId', 'getSku', 'getOptionId'])->getMock();
     $this->productLink1->expects($this->any())->method('getSku')->will($this->returnValue('productLink1Sku'));
     $this->productLink2 = $this->getMockBuilder('Magento\\Bundle\\Service\\V1\\Data\\Product\\Link')->disableOriginalConstructor()->setMethods(['getId', 'getSku', 'getOptionId'])->getMock();
     $this->productLink2->expects($this->any())->method('getSku')->will($this->returnValue('productLink2Sku'));
     $this->productLink3 = $this->getMockBuilder('Magento\\Bundle\\Service\\V1\\Data\\Product\\Link')->disableOriginalConstructor()->setMethods(['getId', 'getSku'])->getMock();
     $this->productLink3->expects($this->any())->method('getSku')->will($this->returnValue('productLink3Sku'));
     $this->productOption1 = $this->getMockBuilder('Magento\\Bundle\\Service\\V1\\Data\\Product\\Option')->disableOriginalConstructor()->getMock();
     $this->productOption1->expects($this->any())->method('getId')->will($this->returnValue('productOption1Sku'));
     $this->productOption2 = $this->getMockBuilder('Magento\\Bundle\\Service\\V1\\Data\\Product\\Option')->disableOriginalConstructor()->getMock();
     $this->productOption2->expects($this->any())->method('getId')->will($this->returnValue('productOption2Sku'));
     $this->linkWriteService = $this->getMockBuilder('Magento\\Bundle\\Service\\V1\\Product\\Link\\WriteService')->disableOriginalConstructor()->getMock();
     $this->optionWriteService = $this->getMockBuilder('Magento\\Bundle\\Service\\V1\\Product\\Option\\WriteService')->disableOriginalConstructor()->getMock();
     $this->linkReadService = $this->getMockBuilder('Magento\\Bundle\\Service\\V1\\Product\\Link\\ReadService')->disableOriginalConstructor()->getMock();
     $this->optionReadService = $this->getMockBuilder('Magento\\Bundle\\Service\\V1\\Product\\Option\\ReadService')->disableOriginalConstructor()->getMock();
     $this->productBuilder = $this->getMockBuilder('Magento\\Catalog\\Service\\V1\\Data\\ProductBuilder')->setMethods(['setCustomAttribute'])->disableOriginalConstructor()->getMock();
     $this->attributeValue = $this->getMockBuilder('Magento\\Framework\\Service\\Data\\Eav\\AttributeValue')->setMethods(['getValue'])->disableOriginalConstructor()->getMock();
     $this->saveProcessor = $helper->getObject('Magento\\Bundle\\Service\\V1\\Product\\BundleProductSaveProcessor', ['linkWriteService' => $this->linkWriteService, 'optionWriteService' => $this->optionWriteService, 'linkReadService' => $this->linkReadService, 'optionReadService' => $this->optionReadService, 'productRepository' => $this->productRepository]);
 }
 /**
  * Compare two links and determine if they are equal
  *
  * @param Link $firstLink
  * @param Link $secondLink
  * @return int
  */
 private function compareLinks(Link $firstLink, Link $secondLink)
 {
     if ($firstLink->getSku() == $secondLink->getSku()) {
         return 0;
     } else {
         return 1;
     }
 }