class ImageImportProcessor implements FileImportProcessor {

    @NonNull
    @Override
    public Single<File> process(@NonNull final Uri uri) {
        return Single.create(emitter -> {
            InputStream inputStream = null;
            try {
                inputStream = mContentResolver.openInputStream(uri);
                if (inputStream != null) {
                    final int scale = getImageScaleFactor(uri);

                    // Get scaled bitmap
                    final BitmapFactory.Options smallerOpts = new BitmapFactory.Options();
                    smallerOpts.inSampleSize = scale;
                    Bitmap bitmap = BitmapFactory.decodeStream(inputStream, null, smallerOpts);

                    // Checking if this file is actual image
                    if (smallerOpts.outHeight <= 0 && smallerOpts.outWidth <= 0) {
                        emitter.onError(new InvalidImageException("Looks like selected file is not an image"));
                        return;
                    }

                    // Perform image processing
                    if (mPreferences.get(UserPreference.Camera.SaveImagesInGrayScale)) {
                        bitmap = ImageUtils.convertToGrayScale(bitmap);
                    }

                    if (mPreferences.get(UserPreference.Camera.AutomaticallyRotateImages)) {
                        Logger.debug(ImageImportProcessor.this, "Configured for auto-rotation. Attempting to determine the orientation");
                        int orientation = getOrientationFromMediaStore(uri);

                        if (orientation == ExifInterface.ORIENTATION_UNDEFINED) {
                            Logger.warn(ImageImportProcessor.this, "Failed to fetch orientation information from the content store. Trying from Exif.");
                            InputStream exifInputStream = null; // Note: Re-open to avoid issues with #reset()
                            try {
                                exifInputStream = mContentResolver.openInputStream(uri);
                                if (exifInputStream != null) {
                                    final ExifInterface exif = new ExifInterface(exifInputStream);
                                    orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_UNDEFINED);
                                    Logger.info(ImageImportProcessor.this, "Read exif orientation as {}", orientation);
                                }
                            } catch (IOException e) {
                                Logger.error(ImageImportProcessor.this, "An Exif parsing exception occurred", e);
                            } finally {
                                StorageManager.closeQuietly(exifInputStream);
                            }
                        }

                        if (orientation != ExifInterface.ORIENTATION_UNDEFINED) {
                            Logger.info(ImageImportProcessor.this, "Image orientation determined as {}. Rotating...", orientation);
                            bitmap = ImageUtils.rotateBitmap(bitmap, orientation);
                        } else {
                            Logger.warn(ImageImportProcessor.this, "Indeterminate orientation. Skipping rotation");
                        }
                    } else {
                        Logger.info(ImageImportProcessor.this, "Image import rotation is disabled. Ignoring...");
                    }

                    if (bitmap != null) {
                        final File destination = mStorageManner.getFile(mTrip.getDirectory(), System.currentTimeMillis() + ".jpg");
                        final Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG;

                        if (!mStorageManner.writeBitmap(Uri.fromFile(destination), bitmap, compressFormat, COMPRESSION_QUALITY)) {
                            Logger.error(ImageImportProcessor.this, "Failed to write the image data. Aborting");
                            emitter.onError(new IOException("Failed to write the image data. Aborting"));
                        } else {
                            Logger.info(ImageImportProcessor.this, "Successfully saved the image to {}.", destination);
                            emitter.onSuccess(destination);
                        }
                    }
                } else {
                    emitter.onError(new FileNotFoundException());
                }
            } catch (IOException e) {
                emitter.onError(e);
            } finally {
                StorageManager.closeQuietly(inputStream);
            }
        });
    }

    public  ImageImportProcessor(@NonNull Trip trip, @NonNull StorageManager storageManager, @NonNull UserPreferenceManager preferences, @NonNull Context context);
    public  ImageImportProcessor(@NonNull Trip trip, @NonNull StorageManager storageManager, @NonNull UserPreferenceManager preferences, @NonNull Context context, @NonNull ContentResolver contentResolver);

}