// Path: src/main/java/org/dataloader/DataLoaderFactory.java
// public static <K, V> DataLoader<K, V> newDataLoader(BatchLoader<K, V> batchLoadFunction) {
//     return newDataLoader(batchLoadFunction, null);
// }
// 
// Path: src/main/java/org/dataloader/DataLoaderFactory.java
// public static <K, V> DataLoader<K, V> newMappedDataLoader(MappedBatchLoader<K, V> batchLoadFunction) {
//     return newMappedDataLoader(batchLoadFunction, null);
// }


import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.dataloader.DataLoaderFactory.newDataLoader;
import static org.dataloader.DataLoaderFactory.newMappedDataLoader;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;

    @Test
    public void missing_key_contexts_are_passed_to_batch_loader_function() {
        BatchLoaderWithContext<String, String> batchLoader = contextBatchLoader();
        DataLoaderOptions options = DataLoaderOptions.newOptions()
                .setBatchLoaderContextProvider(() -> "ctx");
        DataLoader<String, String> loader = newDataLoader(batchLoader, options);

        loader.load("A", "aCtx");
        loader.load("B");
        loader.loadMany(asList("C", "D"), singletonList("cCtx"));

        List<String> results = loader.dispatchAndJoin();

        assertThat(results, equalTo(asList("A-ctx-m:aCtx-l:aCtx", "B-ctx-m:null-l:null", "C-ctx-m:cCtx-l:cCtx", "D-ctx-m:null-l:null")));
    }

    @Test
    public void context_is_passed_to_map_batch_loader_function() {
        MappedBatchLoaderWithContext<String, String> mapBatchLoader = (keys, environment) -> {
            Map<String, String> map = new HashMap<>();
            keys.forEach(k -> {
                Object context = environment.getContext();
                Object keyContext = environment.getKeyContexts().get(k);
                map.put(k, k + "-" + context + "-" + keyContext);
            });
            return CompletableFuture.completedFuture(map);
        };
        DataLoaderOptions options = DataLoaderOptions.newOptions()
                .setBatchLoaderContextProvider(() -> "ctx");
// Path: src/main/java/org/dataloader/DataLoaderFactory.java
// public static <K, V> DataLoader<K, V> newDataLoader(BatchLoader<K, V> batchLoadFunction) {
//     return newDataLoader(batchLoadFunction, null);
// }
// 
// Path: src/main/java/org/dataloader/DataLoaderFactory.java
// public static <K, V> DataLoader<K, V> newMappedDataLoader(MappedBatchLoader<K, V> batchLoadFunction) {
//     return newMappedDataLoader(batchLoadFunction, null);
// }


// Path: src/test/java/org/dataloader/DataLoaderBatchLoaderEnvironmentTest.java
import org.junit.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import static java.util.Arrays.asList;
import static java.util.Collections.singletonList;
import static org.dataloader.DataLoaderFactory.newDataLoader;
import static org.dataloader.DataLoaderFactory.newMappedDataLoader;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;


    @Test
    public void missing_key_contexts_are_passed_to_batch_loader_function() {
        BatchLoaderWithContext<String, String> batchLoader = contextBatchLoader();
        DataLoaderOptions options = DataLoaderOptions.newOptions()
                .setBatchLoaderContextProvider(() -> "ctx");
        DataLoader<String, String> loader = newDataLoader(batchLoader, options);

        loader.load("A", "aCtx");
        loader.load("B");
        loader.loadMany(asList("C", "D"), singletonList("cCtx"));

        List<String> results = loader.dispatchAndJoin();

        assertThat(results, equalTo(asList("A-ctx-m:aCtx-l:aCtx", "B-ctx-m:null-l:null", "C-ctx-m:cCtx-l:cCtx", "D-ctx-m:null-l:null")));
    }

    @Test
    public void context_is_passed_to_map_batch_loader_function() {
        MappedBatchLoaderWithContext<String, String> mapBatchLoader = (keys, environment) -> {
            Map<String, String> map = new HashMap<>();
            keys.forEach(k -> {
                Object context = environment.getContext();
                Object keyContext = environment.getKeyContexts().get(k);
                map.put(k, k + "-" + context + "-" + keyContext);
            });
            return CompletableFuture.completedFuture(map);
        };
        DataLoaderOptions options = DataLoaderOptions.newOptions()
                .setBatchLoaderContextProvider(() -> "ctx");
        DataLoader<String, String> loader = newMappedDataLoader(mapBatchLoader, options);