// Path: src/main/java/com/shapesecurity/bandolier/es2017/ModuleWrapper.java
// public class ModuleWrapper {
// 	@Nonnull
// 	public Module module;
// 
// 	public ModuleWrapper(@Nonnull Module module) {
// 		this.module = module;
// 	}
// }


import com.shapesecurity.bandolier.es2017.ModuleWrapper;
import com.shapesecurity.functional.Pair;
import com.shapesecurity.functional.data.HashTable;
import com.shapesecurity.functional.data.ImmutableList;
import com.shapesecurity.functional.data.ImmutableSet;
import com.shapesecurity.functional.data.Maybe;
import com.shapesecurity.functional.data.MultiHashTable;
import com.shapesecurity.shift.es2017.ast.AssignmentTargetIdentifier;
import com.shapesecurity.shift.es2017.ast.IdentifierExpression;
import com.shapesecurity.shift.es2017.ast.Module;
import com.shapesecurity.shift.es2017.reducer.Director;
import com.shapesecurity.shift.es2017.scope.GlobalScope;
import com.shapesecurity.shift.es2017.scope.Reference;
import com.shapesecurity.shift.es2017.scope.ScopeAnalyzer;
import com.shapesecurity.shift.es2017.scope.ScopeLookup;
import com.shapesecurity.shift.es2017.scope.Variable;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
		});
	}

	private static <K extends Comparable<K>, V> ImmutableList<Pair<K, V>> orderedEntries(@Nonnull HashTable<K, V> table) {
		ArrayList<Pair<K, V>> entries = new ArrayList<>(table.length);
		for (Pair<K, V> entry : table) {
			entries.add(entry);
		}
		entries.sort(Comparator.comparing(p -> p.left));
		return ImmutableList.from(entries);
	}

	public static ResolvedResult resolveCollisions(@Nonnull HashTable<String, ModuleWrapper> modules) {
		HashTable<ModuleWrapper, GlobalScope> globalScopes = modules.foldLeft((acc, pair) -> acc.put(pair.right, ScopeAnalyzer.analyze(pair.right.module)), HashTable.emptyUsingIdentity());
		HashTable<ModuleWrapper, ScopeLookup> scopeLookups = modules.foldLeft((acc, pair) -> acc.put(pair.right, new ScopeLookup(globalScopes.get(pair.right).fromJust())), HashTable.emptyUsingIdentity());
		ImmutableSet<String> allNames = modules.foldLeft((acc, module) -> acc.union(VariableReferenceExtractor.extractAllReferencedVariableNames(globalScopes.get(module.right).fromJust())), ImmutableSet.emptyUsingEquality());
		ImmutableList<ModuleWrapper> sortedModules = ImmutableList.from(StreamSupport.stream(modules.entries().spliterator(), false).sorted(Comparator.comparing(pair1 -> pair1.left)).map(pair -> pair.right).collect(Collectors.toList()));

		HashTable<String, ImmutableList<Pair<ModuleWrapper, ImmutableList<Variable>>>> allDeclaredVariables = sortedModules.foldLeft((acc, module) ->
			VariableDeclarationExtractor.extractAllDeclaredVariables(globalScopes.get(module).fromJust()).entries()
				.foldLeft((subAcc, pair) ->
					subAcc.put(pair.left, Pair.of(
						module,
						pair.right
					)),
					acc
				),
			MultiHashTable.<String, Pair<ModuleWrapper, ImmutableList<Variable>>>emptyUsingEquality()
		).toHashTable(list -> list);

// Path: src/main/java/com/shapesecurity/bandolier/es2017/ModuleWrapper.java
// public class ModuleWrapper {
// 	@Nonnull
// 	public Module module;
// 
// 	public ModuleWrapper(@Nonnull Module module) {
// 		this.module = module;
// 	}
// }


// Path: src/main/java/com/shapesecurity/bandolier/es2017/transformations/VariableCollisionResolver.java
import com.shapesecurity.bandolier.es2017.ModuleWrapper;
import com.shapesecurity.functional.Pair;
import com.shapesecurity.functional.data.HashTable;
import com.shapesecurity.functional.data.ImmutableList;
import com.shapesecurity.functional.data.ImmutableSet;
import com.shapesecurity.functional.data.Maybe;
import com.shapesecurity.functional.data.MultiHashTable;
import com.shapesecurity.shift.es2017.ast.AssignmentTargetIdentifier;
import com.shapesecurity.shift.es2017.ast.IdentifierExpression;
import com.shapesecurity.shift.es2017.ast.Module;
import com.shapesecurity.shift.es2017.reducer.Director;
import com.shapesecurity.shift.es2017.scope.GlobalScope;
import com.shapesecurity.shift.es2017.scope.Reference;
import com.shapesecurity.shift.es2017.scope.ScopeAnalyzer;
import com.shapesecurity.shift.es2017.scope.ScopeLookup;
import com.shapesecurity.shift.es2017.scope.Variable;
import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;

		});
	}

	private static <K extends Comparable<K>, V> ImmutableList<Pair<K, V>> orderedEntries(@Nonnull HashTable<K, V> table) {
		ArrayList<Pair<K, V>> entries = new ArrayList<>(table.length);
		for (Pair<K, V> entry : table) {
			entries.add(entry);
		}
		entries.sort(Comparator.comparing(p -> p.left));
		return ImmutableList.from(entries);
	}

	public static ResolvedResult resolveCollisions(@Nonnull HashTable<String, ModuleWrapper> modules) {
		HashTable<ModuleWrapper, GlobalScope> globalScopes = modules.foldLeft((acc, pair) -> acc.put(pair.right, ScopeAnalyzer.analyze(pair.right.module)), HashTable.emptyUsingIdentity());
		HashTable<ModuleWrapper, ScopeLookup> scopeLookups = modules.foldLeft((acc, pair) -> acc.put(pair.right, new ScopeLookup(globalScopes.get(pair.right).fromJust())), HashTable.emptyUsingIdentity());
		ImmutableSet<String> allNames = modules.foldLeft((acc, module) -> acc.union(VariableReferenceExtractor.extractAllReferencedVariableNames(globalScopes.get(module.right).fromJust())), ImmutableSet.emptyUsingEquality());
		ImmutableList<ModuleWrapper> sortedModules = ImmutableList.from(StreamSupport.stream(modules.entries().spliterator(), false).sorted(Comparator.comparing(pair1 -> pair1.left)).map(pair -> pair.right).collect(Collectors.toList()));

		HashTable<String, ImmutableList<Pair<ModuleWrapper, ImmutableList<Variable>>>> allDeclaredVariables = sortedModules.foldLeft((acc, module) ->
			VariableDeclarationExtractor.extractAllDeclaredVariables(globalScopes.get(module).fromJust()).entries()
				.foldLeft((subAcc, pair) ->
					subAcc.put(pair.left, Pair.of(
						module,
						pair.right
					)),
					acc
				),
			MultiHashTable.<String, Pair<ModuleWrapper, ImmutableList<Variable>>>emptyUsingEquality()
		).toHashTable(list -> list);

		ImmutableList<Pair<String, ImmutableList<Pair<ModuleWrapper, ImmutableList<Variable>>>>> allDeclaredVariablesEntriesSorted =