protected function copyViaClient(
        ObjectIdInterface $targetFolderId = null,
        array $properties = [],
        VersioningState $versioningState = null,
        array $policies = [],
        array $addAces = [],
        array $removeAces = []
    ) {
        $newProperties = [];

        $allPropertiesContext = $this->getSession()->createOperationContext();
        $allPropertiesContext->setFilterString('*');
        $allPropertiesContext->setIncludeAcls(false);
        $allPropertiesContext->setIncludeAllowableActions(false);
        $allPropertiesContext->setIncludePathSegments(false);
        $allPropertiesContext->setIncludePolicies(false);
        $allPropertiesContext->setIncludeRelationships(IncludeRelationships::cast(IncludeRelationships::NONE));
        $allPropertiesContext->setRenditionFilterString(Constants::RENDITION_NONE);

        $allPropertiesDocument = $this->getSession()->getObject($this, $allPropertiesContext);
        if (! $allPropertiesDocument instanceof DocumentInterface) {
            throw new CmisRuntimeException('Returned object is not of expected type DocumentInterface');
        }

        foreach ($allPropertiesDocument->getProperties() as $property) {
            if (Updatability::cast(Updatability::READWRITE)->equals($property->getDefinition()->getUpdatability())
                || Updatability::cast(Updatability::ONCREATE)->equals($property->getDefinition()->getUpdatability())
            ) {
                $newProperties[$property->getId()] = $property->isMultiValued() ? $property->getValues(
                ) : $property->getFirstValue();
            }
        }

        $newProperties = array_merge($newProperties, $properties);
        $contentStream = $allPropertiesDocument->getContentStream();

        return $this->getSession()->createDocument(
            $newProperties,
            $targetFolderId,
            $contentStream,
            $versioningState,
            $policies,
            $addAces,
            $removeAces
        );
    }