diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/CommandLineOptions.java b/vipra-cmd/src/main/java/de/vipra/cmd/CommandLineOptions.java
index ac6610e5c718baf7f93e9fd2aa352c472db5577f..f89aa19f679aae08d464f413d7887c28ce035ce7 100644
--- a/vipra-cmd/src/main/java/de/vipra/cmd/CommandLineOptions.java
+++ b/vipra-cmd/src/main/java/de/vipra/cmd/CommandLineOptions.java
@@ -20,6 +20,8 @@ public class CommandLineOptions {
 	public static final Option ALL = Option.builder("A").longOpt("all").desc("select all models, short for -S all").build();
 	public static final Option CREATE = Option.builder("C").longOpt("create").desc("create new models").hasArgs().argName("models...").build();
 	public static final Option DELETE = Option.builder("D").longOpt("delete").desc("delete existing models").hasArgs().argName("models...").build();
+	public static final Option EDIT = Option.builder("E").longOpt("edit").desc("edit config of selected models").hasArgs().argName("models...")
+			.build();
 	public static final Option IMPORT = Option.builder("I").longOpt("import").desc("import data from json into selected models").hasArgs()
 			.argName("models...").build();
 	public static final Option MODEL = Option.builder("M").longOpt("model").desc("generate topics on selected models").build();
@@ -30,7 +32,7 @@ public class CommandLineOptions {
 	private final String cmdName = "vipra";
 
 	public CommandLineOptions() {
-		final Option[] optionsArray = { CLEAR, DEBUG, HELP, INDEX, LIST, REREAD, SILENT, TEST, ALL, CREATE, DELETE, IMPORT, MODEL, SELECT };
+		final Option[] optionsArray = { CLEAR, DEBUG, HELP, INDEX, LIST, REREAD, SILENT, TEST, ALL, CREATE, DELETE, EDIT, IMPORT, MODEL, SELECT };
 		options = new Options();
 		for (final Option option : optionsArray)
 			options.addOption(option);
@@ -118,6 +120,14 @@ public class CommandLineOptions {
 		return getOptionValues(DELETE);
 	}
 
+	public boolean isEdit() {
+		return hasOption(EDIT);
+	}
+
+	public String[] modelsToEdit() {
+		return getOptionValues(EDIT);
+	}
+
 	public boolean isImport() {
 		return hasOption(IMPORT);
 	}
diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/Main.java b/vipra-cmd/src/main/java/de/vipra/cmd/Main.java
index a6c4906d73212daaf790fef8ae56929d8a449976..096f76120961e34548b7d655d053921d875617ea 100644
--- a/vipra-cmd/src/main/java/de/vipra/cmd/Main.java
+++ b/vipra-cmd/src/main/java/de/vipra/cmd/Main.java
@@ -12,6 +12,7 @@ import de.vipra.cmd.option.ClearCommand;
 import de.vipra.cmd.option.Command;
 import de.vipra.cmd.option.CreateModelCommand;
 import de.vipra.cmd.option.DeleteModelCommand;
+import de.vipra.cmd.option.EditModelCommand;
 import de.vipra.cmd.option.ImportCommand;
 import de.vipra.cmd.option.IndexingCommand;
 import de.vipra.cmd.option.ListModelsCommand;
@@ -67,6 +68,9 @@ public class Main {
 		if (opts.isList())
 			commands.add(new ListModelsCommand());
 
+		if (opts.isEdit())
+			commands.add(new EditModelCommand(opts.modelsToEdit()));
+
 		if (opts.isImport())
 			commands.add(new ImportCommand(opts.selectedModels(), opts.filesToImport()));
 
diff --git a/vipra-cmd/src/main/java/de/vipra/cmd/option/EditModelCommand.java b/vipra-cmd/src/main/java/de/vipra/cmd/option/EditModelCommand.java
new file mode 100644
index 0000000000000000000000000000000000000000..44552463a7610c451ddde49d155a9795080c6c6e
--- /dev/null
+++ b/vipra-cmd/src/main/java/de/vipra/cmd/option/EditModelCommand.java
@@ -0,0 +1,65 @@
+package de.vipra.cmd.option;
+
+import de.vipra.util.Config;
+import de.vipra.util.ConsoleUtils;
+import de.vipra.util.Constants.ProcessorMode;
+import de.vipra.util.Constants.WindowResolution;
+import de.vipra.util.ex.DatabaseException;
+import de.vipra.util.model.TopicModelConfig;
+import de.vipra.util.model.TopicModelFull;
+import de.vipra.util.service.MongoService;
+
+public class EditModelCommand implements Command {
+
+	private final String[] names;
+	private MongoService<TopicModelFull, String> dbTopicModels;
+
+	public EditModelCommand(final String[] names) {
+		this.names = names;
+	}
+
+	private void editModel(final TopicModelConfig topicModelConfig) throws DatabaseException {
+		ConsoleUtils.info("editing model: " + topicModelConfig.getName());
+		topicModelConfig.setDescription(ConsoleUtils.readString("description (↲ to skip)", topicModelConfig.getDescription(), true));
+		topicModelConfig.setkTopics(ConsoleUtils.readInt("k topics", topicModelConfig.getkTopics(), 1, null, true));
+		topicModelConfig
+				.setDynamicMinIterations(ConsoleUtils.readInt("dynamic min iterations", topicModelConfig.getDynamicMinIterations(), 1, null, true));
+		topicModelConfig.setDynamicMaxIterations(ConsoleUtils.readInt("dynamic max iterations", topicModelConfig.getDynamicMaxIterations(),
+				topicModelConfig.getDynamicMinIterations(), null, true));
+		topicModelConfig.setStaticIterations(ConsoleUtils.readInt("static iterations", topicModelConfig.getStaticIterations(), 1, null, true));
+		topicModelConfig
+				.setTopicAutoNamingWords(ConsoleUtils.readInt("topic auto naming words", topicModelConfig.getTopicAutoNamingWords(), 1, null, true));
+		topicModelConfig
+				.setMaxSimilarDocuments(ConsoleUtils.readInt("max similar documents", topicModelConfig.getMaxSimilarDocuments(), 0, null, true));
+		topicModelConfig
+				.setDocumentMinimumLength(ConsoleUtils.readInt("document min length", topicModelConfig.getDocumentMinimumLength(), 0, null, true));
+		topicModelConfig.setDocumentMinimumWordFrequency(
+				ConsoleUtils.readInt("document min word frequency", topicModelConfig.getDocumentMinimumWordFrequency(), 0, null, true));
+		topicModelConfig.setSpotlightSupport(ConsoleUtils.readInt("spotlight support", topicModelConfig.getSpotlightSupport(), 0, null, true));
+		topicModelConfig
+				.setSpotlightConfidence(ConsoleUtils.readDouble("spotlight confidence", topicModelConfig.getSpotlightConfidence(), 0.0, 1.0, true));
+		topicModelConfig.setMinRelativeProbability(
+				ConsoleUtils.readDouble("min relative probability", topicModelConfig.getMinRelativeProbability(), 0.0, 1.0, true));
+		topicModelConfig.setRisingDecayLambda(ConsoleUtils.readDouble("rising decay lambda", topicModelConfig.getRisingDecayLambda()));
+		topicModelConfig.setMaxSimilarDocumentsDivergence(
+				ConsoleUtils.readDouble("max similar documents divergence", topicModelConfig.getMaxSimilarDocumentsDivergence(), 0.0, 1.0, true));
+		topicModelConfig
+				.setWindowResolution(ConsoleUtils.readEnum(WindowResolution.class, "window resolution", topicModelConfig.getWindowResolution()));
+		topicModelConfig.setProcessorMode(ConsoleUtils.readEnum(ProcessorMode.class, "processor mode", topicModelConfig.getProcessorMode()));
+
+		final TopicModelFull topicModel = new TopicModelFull(topicModelConfig.getName());
+		topicModel.setModelConfig(topicModelConfig);
+		dbTopicModels.updateSingle(topicModel, "modelConfig");
+	}
+
+	@Override
+	public void run() throws Exception {
+		final Config config = Config.getConfig();
+		dbTopicModels = MongoService.getDatabaseService(config, TopicModelFull.class);
+
+		for (final String name : names) {
+			editModel(config.getTopicModelConfig(name));
+		}
+	}
+
+}
diff --git a/vipra-ui/app/html/directives/topic-link.html b/vipra-ui/app/html/directives/topic-link.html
index 7ad606fe8f90791a1f8b4db0f4d908b77ad73b0b..bcdd3845f88fc43b47ecdadd912fd9f6b8a86d5b 100644
--- a/vipra-ui/app/html/directives/topic-link.html
+++ b/vipra-ui/app/html/directives/topic-link.html
@@ -1,5 +1,5 @@
 <span>
-  <topic-menu topic="topic" right="true" />
+  <topic-menu topic="topic" />
   <a class="topic-link" ui-sref="topics.show({id:topic.id})">
     <span ng-bind="topic.name"></span>
     <ng-transclude/>
diff --git a/vipra-ui/app/js/controllers.js b/vipra-ui/app/js/controllers.js
index 4be0f3afa730721f61cf00eac93c2a1f0106271c..1a4e7a39799c413e098c4a6ef47f88626b5ac3f3 100644
--- a/vipra-ui/app/js/controllers.js
+++ b/vipra-ui/app/js/controllers.js
@@ -671,6 +671,16 @@
           }, $scope.topic, function(data) {
             $scope.topic = data;
             $scope.isRename = false;
+
+            // if topic list of parent view is loaded, replace name by new name
+            if($scope.$parent.topics) {
+              for(var i = 0, topic; i < $scope.$parent.topics.length; i++) {
+                topic = $scope.$parent.topics[i];
+                if(topic.id === data.id) {
+                  break;
+                }
+              }
+            }
           }, function(err) {
             $scope.errors = err;
           });
diff --git a/vipra-util/src/main/java/de/vipra/util/ConsoleUtils.java b/vipra-util/src/main/java/de/vipra/util/ConsoleUtils.java
index 7e2ee2f0f93636a6d1091322c457b08070f21397..29cadf2964d5ca4fabd5b418a4e7863b32b7dcd9 100644
--- a/vipra-util/src/main/java/de/vipra/util/ConsoleUtils.java
+++ b/vipra-util/src/main/java/de/vipra/util/ConsoleUtils.java
@@ -1,5 +1,9 @@
 package de.vipra.util;
 
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+
 import org.fusesource.jansi.Ansi;
 import org.fusesource.jansi.Ansi.Color;
 
@@ -24,7 +28,7 @@ public class ConsoleUtils {
 
 	public static void error(final String msg) {
 		if (!silent)
-			System.err.println(label("ERROR") + " - " + Ansi.ansi().fg(Color.RED).a(msg).reset());
+			System.out.println(label("ERROR") + " - " + Ansi.ansi().fg(Color.RED).a(msg).reset());
 	}
 
 	public static void error(final Throwable t) {
@@ -35,4 +39,126 @@ public class ConsoleUtils {
 		return StringUtils.pad(label, pad);
 	}
 
+	public static double readDouble(String message, final Double def, final Double min, final Double max, final boolean showBounds) {
+		final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+		if (showBounds)
+			message += " (" + (min != null ? min : "-∞") + ".." + (max != null ? max : "∞") + ")";
+		if (def != null)
+			message += " [" + def + "]";
+		message += ": ";
+		while (true) {
+			System.out.print(message);
+			try {
+				final String line = in.readLine();
+				if (line.isEmpty() && def != null)
+					return def;
+				final double d = Double.parseDouble(line);
+				if (min != null && d < min)
+					continue;
+				if (max != null && d > max)
+					continue;
+				return d;
+			} catch (final NumberFormatException e) {} catch (final IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+	}
+
+	public static double readDouble(final String message, final Double def, final Double min, final Double max) {
+		return readDouble(message, def, min, max, true);
+	}
+
+	public static double readDouble(final String message, final Double def) {
+		return readDouble(message, def, null, null, true);
+	}
+
+	public static double readDouble(final String message) {
+		return readDouble(message, null, null, null, false);
+	}
+
+	public static int readInt(String message, final Integer def, final Integer min, final Integer max, final boolean showBounds) {
+		final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+		if (showBounds)
+			message += " (" + (min != null ? min : "-∞") + ".." + (max != null ? max : "∞") + ")";
+		if (def != null)
+			message += " [" + def + "]";
+		message += ": ";
+		while (true) {
+			System.out.print(message);
+			try {
+				final String line = in.readLine();
+				if (line.isEmpty() && def != null)
+					return def;
+				final int i = Integer.parseInt(line);
+				if (min != null && i < min)
+					continue;
+				if (max != null && i > max)
+					continue;
+				return i;
+			} catch (final NumberFormatException e) {} catch (final IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+	}
+
+	public static int readInt(final String message, final Integer def, final Integer min, final Integer max) {
+		return readInt(message, def, min, max, true);
+	}
+
+	public static int readInt(final String message, final Integer def) {
+		return readInt(message, def, null, null, true);
+	}
+
+	public static int readInt(final String message) {
+		return readInt(message, null, null, null, false);
+	}
+
+	public static String readString(String message, final String def, final boolean canBeEmpty) {
+		final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+		message += ": ";
+		while (true) {
+			System.out.print(message);
+			try {
+				final String line = in.readLine();
+				if (line.isEmpty()) {
+					if (def != null)
+						return def;
+					if (!canBeEmpty)
+						continue;
+				}
+				return line;
+			} catch (final IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+	}
+
+	public static String readString(final String message, final String def) {
+		return readString(message, def, false);
+	}
+
+	public static String readString(final String message) {
+		return readString(message, null, false);
+	}
+
+	public static <T extends Enum<?>> T readEnum(final Class<T> enumClass, String message, final T def) {
+		final BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
+		if (def != null)
+			message += " [" + def + "]";
+		message += ": ";
+		while (true) {
+			System.out.print(message);
+			try {
+				final String line = in.readLine();
+				final T value = EnumUtils.searchEnum(enumClass, line);
+				if (value != null)
+					return value;
+				if (def != null)
+					return def;
+			} catch (final IOException e) {
+				throw new RuntimeException(e);
+			}
+		}
+	}
+
 }
diff --git a/vipra-util/src/main/java/de/vipra/util/EnumUtils.java b/vipra-util/src/main/java/de/vipra/util/EnumUtils.java
new file mode 100644
index 0000000000000000000000000000000000000000..d7e57dc5ae4ca2782f8586921df5b831a4e9d697
--- /dev/null
+++ b/vipra-util/src/main/java/de/vipra/util/EnumUtils.java
@@ -0,0 +1,23 @@
+package de.vipra.util;
+
+public class EnumUtils {
+
+	/**
+	 * Finds an enum value by its name, ignoring case.
+	 *
+	 * @param enumeration
+	 *            Enum to be searched
+	 * @param search
+	 *            Enum value to be searched
+	 * @return the found enum value, or null
+	 */
+	public static <T extends Enum<?>> T searchEnum(final Class<T> enumeration, final String search) {
+		for (final T each : enumeration.getEnumConstants()) {
+			if (each.name().compareToIgnoreCase(search) == 0) {
+				return each;
+			}
+		}
+		return null;
+	}
+
+}
diff --git a/vipra-util/src/main/java/de/vipra/util/model/TopicModelConfig.java b/vipra-util/src/main/java/de/vipra/util/model/TopicModelConfig.java
index 366972d664942ec0d96507e6b5b66c89e9ae3fd1..4dde14aa7bd8bb9e76c2e60839ba49fa44dfd77a 100644
--- a/vipra-util/src/main/java/de/vipra/util/model/TopicModelConfig.java
+++ b/vipra-util/src/main/java/de/vipra/util/model/TopicModelConfig.java
@@ -17,6 +17,7 @@ import de.vipra.util.Constants.WindowResolution;
 public class TopicModelConfig implements Serializable {
 
 	private String name;
+	private String description;
 	private int kTopics = Constants.K_TOPICS;
 	private int dynamicMinIterations = Constants.DYNAMIC_MIN_ITER;
 	private int dynamicMaxIterations = Constants.DYNAMIC_MAX_ITER;
@@ -61,6 +62,14 @@ public class TopicModelConfig implements Serializable {
 		this.name = name;
 	}
 
+	public String getDescription() {
+		return description;
+	}
+
+	public void setDescription(final String description) {
+		this.description = description;
+	}
+
 	public int getkTopics() {
 		return kTopics;
 	}
diff --git a/vipra-util/src/main/java/de/vipra/util/model/Window.java b/vipra-util/src/main/java/de/vipra/util/model/Window.java
index 3039ca0358f909be9c26e767c4498364846cdcc9..b3350267579083cae4eb9245de58210c22239ed9 100644
--- a/vipra-util/src/main/java/de/vipra/util/model/Window.java
+++ b/vipra-util/src/main/java/de/vipra/util/model/Window.java
@@ -26,15 +26,15 @@ public class Window implements Model<Integer>, Serializable, Comparable<Window>
 
 	public Window() {}
 
-	public Window(Integer id) {
+	public Window(final Integer id) {
 		this.id = id;
 	}
 
-	public Window(WindowFull window) {
-		this.id = window.getId();
-		this.startDate = window.getStartDate();
-		this.endDate = window.getEndDate();
-		this.windowResolution = window.getWindowResolution();
+	public Window(final WindowFull window) {
+		id = window.getId();
+		startDate = window.getStartDate();
+		endDate = window.getEndDate();
+		windowResolution = window.getWindowResolution();
 	}
 
 	@Override