Bug 497541: C++ generator should offer a possibility to derive from
generated actor classes

Change-Id: Iee8df84fbc06efe0792e8ed554cbf1fe1e5f54fa
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend
index 6ecaca3..97db7df 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend
@@ -371,5 +371,10 @@
 		else
 			type.getName()
 	}
+	
+	override makeOverridable() {
+		// not possible for C: empty string
+		""
+	}
 
 }
diff --git a/plugins/org.eclipse.etrice.generator.c/xtend-gen/org/eclipse/etrice/generator/c/gen/CExtensions.java b/plugins/org.eclipse.etrice.generator.c/xtend-gen/org/eclipse/etrice/generator/c/gen/CExtensions.java
index f4f5b48..926720d 100644
--- a/plugins/org.eclipse.etrice.generator.c/xtend-gen/org/eclipse/etrice/generator/c/gen/CExtensions.java
+++ b/plugins/org.eclipse.etrice.generator.c/xtend-gen/org/eclipse/etrice/generator/c/gen/CExtensions.java
@@ -812,4 +812,8 @@
     }
     return _xifexpression;
   }
+  
+  public String makeOverridable() {
+    return "";
+  }
 }
diff --git a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/ActorClassGen.xtend b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/ActorClassGen.xtend
index b3fd192..8f0392e 100644
--- a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/ActorClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/ActorClassGen.xtend
@@ -215,7 +215,7 @@
 		#include <string>
 
 		«FOR ar : ac.actorRefs»
-			#include "«ar.type.path»«ar.type.name».h"
+			#include "«ar.type.actorIncludePath»"
 		«ENDFOR»
 
 		using namespace etRuntime;
@@ -239,13 +239,13 @@
 						«IF Main::settings.generateMSCInstrumentation»
 							DebuggingService::getInstance().addMessageActorCreate(*this, "«sub.name»«GenmodelConstants::INDEX_SEP»"+i);
 						«ENDIF»
-						new «sub.type.name»(this, "«sub.name»«GenmodelConstants::INDEX_SEP»"+i);
+						new «sub.type.implementationClassName»(this, "«sub.name»«GenmodelConstants::INDEX_SEP»"+i);
 					}
 				«ELSE»
 					«IF Main::settings.generateMSCInstrumentation»
 						DebuggingService::getInstance().addMessageActorCreate(*this, "«sub.name»");
 					«ENDIF»
-					new «sub.type.name»(this, "«sub.name»");
+					new «sub.type.implementationClassName»(this, "«sub.name»");
 				«ENDIF»
 			«ENDFOR»
 
@@ -300,6 +300,4 @@
 		«ENDIF»
 		'''
 	}
-
-
 }
diff --git a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/CppExtensions.xtend b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/CppExtensions.xtend
index aae8976..3e6ac48 100644
--- a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/CppExtensions.xtend
+++ b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/CppExtensions.xtend
@@ -37,13 +37,17 @@
 import org.eclipse.etrice.generator.generic.ILanguageExtension
 import org.eclipse.etrice.generator.generic.TypeHelpers
 import org.eclipse.xtext.util.Pair
+import org.eclipse.etrice.core.room.ActorClass
+import org.eclipse.etrice.core.room.util.RoomHelpers
+import org.eclipse.etrice.generator.generic.RoomExtensions
 
 @Singleton
 class CppExtensions implements ILanguageExtension {
 
 	@Inject IDiagnostician diagnostician
 	@Inject extension TypeHelpers
-
+	@Inject extension RoomHelpers
+	@Inject extension RoomExtensions
 
 	override String getTypedDataDefinition(EObject msg) {
 		generateArglistAndTypedData((msg as Message).data).get(1)
@@ -270,5 +274,44 @@
 		else
 			type.getName()
 	}
+	
+	override makeOverridable() {
+		"virtual "
+	}
+
+	/**
+	 * check if there is an ImplementationSubclass annotation and return its fully qualified name or the actor class name
+	 */
+	def getImplementationClassName(ActorClass ac) {
+	    val attributes = ac.getAttributes("ImplementationSubclass")
+	    if (attributes.empty) {
+	        ac.name
+	    }
+	    else {
+	        attributes.filter[it.key=="fqnClassName"].head.value.literalToString
+	    }
+	}
+
+	/**
+	 * check if there is an ImplementationSubclass annotation. If it also has an includePath use it.
+	 * If there is not includePath, use the class name as base file name.
+	 * If there is no annotation use the default path.
+	 */
+	def getActorIncludePath(ActorClass ac) {
+	    val attributes = ac.getAttributes("ImplementationSubclass")
+	    if (attributes.empty) {
+		    ac.path+ac.name+".h"
+	    }
+	    else {
+	        val path = attributes.filter[it.key=="includePath"]
+	        if (path.empty) {
+		        val baseName = attributes.filter[it.key=="fqnClassName"].head.value.literalToString.split("::").last
+			    baseName+".h"
+	        }
+	        else {
+	            path.head.value.literalToString
+	        }
+	    }
+	}
 
 }
diff --git a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/DataClassGen.xtend b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/DataClassGen.xtend
index ad78108..0a221a8 100644
--- a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/DataClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/DataClassGen.xtend
@@ -20,10 +20,10 @@
 import org.eclipse.etrice.core.room.Attribute
 import org.eclipse.etrice.core.room.ComplexType
 import org.eclipse.etrice.core.room.DataClass
-import org.eclipse.etrice.core.room.util.RoomHelpers
+//import org.eclipse.etrice.core.room.util.RoomHelpers
 import org.eclipse.etrice.generator.generic.ProcedureHelpers
 import org.eclipse.etrice.generator.generic.RoomExtensions
-import org.eclipse.etrice.generator.generic.TypeHelpers
+//import org.eclipse.etrice.generator.generic.TypeHelpers
 import org.eclipse.xtext.generator.JavaIoFileSystemAccess
 
 @Singleton
@@ -33,9 +33,9 @@
 	@Inject extension CppExtensions stdExt
 	@Inject extension RoomExtensions roomExt
 	@Inject extension ProcedureHelpers helpers
-	@Inject extension TypeHelpers typeHelpers
+//	@Inject extension TypeHelpers typeHelpers
 	@Inject extension Initialization
-	@Inject extension RoomHelpers
+//	@Inject extension RoomHelpers
 	@Inject ILogger logger
 
 	def doGenerate(Root root) {
diff --git a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/NodeGen.xtend b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/NodeGen.xtend
index 4304070..aaa4aae 100644
--- a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/NodeGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/NodeGen.xtend
@@ -155,7 +155,7 @@
 		#include "common/modelbase/InterfaceItemBase.h"
 
 		«FOR ai : comp.actorInstances»
-			#include "«ai.actorClass.path»«ai.actorClass.name».h"
+			#include "«ai.actorClass.actorIncludePath»"
 		«ENDFOR»
 		#include <iostream>
 
@@ -209,13 +209,13 @@
 						«IF Main::settings.generateMSCInstrumentation»
 							DebuggingService::getInstance().addMessageActorCreate(*this, "«sub.name»«GenmodelConstants::INDEX_SEP»"+i);
 						«ENDIF»
-						new «sub.type.name»(this, "«sub.name»«GenmodelConstants::INDEX_SEP»"+i);
+						new «sub.type.implementationClassName»(this, "«sub.name»«GenmodelConstants::INDEX_SEP»"+i);
 					}
 				«ELSE»
 					«IF Main::settings.generateMSCInstrumentation»
 						DebuggingService::getInstance().addMessageActorCreate(*this, "«sub.name»");
 					«ENDIF»
-					new «sub.type.name»(this, "«sub.name»");
+					new «sub.type.implementationClassName»(this, "«sub.name»");
 				«ENDIF»
 			«ENDFOR»
 
diff --git a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/StateMachineGen.xtend b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/StateMachineGen.xtend
index de45d9c..3e1c142 100644
--- a/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/StateMachineGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.cpp/src/org/eclipse/etrice/generator/cpp/gen/StateMachineGen.xtend
@@ -16,13 +16,11 @@
 import com.google.inject.Inject
 import com.google.inject.Singleton
 import org.eclipse.etrice.core.genmodel.fsm.fsmgen.ExpandedModelComponent
+import org.eclipse.etrice.generator.cpp.Main
 import org.eclipse.etrice.generator.generic.GenericStateMachineGenerator
 import org.eclipse.etrice.generator.generic.RoomExtensions
-import org.eclipse.etrice.generator.cpp.Main
-import org.eclipse.etrice.core.room.ActorClass
 
-
- @Singleton
+@Singleton
 class StateMachineGen extends GenericStateMachineGenerator {
 
 	@Inject extension RoomExtensions
diff --git a/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/ActorClassGen.java b/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/ActorClassGen.java
index c99a04f..2cbdd27 100644
--- a/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/ActorClassGen.java
+++ b/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/ActorClassGen.java
@@ -625,12 +625,9 @@
         for(final ActorRef ar : _actorRefs) {
           _builder.append("#include \"");
           ActorClass _type = ar.getType();
-          String _path = this._roomExtensions.getPath(_type);
-          _builder.append(_path, "");
-          ActorClass _type_1 = ar.getType();
-          String _name_3 = _type_1.getName();
-          _builder.append(_name_3, "");
-          _builder.append(".h\"");
+          String _actorIncludePath = this._cppExtensions.getActorIncludePath(_type);
+          _builder.append(_actorIncludePath, "");
+          _builder.append("\"");
           _builder.newLineIfNotEmpty();
         }
       }
@@ -667,8 +664,8 @@
       }
       _builder.append("\t");
       _builder.append("setClassName(\"");
-      String _name_4 = ac.getName();
-      _builder.append(_name_4, "\t");
+      String _name_3 = ac.getName();
+      _builder.append(_name_3, "\t");
       _builder.append("\");");
       _builder.newLineIfNotEmpty();
       _builder.append("\t");
@@ -700,8 +697,8 @@
                   _builder.append("\t");
                   _builder.append("\t");
                   _builder.append("DebuggingService::getInstance().addMessageActorCreate(*this, \"");
-                  String _name_5 = sub.getName();
-                  _builder.append(_name_5, "\t\t");
+                  String _name_4 = sub.getName();
+                  _builder.append(_name_4, "\t\t");
                   _builder.append(GenmodelConstants.INDEX_SEP, "\t\t");
                   _builder.append("\"+i);");
                   _builder.newLineIfNotEmpty();
@@ -710,12 +707,12 @@
               _builder.append("\t");
               _builder.append("\t");
               _builder.append("new ");
-              ActorClass _type_2 = sub.getType();
-              String _name_6 = _type_2.getName();
-              _builder.append(_name_6, "\t\t");
+              ActorClass _type_1 = sub.getType();
+              String _implementationClassName = this._cppExtensions.getImplementationClassName(_type_1);
+              _builder.append(_implementationClassName, "\t\t");
               _builder.append("(this, \"");
-              String _name_7 = sub.getName();
-              _builder.append(_name_7, "\t\t");
+              String _name_5 = sub.getName();
+              _builder.append(_name_5, "\t\t");
               _builder.append(GenmodelConstants.INDEX_SEP, "\t\t");
               _builder.append("\"+i);");
               _builder.newLineIfNotEmpty();
@@ -729,20 +726,20 @@
                 if (_isGenerateMSCInstrumentation_1) {
                   _builder.append("\t");
                   _builder.append("DebuggingService::getInstance().addMessageActorCreate(*this, \"");
-                  String _name_8 = sub.getName();
-                  _builder.append(_name_8, "\t");
+                  String _name_6 = sub.getName();
+                  _builder.append(_name_6, "\t");
                   _builder.append("\");");
                   _builder.newLineIfNotEmpty();
                 }
               }
               _builder.append("\t");
               _builder.append("new ");
-              ActorClass _type_3 = sub.getType();
-              String _name_9 = _type_3.getName();
-              _builder.append(_name_9, "\t");
+              ActorClass _type_2 = sub.getType();
+              String _implementationClassName_1 = this._cppExtensions.getImplementationClassName(_type_2);
+              _builder.append(_implementationClassName_1, "\t");
               _builder.append("(this, \"");
-              String _name_10 = sub.getName();
-              _builder.append(_name_10, "\t");
+              String _name_7 = sub.getName();
+              _builder.append(_name_7, "\t");
               _builder.append("\");");
               _builder.newLineIfNotEmpty();
             }
@@ -807,8 +804,8 @@
       _builder.newLine();
       _builder.newLine();
       _builder.append("void ");
-      String _name_11 = ac.getName();
-      _builder.append(_name_11, "");
+      String _name_8 = ac.getName();
+      _builder.append(_name_8, "");
       _builder.append("::destroy(){");
       _builder.newLineIfNotEmpty();
       _builder.append("\t");
@@ -849,8 +846,8 @@
       _builder.newLine();
       _builder.newLine();
       EList<StandardOperation> _operations = ac.getOperations();
-      String _name_12 = ac.getName();
-      CharSequence _operationsImplementation = this._procedureHelpers.operationsImplementation(_operations, _name_12);
+      String _name_9 = ac.getName();
+      CharSequence _operationsImplementation = this._procedureHelpers.operationsImplementation(_operations, _name_9);
       _builder.append(_operationsImplementation, "");
       _builder.newLineIfNotEmpty();
       _builder.newLine();
@@ -865,8 +862,8 @@
             boolean _equals_4 = Objects.equal(_commType_4, ComponentCommunicationType.DATA_DRIVEN);
             if (_equals_4) {
               _builder.append("void ");
-              String _name_13 = ac.getName();
-              _builder.append(_name_13, "");
+              String _name_10 = ac.getName();
+              _builder.append(_name_10, "");
               _builder.append("::receiveEvent(InterfaceItemBase* ifitem, int evt, void* generic_data) {");
               _builder.newLineIfNotEmpty();
               _builder.append("\t");
@@ -889,8 +886,8 @@
             }
             if (_or_2) {
               _builder.append("void ");
-              String _name_14 = ac.getName();
-              _builder.append(_name_14, "");
+              String _name_11 = ac.getName();
+              _builder.append(_name_11, "");
               _builder.append("::receive(const Message* msg) {");
               _builder.newLineIfNotEmpty();
               {
@@ -917,8 +914,8 @@
             _builder.append("//--------------------- no state machine");
             _builder.newLine();
             _builder.append("void ");
-            String _name_15 = ac.getName();
-            _builder.append(_name_15, "");
+            String _name_12 = ac.getName();
+            _builder.append(_name_12, "");
             _builder.append("::receiveEvent(InterfaceItemBase* ifitem, int evt, void* data) {");
             _builder.newLineIfNotEmpty();
             _builder.append("\t");
diff --git a/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/CppExtensions.java b/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/CppExtensions.java
index d21aaf2..4950a59 100644
--- a/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/CppExtensions.java
+++ b/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/CppExtensions.java
@@ -18,9 +18,12 @@
 import org.eclipse.emf.common.util.EList;
 import org.eclipse.emf.ecore.EObject;
 import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.etrice.core.common.base.KeyValue;
+import org.eclipse.etrice.core.common.base.Literal;
 import org.eclipse.etrice.core.etphys.eTPhys.NodeRef;
 import org.eclipse.etrice.core.genmodel.etricegen.SubSystemInstance;
 import org.eclipse.etrice.core.genmodel.fsm.fsmgen.IDiagnostician;
+import org.eclipse.etrice.core.room.ActorClass;
 import org.eclipse.etrice.core.room.Attribute;
 import org.eclipse.etrice.core.room.DataClass;
 import org.eclipse.etrice.core.room.DataType;
@@ -32,13 +35,17 @@
 import org.eclipse.etrice.core.room.RefableType;
 import org.eclipse.etrice.core.room.RoomClass;
 import org.eclipse.etrice.core.room.VarDecl;
+import org.eclipse.etrice.core.room.util.RoomHelpers;
 import org.eclipse.etrice.generator.generic.ILanguageExtension;
+import org.eclipse.etrice.generator.generic.RoomExtensions;
 import org.eclipse.etrice.generator.generic.TypeHelpers;
 import org.eclipse.xtend2.lib.StringConcatenation;
 import org.eclipse.xtext.util.Pair;
 import org.eclipse.xtext.xbase.lib.CollectionLiterals;
 import org.eclipse.xtext.xbase.lib.Conversions;
 import org.eclipse.xtext.xbase.lib.Extension;
+import org.eclipse.xtext.xbase.lib.Functions.Function1;
+import org.eclipse.xtext.xbase.lib.IterableExtensions;
 
 @Singleton
 @SuppressWarnings("all")
@@ -50,6 +57,14 @@
   @Extension
   private TypeHelpers _typeHelpers;
   
+  @Inject
+  @Extension
+  private RoomHelpers _roomHelpers;
+  
+  @Inject
+  @Extension
+  private RoomExtensions _roomExtensions;
+  
   public String getTypedDataDefinition(final EObject msg) {
     VarDecl _data = ((Message) msg).getData();
     String[] _generateArglistAndTypedData = this.generateArglistAndTypedData(_data);
@@ -513,4 +528,96 @@
     }
     return _xifexpression;
   }
+  
+  public String makeOverridable() {
+    return "virtual ";
+  }
+  
+  /**
+   * check if there is an ImplementationSubclass annotation and return its fully qualified name or the actor class name
+   */
+  public String getImplementationClassName(final ActorClass ac) {
+    String _xblockexpression = null;
+    {
+      final List<KeyValue> attributes = this._roomHelpers.getAttributes(ac, "ImplementationSubclass");
+      String _xifexpression = null;
+      boolean _isEmpty = attributes.isEmpty();
+      if (_isEmpty) {
+        _xifexpression = ac.getName();
+      } else {
+        final Function1<KeyValue, Boolean> _function = new Function1<KeyValue, Boolean>() {
+          public Boolean apply(final KeyValue it) {
+            String _key = it.getKey();
+            return Boolean.valueOf(Objects.equal(_key, "fqnClassName"));
+          }
+        };
+        Iterable<KeyValue> _filter = IterableExtensions.<KeyValue>filter(attributes, _function);
+        KeyValue _head = IterableExtensions.<KeyValue>head(_filter);
+        Literal _value = _head.getValue();
+        _xifexpression = this._roomHelpers.literalToString(_value);
+      }
+      _xblockexpression = _xifexpression;
+    }
+    return _xblockexpression;
+  }
+  
+  /**
+   * check if there is an ImplementationSubclass annotation. If it also has an includePath use it.
+   * If there is not includePath, use the class name as base file name.
+   * If there is no annotation use the default path.
+   */
+  public String getActorIncludePath(final ActorClass ac) {
+    String _xblockexpression = null;
+    {
+      final List<KeyValue> attributes = this._roomHelpers.getAttributes(ac, "ImplementationSubclass");
+      String _xifexpression = null;
+      boolean _isEmpty = attributes.isEmpty();
+      if (_isEmpty) {
+        String _path = this._roomExtensions.getPath(ac);
+        String _name = ac.getName();
+        String _plus = (_path + _name);
+        _xifexpression = (_plus + ".h");
+      } else {
+        String _xblockexpression_1 = null;
+        {
+          final Function1<KeyValue, Boolean> _function = new Function1<KeyValue, Boolean>() {
+            public Boolean apply(final KeyValue it) {
+              String _key = it.getKey();
+              return Boolean.valueOf(Objects.equal(_key, "includePath"));
+            }
+          };
+          final Iterable<KeyValue> path = IterableExtensions.<KeyValue>filter(attributes, _function);
+          String _xifexpression_1 = null;
+          boolean _isEmpty_1 = IterableExtensions.isEmpty(path);
+          if (_isEmpty_1) {
+            String _xblockexpression_2 = null;
+            {
+              final Function1<KeyValue, Boolean> _function_1 = new Function1<KeyValue, Boolean>() {
+                public Boolean apply(final KeyValue it) {
+                  String _key = it.getKey();
+                  return Boolean.valueOf(Objects.equal(_key, "fqnClassName"));
+                }
+              };
+              Iterable<KeyValue> _filter = IterableExtensions.<KeyValue>filter(attributes, _function_1);
+              KeyValue _head = IterableExtensions.<KeyValue>head(_filter);
+              Literal _value = _head.getValue();
+              String _literalToString = this._roomHelpers.literalToString(_value);
+              String[] _split = _literalToString.split("::");
+              final String baseName = IterableExtensions.<String>last(((Iterable<String>)Conversions.doWrapArray(_split)));
+              _xblockexpression_2 = (baseName + ".h");
+            }
+            _xifexpression_1 = _xblockexpression_2;
+          } else {
+            KeyValue _head = IterableExtensions.<KeyValue>head(path);
+            Literal _value = _head.getValue();
+            _xifexpression_1 = this._roomHelpers.literalToString(_value);
+          }
+          _xblockexpression_1 = _xifexpression_1;
+        }
+        _xifexpression = _xblockexpression_1;
+      }
+      _xblockexpression = _xifexpression;
+    }
+    return _xblockexpression;
+  }
 }
diff --git a/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/DataClassGen.java b/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/DataClassGen.java
index 51c89f5..6dd25f9 100644
--- a/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/DataClassGen.java
+++ b/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/DataClassGen.java
@@ -27,12 +27,10 @@
 import org.eclipse.etrice.core.room.RefableType;
 import org.eclipse.etrice.core.room.RoomModel;
 import org.eclipse.etrice.core.room.StandardOperation;
-import org.eclipse.etrice.core.room.util.RoomHelpers;
 import org.eclipse.etrice.generator.cpp.gen.CppExtensions;
 import org.eclipse.etrice.generator.cpp.gen.Initialization;
 import org.eclipse.etrice.generator.generic.ProcedureHelpers;
 import org.eclipse.etrice.generator.generic.RoomExtensions;
-import org.eclipse.etrice.generator.generic.TypeHelpers;
 import org.eclipse.xtend2.lib.StringConcatenation;
 import org.eclipse.xtext.generator.JavaIoFileSystemAccess;
 import org.eclipse.xtext.xbase.lib.CollectionLiterals;
@@ -62,17 +60,9 @@
   
   @Inject
   @Extension
-  private TypeHelpers typeHelpers;
-  
-  @Inject
-  @Extension
   private Initialization _initialization;
   
   @Inject
-  @Extension
-  private RoomHelpers _roomHelpers;
-  
-  @Inject
   private ILogger logger;
   
   public void doGenerate(final Root root) {
diff --git a/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/NodeGen.java b/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/NodeGen.java
index a7b9538..5da4d61 100644
--- a/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/NodeGen.java
+++ b/plugins/org.eclipse.etrice.generator.cpp/xtend-gen/org/eclipse/etrice/generator/cpp/gen/NodeGen.java
@@ -333,12 +333,9 @@
         for(final ActorInstance ai : _actorInstances) {
           _builder.append("#include \"");
           ActorClass _actorClass = ai.getActorClass();
-          String _path = this._roomExtensions.getPath(_actorClass);
-          _builder.append(_path, "");
-          ActorClass _actorClass_1 = ai.getActorClass();
-          String _name = _actorClass_1.getName();
-          _builder.append(_name, "");
-          _builder.append(".h\"");
+          String _actorIncludePath = this._cppExtensions.getActorIncludePath(_actorClass);
+          _builder.append(_actorIncludePath, "");
+          _builder.append("\"");
           _builder.newLineIfNotEmpty();
         }
       }
@@ -435,14 +432,14 @@
               _builder.append("\t");
               _builder.append("msgService = new MessageService(this, IMessageService::");
               ExecMode _execmode_2 = thread_1.getExecmode();
-              String _name_1 = _execmode_2.getName();
-              _builder.append(_name_1, "\t\t");
+              String _name = _execmode_2.getName();
+              _builder.append(_name, "\t\t");
               _builder.append(", interval, 0, ");
               String _threadId_1 = this.getThreadId(thread_1);
               _builder.append(_threadId_1, "\t\t");
               _builder.append(", \"MessageService_");
-              String _name_2 = thread_1.getName();
-              _builder.append(_name_2, "\t\t");
+              String _name_1 = thread_1.getName();
+              _builder.append(_name_1, "\t\t");
               _builder.append("\", ");
               int _prio = thread_1.getPrio();
               _builder.append(_prio, "\t\t");
@@ -453,14 +450,14 @@
               _builder.append("\t");
               _builder.append("msgService = new MessageService(this, IMessageService::");
               ExecMode _execmode_3 = thread_1.getExecmode();
-              String _name_3 = _execmode_3.getName();
-              _builder.append(_name_3, "\t\t");
+              String _name_2 = _execmode_3.getName();
+              _builder.append(_name_2, "\t\t");
               _builder.append(", 0, ");
               String _threadId_2 = this.getThreadId(thread_1);
               _builder.append(_threadId_2, "\t\t");
               _builder.append(", \"MessageService_");
-              String _name_4 = thread_1.getName();
-              _builder.append(_name_4, "\t\t");
+              String _name_3 = thread_1.getName();
+              _builder.append(_name_3, "\t\t");
               _builder.append("\", ");
               int _prio_1 = thread_1.getPrio();
               _builder.append(_prio_1, "\t\t");
@@ -507,8 +504,8 @@
             if (_not) {
               _builder.append("\t");
               _builder.append("addPathToThread(\"");
-              String _path_1 = ai_1.getPath();
-              _builder.append(_path_1, "\t");
+              String _path = ai_1.getPath();
+              _builder.append(_path, "\t");
               _builder.append("\", ");
               PhysicalThread _thread = mapped.getThread();
               String _threadId_3 = this.getThreadId(_thread);
@@ -543,8 +540,8 @@
                   _builder.append("\t");
                   _builder.append("\t");
                   _builder.append("DebuggingService::getInstance().addMessageActorCreate(*this, \"");
-                  String _name_5 = sub.getName();
-                  _builder.append(_name_5, "\t\t");
+                  String _name_4 = sub.getName();
+                  _builder.append(_name_4, "\t\t");
                   _builder.append(GenmodelConstants.INDEX_SEP, "\t\t");
                   _builder.append("\"+i);");
                   _builder.newLineIfNotEmpty();
@@ -554,11 +551,11 @@
               _builder.append("\t");
               _builder.append("new ");
               ActorClass _type_1 = sub.getType();
-              String _name_6 = _type_1.getName();
-              _builder.append(_name_6, "\t\t");
+              String _implementationClassName = this._cppExtensions.getImplementationClassName(_type_1);
+              _builder.append(_implementationClassName, "\t\t");
               _builder.append("(this, \"");
-              String _name_7 = sub.getName();
-              _builder.append(_name_7, "\t\t");
+              String _name_5 = sub.getName();
+              _builder.append(_name_5, "\t\t");
               _builder.append(GenmodelConstants.INDEX_SEP, "\t\t");
               _builder.append("\"+i);");
               _builder.newLineIfNotEmpty();
@@ -572,8 +569,8 @@
                 if (_isGenerateMSCInstrumentation_1) {
                   _builder.append("\t");
                   _builder.append("DebuggingService::getInstance().addMessageActorCreate(*this, \"");
-                  String _name_8 = sub.getName();
-                  _builder.append(_name_8, "\t");
+                  String _name_6 = sub.getName();
+                  _builder.append(_name_6, "\t");
                   _builder.append("\");");
                   _builder.newLineIfNotEmpty();
                 }
@@ -581,11 +578,11 @@
               _builder.append("\t");
               _builder.append("new ");
               ActorClass _type_2 = sub.getType();
-              String _name_9 = _type_2.getName();
-              _builder.append(_name_9, "\t");
+              String _implementationClassName_1 = this._cppExtensions.getImplementationClassName(_type_2);
+              _builder.append(_implementationClassName_1, "\t");
               _builder.append("(this, \"");
-              String _name_10 = sub.getName();
-              _builder.append(_name_10, "\t");
+              String _name_7 = sub.getName();
+              _builder.append(_name_7, "\t");
               _builder.append("\");");
               _builder.newLineIfNotEmpty();
             }
diff --git a/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/generic/ILanguageExtensionBase.java b/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/generic/ILanguageExtensionBase.java
index 5ef06e6..6629ae5 100644
--- a/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/generic/ILanguageExtensionBase.java
+++ b/plugins/org.eclipse.etrice.generator.fsm/src/org/eclipse/etrice/generator/fsm/generic/ILanguageExtensionBase.java
@@ -114,6 +114,11 @@
 	boolean usesInheritance();
 
 	/**
+	 * produces the "virtual" keyword for C++ and the empty string else
+	 */
+	String makeOverridable();
+	
+	/**
 	 * does the target language use pointers
 	 *
 	 * @return true for C++ and C, false for Java
diff --git a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaExtensions.xtend b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaExtensions.xtend
index 49636d7..ed02522 100644
--- a/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaExtensions.xtend
+++ b/plugins/org.eclipse.etrice.generator.java/src/org/eclipse/etrice/generator/java/gen/JavaExtensions.xtend
@@ -285,5 +285,10 @@
 		else
 			"int"
 	}
+	
+	override makeOverridable() {
+		// not needed for Java: empty string
+		""
+	}
 
 }
diff --git a/plugins/org.eclipse.etrice.generator.java/xtend-gen/org/eclipse/etrice/generator/java/gen/JavaExtensions.java b/plugins/org.eclipse.etrice.generator.java/xtend-gen/org/eclipse/etrice/generator/java/gen/JavaExtensions.java
index f63cf8f..caf066c 100644
--- a/plugins/org.eclipse.etrice.generator.java/xtend-gen/org/eclipse/etrice/generator/java/gen/JavaExtensions.java
+++ b/plugins/org.eclipse.etrice.generator.java/xtend-gen/org/eclipse/etrice/generator/java/gen/JavaExtensions.java
@@ -652,4 +652,8 @@
     }
     return _xifexpression;
   }
+  
+  public String makeOverridable() {
+    return "";
+  }
 }
diff --git a/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/generic/GenericStateMachineGenerator.xtend b/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/generic/GenericStateMachineGenerator.xtend
index de3f0b7..35bb5ee 100644
--- a/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/generic/GenericStateMachineGenerator.xtend
+++ b/plugins/org.eclipse.etrice.generator/src/org/eclipse/etrice/generator/generic/GenericStateMachineGenerator.xtend
@@ -115,7 +115,7 @@
         }
         else {
             '''
-                «langExt.accessLevelProtected»void «tr.getActionCodeOperationName()»(«langExt.selfPointer(xpmc.className, hasArgs)»«IF hasArgs»«constIfItemPtr» ifitem«transitionChainGenerator.generateArgumentList(xpmc, tr)»«ENDIF»);
+                «langExt.accessLevelProtected»«langExt.makeOverridable»void «tr.getActionCodeOperationName()»(«langExt.selfPointer(xpmc.className, hasArgs)»«IF hasArgs»«constIfItemPtr» ifitem«transitionChainGenerator.generateArgumentList(xpmc, tr)»«ENDIF»);
             '''
         }
 	}
@@ -171,7 +171,7 @@
 					«entry»
 				}
 			«ELSE»
-				«langExt.accessLevelProtected»void «entryOp»(«selfPtr»);
+				«langExt.accessLevelProtected»«langExt.makeOverridable»void «entryOp»(«selfPtr»);
 			«ENDIF»
 		«ENDIF»
 		«IF !exit.empty»
@@ -180,7 +180,7 @@
 					«exit»
 				}
 			«ELSE»
-				«langExt.accessLevelProtected»void «exitOp»(«selfPtr»);
+				«langExt.accessLevelProtected»«langExt.makeOverridable»void «exitOp»(«selfPtr»);
 			«ENDIF»
 		«ENDIF»
 		«IF !docode.empty»
@@ -189,7 +189,7 @@
 					«docode»
 				}
 			«ELSE»
-				«langExt.accessLevelProtected»void «doOp»(«selfPtr»);
+				«langExt.accessLevelProtected»«langExt.makeOverridable»void «doOp»(«selfPtr»);
 			«ENDIF»
 		«ENDIF»
 		'''
diff --git a/plugins/org.eclipse.etrice.generator/xtend-gen/org/eclipse/etrice/generator/generic/GenericStateMachineGenerator.java b/plugins/org.eclipse.etrice.generator/xtend-gen/org/eclipse/etrice/generator/generic/GenericStateMachineGenerator.java
index 9cd08e5..6c3aa2b 100644
--- a/plugins/org.eclipse.etrice.generator/xtend-gen/org/eclipse/etrice/generator/generic/GenericStateMachineGenerator.java
+++ b/plugins/org.eclipse.etrice.generator/xtend-gen/org/eclipse/etrice/generator/generic/GenericStateMachineGenerator.java
@@ -235,6 +235,8 @@
         StringConcatenation _builder_1 = new StringConcatenation();
         String _accessLevelProtected_1 = this.langExt.accessLevelProtected();
         _builder_1.append(_accessLevelProtected_1, "");
+        String _makeOverridable = this.langExt.makeOverridable();
+        _builder_1.append(_makeOverridable, "");
         _builder_1.append("void ");
         String _actionCodeOperationName_1 = this._codegenHelpers.getActionCodeOperationName(tr);
         _builder_1.append(_actionCodeOperationName_1, "");
@@ -355,6 +357,8 @@
             } else {
               String _accessLevelProtected_1 = this.langExt.accessLevelProtected();
               _builder.append(_accessLevelProtected_1, "");
+              String _makeOverridable = this.langExt.makeOverridable();
+              _builder.append(_makeOverridable, "");
               _builder.append("void ");
               _builder.append(entryOp, "");
               _builder.append("(");
@@ -388,6 +392,8 @@
             } else {
               String _accessLevelProtected_3 = this.langExt.accessLevelProtected();
               _builder.append(_accessLevelProtected_3, "");
+              String _makeOverridable_1 = this.langExt.makeOverridable();
+              _builder.append(_makeOverridable_1, "");
               _builder.append("void ");
               _builder.append(exitOp, "");
               _builder.append("(");
@@ -421,6 +427,8 @@
             } else {
               String _accessLevelProtected_5 = this.langExt.accessLevelProtected();
               _builder.append(_accessLevelProtected_5, "");
+              String _makeOverridable_2 = this.langExt.makeOverridable();
+              _builder.append(_makeOverridable_2, "");
               _builder.append("void ");
               _builder.append(doOp, "");
               _builder.append("(");
diff --git a/plugins/org.eclipse.etrice.ui.behavior.actioneditor/xtend-gen/org/eclipse/etrice/ui/behavior/actioneditor/sourceviewer/CustomCompletionProposal.java b/plugins/org.eclipse.etrice.ui.behavior.actioneditor/xtend-gen/org/eclipse/etrice/ui/behavior/actioneditor/sourceviewer/CustomCompletionProposal.java
index 726c9da..6cc698f 100644
--- a/plugins/org.eclipse.etrice.ui.behavior.actioneditor/xtend-gen/org/eclipse/etrice/ui/behavior/actioneditor/sourceviewer/CustomCompletionProposal.java
+++ b/plugins/org.eclipse.etrice.ui.behavior.actioneditor/xtend-gen/org/eclipse/etrice/ui/behavior/actioneditor/sourceviewer/CustomCompletionProposal.java
@@ -44,8 +44,8 @@
     this.selection = selection;
   }
   
-  public void apply(final IDocument arg0) {
-    this.delegate.apply(arg0);
+  public void apply(final IDocument document) {
+    this.delegate.apply(document);
   }
   
   public String getAdditionalProposalInfo() {
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.examples.c.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.examples.c.zip
index 72cf425..6927ca1 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.examples.c.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.examples.c.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.examples.java.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.examples.java.zip
index 6b5b84d..edc01d1 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.examples.java.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.examples.java.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.c.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.c.zip
index 7710705..20c943a 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.c.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.c.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.cpp.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.cpp.zip
index 6c4ac7a..458792a 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.cpp.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.cpp.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.java.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.java.zip
index 70c36e5..8f81e61 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.java.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.modellib.java.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.c.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.c.zip
index b2e2770..1945382 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.c.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.c.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.cpp.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.cpp.zip
index 6b4b4b5..87352f3 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.cpp.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.cpp.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.java.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.java.zip
index de78dec..ee359db 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.java.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.runtime.java.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.template.c.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.template.c.zip
index 3f32b04..445f576 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.template.c.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.template.c.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.template.cpp.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.template.cpp.zip
index 8637b96..5a8bc6c 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.template.cpp.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.template.cpp.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.c.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.c.zip
index 264c698..ded41ec 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.c.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.c.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.cpp.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.cpp.zip
index d630012..ef911de 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.cpp.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.cpp.zip
Binary files differ
diff --git a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.java.zip b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.java.zip
index c5b7f64..a9062f1 100644
--- a/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.java.zip
+++ b/plugins/org.eclipse.etrice.ui.runtime/contents/org.eclipse.etrice.tutorials.java.zip
Binary files differ
diff --git a/runtime/org.eclipse.etrice.modellib.cpp/model/Annotations.room b/runtime/org.eclipse.etrice.modellib.cpp/model/Annotations.room
new file mode 100644
index 0000000..88a595d
--- /dev/null
+++ b/runtime/org.eclipse.etrice.modellib.cpp/model/Annotations.room
@@ -0,0 +1,8 @@
+RoomModel room.basic.annotations {
+	
+	AnnotationType ImplementationSubclass {
+        target = ActorClass
+        mandatory attribute fqnClassName: ptCharacter
+        optional attribute includePath: ptCharacter
+	}
+}
\ No newline at end of file
diff --git a/tests/org.eclipse.etrice.runtime.cpp.tests/.project b/tests/org.eclipse.etrice.runtime.cpp.tests/.project
index d05e35b..48ecbc9 100644
--- a/tests/org.eclipse.etrice.runtime.cpp.tests/.project
+++ b/tests/org.eclipse.etrice.runtime.cpp.tests/.project
@@ -9,7 +9,7 @@
 	<buildSpec>
 		<buildCommand>
 			<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
-			<triggers></triggers>
+			<triggers>clean,full,incremental,</triggers>
 			<arguments>
 			</arguments>
 		</buildCommand>