         guard let target = targets.first(where: { $0.name == targetName}) else { throw PBXProjError.targetNotFound(targetName: targetName) }
         
         // Product
-        let productDependency: XCSwiftPackageProductDependency
-        // Avoid duplication
-        if let product = objects.swiftPackageProductDependencies.first(where: { $0.value.productName == productName }) {
-            guard objects.fileReferences.first(where: { $0.value.name == productName })?.value.path == path.string else {
-                throw PBXProjError.multipleLocalPackages(productName: productName)
-            }
-            productDependency = product.value
-        } else {
-            productDependency = XCSwiftPackageProductDependency(productName: productName)
-            objects.add(object: productDependency)
-        }
-        target.packageProductDependencies.append(productDependency)
-
+        let productDependency = try addLocalSwiftPackageProduct(path: path,
+                                                                productName: productName,
+                                                                target: target)
+        
         // Build file
         let buildFile = PBXBuildFile(product: productDependency)
         objects.add(object: buildFile)

        guard let target = targets.first(where: { $0.name == targetName}) else { throw PBXProjError.targetNotFound(targetName: targetName) }
        
        // Reference
        let reference: XCRemoteSwiftPackageReference
        if let package = packages.first(where: { $0.repositoryURL == repositoryURL }) {
            guard package.versionRequirement == versionRequirement else {
                throw PBXProjError.multipleRemotePackages(productName: productName)
            }
            reference = package
        } else {
            reference = XCRemoteSwiftPackageReference(repositoryURL: repositoryURL, versionRequirement: versionRequirement)
            objects.add(object: reference)
            packages.append(reference)
        }

        // Product
        let productDependency: XCSwiftPackageProductDependency
        // Avoid duplication
        if let product = objects.swiftPackageProductDependencies.first(where: { $0.value.package == reference })?.value {
            productDependency = product
        } else {
            productDependency = XCSwiftPackageProductDependency(productName: productName, package: reference)
            objects.add(object: productDependency)
        }
        target.packageProductDependencies.append(productDependency)

        // Build file
        let buildFile = PBXBuildFile(product: productDependency)
        objects.add(object: buildFile)

    }
}

// MARK: - Helpers

extension PBXProject {
    /// Adds reference for remote Swift package
    private func addSwiftPackageReference(repositoryURL: String,
                                          productName: String,
                                          versionRequirement: XCRemoteSwiftPackageReference.VersionRequirement) throws -> XCRemoteSwiftPackageReference {
        let reference: XCRemoteSwiftPackageReference
        if let package = packages.first(where: { $0.repositoryURL == repositoryURL }) {
            guard package.versionRequirement == versionRequirement else {
                throw PBXProjError.multipleRemotePackages(productName: productName)
            }
            reference = package
        } else {
            reference = XCRemoteSwiftPackageReference(repositoryURL: repositoryURL, versionRequirement: versionRequirement)
            try self.objects().add(object: reference)
            packages.append(reference)
        }
        
        return reference
    }
    
    /// Adds package product for remote Swift package
    private func addSwiftPackageProduct(reference: XCRemoteSwiftPackageReference,
                                        productName: String,
                                        target: PBXTarget) throws -> XCSwiftPackageProductDependency {
        let objects = try self.objects()
        
        let productDependency: XCSwiftPackageProductDependency
        // Avoid duplication
        if let product = objects.swiftPackageProductDependencies.first(where: { $0.value.package == reference })?.value {
            productDependency = product
        } else {
            productDependency = XCSwiftPackageProductDependency(productName: productName, package: reference)
            objects.add(object: productDependency)
        }
        target.packageProductDependencies.append(productDependency)
        
        return productDependency
    }
    
    /// Adds package product for local Swift package
    private func addLocalSwiftPackageProduct(path: Path,
                                             productName: String,
                                             target: PBXTarget) throws -> XCSwiftPackageProductDependency {
        let objects = try self.objects()
        
        let productDependency: XCSwiftPackageProductDependency
        // Avoid duplication
        if let product = objects.swiftPackageProductDependencies.first(where: { $0.value.productName == productName }) {
            guard objects.fileReferences.first(where: { $0.value.name == productName })?.value.path == path.string else {
                throw PBXProjError.multipleLocalPackages(productName: productName)
            }
            productDependency = product.value
        } else {
            productDependency = XCSwiftPackageProductDependency(productName: productName)
            objects.add(object: productDependency)
        }
        target.packageProductDependencies.append(productDependency)
        
        return productDependency
    }
}

// MARK: - PlistSerializable

extension PBXProject: PlistSerializable {
