class AbstractNearbyDistanceMatrixDemand<Origin_, Destination_, ChildSelector_, ReplayingSelector_>
        implements Demand<NearbyDistanceMatrix<Origin_, Destination_>> {

    protected final NearbyDistanceMeter<Origin_, Destination_> meter;
    protected final NearbyRandom random;
    protected final ChildSelector_ childSelector;
    protected final ReplayingSelector_ replayingSelector;

    protected AbstractNearbyDistanceMatrixDemand(NearbyDistanceMeter<Origin_, Destination_> meter, NearbyRandom random,
            ChildSelector_ childSelector, ReplayingSelector_ replayingSelector) {
        this.meter = meter;
        this.random = random;
        this.childSelector = childSelector;
        this.replayingSelector = replayingSelector;
    }

    @Override
    public final NearbyDistanceMatrix<Origin_, Destination_> createExternalizedSupply(SupplyManager supplyManager) {
        return supplyNearbyDistanceMatrix();
    }

    protected abstract NearbyDistanceMatrix<Origin_, Destination_> supplyNearbyDistanceMatrix();

    /**
     * Two instances of this class are considered equal if and only if:
     *
     * <ul>
     * <li>Their meter instances are equal.</li>
     * <li>Their nearby randoms represent the same distribution.</li>
     * <li>Their child selectors are equal.</li>
     * <li>Their replaying origin entity selectors are equal.</li>
     * </ul>
     *
     * Otherwise as defined by {@link Object#equals(Object)}.
     *
     * @see ClassInstanceCache for how we ensure equality for meter instances in particular and selectors in general.
     */
    @Override
    public final boolean equals(Object o) {<FILL_FUNCTION_BODY>}

    @Override
    public final int hashCode() {
        return Objects.hash(meter, random, childSelector, replayingSelector);
    }
}

        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;
        AbstractNearbyDistanceMatrixDemand<?, ?, ?, ?> that = (AbstractNearbyDistanceMatrixDemand<?, ?, ?, ?>) o;
        return Objects.equals(meter, that.meter)
                && Objects.equals(random, that.random)
                && Objects.equals(childSelector, that.childSelector)
                && Objects.equals(replayingSelector, that.replayingSelector);
    
<no_super_class>