initial commit for model obfuscator
diff --git a/features/org.eclipse.viatra.modelobfuscator.feature/.project b/features/org.eclipse.viatra.modelobfuscator.feature/.project
new file mode 100644
index 0000000..bf6b5ac
--- /dev/null
+++ b/features/org.eclipse.viatra.modelobfuscator.feature/.project
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.viatra.modelobfuscator.feature</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.pde.FeatureBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.FeatureNature</nature>
+	</natures>
+</projectDescription>
diff --git a/features/org.eclipse.viatra.modelobfuscator.feature/build.properties b/features/org.eclipse.viatra.modelobfuscator.feature/build.properties
new file mode 100644
index 0000000..64f93a9
--- /dev/null
+++ b/features/org.eclipse.viatra.modelobfuscator.feature/build.properties
@@ -0,0 +1 @@
+bin.includes = feature.xml
diff --git a/features/org.eclipse.viatra.modelobfuscator.feature/feature.xml b/features/org.eclipse.viatra.modelobfuscator.feature/feature.xml
new file mode 100644
index 0000000..ff05ddc
--- /dev/null
+++ b/features/org.eclipse.viatra.modelobfuscator.feature/feature.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<feature
+      id="org.eclipse.viatra.modelobfuscator.feature"
+      label="VIATRA Model Obfuscator Feature"
+      version="0.7.0.qualifier"
+      provider-name="Eclipse VIATRA Project"
+      license-feature="org.eclipse.incquery.runtime.feature"
+      license-feature-version="0.8.0">
+
+   <description url="http://www.example.com/description">
+      VIATRA Model Obfuscator
+   </description>
+
+   <copyright url="http://www.example.com/copyright">
+      [Enter Copyright Description here.]
+   </copyright>
+
+   <license url="http://www.example.com/license">
+      [Enter License Description here.]
+   </license>
+
+   <plugin
+         id="org.eclipse.viatra.modelobfuscator.runtime"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+   <plugin
+         id="org.eclipse.viatra.modelobfuscator.ui"
+         download-size="0"
+         install-size="0"
+         version="0.0.0"
+         unpack="false"/>
+
+</feature>
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/.classpath b/plugins/org.eclipse.viatra.modelobfuscator.runtime/.classpath
new file mode 100644
index 0000000..358df1b
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="xtend-gen"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/.gitignore b/plugins/org.eclipse.viatra.modelobfuscator.runtime/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/.project b/plugins/org.eclipse.viatra.modelobfuscator.runtime/.project
new file mode 100644
index 0000000..be838b4
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.viatra.modelobfuscator.runtime</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.viatra.modelobfuscator.runtime/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..c537b63
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/META-INF/MANIFEST.MF b/plugins/org.eclipse.viatra.modelobfuscator.runtime/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..e2b9e94
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/META-INF/MANIFEST.MF
@@ -0,0 +1,16 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: VIATRA Model Obfuscator Runtime
+Bundle-SymbolicName: org.eclipse.viatra.modelobfuscator.runtime
+Bundle-Version: 0.7.0.qualifier
+Bundle-Vendor: Eclipse VIATRA Project
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.eclipse.xtend.lib,
+ com.google.guava,
+ org.eclipse.xtext.xbase.lib,
+ org.eclipse.emf.ecore
+Export-Package: org.eclipse.viatra.modelobfuscator.api,
+ org.eclipse.viatra.modelobfuscator.emf.simple,
+ org.eclipse.viatra.modelobfuscator.util,
+ org.eclipse.viatra.modelobfuscator.xml
+
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/build.properties b/plugins/org.eclipse.viatra.modelobfuscator.runtime/build.properties
new file mode 100644
index 0000000..d8e2f0e
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/build.properties
@@ -0,0 +1,5 @@
+source.. = src/,\
+           xtend-gen/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/api/DataTypeObfuscator.xtend b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/api/DataTypeObfuscator.xtend
new file mode 100644
index 0000000..d35b993
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/api/DataTypeObfuscator.xtend
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.api
+
+import org.eclipse.viatra.modelobfuscator.util.StringObfuscator
+
+/**
+ * Obfuscator interface for a single data type (see {@link StringObfuscator} for example).
+ * 
+ * @author Abel Hegedus
+ *
+ */
+interface DataTypeObfuscator<DataType> {
+  
+  /**
+   * Takes the original data and returns its obfuscated form
+   */
+  def DataType obfuscateData(DataType original)
+  
+  /**
+   * Takes the obfuscated data and returns its original form (as long as the 
+   * obfuscation was done with an obfuscator set up with the same values).
+   */
+  def DataType restoreData(DataType obfuscated)
+  
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/api/ModelObfuscator.xtend b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/api/ModelObfuscator.xtend
new file mode 100644
index 0000000..cb1189d
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/api/ModelObfuscator.xtend
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.api
+
+/**
+ * Model obfuscators are used to modify an input model to 
+ * conceal all sensitive details (especially String attribute values)
+ * by replacing them with obfuscated values deterministically (to support restoration as well).
+ * 
+ * @author Abel Hegedus
+ *
+ */
+interface ModelObfuscator {
+  
+  /**
+   * Performs the obfuscation on the input model
+   */  
+  def void obfuscate()
+  
+  /**
+   * Restores the obfuscated model as long as the obfuscator is
+   * configured by the same values as the one used for obfuscation.
+   */
+  def void restore()
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/emf/simple/EMFModelObfuscatorBuilder.xtend b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/emf/simple/EMFModelObfuscatorBuilder.xtend
new file mode 100644
index 0000000..d992b65
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/emf/simple/EMFModelObfuscatorBuilder.xtend
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.emf.simple
+
+import org.eclipse.emf.ecore.resource.ResourceSet
+import org.eclipse.viatra.modelobfuscator.util.ObfuscatorUtil
+import org.eclipse.viatra.modelobfuscator.util.StringObfuscator
+import com.google.common.base.Preconditions
+
+/**
+ * Builder API for setting up an EMF obfuscator. Currently the only implementation that can
+ * be built is {@link SimpleEMFModelObfuscator}. the input for the obfuscator is a ResourceSet, and
+ * it is possible to provide a {@link ResourceFilter} as well.
+ * 
+ * <p/>The builder allows setting a seed and a salt for the obfuscator, which is used when initializing
+ * the {@link StringObfuscator}, thus supporting reproducibility and restoration.
+ * 
+ * <p/>The default value of the seed is a random, 32 character long, hexadecimal string created by
+ * {@link ObfuscatorUtil#generateHexSeed}. The default value of the salt is empty.
+ * 
+ * @author Abel Hegedus
+ *
+ */
+class EMFModelObfuscatorBuilder {
+
+  private ResourceSet inputRS
+  private ResourceFilter filter
+  private String saltString = ""
+  private String seedString = ObfuscatorUtil.generateHexSeed(32);
+
+  /**
+   * Hiding constructor of builder
+   */
+  protected new() {
+  }
+
+  /**
+   * Creates a new, unconfigured builder for EMF model obfuscators.
+   */
+  def static create() {
+    new EMFModelObfuscatorBuilder
+  }
+
+  /**
+   * Sets the input of the built obfuscator
+   */
+  def setInput(ResourceSet inputResourceSet) {
+    inputRS = inputResourceSet
+    return this
+  }
+
+  /**
+   * Sets the filter used in the built obfuscator.
+   * See {@link ResourceFilter} for details.
+   */
+  def setFilter(ResourceFilter filter) {
+    this.filter = filter
+    return this
+  }
+
+  /**
+   * Sets the salt used for obfuscating String values.
+   * See {@link StringObfuscator} for details.
+   */
+  def setSalt(String salt) {
+    saltString = salt
+    return this
+  }
+
+  /**
+   * Sets the seed used for obfuscating String values.
+   * See {@link StringObfuscator} for details.
+   */
+  def setSeed(String seed) {
+    seedString = seed
+    return this
+  }
+
+  /**
+   * Returns the {@link SimpleEMFModelObfuscator} instance built using the current configuration of the builder. 
+   */
+  def build() {
+    Preconditions.checkState(inputRS != null, "Input resource set cannot be null")
+    Preconditions.checkState(seedString != null, "Seed cannot be null")
+    Preconditions.checkState(saltString != null, "Salt cannot be null (empty string allowed)")
+    val obfuscator = new SimpleEMFModelObfuscator()
+    obfuscator.inputResourceSet = inputRS
+    obfuscator.filter = filter
+    obfuscator.stringObfuscator = new StringObfuscator(seedString, saltString)
+    return obfuscator
+  }
+
+}
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/emf/simple/SimpleEMFModelObfuscator.xtend b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/emf/simple/SimpleEMFModelObfuscator.xtend
new file mode 100644
index 0000000..7e93f69
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/emf/simple/SimpleEMFModelObfuscator.xtend
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.emf.simple
+
+import com.google.common.base.Preconditions
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.resource.ResourceSet
+import org.eclipse.emf.ecore.util.EcoreUtil
+import org.eclipse.viatra.modelobfuscator.api.ModelObfuscator
+import org.eclipse.viatra.modelobfuscator.util.StringObfuscator
+import org.eclipse.emf.common.util.EList
+import org.eclipse.emf.ecore.resource.Resource
+
+/**
+ * This simple EMF obfuscator uses the TreeIterator of EcoreUtil to traverse all
+ * resources in the resource set. Note that only resources loaded already are traversed!
+ * 
+ * <p/>Use {@link EMFModelObfuscatorBuilder} to create an instance of this class. 
+
+ * <p/>The obfuscation modifies resources that are not filtered out by a {@link ResourceFilter}
+ * and changes all values of (changeable, non-derived, non-volatile) String attributes using a {@link StringObfuscator}. 
+ * 
+ * <p/>Note that changes are done directly on the model, users must ensure correct invocation in case of editing domains, or 
+ * transactional environments. 
+ * 
+ * @author Abel Hegedus
+ *
+ */
+class SimpleEMFModelObfuscator implements ModelObfuscator {
+
+  protected ResourceSet inputResourceSet
+  protected ResourceFilter filter
+  protected extension StringObfuscator stringObfuscator
+
+  override obfuscate() {
+    modifyModel(true)
+  }
+
+  override restore() {
+    modifyModel(false)
+  }
+
+  protected def modifyModel(boolean obfuscate) {
+    Preconditions.checkState(inputResourceSet != null, "Input resourceset must not be null")
+    val resources = newArrayList
+    resources += inputResourceSet.resources
+    // resource list filtered first
+    resources.filter[filter == null || !filter.avoidObfuscation(it)].forEach [
+      // tree iterator filtered for instances of EObject
+      EcoreUtil.getAllContents(it, true).filter(EObject).forEach [ obj |
+        // only attributes modified
+        obj.eClass.EAllAttributes.filter [
+          // we don't need (or can't) to modify such attributes
+          changeable && !derived && !volatile &&
+          // the value must be String then
+          EAttributeType.instanceClass == String
+        ].forEach [
+          val old = obj.eGet(it)
+          if (many) {
+            // handle EList values
+            val oldValues = old as EList<String>
+            val newValues = newArrayList
+            oldValues.forEach [
+              newValues += it.modifyData(obfuscate)
+            ]
+            oldValues.clear
+            oldValues += newValues
+          } else {
+            // set single value
+            val oldString = old as String
+            obj.eSet(it, oldString.modifyData(obfuscate))
+          }
+        ]
+      ]
+    ]
+  }
+
+  /**
+   * Returns the obfuscator that stores the seed and salt values as well.
+   */
+  def getStringObfuscator() {
+    stringObfuscator
+  }
+
+  protected def modifyData(String data, boolean obfuscate) {
+    if (obfuscate) {
+      data.obfuscateData
+    } else {
+      data.restoreData
+    }
+  }
+}
+
+/**
+ * Simple interface that can be used to filter out resources, which should
+ * not be obfuscated in a resource set.
+ * 
+ * @author Abel Hegedus
+ */
+interface ResourceFilter {
+
+  /**
+   * Return true if resource should NOT be obfuscated
+   */
+  def boolean avoidObfuscation(Resource resource)
+
+}
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/util/ObfuscatorUtil.java b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/util/ObfuscatorUtil.java
new file mode 100644
index 0000000..bdbcaeb
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/util/ObfuscatorUtil.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.util;
+
+import com.google.common.base.Preconditions;
+
+/**
+ * @author Abel Hegedus
+ *
+ */
+public class ObfuscatorUtil {
+
+    public static byte[] xorWithSeed(byte[] input, byte[] key) {
+        byte[] out = new byte[input.length];
+        for (int i = 0; i < input.length; i++) {
+            out[i] = (byte) (input[i] ^ key[i%key.length]);
+        }
+        return out;
+    }
+    
+    public static String generateHexSeed(int length) {
+        Preconditions.checkArgument(length > 0,"Length must be positive");
+        // each fragment is 3 characters and we need an additional one
+        int noOfFragments = (length / 3) + 1;
+        StringBuilder sb = new StringBuilder(noOfFragments * 3);
+        for(int i = 0; i < noOfFragments; i++) {
+            // randomized string but first 3 chars not too random (typically "3fd")
+            String fragment = Long.toHexString(Double.doubleToLongBits(Math.random()));
+            // take only last 3 characters
+            sb.append(fragment.substring(3, 6));
+        }
+        return sb.substring(0, length);
+    }
+    
+}
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/util/StringObfuscator.xtend b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/util/StringObfuscator.xtend
new file mode 100644
index 0000000..0121d4a
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/util/StringObfuscator.xtend
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.util
+
+import org.eclipse.viatra.modelobfuscator.api.DataTypeObfuscator
+import com.google.common.io.BaseEncoding
+import com.google.common.base.Preconditions
+
+/**
+ * @author Abel Hegedus
+ *
+ */
+class StringObfuscator implements DataTypeObfuscator<String> {
+  
+  private String seed
+  private String salt
+  
+  new(String seed, String salt){
+    Preconditions.checkArgument(seed != null, "Seed cannot be null")
+    Preconditions.checkArgument(salt != null, "Salt cannot be null")
+    this.seed = seed
+    this.salt = salt
+  }
+  
+  override obfuscateData(String original) {
+    if(original != null){
+      val salted = salt + original
+      val obfuscatedBytes = ObfuscatorUtil.xorWithSeed(salted.bytes, seed.bytes)
+      return BaseEncoding.base64.encode(obfuscatedBytes)
+    }
+  }
+  
+  override restoreData(String obfuscated) {
+    if(obfuscated != null){
+      val obfuscatedBytes = BaseEncoding.base64.decode(obfuscated)
+      val salted = new String(ObfuscatorUtil.xorWithSeed(obfuscatedBytes, seed.bytes))
+      return salted.substring(salt.length)
+    }
+  }
+  
+  def getSeed(){
+    seed
+  }
+  
+  def getSalt(){
+    salt
+  }
+  
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/xml/XMLModelObfuscator.xtend b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/xml/XMLModelObfuscator.xtend
new file mode 100644
index 0000000..c8c02e3
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/xml/XMLModelObfuscator.xtend
@@ -0,0 +1,160 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.xml
+
+import java.io.InputStream
+import java.io.OutputStream
+import java.util.ArrayDeque
+import javax.xml.stream.XMLEventFactory
+import javax.xml.stream.XMLInputFactory
+import javax.xml.stream.XMLOutputFactory
+import javax.xml.stream.events.Attribute
+import javax.xml.stream.events.XMLEvent
+import org.eclipse.viatra.modelobfuscator.api.ModelObfuscator
+import org.eclipse.viatra.modelobfuscator.util.StringObfuscator
+
+/**
+ * This simple XML obfuscator uses the event-based StaX parser implementation to traverse 
+ * the XML document on the input stream.
+ * 
+ * <p/>Use {@link XMLModelObfuscatorBuilder} to create an instance of this class. 
+
+ * <p/>The obfuscation modifies values of attributes and content set in the provided {@link XMLSchemaConfiguration}
+ *  using a {@link StringObfuscator}.
+ * 
+ * <p/>Note that changes are done on the output stream by piping (and sometimes modifying) events from the input reader. 
+ * 
+ * @author Abel Hegedus
+ *
+ */
+class XMLModelObfuscator implements ModelObfuscator {
+
+  protected InputStream inputStream
+  protected OutputStream outputStream
+  protected extension XMLSchemaConfiguration config
+  protected extension StringObfuscator stringObfuscator
+  protected boolean debug = false
+
+  private extension XMLInputFactory = XMLInputFactory.newInstance
+  private extension XMLOutputFactory = XMLOutputFactory.newInstance
+  private extension XMLEventFactory = XMLEventFactory.newInstance
+
+  override obfuscate() {
+    modifyModel(true)
+  }
+
+  override restore() {
+    modifyModel(false)
+  }
+
+  protected def modifyModel(boolean obfuscate) {
+    val inputReader = createXMLEventReader(inputStream)
+    val outputWriter = createXMLEventWriter(outputStream)
+
+    // we need a stack to know which tag contains some text content  
+    val tagStack = new ArrayDeque()
+    while (inputReader.hasNext) {
+      val event = inputReader.nextEvent
+
+      switch (event.eventType) {
+        case XMLEvent.START_ELEMENT: {
+          val startEvent = event.asStartElement
+          val tagName = startEvent.name.localPart
+          tagStack.push(tagName)
+          if (debug) {
+            println("> start: " + tagName)
+          }
+          
+          // see if there are attributes to obfuscate for this tag
+          val attrsToObfuscate = tagName.toString.obfuscateableAttributeNames
+          if (attrsToObfuscate.empty) {
+            outputWriter.add(event)
+          } else {
+            val attributes = newArrayList()
+            startEvent.attributes.filter(Attribute).forEach [
+              if (attrsToObfuscate.contains(name.localPart)) {
+                // attributes that need to be modified are dealt with
+                val obfuscatedAttr = value.modifyData(obfuscate)
+                if (debug) {
+                  println(
+                    " ! altering attribute: " + name + " from: " + value + " to: " + obfuscatedAttr)
+                }
+                attributes += createAttribute(name, obfuscatedAttr)
+              } else {
+                // no change needed
+                attributes += it
+              }
+            ]
+            
+            // create new event for changed element
+            val obfuscatedStart = createStartElement(startEvent.name, attributes.iterator,
+              startEvent.namespaces)
+            outputWriter.add(obfuscatedStart)
+          }
+        }
+        case XMLEvent.CHARACTERS: {
+          val charEvent = event.asCharacters
+          val data = charEvent.data.trim
+          if (!data.empty) {
+            // the stack is not modified but we need to know what the current tag is
+            val currentTag = tagStack.peek
+            if (debug) {
+              println("  - characters in " + currentTag + ": " + data)
+            }
+
+            if (currentTag.tagContentObfuscateable) {
+              // contents of tag must be obfuscated
+              val obfuscatedData = data.modifyData(obfuscate)
+              if (debug) {
+                println("  + change content to " + obfuscatedData)
+              }
+              // create modified event
+              val obfuscatedEvent = createCharacters(obfuscatedData)
+              outputWriter.add(obfuscatedEvent)
+            } else {
+              // content unmodified
+              outputWriter.add(event)
+            }
+          } else {
+            // even empty string events are needed on the output
+            outputWriter.add(event)
+          }
+        }
+        case XMLEvent.END_ELEMENT: {
+          // just remove top from stack as tag is finished
+          val tagName = tagStack.pop
+          // NOTE: we assume correct input XML, so no check on tag name correctness is done!
+          if (debug) {
+            println("< end: " + tagName)
+          }
+          outputWriter.add(event)
+        }
+        default:
+          // other events (such as control <? ?> are added)
+          outputWriter.add(event)
+      }
+    }
+    
+    outputWriter.close
+  }
+
+  def getStringObfuscator() {
+    stringObfuscator
+  }
+
+  protected def modifyData(String data, boolean obfuscate) {
+    if (obfuscate) {
+      data.obfuscateData
+    } else {
+      data.restoreData
+    }
+  }
+}
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/xml/XMLModelObfuscatorBuilder.xtend b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/xml/XMLModelObfuscatorBuilder.xtend
new file mode 100644
index 0000000..a6dd89c
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/xml/XMLModelObfuscatorBuilder.xtend
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.xml
+
+import java.io.InputStream
+import java.io.OutputStream
+import org.eclipse.viatra.modelobfuscator.util.ObfuscatorUtil
+import org.eclipse.viatra.modelobfuscator.util.StringObfuscator
+import com.google.common.base.Preconditions
+
+/**
+ * Builder API for setting up an XML obfuscator. Currently the only implementation that can
+ * be built is {@link XMLModelObfuscator}. the input for the obfuscator is an InputStream, while the output is 
+ * written into an OutputStream. The obfuscated attributes and content is configured by a {@link XMLSchemaConfiguration}. 
+ *  
+ * <p/>The builder allows setting a seed and a salt for the obfuscator, which is used when initializing
+ * the {@link StringObfuscator}, thus supporting reproducibility and restoration.
+ * 
+ * <p/>The default value of the seed is a random, 32 character long, hexadecimal string created by
+ * {@link ObfuscatorUtil#generateHexSeed}. The default value of the salt is empty.
+ * 
+ * @author Abel Hegedus
+ *
+ */
+class XMLModelObfuscatorBuilder {
+  
+  private InputStream inputStream
+  private OutputStream outputStream
+  private extension XMLSchemaConfiguration config
+  protected extension StringObfuscator stringObfuscator
+  private String saltString = ""
+  private String seedString = ObfuscatorUtil.generateHexSeed(32);
+  
+  /**
+   * Hiding constructor of builder
+   */
+  protected new() {
+  }
+  
+  /**
+   * Creates a new, unconfigured builder for XML model obfuscators.
+   */
+  def static create(){
+    new XMLModelObfuscatorBuilder
+  }
+  
+  /**
+   * Sets the input of the built obfuscator
+   */
+  def setInput(InputStream input){
+    inputStream = input
+    return this
+  }
+  
+  /**
+   * Sets the output of the built obfuscator
+   */
+  def setOutput(OutputStream output){
+    outputStream = output
+    return this
+  }
+  
+  /**
+   * Sets the configuration used for selecting what to obfuscate.
+   * See {@link XMLSchemaConfiguration} for details.
+   */
+  def setSchemaConfiguration(XMLSchemaConfiguration configuration){
+    this.config = configuration
+    return this
+  }
+  
+  /**
+   * Sets the salt used for obfuscating String values.
+   * See {@link StringObfuscator} for details.
+   */
+  def setSalt(String salt){
+    saltString = salt
+    return this
+  }
+  
+  /**
+   * Sets the seed used for obfuscating String values.
+   * See {@link StringObfuscator} for details.
+   */
+  def setSeed(String seed){
+    seedString = seed
+    return this
+  }
+  
+  /**
+   * Returns the {@link XMLModelObfuscator} instance built using the current configuration of the builder. 
+   */
+  def build(){
+    Preconditions.checkState(inputStream != null, "Input resource set cannot be null")
+    Preconditions.checkState(outputStream != null, "Output resource set cannot be null")
+    Preconditions.checkState(seedString != null, "Seed cannot be null")
+    Preconditions.checkState(saltString != null, "Salt cannot be null (empty string allowed)")
+    val obfuscator = new XMLModelObfuscator()
+    obfuscator.inputStream = inputStream
+    obfuscator.outputStream = outputStream
+    obfuscator.config = config
+    obfuscator.stringObfuscator = new StringObfuscator(seedString, saltString)
+    return obfuscator
+  }
+  
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/xml/XMLSchemaConfiguration.xtend b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/xml/XMLSchemaConfiguration.xtend
new file mode 100644
index 0000000..e0e84d9
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/src/org/eclipse/viatra/modelobfuscator/xml/XMLSchemaConfiguration.xtend
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.xml
+
+import com.google.common.base.Preconditions
+import com.google.common.collect.HashMultimap
+import com.google.common.collect.Multimap
+import java.util.Set
+
+/**
+ * Schema configuration is used to select which attributes and text content
+ * is obfuscated in an XML document.
+ * 
+ * <p/>Text content of tags in the obfuscateableTags set are obfuscated.
+ * <p/>Values of the specified attributes of specified tags in the obfuscateableAttributesOfTags
+ * multimap are obfiscated. 
+ * 
+ * @author Abel Hegedus
+ *
+ */
+class XMLSchemaConfiguration {
+  
+  private Multimap<String,String> obfuscateableAttributesOfTags
+  private Set<String> obfuscateableTagContents
+  
+  new(Multimap<String,String> tagAttributes, Set<String> tags){
+    obfuscateableAttributesOfTags = HashMultimap.create
+    obfuscateableAttributesOfTags.putAll(tagAttributes)
+    obfuscateableTagContents = newHashSet()
+    obfuscateableTagContents.addAll(tags)
+  }
+  
+  /**
+   * Collection of attributes that should be obfuscated in the given tag.
+   */
+  def getObfuscateableAttributeNames(String tagName){
+    Preconditions.checkArgument(tagName != null, "Tag name cannot be null!")
+    return obfuscateableAttributesOfTags.get(tagName)
+  }
+  
+  /**
+   * Returns true if the text content of the tag should be obfuscated.
+   */
+  def isTagContentObfuscateable(String tagName){
+    Preconditions.checkArgument(tagName != null, "Tag name cannot be null!")
+    return obfuscateableTagContents.contains(tagName)
+  }
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/api/.gitignore b/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/api/.gitignore
new file mode 100644
index 0000000..ea7b2b7
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/api/.gitignore
@@ -0,0 +1,4 @@
+/.DataTypeObfuscator.java._trace
+/.ModelObfuscator.java._trace
+/DataTypeObfuscator.java
+/ModelObfuscator.java
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/emf/simple/.gitignore b/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/emf/simple/.gitignore
new file mode 100644
index 0000000..3b698f3
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/emf/simple/.gitignore
@@ -0,0 +1,6 @@
+/.EMFModelObfuscatorBuilder.java._trace
+/.ResourceFilter.java._trace
+/.SimpleEMFModelObfuscator.java._trace
+/EMFModelObfuscatorBuilder.java
+/ResourceFilter.java
+/SimpleEMFModelObfuscator.java
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/util/.gitignore b/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/util/.gitignore
new file mode 100644
index 0000000..ade536c
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/util/.gitignore
@@ -0,0 +1,2 @@
+/.StringObfuscator.java._trace
+/StringObfuscator.java
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/xml/.gitignore b/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/xml/.gitignore
new file mode 100644
index 0000000..bde1def
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.runtime/xtend-gen/org/eclipse/viatra/modelobfuscator/xml/.gitignore
@@ -0,0 +1,6 @@
+/.XMLModelObfuscator.java._trace
+/.XMLModelObfuscatorBuilder.java._trace
+/.XMLSchemaConfiguration.java._trace
+/XMLModelObfuscator.java
+/XMLModelObfuscatorBuilder.java
+/XMLSchemaConfiguration.java
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.tests/.classpath b/plugins/org.eclipse.viatra.modelobfuscator.tests/.classpath
new file mode 100644
index 0000000..358df1b
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.tests/.classpath
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="xtend-gen"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.tests/.gitignore b/plugins/org.eclipse.viatra.modelobfuscator.tests/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.tests/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.tests/.project b/plugins/org.eclipse.viatra.modelobfuscator.tests/.project
new file mode 100644
index 0000000..495bc0f
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.tests/.project
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.viatra.modelobfuscator.tests</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.tests/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.viatra.modelobfuscator.tests/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..c537b63
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.tests/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.tests/META-INF/MANIFEST.MF b/plugins/org.eclipse.viatra.modelobfuscator.tests/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..2634174
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.tests/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: VIATRA Model Obfuscator Tests
+Bundle-SymbolicName: org.eclipse.viatra.modelobfuscator.tests
+Bundle-Version: 0.7.0.qualifier
+Bundle-Vendor: Eclipse VIATRA Project
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Require-Bundle: org.eclipse.viatra.modelobfuscator.runtime;bundle-version="0.7.0",
+ org.junit,
+ org.eclipse.xtend.lib,
+ com.google.guava,
+ org.eclipse.xtext.xbase.lib,
+ org.eclipse.emf.ecore,
+ org.eclipse.incquery.examples.bpm
+
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.tests/build.properties b/plugins/org.eclipse.viatra.modelobfuscator.tests/build.properties
new file mode 100644
index 0000000..d8e2f0e
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.tests/build.properties
@@ -0,0 +1,5 @@
+source.. = src/,\
+           xtend-gen/
+output.. = bin/
+bin.includes = META-INF/,\
+               .
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.tests/src/org/eclipse/viatra/modelobfuscator/tests/SimpleEMFModelObfuscatorTest.xtend b/plugins/org.eclipse.viatra.modelobfuscator.tests/src/org/eclipse/viatra/modelobfuscator/tests/SimpleEMFModelObfuscatorTest.xtend
new file mode 100644
index 0000000..f7cbcd3
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.tests/src/org/eclipse/viatra/modelobfuscator/tests/SimpleEMFModelObfuscatorTest.xtend
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.tests
+
+import org.eclipse.emf.common.util.URI
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl
+import org.eclipse.viatra.modelobfuscator.emf.simple.EMFModelObfuscatorBuilder
+import org.junit.Test
+import process.Process
+import process.ProcessFactory
+
+import static org.junit.Assert.*
+import org.eclipse.viatra.modelobfuscator.util.ObfuscatorUtil
+import org.junit.Ignore
+
+/**
+ * @author Abel Hegedus
+ *
+ */
+class SimpleEMFModelObfuscatorTest {
+
+  extension ProcessFactory processFactory = ProcessFactory.eINSTANCE
+
+  @Test
+  def void invokeObfuscatorNoSaltTest() {
+
+    println("Salt NOT used for obfuscation")
+
+    val rs = new ResourceSetImpl()
+    val r = rs.createResource(URI.createURI("dummy"))
+
+    val process = createProcess => [
+      name = "MyProcess"
+    ]
+    r.contents += process
+    val taskName = "T1"
+    val task1 = createTaskWithNameInProcess(taskName, process)
+    val task2 = createTaskWithNameInProcess(taskName, process)
+    createTaskWithNameInProcess("MyTask", process)
+    createTaskWithNameInProcess("MyOtherTask", process)
+    val taskWithEmptyName = createTaskWithNameInProcess("", process)
+    val taskWithNullName = createTaskWithNameInProcess(null, process)
+
+    printProcessModel(process)
+
+    val obfuscator = EMFModelObfuscatorBuilder.create.setInput(rs).build
+    println("Seed: " + obfuscator.stringObfuscator.seed)
+    obfuscator.obfuscate
+
+    printProcessModel(process)
+
+    assertFalse("Obfuscator did not change process name", process.name == "MyProcess")
+    assertTrue("Task names different", task1.name == task2.name)
+    assertTrue("Empty task name changed", taskWithEmptyName.name == "")
+    assertTrue("Null task name changed", taskWithNullName.name == null)
+
+    assertTrue("Restored process name incorrect", "MyProcess" == obfuscator.stringObfuscator.restoreData(process.name))
+
+  }
+
+  @Test
+  def void invokeObfuscatorWithSaltTest() {
+
+    println("Salt used for obfuscation")
+
+    val rs = new ResourceSetImpl()
+    val r = rs.createResource(URI.createURI("dummy"))
+
+    val process = createProcess => [
+      name = "MyProcess"
+    ]
+    r.contents += process
+    val taskName = "T1"
+    val task1 = createTaskWithNameInProcess(taskName, process)
+    val task2 = createTaskWithNameInProcess(taskName, process)
+    createTaskWithNameInProcess("MyTask", process)
+    createTaskWithNameInProcess("MyOtherTask", process)
+    val taskWithEmptyName = createTaskWithNameInProcess("", process)
+    val taskWithNullName = createTaskWithNameInProcess(null, process)
+
+    printProcessModel(process)
+
+    val obfuscator = EMFModelObfuscatorBuilder.create.setInput(rs).setSalt(ObfuscatorUtil.generateHexSeed(6)).build
+    println("Seed: " + obfuscator.stringObfuscator.seed)
+    println("Salt: " + obfuscator.stringObfuscator.salt)
+    obfuscator.obfuscate
+
+    printProcessModel(process)
+
+    assertFalse("Obfuscator did not change process name", process.name == "MyProcess")
+    assertTrue("Task names different", task1.name == task2.name)
+    assertFalse("Empty task name not changed", taskWithEmptyName.name == "")
+    assertTrue("Null task name changed", taskWithNullName.name == null)
+
+    assertTrue("Restored process name incorrect", "MyProcess" == obfuscator.stringObfuscator.restoreData(process.name))
+    assertTrue("Restored empty task name", obfuscator.stringObfuscator.restoreData(taskWithEmptyName.name) == "")
+  }
+  
+  @Test
+  def void invokeObfuscatorWithFilterTest() {
+
+    println("Filter used for obfuscation")
+
+    val rs = new ResourceSetImpl()
+    val r = rs.createResource(URI.createURI("dummy"))
+    val process = createProcess => [
+      name = "MyProcess"
+    ]
+    r.contents += process
+    val r2 = rs.createResource(URI.createURI("dummy2"))
+    val process2 = createProcess => [
+      name = "MyOtherProcess"
+    ]
+    r2.contents += process2
+
+    printProcessModel(process)
+    printProcessModel(process2)
+
+    // do not obfuscate second resource
+    val obfuscator = EMFModelObfuscatorBuilder.create.setInput(rs).setFilter[
+      it == r2
+    ].build
+    println("Seed: " + obfuscator.stringObfuscator.seed)
+    obfuscator.obfuscate
+
+    printProcessModel(process)
+    printProcessModel(process2)
+
+    assertFalse("Obfuscator did not change process name", process.name == "MyProcess")
+    assertTrue("Obfuscator changed process name", process2.name == "MyOtherProcess")
+
+  }
+
+  @Ignore
+  @Test
+  def void seedGeneratorTest() {
+    println(ObfuscatorUtil.generateHexSeed(6))
+    println(ObfuscatorUtil.generateHexSeed(6))
+    println(ObfuscatorUtil.generateHexSeed(6))
+    println(ObfuscatorUtil.generateHexSeed(6))
+    println(ObfuscatorUtil.generateHexSeed(6))
+    println(ObfuscatorUtil.generateHexSeed(6))
+    println(ObfuscatorUtil.generateHexSeed(6))
+    println(ObfuscatorUtil.generateHexSeed(10))
+    println(ObfuscatorUtil.generateHexSeed(16))
+    println(ObfuscatorUtil.generateHexSeed(21))
+    println(ObfuscatorUtil.generateHexSeed(32))
+    println(ObfuscatorUtil.generateHexSeed(36))
+    println(ObfuscatorUtil.generateHexSeed(10))
+    println(ObfuscatorUtil.generateHexSeed(16))
+    println(ObfuscatorUtil.generateHexSeed(21))
+    println(ObfuscatorUtil.generateHexSeed(32))
+    println(ObfuscatorUtil.generateHexSeed(36))
+  }
+
+  def printProcessModel(Process process) {
+    println(
+      '''
+        Model:
+          Process: «process.name»
+          Tasks:
+            «FOR t : process.contents»
+              Name: «t.name»«if(t.name == null) "[null]"»
+            «ENDFOR»
+      ''')
+  }
+
+  def createTaskWithNameInProcess(String taskName, Process process) {
+    val task2 = createTask => [
+      name = taskName
+    ]
+    process.contents += task2
+    task2
+  }
+
+}
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.tests/src/org/eclipse/viatra/modelobfuscator/tests/XMLModelObfuscatorTest.xtend b/plugins/org.eclipse.viatra.modelobfuscator.tests/src/org/eclipse/viatra/modelobfuscator/tests/XMLModelObfuscatorTest.xtend
new file mode 100644
index 0000000..61edb89
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.tests/src/org/eclipse/viatra/modelobfuscator/tests/XMLModelObfuscatorTest.xtend
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.tests
+
+import com.google.common.collect.HashMultimap
+import java.io.BufferedOutputStream
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import org.eclipse.viatra.modelobfuscator.xml.XMLModelObfuscatorBuilder
+import org.eclipse.viatra.modelobfuscator.xml.XMLSchemaConfiguration
+import org.junit.Test
+
+/**
+ * @author Abel Hegedus
+ *
+ */
+class XMLModelObfuscatorTest {
+  
+  @Test
+  def void invokeObfuscatorTest() {
+    
+    val input = '''
+      <process name="MyProcess">
+        <task id="T1">
+          <someTag>Test</someTag>
+        </task>
+        <task id="MyTask" somaAttr="myAttrValue">
+          <someTag>tst</someTag>
+          <otherTag>1</otherTag>
+        </task>
+        someContent
+        <task id="T1" otherAttr="2">
+          <someTag>ts2</someTag>
+          <someTag>ts3</someTag>
+        </task>
+      </process>
+    '''
+    val inputStream = new ByteArrayInputStream(input.bytes)
+    val outputBytes = new ByteArrayOutputStream()
+    val outputStream = new BufferedOutputStream(outputBytes)
+    val attributeMultimap = HashMultimap.create => [
+      put("process", "name")
+      put("task","id")
+      put("task","someAttr")
+    ]
+    val config = new XMLSchemaConfiguration(attributeMultimap, #{"someTag"})
+    
+    val obfuscator = XMLModelObfuscatorBuilder.create.setInput(inputStream).setOutput(outputStream).setSchemaConfiguration(config).build
+    obfuscator.obfuscate
+    
+    println(outputBytes)
+  }
+  
+  @Test
+  def void xmiObfuscationTest(){
+    val input = '''
+      <?xml version="1.0" encoding="UTF-8"?>
+      <root>
+        <process:Process xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:process="http://process/1.0" id="rootProcess" name="Root">
+          <contents xsi:type="process:Task" id="st2" name="Other Service Task" kind="service"/>
+          <contents xsi:type="process:Task" id="st1" name="First Service Task" kind="service"/>
+        </process:Process>
+        <system:System xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:system="http://system/1.0" name="Simple">
+          <contains name="Job1" runsOn="/">
+            <taskIds>st1</taskIds>
+          </contains>
+          <contains name="Job2" runsOn="/">
+            <taskIds>st2</taskIds>
+          </contains>
+          <data name="Data">
+            <readingTaskIds>st1</readingTaskIds>
+            <writingTaskIds>st2</writingTaskIds>
+          </data>
+        </system:System>
+        <operation:Checklist xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:operation="http://operation/1.0" id="chl1" name="First Checklist" processId="rootProcess">
+          <entries id="cle1" name="First CLE" taskId="st1">
+            <info id="" name="Info1"/>
+            <jobPaths>Simple/Job1</jobPaths>
+          </entries>
+        </operation:Checklist>
+      </root>
+    '''
+    
+    val inputStream = new ByteArrayInputStream(input.bytes)
+    val outputBytes = new ByteArrayOutputStream()
+    val outputStream = new BufferedOutputStream(outputBytes)
+    val attributeMultimap = HashMultimap.create => [
+      // process
+      putAll("Process", #{"id","name"})
+      putAll("contents",#{"id","name"})
+      // system
+      put("System","name")
+      put("contains","name")
+      put("data","name")
+      // operation
+      putAll("Checklist",#{"id","name","processId"})
+      putAll("entries",#{"id","name","taskId"})
+      putAll("info",#{"id","name"})
+    ]
+    val config = new XMLSchemaConfiguration(attributeMultimap, #{"taskIds","readingTaskIds","writingTaskIds","jobPaths"})
+    
+    // TODO jobPaths includes "/" which must be kept!
+    
+    val obfuscator = XMLModelObfuscatorBuilder.create.setInput(inputStream).setOutput(outputStream).setSchemaConfiguration(config).build
+    obfuscator.obfuscate
+    
+    println(outputBytes)
+  }
+  
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.tests/xtend-gen/org/eclipse/viatra/modelobfuscator/tests/.gitignore b/plugins/org.eclipse.viatra.modelobfuscator.tests/xtend-gen/org/eclipse/viatra/modelobfuscator/tests/.gitignore
new file mode 100644
index 0000000..f822ea9
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.tests/xtend-gen/org/eclipse/viatra/modelobfuscator/tests/.gitignore
@@ -0,0 +1,4 @@
+/.SimpleEMFModelObfuscatorTest.java._trace
+/.XMLModelObfuscatorTest.java._trace
+/SimpleEMFModelObfuscatorTest.java
+/XMLModelObfuscatorTest.java
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.ui/.classpath b/plugins/org.eclipse.viatra.modelobfuscator.ui/.classpath
new file mode 100644
index 0000000..ad32c83
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.ui/.classpath
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
+	<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
+	<classpathentry kind="src" path="src"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.ui/.gitignore b/plugins/org.eclipse.viatra.modelobfuscator.ui/.gitignore
new file mode 100644
index 0000000..ae3c172
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.ui/.gitignore
@@ -0,0 +1 @@
+/bin/
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.ui/.project b/plugins/org.eclipse.viatra.modelobfuscator.ui/.project
new file mode 100644
index 0000000..74a49b7
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.ui/.project
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.viatra.modelobfuscator.ui</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.ManifestBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.pde.SchemaBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.pde.PluginNature</nature>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.ui/.settings/org.eclipse.jdt.core.prefs b/plugins/org.eclipse.viatra.modelobfuscator.ui/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..c537b63
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.ui/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.6
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.ui/META-INF/MANIFEST.MF b/plugins/org.eclipse.viatra.modelobfuscator.ui/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..1797603
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.ui/META-INF/MANIFEST.MF
@@ -0,0 +1,15 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: EMF-IncQuery Model Obfuscator UI
+Bundle-SymbolicName: org.eclipse.viatra.modelobfuscator.ui;singleton:=true
+Bundle-Version: 0.7.0.qualifier
+Bundle-Activator: org.eclipse.viatra.modelobfuscator.ui.ModelObfuscatorUIPlugin
+Bundle-Vendor: Eclipse VIATRA Project
+Require-Bundle: org.eclipse.ui,
+ org.eclipse.core.runtime,
+ org.eclipse.viatra.modelobfuscator.runtime;bundle-version="0.7.0",
+ org.eclipse.emf.ecore,
+ org.eclipse.emf.edit,
+ org.eclipse.emf.transaction
+Bundle-RequiredExecutionEnvironment: JavaSE-1.6
+Bundle-ActivationPolicy: lazy
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.ui/build.properties b/plugins/org.eclipse.viatra.modelobfuscator.ui/build.properties
new file mode 100644
index 0000000..e9863e2
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.ui/build.properties
@@ -0,0 +1,5 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+               .,\
+               plugin.xml
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.ui/plugin.xml b/plugins/org.eclipse.viatra.modelobfuscator.ui/plugin.xml
new file mode 100644
index 0000000..491b17e
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.ui/plugin.xml
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<?eclipse version="3.4"?>
+<plugin>
+  <extension
+         point="org.eclipse.ui.commands">
+      <command
+            id="org.eclipse.viatra.modelobfuscator.ui.obfuscateModel"
+            name="Obfuscate model loaded into Editor">
+      </command>
+  </extension>
+  <extension
+         point="org.eclipse.ui.handlers">
+      <handler
+            class="org.eclipse.viatra.modelobfuscator.ui.handlers.EMFModelObfuscatorHandler"
+            commandId="org.eclipse.viatra.modelobfuscator.ui.obfuscateModel">
+      </handler>
+   </extension>
+   <extension
+         point="org.eclipse.ui.menus">
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:org.eclipse.ui.popup.any">
+         <command
+               commandId="org.eclipse.viatra.modelobfuscator.ui.obfuscateModel"
+               style="push">
+            <visibleWhen
+                  checkEnabled="false">
+               <with
+                     variable="activePartId">
+                  <equals
+                        value="org.eclipse.emf.ecore.presentation.XMLReflectiveEditorID">
+                  </equals>
+               </with>
+            </visibleWhen>
+         </command>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:org.eclipse.ui.popup.any">
+         <command
+               commandId="org.eclipse.viatra.modelobfuscator.ui.obfuscateModel"
+               style="push">
+            <visibleWhen
+                  checkEnabled="false">
+               <with
+                     variable="activePartId">
+                  <equals
+                        value="org.eclipse.emf.ecore.presentation.ReflectiveEditorID">
+                  </equals>
+               </with>
+            </visibleWhen>
+         </command>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:org.eclipse.ui.popup.any">
+         <command
+               commandId="org.eclipse.viatra.modelobfuscator.ui.obfuscateModel"
+               style="push">
+            <visibleWhen
+                  checkEnabled="false">
+               <with
+                     variable="activePartId">
+                  <equals
+                        value="org.eclipse.emf.genericEditor">
+                  </equals>
+               </with>
+            </visibleWhen>
+         </command>
+      </menuContribution>
+   </extension>
+   <extension
+         point="org.eclipse.core.expressions.definitions">
+      <definition
+            id="org.eclipse.viatra.modelobfuscator.ui.notifierdef">
+         <with
+               variable="selection">
+            <iterate
+                  ifEmpty="false"
+                  operator="or">
+               <instanceof
+                     value="org.eclipse.emf.common.notify.Notifier">
+               </instanceof>
+            </iterate>
+         </with>
+      </definition>
+   </extension>
+</plugin>
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.ui/src/org/eclipse/viatra/modelobfuscator/ui/ModelObfuscatorUIPlugin.java b/plugins/org.eclipse.viatra.modelobfuscator.ui/src/org/eclipse/viatra/modelobfuscator/ui/ModelObfuscatorUIPlugin.java
new file mode 100644
index 0000000..a713c07
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.ui/src/org/eclipse/viatra/modelobfuscator/ui/ModelObfuscatorUIPlugin.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.ui;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ * 
+ * @author Abel Hegedus
+ */
+public class ModelObfuscatorUIPlugin extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.viatra.modelobfuscator.ui"; //$NON-NLS-1$
+
+	// The shared instance
+	private static ModelObfuscatorUIPlugin plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public ModelObfuscatorUIPlugin() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static ModelObfuscatorUIPlugin getDefault() {
+		return plugin;
+	}
+
+}
diff --git a/plugins/org.eclipse.viatra.modelobfuscator.ui/src/org/eclipse/viatra/modelobfuscator/ui/handlers/EMFModelObfuscatorHandler.java b/plugins/org.eclipse.viatra.modelobfuscator.ui/src/org/eclipse/viatra/modelobfuscator/ui/handlers/EMFModelObfuscatorHandler.java
new file mode 100644
index 0000000..a82ca54
--- /dev/null
+++ b/plugins/org.eclipse.viatra.modelobfuscator.ui/src/org/eclipse/viatra/modelobfuscator/ui/handlers/EMFModelObfuscatorHandler.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2010-2014, Abel Hegedus, Istvan Rath and Daniel Varro
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *   Abel Hegedus - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.viatra.modelobfuscator.ui.handlers;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.ILog;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.command.AbstractCommand;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.edit.domain.EditingDomain;
+import org.eclipse.emf.edit.domain.IEditingDomainProvider;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.ui.IEditorPart;
+import org.eclipse.ui.handlers.HandlerUtil;
+import org.eclipse.viatra.modelobfuscator.emf.simple.EMFModelObfuscatorBuilder;
+import org.eclipse.viatra.modelobfuscator.emf.simple.ResourceFilter;
+import org.eclipse.viatra.modelobfuscator.emf.simple.SimpleEMFModelObfuscator;
+import org.eclipse.viatra.modelobfuscator.ui.ModelObfuscatorUIPlugin;
+
+/**
+ * This command handler executes the model obfuscator in a way that only writable resources are modified in the resource
+ * set of the editing domain provided by the editor.
+ * 
+ * <p/>The seed used for the obfuscator is displayed in a confirmation dialog and logged to the Eclips logger with Info
+ * level.
+ * 
+ * <p/>The obfuscation is performed with a {@link SimpleEMFModelObfuscator} in an EMF command, therefore it supports undo/redo and correctly notifies the editor to
+ * show a dirty state.
+ * 
+ * @author Abel Hegedus
+ *
+ */
+public class EMFModelObfuscatorHandler extends AbstractHandler {
+
+    @Override
+    public Object execute(ExecutionEvent event) throws ExecutionException {
+        IEditorPart editorPart = HandlerUtil.getActiveEditor(event);
+        ResourceSet resourceSet = null;
+        if (editorPart instanceof IEditingDomainProvider) {
+            IEditingDomainProvider editingDomainProvider = (IEditingDomainProvider) editorPart;
+            final EditingDomain editingDomain = editingDomainProvider.getEditingDomain();
+            resourceSet = editingDomain.getResourceSet();
+            if (resourceSet != null) {
+                ILog logger = ModelObfuscatorUIPlugin.getDefault().getLog();
+                final SimpleEMFModelObfuscator obfuscator = EMFModelObfuscatorBuilder.create().setInput(resourceSet)
+                        .setFilter(new ResourceFilter() {
+                            @Override
+                            public boolean avoidObfuscation(Resource resource) {
+                                return editingDomain.isReadOnly(resource);
+                            }
+                        }).build();
+                String seed = obfuscator.getStringObfuscator().getSeed();
+
+                boolean confirmed = MessageDialog
+                        .openConfirm(
+                                HandlerUtil.getActiveShell(event),
+                                "Model obfuscation",
+                                "This tool replaces all string attribute values with obfuscated values.\n"
+                                        + " You can Undo the operation or restore the original values with this seed:\n"
+                                        + seed + "\n(logged also as an Info level event)"
+                                        + "Do you want to perform model obuscation?");
+                if (confirmed) {
+                    logger.log(new Status(Status.INFO, ModelObfuscatorUIPlugin.PLUGIN_ID, "Obfuscating with seed: "
+                            + seed));
+                    AbstractCommand obfuscationCommand = new AbstractCommand("Obfuscate model") {
+
+                        @Override
+                        public void redo() {
+                            // obfuscation with the same seed is deterministic
+                            obfuscator.obfuscate();
+                        }
+
+                        @Override
+                        public void undo() {
+                            obfuscator.restore();
+                        }
+
+                        @Override
+                        public void execute() {
+                            obfuscator.obfuscate();
+                        }
+
+                        @Override
+                        protected boolean prepare() {
+                            super.prepare();
+                            return true;
+                        }
+                    };
+                    editingDomain.getCommandStack().execute(obfuscationCommand);
+                }
+            }
+        }
+        return null;
+    }
+
+}