private function moveFile(SplFileInfo $file, $targetDir, $logging, $ioHandler)
    {
        $pathName        = $file->getPathname();
        $destinationFile = str_replace($this->tempDir, $targetDir, $pathName);

        // Symlink must(!) be handled first as the isDir() and isFile() checks return true for symlinks.
        if ($file->isLink()) {
            $target = $file->getLinkTarget();
            if ($logging) {
                $ioHandler->write(sprintf('link %s to %s', $target, $destinationFile));
            }
            symlink($target, $destinationFile);
            unlink($pathName);

            return;
        }

        if ($file->isDir()) {
            $permissions     = substr(decoct(fileperms($pathName)), 1);
            $this->folders[] = $pathName;
            if (!is_dir($destinationFile)) {
                if ($logging) {
                    $ioHandler->write(sprintf('mkdir %s (permissions: %s)', $pathName, $permissions));
                }
                mkdir($destinationFile, octdec($permissions), true);
            }

            return;
        }

        if ($file->isFile()) {
            $permissions = substr(decoct(fileperms($pathName)), 1);
            if ($logging) {
                $ioHandler->write(
                    sprintf('move %s to %s (permissions: %s)', $pathName, $destinationFile, $permissions)
                );
            }
            copy($pathName, $destinationFile);
            chmod($destinationFile, octdec($permissions));
            unlink($pathName);

            return;
        }

        throw new \RuntimeException(
            sprintf(
                'Unknown file of type %s encountered for %s',
                filetype($pathName),
                $pathName
            )
        );
    }