class ReceiptTableActionAlterations extends StubTableActionAlterations<Receipt> {

    @NonNull
    @Override
    public Single<Receipt> preUpdate(@NonNull final Receipt oldReceipt, @NonNull final Receipt newReceipt) {
        return receiptsTable.get(newReceipt.getTrip())
                .map(existingReceipts -> {
                    final ReceiptBuilderFactory factory = receiptBuilderFactoryFactory.build(newReceipt);
                    if (!oldReceipt.getDate().equals(newReceipt.getDate()) || !oldReceipt.getTimeZone().equals(newReceipt.getTimeZone())) {
                        // If the receipt date/timezone changed, update the custom order id
                        // Note: This approach isn't as strictly correct as the reorderReceiptsInList option, but it greatly simplifies our dependency chain
                        // Since this is relatively rare (and can lead to a cyclic dependency), we use this to get the best guess for the next one
                        final long customOrderId = ReceiptsOrderer.getCustomOrderId(newReceipt, existingReceipts);
                        factory.setCustomOrderId(customOrderId);
                    }

                    if (newReceipt.getFile() != null) {
                        // If new receipt has a file, check if we need to update our file name
                        if (!newReceipt.getFile().equals(oldReceipt.getFile())) {
                            // If we changed the receipt file, replace the old file name
                            if (oldReceipt.getFile() != null) {
                                final String oldExtension = "." + UriUtils.getExtension(oldReceipt.getFile(), context);
                                final String newExtension = "." + UriUtils.getExtension(newReceipt.getFile(), context);
                                if (newExtension.equals(oldExtension)) {
                                    picasso.get().invalidate(oldReceipt.getFile());
                                    if (newReceipt.getFile().renameTo(oldReceipt.getFile())) {
                                        // Note: Use 'oldReceipt' here, since File is immutable (and renamedTo doesn't change it)
                                        factory.setFile(oldReceipt.getFile());
                                    }
                                } else {
                                    final String renamedNewFileName = oldReceipt.getFile().getName().replace(oldExtension, newExtension);
                                    final String renamedNewFilePath = newReceipt.getFile().getAbsolutePath().replace(newReceipt.getFile().getName(), renamedNewFileName);
                                    final File renamedNewFile = new File(renamedNewFilePath);
                                    if (newReceipt.getFile().renameTo(renamedNewFile)) {
                                        factory.setFile(renamedNewFile);
                                    }
                                }
                                return factory.build();
                            } else {
                                return updateReceiptFileNameBlocking(factory.build());
                            }
                        } else if (newReceipt.getIndex() != oldReceipt.getIndex()) {
                            return updateReceiptFileNameBlocking(factory.build());
                        } else {
                            return factory.build();
                        }
                    } else {
                        return factory.build();
                    }
                });
    }

    public  ReceiptTableActionAlterations(@NonNull Context context,
                                         @NonNull ReceiptsTable receiptsTable,
                                         @NonNull StorageManager storageManager,
                                         @NonNull Lazy<Picasso> picasso);
      ReceiptTableActionAlterations(@NonNull Context context,
                                  @NonNull ReceiptsTable receiptsTable,
                                  @NonNull StorageManager storageManager,
                                  @NonNull BuilderFactory1<Receipt, ReceiptBuilderFactory> receiptBuilderFactoryFactory,
                                  @NonNull Lazy<Picasso> picasso);

}