/**
  * {@inheritdoc}
  * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  */
 public function save(\Magento\Customer\Api\Data\CustomerInterface $customer, $passwordHash = null)
 {
     $this->validate($customer);
     $origAddresses = $customer->getAddresses();
     $customer->setAddresses([]);
     $customerData = $this->extensibleDataObjectConverter->toNestedArray($customer, [], '\\Magento\\Customer\\Api\\Data\\CustomerInterface');
     $customer->setAddresses($origAddresses);
     $customerModel = $this->customerFactory->create(['data' => $customerData]);
     $storeId = $customerModel->getStoreId();
     if ($storeId === null) {
         $customerModel->setStoreId($this->storeManager->getStore()->getId());
     }
     $customerModel->setId($customer->getId());
     // Need to use attribute set or future updates can cause data loss
     if (!$customerModel->getAttributeSetId()) {
         $customerModel->setAttributeSetId(\Magento\Customer\Api\CustomerMetadataInterface::ATTRIBUTE_SET_ID_CUSTOMER);
     }
     // Populate model with secure data
     if ($customer->getId()) {
         /*
          * TODO: Check \Magento\Customer\Model\Resource\Customer::changeResetPasswordLinkToken setAttribute
          * and make sure its consistent
          */
         $customerSecure = $this->customerRegistry->retrieveSecureData($customer->getId());
         $customerModel->setRpToken($customerSecure->getRpToken());
         $customerModel->setRpTokenCreatedAt($customerSecure->getRpTokenCreatedAt());
         $customerModel->setPasswordHash($customerSecure->getPasswordHash());
     } else {
         if ($passwordHash) {
             $customerModel->setPasswordHash($passwordHash);
         }
     }
     $this->customerResourceModel->save($customerModel);
     $this->customerRegistry->push($customerModel);
     $customerId = $customerModel->getId();
     if ($customer->getAddresses() !== null) {
         if ($customer->getId()) {
             $existingAddresses = $this->getById($customer->getId())->getAddresses();
             $getIdFunc = function ($address) {
                 return $address->getId();
             };
             $existingAddressIds = array_map($getIdFunc, $existingAddresses);
         } else {
             $existingAddressIds = [];
         }
         $savedAddressIds = [];
         foreach ($customer->getAddresses() as $address) {
             $address->setCustomerId($customerId)->setRegion($address->getRegion());
             $this->addressRepository->save($address);
             if ($address->getId()) {
                 $savedAddressIds[] = $address->getId();
             }
         }
         $addressIdsToDelete = array_diff($existingAddressIds, $savedAddressIds);
         foreach ($addressIdsToDelete as $addressId) {
             $this->addressRepository->deleteById($addressId);
         }
     }
     $savedCustomer = $this->get($customer->getEmail(), $customer->getWebsiteId());
     $this->eventManager->dispatch('customer_save_after_data_object', ['customer_data_object' => $savedCustomer, 'orig_customer_data_object' => $customer]);
     return $savedCustomer;
 }