Simplified HW visualization
diff --git a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/META-INF/MANIFEST.MF b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/META-INF/MANIFEST.MF
index 6f0f982..ef2ba44 100644
--- a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/META-INF/MANIFEST.MF
@@ -7,20 +7,11 @@
 Bundle-Vendor: Eclipse APP4MC
 Bundle-RequiredExecutionEnvironment: JavaSE-1.8
 Require-Bundle: org.eclipse.core.runtime,
- org.eclipse.core.resources,
- org.eclipse.e4.ui.model.workbench;bundle-version="2.1.600.v20191106-1503",
- org.eclipse.e4.core.di.annotations,
- org.eclipse.e4.core.di.extensions,
- org.eclipse.e4.ui.services,
  org.eclipse.jface,
- org.eclipse.e4.ui.di,
- org.eclipse.app4mc.amalthea.model;bundle-version="2.0.0"
+ org.eclipse.app4mc.amalthea.model;bundle-version="2.0.0",
+ org.eclipse.app4mc.visualization.util.svg
 Bundle-ActivationPolicy: lazy
 Import-Package: javax.annotation;version="1.2.0",
- javax.inject;version="1.0.0",
- net.sourceforge.plantuml;version="1.2019.0",
- net.sourceforge.plantuml.core;version="1.2019.0",
- net.sourceforge.plantuml.eclipse.utils,
  org.eclipse.app4mc.visualization.ui.registry;version="1.0.0",
  org.osgi.service.component.annotations;version="[1.3.0,2.0.0)";resolution:=optional,
  org.slf4j;version="1.7.2"
diff --git a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/fragment.e4xmi b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/fragment.e4xmi
deleted file mode 100644
index ba5a0b1..0000000
--- a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/fragment.e4xmi
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="ASCII"?>
-<fragment:ModelFragments xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:commands="http://www.eclipse.org/ui/2010/UIModel/application/commands" xmlns:fragment="http://www.eclipse.org/ui/2010/UIModel/fragment" xmlns:menu="http://www.eclipse.org/ui/2010/UIModel/application/ui/menu" xmlns:ui="http://www.eclipse.org/ui/2010/UIModel/application/ui" xmi:id="_hxr9QGd8EeqNVJG0SN1NAg">
-  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_i8vbIGd8EeqNVJG0SN1NAg" featurename="commands" parentElementId="xpath:/">
-    <elements xsi:type="commands:Command" xmi:id="_5hD8oGd8EeqNVJG0SN1NAg" elementId="org.eclipse.app4mc.amalthea.visualization.hw.command.amaltheahwmodelvisualization" commandName="Amalthea HW Model visualization"/>
-  </fragments>
-  <fragments xsi:type="fragment:StringModelFragment" xmi:id="__3LKIGd8EeqNVJG0SN1NAg" featurename="handlers" parentElementId="xpath:/">
-    <elements xsi:type="commands:Handler" xmi:id="_BUL6sGd9EeqNVJG0SN1NAg" elementId="org.eclipse.app4mc.amalthea.visualization.hw.handler.0" contributionURI="bundleclass://org.eclipse.app4mc.amalthea.visualization.hw/org.eclipse.app4mc.amalthea.visualization.hw.VisualizationHandler" command="_5hD8oGd8EeqNVJG0SN1NAg"/>
-  </fragments>
-  <fragments xsi:type="fragment:StringModelFragment" xmi:id="_rOnf0Gd-EeqNVJG0SN1NAg" featurename="menuContributions" parentElementId="xpath:/">
-    <elements xsi:type="menu:MenuContribution" xmi:id="_sLbGUGd-EeqNVJG0SN1NAg" elementId="org.eclipse.app4mc.amalthea.visualization.hw.menucontribution.0" positionInParent="after=additions" parentId="popup">
-      <children xsi:type="menu:HandledMenuItem" xmi:id="_veTMUGd-EeqNVJG0SN1NAg" elementId="id.amaltheahwmodelvisualization" label="AMALTHEA HW Model Visualization" command="_5hD8oGd8EeqNVJG0SN1NAg">
-        <visibleWhen xsi:type="ui:CoreExpression" xmi:id="_sDXCkGeWEeqNVJG0SN1NAg" coreExpressionId="org.eclipse.app4mc.amalthea.visualization.hw.expression"/>
-      </children>
-    </elements>
-  </fragments>
-</fragment:ModelFragments>
diff --git a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/plugin.xml b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/plugin.xml
index f480408..ef2bea6 100644
--- a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/plugin.xml
+++ b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/plugin.xml
@@ -1,28 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <plugin>
 
-   <extension
-         id="org.eclipse.app4mc.amalthea.visualization.hw.fragment"
-         point="org.eclipse.e4.workbench.model">
-      <fragment
-            uri="fragment.e4xmi"
-            apply="always">
-      </fragment>
-   </extension>
-   <extension
-         point="org.eclipse.core.expressions.definitions">
-      <definition
-            id="org.eclipse.app4mc.amalthea.visualization.hw.expression">
-               <with
-                     variable="activeMenuSelection">
-                  <iterate
-                        ifEmpty="false">
-                     <instanceof
-                           value="org.eclipse.app4mc.amalthea.model.HWModel">
-                     </instanceof>
-                  </iterate>
-               </with>
-      </definition>
-   </extension>
 
 </plugin>
diff --git a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/DiagramLocation.java b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/DiagramLocation.java
deleted file mode 100644
index 7ffb7aa..0000000
--- a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/DiagramLocation.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
- ********************************************************************************
- * Copyright (c) 2020-2021 Robert Bosch GmbH.
- *
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     Robert Bosch GmbH - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.app4mc.amalthea.visualization.hw;
-
-import org.eclipse.app4mc.amalthea.model.HWModel;
-import org.eclipse.app4mc.amalthea.model.HwStructure;
-import org.eclipse.core.resources.IContainer;
-import org.eclipse.core.resources.IFile;
-import org.eclipse.core.resources.IFolder;
-import org.eclipse.core.resources.IResource;
-import org.eclipse.core.resources.ResourcesPlugin;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.IPath;
-import org.eclipse.core.runtime.Path;
-import org.eclipse.emf.common.util.URI;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.emf.ecore.resource.Resource;
-
-public class DiagramLocation {
-
-	private IFolder diagramFolder = null;
-	private String plantUmlFileName = null;
-	private String plantUmlFilePath = null;
-	private String diagramFileName = null;
-	private String diagramFilePath = null;
-
-	public DiagramLocation(EObject eObject) {
-		IFile file = getResourceFile(eObject);
-		if (file == null) return;
-
-		IFolder folder = getOrCreateDiagramFolder(file, "hwModelVisualization");
-		if (folder == null) return;
-
-		initialize(folder, buildFilename(file, eObject));
-	}
-
-	public DiagramLocation(IFolder folder, String baseFilename) {
-		if (folder == null || !folder.exists() || baseFilename == null || baseFilename.isEmpty()) return;
-
-		initialize(folder, baseFilename);
-	}
-
-	private void initialize(IFolder folder, String baseFilename) {
-		diagramFolder = folder;
-		plantUmlFileName = baseFilename + ".plantuml";
-		plantUmlFilePath = folder.getFile(plantUmlFileName).getLocation().toString();
-		diagramFileName = baseFilename + ".svg";
-		diagramFilePath = folder.getFile(diagramFileName).getLocation().toString();
-	}
-
-
-	private IFile getResourceFile(EObject eObject) {
-		if (eObject == null) return null;
-
-		Resource eResource = eObject.eResource();
-		if (eResource == null) return null;
-
-		URI uri = eResource.getURI();
-		IPath path = new Path(uri.toPlatformString(true));
-		return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
-	}
-
-	private IFolder getOrCreateDiagramFolder(IFile file, String folderName) {
-		if (file == null) return null;
-
-		IContainer parentFolder = file.getParent();
-		if (parentFolder == null) return null;
-
-		// **** Find visualization folder (create if necessary)
-
-		IFolder folder = parentFolder.getFolder(new Path(folderName));
-
-		if (!folder.exists()) {
-			try {
-				folder.create(IResource.NONE, true, null);
-			} catch (CoreException e) {
-				return null;
-			}
-		}
-
-		return folder;
-	}
-
-	private String buildFilename(IFile file, EObject eObject) {
-		String modelName = "model"; // default
-
-		if (file != null && file.getName() != null) {
-			modelName = file.getName().replaceFirst("[.][^.]+$", ""); // remove extension
-		}
-
-		String extendedName = "";
-		if (eObject instanceof HWModel) {
-			extendedName = "_hw";
-		} else if (eObject instanceof HwStructure) {
-			extendedName = "_structure";
-		}
-
-		return modelName + extendedName;
-	}
-
-	public IFolder getDiagramFolder() {
-		return diagramFolder;
-	}
-
-	public String getPlantUmlFileName() {
-		return plantUmlFileName;
-	}
-
-	public String getPlantUmlFilePath() {
-		return plantUmlFilePath;
-	}
-
-	public String getDiagramFileName() {
-		return diagramFileName;
-	}
-
-	public String getDiagramFilePath() {
-		return diagramFilePath;
-	}
-
-	public boolean isValid() {
-		return diagramFolder != null;
-	}
-}
-
diff --git a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/HWBlockDiagramVisualization.java b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/HWBlockDiagramVisualization.java
index e30a75c..86a1ead 100644
--- a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/HWBlockDiagramVisualization.java
+++ b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/HWBlockDiagramVisualization.java
@@ -14,60 +14,66 @@
 
 package org.eclipse.app4mc.amalthea.visualization.hw;
 
+import java.io.IOException;
+
 import javax.annotation.PostConstruct;
 
 import org.eclipse.app4mc.amalthea.model.HWModel;
+import org.eclipse.app4mc.amalthea.visualization.hw.templates.HWBlockGenerator;
 import org.eclipse.app4mc.visualization.ui.registry.Visualization;
-import org.eclipse.core.runtime.jobs.IJobChangeEvent;
-import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.e4.core.di.annotations.Optional;
-import org.eclipse.e4.core.di.extensions.Preference;
-import org.eclipse.e4.ui.di.UISynchronize;
+import org.eclipse.app4mc.visualization.util.svg.PlantUmlDiagram;
+import org.eclipse.core.runtime.Platform;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.Browser;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Shell;
 import org.osgi.service.component.annotations.Component;
 
-import net.sourceforge.plantuml.eclipse.utils.PlantumlConstants;
-
 @Component(property= {
 		"name=HW Model Block Diagram",
 		"description=Block Diagram Visualization for Hardware Models"
 })
 public class HWBlockDiagramVisualization implements Visualization {
 
+	private PlantUmlDiagram diagram = new PlantUmlDiagram();
+
 	@PostConstruct
 	public void createVisualization(
 			HWModel hwModel,
 			Composite parent,
-			Shell shell,
-			@Optional
-			@Preference(
-					nodePath = "net.sourceforge.plantuml.eclipse",
-					value = PlantumlConstants.GRAPHVIZ_PATH)
-			String dotPath,
-			UISynchronize sync) {
+			Shell shell) {
 
 		Browser browser = new Browser(parent, SWT.NONE);
 
-		DiagramLocation diagramLocation = new DiagramLocation(hwModel);
-		if (!diagramLocation.isValid()) return;
+		// *** Execute thread to render diagram and update browser
 
-		// *** Execute job
+		new Thread(() -> {
+			// Build PlantUML diagram
+			HWBlockGenerator.updateDiagram(diagram, hwModel.getStructures());
 
-		JobChangeAdapter listener = new JobChangeAdapter() {
-			@Override
-			public void done(IJobChangeEvent event) {
-				sync.asyncExec(() -> {
+			String result;
+			try {
+				result = diagram.renderToSvg();
+			} catch (IOException e) {
+				result = prepareErrorMessage(e);
+				Platform.getLog(HWBlockDiagramVisualization2.class).error(result, e);
+			}
+
+			if (result != null && !browser.isDisposed()) {
+				final String browserContent = result;
+				browser.getDisplay().asyncExec(() -> {
 					if (!browser.isDisposed()) {
-						browser.setUrl(diagramLocation.getDiagramFilePath());
+						browser.setText(browserContent);
 					}
 				});
 			}
-		};
 
-		VisualizationHandler handler = new VisualizationHandler();
-		handler.execute(shell, sync, dotPath, hwModel.getStructures(), diagramLocation, false, listener);
+		}).start();
 	}
+
+	private String prepareErrorMessage(IOException e) {
+		return "Error invoking PlantUML: \"" + e.getMessage()
+				+ "\". Make sure you have configured the path to the dot executable properly in the PlantUML preferences.";
+	}
+
 }
diff --git a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/HWBlockDiagramVisualization2.java b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/HWBlockDiagramVisualization2.java
index 2f4774e..6d5fb0a 100644
--- a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/HWBlockDiagramVisualization2.java
+++ b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/HWBlockDiagramVisualization2.java
@@ -1,6 +1,6 @@
 /**
  ********************************************************************************
- * Copyright (c) 2020-2021 Robert Bosch GmbH.
+ * Copyright (c) 2020-2022 Robert Bosch GmbH.
  *
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
@@ -14,62 +14,67 @@
 
 package org.eclipse.app4mc.amalthea.visualization.hw;
 
+import java.io.IOException;
 import java.util.List;
 
 import javax.annotation.PostConstruct;
 
 import org.eclipse.app4mc.amalthea.model.HwStructure;
+import org.eclipse.app4mc.amalthea.visualization.hw.templates.HWBlockGenerator;
 import org.eclipse.app4mc.visualization.ui.registry.Visualization;
-import org.eclipse.core.runtime.jobs.IJobChangeEvent;
-import org.eclipse.core.runtime.jobs.JobChangeAdapter;
-import org.eclipse.e4.core.di.annotations.Optional;
-import org.eclipse.e4.core.di.extensions.Preference;
-import org.eclipse.e4.ui.di.UISynchronize;
+import org.eclipse.app4mc.visualization.util.svg.PlantUmlDiagram;
+import org.eclipse.core.runtime.Platform;
 import org.eclipse.swt.SWT;
 import org.eclipse.swt.browser.Browser;
 import org.eclipse.swt.widgets.Composite;
 import org.eclipse.swt.widgets.Shell;
 import org.osgi.service.component.annotations.Component;
 
-import net.sourceforge.plantuml.eclipse.utils.PlantumlConstants;
-
 @Component(property= {
 		"name=HW Structure Block Diagram",
 		"description=Block Diagram Visualization for Hardware Structures"
 })
 public class HWBlockDiagramVisualization2 implements Visualization {
 
+	private PlantUmlDiagram diagram = new PlantUmlDiagram();
+
 	@PostConstruct
 	public void createVisualization(
 			List<HwStructure> structures,
 			Composite parent,
-			Shell shell,
-			@Optional
-			@Preference(
-					nodePath = "net.sourceforge.plantuml.eclipse",
-					value = PlantumlConstants.GRAPHVIZ_PATH)
-			String dotPath,
-			UISynchronize sync) {
+			Shell shell) {
 
 		Browser browser = new Browser(parent, SWT.NONE);
 
-		DiagramLocation diagramLocation = new DiagramLocation(structures.get(0));
-		if (!diagramLocation.isValid()) return;
+		// *** Execute thread to render diagram and update browser
 
-		// *** Execute job
+		new Thread(() -> {
+			// Build PlantUML diagram
+			HWBlockGenerator.updateDiagram(diagram, structures);
 
-		JobChangeAdapter listener = new JobChangeAdapter() {
-			@Override
-			public void done(IJobChangeEvent event) {
-				sync.asyncExec(() -> {
+			String result;
+			try {
+				result = diagram.renderToSvg();
+			} catch (IOException e) {
+				result = prepareErrorMessage(e);
+				Platform.getLog(HWBlockDiagramVisualization2.class).error(result, e);
+			}
+
+			if (result != null && !browser.isDisposed()) {
+				final String browserContent = result;
+				browser.getDisplay().asyncExec(() -> {
 					if (!browser.isDisposed()) {
-						browser.setUrl(diagramLocation.getDiagramFilePath());
+						browser.setText(browserContent);
 					}
 				});
 			}
-		};
 
-		VisualizationHandler handler = new VisualizationHandler();
-		handler.execute(shell, sync, dotPath, structures, diagramLocation, false, listener);
+		}).start();
 	}
+
+	private String prepareErrorMessage(IOException e) {
+		return "Error invoking PlantUML: \"" + e.getMessage()
+				+ "\". Make sure you have configured the path to the dot executable properly in the PlantUML preferences.";
+	}
+
 }
diff --git a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/ModelToTextResult.java b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/ModelToTextResult.java
deleted file mode 100644
index 7c75528..0000000
--- a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/ModelToTextResult.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/**
- ********************************************************************************
- * Copyright (c) 2018-2020 Robert Bosch GmbH.
- *
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     Robert Bosch GmbH - initial API and implementation
-*******************************************************************************/
-
-package org.eclipse.app4mc.amalthea.visualization.hw;
-
-public class ModelToTextResult {
-
-	private boolean errorFlag;
-	private String errorMessage;
-
-	private CharSequence output;
-
-	public ModelToTextResult() {
-		errorFlag = false;
-	}
-
-	public boolean getErrorFlag() {
-		return errorFlag;
-	}
-
-	public void setErrorFlag(boolean errorFlag) {
-		this.errorFlag = errorFlag;
-	}
-
-	public boolean error() {
-		return errorFlag;
-	}
-
-	public boolean success() {
-		return !errorFlag;
-	}
-
-	public String getErrorMessage() {
-		return errorMessage;
-	}
-
-	public void setErrorMessage(String errorMessage) {
-		this.errorMessage = errorMessage;
-	}
-
-	public CharSequence getOutput() {
-		return output;
-	}
-
-	public void setOutput(CharSequence output) {
-		this.output = output;
-	}
-}
diff --git a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/VisualizationHandler.java b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/VisualizationHandler.java
deleted file mode 100644
index 7d6cc1f..0000000
--- a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/VisualizationHandler.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/**
- ********************************************************************************
- * Copyright (c) 2020-2022 Robert Bosch GmbH.
- *
- * This program and the accompanying materials are made
- * available under the terms of the Eclipse Public License 2.0
- * which is available at https://www.eclipse.org/legal/epl-2.0/
- *
- * SPDX-License-Identifier: EPL-2.0
- *
- * Contributors:
- *     Robert Bosch GmbH - initial API and implementation
- *******************************************************************************/
-
-package org.eclipse.app4mc.amalthea.visualization.hw;
-
-import java.io.BufferedWriter;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.List;
-
-import javax.inject.Named;
-
-import org.eclipse.app4mc.amalthea.model.HWModel;
-import org.eclipse.app4mc.amalthea.model.HwStructure;
-import org.eclipse.app4mc.amalthea.visualization.hw.templates.HWBlockDiagramCreator;
-import org.eclipse.core.runtime.CoreException;
-import org.eclipse.core.runtime.NullProgressMonitor;
-import org.eclipse.core.runtime.Status;
-import org.eclipse.core.runtime.jobs.IJobChangeListener;
-import org.eclipse.core.runtime.jobs.Job;
-import org.eclipse.e4.core.di.annotations.Execute;
-import org.eclipse.e4.core.di.annotations.Optional;
-import org.eclipse.e4.core.di.extensions.Preference;
-import org.eclipse.e4.ui.di.UISynchronize;
-import org.eclipse.e4.ui.services.IServiceConstants;
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.jface.dialogs.MessageDialog;
-import org.eclipse.jface.viewers.IStructuredSelection;
-import org.eclipse.swt.widgets.Shell;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import net.sourceforge.plantuml.FileFormat;
-import net.sourceforge.plantuml.FileFormatOption;
-import net.sourceforge.plantuml.SourceStringReader;
-import net.sourceforge.plantuml.core.DiagramDescription;
-import net.sourceforge.plantuml.eclipse.utils.PlantumlConstants;
-
-public class VisualizationHandler {
-
-	private static final String SYSTEM_PROPERTY = "SystemProperty";
-	private static final String PLANT_UML_PREFERENCE = "PlantUMLPreference";
-	private static final String PROPERTY_GRAPHVIZ_DOT = "GRAPHVIZ_DOT";
-	private static final Logger LOGGER = LoggerFactory.getLogger(VisualizationHandler.class);
-
-	@Execute
-	public void execute(
-			Shell shell,
-			UISynchronize sync,
-			@Optional
-			@Preference(
-					nodePath = "net.sourceforge.plantuml.eclipse",
-					value = PlantumlConstants.GRAPHVIZ_PATH)
-			String dotPath,
-			@Named(IServiceConstants.ACTIVE_SELECTION) IStructuredSelection selection) {
-
-		// **** Check selection and set HW model
-
-		if (selection.isEmpty()) {
-			LOGGER.info("No EObject selected!");
-			return;
-		}
-
-		if (selection.getFirstElement() instanceof EObject) {
-			EObject eObject = ((EObject) selection.getFirstElement());
-
-			DiagramLocation diagramLocation = new DiagramLocation(eObject);
-			if (!diagramLocation.isValid()) return;
-
-			// Execute job
-			List<HwStructure> structures = new ArrayList<>();
-
-			if (eObject instanceof HWModel) {
-				structures.addAll(((HWModel) eObject).getStructures());
-			} else if (eObject instanceof HwStructure) {
-				structures.add((HwStructure) eObject);
-			}
-
-			execute(shell, sync, dotPath, structures, diagramLocation, true, null);
-		}
-
-	}
-
-	/**
-	 *
-	 * @param shell The active Shell needed for info/error dialog creation.
-	 * @param dotPathFromPlantUMLPreferencePage The path to Graphviz dot.exe needed for visualization.
-	 * @param hwModel The {@link HWModel} that should be visualized.
-	 * @param listener optional listener that is notified on diagram generation job changes.
-	 * @return The path to the SVG.
-	 */
-	public void execute(
-			Shell shell,
-			UISynchronize sync,
-			String dotPathFromPlantUMLPreferencePage,
-			List<HwStructure> structures,
-			DiagramLocation diagramLocation,
-			boolean showSuccessInfo,
-			IJobChangeListener listener) {
-
-		// **** Check dot path and set GRAPHVIZ_DOT property
-
-		String dotPathFromSystemProperty = System.getenv(PROPERTY_GRAPHVIZ_DOT);
-
-		File dotFile = null;
-
-		if (dotPathFromPlantUMLPreferencePage != null) {
-			dotFile = ensureValidDotFile(shell, sync, dotPathFromPlantUMLPreferencePage, PLANT_UML_PREFERENCE);
-		} else if (dotPathFromSystemProperty != null) {
-			dotFile = ensureValidDotFile(shell, sync, dotPathFromSystemProperty, SYSTEM_PROPERTY);
-		} else {
-			showErrorDialog(shell, sync, "Missing Graphviz dot.exe location."
-					+ "\nPlease specify location via Window - Preferences - PlantUML - Path to the dot executable of Graphviz.");
-		}
-
-		if (dotFile == null)
-			return;
-
-		System.setProperty(PROPERTY_GRAPHVIZ_DOT, dotFile.getAbsolutePath());
-
-		LOGGER.info("GRAPHVIZ_DOT: {}", System.getProperty(PROPERTY_GRAPHVIZ_DOT));
-
-		// **** Generate Plant-UML file
-
-		Job job = Job.create("Generate diagram", monitor -> {
-
-			ModelToTextResult umlOutput = HWBlockDiagramCreator.generatePlantUML(structures);
-			if (umlOutput.error()) {
-				showErrorDialog(shell, sync, "Errors on generating HW Visualization for selected AMALTHEA model file: " + umlOutput.getErrorMessage());
-				return Status.CANCEL_STATUS;
-			}
-
-			// **** Write to UML to file
-
-			try (BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(diagramLocation.getPlantUmlFilePath()))) {
-				bufferedWriter.write(umlOutput.getOutput().toString());
-			} catch (IOException e) {
-				return Status.CANCEL_STATUS;
-			}
-
-			LOGGER.info("{} created: {}", diagramLocation.getPlantUmlFileName(), umlOutput.getOutput());
-
-			// **** Render SVG output
-
-			try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
-					FileOutputStream fileStream = new FileOutputStream(diagramLocation.getDiagramFilePath())) {
-
-				SourceStringReader reader = new SourceStringReader(umlOutput.getOutput().toString());
-				DiagramDescription description = reader.outputImage(outputStream, new FileFormatOption(FileFormat.SVG));
-
-				byte[] svgBytes = outputStream.toByteArray();
-				String svgString = new String(svgBytes, StandardCharsets.UTF_8);
-
-				fileStream.write(svgBytes);
-				fileStream.flush();
-
-				if (description == null || svgString.contains("An error has occured")) {
-					showErrorDialog(shell, sync, "SVG rendering failed."
-							+ "\nCheck Graphviz dot.exe location via Window - Preferences - PlantUML - Path to the dot executable of Graphviz..");
-					return Status.CANCEL_STATUS;
-				}
-
-				LOGGER.info("{} created.", diagramLocation.getDiagramFileName());
-
-				if (showSuccessInfo) {
-					showInfoDialog(shell, sync, "Successfully generated HW Visualization for amalthea model file.");
-				}
-			} catch (Exception e) {
-				showErrorDialog(shell, sync, "Unable to generate HW Visualization for selected AMALTHEA model file.");
-				LOGGER.error("Unable to generate HW Visualization for selected AMALTHEA model file.", e);
-			} finally {
-				try {
-					diagramLocation.getDiagramFolder().refreshLocal(1, new NullProgressMonitor());
-				} catch (CoreException ex) {
-					// no action required
-				}
-			}
-
-			return Status.OK_STATUS;
-		});
-
-		if (listener != null) {
-			job.addJobChangeListener(listener);
-		}
-
-		job.schedule();
-	}
-
-	private File ensureValidDotFile(Shell shell, UISynchronize sync, String dotPath, String origin) {
-
-
-		if (dotPath == null || dotPath.equals("")) {
-			showErrorDialog(shell, sync, "Missing Graphviz dot.exe location."
-						+ "\nPlease specify location via Window - Preferences - PlantUML - Path to the dot executable of Graphviz.");
-			return null;
-		}
-
-		final File dotFile = new File(dotPath);
-		if (!dotFile.canExecute()) {
-
-			if (origin.equals(PLANT_UML_PREFERENCE)) {
-				showErrorDialog(shell, sync, "Invalid Graphviz dot.exe location: \'" + dotFile.getAbsolutePath()+"\'"
-				+ "\nPlease set location via Window - Preferences - PlantUML - Path to the 'dot executable of Graphviz'.");
-			} else {
-				showErrorDialog(shell, sync, "Invalid Graphviz dot.exe location found in System Property 'GRAPHVIZ_DOT' : \'" + dotFile.getAbsolutePath()+"\'"
-				+ "\nPlease update the System Property 'GRAPHVIZ_DOT' with valid Path to the 'dot executable of Graphviz'.");
-			}
-			return null;
-		}
-
-		return dotFile;
-	}
-
-	private void showInfoDialog(Shell shell, UISynchronize sync, String message) {
-		sync.asyncExec(() ->
-			MessageDialog.openInformation(shell, "AMALTHEA HW Visualization", message)
-		);
-	}
-
-	private void showErrorDialog(Shell shell, UISynchronize sync, String message) {
-		sync.asyncExec(() ->
-			MessageDialog.openError(shell, "AMALTHEA HW Visualization", message)
-		);
-	}
-
-}
diff --git a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockDiagramCreator.xtend b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockGenerator.xtend
similarity index 60%
rename from plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockDiagramCreator.xtend
rename to plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockGenerator.xtend
index 4a96887..299c083 100644
--- a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockDiagramCreator.xtend
+++ b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/src/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockGenerator.xtend
@@ -1,6 +1,6 @@
 /**
  * *******************************************************************************
- * Copyright (c) 2018-2021 Robert Bosch GmbH and others.
+ * Copyright (c) 2018-2022 Robert Bosch GmbH and others.
  * 
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
@@ -21,28 +21,27 @@
 import org.eclipse.app4mc.amalthea.model.INamed
 import org.eclipse.app4mc.amalthea.model.Memory
 import org.eclipse.app4mc.amalthea.model.ProcessingUnit
-import org.eclipse.app4mc.amalthea.visualization.hw.ModelToTextResult
+import org.eclipse.app4mc.visualization.util.svg.PlantUmlDiagram
 
-class HWBlockDiagramCreator {
+class HWBlockGenerator {
 
-	static def ModelToTextResult generatePlantUML(List<HwStructure> structures) {
-		val state = new ModelToTextResult()
-		
-		val output = generateStructures(structures, state)
-		
+	static def void updateDiagram(PlantUmlDiagram diagram, List<HwStructure> structures) {
+		// reset old diagram data
+		diagram.resetDiagramData();
+
+		// generate new diagram
+		val state = new State();
+		val result = generateStructures(structures, state)
+
 		if (state.success) {
-			state.output = output
+			diagram.append(result);
 		} else {
-			// do not show error dialog
-			state.errorFlag = false
-			// create error diagram instead
-			state.output = error(state.errorMessage)
+			// create error diagram 
+			diagram.append(error(state.errorMessage))
 		}
-		
-		return state;
 	}
 
-	static def error(String message) '''
+	private static def error(String message) '''
 		@startuml
 		left to right direction
 		actor User
@@ -58,22 +57,22 @@
 		@enduml
 	'''
 
-	static def CharSequence generateStructures(List<HwStructure> structures, ModelToTextResult result) '''
+	private static def CharSequence generateStructures(List<HwStructure> structures, State state) '''
 			@startuml
 			«IF !structures.empty»
 				
 				' ===== FRAMES =====
 				«FOR s : structures»
-					«generateLevel(s, result)»
+					«generateLevel(s, state)»
 				«ENDFOR»
 				
 				' ===== ROUTES =====
 				«FOR s : structures»
-					«generateRoutes(s, result)»
+					«generateRoutes(s, state)»
 				«ENDFOR»
 			«ELSE»
-				«result.errorFlag = true»
-				«result.errorMessage = " No Structure in the model. "»
+				«state.errorFlag = true»
+				«state.errorMessage = " No Structure in the model. "»
 			«ENDIF»
 			
 			skinparam component {
@@ -91,50 +90,50 @@
 			@enduml
 		'''
 
-	static def CharSequence generateLevel(HwStructure s, ModelToTextResult errorCheck) '''
+	private static def CharSequence generateLevel(HwStructure s, State state) '''
 		«IF !(s === null || s.name.nullOrEmpty)»
 		
-			frame "«s.name»" as «convertFluxString(s.name)» {
+			frame "«s.name»" as «HWBlockGenerator.convertString(s.name)» {
 			«IF !s.modules.empty»
 			
 				«FOR m: s.modules»
 					«IF!(m.name.nullOrEmpty)»
 						«IF m instanceof ProcessingUnit»
-							[«convertFluxString(m.name)»] as «convertFluxString(m.name)» <<ProcessingUnit>>
+							[«HWBlockGenerator.convertString(m.name)»] as «HWBlockGenerator.convertString(m.name)» <<ProcessingUnit>>
 						«ELSEIF m instanceof Memory»
-							[«convertFluxString(m.name)»] as «convertFluxString(m.name)» <<Memory>>
+							[«HWBlockGenerator.convertString(m.name)»] as «HWBlockGenerator.convertString(m.name)» <<Memory>>
 						«ELSEIF m instanceof ConnectionHandler»
-							[«convertFluxString(m.name)»] as «convertFluxString(m.name)» <<ConnectionHandler>>
+							[«HWBlockGenerator.convertString(m.name)»] as «HWBlockGenerator.convertString(m.name)» <<ConnectionHandler>>
 						«ELSE»
-							[«convertFluxString(m.name)»] as «convertFluxString(m.name)» <<Cache>>
+							[«HWBlockGenerator.convertString(m.name)»] as «HWBlockGenerator.convertString(m.name)» <<Cache>>
 						«ENDIF»
 					«ELSE»
-						«errorCheck.errorFlag = true»
-						«errorCheck.errorMessage = " Missing HW Module name. "»
+						«state.errorFlag = true»
+						«state.errorMessage = " Missing HW Module name. "»
 					«ENDIF»
 				«ENDFOR»
 			«ENDIF»
 			«FOR su : s.structures»
-				«generateLevel(su, errorCheck)»
+				«generateLevel(su, state)»
 			«ENDFOR»
 		«ELSE»
-			«errorCheck.errorFlag = true»
-			«errorCheck.errorMessage = " Name of HwStructure is missing. "»
+			«state.errorFlag = true»
+			«state.errorMessage = " Name of HwStructure is missing. "»
 		«ENDIF»
 			}
 	'''
 
-	static def CharSequence generateRoutes(HwStructure s, ModelToTextResult errorCheck) '''
+	private static def CharSequence generateRoutes(HwStructure s, State state) '''
 		«IF !(s === null || s.connections.empty)»
 			
 			' add physical connections of structure «s.name»:
 			«FOR c : s.connections»
 				«IF !(c.name.nullOrEmpty)»
 					«»
-						«convertFluxString(name(c.port1?.eContainer as INamed))» -- «convertFluxString(name(c.port2?.eContainer as INamed))» : «c.name»
+						«HWBlockGenerator.convertString(name(c.port1?.eContainer as INamed))» -- «HWBlockGenerator.convertString(name(c.port2?.eContainer as INamed))» : «c.name»
 				«ELSE»
 					«»
-						«convertFluxString(name(c.port1?.eContainer as INamed))» -- «convertFluxString(name(c.port2?.eContainer as INamed))» : «c.toString»
+						«HWBlockGenerator.convertString(name(c.port1?.eContainer as INamed))» -- «HWBlockGenerator.convertString(name(c.port2?.eContainer as INamed))» : «c.toString»
 				«ENDIF»
 			«ENDFOR»
 		«ENDIF»	
@@ -149,18 +148,18 @@
 							«IF !(ae.name.nullOrEmpty)»
 								«IF ae.destination !== null»
 									«»
-										«convertFluxString(pUnit.name)» ..>«convertFluxString(ae.destination.name)» : «ae.name»
+										«HWBlockGenerator.convertString(pUnit.name)» ..>«HWBlockGenerator.convertString(ae.destination.name)» : «ae.name»
 								«ELSE»
-									«errorCheck.errorFlag = true»
-									«errorCheck.errorMessage = " Missing Destination of AccessElement. "»
+									«state.errorFlag = true»
+									«state.errorMessage = " Missing Destination of AccessElement. "»
 								«ENDIF»	
 							«ELSE»
 								«IF ae.destination !== null»
 									«»
-										«convertFluxString(pUnit.name)» ..>«convertFluxString(ae.destination.name)» : «ae.toString»
+										«HWBlockGenerator.convertString(pUnit.name)» ..>«HWBlockGenerator.convertString(ae.destination.name)» : «ae.toString»
 								«ELSE»
-									«errorCheck.errorFlag = true»
-									«errorCheck.errorMessage = " Missing Destination of AccessElement. "»
+									«state.errorFlag = true»
+									«state.errorMessage = " Missing Destination of AccessElement. "»
 								«ENDIF»	
 							«ENDIF»
 						«ENDFOR»
@@ -170,22 +169,22 @@
 		«ENDIF»
 		«IF !(s === null || s.structures.empty)»
 			«FOR su : s.structures»
-				«generateRoutes(su, errorCheck)»
+				«generateRoutes(su, state)»
 			«ENDFOR»
 		«ENDIF»
 	'''
 
-	static def name(INamed obj) {
+	private static def name(INamed obj) {
 		if (obj === null) return "<undefined>"
 		if (obj.name.nullOrEmpty) return "?"
 		return obj.name
 	}
 
-	static def convertFluxString(String str) {
+	private static def convertString(String str) {
 		return if (str.nullOrEmpty) "<no name>" else convertGenericString(str, "_");
 	}
 
-	static def convertGenericString(String instring, String replacestring) {
+	private static def convertGenericString(String instring, String replacestring) {
 		val String Regex = '/';
 		val tmpstr0 = instring.replaceAll(Regex, replacestring);
 
@@ -244,4 +243,37 @@
 		return tmpstr17;
 	}
 
+	private static class State {
+		boolean errorFlag;
+		String errorMessage;
+
+		def State() {
+			errorFlag = false;
+		}
+
+		def getErrorFlag() {
+			return errorFlag;
+		}
+
+		def setErrorFlag(boolean flag) {
+			errorFlag = flag;
+		}
+
+		def error() {
+			return errorFlag;
+		}
+
+		def success() {
+			return !errorFlag;
+		}
+
+		def String getErrorMessage() {
+			return errorMessage;
+		}
+
+		def void setErrorMessage(String message) {
+			errorMessage = message;
+		}
+	}
+
 }
diff --git a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/xtend-gen/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockDiagramCreator.java b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/xtend-gen/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockGenerator.java
similarity index 72%
rename from plugins/org.eclipse.app4mc.amalthea.visualization.hw/xtend-gen/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockDiagramCreator.java
rename to plugins/org.eclipse.app4mc.amalthea.visualization.hw/xtend-gen/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockGenerator.java
index 1c3ecb7..caffee2 100644
--- a/plugins/org.eclipse.app4mc.amalthea.visualization.hw/xtend-gen/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockDiagramCreator.java
+++ b/plugins/org.eclipse.app4mc.amalthea.visualization.hw/xtend-gen/org/eclipse/app4mc/amalthea/visualization/hw/templates/HWBlockGenerator.java
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 Robert Bosch GmbH and others.
+ * Copyright (c) 2018-2022 Robert Bosch GmbH and others.
  * 
  * This program and the accompanying materials are made
  * available under the terms of the Eclipse Public License 2.0
@@ -23,28 +23,61 @@
 import org.eclipse.app4mc.amalthea.model.INamed;
 import org.eclipse.app4mc.amalthea.model.Memory;
 import org.eclipse.app4mc.amalthea.model.ProcessingUnit;
-import org.eclipse.app4mc.amalthea.visualization.hw.ModelToTextResult;
+import org.eclipse.app4mc.visualization.util.svg.PlantUmlDiagram;
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.xtend2.lib.StringConcatenation;
 import org.eclipse.xtext.xbase.lib.StringExtensions;
 
 @SuppressWarnings("all")
-public class HWBlockDiagramCreator {
-  public static ModelToTextResult generatePlantUML(final List<HwStructure> structures) {
-    final ModelToTextResult state = new ModelToTextResult();
-    final CharSequence output = HWBlockDiagramCreator.generateStructures(structures, state);
-    boolean _success = state.success();
-    if (_success) {
-      state.setOutput(output);
-    } else {
-      state.setErrorFlag(false);
-      state.setOutput(HWBlockDiagramCreator.error(state.getErrorMessage()));
+public class HWBlockGenerator {
+  private static class State {
+    private boolean errorFlag;
+    
+    private String errorMessage;
+    
+    public boolean State() {
+      return this.errorFlag = false;
     }
-    return state;
+    
+    public boolean getErrorFlag() {
+      return this.errorFlag;
+    }
+    
+    public boolean setErrorFlag(final boolean flag) {
+      return this.errorFlag = flag;
+    }
+    
+    public boolean error() {
+      return this.errorFlag;
+    }
+    
+    public boolean success() {
+      return (!this.errorFlag);
+    }
+    
+    public String getErrorMessage() {
+      return this.errorMessage;
+    }
+    
+    public void setErrorMessage(final String message) {
+      this.errorMessage = message;
+    }
   }
   
-  public static CharSequence error(final String message) {
+  public static void updateDiagram(final PlantUmlDiagram diagram, final List<HwStructure> structures) {
+    diagram.resetDiagramData();
+    final HWBlockGenerator.State state = new HWBlockGenerator.State();
+    final CharSequence result = HWBlockGenerator.generateStructures(structures, state);
+    boolean _success = state.success();
+    if (_success) {
+      diagram.append(result);
+    } else {
+      diagram.append(HWBlockGenerator.error(state.errorMessage));
+    }
+  }
+  
+  private static CharSequence error(final String message) {
     StringConcatenation _builder = new StringConcatenation();
     _builder.append("@startuml");
     _builder.newLine();
@@ -77,7 +110,7 @@
     return _builder;
   }
   
-  public static CharSequence generateStructures(final List<HwStructure> structures, final ModelToTextResult result) {
+  private static CharSequence generateStructures(final List<HwStructure> structures, final HWBlockGenerator.State state) {
     StringConcatenation _builder = new StringConcatenation();
     _builder.append("@startuml");
     _builder.newLine();
@@ -90,7 +123,7 @@
         _builder.newLine();
         {
           for(final HwStructure s : structures) {
-            CharSequence _generateLevel = HWBlockDiagramCreator.generateLevel(s, result);
+            CharSequence _generateLevel = HWBlockGenerator.generateLevel(s, state);
             _builder.append(_generateLevel);
             _builder.newLineIfNotEmpty();
           }
@@ -100,15 +133,15 @@
         _builder.newLine();
         {
           for(final HwStructure s_1 : structures) {
-            CharSequence _generateRoutes = HWBlockDiagramCreator.generateRoutes(s_1, result);
+            CharSequence _generateRoutes = HWBlockGenerator.generateRoutes(s_1, state);
             _builder.append(_generateRoutes);
             _builder.newLineIfNotEmpty();
           }
         }
       } else {
-        result.setErrorFlag(true);
+        _builder.append(state.errorFlag = true);
         _builder.newLineIfNotEmpty();
-        result.setErrorMessage(" No Structure in the model. ");
+        _builder.append(state.errorMessage = " No Structure in the model. ");
         _builder.newLineIfNotEmpty();
       }
     }
@@ -150,7 +183,7 @@
     return _builder;
   }
   
-  public static CharSequence generateLevel(final HwStructure s, final ModelToTextResult errorCheck) {
+  private static CharSequence generateLevel(final HwStructure s, final HWBlockGenerator.State state) {
     StringConcatenation _builder = new StringConcatenation();
     {
       boolean _not = (!((s == null) || StringExtensions.isNullOrEmpty(s.getName())));
@@ -161,8 +194,8 @@
         String _name = s.getName();
         _builder.append(_name, "\t");
         _builder.append("\" as ");
-        String _convertFluxString = HWBlockDiagramCreator.convertFluxString(s.getName());
-        _builder.append(_convertFluxString, "\t");
+        String _convertString = HWBlockGenerator.convertString(s.getName());
+        _builder.append(_convertString, "\t");
         _builder.append(" {");
         _builder.newLineIfNotEmpty();
         {
@@ -183,11 +216,11 @@
                         _builder.append("\t");
                         _builder.append("\t");
                         _builder.append("[");
-                        String _convertFluxString_1 = HWBlockDiagramCreator.convertFluxString(((ProcessingUnit)m).getName());
-                        _builder.append(_convertFluxString_1, "\t\t");
+                        String _convertString_1 = HWBlockGenerator.convertString(((ProcessingUnit)m).getName());
+                        _builder.append(_convertString_1, "\t\t");
                         _builder.append("] as ");
-                        String _convertFluxString_2 = HWBlockDiagramCreator.convertFluxString(((ProcessingUnit)m).getName());
-                        _builder.append(_convertFluxString_2, "\t\t");
+                        String _convertString_2 = HWBlockGenerator.convertString(((ProcessingUnit)m).getName());
+                        _builder.append(_convertString_2, "\t\t");
                         _builder.append(" <<ProcessingUnit>>");
                         _builder.newLineIfNotEmpty();
                       } else {
@@ -195,11 +228,11 @@
                           _builder.append("\t");
                           _builder.append("\t");
                           _builder.append("[");
-                          String _convertFluxString_3 = HWBlockDiagramCreator.convertFluxString(((Memory)m).getName());
-                          _builder.append(_convertFluxString_3, "\t\t");
+                          String _convertString_3 = HWBlockGenerator.convertString(((Memory)m).getName());
+                          _builder.append(_convertString_3, "\t\t");
                           _builder.append("] as ");
-                          String _convertFluxString_4 = HWBlockDiagramCreator.convertFluxString(((Memory)m).getName());
-                          _builder.append(_convertFluxString_4, "\t\t");
+                          String _convertString_4 = HWBlockGenerator.convertString(((Memory)m).getName());
+                          _builder.append(_convertString_4, "\t\t");
                           _builder.append(" <<Memory>>");
                           _builder.newLineIfNotEmpty();
                         } else {
@@ -207,22 +240,22 @@
                             _builder.append("\t");
                             _builder.append("\t");
                             _builder.append("[");
-                            String _convertFluxString_5 = HWBlockDiagramCreator.convertFluxString(((ConnectionHandler)m).getName());
-                            _builder.append(_convertFluxString_5, "\t\t");
+                            String _convertString_5 = HWBlockGenerator.convertString(((ConnectionHandler)m).getName());
+                            _builder.append(_convertString_5, "\t\t");
                             _builder.append("] as ");
-                            String _convertFluxString_6 = HWBlockDiagramCreator.convertFluxString(((ConnectionHandler)m).getName());
-                            _builder.append(_convertFluxString_6, "\t\t");
+                            String _convertString_6 = HWBlockGenerator.convertString(((ConnectionHandler)m).getName());
+                            _builder.append(_convertString_6, "\t\t");
                             _builder.append(" <<ConnectionHandler>>");
                             _builder.newLineIfNotEmpty();
                           } else {
                             _builder.append("\t");
                             _builder.append("\t");
                             _builder.append("[");
-                            String _convertFluxString_7 = HWBlockDiagramCreator.convertFluxString(m.getName());
-                            _builder.append(_convertFluxString_7, "\t\t");
+                            String _convertString_7 = HWBlockGenerator.convertString(m.getName());
+                            _builder.append(_convertString_7, "\t\t");
                             _builder.append("] as ");
-                            String _convertFluxString_8 = HWBlockDiagramCreator.convertFluxString(m.getName());
-                            _builder.append(_convertFluxString_8, "\t\t");
+                            String _convertString_8 = HWBlockGenerator.convertString(m.getName());
+                            _builder.append(_convertString_8, "\t\t");
                             _builder.append(" <<Cache>>");
                             _builder.newLineIfNotEmpty();
                           }
@@ -232,11 +265,11 @@
                   } else {
                     _builder.append("\t");
                     _builder.append("\t");
-                    errorCheck.setErrorFlag(true);
+                    _builder.append(state.errorFlag = true, "\t\t");
                     _builder.newLineIfNotEmpty();
                     _builder.append("\t");
                     _builder.append("\t");
-                    errorCheck.setErrorMessage(" Missing HW Module name. ");
+                    _builder.append(state.errorMessage = " Missing HW Module name. ", "\t\t");
                     _builder.newLineIfNotEmpty();
                   }
                 }
@@ -248,15 +281,15 @@
           EList<HwStructure> _structures = s.getStructures();
           for(final HwStructure su : _structures) {
             _builder.append("\t");
-            CharSequence _generateLevel = HWBlockDiagramCreator.generateLevel(su, errorCheck);
+            CharSequence _generateLevel = HWBlockGenerator.generateLevel(su, state);
             _builder.append(_generateLevel, "\t");
             _builder.newLineIfNotEmpty();
           }
         }
       } else {
-        errorCheck.setErrorFlag(true);
+        _builder.append(state.errorFlag = true);
         _builder.newLineIfNotEmpty();
-        errorCheck.setErrorMessage(" Name of HwStructure is missing. ");
+        _builder.append(state.errorMessage = " Name of HwStructure is missing. ");
         _builder.newLineIfNotEmpty();
       }
     }
@@ -266,7 +299,7 @@
     return _builder;
   }
   
-  public static CharSequence generateRoutes(final HwStructure s, final ModelToTextResult errorCheck) {
+  private static CharSequence generateRoutes(final HwStructure s, final HWBlockGenerator.State state) {
     StringConcatenation _builder = new StringConcatenation();
     {
       boolean _not = (!((s == null) || s.getConnections().isEmpty()));
@@ -291,16 +324,16 @@
                 if (_port1!=null) {
                   _eContainer=_port1.eContainer();
                 }
-                String _convertFluxString = HWBlockDiagramCreator.convertFluxString(HWBlockDiagramCreator.name(((INamed) _eContainer)));
-                _builder.append(_convertFluxString, "\t");
+                String _convertString = HWBlockGenerator.convertString(HWBlockGenerator.name(((INamed) _eContainer)));
+                _builder.append(_convertString, "\t");
                 _builder.append(" -- ");
                 HwPort _port2 = c.getPort2();
                 EObject _eContainer_1 = null;
                 if (_port2!=null) {
                   _eContainer_1=_port2.eContainer();
                 }
-                String _convertFluxString_1 = HWBlockDiagramCreator.convertFluxString(HWBlockDiagramCreator.name(((INamed) _eContainer_1)));
-                _builder.append(_convertFluxString_1, "\t");
+                String _convertString_1 = HWBlockGenerator.convertString(HWBlockGenerator.name(((INamed) _eContainer_1)));
+                _builder.append(_convertString_1, "\t");
                 _builder.append(" : ");
                 String _name_1 = c.getName();
                 _builder.append(_name_1, "\t");
@@ -313,16 +346,16 @@
                 if (_port1_1!=null) {
                   _eContainer_2=_port1_1.eContainer();
                 }
-                String _convertFluxString_2 = HWBlockDiagramCreator.convertFluxString(HWBlockDiagramCreator.name(((INamed) _eContainer_2)));
-                _builder.append(_convertFluxString_2, "\t");
+                String _convertString_2 = HWBlockGenerator.convertString(HWBlockGenerator.name(((INamed) _eContainer_2)));
+                _builder.append(_convertString_2, "\t");
                 _builder.append(" -- ");
                 HwPort _port2_1 = c.getPort2();
                 EObject _eContainer_3 = null;
                 if (_port2_1!=null) {
                   _eContainer_3=_port2_1.eContainer();
                 }
-                String _convertFluxString_3 = HWBlockDiagramCreator.convertFluxString(HWBlockDiagramCreator.name(((INamed) _eContainer_3)));
-                _builder.append(_convertFluxString_3, "\t");
+                String _convertString_3 = HWBlockGenerator.convertString(HWBlockGenerator.name(((INamed) _eContainer_3)));
+                _builder.append(_convertString_3, "\t");
                 _builder.append(" : ");
                 String _string = c.toString();
                 _builder.append(_string, "\t");
@@ -366,19 +399,19 @@
                               if (_tripleNotEquals) {
                                 _builder.newLine();
                                 _builder.append("\t");
-                                String _convertFluxString_4 = HWBlockDiagramCreator.convertFluxString(pUnit.getName());
-                                _builder.append(_convertFluxString_4, "\t");
+                                String _convertString_4 = HWBlockGenerator.convertString(pUnit.getName());
+                                _builder.append(_convertString_4, "\t");
                                 _builder.append(" ..>");
-                                String _convertFluxString_5 = HWBlockDiagramCreator.convertFluxString(ae.getDestination().getName());
-                                _builder.append(_convertFluxString_5, "\t");
+                                String _convertString_5 = HWBlockGenerator.convertString(ae.getDestination().getName());
+                                _builder.append(_convertString_5, "\t");
                                 _builder.append(" : ");
                                 String _name_3 = ae.getName();
                                 _builder.append(_name_3, "\t");
                                 _builder.newLineIfNotEmpty();
                               } else {
-                                errorCheck.setErrorFlag(true);
+                                _builder.append(state.errorFlag = true);
                                 _builder.newLineIfNotEmpty();
-                                errorCheck.setErrorMessage(" Missing Destination of AccessElement. ");
+                                _builder.append(state.errorMessage = " Missing Destination of AccessElement. ");
                                 _builder.newLineIfNotEmpty();
                               }
                             }
@@ -389,19 +422,19 @@
                               if (_tripleNotEquals_1) {
                                 _builder.newLine();
                                 _builder.append("\t");
-                                String _convertFluxString_6 = HWBlockDiagramCreator.convertFluxString(pUnit.getName());
-                                _builder.append(_convertFluxString_6, "\t");
+                                String _convertString_6 = HWBlockGenerator.convertString(pUnit.getName());
+                                _builder.append(_convertString_6, "\t");
                                 _builder.append(" ..>");
-                                String _convertFluxString_7 = HWBlockDiagramCreator.convertFluxString(ae.getDestination().getName());
-                                _builder.append(_convertFluxString_7, "\t");
+                                String _convertString_7 = HWBlockGenerator.convertString(ae.getDestination().getName());
+                                _builder.append(_convertString_7, "\t");
                                 _builder.append(" : ");
                                 String _string_1 = ae.toString();
                                 _builder.append(_string_1, "\t");
                                 _builder.newLineIfNotEmpty();
                               } else {
-                                errorCheck.setErrorFlag(true);
+                                _builder.append(state.errorFlag = true);
                                 _builder.newLineIfNotEmpty();
-                                errorCheck.setErrorMessage(" Missing Destination of AccessElement. ");
+                                _builder.append(state.errorMessage = " Missing Destination of AccessElement. ");
                                 _builder.newLineIfNotEmpty();
                               }
                             }
@@ -423,7 +456,7 @@
         {
           EList<HwStructure> _structures = s.getStructures();
           for(final HwStructure su : _structures) {
-            CharSequence _generateRoutes = HWBlockDiagramCreator.generateRoutes(su, errorCheck);
+            CharSequence _generateRoutes = HWBlockGenerator.generateRoutes(su, state);
             _builder.append(_generateRoutes);
             _builder.newLineIfNotEmpty();
           }
@@ -433,7 +466,7 @@
     return _builder;
   }
   
-  public static String name(final INamed obj) {
+  private static String name(final INamed obj) {
     if ((obj == null)) {
       return "<undefined>";
     }
@@ -444,18 +477,18 @@
     return obj.getName();
   }
   
-  public static String convertFluxString(final String str) {
+  private static String convertString(final String str) {
     String _xifexpression = null;
     boolean _isNullOrEmpty = StringExtensions.isNullOrEmpty(str);
     if (_isNullOrEmpty) {
       _xifexpression = "<no name>";
     } else {
-      _xifexpression = HWBlockDiagramCreator.convertGenericString(str, "_");
+      _xifexpression = HWBlockGenerator.convertGenericString(str, "_");
     }
     return _xifexpression;
   }
   
-  public static String convertGenericString(final String instring, final String replacestring) {
+  private static String convertGenericString(final String instring, final String replacestring) {
     final String Regex = "/";
     final String tmpstr0 = instring.replaceAll(Regex, replacestring);
     final String Regex1 = " ";
diff --git a/plugins/org.eclipse.app4mc.emf.visualizations/src/org/eclipse/app4mc/emf/visualizations/EObjectRefsGenerator.java b/plugins/org.eclipse.app4mc.emf.visualizations/src/org/eclipse/app4mc/emf/visualizations/EObjectRefsGenerator.java
index 3322ac3..ea8cbe9 100644
--- a/plugins/org.eclipse.app4mc.emf.visualizations/src/org/eclipse/app4mc/emf/visualizations/EObjectRefsGenerator.java
+++ b/plugins/org.eclipse.app4mc.emf.visualizations/src/org/eclipse/app4mc/emf/visualizations/EObjectRefsGenerator.java
@@ -44,10 +44,10 @@
 
 		// generate new diagram
 		
-		diagram.append("' Created by EObjectRefsBuilder (" + timestamp() + ")\n\n");
-
 		diagram.append("@startuml\n\n");
 
+		diagram.append("' Created by EObjectRefsBuilder (" + timestamp() + ")\n\n");
+
 		diagram.append("hide empty members\n\n");
 
 		if (config.isHorizontalLayout()) {
@@ -56,10 +56,6 @@
 			diagram.append("top to bottom direction\n\n");
 		}
 
-		diagram.append("skinparam class {\n");
-		diagram.append("  BackgroundColor<<selected>> Moccasin\n");
-		diagram.append("}\n");
-
 		buildContent(diagram, eObject, config);
 
 		diagram.append("\n@enduml");
diff --git a/plugins/org.eclipse.app4mc.visualization.util.svg/src/org/eclipse/app4mc/visualization/util/svg/AbstractDiagram.java b/plugins/org.eclipse.app4mc.visualization.util.svg/src/org/eclipse/app4mc/visualization/util/svg/AbstractDiagram.java
index 08637ab..e52172e 100644
--- a/plugins/org.eclipse.app4mc.visualization.util.svg/src/org/eclipse/app4mc/visualization/util/svg/AbstractDiagram.java
+++ b/plugins/org.eclipse.app4mc.visualization.util.svg/src/org/eclipse/app4mc/visualization/util/svg/AbstractDiagram.java
@@ -34,6 +34,10 @@
 		idMap = HashBiMap.create();
 	}
 
+	public void append(CharSequence chars) {
+		diagramBuilder.append(chars);
+	}
+
 	public void append(String str) {
 		diagramBuilder.append(str);
 	}
diff --git a/plugins/org.eclipse.app4mc.visualization.util.svg/src/org/eclipse/app4mc/visualization/util/svg/PlantUmlDiagram.java b/plugins/org.eclipse.app4mc.visualization.util.svg/src/org/eclipse/app4mc/visualization/util/svg/PlantUmlDiagram.java
index 627f387..4be6b82 100644
--- a/plugins/org.eclipse.app4mc.visualization.util.svg/src/org/eclipse/app4mc/visualization/util/svg/PlantUmlDiagram.java
+++ b/plugins/org.eclipse.app4mc.visualization.util.svg/src/org/eclipse/app4mc/visualization/util/svg/PlantUmlDiagram.java
@@ -26,6 +26,18 @@
 
 public class PlantUmlDiagram extends AbstractDiagram {
 
+	private String svg = null;
+
+	public String getDiagramSVG() {
+		return svg;
+	}
+
+	@Override
+	public void resetDiagramData() {
+		super.resetDiagramData();
+		svg = null;
+	}
+	
 	/**
 	 * Renders PlantUML source to SVG
 	 * 
@@ -43,7 +55,8 @@
 		final SourceStringReader reader = new SourceStringReader(source);
 		final DiagramDescription desc = reader.outputImage(baos, new FileFormatOption(FileFormat.SVG));
 		if (desc != null && !desc.getDescription().isEmpty()) {
-			return baos.toString(StandardCharsets.UTF_8.name());
+			svg = baos.toString(StandardCharsets.UTF_8.name());
+			return svg;
 		}
 
 		return null;