private CopyStates copyInternal(final Context context, final NotificationCompat.Builder notification, final Runnable updateForegroundNotification, final boolean isZipFile, final String nameWithinZip, final boolean potentiallyKeepTemporaryFile) {
        boolean keepTemporaryFile = potentiallyKeepTemporaryFile && Settings.getMapDownloadsKeepTemporaryFiles();
        CopyStates status = CopyStates.UNKNOWN_STATE;

        Log.d("start receiving map file: " + filename);
        InputStream inputStream = null;
        final Uri outputUri = ContentStorage.get().create(downloader.targetFolder, filename);

        try {
            inputStream = new BufferedInputStream(context.getContentResolver().openInputStream(uri));
            if (isZipFile) {
                try (ZipInputStream zis = new ZipInputStream(inputStream)) {
                    ZipEntry ze;
                    boolean stillSearching = true;
                    while (stillSearching && (ze = zis.getNextEntry()) != null) {
                        if (ze.getName().equals(nameWithinZip)) {
                            status = doCopy(context, notification, updateForegroundNotification, zis, outputUri);
                            stillSearching = false; // don't continue here, as doCopy also closes the input stream, so further reads would lead to IOException
                        }
                    }
                } catch (IOException e) {
                    Log.e("IOException on receiving map file: " + e.getMessage());
                    status = CopyStates.IO_EXCEPTION;
                }
            } else {
                status = doCopy(context, notification, updateForegroundNotification, inputStream, outputUri);
                keepTemporaryFile = false;
            }
            if (status == CopyStates.SUCCESS && !downloader.verifiedAfterCopying(filename, outputUri)) {
                status = CopyStates.INTEGRITY_CHECK_ERROR;
                cancelled.set(true);
            }
        } catch (SecurityException e) {
            Log.e("SecurityException on receiving map file: " + e.getMessage());
            return CopyStates.FILENOTFOUND_EXCEPTION;
        } catch (FileNotFoundException e) {
            return CopyStates.FILENOTFOUND_EXCEPTION;
        } finally {
            IOUtils.closeQuietly(inputStream);
        }

        // clean up
        if (!cancelled.get()) {
            if (status == CopyStates.SUCCESS) {
                // having successfully received the copy we can delete the temporary copy
                try {
                    if (!keepTemporaryFile) {
                        context.getContentResolver().delete(uri, null, null);
                    }
                } catch (IllegalArgumentException | UnsupportedOperationException e) {
                    Log.w("Deleting Uri '" + uri + "' failed, will be ignored", e);
                }
                // finalization AFTER deleting source file. This handles the very special case when target folder = Download folder
                downloader.onSuccessfulReceive(outputUri);
            } else {
                // delete partial copy, but don't change status
                ContentStorage.get().delete(outputUri);
            }
        } else {
            // delete partial copy, set status to CANCELLED
            ContentStorage.get().delete(outputUri);
            status = CopyStates.CANCELLED;
        }

        return status;
    }
check whether the target file or its companion file already exist, and delete both, if so
main/src/main/java/cgeo/geocaching/downloader/ReceiveDownload.java