private boolean restoreFrom(String config) {
		// Need to add enables
		byte[] data = DatatypeConverter.parseBase64Binary(config);

		// Check the checksum
		ByteBuffer buf = ByteBuffer.allocate(4).put(data, data.length - 16, 4);
		buf.rewind();
		int crc = buf.getInt();

		CRC32 checksum = new CRC32();
		checksum.update(data, 0, data.length - 16);

		if ((int) checksum.getValue() != crc) {
			return false; // checksum failure
		}

		// Restore the actual controls
		restoreStates(data[0], this.goLowerCaseNamesCheckBox,
				this.goNationalDexCheckBox, this.goRemoveTradeEvosCheckBox,
				this.goUpdateMovesCheckBox, this.goUpdateMovesLegacyCheckBox,
				this.goUpdateTypesCheckBox, this.tnRandomizeCB,
				this.tcnRandomizeCB);

		// sanity override
		if (this.goUpdateMovesLegacyCheckBox.isSelected()
				&& (romHandler instanceof Gen5RomHandler)) {
			// they probably don't want moves updated actually
			this.goUpdateMovesLegacyCheckBox.setSelected(false);
			this.goUpdateMovesCheckBox.setSelected(false);
		}

		restoreStates(data[1], this.pbsChangesRandomEvosRB,
				this.pbsChangesRandomTotalRB, this.pbsChangesShuffleRB,
				this.pbsChangesUnchangedRB, this.paUnchangedRB,
				this.paRandomizeRB, this.paWonderGuardCB,
				this.pbsStandardEXPCurvesCB);

		restoreStates(data[2], this.ptRandomFollowEvosRB, this.ptRandomTotalRB,
				this.ptUnchangedRB, this.codeTweaksCB, this.raceModeCB,
				this.randomizeHollowsCB, this.brokenMovesCB, this.pokeLimitCB);

		restoreStates(data[3], this.spCustomRB, this.spRandomRB,
				this.spUnchangedRB, this.spRandom2EvosRB, this.spHeldItemsCB);

		restoreSelectedIndex(data, 4, this.spCustomPoke1Chooser);
		restoreSelectedIndex(data, 6, this.spCustomPoke2Chooser);
		restoreSelectedIndex(data, 8, this.spCustomPoke3Chooser);

		restoreStates(data[10], this.pmsRandomTotalRB, this.pmsRandomTypeRB,
				this.pmsUnchangedRB, this.pmsMetronomeOnlyRB,
				this.pmsGen14MovesCB);

		// changed 160
		restoreStates(data[11], this.tpPowerLevelsCB, this.tpRandomRB,
				this.tpRivalCarriesStarterCB, this.tpTypeThemedRB,
				this.tpTypeWeightingCB, this.tpUnchangedRB,
				this.tpNoLegendariesCB, this.tpNoEarlyShedinjaCB);

		restoreStates(data[12], this.wpARCatchEmAllRB, this.wpArea11RB,
				this.wpARNoneRB, this.wpARTypeThemedRB, this.wpGlobalRB,
				this.wpRandomRB, this.wpUnchangedRB, this.wpUseTimeCB);

		restoreStates(data[13], this.wpCatchRateCB, this.wpNoLegendariesCB,
				this.wpARSimilarStrengthRB, this.wpHeldItemsCB);

		restoreStates(data[14], this.stpUnchangedRB, this.stpRandomL4LRB,
				this.stpRandomTotalRB);

		restoreStates(data[15], this.thcRandomTotalRB, this.thcRandomTypeRB,
				this.thcUnchangedRB, this.tmmRandomRB, this.tmmUnchangedRB);
		restoreStates(data[16], this.mtcRandomTotalRB, this.mtcRandomTypeRB,
				this.mtcUnchangedRB, this.mtmRandomRB, this.mtmUnchangedRB);

		// new 150
		restoreStates(data[17], this.igtBothRB, this.igtGivenOnlyRB,
				this.igtRandomItemCB, this.igtRandomIVsCB,
				this.igtRandomNicknameCB, this.igtRandomOTCB,
				this.igtUnchangedRB);
		restoreStates(data[18], this.fiRandomRB, this.fiShuffleRB,
				this.fiUnchangedRB);

		// gen restrictions
		int genlim = readFullInt(data, 19);
		if (genlim == 0) {
			this.currentRestrictions = null;
		} else {
			this.currentRestrictions = new GenRestrictions(genlim);
			this.currentRestrictions.limitToGen(this.romHandler
					.generationOfPokemon());
		}

		int codetweaks = readFullInt(data, 23);
		this.currentCodeTweaks = codetweaks
				& this.romHandler.codeTweaksAvailable();
		updateCodeTweaksButtonText();
		// Sanity override
		if (this.currentCodeTweaks == 0) {
			this.codeTweaksCB.setSelected(false);
		}

		this.enableOrDisableSubControls();

		// Name data is ignored here - we should've used it earlier.
		return true;
	}