diff --git a/src/main/java/de/prob2/jupyter/PositionalParameter.java b/src/main/java/de/prob2/jupyter/PositionalParameter.java
index f127f49cafb75f93e004d6b671af1dca1b95cfd0..35c89887dc6bd2d487f9a8e1996c0aa25e511401 100644
--- a/src/main/java/de/prob2/jupyter/PositionalParameter.java
+++ b/src/main/java/de/prob2/jupyter/PositionalParameter.java
@@ -1,5 +1,8 @@
 package de.prob2.jupyter;
 
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
 import java.util.Optional;
 
 import org.jetbrains.annotations.NotNull;
@@ -49,6 +52,50 @@ public abstract class PositionalParameter<T> extends Parameter<T> {
 		}
 	}
 	
+	public static final class RequiredMultiple extends PositionalParameter<@NotNull List<@NotNull String>> {
+		public RequiredMultiple(final @NotNull String identifier) {
+			super(identifier);
+		}
+		
+		@Override
+		public boolean isOptional() {
+			return false;
+		}
+		
+		@Override
+		public @NotNull List<@NotNull String> getDefaultValue() {
+			throw new UnsupportedOperationException("Not an optional parameter");
+		}
+		
+		@Override
+		public @NotNull Parameter.ParseResult<@NotNull List<@NotNull String>> parse(final @NotNull String argString) {
+			final String[] split = CommandUtils.ARG_SPLIT_PATTERN.split(argString);
+			return new Parameter.ParseResult<>(Arrays.asList(split), "");
+		}
+	}
+	
+	public static final class OptionalMultiple extends PositionalParameter<@NotNull List<@NotNull String>> {
+		public OptionalMultiple(final @NotNull String identifier) {
+			super(identifier);
+		}
+		
+		@Override
+		public boolean isOptional() {
+			return true;
+		}
+		
+		@Override
+		public @NotNull List<@NotNull String> getDefaultValue() {
+			return Collections.emptyList();
+		}
+		
+		@Override
+		public @NotNull Parameter.ParseResult<@NotNull List<@NotNull String>> parse(final @NotNull String argString) {
+			final String[] split = CommandUtils.ARG_SPLIT_PATTERN.split(argString);
+			return new Parameter.ParseResult<>(Arrays.asList(split), "");
+		}
+	}
+	
 	public static final class RequiredRemainder extends PositionalParameter<@NotNull String> {
 		public RequiredRemainder(final @NotNull String identifier) {
 			super(identifier);
diff --git a/src/main/java/de/prob2/jupyter/commands/LoadCellCommand.java b/src/main/java/de/prob2/jupyter/commands/LoadCellCommand.java
index ac346823e1caa7dede37158de6ad746a0fcb878e..cdb7b21f7955e3dac9f000b614690a50c20fdcc6 100644
--- a/src/main/java/de/prob2/jupyter/commands/LoadCellCommand.java
+++ b/src/main/java/de/prob2/jupyter/commands/LoadCellCommand.java
@@ -2,7 +2,6 @@ package de.prob2.jupyter.commands;
 
 import java.nio.file.Paths;
 import java.util.Collections;
-import java.util.List;
 import java.util.Map;
 
 import com.google.inject.Inject;
@@ -25,7 +24,7 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public final class LoadCellCommand implements Command {
-	private static final @NotNull PositionalParameter.OptionalRemainder PREFS_PARAM = new PositionalParameter.OptionalRemainder("prefs");
+	private static final @NotNull PositionalParameter.OptionalMultiple PREFS_PARAM = new PositionalParameter.OptionalMultiple("prefs");
 	private static final @NotNull PositionalParameter.RequiredRemainder CODE_PARAM = new PositionalParameter.RequiredRemainder("code");
 	
 	private final @NotNull ClassicalBFactory classicalBFactory;
@@ -75,8 +74,7 @@ public final class LoadCellCommand implements Command {
 	@Override
 	public @NotNull DisplayData run(final @NotNull ParsedArguments args) {
 		final String body = args.get(CODE_PARAM);
-		final List<String> prefsSplit = args.get(PREFS_PARAM).map(CommandUtils::splitArgs).orElse(Collections.emptyList());
-		final Map<String, String> preferences = CommandUtils.parsePreferences(prefsSplit);
+		final Map<String, String> preferences = CommandUtils.parsePreferences(args.get(PREFS_PARAM));
 		
 		this.animationSelector.changeCurrentAnimation(new Trace(CommandUtils.withSourceCode(body, () ->
 			this.classicalBFactory.create("(machine from Jupyter cell)", body).load(preferences)
diff --git a/src/main/java/de/prob2/jupyter/commands/LoadFileCommand.java b/src/main/java/de/prob2/jupyter/commands/LoadFileCommand.java
index 4d2155efd15607e716214ac36aef306265397a4d..f3e5dd3f7b4b1cb05309f2aec436b59b142bce9b 100644
--- a/src/main/java/de/prob2/jupyter/commands/LoadFileCommand.java
+++ b/src/main/java/de/prob2/jupyter/commands/LoadFileCommand.java
@@ -5,7 +5,6 @@ import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
@@ -40,7 +39,7 @@ public final class LoadFileCommand implements Command {
 	private static final @NotNull Logger LOGGER = LoggerFactory.getLogger(LoadFileCommand.class);
 	
 	private static final @NotNull PositionalParameter.RequiredSingle FILE_NAME_PARAM = new PositionalParameter.RequiredSingle("fileName");
-	private static final @NotNull PositionalParameter.OptionalRemainder PREFS_PARAM = new PositionalParameter.OptionalRemainder("prefs");
+	private static final @NotNull PositionalParameter.OptionalMultiple PREFS_PARAM = new PositionalParameter.OptionalMultiple("prefs");
 	
 	private final @NotNull Injector injector;
 	private final @NotNull AnimationSelector animationSelector;
@@ -98,12 +97,7 @@ public final class LoadFileCommand implements Command {
 		if (!FactoryProvider.isExtensionKnown(extension)) {
 			throw new UserErrorException("Unsupported file type: ." + extension);
 		}
-		final Map<String, String> preferences;
-		if (args.get(PREFS_PARAM).isPresent()) {
-			preferences = CommandUtils.parsePreferences(CommandUtils.splitArgs(args.get(PREFS_PARAM).get()));
-		} else {
-			preferences = Collections.emptyMap();
-		}
+		final Map<String, String> preferences = CommandUtils.parsePreferences(args.get(PREFS_PARAM));
 		
 		try {
 			final ModelFactory<?> factory = this.injector.getInstance(FactoryProvider.factoryClassFromExtension(extension));
diff --git a/src/main/java/de/prob2/jupyter/commands/PrefCommand.java b/src/main/java/de/prob2/jupyter/commands/PrefCommand.java
index 89df593cd20dca25f67ea375ad1df8a8364889f4..c416a838a81fe819bd7db25ff65f137351b5e6c4 100644
--- a/src/main/java/de/prob2/jupyter/commands/PrefCommand.java
+++ b/src/main/java/de/prob2/jupyter/commands/PrefCommand.java
@@ -27,7 +27,7 @@ import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 public final class PrefCommand implements Command {
-	private static final @NotNull PositionalParameter.OptionalRemainder PREFS_PARAM = new PositionalParameter.OptionalRemainder("prefs");
+	private static final @NotNull PositionalParameter.OptionalMultiple PREFS_PARAM = new PositionalParameter.OptionalMultiple("prefs");
 	
 	private final @NotNull AnimationSelector animationSelector;
 	
@@ -67,7 +67,7 @@ public final class PrefCommand implements Command {
 	@Override
 	public @NotNull DisplayData run(final @NotNull ParsedArguments args) {
 		final StringBuilder sb = new StringBuilder();
-		if (!args.get(PREFS_PARAM).isPresent()) {
+		if (args.get(PREFS_PARAM).isEmpty()) {
 			final GetCurrentPreferencesCommand cmd = new GetCurrentPreferencesCommand();
 			this.animationSelector.getCurrentTrace().getStateSpace().execute(cmd);
 			// TreeMap is used to sort the preferences by name.
@@ -78,7 +78,7 @@ public final class PrefCommand implements Command {
 				sb.append('\n');
 			});
 		} else {
-			final List<String> prefsSplit = CommandUtils.splitArgs(args.get(PREFS_PARAM).get());
+			final List<String> prefsSplit = args.get(PREFS_PARAM);
 			if (prefsSplit.get(0).contains("=")) {
 				final List<SetPreferenceCommand> cmds = new ArrayList<>();
 				CommandUtils.parsePreferences(prefsSplit).forEach((pref, value) -> {