Based on CubeNetImpl, write CubeImpl and CubeSolver in Java language package model; import java.util.Set; public interface Cube { public Set getAllPossibleCubeNets(); } package model; import java.awt.Color; public interface CubeNet { public Color getTop(); public Color getFront(); public Color getRight(); public Color getBack(); public Color getLeft(); public Color getBottom(); } package model; public enum Face { TOP, FRONT, RIGHT, BACK, LEFT, BOTTOM; } package model; public class CubeNetImpl implements CubeNet { private Color top; private Color front; private Color right; private Color left; private Color bottom; private Color back; private Set> allPossibleMaps = null; private Integer hashCode = null; private static long timeSpentHashCode = 0; private static long timeSpentInSetAddMillis = 0; private static boolean CALCULATE_POSSIBLE_MAPS_ONE_TIME = false; private static boolean CALCULATE_HASHCODE_ONE_TIME = false; private static int HASHCODE_LEVEL = 1; public CubeNetImpl(Map faceToColorMap) { assert faceToColorMap != null : "faceToColorMap is null!"; top = faceToColorMap.get(Face.TOP); front = faceToColorMap.get(Face.FRONT); right = faceToColorMap.get(Face.RIGHT); left = faceToColorMap.get(Face.LEFT); back = faceToColorMap.get(Face.BACK); bottom = faceToColorMap.get(Face.BOTTOM); if (CALCULATE_POSSIBLE_MAPS_ONE_TIME) { long startTime = System.currentTimeMillis(); allPossibleMaps = generateAllPossibleMaps(); long endTime = System.currentTimeMillis(); timeSpentInSetAddMillis += endTime - startTime; CALCULATE_POSSIBLE_MAPS_ONE_TIME = false; } if (CALCULATE_HASHCODE_ONE_TIME) { long startTime = System.currentTimeMillis(); hashCode(HASHCODE_LEVEL); long endTime = System.currentTimeMillis(); timeSpentHashCode += endTime - startTime; CALCULATE_HASHCODE_ONE_TIME = false; } } @Override public Color getTop() { return top; } @Override public Color getFront() { return front; } @Override public Color getRight() { return right; } @Override public Color getBack() { return back; } @Override public Color getLeft() { return left; } @Override public Color getBottom() { return bottom; } private int getDistinctColorCount() { Set distinctColors = new HashSet(); distinctColors.add(top); distinctColors.add(front); distinctColors.add(right); distinctColors.add(left); distinctColors.add(bottom); return distinctColors.size(); } private Set> generateAllPossibleMaps() { Set> allMaps = new HashSet<>(); Map initialMap = new HashMap<>(); initialMap.put(Face.FRONT, Color.RED); initialMap.put(Face.BACK, Color.ORANGE); initialMap.put(Face.TOP, Color.WHITE); initialMap.put(Face.BOTTOM, Color.YELLOW); initialMap.put(Face.LEFT, Color.GREEN); initialMap.put(Face.RIGHT, Color.BLUE); generateAllPossibleMapsHelper(allMaps, initialMap); return allMaps; } private void generateAllPossibleMapsHelper(Set> allMaps, Map currentMap) { if (currentMap.size() == 6) { allMaps.add(new HashMap<>(currentMap)); return; } Set usedColors = new HashSet<>(currentMap.values()); for (Color color : Color..