@@ -0,0 +1,3135 @@
+package org.axonframework.serialization.upcasting;%0A%0Aimport static java.util.Objects.requireNonNull;%0A%0Aimport java.util.stream.Stream;%0A%0A/**%0A * Abstract implementation of an %7B@link Upcaster%7D that eases the common process of upcasting one intermediate%0A * representation to another representation by applying a simple mapping function to the input stream of intermediate%0A * representations.%0A * Additionally, it's a context aware implementation, which enables it to store and reuse context information from one%0A * entry to another during upcasting.%0A *%0A * @param %3CT%3E the type of entry to be upcasted as %7B@code T%7D%0A * @param %3CC%3E the type of context used as %7B@code C%7D%0A *%0A * @author Steven van Beelen%0A */%0Apublic abstract class ContextAwareSingleEntryUpcaster%3CT, C%3E implements Upcaster%3CT%3E %7B%0A%0A    @Override%0A    public Stream%3CT%3E upcast(Stream%3CT%3E intermediateRepresentations) %7B%0A        C context = buildContext();%0A%0A        return intermediateRepresentations.map(entry -%3E %7B%0A            if (!canUpcast(entry, context)) %7B%0A                return entry;%0A            %7D%0A            return requireNonNull(doUpcast(entry, context),%0A                                  %22Result from #doUpcast() should not be null. To remove an %22 +%0A                                          %22intermediateRepresentation add a filter to the input stream.%22);%0A        %7D);%0A    %7D%0A%0A    /**%0A     * Checks if this upcaster can upcast the given %7B@code intermediateRepresentation%7D.%0A     * If the upcaster cannot upcast the representation the %7B@link #doUpcast(Object, Object)%7D is not invoked.%0A     * The %7B@code context%7D can be used to store or retrieve entry specific information required to make the%0A     * %7B@code canUpcast(Object, Object)%7D check.%0A     *%0A     * @param intermediateRepresentation the intermediate object representation to upcast as %7B@code T%7D%0A     * @param context                    the context for this upcaster as %7B@code C%7D%0A     * @return %7B@code true%7D if the representation can be upcast, %7B@code false%7D otherwise%0A     */%0A    protected abstract boolean canUpcast(T intermediateRepresentation, C context);%0A%0A    /**%0A     * Upcasts the given %7B@code intermediateRepresentation%7D. This method is only invoked if %7B@link #canUpcast(Object,%0A     * Object)%7D returned %7B@code true%7D for the given representation. The %7B@code context%7D can be used to store or retrieve%0A     * entry specific information required to perform the upcasting process.%0A     * %3Cp%3E%0A     * Note that the returned representation should not be %7B@code null%7D.%0A     * To remove an intermediateRepresentation add a filter to the input stream.%0A     *%0A     * @param intermediateRepresentation the representation of the object to upcast as %7B@code T%7D%0A     * @param context                    the context for this upcaster as %7B@code C%7D%0A     * @return the upcasted representation%0A     */%0A    protected abstract T doUpcast(T intermediateRepresentation, C context);%0A%0A    /**%0A     * Builds a context of generic type %7B@code C%7D to be used when processing the stream of intermediate object%0A     * representations %7B@code T%7D.%0A     *%0A     * @return a context of generic type %7B@code C%7D%0A     */%0A    protected abstract C buildContext();%0A%0A%7D%0A

Introduce ContextAwareSingleEntryUpcaster