public ScrambleRequest(String title, String scrambleRequestUrl, String seed) throws InvalidScrambleRequestException, UnsupportedEncodingException { String[] puzzle_count_copies_scheme = scrambleRequestUrl.split("\\*"); title = URLDecoder.decode(title, "utf-8"); for (int i = 0; i < puzzle_count_copies_scheme.length; i++) { puzzle_count_copies_scheme[i] = URLDecoder.decode(puzzle_count_copies_scheme[i], "utf-8"); } String countStr = ""; String copiesStr = ""; String scheme = ""; String puzzle; switch (puzzle_count_copies_scheme.length) { case 4: scheme = puzzle_count_copies_scheme[3]; case 3: copiesStr = puzzle_count_copies_scheme[2]; case 2: countStr = puzzle_count_copies_scheme[1]; case 1: puzzle = puzzle_count_copies_scheme[0]; break; default: throw new InvalidScrambleRequestException("Invalid puzzle request " + scrambleRequestUrl); } LazyInstantiator<Puzzle> lazyScrambler = puzzles.get(puzzle); if (lazyScrambler == null) { throw new InvalidScrambleRequestException("Invalid scrambler: " + puzzle); } try { this.scrambler = lazyScrambler.cachedInstance(); } catch (Exception e) { throw new InvalidScrambleRequestException(e); } ScrambleCacher scrambleCacher = scrambleCachers.get(puzzle); if (scrambleCacher == null) { scrambleCacher = new ScrambleCacher(scrambler); scrambleCachers.put(puzzle, scrambleCacher); } this.title = title; fmc = countStr.equals("fmc"); int count; if (fmc) { count = 1; } else { count = Math.min(toInt(countStr, 1), MAX_COUNT); } this.copies = Math.min(toInt(copiesStr, 1), MAX_COPIES); if (seed != null) { this.scrambles = scrambler.generateSeededScrambles(seed, count); } else { this.scrambles = scrambleCacher.newScrambles(count); } this.colorScheme = scrambler.parseColorScheme(scheme); }