You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@kie.apache.org by eg...@apache.org on 2024/04/08 06:27:16 UTC

(incubator-kie-kogito-runtimes) branch main updated: [incubator-kie-issues-861] unify identifiers / part 1 (#3403)

This is an automated email from the ASF dual-hosted git repository.

egonzalez pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-kie-kogito-runtimes.git


The following commit(s) were added to refs/heads/main by this push:
     new a6899577fc [incubator-kie-issues-861] unify identifiers / part 1 (#3403)
a6899577fc is described below

commit a6899577fc8bca6c7285e843a423a26454ba455e
Author: Enrique <en...@ibm.com>
AuthorDate: Mon Apr 8 08:27:12 2024 +0200

    [incubator-kie-issues-861] unify identifiers / part 1 (#3403)
    
    * [incubator-kie-issues-916] unify identifiers / part 1
    
    * [incubator-kie-issues-916] PIM / migration plan impl
    
    * [incubator-kie-issues-916] PIM jbpm migration module added
    
    * [incubator-kie-issues-916] add marking logic
    
    * [incubator-kie-issues-916] add process event data state change
---
 .../filesystem/FileSystemProcessInstances.java     |     4 +-
 .../kogito/infinispan/CacheProcessInstances.java   |     2 +-
 .../CacheProcessInstancesWithLockIT.java           |     3 +
 .../kogito/persistence/jdbc/GenericRepository.java |    33 +
 .../persistence/jdbc/JDBCProcessInstances.java     |    14 +-
 .../kie/kogito/persistence/jdbc/Repository.java    |     6 +
 .../jdbc/AbstractProcessInstancesIT.java           |    62 +
 .../kogito/mongodb/MongoDBProcessInstances.java    |     5 +-
 .../DocumentProcessInstanceMarshallerTest.java     |     4 +-
 .../mongodb/PersistentProcessInstancesIT.java      |     2 +
 .../postgresql/PostgresqlProcessInstances.java     |    47 +-
 .../postgresql/PostgresqlProcessInstancesIT.java   |    44 +
 .../rocksdb/RocksDBProcessInstances.java           |     4 +-
 .../rocksdb/RockDBProcessInstancesTest.java        |     6 +-
 .../BaseProcessInstanceManagementResource.java     |    32 +-
 .../management/ProcessInstanceManagement.java      |     5 +
 .../process/management/ProcessMigrationSpec.java   |    26 +-
 .../BaseProcessInstanceManagementResourceTest.java |    15 +-
 .../process/event/KogitoProcessEventSupport.java   |     5 +-
 .../internal/process/runtime/KogitoNode.java       |     1 -
 .../org/kie/kogito/process/ProcessInstances.java   |     9 +
 .../org/kie/kogito/process/ProcessService.java     |     4 +
 .../java/org/kie/kogito/process/Processes.java     |    11 +
 .../main/java/org/kie/kogito/process/WorkItem.java |     4 +-
 .../uow/events/UnitOfWorkProcessEventListener.java |     6 +
 .../process/ProcessInstanceStateEventBody.java     |     1 +
 .../event/impl/ProcessInstanceEventBatch.java      |    11 +-
 .../services/jobs/impl/InMemoryJobService.java     |     9 +-
 .../registry/ProcessDefinitionEventRegistry.java   |     2 +-
 .../org/jbpm/bpmn2/xml/AbstractNodeHandler.java    |    43 +-
 .../org/jbpm/bpmn2/xml/BoundaryEventHandler.java   |     8 +-
 .../java/org/jbpm/bpmn2/xml/EndEventHandler.java   |     2 -
 .../bpmn2/xml/IntermediateCatchEventHandler.java   |     6 +-
 .../bpmn2/xml/IntermediateThrowEventHandler.java   |     3 +-
 .../java/org/jbpm/bpmn2/xml/ProcessHandler.java    |    43 +-
 .../java/org/jbpm/bpmn2/xml/StartEventHandler.java |     8 +-
 .../org/jbpm/bpmn2/xml/XmlBPMNProcessDumper.java   |     6 +-
 .../org/jbpm/bpmn2/xml/di/BPMNPlaneHandler.java    |     4 +-
 .../org/kie/kogito/process/bpmn2/BpmnProcess.java  |     1 +
 .../kogito/process/bpmn2/BpmnProcessCompiler.java  |     1 +
 .../src/test/java/org/jbpm/bpmn2/ActivityTest.java |     3 +-
 .../src/test/java/org/jbpm/bpmn2/EndEventTest.java |     7 +-
 .../src/test/java/org/jbpm/bpmn2/FlowTest.java     |     3 +-
 .../java/org/jbpm/bpmn2/IntermediateEventTest.java |     9 +-
 .../java/org/jbpm/bpmn2/ProcessFactoryTest.java    |   122 +-
 .../canonical/ActivityGenerationModelTest.java     |     7 +-
 .../java/org/jbpm/compiler/ProcessBuilderImpl.java |     2 +-
 .../compiler/canonical/AbstractNodeVisitor.java    |     9 +-
 .../jbpm/compiler/canonical/AbstractVisitor.java   |    12 +
 .../jbpm/compiler/canonical/ActionNodeVisitor.java |     5 +-
 .../canonical/BoundaryEventNodeVisitor.java        |     5 +-
 .../compiler/canonical/CatchLinkNodeVisitor.java   |     3 +-
 .../canonical/CompositeContextNodeVisitor.java     |     3 +-
 .../jbpm/compiler/canonical/EndNodeVisitor.java    |     3 +-
 .../jbpm/compiler/canonical/EventNodeVisitor.java  |     3 +-
 .../jbpm/compiler/canonical/FaultNodeVisitor.java  |     3 +-
 .../compiler/canonical/ForEachNodeVisitor.java     |    11 +-
 .../compiler/canonical/HumanTaskNodeVisitor.java   |     3 +-
 .../jbpm/compiler/canonical/JoinNodeVisitor.java   |     3 +-
 .../canonical/LambdaSubProcessNodeVisitor.java     |     3 +-
 .../compiler/canonical/MilestoneNodeVisitor.java   |     3 +-
 .../jbpm/compiler/canonical/ProcessVisitor.java    |     8 +-
 .../compiler/canonical/RuleSetNodeVisitor.java     |     3 +-
 .../jbpm/compiler/canonical/SplitNodeVisitor.java  |     5 +-
 .../jbpm/compiler/canonical/StartNodeVisitor.java  |     3 +-
 .../jbpm/compiler/canonical/StateNodeVisitor.java  |     4 +-
 .../compiler/canonical/ThrowLinkNodeVisitor.java   |     3 +-
 .../jbpm/compiler/canonical/TimerNodeVisitor.java  |     3 +-
 .../jbpm/compiler/canonical/TriggerMetaData.java   |     4 +-
 .../compiler/canonical/UserTaskModelMetaData.java  |    11 +-
 .../compiler/canonical/WorkItemNodeVisitor.java    |     3 +-
 .../descriptors/ServiceTaskDescriptor.java         |     2 +-
 .../org/jbpm/compiler/xml/ProcessBuildData.java    |     5 +-
 .../MultiConditionalSequenceFlowNodeBuilder.java   |     2 +-
 .../org/jbpm/process/builder/SplitNodeBuilder.java |     2 +-
 .../canonical/ProcessToExecModelGeneratorTest.java |    49 +-
 jbpm/jbpm-flow-migration/pom.xml                   |    73 +
 .../org/jbpm/flow/migration/MigrationPlanFile.java |    30 +-
 .../MigrationPlanFileFormatException.java}         |    15 +-
 .../flow/migration/MigrationPlanFileProvider.java} |    24 +-
 .../flow/migration/MigrationPlanFileReader.java}   |    43 +-
 .../jbpm/flow/migration/MigrationPlanProvider.java |   108 +
 .../jbpm/flow/migration/MigrationPlanService.java  |    92 +
 .../impl/FileSystemMigrationPlanFileProvider.java  |   144 +
 .../impl/JsonMigrationPlanFileReader.java          |    63 +
 ...JsonWorkflowElementIdentifierDeserializer.java} |    29 +-
 .../jbpm/flow/migration/model/MigrationPlan.java   |    71 +
 .../migration/model/NodeInstanceMigrationPlan.java |    77 +
 .../model/ProcessDefinitionMigrationPlan.java      |    75 +
 .../model/ProcessInstanceMigrationPlan.java        |    91 +
 ...MigrationProcessInstanceMarshallerListener.java |    62 +
 ...g.jbpm.flow.migration.MigrationPlanFileProvider |     1 +
 ...org.jbpm.flow.migration.MigrationPlanFileReader |     1 +
 ...serialization.ProcessInstanceMarshallerListener |     1 +
 .../org/jbpm/flow/migration/DummyProcess.java}     |    64 +-
 .../flow/migration/MigrationPlanProviderTest.java  |    63 +
 .../flow/migration/MigrationPlanServiceTest.java   |   128 +
 .../simple_invalid_migration.invalid               |     0
 .../META-INF/migration-plan/simple_migration.mpf   |    23 +
 jbpm/jbpm-flow/pom.xml                             |     1 -
 .../context/exception/CompensationHandler.java     |     2 +-
 .../core/context/exception/CompensationScope.java  |     2 +-
 .../jbpm/process/core/event/EventTypeFilter.java   |     1 +
 .../process/instance/KogitoProcessContextImpl.java |    12 -
 .../command/MigrateProcessInstanceCommand.java     |    15 +-
 .../exception/CompensationScopeInstance.java       |     2 +-
 .../event/KogitoProcessEventSupportImpl.java       |     6 +
 .../event/ProcessMigrationEventImpl.java}          |    25 +-
 .../process/instance/impl/ProcessInstanceImpl.java |     8 +
 .../impl/actions/AbstractNodeInstanceAction.java   |     2 +-
 .../humantask/HumanTaskWorkItemDecoratorImpl.java  |     7 +-
 .../core/RuleFlowNodeContainerFactory.java         |    55 +-
 .../jbpm/ruleflow/core/RuleFlowProcessFactory.java |    17 +-
 .../core/WorkflowElementIdentifierFactory.java     |    87 +
 .../core/factory/AbstractCompositeNodeFactory.java |    15 +-
 .../core/factory/AbstractEventNodeFactory.java     |     3 +-
 .../core/factory/AbstractWorkItemNodeFactory.java  |     3 +-
 .../ruleflow/core/factory/ActionNodeFactory.java   |     3 +-
 .../core/factory/BoundaryEventNodeFactory.java     |     7 +-
 .../core/factory/CatchLinkNodeFactory.java         |     3 +-
 .../core/factory/CompositeContextNodeFactory.java  |     3 +-
 .../ruleflow/core/factory/ConstraintFactory.java   |     3 +-
 .../ruleflow/core/factory/DynamicNodeFactory.java  |     3 +-
 .../jbpm/ruleflow/core/factory/EndNodeFactory.java |     3 +-
 .../ruleflow/core/factory/EventNodeFactory.java    |     3 +-
 .../core/factory/EventSubProcessNodeFactory.java   |     3 +-
 .../ruleflow/core/factory/ExtendedNodeFactory.java |     3 +-
 .../ruleflow/core/factory/FaultNodeFactory.java    |     3 +-
 .../ruleflow/core/factory/ForEachNodeFactory.java  |     5 +-
 .../core/factory/HumanTaskNodeFactory.java         |     3 +-
 .../jbpm/ruleflow/core/factory/JoinFactory.java    |     3 +-
 .../core/factory/MilestoneNodeFactory.java         |     3 +-
 .../jbpm/ruleflow/core/factory/NodeFactory.java    |     8 +-
 .../ruleflow/core/factory/RuleSetNodeFactory.java  |     3 +-
 .../jbpm/ruleflow/core/factory/SplitFactory.java   |    15 +-
 .../ruleflow/core/factory/StartNodeFactory.java    |     3 +-
 .../core/factory/StateBasedNodeFactory.java        |     3 +-
 .../ruleflow/core/factory/StateNodeFactory.java    |     5 +-
 .../core/factory/SubProcessNodeFactory.java        |     3 +-
 .../core/factory/ThrowLinkNodeFactory.java         |     3 +-
 .../ruleflow/core/factory/TimerNodeFactory.java    |     3 +-
 .../ruleflow/core/factory/WorkItemNodeFactory.java |     3 +-
 .../core/validation/RuleFlowProcessValidator.java  |    36 +-
 .../java/org/jbpm/util/JbpmClassLoaderUtil.java}   |    16 +-
 .../src/main/java/org/jbpm/workflow/core/Node.java |     5 +-
 .../java/org/jbpm/workflow/core/NodeContainer.java |     3 +-
 .../jbpm/workflow/core/impl/ConnectionImpl.java    |     8 +
 .../org/jbpm/workflow/core/impl/ConnectionRef.java |    32 +-
 .../jbpm/workflow/core/impl/NodeContainerImpl.java |     9 +-
 .../java/org/jbpm/workflow/core/impl/NodeImpl.java |    39 +-
 .../workflow/core/impl/WorkflowProcessImpl.java    |    12 +-
 .../org/jbpm/workflow/core/node/ActionNode.java    |     8 +-
 .../jbpm/workflow/core/node/AsyncEventNode.java    |     3 +-
 .../org/jbpm/workflow/core/node/CompositeNode.java |    40 +-
 .../org/jbpm/workflow/core/node/DynamicNode.java   |     3 +-
 .../java/org/jbpm/workflow/core/node/EndNode.java  |     6 +-
 .../org/jbpm/workflow/core/node/EventNode.java     |     8 +-
 .../org/jbpm/workflow/core/node/FaultNode.java     |     4 +-
 .../org/jbpm/workflow/core/node/ForEachNode.java   |    49 +-
 .../java/org/jbpm/workflow/core/node/Join.java     |     6 +-
 .../org/jbpm/workflow/core/node/MilestoneNode.java |     4 +-
 .../org/jbpm/workflow/core/node/RuleSetNode.java   |     8 +-
 .../java/org/jbpm/workflow/core/node/Split.java    |    14 +-
 .../org/jbpm/workflow/core/node/StartNode.java     |     8 +-
 .../jbpm/workflow/core/node/StateBasedNode.java    |     2 +-
 .../org/jbpm/workflow/core/node/StateNode.java     |     1 +
 .../jbpm/workflow/core/node/SubProcessNode.java    |     8 +-
 .../org/jbpm/workflow/core/node/TimerNode.java     |     8 +-
 .../org/jbpm/workflow/core/node/WorkItemNode.java  |     8 +-
 .../workflow/instance/NodeInstanceContainer.java   |     6 +-
 .../instance/WorkflowProcessInstanceUpgrader.java  |    37 +-
 .../instance/WorkflowRuntimeException.java         |     9 +-
 .../instance/impl/CompensationEventListener.java   |     2 +-
 .../instance/impl/NodeInstanceFactoryRegistry.java |    13 +-
 .../workflow/instance/impl/NodeInstanceImpl.java   |    26 +-
 .../instance/impl/WorkflowProcessInstanceImpl.java |    30 +-
 .../instance/node/BoundaryEventNodeInstance.java   |     2 +-
 .../instance/node/CompositeNodeInstance.java       |    15 +-
 .../instance/node/ForEachNodeInstance.java         |     8 +-
 .../jbpm/workflow/instance/node/JoinInstance.java  |    39 +-
 .../jbpm/workflow/instance/node/SplitInstance.java |     7 +-
 .../instance/node/StateBasedNodeInstance.java      |     2 +-
 .../workflow/instance/node/StateNodeInstance.java  |     3 +-
 .../instance/node/WorkItemNodeInstance.java        |     2 +-
 .../kie/kogito/process/impl/AbstractProcess.java   |     6 +-
 .../process/impl/AbstractProcessInstance.java      |     6 +-
 .../org/kie/kogito/process/impl/BaseWorkItem.java  |     8 +-
 .../kogito/process/impl/ProcessServiceImpl.java    |    11 +
 .../event/process/ProcessEventSupportTest.java     |    39 +-
 .../java/org/jbpm/process/CompensationTest.java    |    18 +-
 .../test/java/org/jbpm/process/FactoryTest.java    |    22 +-
 .../test/java/org/jbpm/process/ForEachTest.java    |    24 +-
 .../java/org/jbpm/process/ProcessFactoryTest.java  |    22 +-
 .../test/java/org/jbpm/process/SubProcessTest.java |    12 +-
 .../test/java/org/jbpm/process/WorkItemTest.java   |    12 +-
 .../process/instance/LightProcessRuntimeTest.java  |    16 +-
 .../java/org/jbpm/process/test/NodeCreator.java    |     3 +-
 .../validation/RuleFlowProcessValidatorTest.java   |    41 +-
 .../workflow/core/node/NodeInnerClassesTest.java   |     9 +-
 .../instance/node/EndNodeInstanceTest.java         |     9 +-
 .../workflow/instance/node/MockNodeInstance.java   |     4 +-
 .../instance/node/MockNodeInstanceFactory.java     |     1 +
 .../instance/node/StartNodeInstanceTest.java       |    10 +-
 .../process/impl/AbstractProcessInstanceTest.java  |     2 +-
 jbpm/pom.xml                                       |     1 +
 .../flow/serialization}/MarshallerContext.java     |     2 +-
 .../flow/serialization}/MarshallerContextName.java |     3 +-
 .../serialization}/MarshallerReaderContext.java    |     2 +-
 .../serialization}/MarshallerWriterContext.java    |     2 +-
 .../serialization}/ObjectMarshallerStrategy.java   |     2 +-
 .../serialization}/ProcessInstanceMarshaller.java  |     2 +-
 .../ProcessInstanceMarshallerException.java        |     2 +-
 .../ProcessInstanceMarshallerFactory.java          |     2 +-
 .../ProcessInstanceMarshallerListener.java}        |    29 +-
 .../ProcessInstanceMarshallerService.java          |    33 +-
 .../impl/ProtobufAbstractMarshallerContext.java    |    10 +-
 .../impl/ProtobufMarshallerReaderContext.java      |     4 +-
 .../impl/ProtobufProcessInstanceMarshaller.java    |    10 +-
 .../ProtobufProcessInstanceMarshallerFactory.java  |    10 +-
 .../impl/ProtobufProcessInstanceReader.java        |    84 +-
 .../impl/ProtobufProcessInstanceWriter.java        |    87 +-
 .../ProtobufProcessMarshallerWriteContext.java     |     4 +-
 .../impl/ProtobufVariableReader.java               |     8 +-
 .../impl/ProtobufVariableWriter.java               |     8 +-
 .../ProtobufBooleanMarshallerStrategy.java         |     6 +-
 .../ProtobufDateMarshallerStrategy.java            |     6 +-
 .../ProtobufDoubleMarshallerStrategy.java          |     6 +-
 .../ProtobufFloatMarshallerStrategy.java           |     6 +-
 .../ProtobufIntegerMarshallerStrategy.java         |     6 +-
 .../ProtobufJsonNodeMessageMarshaller.java         |     8 +-
 .../ProtobufListMarshallerStrategy.java            |     2 +-
 .../ProtobufLongMarshallerStrategy.java            |     6 +-
 .../ProtobufObjectMarshallerStrategy.java          |     6 +-
 .../ProtobufStringMarshallerStrategy.java          |     6 +-
 .../BooleanProtostreamBaseMarshaller.java          |     2 +-
 .../marshaller}/DateProtostreamBaseMarshaller.java |     2 +-
 .../DoubleProtostreamBaseMarshaller.java           |     2 +-
 .../FloatProtostreamBaseMarshaller.java            |     2 +-
 .../InstantProtostreamBaseMarshaller.java          |     2 +-
 .../IntegerProtostreamBaseMarshaller.java          |     2 +-
 .../marshaller}/LongProtostreamBaseMarshaller.java |     2 +-
 .../SerializableProtostreamBaseMarshaller.java     |     4 +-
 .../StringProtostreamBaseMarshaller.java           |     2 +-
 .../KogitoNodeInstanceContentsProtobuf.java        | 17658 +++++++++++++++++++
 .../protobuf/KogitoProcessInstanceProtobuf.java    |  4692 +++++
 .../protobuf/KogitoTypesProtobuf.java              |  8103 +++++++++
 .../protobuf/KogitoWorkItemsProtobuf.java          |  9059 ++++++++++
 .../protobuf/ProtobufTypeProvider.java             |     2 +-
 .../protobuf/ProtobufTypeRegistryFactory.java      |     4 +-
 .../ProtostreamProtobufAdapterTypeProvider.java    |     5 +-
 .../KogitoNodeInstanceContentsProtobuf.java        | 16703 ------------------
 .../protobuf/KogitoProcessInstanceProtobuf.java    |  4104 -----
 .../process/protobuf/KogitoTypesProtobuf.java      |  7759 --------
 .../process/protobuf/KogitoWorkItemsProtobuf.java  |  8396 ---------
 ...bpm.flow.serialization.ObjectMarshallerStrategy |     9 +
 ...low.serialization.protobuf.ProtobufTypeProvider |     1 +
 ....serialization.process.ObjectMarshallerStrategy |     9 -
 ...alization.process.protobuf.ProtobufTypeProvider |     1 -
 .../protobuf/kogito_node_instance_contents.proto   |     6 +-
 .../protobuf/kogito_process_instance.proto         |     6 +-
 .../serialization}/protobuf/kogito_types.proto     |     4 +-
 .../protobuf/kogito_work_items.proto               |     2 +-
 .../ProcessInstanceMarshallTest.java               |    29 +-
 ...ProtostreamProtobufAdapterTypeProviderTest.java |     2 +-
 jbpm/process-workitems/pom.xml                     |     1 +
 .../process/workitems/impl/KogitoWorkItemImpl.java |     7 +-
 kogito-bom/pom.xml                                 |    11 +
 .../codegen/process/ProcessGenerationIT.java       |     7 +-
 .../kie/kogito/codegen/tests/InvalidProcessIT.java |     8 +-
 .../org/kie/kogito/codegen/tests/TimerEventIT.java |     2 +-
 .../org/kie/kogito/process/impl/MilestoneIT.java   |     8 +-
 .../process/persistence/PersistenceGenerator.java  |    22 +-
 .../class-templates/TaskModelFactoryTemplate.java  |     2 +-
 .../ProtostreamObjectMarshallerJavaTemplate.java   |     4 +-
 .../process/JavaRuleFlowProcessValidatorTest.java  |    16 +-
 .../events/CodegenMessageStartEventTest.java       |     2 +-
 .../InfinispanPersistenceGeneratorTest.java        |     2 +
 .../serverless/workflow/parser/ParserContext.java  |     6 +-
 .../handlers/CompositeContextNodeHandler.java      |     2 +-
 .../workflow/parser/handlers/NodeFactoryUtils.java |    17 +-
 .../workflow/parser/handlers/ParallelHandler.java  |     3 +-
 .../workflow/parser/handlers/StateHandler.java     |    92 +-
 .../workflow/parser/handlers/SwitchHandler.java    |    17 +-
 .../executor/PersistentApplicationTest.java        |     2 +-
 ...CallbackStateServerlessWorkflowParsingTest.java |     6 +-
 .../common/CallbackJobsServiceResource.java        |    11 +-
 .../common/CallbackJobsServiceResourceTest.java    |    10 +-
 ...ogitoAddOnJobsKnativeEventingProcessorTest.java |     5 +-
 .../KogitoProcessKnativeEventingProcessorTest.java |     2 +
 .../persistence/kafka/KafkaProcessInstances.java   |     2 +-
 .../kafka/KafkaProcessInstancesTest.java           |     2 +-
 .../ProcessInstanceManagementResource.java         |    20 +
 .../workflow/deployment/WorkflowProcessor.java     |    10 +-
 .../kogito-quarkus-workflow-common/pom.xml         |     4 +
 .../src/main/resources/HelloActivity.bpmn          |    34 +-
 .../src/main/resources/HelloProcess.bpmn           |    34 +-
 .../ReusableSubProcessWithServiceTaks.bpmn         |    34 +-
 .../quarkus/ManagementAddOnIT.java                 |     8 +-
 .../springboot/CallbackJobsServiceResource.java    |     9 +-
 .../ProcessInstanceManagementRestController.java   |    17 +
 .../springboot/ManagementAddOnTest.java            |     8 +-
 .../kogito-processes-spring-boot-starter/pom.xml   |     4 +
 302 files changed, 42489 insertions(+), 38195 deletions(-)

diff --git a/addons/common/persistence/filesystem/src/main/java/org/kie/kogito/persistence/filesystem/FileSystemProcessInstances.java b/addons/common/persistence/filesystem/src/main/java/org/kie/kogito/persistence/filesystem/FileSystemProcessInstances.java
index c5c1e1b82d..9fa8e5fb0c 100644
--- a/addons/common/persistence/filesystem/src/main/java/org/kie/kogito/persistence/filesystem/FileSystemProcessInstances.java
+++ b/addons/common/persistence/filesystem/src/main/java/org/kie/kogito/persistence/filesystem/FileSystemProcessInstances.java
@@ -30,13 +30,13 @@ import java.util.Optional;
 import java.util.function.Supplier;
 import java.util.stream.Stream;
 
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerService;
 import org.kie.kogito.process.MutableProcessInstances;
 import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.ProcessInstanceDuplicatedException;
 import org.kie.kogito.process.ProcessInstanceReadMode;
 import org.kie.kogito.process.impl.AbstractProcessInstance;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerService;
 
 @SuppressWarnings({ "rawtypes" })
 public class FileSystemProcessInstances implements MutableProcessInstances {
@@ -50,7 +50,7 @@ public class FileSystemProcessInstances implements MutableProcessInstances {
     private ProcessInstanceMarshallerService marshaller;
 
     public FileSystemProcessInstances(Process<?> process, Path storage) {
-        this(process, storage, ProcessInstanceMarshallerService.newBuilder().withDefaultObjectMarshallerStrategies().build());
+        this(process, storage, ProcessInstanceMarshallerService.newBuilder().withDefaultObjectMarshallerStrategies().withDefaultListeners().build());
     }
 
     public FileSystemProcessInstances(Process<?> process, Path storage, ProcessInstanceMarshallerService marshaller) {
diff --git a/addons/common/persistence/infinispan/src/main/java/org/kie/kogito/infinispan/CacheProcessInstances.java b/addons/common/persistence/infinispan/src/main/java/org/kie/kogito/infinispan/CacheProcessInstances.java
index f27f240ded..903c5bb63d 100644
--- a/addons/common/persistence/infinispan/src/main/java/org/kie/kogito/infinispan/CacheProcessInstances.java
+++ b/addons/common/persistence/infinispan/src/main/java/org/kie/kogito/infinispan/CacheProcessInstances.java
@@ -31,6 +31,7 @@ import org.infinispan.client.hotrod.MetadataValue;
 import org.infinispan.client.hotrod.RemoteCache;
 import org.infinispan.client.hotrod.RemoteCacheManager;
 import org.infinispan.commons.util.CloseableIterator;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerService;
 import org.kie.kogito.internal.utils.ConversionUtils;
 import org.kie.kogito.process.MutableProcessInstances;
 import org.kie.kogito.process.Process;
@@ -39,7 +40,6 @@ import org.kie.kogito.process.ProcessInstanceDuplicatedException;
 import org.kie.kogito.process.ProcessInstanceOptimisticLockingException;
 import org.kie.kogito.process.ProcessInstanceReadMode;
 import org.kie.kogito.process.impl.AbstractProcessInstance;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerService;
 
 @SuppressWarnings({ "rawtypes" })
 public class CacheProcessInstances implements MutableProcessInstances {
diff --git a/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesWithLockIT.java b/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesWithLockIT.java
index 231afc3c9e..77b4c8429e 100644
--- a/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesWithLockIT.java
+++ b/addons/common/persistence/infinispan/src/test/java/org/kie/kogito/infinispan/CacheProcessInstancesWithLockIT.java
@@ -28,6 +28,7 @@ import org.jbpm.workflow.instance.WorkflowProcessInstance;
 import org.junit.jupiter.api.AfterEach;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.bpmn2.BpmnProcess;
 import org.kie.kogito.process.bpmn2.BpmnVariables;
@@ -93,6 +94,7 @@ class CacheProcessInstancesWithLockIT {
         when(mockCreatePi.status()).thenReturn(ProcessInstance.STATE_ACTIVE);
         when(mockCreatePi.internalGetProcessInstance()).thenReturn(createPi);
         when(mockCreatePi.id()).thenReturn(TEST_ID);
+        when(mockCreatePi.process()).thenReturn((Process) process);
         pi.create(TEST_ID, mockCreatePi);
         assertOne(pi);
         assertThat(pi.exists(TEST_ID)).isTrue();
@@ -104,6 +106,7 @@ class CacheProcessInstancesWithLockIT {
         when(mockUpdatePi.status()).thenReturn(ProcessInstance.STATE_ACTIVE);
         when(mockUpdatePi.internalGetProcessInstance()).thenReturn(updatePi);
         when(mockUpdatePi.id()).thenReturn(TEST_ID);
+        when(mockUpdatePi.process()).thenReturn((Process) process);
 
         try {
             pi.update(TEST_ID, mockUpdatePi);
diff --git a/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/GenericRepository.java b/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/GenericRepository.java
index 9dd066ee9f..1ff5daae69 100644
--- a/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/GenericRepository.java
+++ b/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/GenericRepository.java
@@ -235,4 +235,37 @@ public class GenericRepository extends Repository {
     private static String sqlIncludingVersion(String statement, String processVersion) {
         return statement + " " + (processVersion == null ? PROCESS_VERSION_IS_NULL : PROCESS_VERSION_EQUALS_TO);
     }
+
+    @Override
+    long migrate(String processId, String processVersion, String targetProcessId, String targetProcessVersion) {
+        try (Connection connection = dataSource.getConnection();
+                PreparedStatement statement = connection.prepareStatement(sqlIncludingVersion(Repository.MIGRATE_BULK, processVersion))) {
+            statement.setString(1, targetProcessId);
+            statement.setString(2, targetProcessVersion);
+            statement.setString(3, processId);
+            if (processVersion != null) {
+                statement.setString(4, processVersion);
+            }
+            return statement.executeUpdate();
+        } catch (Exception e) {
+            throw uncheckedException(e, "Error updating process instance %s-%s", processId, processVersion);
+        }
+    }
+
+    @Override
+    void migrate(String processId, String processVersion, String targetProcessId, String targetProcessVersion, String[] processIds) {
+        try (Connection connection = dataSource.getConnection();
+                PreparedStatement statement = connection.prepareStatement(sqlIncludingVersion(Repository.MIGRATE_INSTANCE, processVersion))) {
+            statement.setString(1, targetProcessId);
+            statement.setString(2, targetProcessVersion);
+            statement.setObject(3, connection.createArrayOf("VARCHAR", processIds));
+            statement.setString(4, processId);
+            if (processVersion != null) {
+                statement.setString(5, processVersion);
+            }
+            statement.executeUpdate();
+        } catch (Exception e) {
+            throw uncheckedException(e, "Error updating process instance %s-%s", processId, processVersion);
+        }
+    }
 }
diff --git a/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/JDBCProcessInstances.java b/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/JDBCProcessInstances.java
index 26c089fecf..4463406180 100644
--- a/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/JDBCProcessInstances.java
+++ b/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/JDBCProcessInstances.java
@@ -24,13 +24,13 @@ import java.util.stream.Stream;
 
 import javax.sql.DataSource;
 
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerService;
 import org.kie.kogito.process.MutableProcessInstances;
 import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.ProcessInstanceOptimisticLockingException;
 import org.kie.kogito.process.ProcessInstanceReadMode;
 import org.kie.kogito.process.impl.AbstractProcessInstance;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerService;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -46,7 +46,7 @@ public class JDBCProcessInstances implements MutableProcessInstances {
     public JDBCProcessInstances(Process<?> process, DataSource dataSource, boolean lock) {
         this.process = process;
         this.lock = lock;
-        this.marshaller = ProcessInstanceMarshallerService.newBuilder().withDefaultObjectMarshallerStrategies().build();
+        this.marshaller = ProcessInstanceMarshallerService.newBuilder().withDefaultObjectMarshallerStrategies().withDefaultListeners().build();
         this.repository = new GenericRepository(dataSource);
     }
 
@@ -88,6 +88,16 @@ public class JDBCProcessInstances implements MutableProcessInstances {
         }
     }
 
+    @Override
+    public long migrateAll(String targetProcessId, String targetProcessVersion) {
+        return repository.migrate(process.id(), process.version(), targetProcessId, targetProcessVersion);
+    }
+
+    @Override
+    public void migrateProcessInstances(String targetProcessId, String targetProcessVersion, String... processIds) {
+        repository.migrate(process.id(), process.version(), targetProcessId, targetProcessVersion, processIds);
+    }
+
     @Override
     public void remove(String id) {
         LOGGER.debug("Removing process instance id: {}, processId: {}", id, process.id());
diff --git a/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/Repository.java b/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/Repository.java
index a1d1036766..cdcb5a64ff 100644
--- a/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/Repository.java
+++ b/addons/common/persistence/jdbc/src/main/java/org/kie/kogito/persistence/jdbc/Repository.java
@@ -34,6 +34,8 @@ abstract class Repository {
     static final String DELETE = "DELETE FROM process_instances WHERE process_id = ? and id = ?";
     static final String PROCESS_VERSION_EQUALS_TO = "and process_version = ?";
     static final String PROCESS_VERSION_IS_NULL = "and process_version is null";
+    static final String MIGRATE_BULK = "UPDATE process_instances SET process_id = ?, process_version = ? WHERE process_id = ? ";
+    static final String MIGRATE_INSTANCE = "UPDATE process_instances SET process_id = ?, process_version = ? WHERE id = ANY (?) and process_id = ? ";
 
     static class Record {
         private final byte[] payload;
@@ -70,4 +72,8 @@ abstract class Repository {
     protected RuntimeException uncheckedException(Exception ex, String message, Object... param) {
         return new RuntimeException(String.format(message, param), ex);
     }
+
+    abstract long migrate(String id, String version, String targetProcessId, String targetProcessVersion);
+
+    abstract void migrate(String id, String version, String targetProcessId, String targetProcessVersion, String[] processIds);
 }
diff --git a/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java b/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java
index 3769ce2329..4a2e47132b 100644
--- a/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java
+++ b/addons/common/persistence/jdbc/src/test/java/org/kie/persistence/jdbc/AbstractProcessInstancesIT.java
@@ -18,6 +18,9 @@
  */
 package org.kie.persistence.jdbc;
 
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.util.Collections;
 import java.util.Optional;
 
 import javax.sql.DataSource;
@@ -39,6 +42,7 @@ import static java.util.Collections.singletonMap;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
 import static org.assertj.core.api.Assertions.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.kie.kogito.internal.process.runtime.KogitoProcessInstance.STATE_ACTIVE;
 import static org.kie.kogito.internal.process.runtime.KogitoProcessInstance.STATE_COMPLETED;
 import static org.kie.kogito.test.utils.ProcessInstancesTestUtils.abort;
@@ -54,6 +58,8 @@ abstract class AbstractProcessInstancesIT {
     public static final String TEST_ID = "02ac3854-46ee-42b7-8b63-5186c9889d96";
     public static SecurityPolicy securityPolicy = SecurityPolicy.of(IdentityProviders.of("john"));
 
+    DataSource dataSource;
+
     public static void initMigration(JdbcDatabaseContainer container, String dbKind) {
         Flyway flyway = Flyway.configure().dataSource(container.getJdbcUrl(),
                 container.getUsername(),
@@ -211,6 +217,62 @@ abstract class AbstractProcessInstancesIT {
         assertEmpty(process.instances());
     }
 
+    @Test
+    public void testMigrateAll() throws Exception {
+        var factory = new TestProcessInstancesFactory(getDataSource(), lock());
+        BpmnProcess process = createProcess(factory, "BPMN2-UserTask.bpmn2");
+        ProcessInstance<BpmnVariables> processInstance1 = process.createInstance(BpmnVariables.create(Collections.singletonMap("test", "test")));
+        processInstance1.start();
+
+        ProcessInstance<BpmnVariables> processInstance2 = process.createInstance(BpmnVariables.create(Collections.singletonMap("test", "test")));
+        processInstance2.start();
+
+        process.instances().migrateAll("migrated", "2");
+
+        DataSource dataSource = getDataSource();
+        try (Connection connection = dataSource.getConnection();
+                ResultSet resultSet = connection.createStatement().executeQuery("SELECT process_id, process_version FROM process_instances")) {
+
+            while (resultSet.next()) {
+                assertEquals(resultSet.getString(1), "migrated");
+                assertEquals(resultSet.getString(2), "2");
+            }
+        }
+    }
+
+    @Test
+    public void testMigrateSingle() throws Exception {
+        var factory = new TestProcessInstancesFactory(getDataSource(), lock());
+        BpmnProcess process = createProcess(factory, "BPMN2-UserTask.bpmn2");
+        ProcessInstance<BpmnVariables> processInstance1 = process.createInstance(BpmnVariables.create(Collections.singletonMap("test", "test")));
+        processInstance1.start();
+
+        ProcessInstance<BpmnVariables> processInstance2 = process.createInstance(BpmnVariables.create(Collections.singletonMap("test", "test")));
+        processInstance2.start();
+
+        process.instances().migrateProcessInstances("migrated", "2", processInstance1.id());
+
+        DataSource dataSource = getDataSource();
+        try (Connection connection = dataSource.getConnection();
+                ResultSet resultSet = connection.createStatement().executeQuery("SELECT process_id, process_version FROM process_instances WHERE id = '" + processInstance1.id() + "'")) {
+
+            while (resultSet.next()) {
+                assertEquals(resultSet.getString(1), "migrated");
+                assertEquals(resultSet.getString(2), "2");
+            }
+        }
+
+        try (Connection connection = dataSource.getConnection();
+                ResultSet resultSet = connection.createStatement().executeQuery("SELECT process_id, process_version FROM process_instances WHERE id = '" + processInstance2.id() + "'")) {
+
+            while (resultSet.next()) {
+                assertEquals(resultSet.getString(1), "BPMN2_UserTask");
+                assertEquals(resultSet.getString(2), "1.0");
+            }
+        }
+
+    }
+
     @Test
     public void testRemove() {
         var factory = new TestProcessInstancesFactory(getDataSource(), lock());
diff --git a/addons/common/persistence/mongodb/src/main/java/org/kie/kogito/mongodb/MongoDBProcessInstances.java b/addons/common/persistence/mongodb/src/main/java/org/kie/kogito/mongodb/MongoDBProcessInstances.java
index 6146970c6b..21d8aa61db 100644
--- a/addons/common/persistence/mongodb/src/main/java/org/kie/kogito/mongodb/MongoDBProcessInstances.java
+++ b/addons/common/persistence/mongodb/src/main/java/org/kie/kogito/mongodb/MongoDBProcessInstances.java
@@ -29,6 +29,8 @@ import org.bson.Document;
 import org.bson.codecs.configuration.CodecRegistries;
 import org.bson.codecs.configuration.CodecRegistry;
 import org.bson.conversions.Bson;
+import org.jbpm.flow.serialization.MarshallerContextName;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerService;
 import org.kie.kogito.Model;
 import org.kie.kogito.mongodb.transaction.AbstractTransactionManager;
 import org.kie.kogito.process.MutableProcessInstances;
@@ -37,8 +39,6 @@ import org.kie.kogito.process.ProcessInstanceDuplicatedException;
 import org.kie.kogito.process.ProcessInstanceOptimisticLockingException;
 import org.kie.kogito.process.ProcessInstanceReadMode;
 import org.kie.kogito.process.impl.AbstractProcessInstance;
-import org.kie.kogito.serialization.process.MarshallerContextName;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerService;
 
 import com.mongodb.MongoClientSettings;
 import com.mongodb.client.ClientSession;
@@ -69,6 +69,7 @@ public class MongoDBProcessInstances<T extends Model> implements MutableProcessI
         this.collection = Objects.requireNonNull(getCollection(mongoClient, process.id(), dbName));
         this.marshaller = ProcessInstanceMarshallerService.newBuilder()
                 .withDefaultObjectMarshallerStrategies()
+                .withDefaultListeners()
                 .withContextEntries(singletonMap(MarshallerContextName.MARSHALLER_FORMAT, MarshallerContextName.MARSHALLER_FORMAT_JSON))
                 .build();
         this.transactionManager = Objects.requireNonNull(transactionManager);
diff --git a/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/DocumentProcessInstanceMarshallerTest.java b/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/DocumentProcessInstanceMarshallerTest.java
index 6c70c5ead1..c58bc3bd47 100644
--- a/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/DocumentProcessInstanceMarshallerTest.java
+++ b/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/DocumentProcessInstanceMarshallerTest.java
@@ -24,13 +24,13 @@ import java.util.Collections;
 
 import org.bson.Document;
 import org.drools.io.ClassPathResource;
+import org.jbpm.flow.serialization.MarshallerContextName;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerService;
 import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Test;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.bpmn2.BpmnProcess;
 import org.kie.kogito.process.bpmn2.BpmnVariables;
-import org.kie.kogito.serialization.process.MarshallerContextName;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerService;
 
 import static java.util.Collections.singletonMap;
 import static org.assertj.core.api.Assertions.assertThat;
diff --git a/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesIT.java b/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesIT.java
index 21e1fcbe3c..97e1de8684 100644
--- a/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesIT.java
+++ b/addons/common/persistence/mongodb/src/test/java/org/kie/kogito/mongodb/PersistentProcessInstancesIT.java
@@ -143,6 +143,7 @@ class PersistentProcessInstancesIT extends TestHelper {
         AbstractProcessInstance mockUpdateProcessInstance = mock(AbstractProcessInstance.class);
         when(mockUpdateProcessInstance.status()).thenReturn(ProcessInstance.STATE_ACTIVE);
         when(mockUpdateProcessInstance.internalGetProcessInstance()).thenReturn(updatePi);
+        when(mockUpdateProcessInstance.process()).thenReturn(process);
 
         mongodbInstance.update(id, mockUpdateProcessInstance);
         verify(mongoCollection, times(1)).replaceOne(eq(clientSession), eq(Filters.eq(PROCESS_INSTANCE_ID, id)), any());
@@ -154,6 +155,7 @@ class PersistentProcessInstancesIT extends TestHelper {
         AbstractProcessInstance mockCreateProcessInstance = mock(AbstractProcessInstance.class);
         when(mockCreateProcessInstance.status()).thenReturn(ProcessInstance.STATE_ACTIVE);
         when(mockCreateProcessInstance.internalGetProcessInstance()).thenReturn(createPi);
+        when(mockCreateProcessInstance.process()).thenReturn(process);
 
         mongodbInstance.create(id, mockCreateProcessInstance);
         verify(mongoCollection, times(1)).insertOne(eq(clientSession), any());
diff --git a/addons/common/persistence/postgresql/src/main/java/org/kie/kogito/persistence/postgresql/PostgresqlProcessInstances.java b/addons/common/persistence/postgresql/src/main/java/org/kie/kogito/persistence/postgresql/PostgresqlProcessInstances.java
index 2f427ee08d..c0a0bb388b 100644
--- a/addons/common/persistence/postgresql/src/main/java/org/kie/kogito/persistence/postgresql/PostgresqlProcessInstances.java
+++ b/addons/common/persistence/postgresql/src/main/java/org/kie/kogito/persistence/postgresql/PostgresqlProcessInstances.java
@@ -18,6 +18,7 @@
  */
 package org.kie.kogito.persistence.postgresql;
 
+import java.util.Arrays;
 import java.util.Iterator;
 import java.util.Optional;
 import java.util.concurrent.ExecutionException;
@@ -26,17 +27,18 @@ import java.util.concurrent.TimeoutException;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerService;
 import org.kie.kogito.process.MutableProcessInstances;
 import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.ProcessInstanceOptimisticLockingException;
 import org.kie.kogito.process.ProcessInstanceReadMode;
 import org.kie.kogito.process.impl.AbstractProcessInstance;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerService;
 
 import io.vertx.core.Future;
 import io.vertx.core.buffer.Buffer;
 import io.vertx.pgclient.PgPool;
+import io.vertx.sqlclient.PreparedQuery;
 import io.vertx.sqlclient.Row;
 import io.vertx.sqlclient.RowSet;
 import io.vertx.sqlclient.Tuple;
@@ -54,6 +56,8 @@ public class PostgresqlProcessInstances implements MutableProcessInstances {
     private static final String FIND_BY_ID = "SELECT payload, version FROM process_instances WHERE process_id = $1 and id = $2 and process_version ";
     private static final String FIND_ALL = "SELECT payload, version FROM process_instances WHERE process_id = $1 and process_version ";
     private static final String UPDATE_WITH_LOCK = "UPDATE process_instances SET payload = $1, version = $2 WHERE process_id = $3 and id = $4 and version = $5 and process_version ";
+    private static final String MIGRATE_BULK = "UPDATE process_instances SET process_id = $1, process_version = $2 WHERE process_id = $3 and process_version ";
+    private static final String MIGRATE_INSTANCE = "UPDATE process_instances SET process_id = $1, process_version = $2 WHERE process_id = $3 and id = ANY ($4) and process_version ";
 
     private final Process<?> process;
     private final PgPool client;
@@ -65,7 +69,7 @@ public class PostgresqlProcessInstances implements MutableProcessInstances {
         this.process = process;
         this.client = client;
         this.queryTimeoutMillis = queryTimeoutMillis;
-        this.marshaller = ProcessInstanceMarshallerService.newBuilder().withDefaultObjectMarshallerStrategies().build();
+        this.marshaller = ProcessInstanceMarshallerService.newBuilder().withDefaultObjectMarshallerStrategies().withDefaultListeners().build();
         this.lock = lock;
     }
 
@@ -161,6 +165,45 @@ public class PostgresqlProcessInstances implements MutableProcessInstances {
         return new RuntimeException(String.format(message, param), ex);
     }
 
+    @Override
+    public long migrateAll(String targetProcessId, String targetProcessVersion) {
+        try {
+            PreparedQuery<RowSet<Row>> rows = null;
+            if (process.version() == null) {
+                rows = client.preparedQuery(MIGRATE_BULK + IS_NULL);
+            } else {
+                rows = client.preparedQuery(MIGRATE_BULK + "= $4");
+            }
+            Future<RowSet<Row>> future = rows.execute(tuple(targetProcessId, targetProcessVersion, process.id()));
+            return getResultFromFuture(future).map(RowSet::rowCount).orElse(0);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw uncheckedException(e, "Error migration process instance %s %s", process.id(), process.version());
+        } catch (Exception e) {
+            throw uncheckedException(e, "Error deleting process instance %s %s", process.id(), process.version());
+        }
+    }
+
+    @Override
+    public void migrateProcessInstances(String targetProcessId, String targetProcessVersion, String... processIds) {
+        try {
+            PreparedQuery<RowSet<Row>> rows = null;
+            if (process.version() == null) {
+                rows = client.preparedQuery(MIGRATE_INSTANCE + IS_NULL);
+
+            } else {
+                rows = client.preparedQuery(MIGRATE_INSTANCE + "= $5");
+            }
+            Future<RowSet<Row>> future = rows.execute(tuple(targetProcessId, targetProcessVersion, process.id(), processIds));
+            getExecutedResult(future);
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            throw uncheckedException(e, "Error deleting process instance %s", Arrays.toString(processIds));
+        } catch (Exception e) {
+            throw uncheckedException(e, "Error deleting process instance %s", Arrays.toString(processIds));
+        }
+    }
+
     private boolean updateInternal(String id, byte[] payload) {
         try {
             Future<RowSet<Row>> future =
diff --git a/addons/common/persistence/postgresql/src/test/java/org/kie/persistence/postgresql/PostgresqlProcessInstancesIT.java b/addons/common/persistence/postgresql/src/test/java/org/kie/persistence/postgresql/PostgresqlProcessInstancesIT.java
index 5df7948142..716c909cec 100644
--- a/addons/common/persistence/postgresql/src/test/java/org/kie/persistence/postgresql/PostgresqlProcessInstancesIT.java
+++ b/addons/common/persistence/postgresql/src/test/java/org/kie/persistence/postgresql/PostgresqlProcessInstancesIT.java
@@ -42,10 +42,14 @@ import org.testcontainers.junit.jupiter.Container;
 import org.testcontainers.junit.jupiter.Testcontainers;
 
 import io.vertx.pgclient.PgPool;
+import io.vertx.sqlclient.Row;
+import io.vertx.sqlclient.RowSet;
+import io.vertx.sqlclient.Tuple;
 
 import static java.util.Collections.singletonMap;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.kie.kogito.internal.process.runtime.KogitoProcessInstance.STATE_ACTIVE;
 import static org.kie.kogito.internal.process.runtime.KogitoProcessInstance.STATE_COMPLETED;
 import static org.kie.kogito.test.utils.ProcessInstancesTestUtils.abort;
@@ -198,6 +202,46 @@ class PostgresqlProcessInstancesIT {
 
     }
 
+    @Test
+    public void testMigrateAll() throws Exception {
+        BpmnProcess process = createProcess("BPMN2-UserTask.bpmn2");
+        ProcessInstance<BpmnVariables> processInstance1 = process.createInstance(BpmnVariables.create(Collections.singletonMap("test", "test")));
+        processInstance1.start();
+
+        ProcessInstance<BpmnVariables> processInstance2 = process.createInstance(BpmnVariables.create(Collections.singletonMap("test", "test")));
+        processInstance2.start();
+
+        process.instances().migrateAll("migrated", "2");
+        RowSet<Row> rows = client.preparedQuery("SELECT process_id, process_version FROM process_instances").execute().toCompletionStage().toCompletableFuture().get();
+        for (Row row : rows) {
+            assertEquals(row.get(String.class, 0), "migrated");
+            assertEquals(row.get(String.class, 1), "2");
+        }
+    }
+
+    @Test
+    public void testMigrateSingle() throws Exception {
+        BpmnProcess process = createProcess("BPMN2-UserTask.bpmn2");
+        ProcessInstance<BpmnVariables> processInstance1 = process.createInstance(BpmnVariables.create(Collections.singletonMap("test", "test")));
+        processInstance1.start();
+
+        ProcessInstance<BpmnVariables> processInstance2 = process.createInstance(BpmnVariables.create(Collections.singletonMap("test", "test")));
+        processInstance2.start();
+
+        process.instances().migrateProcessInstances("migrated", "2", processInstance1.id());
+        RowSet<Row> rows = null;
+        rows = client.preparedQuery("SELECT process_id, process_version FROM process_instances WHERE id = $1").execute(Tuple.of(processInstance1.id())).toCompletionStage().toCompletableFuture().get();
+        for (Row row : rows) {
+            assertEquals(row.get(String.class, 0), "migrated");
+            assertEquals(row.get(String.class, 1), "2");
+        }
+        rows = client.preparedQuery("SELECT process_id, process_version FROM process_instances WHERE id = $1").execute(Tuple.of(processInstance2.id())).toCompletionStage().toCompletableFuture().get();
+        for (Row row : rows) {
+            assertEquals(row.get(String.class, 0), "BPMN2_UserTask");
+            assertEquals(row.get(String.class, 1), "1.0");
+        }
+    }
+
     @Test
     public void testRemove() {
         BpmnProcess process = createProcess("BPMN2-UserTask.bpmn2");
diff --git a/addons/common/persistence/rocksdb/src/main/java/org/kie/kogito/persistence/rocksdb/RocksDBProcessInstances.java b/addons/common/persistence/rocksdb/src/main/java/org/kie/kogito/persistence/rocksdb/RocksDBProcessInstances.java
index 0e8439e638..aa0bd88619 100644
--- a/addons/common/persistence/rocksdb/src/main/java/org/kie/kogito/persistence/rocksdb/RocksDBProcessInstances.java
+++ b/addons/common/persistence/rocksdb/src/main/java/org/kie/kogito/persistence/rocksdb/RocksDBProcessInstances.java
@@ -25,11 +25,11 @@ import java.util.function.Consumer;
 import java.util.stream.Stream;
 import java.util.stream.StreamSupport;
 
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerService;
 import org.kie.kogito.process.MutableProcessInstances;
 import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.ProcessInstanceReadMode;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerService;
 import org.rocksdb.RocksDB;
 import org.rocksdb.RocksDBException;
 import org.rocksdb.RocksIterator;
@@ -42,7 +42,7 @@ public class RocksDBProcessInstances<T> implements MutableProcessInstances<T> {
 
     public RocksDBProcessInstances(Process<T> process, RocksDB db) {
         this.process = process;
-        marshaller = ProcessInstanceMarshallerService.newBuilder().withDefaultObjectMarshallerStrategies().build();
+        marshaller = ProcessInstanceMarshallerService.newBuilder().withDefaultObjectMarshallerStrategies().withDefaultListeners().build();
         this.db = db;
     }
 
diff --git a/addons/common/persistence/rocksdb/src/test/java/org/kie/kogito/persistence/rocksdb/RockDBProcessInstancesTest.java b/addons/common/persistence/rocksdb/src/test/java/org/kie/kogito/persistence/rocksdb/RockDBProcessInstancesTest.java
index 8a8cf4ffa1..7f07fb32bc 100644
--- a/addons/common/persistence/rocksdb/src/test/java/org/kie/kogito/persistence/rocksdb/RockDBProcessInstancesTest.java
+++ b/addons/common/persistence/rocksdb/src/test/java/org/kie/kogito/persistence/rocksdb/RockDBProcessInstancesTest.java
@@ -39,6 +39,7 @@ import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.io.TempDir;
 import org.kie.kogito.process.MutableProcessInstances;
+import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.bpmn2.BpmnProcess;
 import org.kie.kogito.process.bpmn2.BpmnVariables;
@@ -130,7 +131,7 @@ class RockDBProcessInstancesTest {
         WorkflowProcessInstance instance = ((AbstractProcessInstance<?>) process.createInstance(BpmnVariables.create(Collections.singletonMap("test", "test")))).internalGetProcessInstance();
         logger.debug("Created instance {}", instance.getId());
         instance.setStartDate(new Date());
-        pi.create(instance.getId(), mockProcessInstance(instance));
+        pi.create(instance.getId(), mockProcessInstance(instance, process));
         assertThat(pi.exists(instance.getId())).isTrue();
         assertThat(pi.findById(instance.getId())).isNotEmpty();
         assertThat(pi.findById("non_existant")).isEmpty();
@@ -147,12 +148,13 @@ class RockDBProcessInstancesTest {
         logger.debug("Checked removed instance {}", instance.getId());
     }
 
-    private static AbstractProcessInstance<?> mockProcessInstance(WorkflowProcessInstance pi) {
+    private static AbstractProcessInstance<?> mockProcessInstance(WorkflowProcessInstance pi, Process process) {
         AbstractProcessInstance<?> mockPi = mock(AbstractProcessInstance.class);
         mockPi.setVersion(1L);
         when(mockPi.status()).thenReturn(ProcessInstance.STATE_ACTIVE);
         when(mockPi.internalGetProcessInstance()).thenReturn(pi);
         when(mockPi.id()).thenReturn(pi.getId());
+        when(mockPi.process()).thenReturn(process);
         return mockPi;
     }
 }
diff --git a/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java
index 4e4f420873..f2614a1640 100644
--- a/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java
+++ b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResource.java
@@ -30,12 +30,14 @@ import org.jbpm.ruleflow.core.Metadata;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.WorkflowProcess;
 import org.kie.kogito.Application;
+import org.kie.kogito.Model;
 import org.kie.kogito.auth.SecurityPolicy;
 import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
 import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessError;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.ProcessInstanceExecutionException;
+import org.kie.kogito.process.ProcessService;
 import org.kie.kogito.process.Processes;
 import org.kie.kogito.process.WorkItem;
 import org.kie.kogito.process.impl.AbstractProcess;
@@ -101,9 +103,9 @@ public abstract class BaseProcessInstanceManagementResource<T> implements Proces
             List<org.kie.api.definition.process.Node> nodes = ((KogitoWorkflowProcess) ((AbstractProcess<?>) process).get()).getNodesRecursively();
             List<Map<String, Object>> list = nodes.stream().map(n -> {
                 Map<String, Object> data = new HashMap<>();
-                data.put("id", n.getId());
+                data.put("id", n.getId().toExternalFormat());
                 data.put("uniqueId", ((Node) n).getUniqueId());
-                data.put("nodeDefinitionId", n.getMetaData().get(Metadata.UNIQUE_ID));
+                data.put("nodeDefinitionId", n.getUniqueId());
                 data.put("metadata", n.getMetaData());
                 data.put("type", n.getClass().getSimpleName());
                 data.put("name", n.getName());
@@ -127,6 +129,32 @@ public abstract class BaseProcessInstanceManagementResource<T> implements Proces
         });
     }
 
+    public T doMigrateInstance(ProcessService processService, String processId, ProcessMigrationSpec migrationSpec, String processInstanceId) {
+        try {
+            Process<? extends Model> process = processes.get().processById(processId);
+            processService.migrateProcessInstances(process, migrationSpec.getTargetProcessId(), migrationSpec.getTargetProcessVersion(), processInstanceId);
+            Map<String, Object> message = new HashMap<>();
+            message.put("message", processInstanceId + " instance migrated");
+            message.put("processInstanceId", processInstanceId);
+            return buildOkResponse(message);
+        } catch (Exception e) {
+            return badRequestResponse(e.getMessage());
+        }
+    }
+
+    public T doMigrateAllInstances(ProcessService processService, String processId, ProcessMigrationSpec migrationSpec) {
+        try {
+            Process<? extends Model> process = processes.get().processById(processId);
+            long numberOfProcessInstanceMigrated = processService.migrateAll(process, migrationSpec.getTargetProcessId(), migrationSpec.getTargetProcessVersion());
+            Map<String, Object> message = new HashMap<>();
+            message.put("message", "All intances migrated");
+            message.put("numberOfProcessInstanceMigrated", numberOfProcessInstanceMigrated);
+            return buildOkResponse(message);
+        } catch (Exception e) {
+            return badRequestResponse(e.getMessage());
+        }
+    }
+
     public T doGetWorkItemsInProcessInstance(String processId, String processInstanceId) {
 
         return executeOnProcessInstance(processId, processInstanceId, processInstance -> {
diff --git a/addons/common/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagement.java b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagement.java
index 7f6155dab7..7aa1a5210b 100644
--- a/addons/common/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagement.java
+++ b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/ProcessInstanceManagement.java
@@ -41,4 +41,9 @@ public interface ProcessInstanceManagement<T> {
     T cancelNodeInstanceId(String processId, String processInstanceId, String nodeInstanceId);
 
     T cancelProcessInstanceId(String processId, String processInstanceId);
+
+    T migrateAllInstances(String processId, ProcessMigrationSpec migrationSpec);
+
+    T migrateInstance(String processId, String processInstanceId, ProcessMigrationSpec migrationSpec);
+
 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationHandler.java b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/ProcessMigrationSpec.java
old mode 100755
new mode 100644
similarity index 60%
copy from jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationHandler.java
copy to addons/common/process-management/src/main/java/org/kie/kogito/process/management/ProcessMigrationSpec.java
index d88e439aad..37b6d19c05
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationHandler.java
+++ b/addons/common/process-management/src/main/java/org/kie/kogito/process/management/ProcessMigrationSpec.java
@@ -16,28 +16,28 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.jbpm.process.core.context.exception;
+package org.kie.kogito.process.management;
 
-import java.io.Serializable;
+public class ProcessMigrationSpec {
 
-import org.kie.api.definition.process.Node;
+    private String targetProcessId;
 
-public class CompensationHandler implements ExceptionHandler, Serializable {
+    private String targetProcessVersion;
 
-    private static final long serialVersionUID = 510l;
-
-    private Node node;
+    public String getTargetProcessId() {
+        return targetProcessId;
+    }
 
-    public Node getnode() {
-        return node;
+    public void setTargetProcessId(String targetProcessId) {
+        this.targetProcessId = targetProcessId;
     }
 
-    public void setNode(Node node) {
-        this.node = node;
+    public String getTargetProcessVersion() {
+        return targetProcessVersion;
     }
 
-    public String toString() {
-        return "Compensation Handler [" + this.node.getName() + ", " + this.node.getMetaData().get("UniqueId") + "]";
+    public void setTargetProcessVersion(String targetProcessVersion) {
+        this.targetProcessVersion = targetProcessVersion;
     }
 
 }
diff --git a/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java b/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java
index c20bd60055..d58a3f10df 100644
--- a/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java
+++ b/addons/common/process-management/src/test/java/org/kie/kogito/process/management/BaseProcessInstanceManagementResourceTest.java
@@ -24,6 +24,7 @@ import java.util.Map;
 import java.util.Optional;
 
 import org.jbpm.ruleflow.core.Metadata;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.WorkflowModelValidator;
 import org.jbpm.workflow.core.WorkflowProcess;
@@ -102,7 +103,7 @@ class BaseProcessInstanceManagementResourceTest {
 
     @BeforeEach
     void setUp() {
-        lenient().when(node.getId()).thenReturn(1l);
+        lenient().when(node.getId()).thenReturn(WorkflowElementIdentifierFactory.fromExternalFormat("one"));
         lenient().when(node.getName()).thenReturn("node");
         lenient().when(node.getUniqueId()).thenReturn(NODE_ID);
         lenient().when(node.getMetaData()).thenReturn(singletonMap(UNIQUE_ID, NODE_UNIQUE_ID));
@@ -200,6 +201,16 @@ class BaseProcessInstanceManagementResourceTest {
             public Object getProcessInfo(String processId) {
                 return null;
             }
+
+            @Override
+            public Object migrateAllInstances(String processId, ProcessMigrationSpec migrationSpec) {
+                return null;
+            }
+
+            @Override
+            public Object migrateInstance(String processId, String processInstanceId, ProcessMigrationSpec migrationSpec) {
+                return null;
+            }
         });
     }
 
@@ -227,7 +238,7 @@ class BaseProcessInstanceManagementResourceTest {
         verify(workflowProcess).getNodesRecursively();
 
         assertThat(response).isInstanceOf(List.class).asList().hasSize(1).element(0)
-                .hasFieldOrPropertyWithValue("id", node.getId())
+                .hasFieldOrPropertyWithValue("id", node.getId().toExternalFormat())
                 .hasFieldOrPropertyWithValue("name", node.getName())
                 .hasFieldOrPropertyWithValue("uniqueId", node.getUniqueId())
                 .hasFieldOrProperty("metadata")
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventSupport.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventSupport.java
index 01fffac0f4..89539f60d0 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventSupport.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/event/KogitoProcessEventSupport.java
@@ -71,6 +71,10 @@ public interface KogitoProcessEventSupport {
 
     void fireOnMessage(KogitoProcessInstance instance, KogitoNodeInstance nodeInstance, KieRuntime kruntime, String messageName, Object messageObject);
 
+    void fireOnError(KogitoProcessInstance instance, KogitoNodeInstance nodeInstance, KieRuntime kruntime, Exception exception);
+
+    void fireOnMigration(KogitoProcessInstance processInstance, KieRuntime runtime);
+
     // user tasks events
 
     void fireOneUserTaskStateChange(
@@ -164,5 +168,4 @@ public interface KogitoProcessEventSupport {
 
     void removeEventListener(KogitoProcessEventListener listener);
 
-    void fireOnError(KogitoProcessInstance instance, KogitoNodeInstance nodeInstance, KieRuntime kruntime, Exception exception);
 }
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoNode.java b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoNode.java
index f15769da3d..5fe95dee84 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoNode.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/internal/process/runtime/KogitoNode.java
@@ -25,5 +25,4 @@ public interface KogitoNode extends Node {
 
     NodeContainer getParentContainer();
 
-    String getUniqueId();
 }
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstances.java b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstances.java
index a0ce2e8c42..59529c8b53 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstances.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessInstances.java
@@ -33,6 +33,14 @@ public interface ProcessInstances<T> {
         return findByBusinessKey(id, ProcessInstanceReadMode.READ_ONLY);
     }
 
+    default void migrateProcessInstances(String targetProcessId, String targetProcessVersion, String... processIds) {
+        throw new UnsupportedOperationException();
+    }
+
+    default long migrateAll(String targetProcessId, String targetProcessVersion) {
+        throw new UnsupportedOperationException();
+    }
+
     default Optional<ProcessInstance<T>> findByBusinessKey(String id, ProcessInstanceReadMode mode) {
         return stream(mode).filter(pi -> id.equals(pi.businessKey())).findAny();
     }
@@ -42,4 +50,5 @@ public interface ProcessInstances<T> {
     default Stream<ProcessInstance<T>> stream() {
         return stream(ProcessInstanceReadMode.READ_ONLY);
     }
+
 }
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessService.java b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessService.java
index d46e32a308..5708c0c187 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessService.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/process/ProcessService.java
@@ -65,6 +65,10 @@ public interface ProcessService {
 
     <T extends MappableToModel<R>, R> Optional<R> findById(Process<T> process, String id);
 
+    <T> void migrateProcessInstances(Process<T> process, String targetProcessId, String targetProcessVersion, String... id) throws UnsupportedOperationException;
+
+    <T> long migrateAll(Process<T> process, String targetProcessId, String targetProcessVersion) throws UnsupportedOperationException;
+
     <T extends MappableToModel<R>, R> Optional<R> delete(Process<T> process, String id);
 
     <T extends MappableToModel<R>, R> Optional<R> update(Process<T> process, String id, T resource);
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/Processes.java b/api/kogito-api/src/main/java/org/kie/kogito/process/Processes.java
index 9b88793215..60a9e6a21c 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/process/Processes.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/process/Processes.java
@@ -19,12 +19,23 @@
 package org.kie.kogito.process;
 
 import java.util.Collection;
+import java.util.Optional;
 
 import org.kie.kogito.KogitoEngine;
 import org.kie.kogito.Model;
 
 public interface Processes extends KogitoEngine {
 
+    default Optional<Process<? extends Model>> processByProcessInstanceId(String processInstanceId) {
+        for (String processId : processIds()) {
+            Process<? extends Model> process = processById(processId);
+            if (process.instances().findById(processInstanceId, ProcessInstanceReadMode.READ_ONLY).isPresent()) {
+                return Optional.of(process);
+            }
+        }
+        return Optional.empty();
+    }
+
     Process<? extends Model> processById(String processId);
 
     Collection<String> processIds();
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItem.java b/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItem.java
index 7109b44ca8..11a85db4af 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItem.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/process/WorkItem.java
@@ -20,11 +20,13 @@ package org.kie.kogito.process;
 
 import java.util.Map;
 
+import org.kie.api.definition.process.WorkflowElementIdentifier;
+
 public interface WorkItem {
 
     String getId();
 
-    default String getNodeId() {
+    default WorkflowElementIdentifier getNodeId() {
         throw new UnsupportedOperationException();
     }
 
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkProcessEventListener.java b/api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkProcessEventListener.java
index 3428ebfbb9..089c96d07d 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkProcessEventListener.java
+++ b/api/kogito-api/src/main/java/org/kie/kogito/uow/events/UnitOfWorkProcessEventListener.java
@@ -22,6 +22,7 @@ import org.kie.api.event.process.ErrorEvent;
 import org.kie.api.event.process.MessageEvent;
 import org.kie.api.event.process.ProcessCompletedEvent;
 import org.kie.api.event.process.ProcessEvent;
+import org.kie.api.event.process.ProcessMigrationEvent;
 import org.kie.api.event.process.ProcessNodeLeftEvent;
 import org.kie.api.event.process.ProcessNodeTriggeredEvent;
 import org.kie.api.event.process.ProcessStartedEvent;
@@ -137,6 +138,11 @@ public class UnitOfWorkProcessEventListener extends DefaultKogitoProcessEventLis
         intercept(event);
     }
 
+    @Override
+    public void onMigration(ProcessMigrationEvent event) {
+        intercept(event);
+    }
+
     // user tasks
     @Override
     public void onUserTaskDeadline(UserTaskDeadlineEvent event) {
diff --git a/api/kogito-events-api/src/main/java/org/kie/kogito/event/process/ProcessInstanceStateEventBody.java b/api/kogito-events-api/src/main/java/org/kie/kogito/event/process/ProcessInstanceStateEventBody.java
index 6c7b7a80c3..b9bb4fd9ad 100644
--- a/api/kogito-events-api/src/main/java/org/kie/kogito/event/process/ProcessInstanceStateEventBody.java
+++ b/api/kogito-events-api/src/main/java/org/kie/kogito/event/process/ProcessInstanceStateEventBody.java
@@ -28,6 +28,7 @@ public class ProcessInstanceStateEventBody {
 
     public static final int EVENT_TYPE_STARTED = 1;
     public static final int EVENT_TYPE_ENDED = 2;
+    public static final int EVENT_TYPE_MIGRATED = 3;
 
     // common fields for events
     private Date eventDate;
diff --git a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/ProcessInstanceEventBatch.java b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/ProcessInstanceEventBatch.java
index 9d55dff1b9..dc10e841e9 100644
--- a/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/ProcessInstanceEventBatch.java
+++ b/api/kogito-events-core/src/main/java/org/kie/kogito/event/impl/ProcessInstanceEventBatch.java
@@ -30,6 +30,7 @@ import java.util.TreeSet;
 import org.kie.api.event.process.ErrorEvent;
 import org.kie.api.event.process.ProcessCompletedEvent;
 import org.kie.api.event.process.ProcessEvent;
+import org.kie.api.event.process.ProcessMigrationEvent;
 import org.kie.api.event.process.ProcessNodeEvent;
 import org.kie.api.event.process.ProcessNodeLeftEvent;
 import org.kie.api.event.process.ProcessNodeTriggeredEvent;
@@ -125,6 +126,8 @@ public class ProcessInstanceEventBatch implements EventBatch {
             handleUserTaskAttachmentEvent((UserTaskAttachmentEvent) event);
         } else if (event instanceof UserTaskCommentEvent) {
             handleUserTaskCommentEvent((UserTaskCommentEvent) event);
+        } else if (event instanceof ProcessMigrationEvent) {
+            handleProcessStateEvent((ProcessMigrationEvent) event);
         }
     }
 
@@ -179,7 +182,7 @@ public class ProcessInstanceEventBatch implements EventBatch {
 
         if (event.getNodeInstance() instanceof KogitoNodeInstance) {
             KogitoNodeInstance ni = (KogitoNodeInstance) event.getNodeInstance();
-            builder.nodeDefinitionId(ni.getNode().getNodeUniqueId())
+            builder.nodeDefinitionId(ni.getNode().getUniqueId())
                     .nodeInstanceId(ni.getId())
                     .nodeName(ni.getNodeName())
                     .nodeType(ni.getNode().getClass().getSimpleName())
@@ -236,7 +239,7 @@ public class ProcessInstanceEventBatch implements EventBatch {
                 .nodeName(event.getNodeInstance().getNodeName())
                 .nodeType(event.getNodeInstance().getNode().getClass().getSimpleName())
                 .nodeInstanceId(event.getNodeInstance().getId())
-                .nodeDefinitionId(event.getNodeInstance().getNode().getNodeUniqueId())
+                .nodeDefinitionId(event.getNodeInstance().getNode().getUniqueId())
                 .slaDueDate(nodeInstance.getSlaDueDate());
 
         if (eventType == ProcessInstanceNodeEventBody.EVENT_TYPE_ENTER) {
@@ -285,6 +288,10 @@ public class ProcessInstanceEventBatch implements EventBatch {
         processedEvents.add(toProcessInstanceStateEvent(event, ProcessInstanceStateEventBody.EVENT_TYPE_STARTED));
     }
 
+    private void handleProcessStateEvent(ProcessMigrationEvent event) {
+        processedEvents.add(toProcessInstanceStateEvent(event, ProcessInstanceStateEventBody.EVENT_TYPE_MIGRATED));
+    }
+
     private ProcessInstanceStateDataEvent toProcessInstanceStateEvent(ProcessEvent event, int eventType) {
         Map<String, Object> metadata = buildProcessMetadata((KogitoWorkflowProcessInstance) event.getProcessInstance());
 
diff --git a/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryJobService.java b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryJobService.java
index 7653c2eaa8..8a139b6c89 100644
--- a/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryJobService.java
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/jobs/impl/InMemoryJobService.java
@@ -21,6 +21,7 @@ package org.kie.kogito.services.jobs.impl;
 import java.time.Duration;
 import java.time.ZonedDateTime;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
@@ -160,10 +161,14 @@ public class InMemoryJobService implements JobsService, AutoCloseable {
         @Override
         public void run() {
             try {
+                Optional<Process<? extends Model>> process = processes.processByProcessInstanceId(processInstanceId);
+                if (process.isEmpty()) {
+                    LOGGER.info("Skipping Job {}. There is no process for pid {} ", id, processInstanceId);
+                    return;
+                }
                 LOGGER.info("Job {} started", id);
-                Process<? extends Model> process = processes.processById(processId);
                 limit--;
-                boolean executed = new TriggerJobCommand(processInstanceId, id, timerId, limit, process, unitOfWorkManager).execute();
+                boolean executed = new TriggerJobCommand(processInstanceId, id, timerId, limit, process.get(), unitOfWorkManager).execute();
                 if (limit == 0 || !executed) {
                     cancelJob(id, false);
                 }
diff --git a/api/kogito-services/src/main/java/org/kie/kogito/services/registry/ProcessDefinitionEventRegistry.java b/api/kogito-services/src/main/java/org/kie/kogito/services/registry/ProcessDefinitionEventRegistry.java
index e3cb1f01f9..c97ff7fdc5 100644
--- a/api/kogito-services/src/main/java/org/kie/kogito/services/registry/ProcessDefinitionEventRegistry.java
+++ b/api/kogito-services/src/main/java/org/kie/kogito/services/registry/ProcessDefinitionEventRegistry.java
@@ -124,7 +124,7 @@ public class ProcessDefinitionEventRegistry {
     private List<NodeDefinition> getNodesDefinitions(Process<?> p) {
         return p.findNodes(n -> true).stream()
                 .map(node -> NodeDefinition.builder()
-                        .setId(String.valueOf(node.getId()))
+                        .setId(node.getId().toExternalFormat())
                         .setName(node.getName())
                         .setType(node.getClass().getSimpleName())
                         .setUniqueId(node.getUniqueId())
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/AbstractNodeHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/AbstractNodeHandler.java
index f55df1f084..93d771f0ca 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/AbstractNodeHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/AbstractNodeHandler.java
@@ -28,7 +28,6 @@ import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.UUID;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Function;
 import java.util.regex.Matcher;
 
@@ -52,6 +51,7 @@ import org.jbpm.process.core.context.variable.VariableScope;
 import org.jbpm.process.core.datatype.DataTypeResolver;
 import org.jbpm.process.core.impl.DataTransformerRegistry;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.util.PatternConstants;
 import org.jbpm.workflow.core.DroolsAction;
 import org.jbpm.workflow.core.Node;
@@ -128,35 +128,15 @@ public abstract class AbstractNodeHandler extends BaseAbstractHandler implements
     public Object start(final String uri, final String localName, final Attributes attrs,
             final Parser parser) throws SAXException {
         parser.startElementBuilder(localName, attrs);
-        final Node node = createNode(attrs);
+
         String id = attrs.getValue("id");
-        node.setMetaData("UniqueId", id);
-        final String name = attrs.getValue("name");
+        String name = attrs.getValue("name");
+
+        Node node = createNode(attrs);
+        node.setId(WorkflowElementIdentifierFactory.fromExternalFormat(id));
         node.setName(name);
         node.setMetaData(INPUT_TYPES, new HashMap<String, String>());
         node.setMetaData(OUTPUT_TYPES, new HashMap<String, String>());
-        if ("true".equalsIgnoreCase(System.getProperty("jbpm.v5.id.strategy"))) {
-            try {
-                // remove starting _
-                id = id.substring(1);
-                // remove ids of parent nodes
-                id = id.substring(id.lastIndexOf("-") + 1);
-                node.setId(Integer.parseInt(id));
-            } catch (NumberFormatException e) {
-                // id is not in the expected format, generating a new one
-                long newId = 0;
-                NodeContainer nodeContainer = (NodeContainer) parser.getParent();
-                for (org.kie.api.definition.process.Node n : nodeContainer.getNodes()) {
-                    if (n.getId() > newId) {
-                        newId = n.getId();
-                    }
-                }
-                node.setId(++newId);
-            }
-        } else {
-            AtomicInteger idGen = (AtomicInteger) parser.getMetaData().get("idGen");
-            node.setId(idGen.getAndIncrement());
-        }
         return node;
     }
 
@@ -662,7 +642,6 @@ public abstract class AbstractNodeHandler extends BaseAbstractHandler implements
 
     protected NodeImpl decorateMultiInstanceSpecificationSubProcess(CompositeContextNode nodeTarget, MultiInstanceSpecification multiInstanceSpecification) {
         ForEachNode forEachNode = decorateMultiInstanceSpecification(nodeTarget, multiInstanceSpecification);
-        forEachNode.setMetaData("UniqueId", nodeTarget.getMetaData().get("UniqueId"));
         forEachNode.setMetaData(ProcessHandler.CONNECTIONS, nodeTarget.getMetaData(ProcessHandler.CONNECTIONS));
         forEachNode.setAutoComplete(nodeTarget.isAutoComplete());
         // nodeTarget/subprocess is invalidated by this. we get all the content and added to the for each nodes 
@@ -695,9 +674,8 @@ public abstract class AbstractNodeHandler extends BaseAbstractHandler implements
 
     protected NodeImpl decorateMultiInstanceSpecificationActivity(NodeImpl nodeTarget, MultiInstanceSpecification multiInstanceSpecification) {
         ForEachNode forEachNode = decorateMultiInstanceSpecification(nodeTarget, multiInstanceSpecification);
-        String uniqueId = (String) nodeTarget.getMetaData().get("UniqueId");
-        nodeTarget.getMetaData().put("UniqueId", uniqueId + ":1");
-        forEachNode.setMetaData("UniqueId", uniqueId);
+        String uniqueId = nodeTarget.getUniqueId();
+        nodeTarget.setId(WorkflowElementIdentifierFactory.fromExternalFormat(uniqueId + "_1"));
         forEachNode.addNode(nodeTarget);
         forEachNode.linkIncomingConnections(Node.CONNECTION_DEFAULT_TYPE, nodeTarget.getId(), Node.CONNECTION_DEFAULT_TYPE);
         forEachNode.linkOutgoingConnections(nodeTarget.getId(), Node.CONNECTION_DEFAULT_TYPE, Node.CONNECTION_DEFAULT_TYPE);
@@ -705,8 +683,7 @@ public abstract class AbstractNodeHandler extends BaseAbstractHandler implements
     }
 
     protected ForEachNode decorateMultiInstanceSpecification(NodeImpl nodeTarget, MultiInstanceSpecification multiInstanceSpecification) {
-        ForEachNode forEachNode = new ForEachNode();
-        forEachNode.setId(nodeTarget.getId());
+        ForEachNode forEachNode = new ForEachNode(nodeTarget.getId());
         forEachNode.setName(nodeTarget.getName());
         nodeTarget.setMetaData("hidden", true);
         forEachNode.setIoSpecification(nodeTarget.getIoSpecification());
@@ -888,7 +865,7 @@ public abstract class AbstractNodeHandler extends BaseAbstractHandler implements
                  * Alternatively, compensation can be triggered without waiting for its completion,
                  * by setting the throw compensation event's waitForCompletion attribute to false."
                  */
-                String nodeId = (String) node.getMetaData().get("UniqueId");
+                String nodeId = (String) node.getUniqueId();
                 String waitForCompletionString = ((Element) xmlNode).getAttribute("waitForCompletion");
                 boolean waitForCompletion = true;
                 if (waitForCompletionString != null && waitForCompletionString.length() > 0) {
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/BoundaryEventHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/BoundaryEventHandler.java
index 94734006f1..dbd45edfa2 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/BoundaryEventHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/BoundaryEventHandler.java
@@ -256,14 +256,14 @@ public class BoundaryEventHandler extends AbstractNodeHandler {
                 if (timeDuration != null && timeDuration.trim().length() > 0) {
                     List<EventFilter> eventFilters = new ArrayList<>();
                     EventTypeFilter eventFilter = new EventTypeFilter();
-                    eventFilter.setType("Timer-" + attachedTo + "-" + timeDuration + "-" + eventNode.getId());
+                    eventFilter.setType("Timer-" + attachedTo + "-" + timeDuration + "-" + eventNode.getId().toExternalFormat());
                     eventFilters.add(eventFilter);
                     eventNode.setEventFilters(eventFilters);
                     eventNode.setMetaData("TimeDuration", timeDuration);
                 } else if (timeCycle != null && timeCycle.trim().length() > 0) {
                     List<EventFilter> eventFilters = new ArrayList<>();
                     EventTypeFilter eventFilter = new EventTypeFilter();
-                    eventFilter.setType("Timer-" + attachedTo + "-" + timeCycle + "-" + eventNode.getId());
+                    eventFilter.setType("Timer-" + attachedTo + "-" + timeCycle + "-" + eventNode.getId().toExternalFormat());
                     eventFilters.add(eventFilter);
                     eventNode.setEventFilters(eventFilters);
                     eventNode.setMetaData("TimeCycle", timeCycle);
@@ -271,7 +271,7 @@ public class BoundaryEventHandler extends AbstractNodeHandler {
                 } else if (timeDate != null && timeDate.trim().length() > 0) {
                     List<EventFilter> eventFilters = new ArrayList<>();
                     EventTypeFilter eventFilter = new EventTypeFilter();
-                    eventFilter.setType("Timer-" + attachedTo + "-" + timeDate + "-" + eventNode.getId());
+                    eventFilter.setType("Timer-" + attachedTo + "-" + timeDate + "-" + eventNode.getId().toExternalFormat());
                     eventFilters.add(eventFilter);
                     eventNode.setEventFilters(eventFilters);
                     eventNode.setMetaData("TimeDate", timeDate);
@@ -295,7 +295,7 @@ public class BoundaryEventHandler extends AbstractNodeHandler {
                 if ("compensateEventDefinition".equalsIgnoreCase(el.getNodeName())) {
                     String activityRef = el.getAttribute("activityRef");
                     if (activityRef != null && activityRef.length() > 0) {
-                        logger.warn("activityRef value [" + activityRef + "] on Boundary Event '" + eventNode.getMetaData("UniqueId")
+                        logger.warn("activityRef value [" + activityRef + "] on Boundary Event '" + eventNode.getUniqueId()
                                 + "' ignored per the BPMN2 specification.");
                     }
                 }
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/EndEventHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/EndEventHandler.java
index 4e7ffe736f..2043d99ca5 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/EndEventHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/EndEventHandler.java
@@ -92,7 +92,6 @@ public class EndEventHandler extends AbstractNodeHandler {
                 faultNode.setId(node.getId());
                 faultNode.setName(node.getName());
                 faultNode.setTerminateParent(true);
-                faultNode.setMetaData("UniqueId", node.getMetaData().get("UniqueId"));
                 node = faultNode;
                 setThrowVariable(ioSpecification, node);
                 faultNode.setFaultVariable((String) node.getMetaData().get(Metadata.VARIABLE));
@@ -103,7 +102,6 @@ public class EndEventHandler extends AbstractNodeHandler {
                 FaultNode faultNode = new FaultNode();
                 faultNode.setId(node.getId());
                 faultNode.setName(node.getName());
-                faultNode.setMetaData("UniqueId", node.getMetaData().get("UniqueId"));
                 node = faultNode;
                 setThrowVariable(ioSpecification, node);
                 faultNode.setFaultVariable((String) node.getMetaData().get(Metadata.VARIABLE));
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/IntermediateCatchEventHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/IntermediateCatchEventHandler.java
index 0900362b5a..267a7fa462 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/IntermediateCatchEventHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/IntermediateCatchEventHandler.java
@@ -31,6 +31,7 @@ import org.jbpm.process.core.event.EventFilter;
 import org.jbpm.process.core.event.EventTypeFilter;
 import org.jbpm.process.core.timer.Timer;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.DataAssociation;
@@ -95,8 +96,6 @@ public class IntermediateCatchEventHandler extends AbstractNodeHandler {
                 TimerNode timerNode = new TimerNode();
                 timerNode.setId(node.getId());
                 timerNode.setName(node.getName());
-                timerNode.setMetaData("UniqueId",
-                        node.getMetaData().get("UniqueId"));
                 node = timerNode;
                 setCatchVariable(ioSpecification, node);
                 node.setMetaData(EVENT_TYPE, EVENT_TYPE_TIMER);
@@ -107,7 +106,6 @@ public class IntermediateCatchEventHandler extends AbstractNodeHandler {
                 StateNode stateNode = new StateNode();
                 stateNode.setId(node.getId());
                 stateNode.setName(node.getName());
-                stateNode.setMetaData("UniqueId", node.getMetaData().get("UniqueId"));
                 node = stateNode;
                 setCatchVariable(ioSpecification, node);
                 node.setMetaData(EVENT_TYPE, EVENT_TYPE_CONDITIONAL);
@@ -138,7 +136,7 @@ public class IntermediateCatchEventHandler extends AbstractNodeHandler {
         String name = linkAttr.getNamedItem("name").getNodeValue();
         String id = element.getAttribute("id");
 
-        node.setMetaData("UniqueId", id);
+        node.setId(WorkflowElementIdentifierFactory.fromExternalFormat(id));
         node.setMetaData(LINK_NAME, name);
 
         org.w3c.dom.Node xmlNode = xmlLinkNode.getFirstChild();
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/IntermediateThrowEventHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/IntermediateThrowEventHandler.java
index 92b2d9bcf8..033076b8ab 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/IntermediateThrowEventHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/IntermediateThrowEventHandler.java
@@ -33,6 +33,7 @@ import org.jbpm.process.instance.impl.actions.HandleMessageAction;
 import org.jbpm.process.instance.impl.actions.SignalProcessInstanceAction;
 import org.jbpm.ruleflow.core.Metadata;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.DataAssociation;
@@ -132,7 +133,7 @@ public class IntermediateThrowEventHandler extends AbstractNodeHandler {
         String name = linkAttr.getNamedItem("name").getNodeValue();
 
         String id = element.getAttribute("id");
-        node.setMetaData("UniqueId", id);
+        node.setId(WorkflowElementIdentifierFactory.fromExternalFormat(id));
         node.setMetaData(LINK_NAME, name);
 
         org.w3c.dom.Node xmlNode = xmlLinkNode.getFirstChild();
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/ProcessHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/ProcessHandler.java
index 43aa54fe76..836248b6df 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/ProcessHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/ProcessHandler.java
@@ -25,7 +25,6 @@ import java.util.HashSet;
 import java.util.LinkedHashSet;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
@@ -191,7 +190,6 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
         }
 
         // for unique id's of nodes, start with one to avoid returning wrong nodes for dynamic nodes
-        parser.getMetaData().put("idGen", new AtomicInteger(1));
         parser.getMetaData().put("CurrentProcessDefinition", process);
         process.getCorrelationManager().setClassLoader(parser.getClassLoader());
         return process;
@@ -368,7 +366,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
         Node node = null;
         // try looking for a node with same "UniqueId" (in metadata)
         for (Node containerNode : nodeContainer.getNodes()) {
-            if (nodeRef.equals(containerNode.getMetaData().get("UniqueId"))) {
+            if (nodeRef.equals(containerNode.getUniqueId())) {
                 node = containerNode;
                 break;
             }
@@ -410,7 +408,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
                         source, org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE,
                         target, org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE);
                 result.setMetaData("bendpoints", connection.getBendpoints());
-                result.setMetaData("UniqueId", connection.getId());
+                result.setMetaData(Metadata.UNIQUE_ID, connection.getId());
 
                 if ("true".equals(System.getProperty("jbpm.enable.multi.con"))) {
                     NodeImpl nodeImpl = (NodeImpl) source;
@@ -443,7 +441,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
                         // 
                         if (!(attachedNode instanceof StateBasedNode) && !type.equals("Compensation")) {
                             throw new ProcessParsingValidationException("Boundary events are supported only on StateBasedNode, found node: "
-                                    + attachedNode.getClass().getName() + " [" + attachedNode.getMetaData().get("UniqueId") + "]");
+                                    + attachedNode.getClass().getName() + " [" + attachedNode.getUniqueId() + "]");
                         }
 
                         if (type.startsWith("Escalation")) {
@@ -544,7 +542,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
         if (timeDuration != null) {
             timer.setDelay(timeDuration);
             timer.setTimeType(Timer.TIME_DURATION);
-            DroolsConsequenceAction consequenceAction = createJavaAction(new SignalProcessInstanceAction("Timer-" + attachedTo + "-" + timeDuration + "-" + node.getId(),
+            DroolsConsequenceAction consequenceAction = createJavaAction(new SignalProcessInstanceAction("Timer-" + attachedTo + "-" + timeDuration + "-" + node.getId().toExternalFormat(),
                     kcontext -> kcontext.getNodeInstance().getStringId(), SignalProcessInstanceAction.PROCESS_INSTANCE_SCOPE));
             compositeNode.addTimer(timer, consequenceAction);
         } else if (timeCycle != null) {
@@ -560,13 +558,14 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
             String finalTimeCycle = timeCycle;
 
             DroolsConsequenceAction action =
-                    createJavaAction(new SignalProcessInstanceAction("Timer-" + attachedTo + "-" + finalTimeCycle + (timer.getPeriod() == null ? "" : "###" + timer.getPeriod()) + "-" + node.getId(),
+                    createJavaAction(new SignalProcessInstanceAction(
+                            "Timer-" + attachedTo + "-" + finalTimeCycle + (timer.getPeriod() == null ? "" : "###" + timer.getPeriod()) + "-" + node.getId().toExternalFormat(),
                             kcontext -> kcontext.getNodeInstance().getStringId(), SignalProcessInstanceAction.PROCESS_INSTANCE_SCOPE));
             compositeNode.addTimer(timer, action);
         } else if (timeDate != null) {
             timer.setDate(timeDate);
             timer.setTimeType(Timer.TIME_DATE);
-            DroolsConsequenceAction action = createJavaAction(new SignalProcessInstanceAction("Timer-" + attachedTo + "-" + timeDate + "-" + node.getId(),
+            DroolsConsequenceAction action = createJavaAction(new SignalProcessInstanceAction("Timer-" + attachedTo + "-" + timeDate + "-" + node.getId().toExternalFormat(),
                     kcontext -> kcontext.getNodeInstance().getStringId(), SignalProcessInstanceAction.PROCESS_INSTANCE_SCOPE));
             compositeNode.addTimer(timer, action);
         }
@@ -678,7 +677,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
 
                     // connect boundary event to compensation activity
                     ConnectionImpl connection = new ConnectionImpl(sourceNode, org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE, targetNode, org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE);
-                    connection.setMetaData("UniqueId", null);
+                    connection.setMetaData(Metadata.UNIQUE_ID, null);
                     connection.setMetaData("hidden", true);
                     connection.setMetaData("association", true);
 
@@ -712,7 +711,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
         // - event node is boundary event node
         if (!(source instanceof BoundaryEventNode)) {
             throw new ProcessParsingValidationException("(Compensation) activities may only be associated with Boundary Event Nodes (not with" +
-                    source.getClass().getSimpleName() + " nodes [node " + ((String) source.getMetaData().get("UniqueId")) + "].");
+                    source.getClass().getSimpleName() + " nodes [node " + source.getUniqueId() + "].");
         }
         BoundaryEventNode eventNode = (BoundaryEventNode) source;
 
@@ -731,7 +730,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
         }
 
         if (!compensationCheckPassed) {
-            throw new ProcessParsingValidationException("An Event [" + ((String) eventNode.getMetaData("UniqueId"))
+            throw new ProcessParsingValidationException("An Event [" + eventNode.getUniqueId()
                     + "] linked from an association [" + association.getId()
                     + "] must be a (Boundary) Compensation Event.");
         }
@@ -751,13 +750,13 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
         String attachedToId = eventNode.getAttachedToNodeId();
         Node attachedToNode = null;
         for (Node node : eventNode.getParentContainer().getNodes()) {
-            if (attachedToId.equals(node.getMetaData().get("UniqueId"))) {
+            if (attachedToId.equals(node.getUniqueId())) {
                 attachedToNode = node;
                 break;
             }
         }
         if (attachedToNode == null) {
-            throw new ProcessParsingValidationException("Boundary Event [" + ((String) eventNode.getMetaData("UniqueId"))
+            throw new ProcessParsingValidationException("Boundary Event [" + eventNode.getUniqueId()
                     + "] is not attached to a node [" + attachedToId + "] that can be found.");
         }
         if (!(attachedToNode instanceof RuleSetNode
@@ -766,7 +765,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
                 || attachedToNode instanceof HumanTaskNode
                 || attachedToNode instanceof CompositeNode
                 || attachedToNode instanceof SubProcessNode)) {
-            throw new ProcessParsingValidationException("Compensation Boundary Event [" + ((String) eventNode.getMetaData("UniqueId"))
+            throw new ProcessParsingValidationException("Compensation Boundary Event [" + eventNode.getUniqueId()
                     + "] must be attached to a task or sub-process.");
         }
 
@@ -783,7 +782,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
         }
         if (!compensationCheckPassed) {
             throw new ProcessParsingValidationException("An Activity ["
-                    + ((String) ((NodeImpl) target).getMetaData("UniqueId")) +
+                    + ((NodeImpl) target).getUniqueId() +
                     "] associated with a Boundary Compensation Event must be a Task or a (non-Event) Sub-Process");
         }
 
@@ -808,9 +807,9 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
         }
         if (!compensationCheckPassed) {
             throw new ProcessParsingValidationException("A Compensation Activity ["
-                    + ((String) targetNode.getMetaData("UniqueId"))
+                    + targetNode.getUniqueId()
                     + "] may not have any outgoing connection ["
-                    + (String) outgoingConnection.getMetaData("UniqueId") + "]");
+                    + (String) outgoingConnection.getUniqueId() + "]");
         }
     }
 
@@ -908,7 +907,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
                                             if (isForCompensationObj == null) {
                                                 eventSubProcessNode.setMetaData("isForCompensation", true);
                                                 logger.warn("Overriding empty value of \"isForCompensation\" attribute on Event Sub-Process [{}] and setting it to true.",
-                                                        eventSubProcessNode.getMetaData("UniqueId"));
+                                                        eventSubProcessNode.getUniqueId());
                                             }
                                             String compensationHandlerId = "";
                                             if (subProcess instanceof RuleFlowProcess) {
@@ -918,7 +917,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
                                             }
                                             if (subProcess instanceof Node) {
                                                 parentSubProcess = ((KogitoNode) subProcess).getParentContainer();
-                                                compensationHandlerId = (String) ((CompositeNode) subProcess).getMetaData(Metadata.UNIQUE_ID);
+                                                compensationHandlerId = (String) ((CompositeNode) subProcess).getUniqueId();
                                             }
                                             // 2. The event filter (never fires, purely for dumping purposes) has already been added
 
@@ -949,7 +948,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
             } else if (node instanceof EventNode) {
                 final EventNode eventNode = (EventNode) node;
                 if (!(eventNode instanceof BoundaryEventNode) && eventNode.getDefaultIncomingConnections().isEmpty()) {
-                    throw new ProcessParsingValidationException("Event node '" + node.getName() + "' [" + node.getId() + "] has no incoming connection");
+                    throw new ProcessParsingValidationException("Event node '" + node.getName() + "' [" + node.getId().toExternalFormat() + "] has no incoming connection");
                 }
             }
         }
@@ -968,7 +967,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
     private void assignLanes(NodeContainer nodeContainer, Map<String, String> laneMapping) {
         for (Node node : nodeContainer.getNodes()) {
             String lane = null;
-            String uniqueId = (String) node.getMetaData().get("UniqueId");
+            String uniqueId = node.getUniqueId();
             if (uniqueId != null) {
                 lane = laneMapping.get(uniqueId);
             } else {
@@ -1078,7 +1077,7 @@ public class ProcessHandler extends BaseAbstractHandler implements Handler {
             if (nodeParent instanceof RuleFlowProcess) {
                 parentId = ((RuleFlowProcess) nodeParent).getId();
             } else {
-                parentId = (String) ((NodeImpl) nodeParent).getMetaData("UniqueId");
+                parentId = ((NodeImpl) nodeParent).getUniqueId();
             }
 
             String compensationEvent;
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/StartEventHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/StartEventHandler.java
index 94ff1a023f..7334cd4019 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/StartEventHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/StartEventHandler.java
@@ -257,7 +257,7 @@ public class StartEventHandler extends AbstractNodeHandler {
 
                 if (mapping != null) {
                     xmlDump.append(
-                            "      <dataOutput id=\"_" + startNode.getId() + "_Output\" name=\"" + nameMapping + "\" />" + EOL +
+                            "      <dataOutput id=\"_" + startNode.getId().toExternalFormat() + "_Output\" name=\"" + nameMapping + "\" />" + EOL +
                                     "      <dataOutputAssociation>" + EOL +
                                     "        <sourceRef>_" + startNode.getId() + "_Output</sourceRef>" + EOL +
                                     "        <targetRef>" + mapping + "</targetRef>" + EOL +
@@ -372,7 +372,7 @@ public class StartEventHandler extends AbstractNodeHandler {
 
                     EventTrigger trigger = new EventTrigger();
                     EventTypeFilter eventFilter = new EventTypeFilter();
-                    eventFilter.setType("Timer-" + ((EventSubProcessNode) parser.getParent()).getId());
+                    eventFilter.setType("Timer-" + ((EventSubProcessNode) parser.getParent()).getId().toExternalFormat());
                     trigger.addEventFilter(eventFilter);
                     String mapping = (String) startNode.getMetaData(TRIGGER_MAPPING);
                     if (mapping != null) {
@@ -388,7 +388,7 @@ public class StartEventHandler extends AbstractNodeHandler {
 
     protected void handleCompensationNode(final StartNode startNode, final org.w3c.dom.Node xmlNode) {
         if (startNode.isInterrupting()) {
-            logger.warn("Compensation Event Sub-Processes [" + startNode.getMetaData("UniqueId") + "] may not be specified as interrupting:" +
+            logger.warn("Compensation Event Sub-Processes [" + startNode.getUniqueId() + "] may not be specified as interrupting:" +
                     " overriding attribute and setting to not-interrupting.");
         }
         startNode.setInterrupting(false);
@@ -409,7 +409,7 @@ public class StartEventHandler extends AbstractNodeHandler {
          */
         String activityRef = ((Element) xmlNode).getAttribute("activityRef");
         if (activityRef != null && activityRef.length() > 0) {
-            logger.warn("activityRef value [" + activityRef + "] on Start Event '" + startNode.getMetaData("UniqueId")
+            logger.warn("activityRef value [" + activityRef + "] on Start Event '" + startNode.getUniqueId()
                     + "' ignored per the BPMN2 specification.");
         }
 
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/XmlBPMNProcessDumper.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/XmlBPMNProcessDumper.java
index fcd5d6c689..b41aa28b4d 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/XmlBPMNProcessDumper.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/XmlBPMNProcessDumper.java
@@ -867,15 +867,15 @@ public class XmlBPMNProcessDumper implements XmlProcessDumper {
     }
 
     public static String getUniqueNodeId(org.kie.api.definition.process.Node node) {
-        String result = (String) node.getMetaData().get("UniqueId");
+        String result = node.getUniqueId();
         if (result != null) {
             return result;
         }
-        result = node.getId() + "";
+        result = node.getId().toExternalFormat();
         NodeContainer nodeContainer = ((KogitoNode) node).getParentContainer();
         while (nodeContainer instanceof CompositeNode) {
             CompositeNode composite = (CompositeNode) nodeContainer;
-            result = composite.getId() + "-" + result;
+            result = composite.getId().toExternalFormat() + "-" + result;
             nodeContainer = composite.getParentContainer();
         }
         return "_" + result;
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/di/BPMNPlaneHandler.java b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/di/BPMNPlaneHandler.java
index 2a3990c288..b0a8c1c088 100755
--- a/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/di/BPMNPlaneHandler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/jbpm/bpmn2/xml/di/BPMNPlaneHandler.java
@@ -97,7 +97,7 @@ public class BPMNPlaneHandler extends BaseAbstractHandler implements Handler {
             return false;
         }
         for (org.kie.api.definition.process.Node node : nodes) {
-            String id = (String) node.getMetaData().get("UniqueId");
+            String id = node.getUniqueId();
             if (nodeInfo.getNodeRef().equals(id)) {
                 ((Node) node).setMetaData("x", nodeInfo.getX());
                 ((Node) node).setMetaData("y", nodeInfo.getY());
@@ -135,7 +135,7 @@ public class BPMNPlaneHandler extends BaseAbstractHandler implements Handler {
         for (org.kie.api.definition.process.Node node : nodes) {
             for (List<Connection> connections : node.getOutgoingConnections().values()) {
                 for (Connection connection : connections) {
-                    String id = (String) connection.getMetaData().get("UniqueId");
+                    String id = connection.getUniqueId();
                     if (id != null && id.equals(connectionInfo.getElementRef())) {
                         ((ConnectionImpl) connection).setMetaData(
                                 "bendpoints", connectionInfo.getBendpoints());
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java b/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java
index 71c6c6a3f9..e6a29b85c1 100644
--- a/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcess.java
@@ -56,6 +56,7 @@ public class BpmnProcess extends AbstractProcess<BpmnVariables> {
         this.process = process;
         application.get(BpmnProcesses.class).addProcess(this);
         this.application = application;
+        this.activate();
     }
 
     public Application getApplication() {
diff --git a/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcessCompiler.java b/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcessCompiler.java
index 2deb3eb301..4e38a9f011 100644
--- a/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcessCompiler.java
+++ b/jbpm/jbpm-bpmn2/src/main/java/org/kie/kogito/process/bpmn2/BpmnProcessCompiler.java
@@ -86,6 +86,7 @@ public class BpmnProcessCompiler {
                 }
             });
 
+            bpmnProcessesList.forEach(BpmnProcess::activate);
             return bpmnProcessesList;
         } catch (Exception e) {
             throw new BpmnProcessReaderException(e);
diff --git a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/ActivityTest.java b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/ActivityTest.java
index 55deecd856..047dd05930 100755
--- a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/ActivityTest.java
+++ b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/ActivityTest.java
@@ -65,6 +65,7 @@ import org.kie.api.command.ExecutableCommand;
 import org.kie.api.definition.process.Node;
 import org.kie.api.definition.process.NodeContainer;
 import org.kie.api.definition.process.Process;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.event.process.ProcessNodeTriggeredEvent;
 import org.kie.api.event.process.ProcessStartedEvent;
 import org.kie.api.event.process.ProcessVariableChangedEvent;
@@ -389,7 +390,7 @@ public class ActivityTest extends JbpmBpmn2TestCase {
             assertThat(nodeInstance).isNotNull().isInstanceOf(WorkItemNodeInstance.class);
             String deploymentId = ((WorkItemNodeInstance) nodeInstance).getWorkItem().getDeploymentId();
             String nodeInstanceId = ((WorkItemNodeInstance) nodeInstance).getWorkItem().getNodeInstanceStringId();
-            long nodeId = ((WorkItemNodeInstance) nodeInstance).getWorkItem().getNodeId();
+            WorkflowElementIdentifier nodeId = ((WorkItemNodeInstance) nodeInstance).getWorkItem().getNodeId();
 
             assertThat(deploymentId).isEqualTo(((InternalKogitoWorkItem) workItem).getDeploymentId());
             assertThat(nodeId).isEqualTo(((InternalKogitoWorkItem) workItem).getNodeId());
diff --git a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/EndEventTest.java b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/EndEventTest.java
index 06b0c2240e..e4d018cbbe 100755
--- a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/EndEventTest.java
+++ b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/EndEventTest.java
@@ -28,6 +28,7 @@ import org.jbpm.bpmn2.objects.TestWorkItemHandler;
 import org.jbpm.process.instance.impl.demo.SystemOutWorkItemHandler;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
 import org.kie.kogito.process.workitems.InternalKogitoWorkItem;
 
@@ -100,10 +101,10 @@ public class EndEventTest extends JbpmBpmn2TestCase {
         assertThat(workItem).isNotNull();
 
         String nodeInstanceId = workItem.getNodeInstanceStringId();
-        long nodeId = workItem.getNodeId();
+        WorkflowElementIdentifier nodeId = workItem.getNodeId();
         String deploymentId = workItem.getDeploymentId();
 
-        assertThat(nodeId).isPositive();
+        assertThat(nodeId).isNotNull();
         assertThat(nodeInstanceId).isNotNull();
         assertThat(deploymentId).isNull();
 
@@ -119,7 +120,7 @@ public class EndEventTest extends JbpmBpmn2TestCase {
         nodeInstanceId = workItem.getNodeInstanceStringId();
         nodeId = workItem.getNodeId();
 
-        assertThat(nodeId).isPositive();
+        assertThat(nodeId).isNotNull();
         assertThat(nodeInstanceId).isNotNull();
     }
 
diff --git a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/FlowTest.java b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/FlowTest.java
index 83fa005825..06eff6409b 100755
--- a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/FlowTest.java
+++ b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/FlowTest.java
@@ -46,6 +46,7 @@ import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Timeout;
 import org.kie.api.command.ExecutableCommand;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.event.process.ProcessNodeTriggeredEvent;
 import org.kie.api.event.process.ProcessStartedEvent;
 import org.kie.api.runtime.Context;
@@ -1292,7 +1293,7 @@ public class FlowTest extends JbpmBpmn2TestCase {
         System.setProperty("jbpm.enable.multi.con", "true");
         kruntime = createKogitoProcessRuntime("BPMN2-MultiConnEnabled.bpmn2");
 
-        final List<Long> list = new ArrayList<>();
+        final List<WorkflowElementIdentifier> list = new ArrayList<>();
         kruntime.getProcessEventManager().addEventListener(new DefaultKogitoProcessEventListener() {
             public void afterNodeTriggered(org.kie.api.event.process.ProcessNodeTriggeredEvent event) {
                 if ("Task2".equals(event.getNodeInstance().getNodeName())) {
diff --git a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java
index 7459f98cde..a0a5cd1a33 100755
--- a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java
+++ b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/IntermediateEventTest.java
@@ -42,6 +42,7 @@ import org.jbpm.test.util.ProcessCompletedCountDownProcessEventListener;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.kie.api.command.ExecutableCommand;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.event.process.ProcessNodeLeftEvent;
 import org.kie.api.event.process.ProcessNodeTriggeredEvent;
 import org.kie.api.event.process.ProcessStartedEvent;
@@ -998,9 +999,9 @@ public class IntermediateEventTest extends JbpmBpmn2TestCase {
         assertThat(workItem).isNotNull().isInstanceOf(KogitoWorkItem.class);
 
         String nodeInstanceId = ((InternalKogitoWorkItem) workItem).getNodeInstanceStringId();
-        long nodeId = ((InternalKogitoWorkItem) workItem).getNodeId();
+        WorkflowElementIdentifier nodeId = ((InternalKogitoWorkItem) workItem).getNodeId();
 
-        assertThat(nodeId).isPositive();
+        assertThat(nodeId).isNotNull();
         assertThat(nodeInstanceId).isNotNull();
     }
 
@@ -1018,10 +1019,10 @@ public class IntermediateEventTest extends JbpmBpmn2TestCase {
         assertThat(workItem).isNotNull().isInstanceOf(KogitoWorkItem.class);
 
         String nodeInstanceId = ((InternalKogitoWorkItem) workItem).getNodeInstanceStringId();
-        long nodeId = ((InternalKogitoWorkItem) workItem).getNodeId();
+        WorkflowElementIdentifier nodeId = ((InternalKogitoWorkItem) workItem).getNodeId();
         String deploymentId = ((InternalKogitoWorkItem) workItem).getDeploymentId();
 
-        assertThat(nodeId).isPositive();
+        assertThat(nodeId).isNotNull();
         assertThat(nodeInstanceId).isNotNull();
         assertThat(deploymentId).isNull();
     }
diff --git a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/ProcessFactoryTest.java b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/ProcessFactoryTest.java
index 36cdf24207..2a78663004 100755
--- a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/ProcessFactoryTest.java
+++ b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/ProcessFactoryTest.java
@@ -29,11 +29,13 @@ import org.jbpm.process.instance.LightProcessRuntime;
 import org.jbpm.process.instance.LightProcessRuntimeServiceProvider;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
 import org.jbpm.ruleflow.core.RuleFlowProcessFactory;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.test.util.NodeLeftCountDownProcessEventListener;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Timeout;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.event.process.ProcessNodeLeftEvent;
 import org.kie.api.io.Resource;
 import org.kie.api.runtime.process.ProcessInstance;
@@ -54,12 +56,17 @@ import static org.jbpm.ruleflow.core.Metadata.EVENT_TYPE_TIMER;
 import static org.jbpm.ruleflow.core.Metadata.HAS_ERROR_EVENT;
 import static org.jbpm.ruleflow.core.Metadata.TIME_CYCLE;
 import static org.jbpm.ruleflow.core.Metadata.TIME_DURATION;
-import static org.jbpm.ruleflow.core.Metadata.UNIQUE_ID;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.when;
 
 public class ProcessFactoryTest extends JbpmBpmn2TestCase {
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("two");
+    private static WorkflowElementIdentifier three = WorkflowElementIdentifierFactory.fromExternalFormat("three");
+    private static WorkflowElementIdentifier four = WorkflowElementIdentifierFactory.fromExternalFormat("four");
+    private static WorkflowElementIdentifier five = WorkflowElementIdentifierFactory.fromExternalFormat("five");
+
     @Test
     public void testProcessFactory() throws Exception {
         RuleFlowProcessFactory factory = RuleFlowProcessFactory.createProcess("org.jbpm.process");
@@ -68,20 +75,20 @@ public class ProcessFactoryTest extends JbpmBpmn2TestCase {
                 .name("My process")
                 .packageName("org.jbpm")
                 // nodes
-                .startNode(1)
+                .startNode(one)
                 .name("Start")
                 .done()
-                .actionNode(2)
+                .actionNode(two)
                 .name("Action")
                 .action("java",
                         "System.out.println(\"Action\");")
                 .done()
-                .endNode(3)
+                .endNode(three)
                 .name("End")
                 .done()
                 // connections
-                .connection(1, 2)
-                .connection(2, 3);
+                .connection(one, two)
+                .connection(two, three);
         RuleFlowProcess process = factory.validate().getProcess();
         Resource res = ResourceFactory.newByteArrayResource(XmlBPMNProcessDumper.INSTANCE.dump(process).getBytes());
         res.setSourcePath("/tmp/processFactory.bpmn2"); // source path or target path must be set to be added into kbase
@@ -97,35 +104,35 @@ public class ProcessFactoryTest extends JbpmBpmn2TestCase {
                 .name("My process")
                 .packageName("org.jbpm")
                 // nodes
-                .startNode(1)
+                .startNode(one)
                 .name("Start")
                 .done()
-                .compositeContextNode(2)
+                .compositeContextNode(two)
                 .name("SubProcess")
-                .startNode(1)
+                .startNode(one)
                 .name("SubProcess Start")
                 .done()
-                .actionNode(2)
+                .actionNode(two)
                 .name("SubProcess Action")
                 .action("java",
                         "System.out.println(\"SubProcess Action\");")
                 .done()
-                .endNode(3)
+                .endNode(three)
                 .name("SubProcess End")
                 .terminate(true)
                 .done()
-                .connection(1, 2)
-                .connection(2, 3)
+                .connection(one, two)
+                .connection(two, three)
                 .done()
-                .endNode(3)
+                .endNode(three)
                 .name("End")
                 .done()
                 // connections
-                .connection(1, 2)
-                .connection(2, 3);
+                .connection(one, two)
+                .connection(two, three);
         RuleFlowProcess process = factory.validate().getProcess();
 
-        assertThat(process.getNode(2).getName()).isEqualTo("SubProcess");
+        assertThat(process.getNode(two).getName()).isEqualTo("SubProcess");
 
         Resource res = ResourceFactory.newByteArrayResource(XmlBPMNProcessDumper.INSTANCE.dump(process).getBytes());
         res.setSourcePath("/tmp/processFactory.bpmn2"); // source path or target path must be set to be added into kbase
@@ -148,33 +155,33 @@ public class ProcessFactoryTest extends JbpmBpmn2TestCase {
                 .name("My process")
                 .packageName("org.jbpm")
                 // nodes
-                .startNode(1)
+                .startNode(one)
                 .name("Start")
                 .done()
-                .humanTaskNode(2)
+                .humanTaskNode(two)
                 .name("Task")
                 .actorId("john")
                 .taskName("MyTask")
                 .done()
-                .endNode(3)
+                .endNode(three)
                 .name("End1")
                 .terminate(false)
                 .done()
-                .boundaryEventNode(4)
+                .boundaryEventNode(four)
                 .name("BoundaryTimerEvent")
-                .attachedTo(2)
+                .attachedTo(two)
                 .metaData(TIME_CYCLE, timeCycle)
                 .metaData(CANCEL_ACTIVITY, false)
                 .eventType(EVENT_TYPE_TIMER, timeCycle)
                 .done()
-                .endNode(5)
+                .endNode(five)
                 .name("End2")
                 .terminate(false)
                 .done()
                 // connections
-                .connection(1, 2)
-                .connection(2, 3)
-                .connection(4, 5);
+                .connection(one, two)
+                .connection(two, three)
+                .connection(four, five);
         RuleFlowProcess process = factory.validate().getProcess();
 
         Resource res = ResourceFactory.newByteArrayResource(XmlBPMNProcessDumper.INSTANCE.dump(process).getBytes());
@@ -212,33 +219,33 @@ public class ProcessFactoryTest extends JbpmBpmn2TestCase {
                 .name("My process")
                 .packageName("org.jbpm")
                 // nodes
-                .startNode(1)
+                .startNode(one)
                 .name("Start")
                 .done()
-                .humanTaskNode(2)
+                .humanTaskNode(two)
                 .name("Task")
                 .actorId("john")
                 .taskName("MyTask")
                 .done()
-                .endNode(3)
+                .endNode(three)
                 .name("End1")
                 .terminate(false)
                 .done()
-                .boundaryEventNode(4)
+                .boundaryEventNode(four)
                 .name("BoundaryTimerEvent")
-                .attachedTo(2)
+                .attachedTo(two)
                 .metaData(TIME_DURATION, timeDuration)
                 .metaData(CANCEL_ACTIVITY, false)
                 .eventType(EVENT_TYPE_TIMER, timeDuration)
                 .done()
-                .endNode(5)
+                .endNode(five)
                 .name("End2")
                 .terminate(false)
                 .done()
                 // connections
-                .connection(1, 2)
-                .connection(2, 3)
-                .connection(4, 5);
+                .connection(one, two)
+                .connection(two, three)
+                .connection(four, five);
         RuleFlowProcess process = factory.validate().getProcess();
 
         Resource res = ResourceFactory.newByteArrayResource(XmlBPMNProcessDumper.INSTANCE.dump(process).getBytes());
@@ -288,25 +295,25 @@ public class ProcessFactoryTest extends JbpmBpmn2TestCase {
                 .packageName("org.jbpm")
                 .variable("eventData",
                         new org.jbpm.process.core.datatype.impl.type.StringDataType())
-                .startNode(1)
+                .startNode(one)
                 .name("Start")
                 .done()
-                .eventNode(2)
+                .eventNode(two)
                 .name("Event1")
                 .eventType("testEvent")
                 .variableName("eventData")
                 .done()
-                .actionNode(3)
+                .actionNode(three)
                 .name("simpleActionNode")
                 .action("java",
                         "System.out.println(\"test event action\");")
                 .done()
-                .endNode(4)
+                .endNode(four)
                 .name("End")
                 .done()
-                .connection(1, 2)
-                .connection(2, 3)
-                .connection(3, 4);
+                .connection(one, two)
+                .connection(two, three)
+                .connection(three, four);
         RuleFlowProcess process = factory.validate().getProcess();
 
         assertThat(process).isNotNull();
@@ -335,20 +342,20 @@ public class ProcessFactoryTest extends JbpmBpmn2TestCase {
         factory
                 .name("ActionNodeActionProcess")
                 .version("1")
-                .startNode(1)
+                .startNode(one)
                 .name("Start")
                 .done()
-                .endNode(3)
+                .endNode(three)
                 .name("End")
                 .done()
-                .actionNode(2)
+                .actionNode(two)
                 .name("printTextActionNode")
                 .action("java",
                         "System.out.println(\"test print\");",
                         true)
                 .done()
-                .connection(1, 2)
-                .connection(2, 3);
+                .connection(one, two)
+                .connection(two, three);
         RuleFlowProcess process = factory.validate().getProcess();
 
         assertThat(process).isNotNull();
@@ -379,36 +386,33 @@ public class ProcessFactoryTest extends JbpmBpmn2TestCase {
                 .name("My process")
                 .packageName("org.kie.kogito")
                 // nodes
-                .startNode(1)
+                .startNode(one)
                 .name(startNode)
-                .metaData(UNIQUE_ID, startNode)
                 .done()
-                .workItemNode(2)
+                .workItemNode(two)
                 .name(task)
                 .workName(task)
                 .done()
-                .endNode(3)
+                .endNode(three)
                 .name("EndOnSuccess")
                 .done()
-                .boundaryEventNode(4)
+                .boundaryEventNode(four)
                 .name(boundaryErrorEvent)
-                .attachedTo(2)
+                .attachedTo(two)
                 .metaData(ERROR_EVENT, errorCode)
                 .metaData(HAS_ERROR_EVENT, true)
                 .metaData(ERROR_STRUCTURE_REF, null)
                 .metaData("EventTpe", "error")
-                .metaData(UNIQUE_ID, boundaryErrorEvent)
                 .eventType("Error", errorCode)
                 .done()
-                .endNode(5)
+                .endNode(five)
                 .name(endOnError)
-                .metaData(UNIQUE_ID, endOnError)
                 .terminate(true)
                 .done()
                 // connections
-                .connection(1, 2)
-                .connection(2, 3)
-                .connection(4, 5);
+                .connection(one, two)
+                .connection(two, three)
+                .connection(four, five);
 
         final RuleFlowProcess process = factory.validate().getProcess();
 
diff --git a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/canonical/ActivityGenerationModelTest.java b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/canonical/ActivityGenerationModelTest.java
index 55eda0b45e..964b44c17d 100644
--- a/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/canonical/ActivityGenerationModelTest.java
+++ b/jbpm/jbpm-bpmn2/src/test/java/org/jbpm/bpmn2/canonical/ActivityGenerationModelTest.java
@@ -419,7 +419,7 @@ public class ActivityGenerationModelTest extends JbpmBpmn2TestCase {
         TestWorkItemHandler workItemHandler = new TestWorkItemHandler();
         Map<String, Object> params = new HashMap<String, Object>();
         params.put("s", "john");
-        Map<String, BpmnProcess> processes = createProcesses(classData, Collections.singletonMap("org.jbpm.bpmn2.objects.HelloService_hello_2_Handler", workItemHandler));
+        Map<String, BpmnProcess> processes = createProcesses(classData, Collections.singletonMap("org.jbpm.bpmn2.objects.HelloService_hello__2_Handler", workItemHandler));
         ProcessInstance<BpmnVariables> processInstance = processes.get("ServiceProcess").createInstance(BpmnVariables.create(params));
 
         processInstance.start();
@@ -459,7 +459,7 @@ public class ActivityGenerationModelTest extends JbpmBpmn2TestCase {
 
         assertThat(metaData.getWorkItems())
                 .hasSize(1)
-                .contains("org.jbpm.bpmn2.objects.HelloService_hello_2_Handler");
+                .contains("org.jbpm.bpmn2.objects.HelloService_hello__2_Handler");
     }
 
     @Test
@@ -503,7 +503,8 @@ public class ActivityGenerationModelTest extends JbpmBpmn2TestCase {
             }
         };
 
-        Map<String, BpmnProcess> processes = createProcesses(classData, Collections.singletonMap("org.jbpm.bpmn2.objects.HelloService_hello_3_Handler", workItemHandler));
+        Map<String, BpmnProcess> processes =
+                createProcesses(classData, Collections.singletonMap("org.jbpm.bpmn2.objects.HelloService_hello__F387A14A_BC7C_49AC_BAED_0CCFE1E114C6_Handler", workItemHandler));
         ProcessInstance i = UnitOfWorkExecutor.executeInUnitOfWork(process.getApplication().unitOfWorkManager(), () -> {
             ProcessInstance<BpmnVariables> processInstance = processes.get("AsyncProcess").createInstance(BpmnVariables.create(Collections.singletonMap("name", "Tiago")));
             processInstance.start();
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/ProcessBuilderImpl.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/ProcessBuilderImpl.java
index 3257a0db6f..77e6a2c39f 100755
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/ProcessBuilderImpl.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/ProcessBuilderImpl.java
@@ -386,7 +386,7 @@ public class ProcessBuilderImpl implements org.drools.compiler.compiler.ProcessB
             return "";
         } else {
             return "rule \"RuleFlowStateNode-" + process.getId() + "-" + state.getUniqueId() + "-" +
-                    key.getNodeId() + "-" + key.getToType() + "\" @Propagation(EAGER) \n" +
+                    key.getNodeId().toExternalFormat() + "-" + key.getToType() + "\" @Propagation(EAGER) \n" +
                     "      ruleflow-group \"DROOLS_SYSTEM\" \n" +
                     "    when \n" +
                     "      " + state.internalGetConstraint(key).getConstraint() + "\n" +
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractNodeVisitor.java
index fea1ecb867..c5cffb2e7b 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractNodeVisitor.java
@@ -48,7 +48,6 @@ import com.github.javaparser.ast.expr.ClassExpr;
 import com.github.javaparser.ast.expr.EnclosedExpr;
 import com.github.javaparser.ast.expr.Expression;
 import com.github.javaparser.ast.expr.LambdaExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.MethodCallExpr;
 import com.github.javaparser.ast.expr.NameExpr;
 import com.github.javaparser.ast.expr.NullLiteralExpr;
@@ -89,7 +88,7 @@ public abstract class AbstractNodeVisitor<T extends Node> extends AbstractVisito
     }
 
     protected String getNodeId(T node) {
-        return getNodeKey() + node.getId();
+        return getNodeKey() + node.getId().toSanitizeString();
     }
 
     public void visitNode(String factoryField, T node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
@@ -272,9 +271,9 @@ public abstract class AbstractNodeVisitor<T extends Node> extends AbstractVisito
             return;
         }
 
-        body.addStatement(getFactoryMethod(factoryField, "connection", new LongLiteralExpr(connection.getFrom().getId()),
-                new LongLiteralExpr(connection.getTo().getId()),
-                new StringLiteralExpr(getOrDefault((String) connection.getMetaData().get("UniqueId"), ""))));
+        body.addStatement(getFactoryMethod(factoryField, "connection", getWorkflowElementConstructor(connection.getFrom().getId()),
+                getWorkflowElementConstructor(connection.getTo().getId()),
+                new StringLiteralExpr(getOrDefault(connection.getUniqueId(), ""))));
     }
 
     protected static LambdaExpr createLambdaExpr(String consequence, VariableScope scope) {
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractVisitor.java
index 3f206bc417..5c59c3eb93 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/AbstractVisitor.java
@@ -28,17 +28,23 @@ import org.jbpm.process.core.context.exception.CompensationScope;
 import org.jbpm.process.core.context.variable.Variable;
 import org.jbpm.process.core.context.variable.VariableScope;
 import org.jbpm.process.core.datatype.DataTypeResolver;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.kie.api.definition.process.NodeContainer;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoNode;
 import org.kie.kogito.internal.utils.KogitoTags;
 
+import com.github.javaparser.ast.NodeList;
 import com.github.javaparser.ast.expr.ClassExpr;
 import com.github.javaparser.ast.expr.Expression;
 import com.github.javaparser.ast.expr.MethodCallExpr;
 import com.github.javaparser.ast.expr.NameExpr;
 import com.github.javaparser.ast.expr.NullLiteralExpr;
 import com.github.javaparser.ast.expr.StringLiteralExpr;
+import com.github.javaparser.ast.expr.TypeExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
+import com.github.javaparser.ast.type.ClassOrInterfaceType;
+import com.github.javaparser.ast.type.Type;
 
 import static com.github.javaparser.StaticJavaParser.parseClassOrInterfaceType;
 import static org.jbpm.ruleflow.core.RuleFlowProcessFactory.METHOD_ADD_COMPENSATION_CONTEXT;
@@ -50,6 +56,12 @@ public abstract class AbstractVisitor {
     protected static final String FACTORY_FIELD_NAME = "factory";
     protected static final String KCONTEXT_VAR = "kcontext";
 
+    protected MethodCallExpr getWorkflowElementConstructor(WorkflowElementIdentifier identifier) {
+        Type type = new ClassOrInterfaceType().setName(WorkflowElementIdentifierFactory.class.getName());
+        MethodCallExpr identifierConstructor = new MethodCallExpr(new TypeExpr(type), "fromExternalFormat", NodeList.nodeList(new StringLiteralExpr(identifier.toExternalFormat())));
+        return identifierConstructor;
+    }
+
     protected MethodCallExpr getFactoryMethod(String object, String methodName, Expression... args) {
         MethodCallExpr variableMethod = new MethodCallExpr(new NameExpr(object), methodName);
 
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ActionNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ActionNodeVisitor.java
index 54e6be8b12..ef04ad0a73 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ActionNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ActionNodeVisitor.java
@@ -34,7 +34,6 @@ import org.jbpm.workflow.core.node.ActionNode;
 import com.github.javaparser.StaticJavaParser;
 import com.github.javaparser.ast.body.Parameter;
 import com.github.javaparser.ast.expr.LambdaExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 import com.github.javaparser.ast.type.UnknownType;
 
@@ -58,7 +57,7 @@ public class ActionNodeVisitor extends AbstractNodeVisitor<ActionNode> {
 
     @Override
     public void visitNode(String factoryField, ActionNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, ActionNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, ActionNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "Script"));
 
         Optional<ExpressionSupplier> supplierAction = getAction(node, ExpressionSupplier.class);
@@ -80,7 +79,7 @@ public class ActionNodeVisitor extends AbstractNodeVisitor<ActionNode> {
         } else if (node.getAction() instanceof DroolsConsequenceAction) {
             String consequence = getActionConsequence(node.getAction());
             if (consequence == null || consequence.trim().isEmpty()) {
-                throw new IllegalStateException("Action node " + node.getId() + " name " + node.getName() + " has no action defined");
+                throw new IllegalStateException("Action node " + node.getId().toExternalFormat() + " name " + node.getName() + " has no action defined");
             }
             BlockStmt actionBody = new BlockStmt();
             List<Variable> variables = variableScope.getVariables();
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/BoundaryEventNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/BoundaryEventNodeVisitor.java
index 1e149b419d..e42e95c719 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/BoundaryEventNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/BoundaryEventNodeVisitor.java
@@ -23,7 +23,6 @@ import org.jbpm.process.core.context.variable.VariableScope;
 import org.jbpm.ruleflow.core.factory.BoundaryEventNodeFactory;
 import org.jbpm.workflow.core.node.BoundaryEventNode;
 
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.StringLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
@@ -47,7 +46,7 @@ public class BoundaryEventNodeVisitor extends AbstractNodeVisitor<BoundaryEventN
 
     @Override
     public void visitNode(String factoryField, BoundaryEventNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, BoundaryEventNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, BoundaryEventNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "BoundaryEvent"))
                 .addStatement(getFactoryMethod(getNodeId(node), METHOD_EVENT_TYPE, new StringLiteralExpr(node.getType())))
                 .addStatement(getFactoryMethod(getNodeId(node), METHOD_ATTACHED_TO, new StringLiteralExpr(node.getAttachedToNodeId())))
@@ -74,4 +73,4 @@ public class BoundaryEventNodeVisitor extends AbstractNodeVisitor<BoundaryEventN
         visitMetaData(node.getMetaData(), body, getNodeId(node));
         body.addStatement(getDoneMethod(getNodeId(node)));
     }
-}
\ No newline at end of file
+}
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/CatchLinkNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/CatchLinkNodeVisitor.java
index a2f5247b93..04b521c972 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/CatchLinkNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/CatchLinkNodeVisitor.java
@@ -22,7 +22,6 @@ import org.jbpm.process.core.context.variable.VariableScope;
 import org.jbpm.ruleflow.core.factory.CatchLinkNodeFactory;
 import org.jbpm.workflow.core.node.CatchLinkNode;
 
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
 public class CatchLinkNodeVisitor extends AbstractNodeVisitor<CatchLinkNode> {
@@ -40,7 +39,7 @@ public class CatchLinkNodeVisitor extends AbstractNodeVisitor<CatchLinkNode> {
             ProcessMetaData metadata) {
         String nodeId = getNodeId(node);
         body.addStatement(getAssignedFactoryMethod(factoryField, CatchLinkNodeFactory.class, nodeId,
-                getNodeKey(), new LongLiteralExpr(node.getId())));
+                getNodeKey(), getWorkflowElementConstructor(node.getId())));
         body.addStatement(getDoneMethod(nodeId));
     }
 
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/CompositeContextNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/CompositeContextNodeVisitor.java
index 688570b95e..12d7946aef 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/CompositeContextNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/CompositeContextNodeVisitor.java
@@ -28,7 +28,6 @@ import org.jbpm.workflow.core.node.CompositeContextNode;
 import org.kie.api.definition.process.Node;
 
 import com.github.javaparser.ast.expr.BooleanLiteralExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.MethodCallExpr;
 import com.github.javaparser.ast.expr.StringLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
@@ -58,7 +57,7 @@ public class CompositeContextNodeVisitor<T extends CompositeContextNode> extends
 
     @Override
     public void visitNode(String factoryField, T node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, factoryClass(), getNodeId(node), factoryMethod(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, factoryClass(), getNodeId(node), factoryMethod(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, getDefaultName()));
         visitMetaData(node.getMetaData(), body, getNodeId(node));
         VariableScope variableScopeNode = (VariableScope) node.getDefaultContext(VariableScope.VARIABLE_SCOPE);
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EndNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EndNodeVisitor.java
index 291eae41a1..a875f862ef 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EndNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EndNodeVisitor.java
@@ -35,7 +35,6 @@ import org.jbpm.workflow.core.node.EndNode;
 
 import com.github.javaparser.ast.expr.BooleanLiteralExpr;
 import com.github.javaparser.ast.expr.LambdaExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
 import static org.jbpm.ruleflow.core.Metadata.CUSTOM_SCOPE;
@@ -57,7 +56,7 @@ public class EndNodeVisitor extends AbstractNodeVisitor<EndNode> {
 
     @Override
     public void visitNode(String factoryField, EndNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, EndNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, EndNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "End"))
                 .addStatement(getFactoryMethod(getNodeId(node), METHOD_TERMINATE, new BooleanLiteralExpr(node.isTerminate())));
 
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EventNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EventNodeVisitor.java
index 65ee26fa14..17db88370f 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EventNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/EventNodeVisitor.java
@@ -25,7 +25,6 @@ import org.jbpm.process.core.context.variable.VariableScope;
 import org.jbpm.ruleflow.core.factory.EventNodeFactory;
 import org.jbpm.workflow.core.node.EventNode;
 
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.StringLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
@@ -45,7 +44,7 @@ public class EventNodeVisitor extends AbstractNodeVisitor<EventNode> {
 
     @Override
     public void visitNode(String factoryField, EventNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, EventNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, EventNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "Event"))
                 .addStatement(getFactoryMethod(getNodeId(node), METHOD_EVENT_TYPE, new StringLiteralExpr(node.getType())));
 
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/FaultNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/FaultNodeVisitor.java
index 64fbbb3667..e7de77ff57 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/FaultNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/FaultNodeVisitor.java
@@ -23,7 +23,6 @@ import org.jbpm.ruleflow.core.factory.FaultNodeFactory;
 import org.jbpm.workflow.core.node.FaultNode;
 
 import com.github.javaparser.ast.expr.BooleanLiteralExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.StringLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
@@ -40,7 +39,7 @@ public class FaultNodeVisitor extends AbstractNodeVisitor<FaultNode> {
 
     @Override
     public void visitNode(String factoryField, FaultNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, FaultNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, FaultNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "Error"));
         if (node.getFaultVariable() != null) {
             body.addStatement(getFactoryMethod(getNodeId(node), METHOD_FAULT_VARIABLE, new StringLiteralExpr(node.getFaultVariable())));
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ForEachNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ForEachNodeVisitor.java
index 422c2dac03..bb9bf76a41 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ForEachNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ForEachNodeVisitor.java
@@ -31,7 +31,6 @@ import org.jbpm.workflow.core.node.CompositeNode.NodeAndType;
 import org.jbpm.workflow.core.node.ForEachNode;
 
 import com.github.javaparser.ast.expr.BooleanLiteralExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.StringLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
@@ -57,7 +56,7 @@ public class ForEachNodeVisitor extends AbstractCompositeNodeVisitor<ForEachNode
 
     @Override
     public void visitNode(String factoryField, ForEachNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, ForEachNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, ForEachNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "ForEach"));
 
         body.addStatement(getFactoryMethod(getNodeId(node), METHOD_SEQUENTIAL, new BooleanLiteralExpr(node.isSequential())));
@@ -107,13 +106,13 @@ public class ForEachNodeVisitor extends AbstractCompositeNodeVisitor<ForEachNode
 
         NodeAndType incomingNode = node.getLinkedIncomingNode(Node.CONNECTION_DEFAULT_TYPE);
         if (incomingNode != null) {
-            body.addStatement(getFactoryMethod(getNodeId(node), METHOD_LINK_INCOMING_CONNECTIONS, new LongLiteralExpr(incomingNode.getNodeId())));
-            filterNodes.removeIf(n -> n.getId() == incomingNode.getNodeId());
+            body.addStatement(getFactoryMethod(getNodeId(node), METHOD_LINK_INCOMING_CONNECTIONS, getWorkflowElementConstructor(incomingNode.getNodeId())));
+            filterNodes.removeIf(n -> n.getId().equals(incomingNode.getNodeId()));
         }
         NodeAndType outgoingNode = node.getLinkedOutgoingNode(Node.CONNECTION_DEFAULT_TYPE);
         if (outgoingNode != null) {
-            body.addStatement(getFactoryMethod(getNodeId(node), METHOD_LINK_OUTGOING_CONNECTIONS, new LongLiteralExpr(outgoingNode.getNodeId())));
-            filterNodes.removeIf(n -> n.getId() == outgoingNode.getNodeId());
+            body.addStatement(getFactoryMethod(getNodeId(node), METHOD_LINK_OUTGOING_CONNECTIONS, getWorkflowElementConstructor(outgoingNode.getNodeId())));
+            filterNodes.removeIf(n -> n.getId().equals(outgoingNode.getNodeId()));
         }
 
         visitConnections(getNodeId(node), filterNodes.toArray(new Node[filterNodes.size()]), body);
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/HumanTaskNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/HumanTaskNodeVisitor.java
index 6fa98941b6..2c2849dc00 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/HumanTaskNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/HumanTaskNodeVisitor.java
@@ -23,7 +23,6 @@ import org.jbpm.process.core.context.variable.VariableScope;
 import org.jbpm.ruleflow.core.factory.HumanTaskNodeFactory;
 import org.jbpm.workflow.core.node.HumanTaskNode;
 
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
 public class HumanTaskNodeVisitor extends WorkItemNodeVisitor<HumanTaskNode> {
@@ -41,7 +40,7 @@ public class HumanTaskNodeVisitor extends WorkItemNodeVisitor<HumanTaskNode> {
     public void visitNode(String factoryField, HumanTaskNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
         Work work = node.getWork();
 
-        body.addStatement(getAssignedFactoryMethod(factoryField, HumanTaskNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, HumanTaskNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "Task"));
 
         addWorkItemParameters(work, body, getNodeId(node));
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/JoinNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/JoinNodeVisitor.java
index c88c0d2ab1..c4a6001162 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/JoinNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/JoinNodeVisitor.java
@@ -23,7 +23,6 @@ import org.jbpm.ruleflow.core.factory.JoinFactory;
 import org.jbpm.workflow.core.node.Join;
 
 import com.github.javaparser.ast.expr.IntegerLiteralExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
 import static org.jbpm.ruleflow.core.factory.JoinFactory.METHOD_TYPE;
@@ -37,7 +36,7 @@ public class JoinNodeVisitor extends AbstractNodeVisitor<Join> {
 
     @Override
     public void visitNode(String factoryField, Join node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, JoinFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())));
+        body.addStatement(getAssignedFactoryMethod(factoryField, JoinFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())));
         body.addStatement(getNameMethod(node, "Join"));
         body.addStatement(getFactoryMethod(getNodeId(node), METHOD_TYPE, new IntegerLiteralExpr(node.getType())));
 
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/LambdaSubProcessNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/LambdaSubProcessNodeVisitor.java
index bd56d6e284..2142580b41 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/LambdaSubProcessNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/LambdaSubProcessNodeVisitor.java
@@ -38,7 +38,6 @@ import com.github.javaparser.ast.expr.BooleanLiteralExpr;
 import com.github.javaparser.ast.expr.CastExpr;
 import com.github.javaparser.ast.expr.Expression;
 import com.github.javaparser.ast.expr.LambdaExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.MethodCallExpr;
 import com.github.javaparser.ast.expr.NameExpr;
 import com.github.javaparser.ast.expr.ObjectCreationExpr;
@@ -78,7 +77,7 @@ public class LambdaSubProcessNodeVisitor extends AbstractNodeVisitor<SubProcessN
                 .notEmpty("subProcessId", subProcessId)
                 .validate();
 
-        body.addStatement(getAssignedFactoryMethod(factoryField, SubProcessNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, SubProcessNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "Call Activity"))
                 .addStatement(getFactoryMethod(getNodeId(node), METHOD_PROCESS_ID, new StringLiteralExpr(subProcessId)))
                 .addStatement(getFactoryMethod(getNodeId(node), METHOD_PROCESS_NAME, new StringLiteralExpr(getOrDefault(node.getProcessName(), ""))))
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/MilestoneNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/MilestoneNodeVisitor.java
index 70c7eebd8b..edab9d4d1e 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/MilestoneNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/MilestoneNodeVisitor.java
@@ -22,7 +22,6 @@ import org.jbpm.process.core.context.variable.VariableScope;
 import org.jbpm.ruleflow.core.factory.MilestoneNodeFactory;
 import org.jbpm.workflow.core.node.MilestoneNode;
 
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.MethodCallExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
@@ -37,7 +36,7 @@ public class MilestoneNodeVisitor extends AbstractNodeVisitor<MilestoneNode> {
 
     @Override
     public void visitNode(String factoryField, MilestoneNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, MilestoneNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, MilestoneNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "Milestone"));
         if (node.getCondition() != null && !node.getCondition().trim().isEmpty()) {
             body.addStatement(getConditionStatement(node, variableScope));
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ProcessVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ProcessVisitor.java
index ec9b667b91..355ab77aa4 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ProcessVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ProcessVisitor.java
@@ -71,7 +71,6 @@ import com.github.javaparser.ast.body.MethodDeclaration;
 import com.github.javaparser.ast.expr.AssignExpr;
 import com.github.javaparser.ast.expr.BooleanLiteralExpr;
 import com.github.javaparser.ast.expr.Expression;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.MethodCallExpr;
 import com.github.javaparser.ast.expr.NameExpr;
 import com.github.javaparser.ast.expr.NullLiteralExpr;
@@ -82,7 +81,6 @@ import com.github.javaparser.ast.stmt.ReturnStmt;
 import com.github.javaparser.ast.type.ClassOrInterfaceType;
 
 import static org.jbpm.ruleflow.core.Metadata.ASSOCIATION;
-import static org.jbpm.ruleflow.core.Metadata.UNIQUE_ID;
 import static org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory.METHOD_ASSOCIATION;
 import static org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory.METHOD_CONNECTION;
 import static org.jbpm.ruleflow.core.RuleFlowProcessFactory.METHOD_DYNAMIC;
@@ -263,9 +261,9 @@ public class ProcessVisitor extends AbstractVisitor {
             method = METHOD_ASSOCIATION;
         }
         body.addStatement(getFactoryMethod(FACTORY_FIELD_NAME, method,
-                new LongLiteralExpr(connection.getFrom().getId()),
-                new LongLiteralExpr(connection.getTo().getId()),
-                new StringLiteralExpr(getOrDefault((String) connection.getMetaData().get(UNIQUE_ID), ""))));
+                getWorkflowElementConstructor(connection.getFrom().getId()),
+                getWorkflowElementConstructor(connection.getTo().getId()),
+                new StringLiteralExpr(getOrDefault(connection.getUniqueId(), ""))));
     }
 
     private void visitCompensationScope(Process process, BlockStmt body) {
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/RuleSetNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/RuleSetNodeVisitor.java
index 7320f10a33..5028ee6b96 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/RuleSetNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/RuleSetNodeVisitor.java
@@ -47,7 +47,6 @@ import com.github.javaparser.ast.expr.AssignExpr;
 import com.github.javaparser.ast.expr.ClassExpr;
 import com.github.javaparser.ast.expr.Expression;
 import com.github.javaparser.ast.expr.LambdaExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.MethodCallExpr;
 import com.github.javaparser.ast.expr.NameExpr;
 import com.github.javaparser.ast.expr.NullLiteralExpr;
@@ -82,7 +81,7 @@ public class RuleSetNodeVisitor extends AbstractNodeVisitor<RuleSetNode> {
     public void visitNode(String factoryField, RuleSetNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
         String nodeName = node.getName();
 
-        body.addStatement(getAssignedFactoryMethod(factoryField, RuleSetNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, RuleSetNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "Rule"));
 
         RuleType ruleType = node.getRuleType();
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/SplitNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/SplitNodeVisitor.java
index 4eebbc0a16..2fcdad5cdf 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/SplitNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/SplitNodeVisitor.java
@@ -37,7 +37,6 @@ import com.github.javaparser.ast.expr.BooleanLiteralExpr;
 import com.github.javaparser.ast.expr.Expression;
 import com.github.javaparser.ast.expr.IntegerLiteralExpr;
 import com.github.javaparser.ast.expr.LambdaExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.ObjectCreationExpr;
 import com.github.javaparser.ast.expr.StringLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
@@ -55,7 +54,7 @@ public class SplitNodeVisitor extends AbstractNodeVisitor<Split> {
 
     @Override
     public void visitNode(String factoryField, Split node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, SplitFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, SplitFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "Split"))
                 .addStatement(getFactoryMethod(getNodeId(node), METHOD_TYPE, new IntegerLiteralExpr(node.getType())));
 
@@ -87,7 +86,7 @@ public class SplitNodeVisitor extends AbstractNodeVisitor<Split> {
                                 returnValueEvaluator = lambda;
                             }
                             body.addStatement(getFactoryMethod(getNodeId(node), METHOD_CONSTRAINT,
-                                    new LongLiteralExpr(entry.getKey().getNodeId()),
+                                    getWorkflowElementConstructor(entry.getKey().getNodeId()),
                                     new StringLiteralExpr(getOrDefault(entry.getKey().getConnectionId(), "")),
                                     new StringLiteralExpr(entry.getKey().getToType()),
                                     new StringLiteralExpr(constraint.getDialect()),
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StartNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StartNodeVisitor.java
index 4893d250cf..de5c641a6f 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StartNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StartNodeVisitor.java
@@ -28,7 +28,6 @@ import org.jbpm.workflow.core.node.StartNode;
 
 import com.github.javaparser.ast.expr.BooleanLiteralExpr;
 import com.github.javaparser.ast.expr.IntegerLiteralExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.StringLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
@@ -50,7 +49,7 @@ public class StartNodeVisitor extends AbstractNodeVisitor<StartNode> {
 
     @Override
     public void visitNode(String factoryField, StartNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, StartNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, StartNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "Start"))
                 .addStatement(getFactoryMethod(getNodeId(node), METHOD_INTERRUPTING, new BooleanLiteralExpr(node.isInterrupting())));
 
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StateNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StateNodeVisitor.java
index cec7b37a91..8c4d95aa9f 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StateNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/StateNodeVisitor.java
@@ -31,7 +31,6 @@ import org.jbpm.workflow.core.node.StateNode;
 import org.kie.api.definition.process.Node;
 
 import com.github.javaparser.ast.expr.IntegerLiteralExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.MethodCallExpr;
 import com.github.javaparser.ast.expr.StringLiteralExpr;
 import com.github.javaparser.utils.StringEscapeUtils;
@@ -64,6 +63,7 @@ public class StateNodeVisitor extends CompositeContextNodeVisitor<StateNode> {
         if (node.getConstraints() == null) {
             return Stream.empty();
         }
+
         Collection<MethodCallExpr> result = new ArrayList<>();
         for (Map.Entry<ConnectionRef, Collection<Constraint>> entry : node.getConstraints().entrySet()) {
             ConnectionRef ref = entry.getKey();
@@ -71,7 +71,7 @@ public class StateNodeVisitor extends CompositeContextNodeVisitor<StateNode> {
                 if (constraint != null) {
                     result.add(getFactoryMethod(getNodeId(node), METHOD_CONSTRAINT,
                             getOrNullExpr(ref.getConnectionId()),
-                            new LongLiteralExpr(ref.getNodeId()),
+                            getWorkflowElementConstructor(ref.getNodeId()),
                             new StringLiteralExpr(ref.getToType()),
                             new StringLiteralExpr(constraint.getDialect()),
                             new StringLiteralExpr(StringEscapeUtils.escapeJava(constraint.getConstraint())),
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ThrowLinkNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ThrowLinkNodeVisitor.java
index b7b96bb07c..916cb0fe30 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ThrowLinkNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/ThrowLinkNodeVisitor.java
@@ -22,7 +22,6 @@ import org.jbpm.process.core.context.variable.VariableScope;
 import org.jbpm.ruleflow.core.factory.ThrowLinkNodeFactory;
 import org.jbpm.workflow.core.node.ThrowLinkNode;
 
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
 public class ThrowLinkNodeVisitor extends AbstractNodeVisitor<ThrowLinkNode> {
@@ -40,7 +39,7 @@ public class ThrowLinkNodeVisitor extends AbstractNodeVisitor<ThrowLinkNode> {
             ProcessMetaData metadata) {
         String nodeId = getNodeId(node);
         body.addStatement(getAssignedFactoryMethod(factoryField, ThrowLinkNodeFactory.class, nodeId,
-                getNodeKey(), new LongLiteralExpr(node.getId())));
+                getNodeKey(), getWorkflowElementConstructor(node.getId())));
         body.addStatement(getDoneMethod(nodeId));
     }
 
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/TimerNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/TimerNodeVisitor.java
index fbedd7eb32..b80a7650a8 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/TimerNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/TimerNodeVisitor.java
@@ -24,7 +24,6 @@ import org.jbpm.ruleflow.core.factory.TimerNodeFactory;
 import org.jbpm.workflow.core.node.TimerNode;
 
 import com.github.javaparser.ast.expr.IntegerLiteralExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.StringLiteralExpr;
 import com.github.javaparser.ast.stmt.BlockStmt;
 
@@ -42,7 +41,7 @@ public class TimerNodeVisitor extends AbstractNodeVisitor<TimerNode> {
 
     @Override
     public void visitNode(String factoryField, TimerNode node, BlockStmt body, VariableScope variableScope, ProcessMetaData metadata) {
-        body.addStatement(getAssignedFactoryMethod(factoryField, TimerNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, TimerNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, "Timer"));
 
         Timer timer = node.getTimer();
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/TriggerMetaData.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/TriggerMetaData.java
index 50849ac081..4dddd44d5e 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/TriggerMetaData.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/TriggerMetaData.java
@@ -163,11 +163,11 @@ public class TriggerMetaData {
             NodeContainer container = ((KogitoNode) node).getParentContainer();
             while (container instanceof CompositeNode) {
                 CompositeNode compositeNode = (CompositeNode) container;
-                prefix.append(compositeNode.getId()).append('_');
+                prefix.append(compositeNode.getId().toSanitizeString()).append('_');
                 container = compositeNode.getParentContainer();
             }
         }
-        return prefix.append(node.getId()).toString();
+        return prefix.append(node.getId().toSanitizeString()).toString();
     }
 
 }
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/UserTaskModelMetaData.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/UserTaskModelMetaData.java
index e2134e0e02..3d648ad2e2 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/UserTaskModelMetaData.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/UserTaskModelMetaData.java
@@ -31,6 +31,7 @@ import org.jbpm.process.core.datatype.DataType;
 import org.jbpm.process.core.datatype.DataTypeResolver;
 import org.jbpm.util.PatternConstants;
 import org.jbpm.workflow.core.node.HumanTaskNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.UserTask;
 import org.kie.kogito.UserTaskParam;
 import org.kie.kogito.UserTaskParam.ParamType;
@@ -104,13 +105,13 @@ public class UserTaskModelMetaData {
         this.humanTaskNode = humanTaskNode;
         this.processId = processId;
 
-        this.inputModelClassSimpleName = sanitizeClassName(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + humanTaskNode.getId() + "_" + TASK_INTPUT_CLASS_SUFFIX);
+        this.inputModelClassSimpleName = sanitizeClassName(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + humanTaskNode.getId().toExternalFormat() + "_" + TASK_INTPUT_CLASS_SUFFIX);
         this.inputModelClassName = packageName + '.' + inputModelClassSimpleName;
 
-        this.outputModelClassSimpleName = sanitizeClassName(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + humanTaskNode.getId() + "_" + TASK_OUTTPUT_CLASS_SUFFIX);
+        this.outputModelClassSimpleName = sanitizeClassName(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + humanTaskNode.getId().toExternalFormat() + "_" + TASK_OUTTPUT_CLASS_SUFFIX);
         this.outputModelClassName = packageName + '.' + outputModelClassSimpleName;
 
-        this.taskModelClassSimpleName = sanitizeClassName(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + humanTaskNode.getId() + "_" + TASK_MODEL_CLASS_SUFFIX);
+        this.taskModelClassSimpleName = sanitizeClassName(ProcessToExecModelGenerator.extractProcessId(processId) + "_" + humanTaskNode.getId().toExternalFormat() + "_" + TASK_MODEL_CLASS_SUFFIX);
         this.taskModelClassName = packageName + '.' + taskModelClassSimpleName;
 
     }
@@ -150,7 +151,7 @@ public class UserTaskModelMetaData {
         return humanTaskNode.getName();
     }
 
-    public long getId() {
+    public WorkflowElementIdentifier getId() {
         return humanTaskNode.getId();
     }
 
@@ -412,7 +413,7 @@ public class UserTaskModelMetaData {
 
     public SwitchEntry getModelSwitchEntry() {
         SwitchEntry entry = new SwitchEntry();
-        entry.setLabels(NodeList.nodeList(new StringLiteralExpr(Long.toString(humanTaskNode.getId()))));
+        entry.setLabels(NodeList.nodeList(new StringLiteralExpr(humanTaskNode.getId().toExternalFormat())));
         entry.addStatement(new ReturnStmt(new MethodCallExpr(new NameExpr(
                 taskModelClassSimpleName), new SimpleName("from")).addArgument(WORK_ITEM)));
         return entry;
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/WorkItemNodeVisitor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/WorkItemNodeVisitor.java
index c949079c75..479e80775e 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/WorkItemNodeVisitor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/WorkItemNodeVisitor.java
@@ -33,7 +33,6 @@ import org.jbpm.workflow.core.node.WorkItemNode;
 import com.github.javaparser.ast.expr.BooleanLiteralExpr;
 import com.github.javaparser.ast.expr.Expression;
 import com.github.javaparser.ast.expr.IntegerLiteralExpr;
-import com.github.javaparser.ast.expr.LongLiteralExpr;
 import com.github.javaparser.ast.expr.MethodCallExpr;
 import com.github.javaparser.ast.expr.NameExpr;
 import com.github.javaparser.ast.expr.NullLiteralExpr;
@@ -99,7 +98,7 @@ public class WorkItemNodeVisitor<T extends WorkItemNode> extends AbstractNodeVis
             metadata.getGeneratedHandlers().put(workName, taskDescriptor.generateHandlerClassForService());
         }
 
-        body.addStatement(getAssignedFactoryMethod(factoryField, WorkItemNodeFactory.class, getNodeId(node), getNodeKey(), new LongLiteralExpr(node.getId())))
+        body.addStatement(getAssignedFactoryMethod(factoryField, WorkItemNodeFactory.class, getNodeId(node), getNodeKey(), getWorkflowElementConstructor(node.getId())))
                 .addStatement(getNameMethod(node, work.getName()))
                 .addStatement(getFactoryMethod(nodeId, METHOD_WORK_NAME, new StringLiteralExpr(workName)));
 
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/ServiceTaskDescriptor.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/ServiceTaskDescriptor.java
index 9ce5ea5d62..26a475e8f7 100644
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/ServiceTaskDescriptor.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/canonical/descriptors/ServiceTaskDescriptor.java
@@ -83,7 +83,7 @@ public class ServiceTaskDescriptor extends AbstractServiceTaskDescriptor {
 
     protected ServiceTaskDescriptor(WorkItemNode workItemNode, ClassLoader contextClassLoader) {
         super(workItemNode);
-        mangledName = mangledHandlerName(interfaceName, operationName, String.valueOf(workItemNode.getId()));
+        mangledName = mangledHandlerName(interfaceName, operationName, String.valueOf(workItemNode.getId().toSanitizeString()));
         this.parameters = extractTaskParameters();
         try {
             cls = contextClassLoader.loadClass(interfaceName);
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/xml/ProcessBuildData.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/xml/ProcessBuildData.java
index 82e1c923aa..4c5c1440f1 100755
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/xml/ProcessBuildData.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/compiler/xml/ProcessBuildData.java
@@ -29,6 +29,7 @@ import java.util.ServiceLoader;
 
 import org.jbpm.workflow.core.Node;
 import org.kie.api.definition.process.Process;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -39,7 +40,7 @@ public class ProcessBuildData {
     private static List<ProcessDataEventListenerProvider> providers = collectProviders();
 
     private List<Process> processes = new ArrayList<>();
-    private Map<Long, Node> nodes = new HashMap<>();
+    private Map<WorkflowElementIdentifier, Node> nodes = new HashMap<>();
     private Map<String, Object> metaData = new HashMap<>();
 
     private List<ProcessDataEventListener> listeners = new ArrayList<>();
@@ -69,7 +70,7 @@ public class ProcessBuildData {
         this.processes = process;
     }
 
-    public Map<Long, Node> getNodes() {
+    public Map<WorkflowElementIdentifier, Node> getNodes() {
         return nodes;
     }
 
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/MultiConditionalSequenceFlowNodeBuilder.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/MultiConditionalSequenceFlowNodeBuilder.java
index 5f6f92f395..d0f673f1c8 100755
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/MultiConditionalSequenceFlowNodeBuilder.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/MultiConditionalSequenceFlowNodeBuilder.java
@@ -55,7 +55,7 @@ public class MultiConditionalSequenceFlowNodeBuilder implements ProcessNodeBuild
             Connection outgoingConnection = null;
             for (Connection out : ((NodeImpl) node).getDefaultOutgoingConnections()) {
                 if (out.getToType().equals(connection.getToType())
-                        && out.getTo().getId() == connection.getNodeId()) {
+                        && out.getTo().getId().equals(connection.getNodeId())) {
                     outgoingConnection = out;
                 }
             }
diff --git a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/SplitNodeBuilder.java b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/SplitNodeBuilder.java
index 3fc60663da..e0cdc62c60 100755
--- a/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/SplitNodeBuilder.java
+++ b/jbpm/jbpm-flow-builder/src/main/java/org/jbpm/process/builder/SplitNodeBuilder.java
@@ -58,7 +58,7 @@ public class SplitNodeBuilder implements ProcessNodeBuilder {
             Connection outgoingConnection = null;
             for (Connection out : splitNode.getDefaultOutgoingConnections()) {
                 if (out.getToType().equals(connection.getToType())
-                        && out.getTo().getId() == connection.getNodeId()) {
+                        && out.getTo().getId().equals(connection.getNodeId())) {
                     outgoingConnection = out;
                 }
             }
diff --git a/jbpm/jbpm-flow-builder/src/test/java/org/jbpm/compiler/canonical/ProcessToExecModelGeneratorTest.java b/jbpm/jbpm-flow-builder/src/test/java/org/jbpm/compiler/canonical/ProcessToExecModelGeneratorTest.java
index df78ac1635..e454d26ee0 100644
--- a/jbpm/jbpm-flow-builder/src/test/java/org/jbpm/compiler/canonical/ProcessToExecModelGeneratorTest.java
+++ b/jbpm/jbpm-flow-builder/src/test/java/org/jbpm/compiler/canonical/ProcessToExecModelGeneratorTest.java
@@ -22,8 +22,10 @@ import org.jbpm.process.core.datatype.impl.type.IntegerDataType;
 import org.jbpm.process.core.datatype.impl.type.ObjectDataType;
 import org.jbpm.process.core.datatype.impl.type.StringDataType;
 import org.jbpm.ruleflow.core.RuleFlowProcessFactory;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.junit.jupiter.api.Test;
 import org.kie.api.definition.process.Process;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.definition.process.WorkflowProcess;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -34,6 +36,11 @@ public class ProcessToExecModelGeneratorTest {
 
     private static final Logger logger = LoggerFactory.getLogger(ProcessToExecModelGeneratorTest.class);
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("two");
+    private static WorkflowElementIdentifier three = WorkflowElementIdentifierFactory.fromExternalFormat("three");
+    private static WorkflowElementIdentifier four = WorkflowElementIdentifierFactory.fromExternalFormat("four");
+
     @Test
     public void testScriptAndWorkItemGeneration() {
 
@@ -45,24 +52,24 @@ public class ProcessToExecModelGeneratorTest {
                 .packageName("com.myspace.demo")
                 .dynamic(false)
                 .version("1.0")
-                .workItemNode(1)
+                .workItemNode(one)
                 .name("Log")
                 .workName("Log")
                 .done()
-                .actionNode(2)
+                .actionNode(two)
                 .name("Dump order")
                 .action("java", "System.out.println(\"Order has been created \" + order);")
                 .done()
-                .endNode(3)
+                .endNode(three)
                 .name("end")
                 .terminate(false)
                 .done()
-                .startNode(4)
+                .startNode(four)
                 .name("start")
                 .done()
-                .connection(2, 1)
-                .connection(4, 2)
-                .connection(1, 3);
+                .connection(two, one)
+                .connection(four, two)
+                .connection(one, three);
 
         WorkflowProcess process = factory.validate().getProcess();
 
@@ -91,24 +98,24 @@ public class ProcessToExecModelGeneratorTest {
                 .packageName("com.myspace.demo")
                 .dynamic(false)
                 .version("1.0")
-                .workItemNode(1)
+                .workItemNode(one)
                 .name("Log")
                 .workName("Log")
                 .done()
-                .actionNode(2)
+                .actionNode(two)
                 .name("Dump order")
                 .action("java", "System.out.println(\"Order has been created \" + order);")
                 .done()
-                .endNode(3)
+                .endNode(three)
                 .name("end")
                 .terminate(false)
                 .done()
-                .startNode(4)
+                .startNode(four)
                 .name("start")
                 .done()
-                .connection(2, 1)
-                .connection(4, 2)
-                .connection(1, 3);
+                .connection(two, one)
+                .connection(four, two)
+                .connection(one, three);
 
         Process process = factory.validate().getProcess();
 
@@ -129,24 +136,24 @@ public class ProcessToExecModelGeneratorTest {
                 .packageName("com.myspace.demo")
                 .dynamic(false)
                 .version("1.0")
-                .workItemNode(1)
+                .workItemNode(one)
                 .name("Log")
                 .workName("Log")
                 .done()
-                .actionNode(2)
+                .actionNode(two)
                 .name("Dump order")
                 .action("java", "System.out.println(\"Order has been created \" + order);")
                 .done()
-                .endNode(3)
+                .endNode(three)
                 .name("end")
                 .terminate(false)
                 .done()
-                .startNode(4)
+                .startNode(four)
                 .name("start")
                 .done()
-                .connection(2, 1)
-                .connection(4, 2)
-                .connection(1, 3);
+                .connection(two, one)
+                .connection(four, two)
+                .connection(one, three);
 
         WorkflowProcess process = factory.validate().getProcess();
 
diff --git a/jbpm/jbpm-flow-migration/pom.xml b/jbpm/jbpm-flow-migration/pom.xml
new file mode 100644
index 0000000000..6a7e41a0af
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/pom.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <artifactId>jbpm</artifactId>
+        <groupId>org.kie.kogito</groupId>
+        <version>999-SNAPSHOT</version>
+    </parent>
+
+    <artifactId>jbpm-flow-migration</artifactId>
+
+    <properties>
+        <java.module.name>org.kie.kogito.jbpm.flow.migration</java.module.name>
+    </properties>
+
+    <name>jbpm-flow-migration</name>
+
+    <dependencies>
+        <dependency>
+            <groupId>org.kie.kogito</groupId>
+            <artifactId>jbpm-flow</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-databind</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.kie.kogito</groupId>
+            <artifactId>process-serialization-protobuf</artifactId>
+        </dependency>
+
+        <!-- tests -->
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-engine</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.junit.jupiter</groupId>
+            <artifactId>junit-jupiter-params</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.mockito</groupId>
+            <artifactId>mockito-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>ch.qos.logback</groupId>
+            <artifactId>logback-classic</artifactId>
+            <scope>test</scope>
+        </dependency>
+        <dependency>
+            <groupId>org.assertj</groupId>
+            <artifactId>assertj-core</artifactId>
+            <scope>test</scope>
+        </dependency>
+    </dependencies>
+
+    <dependencyManagement>
+        <dependencies>
+            <dependency>
+                <groupId>org.kie.kogito</groupId>
+                <artifactId>kogito-kie-bom</artifactId>
+                <version>${project.version}</version>
+                <type>pom</type>
+                <scope>import</scope>
+            </dependency>
+        </dependencies>
+    </dependencyManagement>
+</project>
diff --git a/api/kogito-api/src/main/java/org/kie/kogito/process/Processes.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFile.java
similarity index 61%
copy from api/kogito-api/src/main/java/org/kie/kogito/process/Processes.java
copy to jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFile.java
index 9b88793215..f5bb93709b 100644
--- a/api/kogito-api/src/main/java/org/kie/kogito/process/Processes.java
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFile.java
@@ -16,24 +16,36 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.process;
 
-import java.util.Collection;
+package org.jbpm.flow.migration;
 
-import org.kie.kogito.KogitoEngine;
-import org.kie.kogito.Model;
+import java.nio.file.Path;
 
-public interface Processes extends KogitoEngine {
+public class MigrationPlanFile {
 
-    Process<? extends Model> processById(String processId);
+    private Path path;
 
-    Collection<String> processIds();
+    private byte[] content;
 
-    default void activate() {
+    public MigrationPlanFile(Path path, byte[] content) {
+        this.path = path;
+        this.content = content;
+    }
 
+    public Path getPath() {
+        return path;
     }
 
-    default void deactivate() {
+    public void setPath(Path path) {
+        this.path = path;
+    }
 
+    public byte[] getContent() {
+        return content;
     }
+
+    public void setContent(byte[] content) {
+        this.content = content;
+    }
+
 }
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerException.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFileFormatException.java
similarity index 70%
copy from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerException.java
copy to jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFileFormatException.java
index 8ec1bf0596..a410f821b0 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerException.java
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFileFormatException.java
@@ -16,17 +16,20 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process;
+package org.jbpm.flow.migration;
 
-public class ProcessInstanceMarshallerException extends RuntimeException {
+import java.io.IOException;
 
-    private static final long serialVersionUID = -1676023219884892322L;
+public class MigrationPlanFileFormatException extends IOException {
 
-    public ProcessInstanceMarshallerException(String msg) {
+    private static final long serialVersionUID = 1L;
+
+    public MigrationPlanFileFormatException(String msg) {
         super(msg);
     }
 
-    public ProcessInstanceMarshallerException(String msg, Throwable th) {
-        super(msg, th);
+    public MigrationPlanFileFormatException(String msg, IOException e) {
+        super(msg, e);
     }
+
 }
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufListMarshallerStrategy.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFileProvider.java
similarity index 58%
copy from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufListMarshallerStrategy.java
copy to jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFileProvider.java
index 152e56c35c..ad072b0dfb 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufListMarshallerStrategy.java
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFileProvider.java
@@ -16,19 +16,25 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl.marshallers;
+
+package org.jbpm.flow.migration;
 
 import java.util.List;
+import java.util.ServiceLoader;
+import java.util.ServiceLoader.Provider;
+import java.util.stream.Collectors;
 
-public class ProtobufListMarshallerStrategy extends ProtobufObjectMarshallerStrategy {
+import org.jbpm.util.JbpmClassLoaderUtil;
 
-    @Override
-    public Integer order() {
-        return DEFAULT_ORDER;
-    }
+public interface MigrationPlanFileProvider {
 
-    @Override
-    public boolean acceptForMarshalling(Object value) {
-        return List.class.isInstance(value);
+    static List<MigrationPlanFileProvider> findMigrationPlanFileProviders() {
+        return ServiceLoader.load(MigrationPlanFileProvider.class, JbpmClassLoaderUtil.findClassLoader())
+                .stream()
+                .map(Provider::get)
+                .collect(Collectors.toList());
     }
+
+    List<MigrationPlanFile> listMigrationPlanFiles(String... extensions);
+
 }
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/persistence/InstantProtostreamBaseMarshaller.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFileReader.java
similarity index 50%
copy from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/persistence/InstantProtostreamBaseMarshaller.java
copy to jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFileReader.java
index f1f6d13283..5617a52cfd 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/persistence/InstantProtostreamBaseMarshaller.java
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanFileReader.java
@@ -16,33 +16,34 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.persistence;
+package org.jbpm.flow.migration;
 
 import java.io.IOException;
-import java.time.Instant;
-
-import org.infinispan.protostream.MessageMarshaller;
-
-public class InstantProtostreamBaseMarshaller implements MessageMarshaller<Instant> {
-
-    @Override
-    public Class<? extends Instant> getJavaClass() {
-        return Instant.class;
+import java.io.InputStream;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.ServiceLoader;
+import java.util.ServiceLoader.Provider;
+import java.util.stream.Collectors;
+
+import org.jbpm.flow.migration.model.MigrationPlan;
+import org.jbpm.util.JbpmClassLoaderUtil;
+
+public interface MigrationPlanFileReader {
+
+    static List<MigrationPlanFileReader> findMigrationPlanFileReaders() {
+        return ServiceLoader.load(MigrationPlanFileReader.class, JbpmClassLoaderUtil.findClassLoader())
+                .stream()
+                .map(Provider::get)
+                .collect(Collectors.toList());
     }
 
-    @Override
-    public String getTypeName() {
-        return "kogito.Instant";
-    }
+    MigrationPlan read(InputStream inputStream) throws IOException;
 
-    @Override
-    public Instant readFrom(ProtoStreamReader reader) throws IOException {
-        return reader.readInstant("data");
-    }
+    String getFileExtension();
 
-    @Override
-    public void writeTo(ProtoStreamWriter writer, Instant instant) throws IOException {
-        writer.writeInstant("data", instant);
+    default boolean accept(Path path) {
+        return path.toString().endsWith(getFileExtension());
     }
 
 }
diff --git a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanProvider.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanProvider.java
new file mode 100644
index 0000000000..8b250b60df
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanProvider.java
@@ -0,0 +1,108 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.flow.migration;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jbpm.flow.migration.model.MigrationPlan;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class MigrationPlanProvider {
+    private static final Logger LOGGER = LoggerFactory.getLogger(MigrationPlanProvider.class);
+
+    private List<MigrationPlanFileReader> fileReaders;
+    private List<MigrationPlanFileProvider> fileProviders;
+
+    public MigrationPlanProvider() {
+        fileReaders = new ArrayList<>();
+        fileProviders = new ArrayList<>();
+    }
+
+    public List<MigrationPlan> findMigrationPlans() {
+        String[] extensions = fileReaders.stream().map(MigrationPlanFileReader::getFileExtension).toArray(String[]::new);
+
+        List<MigrationPlanFile> migrationPlanFiles = new ArrayList<>();
+        for (MigrationPlanFileProvider provider : fileProviders) {
+            migrationPlanFiles.addAll(provider.listMigrationPlanFiles(extensions));
+        }
+
+        List<MigrationPlan> migrationPlans = new ArrayList<>();
+        for (MigrationPlanFile mpf : migrationPlanFiles) {
+            try {
+                migrationPlans.add(readMigrationPlan(mpf));
+            } catch (IOException e) {
+                LOGGER.error("Error trying to read migration plan {}", mpf.getPath(), e);
+            }
+        }
+
+        return migrationPlans;
+    }
+
+    private MigrationPlan readMigrationPlan(MigrationPlanFile mpf) throws IOException {
+        try (InputStream is = new ByteArrayInputStream(mpf.getContent())) {
+            for (MigrationPlanFileReader reader : fileReaders) {
+                if (reader.accept(mpf.getPath())) {
+                    return reader.read(is);
+                }
+            }
+        }
+        throw new MigrationPlanFileFormatException("Not file format reader found for " + mpf.getPath());
+
+    }
+
+    public static class MigrationPlanProviderBuilder {
+
+        private MigrationPlanProvider migrationPlanProvider;
+
+        public MigrationPlanProviderBuilder() {
+            this.migrationPlanProvider = new MigrationPlanProvider();
+        }
+
+        public MigrationPlanProviderBuilder withEnvironmentDefaults() {
+            migrationPlanProvider.fileReaders.addAll(MigrationPlanFileReader.findMigrationPlanFileReaders());
+            migrationPlanProvider.fileProviders.addAll(MigrationPlanFileProvider.findMigrationPlanFileProviders());
+            return this;
+        }
+
+        public MigrationPlanProviderBuilder withMigrationPlanFileReader(MigrationPlanFileReader migrationPlanFileReader) {
+            migrationPlanProvider.fileReaders.add(migrationPlanFileReader);
+            return this;
+        }
+
+        public MigrationPlanProviderBuilder withMigrationPlanFileProvider(MigrationPlanFileProvider MigrationPlanFileProvider) {
+            migrationPlanProvider.fileProviders.add(MigrationPlanFileProvider);
+            return this;
+        }
+
+        public MigrationPlanProvider build() {
+            return migrationPlanProvider;
+        }
+
+    }
+
+    public static MigrationPlanProviderBuilder newMigrationPlanProviderBuilder() {
+        return new MigrationPlanProviderBuilder();
+    }
+
+}
diff --git a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanService.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanService.java
new file mode 100644
index 0000000000..12951dfb16
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/MigrationPlanService.java
@@ -0,0 +1,92 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.flow.migration;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.jbpm.flow.migration.model.MigrationPlan;
+import org.jbpm.flow.migration.model.ProcessDefinitionMigrationPlan;
+import org.jbpm.ruleflow.instance.RuleFlowProcessInstance;
+import org.jbpm.workflow.instance.impl.NodeInstanceImpl;
+import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
+import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static com.google.common.base.Functions.identity;
+import static java.util.stream.Collectors.toMap;
+
+public class MigrationPlanService {
+    private static final Logger LOGGER = LoggerFactory.getLogger(MigrationPlanService.class);
+
+    private MigrationPlanProvider migrationPlanProvider;
+    private Map<ProcessDefinitionMigrationPlan, MigrationPlan> migrations;
+
+    public MigrationPlanService() {
+        this(MigrationPlanProvider.newMigrationPlanProviderBuilder().withEnvironmentDefaults().build());
+    }
+
+    public MigrationPlanService(MigrationPlanProvider migrationPlanProvider) {
+        this.migrationPlanProvider = migrationPlanProvider;
+        this.migrations = new HashMap<>();
+        this.migrations.putAll(this.migrationPlanProvider.findMigrationPlans().stream().collect(toMap(MigrationPlan::getSource, identity())));
+    }
+
+    public void migrateProcessElement(KogitoWorkflowProcessInstance processInstance) {
+        MigrationPlan plan = getMigrationPlan(processInstance);
+        if (plan != null) {
+            // the process will have to do nothing as it is done by the engine itself
+            LOGGER.info("Process instance {} will be migrated from {} to {} with plan {}",
+                    processInstance.getStringId(),
+                    plan.getProcessMigrationPlan().getSourceProcessDefinition(),
+                    plan.getProcessMigrationPlan().getTargetProcessDefinition(),
+                    plan.getName());
+
+            RuleFlowProcessInstance ruleFlowProcessInstance = (RuleFlowProcessInstance) processInstance;
+            ruleFlowProcessInstance.setProcessId(plan.getProcessMigrationPlan().getTargetProcessDefinition().getProcessId());
+            ruleFlowProcessInstance.setProcessVersion(plan.getProcessMigrationPlan().getTargetProcessDefinition().getProcessVersion());
+        } else {
+            LOGGER.debug("Process instance {} won't be migrated", processInstance);
+        }
+    }
+
+    public void migrateNodeElement(KogitoNodeInstance nodeInstance) {
+        KogitoWorkflowProcessInstance pi = (KogitoWorkflowProcessInstance) nodeInstance.getProcessInstance();
+        MigrationPlan plan = getMigrationPlan(pi);
+        if (plan == null) {
+            return;
+        }
+
+        LOGGER.debug("Migration node element {}", nodeInstance);
+        NodeInstanceImpl impl = (NodeInstanceImpl) nodeInstance;
+        impl.setNodeId(plan.getProcessMigrationPlan().getNodeMigratedFor(nodeInstance));
+    }
+
+    private MigrationPlan getMigrationPlan(KogitoWorkflowProcessInstance processInstance) {
+        RuleFlowProcessInstance pi = (RuleFlowProcessInstance) processInstance;
+        ProcessDefinitionMigrationPlan pd =
+                new ProcessDefinitionMigrationPlan(pi.getProcessId(), pi.getProcessVersion());
+        return migrations.get(pd);
+    }
+
+    public boolean shouldMigrate(KogitoWorkflowProcessInstance processInstance) {
+        return getMigrationPlan(processInstance) != null;
+    }
+}
diff --git a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/FileSystemMigrationPlanFileProvider.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/FileSystemMigrationPlanFileProvider.java
new file mode 100644
index 0000000000..7d26bc7f96
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/FileSystemMigrationPlanFileProvider.java
@@ -0,0 +1,144 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.flow.migration.impl;
+
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Optional;
+import java.util.function.Predicate;
+import java.util.stream.Stream;
+
+import org.jbpm.flow.migration.MigrationPlanFile;
+import org.jbpm.flow.migration.MigrationPlanFileProvider;
+import org.jbpm.util.JbpmClassLoaderUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static java.util.Collections.emptyMap;
+
+public class FileSystemMigrationPlanFileProvider implements MigrationPlanFileProvider {
+
+    private static final Logger LOGGER = LoggerFactory.getLogger(FileSystemMigrationPlanFileProvider.class);
+
+    public static final String EXPLODED_MIGRATION_PLAN_FOLDER = "META-INF/migration-plan/";
+    public static final String MIGRATION_PLAN_FOLDER = "/META-INF/migration-plan/";
+
+    private List<URI> rootPaths;
+
+    public FileSystemMigrationPlanFileProvider() {
+        try {
+            List<URL> url = Collections.list(JbpmClassLoaderUtil.findClassLoader().getResources(MIGRATION_PLAN_FOLDER));
+            if (url.isEmpty()) {
+                url = Collections.list(JbpmClassLoaderUtil.findClassLoader().getResources(EXPLODED_MIGRATION_PLAN_FOLDER));
+            }
+            this.rootPaths = url.stream().map(this::toURI).filter(Optional::isPresent).map(Optional::get).toList();
+        } catch (IOException e) {
+            throw new IllegalArgumentException("error trying to get Migration Plan folder");
+        }
+    }
+
+    private Optional<URI> toURI(URL e) {
+        try {
+            return Optional.of(e.toURI());
+        } catch (URISyntaxException ex) {
+            return Optional.<URI> empty();
+        }
+    }
+
+    public FileSystemMigrationPlanFileProvider(URI rootPath) {
+        this.rootPaths = List.of(rootPath);
+    }
+
+    @Override
+    public List<MigrationPlanFile> listMigrationPlanFiles(String... extensions) {
+        List<String> allowedExtensions = Arrays.asList(extensions);
+        List<MigrationPlanFile> migrationPlanFiles = new ArrayList<>();
+        for (URI rootPath : rootPaths) {
+            if ("jar".equals(rootPath.getScheme())) {
+                migrationPlanFiles.addAll(walkInJarPaths(rootPath, allowedExtensions));
+            } else {
+                migrationPlanFiles.addAll(walkingPaths(Path.of(rootPath), allowedExtensions));
+            }
+        }
+        return migrationPlanFiles;
+    }
+
+    private List<MigrationPlanFile> walkInJarPaths(URI baseURI, List<String> extensions) {
+        LOGGER.debug("Searching Migration Plans in rootPath {}", baseURI);
+        try (FileSystem fileSystem = FileSystems.newFileSystem(baseURI, emptyMap(), JbpmClassLoaderUtil.findClassLoader())) {
+            Path myPath = fileSystem.getPath(MIGRATION_PLAN_FOLDER);
+            if (!Files.exists(myPath)) {
+                LOGGER.debug("There was not any migration plan found within jar {}", myPath);
+                return Collections.emptyList();
+            }
+            return walkingPaths(myPath, extensions);
+        } catch (Exception e) {
+            LOGGER.error("There was a problem during migration plan execution", e);
+            return Collections.emptyList();
+        }
+    }
+
+    public List<MigrationPlanFile> walkingPaths(Path basePath, List<String> allowedExtensions) {
+        List<MigrationPlanFile> migrationPlans = new ArrayList<>();
+        if (!Files.exists(basePath)) {
+            LOGGER.debug("There was not any migration plan found in path {}", basePath);
+            return Collections.emptyList();
+        }
+        try (Stream<Path> walk = Files.walk(basePath)) {
+            migrationPlans = walk
+                    .filter(Files::isRegularFile)
+                    .filter(e -> isMigrationPlanFileExtension(e, allowedExtensions))
+                    .map(this::toMigrationPlanFile)
+                    .toList();
+        } catch (IOException e) {
+            LOGGER.error("There was an error trying to search for migration plan in basePath {}", basePath, e);
+        }
+        return migrationPlans;
+    }
+
+    private boolean isMigrationPlanFileExtension(Path path, List<String> extensions) {
+        Predicate<String> predicate = new Predicate<String>() {
+            @Override
+            public boolean test(String extension) {
+                return path.toString().endsWith(extension);
+            }
+        };
+        return extensions.stream().anyMatch(predicate);
+    }
+
+    private MigrationPlanFile toMigrationPlanFile(Path path) {
+        try {
+            return new MigrationPlanFile(path, Files.readAllBytes(path));
+        } catch (IOException e) {
+            LOGGER.error("There was an error trying to search for migration plan in basePath {}", e);
+            return new MigrationPlanFile(path, new byte[0]);
+        }
+    }
+
+}
diff --git a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/JsonMigrationPlanFileReader.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/JsonMigrationPlanFileReader.java
new file mode 100644
index 0000000000..a37c00a514
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/JsonMigrationPlanFileReader.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.flow.migration.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.jbpm.flow.migration.MigrationPlanFileFormatException;
+import org.jbpm.flow.migration.MigrationPlanFileReader;
+import org.jbpm.flow.migration.model.MigrationPlan;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+public class JsonMigrationPlanFileReader implements MigrationPlanFileReader {
+    private static final Logger LOGGER = LoggerFactory.getLogger(JsonMigrationPlanFileReader.class);
+    public static final String MIGRATION_PLAN_FILE_EXTENSION = "mpf";
+
+    private ObjectMapper objectMapper;
+
+    public JsonMigrationPlanFileReader() {
+        objectMapper = new ObjectMapper();
+        SimpleModule simpleModule = new SimpleModule();
+        simpleModule.addDeserializer(WorkflowElementIdentifier.class, new JsonWorkflowElementIdentifierDeserializer());
+        objectMapper.registerModule(simpleModule);
+    }
+
+    public MigrationPlan read(InputStream is) throws IOException {
+        try {
+
+            MigrationPlan migrationPlan = objectMapper.readValue(is, MigrationPlan.class);
+            LOGGER.trace("Read migration plan {} in json format", migrationPlan);
+            return migrationPlan;
+        } catch (IOException e) {
+            throw new MigrationPlanFileFormatException("Error during marshalling", e);
+        }
+    }
+
+    @Override
+    public String getFileExtension() {
+        return "." + MIGRATION_PLAN_FILE_EXTENSION;
+    }
+
+}
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/persistence/DateProtostreamBaseMarshaller.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/JsonWorkflowElementIdentifierDeserializer.java
similarity index 54%
copy from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/persistence/DateProtostreamBaseMarshaller.java
copy to jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/JsonWorkflowElementIdentifierDeserializer.java
index 172b6fd09b..d4eeedc599 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/persistence/DateProtostreamBaseMarshaller.java
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/impl/JsonWorkflowElementIdentifierDeserializer.java
@@ -16,32 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.persistence;
+package org.jbpm.flow.migration.impl;
 
 import java.io.IOException;
-import java.util.Date;
 
-import org.infinispan.protostream.MessageMarshaller;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
-public class DateProtostreamBaseMarshaller implements MessageMarshaller<Date> {
+import com.fasterxml.jackson.core.JacksonException;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonDeserializer;
 
-    @Override
-    public Class<Date> getJavaClass() {
-        return Date.class;
-    }
+public class JsonWorkflowElementIdentifierDeserializer extends JsonDeserializer<WorkflowElementIdentifier> {
 
     @Override
-    public String getTypeName() {
-        return "kogito.Date";
+    public WorkflowElementIdentifier deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
+        return WorkflowElementIdentifierFactory.fromExternalFormat(p.getValueAsString());
     }
 
-    @Override
-    public Date readFrom(ProtoStreamReader reader) throws IOException {
-        return reader.readDate("data");
-    }
-
-    @Override
-    public void writeTo(ProtoStreamWriter writer, Date data) throws IOException {
-        writer.writeDate("data", data);
-    }
 }
diff --git a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/MigrationPlan.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/MigrationPlan.java
new file mode 100644
index 0000000000..b97c564170
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/MigrationPlan.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.flow.migration.model;
+
+import java.util.Objects;
+
+public class MigrationPlan {
+
+    private String name;
+
+    private ProcessInstanceMigrationPlan processMigrationPlan;
+
+    public ProcessInstanceMigrationPlan getProcessMigrationPlan() {
+        return processMigrationPlan;
+    }
+
+    public void setProcessMigrationPlan(ProcessInstanceMigrationPlan processMigrationPlan) {
+        this.processMigrationPlan = processMigrationPlan;
+    }
+
+    public ProcessDefinitionMigrationPlan getSource() {
+        return this.processMigrationPlan.getSourceProcessDefinition();
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(String name) {
+        this.name = name;
+    }
+
+    @Override
+    public String toString() {
+        return "MigrationPlan [name=" + name + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(name, processMigrationPlan);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        MigrationPlan other = (MigrationPlan) obj;
+        return Objects.equals(name, other.name) && Objects.equals(processMigrationPlan, other.processMigrationPlan);
+    }
+
+}
diff --git a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/NodeInstanceMigrationPlan.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/NodeInstanceMigrationPlan.java
new file mode 100644
index 0000000000..978faf34f2
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/NodeInstanceMigrationPlan.java
@@ -0,0 +1,77 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.flow.migration.model;
+
+import java.util.Objects;
+
+import org.kie.api.definition.process.WorkflowElementIdentifier;
+
+public class NodeInstanceMigrationPlan {
+
+    private WorkflowElementIdentifier sourceNodeId;
+    private WorkflowElementIdentifier targetNodeId;
+
+    public NodeInstanceMigrationPlan() {
+        // do nothing
+    }
+
+    public NodeInstanceMigrationPlan(WorkflowElementIdentifier sourceNodeId, WorkflowElementIdentifier targetNodeId) {
+        this.sourceNodeId = sourceNodeId;
+        this.targetNodeId = targetNodeId;
+    }
+
+    public WorkflowElementIdentifier getSourceNodeId() {
+        return sourceNodeId;
+    }
+
+    public void setSourceNodeId(WorkflowElementIdentifier sourceNodeId) {
+        this.sourceNodeId = sourceNodeId;
+    }
+
+    public WorkflowElementIdentifier getTargetNodeId() {
+        return targetNodeId;
+    }
+
+    public void setTargetNodeId(WorkflowElementIdentifier targetNodeId) {
+        this.targetNodeId = targetNodeId;
+    }
+
+    @Override
+    public String toString() {
+        return "NodeMigrationPlan [sourceNodeId=" + sourceNodeId + ", targetNodeId=" + targetNodeId + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(sourceNodeId, targetNodeId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        NodeInstanceMigrationPlan other = (NodeInstanceMigrationPlan) obj;
+        return Objects.equals(sourceNodeId, other.sourceNodeId) && Objects.equals(targetNodeId, other.targetNodeId);
+    }
+
+}
diff --git a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/ProcessDefinitionMigrationPlan.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/ProcessDefinitionMigrationPlan.java
new file mode 100644
index 0000000000..c9576ebdc1
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/ProcessDefinitionMigrationPlan.java
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.flow.migration.model;
+
+import java.util.Objects;
+
+public class ProcessDefinitionMigrationPlan {
+
+    private String processId;
+    private String processVersion;
+
+    public ProcessDefinitionMigrationPlan() {
+        // do nothing
+    }
+
+    public ProcessDefinitionMigrationPlan(String processId, String processVersion) {
+        this.processId = processId;
+        this.processVersion = processVersion;
+    }
+
+    public String getProcessId() {
+        return processId;
+    }
+
+    public void setProcessId(String processId) {
+        this.processId = processId;
+    }
+
+    public String getProcessVersion() {
+        return processVersion;
+    }
+
+    public void setProcessVersion(String processVersion) {
+        this.processVersion = processVersion;
+    }
+
+    @Override
+    public String toString() {
+        return "Process [processId=" + processId + ", processVersion=" + processVersion + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(processId, processVersion);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ProcessDefinitionMigrationPlan other = (ProcessDefinitionMigrationPlan) obj;
+        return Objects.equals(processId, other.processId) && Objects.equals(processVersion, other.processVersion);
+    }
+
+}
\ No newline at end of file
diff --git a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/ProcessInstanceMigrationPlan.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/ProcessInstanceMigrationPlan.java
new file mode 100644
index 0000000000..3a49d21862
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/migration/model/ProcessInstanceMigrationPlan.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.flow.migration.model;
+
+import java.util.List;
+import java.util.Objects;
+
+import org.kie.api.definition.process.WorkflowElementIdentifier;
+import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
+
+public class ProcessInstanceMigrationPlan {
+
+    private ProcessDefinitionMigrationPlan sourceProcessDefinition;
+    private ProcessDefinitionMigrationPlan targetProcessDefinition;
+
+    private List<NodeInstanceMigrationPlan> nodeInstanceMigrationPlan;
+
+    public List<NodeInstanceMigrationPlan> getNodeInstanceMigrationPlan() {
+        return nodeInstanceMigrationPlan;
+    }
+
+    public void setNodeInstanceMigrationPlan(List<NodeInstanceMigrationPlan> nodeInstanceMigrationPlan) {
+        this.nodeInstanceMigrationPlan = nodeInstanceMigrationPlan;
+    }
+
+    public WorkflowElementIdentifier getNodeMigratedFor(KogitoNodeInstance instance) {
+        List<NodeInstanceMigrationPlan> plans = nodeInstanceMigrationPlan.stream().filter(e -> e.getSourceNodeId().equals(instance.getNodeId())).toList();
+        if (plans.isEmpty()) {
+            return instance.getNodeId();
+        } else if (plans.size() > 1) {
+            throw new IllegalArgumentException("more than one node migration plan found for " + instance);
+        }
+        return plans.get(0).getTargetNodeId();
+    }
+
+    public ProcessDefinitionMigrationPlan getSourceProcessDefinition() {
+        return sourceProcessDefinition;
+    }
+
+    public void setSourceProcessDefinition(ProcessDefinitionMigrationPlan source) {
+        this.sourceProcessDefinition = source;
+    }
+
+    public ProcessDefinitionMigrationPlan getTargetProcessDefinition() {
+        return targetProcessDefinition;
+    }
+
+    public void setTargetProcessDefinition(ProcessDefinitionMigrationPlan target) {
+        this.targetProcessDefinition = target;
+    }
+
+    @Override
+    public String toString() {
+        return "ProcessMigrationPlan [source=" + sourceProcessDefinition + ", target=" + targetProcessDefinition + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(nodeInstanceMigrationPlan, sourceProcessDefinition, targetProcessDefinition);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ProcessInstanceMigrationPlan other = (ProcessInstanceMigrationPlan) obj;
+        return Objects.equals(nodeInstanceMigrationPlan, other.nodeInstanceMigrationPlan) && Objects.equals(sourceProcessDefinition, other.sourceProcessDefinition)
+                && Objects.equals(targetProcessDefinition, other.targetProcessDefinition);
+    }
+
+}
diff --git a/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/serialization/migration/StandardMigrationProcessInstanceMarshallerListener.java b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/serialization/migration/StandardMigrationProcessInstanceMarshallerListener.java
new file mode 100644
index 0000000000..22ac0cdf03
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/java/org/jbpm/flow/serialization/migration/StandardMigrationProcessInstanceMarshallerListener.java
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.flow.serialization.migration;
+
+import org.jbpm.flow.migration.MigrationPlanService;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerListener;
+import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
+import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
+import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * This class acts as a bridge between migration service and serialization system
+ */
+public class StandardMigrationProcessInstanceMarshallerListener implements ProcessInstanceMarshallerListener {
+    private static final Logger LOGGER = LoggerFactory.getLogger(StandardMigrationProcessInstanceMarshallerListener.class);
+
+    private MigrationPlanService migrationPlanService;
+
+    public StandardMigrationProcessInstanceMarshallerListener() {
+        this.migrationPlanService = new MigrationPlanService();
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void afterUnmarshallProcess(KogitoProcessRuntime runtime, KogitoWorkflowProcessInstance processInstance) {
+        if (!migrationPlanService.shouldMigrate(processInstance)) {
+            return;
+        }
+        LOGGER.debug("Migration processInstance {}", processInstance);
+        migrationPlanService.migrateProcessElement(processInstance);
+        runtime.getProcessEventSupport().fireOnMigration(processInstance, runtime.getKieRuntime());
+
+    }
+
+    @Override
+    public void afterUnmarshallNode(KogitoProcessRuntime runtime, KogitoNodeInstance nodeInstance) {
+        if (!migrationPlanService.shouldMigrate((KogitoWorkflowProcessInstance) nodeInstance.getProcessInstance())) {
+            return;
+        }
+        LOGGER.debug("Migration nodeInstance {}", nodeInstance);
+        migrationPlanService.migrateNodeElement(nodeInstance);
+    }
+
+}
diff --git a/jbpm/jbpm-flow-migration/src/main/resources/META-INF/services/org.jbpm.flow.migration.MigrationPlanFileProvider b/jbpm/jbpm-flow-migration/src/main/resources/META-INF/services/org.jbpm.flow.migration.MigrationPlanFileProvider
new file mode 100644
index 0000000000..cda56c196f
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/resources/META-INF/services/org.jbpm.flow.migration.MigrationPlanFileProvider
@@ -0,0 +1 @@
+org.jbpm.flow.migration.impl.FileSystemMigrationPlanFileProvider
\ No newline at end of file
diff --git a/jbpm/jbpm-flow-migration/src/main/resources/META-INF/services/org.jbpm.flow.migration.MigrationPlanFileReader b/jbpm/jbpm-flow-migration/src/main/resources/META-INF/services/org.jbpm.flow.migration.MigrationPlanFileReader
new file mode 100644
index 0000000000..77d6732019
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/resources/META-INF/services/org.jbpm.flow.migration.MigrationPlanFileReader
@@ -0,0 +1 @@
+org.jbpm.flow.migration.impl.JsonMigrationPlanFileReader
\ No newline at end of file
diff --git a/jbpm/jbpm-flow-migration/src/main/resources/META-INF/services/org.jbpm.flow.serialization.ProcessInstanceMarshallerListener b/jbpm/jbpm-flow-migration/src/main/resources/META-INF/services/org.jbpm.flow.serialization.ProcessInstanceMarshallerListener
new file mode 100644
index 0000000000..f5923fd822
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/main/resources/META-INF/services/org.jbpm.flow.serialization.ProcessInstanceMarshallerListener
@@ -0,0 +1 @@
+org.jbpm.flow.serialization.migration.StandardMigrationProcessInstanceMarshallerListener
\ No newline at end of file
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNode.java b/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/DummyProcess.java
similarity index 50%
copy from jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNode.java
copy to jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/DummyProcess.java
index 00964aad86..73a4d4b5b9 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNode.java
+++ b/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/DummyProcess.java
@@ -16,43 +16,69 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.jbpm.workflow.core.node;
+package org.jbpm.flow.migration;
 
-import java.util.HashMap;
 import java.util.Map;
 
-import org.jbpm.workflow.core.impl.NodeImpl;
-import org.kie.api.definition.process.Node;
+import org.kie.api.io.Resource;
 
-public class AsyncEventNode extends EventNode {
+public class DummyProcess implements org.kie.api.definition.process.Process {
 
-    private static final long serialVersionUID = -4724021457443413412L;
+    private String id;
+    private String version;
 
-    private Node node;
+    public DummyProcess(String id, String version) {
+        this.id = id;
+        this.version = version;
+    }
+
+    @Override
+    public KnowledgeType getKnowledgeType() {
+        return null;
+    }
+
+    @Override
+    public String getNamespace() {
+        return null;
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
 
-    public AsyncEventNode(Node node) {
-        this.node = node;
+    @Override
+    public String getName() {
+        return null;
     }
 
-    public Node getActualNode() {
-        return node;
+    @Override
+    public String getVersion() {
+        return version;
     }
 
     @Override
-    public long getId() {
-        return node.getId();
+    public String getPackageName() {
+        return null;
     }
 
     @Override
-    public Object getMetaData(String name) {
-        return ((NodeImpl) node).getMetaData(name);
+    public String getType() {
+        return null;
     }
 
     @Override
     public Map<String, Object> getMetaData() {
-        Map<String, Object> metaData = new HashMap<>(node.getMetaData());
-        metaData.put("hidden", "true");
-        return metaData;
+        return null;
+    }
+
+    @Override
+    public Resource getResource() {
+        return null;
+    }
+
+    @Override
+    public void setResource(Resource res) {
     }
 
-}
+}
\ No newline at end of file
diff --git a/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanProviderTest.java b/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanProviderTest.java
new file mode 100644
index 0000000000..2a279c20f1
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanProviderTest.java
@@ -0,0 +1,63 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.flow.migration;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.jbpm.flow.migration.model.MigrationPlan;
+import org.jbpm.flow.migration.model.NodeInstanceMigrationPlan;
+import org.jbpm.flow.migration.model.ProcessDefinitionMigrationPlan;
+import org.jbpm.flow.migration.model.ProcessInstanceMigrationPlan;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MigrationPlanProviderTest {
+
+    @Test
+    public void testReadingFiles() {
+        MigrationPlanProvider provider = MigrationPlanProvider.newMigrationPlanProviderBuilder().withEnvironmentDefaults().build();
+        List<MigrationPlan> plans = provider.findMigrationPlans();
+
+        NodeInstanceMigrationPlan a = new NodeInstanceMigrationPlan(
+                WorkflowElementIdentifierFactory.fromExternalFormat("node_1"),
+                WorkflowElementIdentifierFactory.fromExternalFormat("node_2"));
+
+        NodeInstanceMigrationPlan b = new NodeInstanceMigrationPlan(
+                WorkflowElementIdentifierFactory.fromExternalFormat("node_2"),
+                WorkflowElementIdentifierFactory.fromExternalFormat("node_3"));
+
+        ProcessInstanceMigrationPlan pdmp = new ProcessInstanceMigrationPlan();
+        pdmp.setSourceProcessDefinition(new ProcessDefinitionMigrationPlan("process_A", "1"));
+        pdmp.setTargetProcessDefinition(new ProcessDefinitionMigrationPlan("process_B", "2"));
+        pdmp.setNodeInstanceMigrationPlan(Arrays.asList(a, b));
+
+        MigrationPlan plan = new MigrationPlan();
+        plan.setName("my simple migration");
+        plan.setProcessMigrationPlan(pdmp);
+
+        assertThat(plans)
+                .hasSize(1)
+                .containsExactly(plan);
+
+    }
+
+}
diff --git a/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanServiceTest.java b/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanServiceTest.java
new file mode 100644
index 0000000000..1e2f141110
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/test/java/org/jbpm/flow/migration/MigrationPlanServiceTest.java
@@ -0,0 +1,128 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.flow.migration;
+
+import org.jbpm.ruleflow.instance.RuleFlowProcessInstance;
+import org.jbpm.workflow.instance.impl.ExtendedNodeInstanceImpl;
+import org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory.fromExternalFormat;
+
+public class MigrationPlanServiceTest {
+
+    @Test
+    public void testMigrationProcessInstance() {
+        MigrationPlanService service = new MigrationPlanService();
+
+        WorkflowProcessInstanceImpl processImpl = new RuleFlowProcessInstance();
+        processImpl.setProcess(new DummyProcess("process_A", "1"));
+        service.migrateProcessElement(processImpl);
+
+        assertThat(processImpl)
+                .hasFieldOrPropertyWithValue("processId", "process_B")
+                .hasFieldOrPropertyWithValue("processVersion", "2");
+
+    }
+
+    @Test
+    public void testMigrationProcessNonExisting() {
+        MigrationPlanService service = new MigrationPlanService();
+        WorkflowProcessInstanceImpl processImpl = new RuleFlowProcessInstance();
+        processImpl.setProcess(new DummyProcess("process_C", "1"));
+        service.migrateProcessElement(processImpl);
+
+        assertThat(processImpl)
+                .hasFieldOrPropertyWithValue("processId", "process_C")
+                .hasFieldOrPropertyWithValue("processVersion", "1");
+    }
+
+    @Test
+    public void testMigrationProcessNotRightVersion() {
+        MigrationPlanService service = new MigrationPlanService();
+        WorkflowProcessInstanceImpl processImpl = new RuleFlowProcessInstance();
+        processImpl.setProcess(new DummyProcess("process_A", "3"));
+        service.migrateProcessElement(processImpl);
+
+        assertThat(processImpl)
+                .hasFieldOrPropertyWithValue("processId", "process_A")
+                .hasFieldOrPropertyWithValue("processVersion", "3");
+    }
+
+    @Test
+    public void testMigrationNode() {
+        MigrationPlanService service = new MigrationPlanService();
+        WorkflowProcessInstanceImpl processImpl = new RuleFlowProcessInstance();
+        processImpl.setProcess(new DummyProcess("process_A", "1"));
+        ExtendedNodeInstanceImpl nodeInstanceImpl = new ExtendedNodeInstanceImpl() {
+        };
+        nodeInstanceImpl.setProcessInstance(processImpl);
+        nodeInstanceImpl.setNodeId(fromExternalFormat("node_1"));
+        service.migrateNodeElement(nodeInstanceImpl);
+
+        assertThat(nodeInstanceImpl)
+                .hasFieldOrPropertyWithValue("nodeId", fromExternalFormat("node_2"));
+    }
+
+    @Test
+    public void testMigrationNodeNextItem() {
+        MigrationPlanService service = new MigrationPlanService();
+        WorkflowProcessInstanceImpl processImpl = new RuleFlowProcessInstance();
+        processImpl.setProcess(new DummyProcess("process_A", "1"));
+        ExtendedNodeInstanceImpl nodeInstanceImpl = new ExtendedNodeInstanceImpl() {
+        };
+        nodeInstanceImpl.setProcessInstance(processImpl);
+        nodeInstanceImpl.setNodeId(fromExternalFormat("node_2"));
+        service.migrateNodeElement(nodeInstanceImpl);
+
+        assertThat(nodeInstanceImpl)
+                .hasFieldOrPropertyWithValue("nodeId", fromExternalFormat("node_3"));
+    }
+
+    @Test
+    public void testMigrationNodeNonExistent() {
+        MigrationPlanService service = new MigrationPlanService();
+        WorkflowProcessInstanceImpl processImpl = new RuleFlowProcessInstance();
+        processImpl.setProcess(new DummyProcess("process_A", "1"));
+        ExtendedNodeInstanceImpl nodeInstanceImpl = new ExtendedNodeInstanceImpl() {
+        };
+        nodeInstanceImpl.setProcessInstance(processImpl);
+        nodeInstanceImpl.setNodeId(fromExternalFormat("node_3"));
+        service.migrateNodeElement(nodeInstanceImpl);
+
+        assertThat(nodeInstanceImpl)
+                .hasFieldOrPropertyWithValue("nodeId", fromExternalFormat("node_3"));
+    }
+
+    @Test
+    public void testMigrationNodeNotMigratedWrongProcess() {
+        MigrationPlanService service = new MigrationPlanService();
+        WorkflowProcessInstanceImpl processImpl = new RuleFlowProcessInstance();
+        processImpl.setProcess(new DummyProcess("process_C", "1"));
+        ExtendedNodeInstanceImpl nodeInstanceImpl = new ExtendedNodeInstanceImpl() {
+        };
+        nodeInstanceImpl.setProcessInstance(processImpl);
+        nodeInstanceImpl.setNodeId(fromExternalFormat("node_3"));
+        service.migrateNodeElement(nodeInstanceImpl);
+
+        assertThat(nodeInstanceImpl)
+                .hasFieldOrPropertyWithValue("nodeId", fromExternalFormat("node_3"));
+    }
+}
diff --git a/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_invalid_migration.invalid b/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_invalid_migration.invalid
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration.mpf b/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration.mpf
new file mode 100644
index 0000000000..98d93052b2
--- /dev/null
+++ b/jbpm/jbpm-flow-migration/src/test/resources/META-INF/migration-plan/simple_migration.mpf
@@ -0,0 +1,23 @@
+{
+    "name" : "my simple migration",
+    "processMigrationPlan" : {
+        "sourceProcessDefinition" : {
+            "processId" : "process_A",
+            "processVersion" : "1"
+        },
+        "targetProcessDefinition" : {
+            "processId" : "process_B",
+            "processVersion" : "2"
+        },
+        "nodeInstanceMigrationPlan" : [
+            {
+                "sourceNodeId" : "node_1",
+                "targetNodeId" : "node_2"
+            },
+            {
+                "sourceNodeId" : "node_2",
+                "targetNodeId" : "node_3"
+            }
+        ]
+    }
+}
diff --git a/jbpm/jbpm-flow/pom.xml b/jbpm/jbpm-flow/pom.xml
index bdc73748c1..d0fc15edb2 100755
--- a/jbpm/jbpm-flow/pom.xml
+++ b/jbpm/jbpm-flow/pom.xml
@@ -109,7 +109,6 @@
       <groupId>jakarta.xml.bind</groupId>
       <artifactId>jakarta.xml.bind-api</artifactId>
       <scope>provided</scope>
-      <version>4.0.1</version>
     </dependency>
 
     <dependency>
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationHandler.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationHandler.java
index d88e439aad..e5fd52657a 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationHandler.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationHandler.java
@@ -37,7 +37,7 @@ public class CompensationHandler implements ExceptionHandler, Serializable {
     }
 
     public String toString() {
-        return "Compensation Handler [" + this.node.getName() + ", " + this.node.getMetaData().get("UniqueId") + "]";
+        return "Compensation Handler [" + this.node.getName() + ", " + this.node.getUniqueId() + "]";
     }
 
 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationScope.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationScope.java
index 65904be02d..878864fe8d 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationScope.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationScope.java
@@ -51,7 +51,7 @@ public class CompensationScope extends ExceptionScope {
                         "(" + contextContainer.getClass().getSimpleName() + ")";
         super.setContextContainer(contextContainer);
         if (contextContainer instanceof NodeImpl) {
-            containerId = (String) ((NodeImpl) contextContainer).getMetaData("UniqueId");
+            containerId = ((NodeImpl) contextContainer).getUniqueId();
         } else if (contextContainer instanceof RuleFlowProcess) {
             containerId = ((Process) contextContainer).getId();
         }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/event/EventTypeFilter.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/event/EventTypeFilter.java
index 4fa6c9b2e0..6177d6cbcc 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/event/EventTypeFilter.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/event/EventTypeFilter.java
@@ -61,6 +61,7 @@ public class EventTypeFilter implements EventFilter, Serializable {
 
     @Override
     public boolean acceptsEvent(String type, Object event, Function<String, Object> resolver) {
+        logger.info("This event is subscribed to a message ref {} {}", type, event);
         if (resolver == null) {
             return this.type != null && this.type.equals(type);
         }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/KogitoProcessContextImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/KogitoProcessContextImpl.java
index 0ef0f96384..d562db27a7 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/KogitoProcessContextImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/KogitoProcessContextImpl.java
@@ -23,8 +23,6 @@ import java.util.Map;
 
 import org.drools.core.process.AbstractProcessContext;
 import org.kie.api.runtime.KieRuntime;
-import org.kie.api.runtime.process.CaseAssignment;
-import org.kie.api.runtime.process.CaseData;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoProcessContext;
 import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
@@ -54,16 +52,6 @@ public class KogitoProcessContextImpl extends AbstractProcessContext implements
         return InternalProcessRuntime.asKogitoProcessRuntime(getKieRuntime());
     }
 
-    @Override
-    public CaseAssignment getCaseAssignment() {
-        throw new UnsupportedOperationException();
-    }
-
-    @Override
-    public CaseData getCaseData() {
-        throw new UnsupportedOperationException();
-    }
-
     public void setContextData(Map<String, Object> contextData) {
         this.contextData = contextData;
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/command/MigrateProcessInstanceCommand.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/command/MigrateProcessInstanceCommand.java
index bd12831690..ca6b47a19e 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/command/MigrateProcessInstanceCommand.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/command/MigrateProcessInstanceCommand.java
@@ -27,6 +27,7 @@ import org.jbpm.workflow.instance.NodeInstanceContainer;
 import org.jbpm.workflow.instance.impl.NodeInstanceImpl;
 import org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl;
 import org.kie.api.command.ExecutableCommand;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.definition.process.WorkflowProcess;
 import org.kie.api.runtime.Context;
 import org.kie.api.runtime.KieSession;
@@ -55,14 +56,14 @@ public class MigrateProcessInstanceCommand implements ExecutableCommand<Void>, K
     private String processId;
 
     @XmlElement
-    private Map<String, Long> nodeMapping;
+    private Map<WorkflowElementIdentifier, WorkflowElementIdentifier> nodeMapping;
 
     public MigrateProcessInstanceCommand(String processInstanceId, String processId) {
         this.processInstanceId = processInstanceId;
         this.processId = processId;
     }
 
-    public MigrateProcessInstanceCommand(String processInstanceId, String processId, Map<String, Long> nodeMapping) {
+    public MigrateProcessInstanceCommand(String processInstanceId, String processId, Map<WorkflowElementIdentifier, WorkflowElementIdentifier> nodeMapping) {
         this.processInstanceId = processInstanceId;
         this.processId = processId;
         this.nodeMapping = nodeMapping;
@@ -86,11 +87,11 @@ public class MigrateProcessInstanceCommand implements ExecutableCommand<Void>, K
         this.processId = processId;
     }
 
-    public Map<String, Long> getNodeMapping() {
+    public Map<WorkflowElementIdentifier, WorkflowElementIdentifier> getNodeMapping() {
         return nodeMapping;
     }
 
-    public void setNodeMapping(Map<String, Long> nodeMapping) {
+    public void setNodeMapping(Map<WorkflowElementIdentifier, WorkflowElementIdentifier> nodeMapping) {
         this.nodeMapping = nodeMapping;
     }
 
@@ -126,10 +127,10 @@ public class MigrateProcessInstanceCommand implements ExecutableCommand<Void>, K
         return null;
     }
 
-    private void updateNodeInstances(NodeInstanceContainer nodeInstanceContainer, Map<String, Long> nodeMapping) {
+    private void updateNodeInstances(NodeInstanceContainer nodeInstanceContainer, Map<WorkflowElementIdentifier, WorkflowElementIdentifier> nodeMapping) {
         for (NodeInstance nodeInstance : nodeInstanceContainer.getNodeInstances()) {
-            String oldNodeId = ((NodeImpl) ((org.jbpm.workflow.instance.NodeInstance) nodeInstance).getNode()).getUniqueId();
-            Long newNodeId = nodeMapping.get(oldNodeId);
+            WorkflowElementIdentifier oldNodeId = ((NodeImpl) ((org.jbpm.workflow.instance.NodeInstance) nodeInstance).getNode()).getId();
+            WorkflowElementIdentifier newNodeId = nodeMapping.get(oldNodeId);
             if (newNodeId == null) {
                 newNodeId = nodeInstance.getNodeId();
             }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/CompensationScopeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/CompensationScopeInstance.java
index 544b422cd7..18c4f882e6 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/CompensationScopeInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/context/exception/CompensationScopeInstance.java
@@ -114,7 +114,7 @@ public class CompensationScopeInstance extends ExceptionScopeInstance {
                 } else if (handlerNode instanceof EventSubProcessNode) {
                     // Check that subprocess parent has completed. 
                     List<String> completedIds = processInstance.getCompletedNodeIds();
-                    if (completedIds.contains(((NodeImpl) ((Node) handlerNode).getParentContainer()).getMetaData("UniqueId"))) {
+                    if (completedIds.contains(((NodeImpl) ((Node) handlerNode).getParentContainer()).getUniqueId())) {
                         NodeInstance subProcessNodeInstance =
                                 (nodeInstanceContainer).getNodeInstance((org.kie.api.definition.process.Node) ((Node) handlerNode).getParentContainer());
                         compensationInstances.add(subProcessNodeInstance);
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessEventSupportImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessEventSupportImpl.java
index 4bbd231485..9d3f804397 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessEventSupportImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/KogitoProcessEventSupportImpl.java
@@ -210,6 +210,12 @@ public class KogitoProcessEventSupportImpl implements KogitoProcessEventSupport
         notifyAllListeners(l -> l.onMessage(event));
     }
 
+    @Override
+    public void fireOnMigration(final KogitoProcessInstance processInstance, KieRuntime kruntime) {
+        ProcessMigrationEventImpl event = new ProcessMigrationEventImpl(processInstance, kruntime, "System");
+        notifyAllListeners(l -> l.onMigration(event));
+    }
+
     // users tasks events
     @Override
     public void fireOnUserTaskNotStartedDeadline(KogitoProcessInstance instance,
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationHandler.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/ProcessMigrationEventImpl.java
old mode 100755
new mode 100644
similarity index 60%
copy from jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationHandler.java
copy to jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/ProcessMigrationEventImpl.java
index d88e439aad..8f3d64c75b
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/core/context/exception/CompensationHandler.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/event/ProcessMigrationEventImpl.java
@@ -16,28 +16,23 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.jbpm.process.core.context.exception;
+package org.jbpm.process.instance.event;
 
-import java.io.Serializable;
+import org.kie.api.event.process.ProcessMigrationEvent;
+import org.kie.api.runtime.KieRuntime;
+import org.kie.api.runtime.process.ProcessInstance;
 
-import org.kie.api.definition.process.Node;
-
-public class CompensationHandler implements ExceptionHandler, Serializable {
+public class ProcessMigrationEventImpl extends ProcessEvent implements ProcessMigrationEvent {
 
     private static final long serialVersionUID = 510l;
 
-    private Node node;
-
-    public Node getnode() {
-        return node;
-    }
-
-    public void setNode(Node node) {
-        this.node = node;
+    public ProcessMigrationEventImpl(ProcessInstance instance, KieRuntime kruntime, String identity) {
+        super(instance, kruntime, identity);
     }
 
+    @Override
     public String toString() {
-        return "Compensation Handler [" + this.node.getName() + ", " + this.node.getMetaData().get("UniqueId") + "]";
+        return "==>[ProcessMigratedEventImpl(name=" + getProcessInstance().getProcessName() + "; id=" + getProcessInstance().getProcessId() + ")]";
     }
 
-}
+}
\ No newline at end of file
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/ProcessInstanceImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/ProcessInstanceImpl.java
index b78c644f7a..98ea0bbee8 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/ProcessInstanceImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/ProcessInstanceImpl.java
@@ -118,11 +118,19 @@ public abstract class ProcessInstanceImpl implements ProcessInstance,
         this.process = process;
     }
 
+    public void setInternalProcess(Process process) {
+        this.process = process;
+    }
+
     @Override
     public String getProcessVersion() {
         return processVersion;
     }
 
+    public void setProcessVersion(String processVersion) {
+        this.processVersion = processVersion;
+    }
+
     @Override
     public String getProcessId() {
         return processId;
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/actions/AbstractNodeInstanceAction.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/actions/AbstractNodeInstanceAction.java
index f220dd4887..569a3faceb 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/actions/AbstractNodeInstanceAction.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/actions/AbstractNodeInstanceAction.java
@@ -51,7 +51,7 @@ public abstract class AbstractNodeInstanceAction implements Action, Serializable
     private static NodeInstance findNodeByUniqueId(Collection<NodeInstance> nodeInstances, String uniqueId) {
         if (nodeInstances != null && !nodeInstances.isEmpty()) {
             for (NodeInstance nInstance : nodeInstances) {
-                String nodeUniqueId = (String) nInstance.getNode().getMetaData().get("UniqueId");
+                String nodeUniqueId = nInstance.getNode().getUniqueId();
                 if (uniqueId.equals(nodeUniqueId)) {
                     return nInstance;
                 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemDecoratorImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemDecoratorImpl.java
index bea5b2cbb6..4f22848d30 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemDecoratorImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/process/instance/impl/humantask/HumanTaskWorkItemDecoratorImpl.java
@@ -29,6 +29,7 @@ import org.drools.core.common.InternalKnowledgeRuntime;
 import org.jbpm.process.instance.InternalProcessRuntime;
 import org.jbpm.workflow.instance.NodeInstance;
 import org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.event.KogitoProcessEventSupport;
 import org.kie.kogito.internal.process.event.KogitoProcessEventSupport.AssignmentType;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
@@ -269,7 +270,7 @@ public class HumanTaskWorkItemDecoratorImpl implements InternalHumanTaskWorkItem
     }
 
     @Override
-    public long getNodeId() {
+    public WorkflowElementIdentifier getNodeId() {
         return delegate.getNodeId();
     }
 
@@ -374,8 +375,8 @@ public class HumanTaskWorkItemDecoratorImpl implements InternalHumanTaskWorkItem
     }
 
     @Override
-    public void setNodeId(long deploymentId) {
-        delegate.setNodeId(deploymentId);
+    public void setNodeId(WorkflowElementIdentifier nodeIdentifier) {
+        delegate.setNodeId(nodeIdentifier);
     }
 
     @Override
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowNodeContainerFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowNodeContainerFactory.java
index d0c5b62220..66c1e2e16d 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowNodeContainerFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowNodeContainerFactory.java
@@ -53,6 +53,7 @@ import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.ConnectionImpl;
 import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
 import org.kie.api.definition.process.Node;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 import static org.jbpm.ruleflow.core.Metadata.ASSOCIATION;
 import static org.jbpm.ruleflow.core.Metadata.HIDDEN;
@@ -64,111 +65,111 @@ public abstract class RuleFlowNodeContainerFactory<T extends RuleFlowNodeContain
     public static final String METHOD_CONNECTION = "connection";
     public static final String METHOD_ASSOCIATION = "association";
 
-    protected RuleFlowNodeContainerFactory(P nodeContainerFactory, NodeContainer nodeContainer, NodeContainer node, Object id) {
+    protected RuleFlowNodeContainerFactory(P nodeContainerFactory, NodeContainer nodeContainer, NodeContainer node, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, node, id);
     }
 
-    public StartNodeFactory<T> startNode(long id) {
+    public StartNodeFactory<T> startNode(WorkflowElementIdentifier id) {
         return new StartNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public EndNodeFactory<T> endNode(long id) {
+    public EndNodeFactory<T> endNode(WorkflowElementIdentifier id) {
         return new EndNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public CatchLinkNodeFactory<T> catchLinkNode(long id) {
+    public CatchLinkNodeFactory<T> catchLinkNode(WorkflowElementIdentifier id) {
         return new CatchLinkNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public ThrowLinkNodeFactory<T> throwLinkNode(long id) {
+    public ThrowLinkNodeFactory<T> throwLinkNode(WorkflowElementIdentifier id) {
         return new ThrowLinkNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public ActionNodeFactory<T> actionNode(long id) {
+    public ActionNodeFactory<T> actionNode(WorkflowElementIdentifier id) {
         return new ActionNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public MilestoneNodeFactory<T> milestoneNode(long id) {
+    public MilestoneNodeFactory<T> milestoneNode(WorkflowElementIdentifier id) {
         return new MilestoneNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public TimerNodeFactory<T> timerNode(long id) {
+    public TimerNodeFactory<T> timerNode(WorkflowElementIdentifier id) {
         return new TimerNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public HumanTaskNodeFactory<T> humanTaskNode(long id) {
+    public HumanTaskNodeFactory<T> humanTaskNode(WorkflowElementIdentifier id) {
         return new HumanTaskNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public SubProcessNodeFactory<T> subProcessNode(long id) {
+    public SubProcessNodeFactory<T> subProcessNode(WorkflowElementIdentifier id) {
         return new SubProcessNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public SplitFactory<T> splitNode(long id) {
+    public SplitFactory<T> splitNode(WorkflowElementIdentifier id) {
         return new SplitFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public JoinFactory<T> joinNode(long id) {
+    public JoinFactory<T> joinNode(WorkflowElementIdentifier id) {
         return new JoinFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public RuleSetNodeFactory<T> ruleSetNode(long id) {
+    public RuleSetNodeFactory<T> ruleSetNode(WorkflowElementIdentifier id) {
         return new RuleSetNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public FaultNodeFactory<T> faultNode(long id) {
+    public FaultNodeFactory<T> faultNode(WorkflowElementIdentifier id) {
         return new FaultNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public EventNodeFactory<T> eventNode(long id) {
+    public EventNodeFactory<T> eventNode(WorkflowElementIdentifier id) {
         return new EventNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public BoundaryEventNodeFactory<T> boundaryEventNode(long id) {
+    public BoundaryEventNodeFactory<T> boundaryEventNode(WorkflowElementIdentifier id) {
         return new BoundaryEventNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public CompositeContextNodeFactory<T> compositeContextNode(long id) {
+    public CompositeContextNodeFactory<T> compositeContextNode(WorkflowElementIdentifier id) {
         return new CompositeContextNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public ForEachNodeFactory<T> forEachNode(long id) {
+    public ForEachNodeFactory<T> forEachNode(WorkflowElementIdentifier id) {
         return new ForEachNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public DynamicNodeFactory<T> dynamicNode(long id) {
+    public DynamicNodeFactory<T> dynamicNode(WorkflowElementIdentifier id) {
         return new DynamicNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public WorkItemNodeFactory<T> workItemNode(long id) {
+    public WorkItemNodeFactory<T> workItemNode(WorkflowElementIdentifier id) {
         return new WorkItemNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public EventSubProcessNodeFactory<T> eventSubProcessNode(long id) {
+    public EventSubProcessNodeFactory<T> eventSubProcessNode(WorkflowElementIdentifier id) {
         return new EventSubProcessNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public StateNodeFactory<T> stateNode(long id) {
+    public StateNodeFactory<T> stateNode(WorkflowElementIdentifier id) {
         return new StateNodeFactory<>((T) this, (NodeContainer) node, id);
     }
 
-    public T connection(long fromId, long toId) {
-        return connection(fromId, toId, fromId + "_" + toId);
+    public T connection(WorkflowElementIdentifier fromId, WorkflowElementIdentifier toId) {
+        return connection(fromId, toId, fromId.toSanitizeString() + "_" + toId.toSanitizeString());
     }
 
-    public T connection(long fromId, long toId, String uniqueId) {
+    public T connection(WorkflowElementIdentifier fromId, WorkflowElementIdentifier toId, String uniqueId) {
         getConnection(fromId, toId, uniqueId);
         return (T) this;
     }
 
-    public T association(long fromId, long toId, String uniqueId) {
+    public T association(WorkflowElementIdentifier fromId, WorkflowElementIdentifier toId, String uniqueId) {
         Connection connection = getConnection(fromId, toId, uniqueId);
         connection.setMetaData(ASSOCIATION, Boolean.TRUE);
         connection.setMetaData(HIDDEN, Boolean.TRUE);
         return (T) this;
     }
 
-    private Connection getConnection(long fromId, long toId, String uniqueId) {
+    private Connection getConnection(WorkflowElementIdentifier fromId, WorkflowElementIdentifier toId, String uniqueId) {
         Node from = ((NodeContainer) node).getNode(fromId);
         Node to = ((NodeContainer) node).getNode(toId);
         Connection connection = new ConnectionImpl(from, CONNECTION_DEFAULT_TYPE, to, CONNECTION_DEFAULT_TYPE);
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowProcessFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowProcessFactory.java
index c9e82a7dfe..881a28be78 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowProcessFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/RuleFlowProcessFactory.java
@@ -53,6 +53,7 @@ import org.jbpm.workflow.core.node.StateBasedNode;
 import org.jbpm.workflow.core.node.Trigger;
 import org.kie.api.definition.process.Node;
 import org.kie.api.definition.process.NodeContainer;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoNode;
 
 import static org.jbpm.process.core.context.exception.ExceptionScope.EXCEPTION_SCOPE;
@@ -66,7 +67,6 @@ import static org.jbpm.ruleflow.core.Metadata.SIGNAL_NAME;
 import static org.jbpm.ruleflow.core.Metadata.TIME_CYCLE;
 import static org.jbpm.ruleflow.core.Metadata.TIME_DATE;
 import static org.jbpm.ruleflow.core.Metadata.TIME_DURATION;
-import static org.jbpm.ruleflow.core.Metadata.UNIQUE_ID;
 import static org.jbpm.workflow.core.impl.ExtendedNodeImpl.EVENT_NODE_EXIT;
 
 public class RuleFlowProcessFactory extends RuleFlowNodeContainerFactory<RuleFlowProcessFactory, RuleFlowProcessFactory> {
@@ -96,13 +96,13 @@ public class RuleFlowProcessFactory extends RuleFlowNodeContainerFactory<RuleFlo
     }
 
     protected RuleFlowProcessFactory(String id, boolean autoComplete) {
-        super(null, null, new RuleFlowProcess(), id);
+        super(null, null, new RuleFlowProcess(), WorkflowElementIdentifierFactory.fromExternalFormat(id));
         getRuleFlowProcess().setAutoComplete(autoComplete);
     }
 
     @Override
-    protected void setId(Object node, Object id) {
-        getRuleFlowProcess().setId((String) id);
+    protected void setId(Object node, WorkflowElementIdentifier id) {
+        getRuleFlowProcess().setId(id.toExternalFormat());
     }
 
     public RuleFlowProcessFactory expressionLanguage(String exprLanguage) {
@@ -289,7 +289,7 @@ public class RuleFlowProcessFactory extends RuleFlowNodeContainerFactory<RuleFlo
         if (timeDuration != null) {
             timer.setDelay(timeDuration);
             timer.setTimeType(Timer.TIME_DURATION);
-            compositeNode.addTimer(timer, timerAction(TIMER_TYPE_PREFIX + attachedTo + "-" + timeDuration + "-" + node.getId()));
+            compositeNode.addTimer(timer, timerAction(TIMER_TYPE_PREFIX + attachedTo + "-" + timeDuration + "-" + node.getId().toExternalFormat()));
         } else if (timeCycle != null) {
             int index = timeCycle.indexOf("###");
             if (index != -1) {
@@ -299,11 +299,12 @@ public class RuleFlowProcessFactory extends RuleFlowNodeContainerFactory<RuleFlo
             }
             timer.setDelay(timeCycle);
             timer.setTimeType(Timer.TIME_CYCLE);
-            compositeNode.addTimer(timer, timerAction(TIMER_TYPE_PREFIX + attachedTo + "-" + timeCycle + (timer.getPeriod() == null ? "" : "###" + timer.getPeriod()) + "-" + node.getId()));
+            compositeNode.addTimer(timer,
+                    timerAction(TIMER_TYPE_PREFIX + attachedTo + "-" + timeCycle + (timer.getPeriod() == null ? "" : "###" + timer.getPeriod()) + "-" + node.getId().toExternalFormat()));
         } else if (timeDate != null) {
             timer.setDate(timeDate);
             timer.setTimeType(Timer.TIME_DATE);
-            compositeNode.addTimer(timer, timerAction(TIMER_TYPE_PREFIX + attachedTo + "-" + timeDate + "-" + node.getId()));
+            compositeNode.addTimer(timer, timerAction(TIMER_TYPE_PREFIX + attachedTo + "-" + timeDate + "-" + node.getId().toExternalFormat()));
         }
 
         if (cancelActivity) {
@@ -387,7 +388,7 @@ public class RuleFlowProcessFactory extends RuleFlowNodeContainerFactory<RuleFlo
         Node node = null;
         // try looking for a node with same "UniqueId" (in metadata)
         for (Node containerNode : nodeContainer.getNodes()) {
-            if (nodeRef.equals(containerNode.getMetaData().get(UNIQUE_ID))) {
+            if (nodeRef.equals(containerNode.getUniqueId())) {
                 node = containerNode;
                 break;
             }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/WorkflowElementIdentifierFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/WorkflowElementIdentifierFactory.java
new file mode 100644
index 0000000000..9c0e016f5f
--- /dev/null
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/WorkflowElementIdentifierFactory.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.jbpm.ruleflow.core;
+
+import java.util.UUID;
+
+import org.kie.api.definition.process.WorkflowElementIdentifier;
+
+public class WorkflowElementIdentifierFactory implements WorkflowElementIdentifier {
+
+    private String elementId;
+
+    public static WorkflowElementIdentifier fromExternalFormat(Long elementId) {
+        return fromExternalFormat(String.valueOf(elementId));
+    }
+
+    public static WorkflowElementIdentifier fromExternalFormat(String elementId) {
+        return new WorkflowElementIdentifierFactory(elementId);
+    }
+
+    public static WorkflowElementIdentifier newRandom() {
+        return new WorkflowElementIdentifierFactory("jbpm-" + UUID.randomUUID().toString());
+    }
+
+    public WorkflowElementIdentifierFactory(String elementId) {
+        this.elementId = elementId;
+    }
+
+    @Override
+    public <T> T toValue() {
+        return (T) elementId;
+    }
+
+    @Override
+    public String toString() {
+        return "[uuid=" + elementId + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        return elementId.hashCode();
+    }
+
+    @Override
+    public String toExternalFormat() {
+        return this.elementId;
+    }
+
+    @Override
+    public int compareTo(WorkflowElementIdentifier o) {
+        return this.elementId.compareTo(((WorkflowElementIdentifierFactory) o).elementId);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        WorkflowElementIdentifierFactory other = (WorkflowElementIdentifierFactory) obj;
+        return elementId.equals(other.elementId);
+    }
+
+    @Override
+    public String toSanitizeString() {
+        return toExternalFormat().replaceAll("-", "_");
+    }
+
+}
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractCompositeNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractCompositeNodeFactory.java
index 160e23e008..0befff9481 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractCompositeNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractCompositeNodeFactory.java
@@ -25,14 +25,15 @@ import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.CompositeContextNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 @SuppressWarnings("unchecked")
 public abstract class AbstractCompositeNodeFactory<T extends RuleFlowNodeContainerFactory<T, P>, P extends RuleFlowNodeContainerFactory<P, ?>> extends RuleFlowNodeContainerFactory<T, P> {
 
-    private long linkedIncomingNodeId = -1;
-    private long linkedOutgoingNodeId = -1;
+    private WorkflowElementIdentifier linkedIncomingNodeId;
+    private WorkflowElementIdentifier linkedOutgoingNodeId;
 
-    protected AbstractCompositeNodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, NodeContainer node, Object id) {
+    protected AbstractCompositeNodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, NodeContainer node, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, node, id);
     }
 
@@ -79,7 +80,7 @@ public abstract class AbstractCompositeNodeFactory<T extends RuleFlowNodeContain
         return (T) this;
     }
 
-    public T linkIncomingConnections(long nodeId) {
+    public T linkIncomingConnections(WorkflowElementIdentifier nodeId) {
         this.linkedIncomingNodeId = nodeId;
         return (T) this;
     }
@@ -89,19 +90,19 @@ public abstract class AbstractCompositeNodeFactory<T extends RuleFlowNodeContain
         return (T) this;
     }
 
-    public T linkOutgoingConnections(long nodeId) {
+    public T linkOutgoingConnections(WorkflowElementIdentifier nodeId) {
         this.linkedOutgoingNodeId = nodeId;
         return (T) this;
     }
 
     @Override
     public P done() {
-        if (linkedIncomingNodeId != -1) {
+        if (linkedIncomingNodeId != null) {
             getCompositeNode().linkIncomingConnections(
                     Node.CONNECTION_DEFAULT_TYPE,
                     linkedIncomingNodeId, Node.CONNECTION_DEFAULT_TYPE);
         }
-        if (linkedOutgoingNodeId != -1) {
+        if (linkedOutgoingNodeId != null) {
             getCompositeNode().linkOutgoingConnections(
                     linkedOutgoingNodeId, Node.CONNECTION_DEFAULT_TYPE,
                     Node.CONNECTION_DEFAULT_TYPE);
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractEventNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractEventNodeFactory.java
index c1bf9c6e08..d2dd920998 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractEventNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractEventNodeFactory.java
@@ -24,10 +24,11 @@ import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.EventNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public abstract class AbstractEventNodeFactory<T extends AbstractEventNodeFactory<T, P>, P extends RuleFlowNodeContainerFactory<P, ?>> extends ExtendedNodeFactory<T, P> {
 
-    protected AbstractEventNodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, Node node, long id) {
+    protected AbstractEventNodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, Node node, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, node, id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractWorkItemNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractWorkItemNodeFactory.java
index 71e7f27abf..63242254bb 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractWorkItemNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/AbstractWorkItemNodeFactory.java
@@ -29,6 +29,7 @@ import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.WorkItemNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.process.workitems.WorkParametersFactory;
 
 public class AbstractWorkItemNodeFactory<T extends AbstractWorkItemNodeFactory<T, P>, P extends RuleFlowNodeContainerFactory<P, ?>> extends StateBasedNodeFactory<T, P> {
@@ -36,7 +37,7 @@ public class AbstractWorkItemNodeFactory<T extends AbstractWorkItemNodeFactory<T
     public static final String METHOD_WORK_NAME = "workName";
     public static final String METHOD_WORK_PARAMETER = "workParameter";
 
-    protected AbstractWorkItemNodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, Node node, long id) {
+    protected AbstractWorkItemNodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, Node node, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, node, id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ActionNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ActionNodeFactory.java
index 50c9bd3c38..9ee08577ce 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ActionNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ActionNodeFactory.java
@@ -24,6 +24,7 @@ import org.jbpm.workflow.core.DroolsAction;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
 import org.jbpm.workflow.core.node.ActionNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class ActionNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends NodeFactory<ActionNodeFactory<T>, T> implements SupportsAction<ActionNodeFactory<T>, T> {
 
@@ -31,7 +32,7 @@ public class ActionNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> ext
 
     public ActionNodeFactory(T nodeContainerFactory,
             NodeContainer nodeContainer,
-            long id) {
+            WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new ActionNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/BoundaryEventNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/BoundaryEventNodeFactory.java
index 2cace34865..437857efce 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/BoundaryEventNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/BoundaryEventNodeFactory.java
@@ -28,6 +28,7 @@ import org.jbpm.ruleflow.core.Metadata;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.BoundaryEventNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 import static org.jbpm.ruleflow.core.Metadata.ATTACHED_TO;
 
@@ -38,7 +39,7 @@ public class BoundaryEventNodeFactory<T extends RuleFlowNodeContainerFactory<T,
 
     private String attachedToUniqueId;
 
-    public BoundaryEventNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public BoundaryEventNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new BoundaryEventNode(), id);
 
     }
@@ -47,8 +48,8 @@ public class BoundaryEventNodeFactory<T extends RuleFlowNodeContainerFactory<T,
         return (BoundaryEventNode) getNode();
     }
 
-    public BoundaryEventNodeFactory<T> attachedTo(long attachedToId) {
-        return attachedTo((String) nodeContainer.getNode(attachedToId).getMetaData().get("UniqueId"));
+    public BoundaryEventNodeFactory<T> attachedTo(WorkflowElementIdentifier attachedToId) {
+        return attachedTo((String) nodeContainer.getNode(attachedToId).getUniqueId());
     }
 
     public BoundaryEventNodeFactory<T> attachedTo(String attachedToId) {
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/CatchLinkNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/CatchLinkNodeFactory.java
index 051b4cd72b..136fd5f13c 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/CatchLinkNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/CatchLinkNodeFactory.java
@@ -21,10 +21,11 @@ package org.jbpm.ruleflow.core.factory;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.CatchLinkNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class CatchLinkNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends ExtendedNodeFactory<CatchLinkNodeFactory<T>, T> {
 
-    public CatchLinkNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public CatchLinkNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new CatchLinkNode(), id);
     }
 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/CompositeContextNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/CompositeContextNodeFactory.java
index 929633060d..a57a1a7358 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/CompositeContextNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/CompositeContextNodeFactory.java
@@ -21,6 +21,7 @@ package org.jbpm.ruleflow.core.factory;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.CompositeContextNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class CompositeContextNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends AbstractCompositeNodeFactory<CompositeContextNodeFactory<T>, T> {
 
@@ -29,7 +30,7 @@ public class CompositeContextNodeFactory<T extends RuleFlowNodeContainerFactory<
     public static final String METHOD_LINK_OUTGOING_CONNECTIONS = "linkOutgoingConnections";
     public static final String METHOD_AUTO_COMPLETE = "autoComplete";
 
-    public CompositeContextNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public CompositeContextNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new CompositeContextNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ConstraintFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ConstraintFactory.java
index c444132299..1a74594ce8 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ConstraintFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ConstraintFactory.java
@@ -21,12 +21,13 @@ package org.jbpm.ruleflow.core.factory;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.impl.ConnectionRef;
 import org.jbpm.workflow.core.impl.ConstraintImpl;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class ConstraintFactory<T extends SplitFactory<?>> {
     private T parent;
     private ConstraintImpl constraintImpl;
 
-    public ConstraintFactory(T parent, long toNodeId, String name, String type, String dialect, String constraint) {
+    public ConstraintFactory(T parent, WorkflowElementIdentifier toNodeId, String name, String type, String dialect, String constraint) {
         this.parent = parent;
         constraintImpl = new ConstraintImpl();
         constraintImpl.setName(name);
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/DynamicNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/DynamicNodeFactory.java
index 623004cff2..8c9dffb8ce 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/DynamicNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/DynamicNodeFactory.java
@@ -23,6 +23,7 @@ import java.util.function.Predicate;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.DynamicNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.runtime.process.ProcessContext;
 
 public class DynamicNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends AbstractCompositeNodeFactory<DynamicNodeFactory<T>, T> {
@@ -31,7 +32,7 @@ public class DynamicNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> ex
     public static final String METHOD_ACTIVATION_EXPRESSION = "activationExpression";
     public static final String METHOD_COMPLETION_EXPRESSION = "completionExpression";
 
-    public DynamicNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public DynamicNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new DynamicNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EndNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EndNodeFactory.java
index bc144765af..b354c5c10f 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EndNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EndNodeFactory.java
@@ -27,6 +27,7 @@ import org.jbpm.workflow.core.DroolsAction;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
 import org.jbpm.workflow.core.node.EndNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 import static org.jbpm.ruleflow.core.Metadata.ACTION;
 
@@ -35,7 +36,7 @@ public class EndNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extend
     public static final String METHOD_TERMINATE = "terminate";
     public static final String METHOD_ACTION = "action";
 
-    public EndNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public EndNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new EndNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventNodeFactory.java
index 6c57d0d5a4..335c167562 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventNodeFactory.java
@@ -21,6 +21,7 @@ package org.jbpm.ruleflow.core.factory;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.EventNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class EventNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends AbstractEventNodeFactory<EventNodeFactory<T>, T> {
 
@@ -29,7 +30,7 @@ public class EventNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> exte
     public static final String METHOD_VARIABLE_NAME = "variableName";
     public static final String METHOD_INPUT_VARIABLE_NAME = "inputVariableName";
 
-    public EventNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public EventNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new EventNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventSubProcessNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventSubProcessNodeFactory.java
index 3abd7b7401..1244b34993 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventSubProcessNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/EventSubProcessNodeFactory.java
@@ -22,13 +22,14 @@ import org.jbpm.process.core.event.EventTypeFilter;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.EventSubProcessNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class EventSubProcessNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends AbstractCompositeNodeFactory<EventSubProcessNodeFactory<T>, T> {
 
     public static final String METHOD_KEEP_ACTIVE = "keepActive";
     public static final String METHOD_EVENT = "event";
 
-    public EventSubProcessNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public EventSubProcessNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new EventSubProcessNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ExtendedNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ExtendedNodeFactory.java
index 0977e9d2c9..0653d5f6df 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ExtendedNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ExtendedNodeFactory.java
@@ -27,10 +27,11 @@ import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
 import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public abstract class ExtendedNodeFactory<T extends NodeFactory<T, P>, P extends RuleFlowNodeContainerFactory<P, ?>> extends NodeFactory<T, P> {
 
-    protected ExtendedNodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, Node node, long id) {
+    protected ExtendedNodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, Node node, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, node, id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/FaultNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/FaultNodeFactory.java
index ab948994e0..2048dd10f5 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/FaultNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/FaultNodeFactory.java
@@ -21,6 +21,7 @@ package org.jbpm.ruleflow.core.factory;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.FaultNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class FaultNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends ExtendedNodeFactory<FaultNodeFactory<T>, T> {
 
@@ -28,7 +29,7 @@ public class FaultNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> exte
     public static final String METHOD_FAULT_VARIABLE = "faultVariable";
     public static final String METHOD_TERMINATE_PARENT = "terminateParent";
 
-    public FaultNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public FaultNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new FaultNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ForEachNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ForEachNodeFactory.java
index 4ee362d81b..501499530e 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ForEachNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ForEachNodeFactory.java
@@ -27,6 +27,7 @@ import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.DataDefinition;
 import org.jbpm.workflow.core.node.CompositeContextNode;
 import org.jbpm.workflow.core.node.ForEachNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.utils.KogitoTags;
 
 public class ForEachNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends AbstractCompositeNodeFactory<ForEachNodeFactory<T>, T> {
@@ -38,8 +39,8 @@ public class ForEachNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> ex
     public static final String METHOD_OUTPUT_TEMP = "tempVariable";
     public static final String METHOD_SEQUENTIAL = "sequential";
 
-    public ForEachNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
-        super(nodeContainerFactory, nodeContainer, new ForEachNode(), id);
+    public ForEachNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
+        super(nodeContainerFactory, nodeContainer, new ForEachNode(id), id);
     }
 
     protected ForEachNode getForEachNode() {
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/HumanTaskNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/HumanTaskNodeFactory.java
index 312e0d4781..1b86be7ad0 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/HumanTaskNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/HumanTaskNodeFactory.java
@@ -23,6 +23,7 @@ import org.jbpm.process.core.impl.WorkImpl;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.HumanTaskNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class HumanTaskNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends AbstractWorkItemNodeFactory<HumanTaskNodeFactory<T>, T> {
 
@@ -34,7 +35,7 @@ public class HumanTaskNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>>
     public static final String WORK_SKIPPABLE = "Skippable";
     public static final String WORK_CONTENT = "Content";
 
-    public HumanTaskNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public HumanTaskNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new HumanTaskNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/JoinFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/JoinFactory.java
index 84996396b4..b087fc24b8 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/JoinFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/JoinFactory.java
@@ -21,12 +21,13 @@ package org.jbpm.ruleflow.core.factory;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.Join;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class JoinFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends NodeFactory<JoinFactory<T>, T> {
 
     public static final String METHOD_TYPE = "type";
 
-    public JoinFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public JoinFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new Join(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/MilestoneNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/MilestoneNodeFactory.java
index ac0cb26d0c..4592c24447 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/MilestoneNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/MilestoneNodeFactory.java
@@ -23,13 +23,14 @@ import java.util.function.Predicate;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.MilestoneNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.runtime.process.ProcessContext;
 
 public class MilestoneNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends StateBasedNodeFactory<MilestoneNodeFactory<T>, T> {
 
     public static final String METHOD_CONDITION = "condition";
 
-    public MilestoneNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public MilestoneNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new MilestoneNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/NodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/NodeFactory.java
index 2c990f3feb..bcbfb1f475 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/NodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/NodeFactory.java
@@ -22,6 +22,7 @@ import org.jbpm.process.core.context.variable.Mappable;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.NodeContainer;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public abstract class NodeFactory<T extends NodeFactory<T, P>, P extends RuleFlowNodeContainerFactory<P, ?>> implements MappableNodeFactory<T> {
 
@@ -33,7 +34,7 @@ public abstract class NodeFactory<T extends NodeFactory<T, P>, P extends RuleFlo
     protected NodeContainer nodeContainer;
     protected P nodeContainerFactory;
 
-    protected NodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, Object node, Object id) {
+    protected NodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, Object node, WorkflowElementIdentifier id) {
         this.nodeContainerFactory = nodeContainerFactory;
         this.nodeContainer = nodeContainer;
         this.node = node;
@@ -43,8 +44,8 @@ public abstract class NodeFactory<T extends NodeFactory<T, P>, P extends RuleFlo
         }
     }
 
-    protected void setId(Object node, Object id) {
-        ((Node) node).setId((long) id);
+    protected void setId(Object node, WorkflowElementIdentifier id) {
+        ((Node) node).setId(id);
     }
 
     public Node getNode() {
@@ -69,4 +70,5 @@ public abstract class NodeFactory<T extends NodeFactory<T, P>, P extends RuleFlo
     public Mappable getMappableNode() {
         return (Mappable) node;
     }
+
 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/RuleSetNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/RuleSetNodeFactory.java
index 07349627bb..1adf7764cb 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/RuleSetNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/RuleSetNodeFactory.java
@@ -26,6 +26,7 @@ import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.RuleSetNode;
 import org.jbpm.workflow.core.node.RuleUnitFactory;
 import org.jbpm.workflow.instance.rule.RuleType;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.runtime.KieRuntime;
 import org.kie.kogito.decision.DecisionModel;
 
@@ -38,7 +39,7 @@ public class RuleSetNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> ex
     public static final String METHOD_DECISION = "decision";
     public static final String METHOD_PARAMETER = "parameter";
 
-    public RuleSetNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public RuleSetNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new RuleSetNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/SplitFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/SplitFactory.java
index b237cbbcc2..63228ad23e 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/SplitFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/SplitFactory.java
@@ -25,13 +25,14 @@ import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.ConnectionRef;
 import org.jbpm.workflow.core.node.Split;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class SplitFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends NodeFactory<SplitFactory<T>, T> {
 
     public static final String METHOD_TYPE = "type";
     public static final String METHOD_CONSTRAINT = "constraint";
 
-    public SplitFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public SplitFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new Split(), id);
     }
 
@@ -44,27 +45,27 @@ public class SplitFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends
         return this;
     }
 
-    public SplitFactory<T> constraint(long toNodeId, String name, String type, String dialect, String constraint) {
+    public SplitFactory<T> constraint(WorkflowElementIdentifier toNodeId, String name, String type, String dialect, String constraint) {
         return constraint(toNodeId, name, type, dialect, constraint, 0);
     }
 
-    public SplitFactory<T> constraint(long toNodeId, String name, String type, String dialect, String constraint, int priority) {
+    public SplitFactory<T> constraint(WorkflowElementIdentifier toNodeId, String name, String type, String dialect, String constraint, int priority) {
         return constraint(toNodeId, name, type, dialect, constraint, priority, false);
     }
 
-    public SplitFactory<T> constraint(long toNodeId, String name, String type, String dialect, String constraint, int priority, boolean isDefault) {
+    public SplitFactory<T> constraint(WorkflowElementIdentifier toNodeId, String name, String type, String dialect, String constraint, int priority, boolean isDefault) {
         return constraintBuilder(toNodeId, name, type, dialect, constraint).withDefault(isDefault).priority(priority).done();
     }
 
-    public ConstraintFactory<SplitFactory<T>> constraintBuilder(long toNodeId, String name, String type, String dialect, String constraint) {
+    public ConstraintFactory<SplitFactory<T>> constraintBuilder(WorkflowElementIdentifier toNodeId, String name, String type, String dialect, String constraint) {
         return new ConstraintFactory<>(this, toNodeId, name, type, dialect, constraint);
     }
 
-    public SplitFactory<T> constraint(long toNodeId, String name, String type, String dialect, ReturnValueEvaluator evaluator, int priority) {
+    public SplitFactory<T> constraint(WorkflowElementIdentifier toNodeId, String name, String type, String dialect, ReturnValueEvaluator evaluator, int priority) {
         return constraint(toNodeId, name, type, dialect, evaluator, priority, false);
     }
 
-    public SplitFactory<T> constraint(long toNodeId, String name, String type, String dialect, ReturnValueEvaluator evaluator, int priority, boolean isDefault) {
+    public SplitFactory<T> constraint(WorkflowElementIdentifier toNodeId, String name, String type, String dialect, ReturnValueEvaluator evaluator, int priority, boolean isDefault) {
         ReturnValueConstraintEvaluator constraintImpl = new ReturnValueConstraintEvaluator();
         constraintImpl.setName(name);
         constraintImpl.setType(type);
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StartNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StartNodeFactory.java
index adc2cb49e0..27954c9d1f 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StartNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StartNodeFactory.java
@@ -27,6 +27,7 @@ import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.DataAssociation;
 import org.jbpm.workflow.core.node.EventTrigger;
 import org.jbpm.workflow.core.node.StartNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class StartNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends NodeFactory<StartNodeFactory<T>, T> {
 
@@ -34,7 +35,7 @@ public class StartNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> exte
     public static final String METHOD_TRIGGER = "trigger";
     public static final String METHOD_TIMER = "timer";
 
-    public StartNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public StartNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new StartNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StateBasedNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StateBasedNodeFactory.java
index adfeda8241..2899edf814 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StateBasedNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StateBasedNodeFactory.java
@@ -24,12 +24,13 @@ import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
 import org.jbpm.workflow.core.node.StateBasedNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public abstract class StateBasedNodeFactory<T extends StateBasedNodeFactory<T, P>, P extends RuleFlowNodeContainerFactory<P, ?>> extends ExtendedNodeFactory<T, P> {
 
     public static final String METHOD_TIMER = "timer";
 
-    protected StateBasedNodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, Node node, long id) {
+    protected StateBasedNodeFactory(P nodeContainerFactory, NodeContainer nodeContainer, Node node, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, node, id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StateNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StateNodeFactory.java
index 688d6edd02..83435dbad9 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StateNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/StateNodeFactory.java
@@ -23,6 +23,7 @@ import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.ConnectionRef;
 import org.jbpm.workflow.core.impl.ConstraintImpl;
 import org.jbpm.workflow.core.node.StateNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 import static org.jbpm.workflow.core.Node.CONNECTION_DEFAULT_TYPE;
 
@@ -30,7 +31,7 @@ public class StateNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> exte
 
     public static final String METHOD_CONSTRAINT = "constraint";
 
-    public StateNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public StateNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new StateNode(), id);
     }
 
@@ -38,7 +39,7 @@ public class StateNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> exte
         return (StateNode) node;
     }
 
-    public StateNodeFactory<T> constraint(String connectionId, long nodeId, String type, String dialect, String constraint, int priority) {
+    public StateNodeFactory<T> constraint(String connectionId, WorkflowElementIdentifier nodeId, String type, String dialect, String constraint, int priority) {
         ConstraintImpl constraintImpl = new ConstraintImpl();
         constraintImpl.setName(connectionId);
         constraintImpl.setType(type);
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/SubProcessNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/SubProcessNodeFactory.java
index b9c0e7178d..574b8e498d 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/SubProcessNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/SubProcessNodeFactory.java
@@ -24,6 +24,7 @@ import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.SubProcessFactory;
 import org.jbpm.workflow.core.node.SubProcessNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.Model;
 
 public class SubProcessNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends StateBasedNodeFactory<SubProcessNodeFactory<T>, T>
@@ -34,7 +35,7 @@ public class SubProcessNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>>
     public static final String METHOD_WAIT_FOR_COMPLETION = "waitForCompletion";
     public static final String METHOD_INDEPENDENT = "independent";
 
-    public SubProcessNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public SubProcessNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new SubProcessNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ThrowLinkNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ThrowLinkNodeFactory.java
index bd3850f5af..54a0189b34 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ThrowLinkNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/ThrowLinkNodeFactory.java
@@ -21,10 +21,11 @@ package org.jbpm.ruleflow.core.factory;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.ThrowLinkNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class ThrowLinkNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends ExtendedNodeFactory<ThrowLinkNodeFactory<T>, T> {
 
-    public ThrowLinkNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public ThrowLinkNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new ThrowLinkNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/TimerNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/TimerNodeFactory.java
index 20330eeede..ead36f7bcb 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/TimerNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/TimerNodeFactory.java
@@ -22,6 +22,7 @@ import org.jbpm.process.core.timer.Timer;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.TimerNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class TimerNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends ExtendedNodeFactory<TimerNodeFactory<T>, T> {
 
@@ -30,7 +31,7 @@ public class TimerNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> exte
     public static final String METHOD_PERIOD = "period";
     public static final String METHOD_DATE = "date";
 
-    public TimerNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public TimerNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new TimerNode(), id);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/WorkItemNodeFactory.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/WorkItemNodeFactory.java
index b0a1d6f7e1..6329e1e5f2 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/WorkItemNodeFactory.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/factory/WorkItemNodeFactory.java
@@ -21,13 +21,14 @@ package org.jbpm.ruleflow.core.factory;
 import org.jbpm.ruleflow.core.RuleFlowNodeContainerFactory;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.node.WorkItemNode;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class WorkItemNodeFactory<T extends RuleFlowNodeContainerFactory<T, ?>> extends AbstractWorkItemNodeFactory<WorkItemNodeFactory<T>, T> {
 
     public static final String METHOD_WORK_NAME = "workName";
     public static final String METHOD_WORK_PARAMETER = "workParameter";
 
-    public WorkItemNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, long id) {
+    public WorkItemNodeFactory(T nodeContainerFactory, NodeContainer nodeContainer, WorkflowElementIdentifier id) {
         super(nodeContainerFactory, nodeContainer, new WorkItemNode(), id);
     }
 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java
index 72106aa8cf..f1bb75950a 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidator.java
@@ -84,6 +84,8 @@ import org.kie.api.definition.process.Process;
 import org.kie.api.io.Resource;
 import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcess;
 import org.kie.kogito.process.expr.ExpressionHandlerFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import static java.lang.String.format;
 import static org.jbpm.ruleflow.core.Metadata.EVENT_TYPE;
@@ -99,6 +101,8 @@ import static org.jbpm.ruleflow.core.Metadata.TRIGGER_REF;
  */
 public class RuleFlowProcessValidator implements ProcessValidator {
 
+    private static final Logger logger = LoggerFactory.getLogger(RuleFlowProcessValidator.class);
+
     public static final String ASSOCIATIONS = "BPMN.Associations";
 
     private static RuleFlowProcessValidator INSTANCE;
@@ -611,7 +615,7 @@ public class RuleFlowProcessValidator implements ProcessValidator {
                                 addErrorMessage(process,
                                         startNode,
                                         errors,
-                                        "Start in Event SubProcess '" + compositeNode.getName() + "' [" + compositeNode.getId() + "] must contain a trigger (event definition).");
+                                        "Start in Event SubProcess '" + compositeNode.getName() + "' [" + compositeNode.getId().toExternalFormat() + "] must contain a trigger (event definition).");
                             }
                         }
                     }
@@ -805,8 +809,11 @@ public class RuleFlowProcessValidator implements ProcessValidator {
             }
             if (container instanceof CompositeNode) {
                 for (CompositeNode.NodeAndType nodeAndTypes : ((CompositeNode) container).getLinkedIncomingNodes().values()) {
-                    processNode(nodeAndTypes.getNode(),
-                            processNodes);
+                    if (nodeAndTypes.getNode() != null) {
+                        processNode(nodeAndTypes.getNode(), processNodes);
+                    } else {
+                        logger.error("Composite Node " + nodeAndTypes + " is null");
+                    }
                 }
             }
         }
@@ -840,7 +847,11 @@ public class RuleFlowProcessValidator implements ProcessValidator {
         if (prevValue == null || Boolean.FALSE.equals(prevValue)) {
             for (final List<Connection> list : node.getOutgoingConnections().values()) {
                 for (final Connection connection : list) {
-                    processNode(connection.getTo(), nodes);
+                    if (connection.getTo() != null) {
+                        processNode(connection.getTo(), nodes);
+                    } else {
+                        logger.error("Connection is null {} connected to {} from {}", connection.getMetaData(), connection.getTo(), connection.getFrom());
+                    }
                 }
             }
         }
@@ -1057,7 +1068,7 @@ public class RuleFlowProcessValidator implements ProcessValidator {
                 nodeQueue.addAll(Arrays.asList(process.getNodes()));
                 while (!nodeQueue.isEmpty()) {
                     org.kie.api.definition.process.Node polledNode = nodeQueue.poll();
-                    if (activityRef.equals(polledNode.getMetaData().get("UniqueId"))) {
+                    if (activityRef.equals(polledNode.getUniqueId())) {
                         refNode = polledNode;
                         break;
                     }
@@ -1095,11 +1106,14 @@ public class RuleFlowProcessValidator implements ProcessValidator {
             org.kie.api.definition.process.Node node,
             List<ProcessValidationError> errors,
             String message) {
-        String error = String.format("Node '%s' [%d] %s",
-                node.getName(),
-                node.getId(),
-                message);
-        errors.add(new ProcessValidationErrorImpl(process,
-                error));
+
+        String error = message;
+        if (node != null) {
+            error = String.format("Node '%s' [%s] %s",
+                    node.getName(),
+                    node.getId().toExternalFormat(),
+                    message);
+        }
+        errors.add(new ProcessValidationErrorImpl(process, error));
     }
 }
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/protobuf/ProtobufTypeProvider.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/util/JbpmClassLoaderUtil.java
similarity index 71%
copy from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/protobuf/ProtobufTypeProvider.java
copy to jbpm/jbpm-flow/src/main/java/org/jbpm/util/JbpmClassLoaderUtil.java
index 60103a35ab..be4bcf4382 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/protobuf/ProtobufTypeProvider.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/util/JbpmClassLoaderUtil.java
@@ -16,14 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.protobuf;
+package org.jbpm.util;
 
-import java.util.Collection;
+public class JbpmClassLoaderUtil {
 
-import com.google.protobuf.Descriptors;
-
-public interface ProtobufTypeProvider {
-
-    Collection<Descriptors.Descriptor> descriptors();
+    public static ClassLoader findClassLoader() {
+        ClassLoader loader = Thread.currentThread().getContextClassLoader();
+        if (loader == null) {
+            loader = JbpmClassLoaderUtil.class.getClassLoader();
+        }
+        return loader;
+    }
 
 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/Node.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/Node.java
index 20cb030c02..c70bc74eaa 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/Node.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/Node.java
@@ -23,6 +23,7 @@ import java.io.Serializable;
 import org.jbpm.process.core.Contextable;
 import org.kie.api.definition.process.Connection;
 import org.kie.api.definition.process.NodeContainer;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoNode;
 
 /**
@@ -38,7 +39,7 @@ public interface Node extends KogitoNode, Contextable, Serializable {
      * 
      * @param id the id of the node
      */
-    void setId(long id);
+    void setId(WorkflowElementIdentifier id);
 
     /**
      * Method for setting the name of the node
@@ -47,8 +48,6 @@ public interface Node extends KogitoNode, Contextable, Serializable {
      */
     void setName(String name);
 
-    String getUniqueId();
-
     void addIncomingConnection(String type, Connection connection);
 
     void addOutgoingConnection(String type, Connection connection);
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/NodeContainer.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/NodeContainer.java
index 4a02925009..c8206024d2 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/NodeContainer.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/NodeContainer.java
@@ -22,6 +22,7 @@ import java.io.Serializable;
 
 import org.jbpm.process.core.Context;
 import org.kie.api.definition.process.Node;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public interface NodeContainer extends org.kie.api.definition.process.NodeContainer, Serializable {
 
@@ -44,6 +45,6 @@ public interface NodeContainer extends org.kie.api.definition.process.NodeContai
 
     Context resolveContext(String contextId, Object param);
 
-    Node internalGetNode(long id);
+    Node internalGetNode(WorkflowElementIdentifier id);
 
 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ConnectionImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ConnectionImpl.java
index bfdae4937c..dbb3a85df4 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ConnectionImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ConnectionImpl.java
@@ -23,8 +23,11 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
+import org.jbpm.ruleflow.core.Metadata;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.workflow.core.Connection;
 import org.jbpm.workflow.core.Node;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.process.validation.ValidationException;
 
 /**
@@ -44,6 +47,11 @@ public class ConnectionImpl implements Connection, Serializable {
     public ConnectionImpl() {
     }
 
+    @Override
+    public WorkflowElementIdentifier getId() {
+        return WorkflowElementIdentifierFactory.fromExternalFormat((String) getMetaData().get(Metadata.UNIQUE_ID));
+    }
+
     /**
      * This constructor calls {@link #connect()} itself! That means
      * that simply creating the object also adds it to the appropriate
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ConnectionRef.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ConnectionRef.java
index 30da84e0a8..6221dfd002 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ConnectionRef.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/ConnectionRef.java
@@ -19,6 +19,9 @@
 package org.jbpm.workflow.core.impl;
 
 import java.io.Serializable;
+import java.util.Objects;
+
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class ConnectionRef implements Serializable {
 
@@ -26,14 +29,14 @@ public class ConnectionRef implements Serializable {
 
     private String connectionId;
     private String toType;
-    private long nodeId;
+    private WorkflowElementIdentifier nodeId;
 
-    public ConnectionRef(long nodeId, String toType) {
+    public ConnectionRef(WorkflowElementIdentifier nodeId, String toType) {
         this.nodeId = nodeId;
         this.toType = toType;
     }
 
-    public ConnectionRef(String connectionId, long nodeId, String toType) {
+    public ConnectionRef(String connectionId, WorkflowElementIdentifier nodeId, String toType) {
         this.connectionId = connectionId;
         this.nodeId = nodeId;
         this.toType = toType;
@@ -43,7 +46,7 @@ public class ConnectionRef implements Serializable {
         return toType;
     }
 
-    public long getNodeId() {
+    public WorkflowElementIdentifier getNodeId() {
         return nodeId;
     }
 
@@ -53,12 +56,7 @@ public class ConnectionRef implements Serializable {
 
     @Override
     public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((connectionId == null) ? 0 : connectionId.hashCode());
-        result = prime * result + (int) (nodeId ^ (nodeId >>> 32));
-        result = prime * result + ((toType == null) ? 0 : toType.hashCode());
-        return result;
+        return Objects.hash(connectionId, nodeId, toType);
     }
 
     @Override
@@ -70,19 +68,7 @@ public class ConnectionRef implements Serializable {
         if (getClass() != obj.getClass())
             return false;
         ConnectionRef other = (ConnectionRef) obj;
-        if (connectionId == null) {
-            if (other.connectionId != null)
-                return false;
-        } else if (!connectionId.equals(other.connectionId))
-            return false;
-        if (nodeId != other.nodeId)
-            return false;
-        if (toType == null) {
-            if (other.toType != null)
-                return false;
-        } else if (!toType.equals(other.toType))
-            return false;
-        return true;
+        return Objects.equals(connectionId, other.connectionId) && Objects.equals(nodeId, other.nodeId) && Objects.equals(toType, other.toType);
     }
 
 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeContainerImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeContainerImpl.java
index 126e9651b1..f9d90e83b3 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeContainerImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeContainerImpl.java
@@ -24,6 +24,7 @@ import java.util.Map;
 import org.jbpm.process.core.Context;
 import org.jbpm.workflow.core.NodeContainer;
 import org.kie.api.definition.process.Node;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 /**
  * 
@@ -32,7 +33,7 @@ public class NodeContainerImpl implements NodeContainer {
 
     private static final long serialVersionUID = 510l;
 
-    private Map<Long, Node> nodes;
+    private Map<WorkflowElementIdentifier, Node> nodes;
 
     public NodeContainerImpl() {
         // keeping insertion order is useful for debugging and testing purposes.
@@ -62,7 +63,7 @@ public class NodeContainerImpl implements NodeContainer {
     }
 
     @Override
-    public Node getNode(final long id) {
+    public Node getNode(WorkflowElementIdentifier id) {
         Node node = this.nodes.get(id);
         if (node == null) {
             throw new IllegalArgumentException("Unknown node id: " + id);
@@ -76,12 +77,12 @@ public class NodeContainerImpl implements NodeContainer {
     }
 
     @Override
-    public Node internalGetNode(long id) {
+    public Node internalGetNode(WorkflowElementIdentifier id) {
         return getNode(id);
     }
 
     @Override
-    public void removeNode(final Node node) {
+    public void removeNode(Node node) {
         validateRemoveNode(node);
         this.nodes.remove(node.getId());
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeImpl.java
index 694e3049c2..4410c19d6d 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/NodeImpl.java
@@ -25,19 +25,20 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.concurrent.atomic.AtomicLong;
 
 import org.jbpm.process.core.Context;
 import org.jbpm.process.core.ContextResolver;
 import org.jbpm.process.core.context.variable.Mappable;
 import org.jbpm.process.instance.impl.ReturnValueConstraintEvaluator;
+import org.jbpm.ruleflow.core.Metadata;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.workflow.core.Constraint;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.WorkflowProcess;
-import org.jbpm.workflow.core.node.CompositeNode;
 import org.kie.api.definition.process.Connection;
 import org.kie.api.definition.process.NodeContainer;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 /**
  * Default implementation of a node.
@@ -46,8 +47,7 @@ public abstract class NodeImpl implements Node, ContextResolver, Mappable {
 
     private static final long serialVersionUID = 510l;
 
-    private long id;
-    private static final AtomicLong uniqueIdGen = new AtomicLong(0);
+    private WorkflowElementIdentifier id;
 
     private String name;
     private Map<String, List<Connection>> incomingConnections;
@@ -62,7 +62,7 @@ public abstract class NodeImpl implements Node, ContextResolver, Mappable {
     private MultiInstanceSpecification multiInstanceSpecification;
 
     public NodeImpl() {
-        this.id = -1;
+        this.id = WorkflowElementIdentifierFactory.newRandom();
         this.incomingConnections = new HashMap<>();
         this.outgoingConnections = new HashMap<>();
         this.ioSpecification = new IOSpecification();
@@ -146,28 +146,16 @@ public abstract class NodeImpl implements Node, ContextResolver, Mappable {
     }
 
     @Override
-    public long getId() {
+    public WorkflowElementIdentifier getId() {
         return this.id;
     }
 
     @Override
-    public String getUniqueId() {
-        StringBuilder result = new StringBuilder(id + "");
-        NodeContainer nodeContainer = getParentContainer();
-        while (nodeContainer instanceof CompositeNode) {
-            CompositeNode composite = (CompositeNode) nodeContainer;
-            result.insert(0, composite.getId() + ":");
-            nodeContainer = composite.getParentContainer();
-        }
-        return result.toString();
-    }
-
-    @Override
-    public void setId(final long id) {
+    public void setId(WorkflowElementIdentifier id) {
         this.id = id;
-        String uniqueId = (String) getMetaData("UniqueId");
+        String uniqueId = (String) getMetaData(Metadata.UNIQUE_ID);
         if (uniqueId == null) {
-            setMetaData("UniqueId", "_jbpm-unique-" + uniqueIdGen.getAndIncrement());
+            setMetaData(Metadata.UNIQUE_ID, id.toExternalFormat());
         }
     }
 
@@ -406,7 +394,7 @@ public abstract class NodeImpl implements Node, ContextResolver, Mappable {
             throw new IllegalArgumentException("connection is null");
         }
 
-        ConnectionRef ref = new ConnectionRef((String) connection.getMetaData().get("UniqueId"), connection.getTo().getId(), connection.getToType());
+        ConnectionRef ref = new ConnectionRef(connection.getUniqueId(), connection.getTo().getId(), connection.getToType());
         return this.constraints.get(ref);
     }
 
@@ -429,7 +417,7 @@ public abstract class NodeImpl implements Node, ContextResolver, Mappable {
             throw new IllegalArgumentException("connection is unknown:" + connection);
         }
         addConstraint(
-                new ConnectionRef((String) connection.getMetaData().get("UniqueId"), connection.getTo().getId(), connection.getToType()),
+                new ConnectionRef(connection.getUniqueId(), connection.getTo().getId(), connection.getToType()),
                 constraint);
 
     }
@@ -448,11 +436,6 @@ public abstract class NodeImpl implements Node, ContextResolver, Mappable {
         return Collections.unmodifiableMap(this.constraints);
     }
 
-    @Override
-    public String getNodeUniqueId() {
-        return (String) getMetaData("UniqueId");
-    }
-
     @Override
     public NodeContainer getNodeContainer() {
         return getParentContainer();
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/WorkflowProcessImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/WorkflowProcessImpl.java
index 667a34e1ff..736e490084 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/WorkflowProcessImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/impl/WorkflowProcessImpl.java
@@ -38,6 +38,7 @@ import org.jbpm.workflow.instance.WorkflowProcessInstance;
 import org.jbpm.workflow.instance.impl.MVELProcessHelper;
 import org.jbpm.workflow.instance.impl.ProcessInstanceResolverFactory;
 import org.kie.api.definition.process.NodeContainer;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -102,7 +103,7 @@ public class WorkflowProcessImpl extends ProcessImpl implements WorkflowProcess,
     }
 
     @Override
-    public org.kie.api.definition.process.Node getNode(final long id) {
+    public org.kie.api.definition.process.Node getNode(WorkflowElementIdentifier id) {
         return nodeContainer.getNode(id);
     }
 
@@ -112,7 +113,7 @@ public class WorkflowProcessImpl extends ProcessImpl implements WorkflowProcess,
     }
 
     @Override
-    public org.kie.api.definition.process.Node internalGetNode(long id) {
+    public org.kie.api.definition.process.Node internalGetNode(WorkflowElementIdentifier id) {
         try {
             return getNode(id);
         } catch (IllegalArgumentException e) {
@@ -181,9 +182,10 @@ public class WorkflowProcessImpl extends ProcessImpl implements WorkflowProcess,
         }
     }
 
-    protected org.kie.api.definition.process.Node getContainerNode(org.kie.api.definition.process.Node currentNode, org.jbpm.workflow.core.NodeContainer nodeContainer, long nodeId) {
+    protected org.kie.api.definition.process.Node getContainerNode(org.kie.api.definition.process.Node currentNode, org.jbpm.workflow.core.NodeContainer nodeContainer,
+            WorkflowElementIdentifier nodeId) {
         for (org.kie.api.definition.process.Node node : nodeContainer.getNodes()) {
-            if (nodeId == node.getId()) {
+            if (nodeId.equals(node.getId())) {
                 return currentNode;
             } else {
                 if (node instanceof org.jbpm.workflow.core.NodeContainer) {
@@ -194,7 +196,7 @@ public class WorkflowProcessImpl extends ProcessImpl implements WorkflowProcess,
         return null;
     }
 
-    public org.kie.api.definition.process.Node getParentNode(long nodeId) {
+    public org.kie.api.definition.process.Node getParentNode(WorkflowElementIdentifier nodeId) {
         return getContainerNode(null, nodeContainer, nodeId);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/ActionNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/ActionNode.java
index 639c079b18..aff798ca7f 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/ActionNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/ActionNode.java
@@ -50,12 +50,12 @@ public class ActionNode extends ExtendedNodeImpl {
         super.validateAddIncomingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] only accepts default incoming connection type!");
         }
         if (getFrom() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] cannot have more than one incoming connection!");
         }
     }
@@ -65,12 +65,12 @@ public class ActionNode extends ExtendedNodeImpl {
         super.validateAddOutgoingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] only accepts default outgoing connection type!");
         }
         if (getTo() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] cannot have more than one outgoing connection!");
         }
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNode.java
index 00964aad86..d19c62969d 100644
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/AsyncEventNode.java
@@ -23,6 +23,7 @@ import java.util.Map;
 
 import org.jbpm.workflow.core.impl.NodeImpl;
 import org.kie.api.definition.process.Node;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class AsyncEventNode extends EventNode {
 
@@ -39,7 +40,7 @@ public class AsyncEventNode extends EventNode {
     }
 
     @Override
-    public long getId() {
+    public WorkflowElementIdentifier getId() {
         return node.getId();
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/CompositeNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/CompositeNode.java
index 78218b8e1e..72a95fb161 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/CompositeNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/CompositeNode.java
@@ -25,12 +25,14 @@ import java.util.List;
 import java.util.Map;
 import java.util.function.Function;
 
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.ConnectionImpl;
 import org.jbpm.workflow.core.impl.NodeContainerImpl;
 import org.jbpm.workflow.core.impl.NodeImpl;
 import org.kie.api.definition.process.Connection;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 public class CompositeNode extends StateBasedNode implements NodeContainer, EventNodeInterface {
 
@@ -46,7 +48,7 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
         this.nodeContainer = new NodeContainerImpl();
     }
 
-    public org.kie.api.definition.process.Node getNode(long id) {
+    public org.kie.api.definition.process.Node getNode(WorkflowElementIdentifier id) {
         return nodeContainer.getNode(id);
     }
 
@@ -60,7 +62,7 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
         return nodeContainer;
     }
 
-    public org.kie.api.definition.process.Node internalGetNode(long id) {
+    public org.kie.api.definition.process.Node internalGetNode(WorkflowElementIdentifier id) {
         return getNode(id);
     }
 
@@ -80,18 +82,6 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
     }
 
     public void addNode(org.kie.api.definition.process.Node node) {
-        // TODO find a more elegant solution for this
-        // preferrable remove id setting from this class
-        // and delegate to GUI command that drops node
-        if (node.getId() <= 0) {
-            long id = 0;
-            for (org.kie.api.definition.process.Node n : nodeContainer.getNodes()) {
-                if (n.getId() > id) {
-                    id = n.getId();
-                }
-            }
-            ((Node) node).setId(++id);
-        }
         nodeContainer.addNode(node);
         ((Node) node).setParentContainer(this);
     }
@@ -121,7 +111,7 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
         return false;
     }
 
-    public void linkIncomingConnections(String inType, long inNodeId, String inNodeType) {
+    public void linkIncomingConnections(String inType, WorkflowElementIdentifier inNodeId, String inNodeType) {
         linkIncomingConnections(inType, new NodeAndType(nodeContainer, inNodeId, inNodeType));
     }
 
@@ -159,7 +149,7 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
         }
     }
 
-    public void linkOutgoingConnections(long outNodeId, String outNodeType, String outType) {
+    public void linkOutgoingConnections(WorkflowElementIdentifier outNodeId, String outNodeType, String outType) {
         linkOutgoingConnections(new NodeAndType(this, outNodeId, outNodeType), outType);
     }
 
@@ -382,11 +372,11 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
         private static final long serialVersionUID = 510l;
 
         private NodeContainer nodeContainer;
-        private long nodeId;
+        private WorkflowElementIdentifier nodeId;
         private String type;
         private transient org.kie.api.definition.process.Node node;
 
-        public NodeAndType(NodeContainer nodeContainer, long nodeId, String type) {
+        public NodeAndType(NodeContainer nodeContainer, WorkflowElementIdentifier nodeId, String type) {
             if (type == null) {
                 throw new IllegalArgumentException(
                         "Node or type may not be null!");
@@ -417,7 +407,7 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
             return node;
         }
 
-        public long getNodeId() {
+        public WorkflowElementIdentifier getNodeId() {
             return nodeId;
         }
 
@@ -434,7 +424,7 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
         }
 
         public int hashCode() {
-            return 7 * (int) nodeId + 13 * type.hashCode();
+            return 7 * nodeId.hashCode() + 13 * type.hashCode();
         }
 
     }
@@ -444,11 +434,12 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
         private static final long serialVersionUID = 510l;
 
         private CompositeNode parentNode;
-        private long inNodeId;
+        private WorkflowElementIdentifier inNodeId;
         private transient org.kie.api.definition.process.Node inNode;
         private String inType;
 
         public CompositeNodeStart(CompositeNode parentNode, org.kie.api.definition.process.Node outNode, String outType) {
+            setId(WorkflowElementIdentifierFactory.fromExternalFormat(parentNode.getId().toExternalFormat() + ":composite:start"));
             setName("Composite node start");
             this.inNodeId = outNode.getId();
             this.inNode = outNode;
@@ -464,7 +455,7 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
             return inNode;
         }
 
-        public long getInNodeId() {
+        public WorkflowElementIdentifier getInNodeId() {
             return inNodeId;
         }
 
@@ -479,11 +470,12 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
         private static final long serialVersionUID = 510l;
 
         private CompositeNode parentNode;
-        private long outNodeId;
+        private WorkflowElementIdentifier outNodeId;
         private transient org.kie.api.definition.process.Node outNode;
         private String outType;
 
         public CompositeNodeEnd(CompositeNode parentNode, org.kie.api.definition.process.Node outNode, String outType) {
+            setId(WorkflowElementIdentifierFactory.fromExternalFormat(parentNode.getId().toExternalFormat() + ":composite:end"));
             setName("Composite node end");
             this.outNodeId = outNode.getId();
             this.outNode = outNode;
@@ -499,7 +491,7 @@ public class CompositeNode extends StateBasedNode implements NodeContainer, Even
             return outNode;
         }
 
-        public long getOutNodeId() {
+        public WorkflowElementIdentifier getOutNodeId() {
             return outNodeId;
         }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/DynamicNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/DynamicNode.java
index 7ac9df9326..d09348f1e5 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/DynamicNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/DynamicNode.java
@@ -24,6 +24,7 @@ import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
 import org.kie.api.definition.process.Node;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.runtime.process.ProcessContext;
 
 import static org.jbpm.ruleflow.core.Metadata.CUSTOM_AUTO_START;
@@ -50,7 +51,7 @@ public class DynamicNode extends CompositeContextNode {
     }
 
     @Override
-    public Node internalGetNode(long id) {
+    public Node internalGetNode(WorkflowElementIdentifier id) {
         try {
             return getNode(id);
         } catch (IllegalArgumentException e) {
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/EndNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/EndNode.java
index a4e5603894..eb45e40590 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/EndNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/EndNode.java
@@ -22,8 +22,6 @@ import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
 import org.kie.api.definition.process.Connection;
 
-import static org.jbpm.ruleflow.core.Metadata.UNIQUE_ID;
-
 /**
  * Default implementation of an end node.
  * 
@@ -57,12 +55,12 @@ public class EndNode extends ExtendedNodeImpl {
         super.validateAddIncomingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get(UNIQUE_ID) + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] only accepts default incoming connection type!");
         }
         if (getFrom() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get(UNIQUE_ID) + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] cannot have more than one incoming connection!");
         }
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/EventNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/EventNode.java
index 6878d879e9..968ecb96df 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/EventNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/EventNode.java
@@ -101,12 +101,12 @@ public class EventNode extends ExtendedNodeImpl implements EventNodeInterface {
         super.validateAddIncomingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] only accepts default incoming connection type!");
         }
         if (getFrom() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] cannot have more than one incoming connection!");
         }
     }
@@ -116,12 +116,12 @@ public class EventNode extends ExtendedNodeImpl implements EventNodeInterface {
         super.validateAddOutgoingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] only accepts default outgoing connection type!");
         }
         if (getTo() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] cannot have more than one outgoing connection!");
         }
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/FaultNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/FaultNode.java
index 83b541a405..bd5a13bfdf 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/FaultNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/FaultNode.java
@@ -71,12 +71,12 @@ public class FaultNode extends ExtendedNodeImpl {
         super.validateAddIncomingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] only accepts default incoming connection type!");
         }
         if (getFrom() != null) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] cannot have more than one incoming connection!");
         }
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/ForEachNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/ForEachNode.java
index 8b7ea883ad..a53a6aff11 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/ForEachNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/ForEachNode.java
@@ -27,9 +27,11 @@ import org.jbpm.process.core.context.variable.Variable;
 import org.jbpm.process.core.context.variable.VariableScope;
 import org.jbpm.process.core.datatype.DataType;
 import org.jbpm.process.instance.impl.Action;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.impl.ConnectionImpl;
 import org.jbpm.workflow.core.impl.ExtendedNodeImpl;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.process.expr.Expression;
 import org.kie.kogito.process.expr.ExpressionHandlerFactory;
 
@@ -56,39 +58,59 @@ public class ForEachNode extends CompositeContextNode {
     private Expression evaluateExpression;
 
     public ForEachNode() {
+        this(WorkflowElementIdentifierFactory.newRandom());
+    }
+
+    public ForEachNode(WorkflowElementIdentifier id) {
+        setId(id);
         // Split
         ForEachSplitNode split = new ForEachSplitNode();
+        split.setId(getSplitIdentifier());
         split.setName("ForEachSplit");
         split.setMetaData("hidden", true);
-        split.setMetaData("UniqueId", getMetaData("Uniqueid") + ":foreach:split");
+
         super.addNode(split);//Node ID 1
         super.linkIncomingConnections(
                 Node.CONNECTION_DEFAULT_TYPE,
                 new CompositeNode.NodeAndType(split, Node.CONNECTION_DEFAULT_TYPE));
         // Composite node
         CompositeContextNode compositeNode = new CompositeContextNode();
+        compositeNode.setId(getCompositeIdentifier());
         compositeNode.setName("ForEachComposite");
         compositeNode.setMetaData("hidden", true);
-        compositeNode.setMetaData("UniqueId", getMetaData("Uniqueid") + ":foreach:composite");
+
         super.addNode(compositeNode);//Node ID 2
         VariableScope variableScope = new VariableScope();
         compositeNode.addContext(variableScope);
         compositeNode.setDefaultContext(variableScope);
         // Join
         ForEachJoinNode join = new ForEachJoinNode();
+        join.setId(getJoinIdentifier());
         join.setName("ForEachJoin");
         join.setMetaData("hidden", true);
-        join.setMetaData("UniqueId", getMetaData("Uniqueid") + ":foreach:join");
+
         super.addNode(join);//Node ID 3
         super.linkOutgoingConnections(
                 new CompositeNode.NodeAndType(join, Node.CONNECTION_DEFAULT_TYPE),
                 Node.CONNECTION_DEFAULT_TYPE);
         new ConnectionImpl(
-                super.getNode(ForEachSplitNode.NODE_ID), Node.CONNECTION_DEFAULT_TYPE,
+                super.getNode(getSplitIdentifier()), Node.CONNECTION_DEFAULT_TYPE,
                 getCompositeNode(), Node.CONNECTION_DEFAULT_TYPE);
         new ConnectionImpl(
                 getCompositeNode(), Node.CONNECTION_DEFAULT_TYPE,
-                super.getNode(ForEachJoinNode.NODE_ID), Node.CONNECTION_DEFAULT_TYPE);
+                super.getNode(getJoinIdentifier()), Node.CONNECTION_DEFAULT_TYPE);
+    }
+
+    private WorkflowElementIdentifier getCompositeIdentifier() {
+        return WorkflowElementIdentifierFactory.fromExternalFormat(getUniqueId() + ":foreach:composite");
+    }
+
+    private WorkflowElementIdentifier getJoinIdentifier() {
+        return WorkflowElementIdentifierFactory.fromExternalFormat(getUniqueId() + ":foreach:join");
+    }
+
+    private WorkflowElementIdentifier getSplitIdentifier() {
+        return WorkflowElementIdentifierFactory.fromExternalFormat(getUniqueId() + ":foreach:split");
     }
 
     @Override
@@ -141,15 +163,15 @@ public class ForEachNode extends CompositeContextNode {
     }
 
     public CompositeContextNode getCompositeNode() {
-        return (CompositeContextNode) super.getNode(2);
+        return (CompositeContextNode) super.getNode(getCompositeIdentifier());
     }
 
     public ForEachSplitNode getForEachSplitNode() {
-        return (ForEachSplitNode) super.getNode(1);
+        return (ForEachSplitNode) super.getNode(getSplitIdentifier());
     }
 
     public ForEachJoinNode getForEachJoinNode() {
-        return (ForEachJoinNode) super.getNode(3);
+        return (ForEachJoinNode) super.getNode(getJoinIdentifier());
     }
 
     @Override
@@ -163,12 +185,12 @@ public class ForEachNode extends CompositeContextNode {
     }
 
     @Override
-    public org.kie.api.definition.process.Node getNode(long id) {
+    public org.kie.api.definition.process.Node getNode(WorkflowElementIdentifier id) {
         return getCompositeNode().getNode(id);
     }
 
     @Override
-    public org.kie.api.definition.process.Node internalGetNode(long id) {
+    public org.kie.api.definition.process.Node internalGetNode(WorkflowElementIdentifier id) {
         return super.getNode(id);
     }
 
@@ -193,12 +215,12 @@ public class ForEachNode extends CompositeContextNode {
     }
 
     @Override
-    public void linkIncomingConnections(String inType, long inNodeId, String inNodeType) {
+    public void linkIncomingConnections(String inType, WorkflowElementIdentifier inNodeId, String inNodeType) {
         getCompositeNode().linkIncomingConnections(inType, inNodeId, inNodeType);
     }
 
     @Override
-    public void linkOutgoingConnections(long outNodeId, String outNodeType, String outType) {
+    public void linkOutgoingConnections(WorkflowElementIdentifier outNodeId, String outNodeType, String outType) {
         getCompositeNode().linkOutgoingConnections(outNodeId, outNodeType, outType);
     }
 
@@ -275,12 +297,11 @@ public class ForEachNode extends CompositeContextNode {
 
     public static class ForEachSplitNode extends ExtendedNodeImpl {
         private static final long serialVersionUID = 510l;
-        public static long NODE_ID = 1;
     }
 
     public static class ForEachJoinNode extends ExtendedNodeImpl {
         private static final long serialVersionUID = 510l;
-        public static long NODE_ID = 3;
+
     }
 
     @Override
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Join.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Join.java
index 87d81e0941..c91fec1525 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Join.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Join.java
@@ -84,7 +84,7 @@ public class Join extends NodeImpl {
         super.validateAddIncomingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] only accepts default incoming connection type!");
         }
     }
@@ -94,12 +94,12 @@ public class Join extends NodeImpl {
         super.validateAddOutgoingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] only accepts default outgoing connection type!");
         }
         if (getTo() != null) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] cannot have more than one outgoing connection!");
         }
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/MilestoneNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/MilestoneNode.java
index fde2b20a75..ddac709244 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/MilestoneNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/MilestoneNode.java
@@ -24,8 +24,6 @@ import org.jbpm.workflow.core.Node;
 import org.kie.api.definition.process.Connection;
 import org.kie.api.runtime.process.ProcessContext;
 
-import static org.jbpm.ruleflow.core.Metadata.UNIQUE_ID;
-
 /**
  * Default implementation of a milestone node.
  */
@@ -79,7 +77,7 @@ public class MilestoneNode extends StateBasedNode implements Constrainable {
 
     private static void throwValidationException(Connection connection, String msg) {
         throw new IllegalArgumentException("This type of node ["
-                + connection.getFrom().getMetaData().get(UNIQUE_ID) + ", "
+                + connection.getFrom().getUniqueId() + ", "
                 + connection.getFrom().getName() + "] "
                 + msg);
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/RuleSetNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/RuleSetNode.java
index 37648d9d36..5f3a242dd8 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/RuleSetNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/RuleSetNode.java
@@ -102,12 +102,12 @@ public class RuleSetNode extends StateBasedNode implements ContextContainer {
         super.validateAddIncomingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] only accepts default incoming connection type!");
         }
         if (getFrom() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] cannot have more than one incoming connection!");
         }
     }
@@ -117,12 +117,12 @@ public class RuleSetNode extends StateBasedNode implements ContextContainer {
         super.validateAddOutgoingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] only accepts default outgoing connection type!");
         }
         if (getTo() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] cannot have more than one outgoing connection!");
         }
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Split.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Split.java
index 659b877dc6..20f90546da 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Split.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/Split.java
@@ -84,7 +84,7 @@ public class Split extends NodeImpl implements Constrainable {
         }
 
         if (this.type == TYPE_OR || this.type == TYPE_XOR) {
-            ConnectionRef ref = new ConnectionRef((String) connection.getMetaData().get("UniqueId"), connection.getTo().getId(), connection.getToType());
+            ConnectionRef ref = new ConnectionRef(connection.getUniqueId(), connection.getTo().getId(), connection.getToType());
             Collection<Constraint> constraints = this.constraints.get(ref);
             if (constraints != null) {
                 for (Constraint constraint : constraints) {
@@ -108,7 +108,7 @@ public class Split extends NodeImpl implements Constrainable {
         }
 
         if (this.type == TYPE_OR || this.type == TYPE_XOR) {
-            ConnectionRef ref = new ConnectionRef((String) connection.getMetaData().get("UniqueId"), connection.getTo().getId(), connection.getToType());
+            ConnectionRef ref = new ConnectionRef(connection.getUniqueId(), connection.getTo().getId(), connection.getToType());
             return this.constraints.get(ref);
         }
         throw new UnsupportedOperationException("Constraints are " +
@@ -126,7 +126,7 @@ public class Split extends NodeImpl implements Constrainable {
                 throw new IllegalArgumentException("connection is unknown:" + connection);
             }
             addConstraint(
-                    new ConnectionRef((String) connection.getMetaData().get("UniqueId"), connection.getTo().getId(), connection.getToType()),
+                    new ConnectionRef(connection.getUniqueId(), connection.getTo().getId(), connection.getToType()),
                     constraint);
         } else {
             throw new UnsupportedOperationException("Constraints are " +
@@ -139,13 +139,13 @@ public class Split extends NodeImpl implements Constrainable {
         super.validateAddIncomingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] only accepts default incoming connection type!");
         }
 
         if (!getIncomingConnections(Node.CONNECTION_DEFAULT_TYPE).isEmpty() && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] cannot have more than one incoming connection!");
         }
     }
@@ -155,7 +155,7 @@ public class Split extends NodeImpl implements Constrainable {
         super.validateAddOutgoingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] only accepts default outgoing connection type!");
         }
     }
@@ -167,7 +167,7 @@ public class Split extends NodeImpl implements Constrainable {
     }
 
     public void removeConstraint(Connection connection) {
-        ConnectionRef ref = new ConnectionRef((String) connection.getMetaData().get("UniqueId"), connection.getTo().getId(), connection.getToType());
+        ConnectionRef ref = new ConnectionRef(connection.getUniqueId(), connection.getTo().getId(), connection.getToType());
         internalRemoveConstraint(ref);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StartNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StartNode.java
index a4c542a548..f1062e67d6 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StartNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StartNode.java
@@ -71,13 +71,13 @@ public class StartNode extends ExtendedNodeImpl {
     @Override
     public void validateAddIncomingConnection(final String type, final Connection connection) {
         throw new UnsupportedOperationException(
-                "A start node [" + this.getMetaData("UniqueId") + ", " + this.getName() + "] may not have an incoming connection!");
+                "A start node [" + this.getUniqueId() + ", " + this.getName() + "] may not have an incoming connection!");
     }
 
     @Override
     public void validateRemoveIncomingConnection(final String type, final Connection connection) {
         throw new UnsupportedOperationException(
-                "A start node [" + this.getMetaData("UniqueId") + ", " + this.getName() + "] may not have an incoming connection!");
+                "A start node [" + this.getUniqueId() + ", " + this.getName() + "] may not have an incoming connection!");
     }
 
     @Override
@@ -85,11 +85,11 @@ public class StartNode extends ExtendedNodeImpl {
         super.validateAddOutgoingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "A start node [" + this.getMetaData("UniqueId") + ", " + this.getName() + "] only accepts default outgoing connection type!");
+                    "A start node [" + this.getUniqueId() + ", " + this.getName() + "] only accepts default outgoing connection type!");
         }
         if (getTo() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "A start node [" + this.getMetaData("UniqueId") + ", " + this.getName() + "] cannot have more than one outgoing connection!");
+                    "A start node [" + this.getUniqueId() + ", " + this.getName() + "] cannot have more than one outgoing connection!");
         }
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateBasedNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateBasedNode.java
index 5f7bd9774d..868b145a0d 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateBasedNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateBasedNode.java
@@ -50,7 +50,7 @@ public class StateBasedNode extends ExtendedNodeImpl {
         Timer timer = new Timer();
         timer.setDelay(duration);
         DroolsConsequenceAction timeoutAction = new DroolsConsequenceAction("java", null);
-        timeoutAction.setMetaData(ACTION, new CompleteStateBasedNodeInstanceAction(getNodeUniqueId()));
+        timeoutAction.setMetaData(ACTION, new CompleteStateBasedNodeInstanceAction(getUniqueId()));
         addTimer(timer, timeoutAction);
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateNode.java
index 013876f710..e9e0743fbf 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/StateNode.java
@@ -21,4 +21,5 @@ package org.jbpm.workflow.core.node;
 public class StateNode extends CompositeContextNode implements Constrainable {
 
     private static final long serialVersionUID = 510l;
+
 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/SubProcessNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/SubProcessNode.java
index 07c7a9bda8..80b6f75f87 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/SubProcessNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/SubProcessNode.java
@@ -74,12 +74,12 @@ public class SubProcessNode extends StateBasedNode implements ContextContainer {
         super.validateAddIncomingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] only accepts default incoming connection type!");
         }
         if (getFrom() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] cannot have more than one incoming connection!");
         }
     }
@@ -89,12 +89,12 @@ public class SubProcessNode extends StateBasedNode implements ContextContainer {
         super.validateAddOutgoingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] only accepts default outgoing connection type!");
         }
         if (getTo() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] cannot have more than one outgoing connection!");
         }
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/TimerNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/TimerNode.java
index 7f2df74a17..a3a4e29d95 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/TimerNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/TimerNode.java
@@ -42,12 +42,12 @@ public class TimerNode extends ExtendedNodeImpl {
         super.validateAddIncomingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] only accepts default incoming connection type!");
         }
         if (getFrom() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] cannot have more than one incoming connection!");
         }
     }
@@ -57,12 +57,12 @@ public class TimerNode extends ExtendedNodeImpl {
         super.validateAddOutgoingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] only accepts default outgoing connection type!");
         }
         if (getTo() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] cannot have more than one outgoing connection!");
         }
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/WorkItemNode.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/WorkItemNode.java
index e997056e7d..dd1357b5ff 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/WorkItemNode.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/core/node/WorkItemNode.java
@@ -63,12 +63,12 @@ public class WorkItemNode extends StateBasedNode implements ContextContainer {
         super.validateAddIncomingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] only accepts default incoming connection type!");
         }
         if (getFrom() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getTo().getMetaData().get("UniqueId") + ", " + connection.getTo().getName()
+                    "This type of node [" + connection.getTo().getUniqueId() + ", " + connection.getTo().getName()
                             + "] cannot have more than one incoming connection!");
         }
     }
@@ -78,12 +78,12 @@ public class WorkItemNode extends StateBasedNode implements ContextContainer {
         super.validateAddOutgoingConnection(type, connection);
         if (!Node.CONNECTION_DEFAULT_TYPE.equals(type)) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] only accepts default outgoing connection type!");
         }
         if (getTo() != null && !"true".equals(System.getProperty("jbpm.enable.multi.con"))) {
             throw new IllegalArgumentException(
-                    "This type of node [" + connection.getFrom().getMetaData().get("UniqueId") + ", " + connection.getFrom().getName()
+                    "This type of node [" + connection.getFrom().getUniqueId() + ", " + connection.getFrom().getName()
                             + "] cannot have more than one outgoing connection!");
         }
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java
index 471b6a6ff7..65c8e09205 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/NodeInstanceContainer.java
@@ -23,11 +23,11 @@ import java.util.Collection;
 import org.jbpm.workflow.core.node.AsyncEventNode;
 import org.kie.api.definition.process.Node;
 import org.kie.api.definition.process.NodeContainer;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstanceContainer;
 
 import static org.jbpm.ruleflow.core.Metadata.CUSTOM_ASYNC;
-import static org.jbpm.ruleflow.core.Metadata.UNIQUE_ID;
 
 /**
  *
@@ -36,7 +36,7 @@ public interface NodeInstanceContainer extends KogitoNodeInstanceContainer {
 
     Collection<NodeInstance> getNodeInstances(boolean recursive);
 
-    NodeInstance getFirstNodeInstance(long nodeId);
+    NodeInstance getFirstNodeInstance(WorkflowElementIdentifier nodeId);
 
     NodeInstance getNodeInstance(Node node);
 
@@ -63,7 +63,7 @@ public interface NodeInstanceContainer extends KogitoNodeInstanceContainer {
     default NodeInstance getByNodeDefinitionId(final String nodeDefinitionId, NodeContainer nodeContainer) {
         for (Node node : nodeContainer.getNodes()) {
 
-            if (nodeDefinitionId.equals(node.getMetaData().get(UNIQUE_ID))) {
+            if (nodeDefinitionId.equals(node.getUniqueId())) {
                 if (nodeContainer instanceof Node) {
                     Collection<KogitoNodeInstance> nodeInstances = getKogitoNodeInstances(ni -> ni.getNode().getId() == (((Node) nodeContainer).getId()), true);
                     if (nodeInstances.isEmpty()) {
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/WorkflowProcessInstanceUpgrader.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/WorkflowProcessInstanceUpgrader.java
index 0ae4ebac5e..46c96ca396 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/WorkflowProcessInstanceUpgrader.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/WorkflowProcessInstanceUpgrader.java
@@ -24,12 +24,12 @@ import java.util.Stack;
 
 import org.drools.core.common.InternalKnowledgeRuntime;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
-import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.impl.NodeImpl;
 import org.jbpm.workflow.instance.impl.NodeInstanceImpl;
 import org.jbpm.workflow.instance.impl.WorkflowProcessInstanceImpl;
 import org.kie.api.definition.process.NodeContainer;
 import org.kie.api.definition.process.Process;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.definition.process.WorkflowProcess;
 import org.kie.api.runtime.process.NodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
@@ -41,7 +41,7 @@ public class WorkflowProcessInstanceUpgrader {
     }
 
     public static void upgradeProcessInstance(KogitoProcessRuntime kruntime, String processInstanceId, String processId,
-            Map<String, Long> nodeMapping) {
+            Map<WorkflowElementIdentifier, WorkflowElementIdentifier> nodeMapping) {
         if (nodeMapping == null) {
             nodeMapping = new HashMap<>();
         }
@@ -79,15 +79,15 @@ public class WorkflowProcessInstanceUpgrader {
             String toProcessId,
             Map<String, String> nodeNamesMapping) {
 
-        Map<String, Long> nodeIdMapping = new HashMap<>();
+        Map<WorkflowElementIdentifier, WorkflowElementIdentifier> nodeIdMapping = new HashMap<>();
 
         String fromProcessIdString = kruntime.getProcessInstance(fromProcessId).getProcessId();
         Process processFrom = kruntime.getKieBase().getProcess(fromProcessIdString);
         Process processTo = kruntime.getKieBase().getProcess(toProcessId);
 
         for (Map.Entry<String, String> entry : nodeNamesMapping.entrySet()) {
-            String from = null;
-            Long to = null;
+            WorkflowElementIdentifier from = null;
+            WorkflowElementIdentifier to = null;
 
             if (processFrom instanceof WorkflowProcess) {
                 from = getNodeId(((WorkflowProcess) processFrom).getNodes(), entry.getKey(), true);
@@ -100,9 +100,9 @@ public class WorkflowProcessInstanceUpgrader {
             }
 
             if (processTo instanceof WorkflowProcess) {
-                to = Long.valueOf(getNodeId(((WorkflowProcess) processTo).getNodes(), entry.getValue(), false));
+                to = getNodeId(((WorkflowProcess) processTo).getNodes(), entry.getValue(), false);
             } else if (processTo instanceof RuleFlowProcess) {
-                to = Long.valueOf(getNodeId(((RuleFlowProcess) processTo).getNodes(), entry.getValue(), false));
+                to = getNodeId(((RuleFlowProcess) processTo).getNodes(), entry.getValue(), false);
             } else if (processTo != null) {
                 throw new IllegalArgumentException("Suported processes are WorkflowProcess and RuleFlowProcess, it was:" + processTo.getClass());
             } else {
@@ -114,7 +114,7 @@ public class WorkflowProcessInstanceUpgrader {
         upgradeProcessInstance(kruntime, fromProcessId, toProcessId, nodeIdMapping);
     }
 
-    private static String getNodeId(org.kie.api.definition.process.Node[] nodes, String nodeName, boolean unique) {
+    private static WorkflowElementIdentifier getNodeId(org.kie.api.definition.process.Node[] nodes, String nodeName, boolean unique) {
 
         Stack<org.kie.api.definition.process.Node> nodeStack = new Stack<>();
         for (org.kie.api.definition.process.Node node : nodes) {
@@ -141,31 +141,20 @@ public class WorkflowProcessInstanceUpgrader {
             throw new IllegalArgumentException("No node with name " + nodeName);
         }
 
-        StringBuilder id = new StringBuilder();
-
-        if (unique) {
-            while (!(((Node) match).getParentContainer() instanceof Process)) {
-                id.insert(0, ":" + match.getId());
-                match = (org.kie.api.definition.process.Node) ((Node) match).getParentContainer();
-            }
-        }
-
-        id.insert(0, match.getId());
-
-        return id.toString();
+        return match.getId();
     }
 
-    private static void updateNodeInstances(NodeInstanceContainer nodeInstanceContainer, Map<String, Long> nodeMapping) {
+    private static void updateNodeInstances(NodeInstanceContainer nodeInstanceContainer, Map<WorkflowElementIdentifier, WorkflowElementIdentifier> nodeMapping) {
         for (NodeInstance nodeInstance : nodeInstanceContainer.getNodeInstances()) {
-            String oldNodeId = ((NodeImpl) ((org.jbpm.workflow.instance.NodeInstance) nodeInstance).getNode()).getUniqueId();
-            Long newNodeId = nodeMapping.get(oldNodeId);
+            WorkflowElementIdentifier oldNodeId = ((NodeImpl) ((org.jbpm.workflow.instance.NodeInstance) nodeInstance).getNode()).getId();
+            WorkflowElementIdentifier newNodeId = nodeMapping.get(oldNodeId);
             if (newNodeId == null) {
                 newNodeId = nodeInstance.getNodeId();
             }
 
             // clean up iteration levels for removed (old) nodes
             Map<String, Integer> iterLevels = ((WorkflowProcessInstanceImpl) nodeInstance.getProcessInstance()).getIterationLevels();
-            String uniqueId = (String) ((NodeImpl) nodeInstance.getNode()).getMetaData("UniqueId");
+            String uniqueId = (String) ((NodeImpl) nodeInstance.getNode()).getUniqueId();
             iterLevels.remove(uniqueId);
             // and now set to new node id
             ((NodeInstanceImpl) nodeInstance).setNodeId(newNodeId);
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/WorkflowRuntimeException.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/WorkflowRuntimeException.java
index 8172ad0532..c62b65efc7 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/WorkflowRuntimeException.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/WorkflowRuntimeException.java
@@ -25,6 +25,7 @@ import java.util.Map;
 import org.jbpm.process.core.context.variable.VariableScope;
 import org.jbpm.process.instance.context.variable.VariableScopeInstance;
 import org.jbpm.process.instance.impl.ProcessInstanceImpl;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
 
@@ -40,7 +41,7 @@ public class WorkflowRuntimeException extends RuntimeException {
     private String processInstanceId;
     private String processId;
     private String nodeInstanceId;
-    private long nodeId;
+    private WorkflowElementIdentifier nodeId;
     private String nodeName;
     private String deploymentId;
 
@@ -128,14 +129,14 @@ public class WorkflowRuntimeException extends RuntimeException {
     /**
      * @return the nodeId
      */
-    public long getNodeId() {
+    public WorkflowElementIdentifier getNodeId() {
         return nodeId;
     }
 
     /**
      * @param nodeId the nodeId to set
      */
-    public void setNodeId(long nodeId) {
+    public void setNodeId(WorkflowElementIdentifier nodeId) {
         this.nodeId = nodeId;
     }
 
@@ -162,7 +163,7 @@ public class WorkflowRuntimeException extends RuntimeException {
         return MessageFormat.format("[{0}:{4} - {1}:{2}] -- {3}",
                 getProcessId(),
                 (getNodeName() == null ? "?" : getNodeName()),
-                (getNodeId() == 0 ? "?" : getNodeId()),
+                (getNodeId()),
                 (getCause() == null ? "WorkflowRuntimeException" : getCause().getMessage()),
                 getProcessInstanceId());
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/CompensationEventListener.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/CompensationEventListener.java
index 4cf8b8eba5..211ac2c9dd 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/CompensationEventListener.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/CompensationEventListener.java
@@ -136,7 +136,7 @@ class CompensationEventListener implements KogitoEventListener {
         allProcessNodes.addAll(Arrays.asList(instance.getNodeContainer().getNodes()));
         while (!allProcessNodes.isEmpty()) {
             org.kie.api.definition.process.Node node = allProcessNodes.poll();
-            if (nodeId.equals(node.getMetaData().get("UniqueId"))) {
+            if (nodeId.equals(node.getUniqueId())) {
                 found = node;
                 break;
             }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactoryRegistry.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactoryRegistry.java
index 659eb924c1..991932f3f1 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactoryRegistry.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceFactoryRegistry.java
@@ -74,12 +74,13 @@ import org.kie.api.runtime.Environment;
 import org.kie.api.runtime.process.NodeInstance;
 import org.kie.api.runtime.process.NodeInstanceContainer;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstanceContainer;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import static org.jbpm.ruleflow.core.Metadata.CUSTOM_ASYNC;
-import static org.jbpm.ruleflow.core.Metadata.UNIQUE_ID;
 
 public class NodeInstanceFactoryRegistry {
-
+    private static final Logger LOGGER = LoggerFactory.getLogger(NodeInstanceFactoryRegistry.class);
     private static final NodeInstanceFactoryRegistry INSTANCE = new NodeInstanceFactoryRegistry();
 
     private Map<Class<? extends Node>, NodeInstanceFactory> registry;
@@ -198,6 +199,7 @@ public class NodeInstanceFactoryRegistry {
             if (result != null) {
                 return result;
             } else {
+                LOGGER.debug("creating node {} with identifier {}", node, node.getId());
                 return createInstance(supplier.get(), node, processInstance, nodeInstanceContainer);
             }
         };
@@ -211,14 +213,9 @@ public class NodeInstanceFactoryRegistry {
         nodeInstance.setNodeId(node.getId());
         nodeInstance.setNodeInstanceContainer((KogitoNodeInstanceContainer) nodeInstanceContainer);
         nodeInstance.setProcessInstance(processInstance);
-        String uniqueId = (String) node.getMetaData().get(UNIQUE_ID);
-        if (uniqueId == null) {
-            uniqueId = node.getId() + "";
-        }
-        nodeInstance.setMetaData(UNIQUE_ID, uniqueId);
         nodeInstance.setMetaData(CUSTOM_ASYNC, node.getMetaData().get(CUSTOM_ASYNC));
 
-        int level = ((org.jbpm.workflow.instance.NodeInstanceContainer) nodeInstanceContainer).getLevelForNode(uniqueId);
+        int level = ((org.jbpm.workflow.instance.NodeInstanceContainer) nodeInstanceContainer).getLevelForNode(node.getUniqueId());
         nodeInstance.setLevel(level);
         return nodeInstance;
     }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
index 0cfd7ea001..6ab030d9ff 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/NodeInstanceImpl.java
@@ -54,6 +54,7 @@ import org.jbpm.workflow.instance.WorkflowRuntimeException;
 import org.jbpm.workflow.instance.node.ActionNodeInstance;
 import org.jbpm.workflow.instance.node.CompositeNodeInstance;
 import org.kie.api.definition.process.Connection;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.runtime.process.NodeInstanceContainer;
 import org.kie.kogito.internal.process.runtime.KogitoNode;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
@@ -66,7 +67,6 @@ import org.slf4j.LoggerFactory;
 import static org.jbpm.ruleflow.core.Metadata.HIDDEN;
 import static org.jbpm.ruleflow.core.Metadata.INCOMING_CONNECTION;
 import static org.jbpm.ruleflow.core.Metadata.OUTGOING_CONNECTION;
-import static org.jbpm.ruleflow.core.Metadata.UNIQUE_ID;
 import static org.kie.kogito.internal.process.runtime.KogitoProcessInstance.STATE_ACTIVE;
 
 /**
@@ -79,7 +79,7 @@ public abstract class NodeInstanceImpl implements org.jbpm.workflow.instance.Nod
     protected static final Logger logger = LoggerFactory.getLogger(NodeInstanceImpl.class);
 
     private String id;
-    private long nodeId;
+    private WorkflowElementIdentifier nodeId;
     private WorkflowProcessInstance processInstance;
     private org.jbpm.workflow.instance.NodeInstanceContainer nodeInstanceContainer;
     private Map<String, Object> metaData = new HashMap<>();
@@ -109,12 +109,12 @@ public abstract class NodeInstanceImpl implements org.jbpm.workflow.instance.Nod
         return this.id;
     }
 
-    public void setNodeId(final long nodeId) {
+    public void setNodeId(WorkflowElementIdentifier nodeId) {
         this.nodeId = nodeId;
     }
 
     @Override
-    public long getNodeId() {
+    public WorkflowElementIdentifier getNodeId() {
         return this.nodeId;
     }
 
@@ -126,7 +126,7 @@ public abstract class NodeInstanceImpl implements org.jbpm.workflow.instance.Nod
 
     @Override
     public String getNodeDefinitionId() {
-        return (String) getNode().getMetaData().get(UNIQUE_ID);
+        return getNode().getUniqueId();
     }
 
     @Override
@@ -224,8 +224,8 @@ public abstract class NodeInstanceImpl implements org.jbpm.workflow.instance.Nod
             ((org.jbpm.workflow.instance.NodeInstanceContainer) getNodeInstanceContainer()).setCurrentLevel(level);
             Collection<Connection> incoming = getNode().getIncomingConnections(type);
             for (Connection conn : incoming) {
-                if (conn.getFrom().getId() == from.getNodeId()) {
-                    this.metaData.put(INCOMING_CONNECTION, conn.getMetaData().get(UNIQUE_ID));
+                if (conn.getFrom().getId().equals(from.getNodeId())) {
+                    this.metaData.put(INCOMING_CONNECTION, conn.getUniqueId());
                     break;
                 }
             }
@@ -257,6 +257,8 @@ public abstract class NodeInstanceImpl implements org.jbpm.workflow.instance.Nod
     }
 
     protected void captureError(Exception e) {
+        e.printStackTrace();
+        logger.error("capture error", e);
         getProcessInstance().setErrorState(this, e);
     }
 
@@ -291,7 +293,7 @@ public abstract class NodeInstanceImpl implements org.jbpm.workflow.instance.Nod
         leaveTime = new Date();
         org.kie.api.definition.process.Node node = getNode();
         if (node != null) {
-            String uniqueId = (String) node.getMetaData().get(UNIQUE_ID);
+            String uniqueId = node.getUniqueId();
             if (uniqueId == null) {
                 uniqueId = ((NodeImpl) node).getUniqueId();
             }
@@ -456,8 +458,8 @@ public abstract class NodeInstanceImpl implements org.jbpm.workflow.instance.Nod
         nodeInstance.trigger(this, type);
         Collection<Connection> outgoing = getNode().getOutgoingConnections(type);
         for (Connection conn : outgoing) {
-            if (conn.getTo().getId() == nodeInstance.getNodeId()) {
-                this.metaData.put(OUTGOING_CONNECTION, conn.getMetaData().get(UNIQUE_ID));
+            if (conn.getTo().getId().equals(nodeInstance.getNodeId())) {
+                this.metaData.put(OUTGOING_CONNECTION, conn.getUniqueId());
                 break;
             }
         }
@@ -478,11 +480,11 @@ public abstract class NodeInstanceImpl implements org.jbpm.workflow.instance.Nod
         triggerNode(getNodeId(), !remove);
     }
 
-    public void triggerNode(long nodeId) {
+    public void triggerNode(WorkflowElementIdentifier nodeId) {
         triggerNode(nodeId, true);
     }
 
-    public void triggerNode(long nodeId, boolean fireEvents) {
+    public void triggerNode(WorkflowElementIdentifier nodeId, boolean fireEvents) {
         org.jbpm.workflow.instance.NodeInstance nodeInstance = ((org.jbpm.workflow.instance.NodeInstanceContainer) getNodeInstanceContainer())
                 .getNodeInstance(((KogitoNode) getNode()).getParentContainer().getNode(nodeId));
         triggerNodeInstance(nodeInstance, Node.CONNECTION_DEFAULT_TYPE, fireEvents);
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java
index 437b054eec..1646335437 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/impl/WorkflowProcessInstanceImpl.java
@@ -75,6 +75,7 @@ import org.jbpm.workflow.instance.node.EventSubProcessNodeInstance;
 import org.jbpm.workflow.instance.node.FaultNodeInstance;
 import org.jbpm.workflow.instance.node.StateBasedNodeInstance;
 import org.kie.api.definition.process.NodeContainer;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.runtime.rule.AgendaFilter;
 import org.kie.internal.process.CorrelationKey;
 import org.kie.kogito.internal.process.event.KogitoEventListener;
@@ -104,7 +105,6 @@ import static org.jbpm.ruleflow.core.Metadata.CUSTOM_SLA_DUE_DATE;
 import static org.jbpm.ruleflow.core.Metadata.EVENT_TYPE;
 import static org.jbpm.ruleflow.core.Metadata.EVENT_TYPE_SIGNAL;
 import static org.jbpm.ruleflow.core.Metadata.IS_FOR_COMPENSATION;
-import static org.jbpm.ruleflow.core.Metadata.UNIQUE_ID;
 import static org.jbpm.workflow.instance.impl.DummyEventListener.EMPTY_EVENT_LISTENER;
 import static org.jbpm.workflow.instance.node.TimerNodeInstance.TIMER_TRIGGERED_EVENT;
 import static org.kie.kogito.process.flexible.ItemDescription.Status.ACTIVE;
@@ -267,29 +267,29 @@ public abstract class WorkflowProcessInstanceImpl extends ProcessInstanceImpl im
     }
 
     @Override
-    public NodeInstance getFirstNodeInstance(final long nodeId) {
+    public NodeInstance getFirstNodeInstance(WorkflowElementIdentifier nodeId) {
         for (final NodeInstance nodeInstance : this.nodeInstances) {
-            if (nodeInstance.getNodeId() == nodeId && nodeInstance.getLevel() == getCurrentLevel()) {
+            if (nodeInstance.getNodeId().equals(nodeId) && nodeInstance.getLevel() == getCurrentLevel()) {
                 return nodeInstance;
             }
         }
         return null;
     }
 
-    public List<NodeInstance> getNodeInstances(final long nodeId) {
+    public List<NodeInstance> getNodeInstances(WorkflowElementIdentifier nodeId) {
         List<NodeInstance> result = new ArrayList<>();
         for (final NodeInstance nodeInstance : this.nodeInstances) {
-            if (nodeInstance.getNodeId() == nodeId) {
+            if (nodeInstance.getNodeId().equals(nodeId)) {
                 result.add(nodeInstance);
             }
         }
         return result;
     }
 
-    public List<NodeInstance> getNodeInstances(final long nodeId, final List<NodeInstance> currentView) {
+    public List<NodeInstance> getNodeInstances(WorkflowElementIdentifier nodeId, final List<NodeInstance> currentView) {
         List<NodeInstance> result = new ArrayList<>();
         for (final NodeInstance nodeInstance : currentView) {
-            if (nodeInstance.getNodeId() == nodeId) {
+            if (nodeInstance.getNodeId().equals(nodeId)) {
                 result.add(nodeInstance);
             }
         }
@@ -708,7 +708,7 @@ public abstract class WorkflowProcessInstanceImpl extends ProcessInstanceImpl im
                             }
                             nodeInstance.trigger(null, Node.CONNECTION_DEFAULT_TYPE);
                         } else if (node instanceof CompositeNode) {
-                            Optional<NodeInstance> instance = this.nodeInstances.stream().filter(ni -> ni.getNodeId() == node.getId()).findFirst();
+                            Optional<NodeInstance> instance = this.nodeInstances.stream().filter(ni -> ni.getNodeId().equals(node.getId())).findFirst();
                             instance.ifPresent(n -> ((CompositeNodeInstance) n).signalEvent(type, event));
                         }
                     }
@@ -854,7 +854,7 @@ public abstract class WorkflowProcessInstanceImpl extends ProcessInstanceImpl im
             if (n instanceof BoundaryEventNode) {
                 BoundaryEventNode boundaryEventNode = (BoundaryEventNode) n;
                 StateBasedNodeInstance attachedToNodeInstance = (StateBasedNodeInstance) getNodeInstances(true).stream()
-                        .filter(ni -> ni.getNode().getMetaData().get(UNIQUE_ID).equals(boundaryEventNode.getAttachedToNodeId())).findFirst().orElse(null);
+                        .filter(ni -> ni.getNode().getUniqueId().equals(boundaryEventNode.getAttachedToNodeId())).findFirst().orElse(null);
                 if (attachedToNodeInstance != null) {
                     Map<String, String> properties = new HashMap<>();
                     properties.put("AttachedToID", attachedToNodeInstance.getNodeDefinitionId());
@@ -868,7 +868,7 @@ public abstract class WorkflowProcessInstanceImpl extends ProcessInstanceImpl im
                         eventName = TIMER_TRIGGERED_EVENT;
                     }
 
-                    eventDesciptions.add(new BaseEventDescription(eventName, (String) n.getMetaData().get(UNIQUE_ID), n.getName(), eventType, null, getStringId(), dataType, properties));
+                    eventDesciptions.add(new BaseEventDescription(eventName, n.getUniqueId(), n.getName(), eventType, null, getStringId(), dataType, properties));
 
                 }
 
@@ -882,7 +882,7 @@ public abstract class WorkflowProcessInstanceImpl extends ProcessInstanceImpl im
                         Map<String, String> timerProperties = ((StateBasedNodeInstance) ni).extractTimerEventInformation();
                         if (timerProperties != null) {
 
-                            eventDesciptions.add(new BaseEventDescription(TIMER_TRIGGERED_EVENT, (String) startNode.getMetaData().get("UniqueId"), startNode.getName(), "timer", ni.getStringId(),
+                            eventDesciptions.add(new BaseEventDescription(TIMER_TRIGGERED_EVENT, (String) startNode.getUniqueId(), startNode.getName(), "timer", ni.getStringId(),
                                     getStringId(), null, timerProperties));
 
                         }
@@ -891,7 +891,7 @@ public abstract class WorkflowProcessInstanceImpl extends ProcessInstanceImpl im
 
                     for (String eventName : eventSubProcessNode.getEvents()) {
 
-                        eventDesciptions.add(new BaseEventDescription(eventName, (String) startNode.getMetaData().get("UniqueId"), startNode.getName(), "signal", null, getStringId(), dataType));
+                        eventDesciptions.add(new BaseEventDescription(eventName, (String) startNode.getUniqueId(), startNode.getName(), "signal", null, getStringId(), dataType));
                     }
 
                 }
@@ -900,7 +900,7 @@ public abstract class WorkflowProcessInstanceImpl extends ProcessInstanceImpl im
                 getNodeInstances(n.getId()).forEach(ni -> eventDesciptions.add(
                         new BaseEventDescription(
                                 ((EventNode) n).getType(),
-                                (String) n.getMetaData().get(UNIQUE_ID),
+                                n.getUniqueId(),
                                 n.getName(),
                                 (String) n.getMetaData().getOrDefault(EVENT_TYPE, EVENT_TYPE_SIGNAL),
                                 ni.getStringId(),
@@ -910,7 +910,7 @@ public abstract class WorkflowProcessInstanceImpl extends ProcessInstanceImpl im
                 getNodeInstances(n.getId()).forEach(ni -> eventDesciptions.add(
                         new BaseEventDescription(
                                 (String) n.getMetaData().get(CONDITION),
-                                (String) n.getMetaData().get(UNIQUE_ID),
+                                n.getUniqueId(),
                                 n.getName(),
                                 (String) n.getMetaData().getOrDefault(EVENT_TYPE, EVENT_TYPE_SIGNAL),
                                 ni.getStringId(),
@@ -1179,7 +1179,7 @@ public abstract class WorkflowProcessInstanceImpl extends ProcessInstanceImpl im
     public Collection<Milestone> milestones() {
         return getNodesByType(MilestoneNode.class)
                 .map(n -> {
-                    String uid = (String) n.getMetaData().get(UNIQUE_ID);
+                    String uid = n.getUniqueId();
                     return Milestone.builder()
                             .withId(uid)
                             .withName(n.getName())
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/BoundaryEventNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/BoundaryEventNodeInstance.java
index fa53336609..0decee69f7 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/BoundaryEventNodeInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/BoundaryEventNodeInstance.java
@@ -65,7 +65,7 @@ public class BoundaryEventNodeInstance extends EventNodeInstance {
     private boolean isAttachedToNodeActive(Collection<NodeInstance> nodeInstances, String attachedTo, String type, Object event) {
         if (nodeInstances != null && !nodeInstances.isEmpty()) {
             for (NodeInstance nInstance : nodeInstances) {
-                String nodeUniqueId = (String) nInstance.getNode().getMetaData().get("UniqueId");
+                String nodeUniqueId = (String) nInstance.getNode().getUniqueId();
                 boolean isActivating = ((WorkflowProcessInstanceImpl) nInstance.getProcessInstance()).getActivatingNodeIds().contains(nodeUniqueId);
                 if (attachedTo.equals(nodeUniqueId) && !isActivating) {
                     // in case this is timer event make sure it corresponds to the proper node instance
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeNodeInstance.java
index f07a0bccc0..e757112164 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeNodeInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/CompositeNodeInstance.java
@@ -43,6 +43,7 @@ import org.jbpm.workflow.instance.impl.NodeInstanceFactoryRegistry;
 import org.jbpm.workflow.instance.impl.NodeInstanceImpl;
 import org.kie.api.definition.process.Connection;
 import org.kie.api.definition.process.NodeContainer;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstanceContainer;
 
@@ -127,7 +128,7 @@ public class CompositeNodeInstance extends StateBasedNodeInstance implements Nod
             for (Connection connection : connections) {
                 if ((connection.getFrom() instanceof CompositeNode.CompositeNodeStart) &&
                         (from == null ||
-                                ((CompositeNode.CompositeNodeStart) connection.getFrom()).getInNode().getId() == from.getNodeId())) {
+                                ((CompositeNode.CompositeNodeStart) connection.getFrom()).getInNode().getId().equals(from.getNodeId()))) {
                     NodeInstance nodeInstance = getNodeInstance(connection.getFrom());
                     nodeInstance.trigger(null, nodeAndType.getType());
                     return;
@@ -264,9 +265,9 @@ public class CompositeNodeInstance extends StateBasedNodeInstance implements Nod
     }
 
     @Override
-    public NodeInstance getFirstNodeInstance(final long nodeId) {
+    public NodeInstance getFirstNodeInstance(WorkflowElementIdentifier nodeId) {
         for (final NodeInstance nodeInstance : this.nodeInstances) {
-            if (nodeInstance.getNodeId() == nodeId && nodeInstance.getLevel() == getCurrentLevel()) {
+            if (nodeInstance.getNodeId().equals(nodeId) && nodeInstance.getLevel() == getCurrentLevel()) {
                 return nodeInstance;
             }
         }
@@ -343,20 +344,20 @@ public class CompositeNodeInstance extends StateBasedNodeInstance implements Nod
         this.signalEvent(type, event, varName -> this.getVariable(varName));
     }
 
-    public List<NodeInstance> getNodeInstances(final long nodeId) {
+    public List<NodeInstance> getNodeInstances(WorkflowElementIdentifier nodeId) {
         List<NodeInstance> result = new ArrayList<>();
         for (final NodeInstance nodeInstance : this.nodeInstances) {
-            if (nodeInstance.getNodeId() == nodeId) {
+            if (nodeInstance.getNodeId().equals(nodeId)) {
                 result.add(nodeInstance);
             }
         }
         return result;
     }
 
-    public List<NodeInstance> getNodeInstances(final long nodeId, List<NodeInstance> currentView) {
+    public List<NodeInstance> getNodeInstances(WorkflowElementIdentifier nodeId, List<NodeInstance> currentView) {
         List<NodeInstance> result = new ArrayList<>();
         for (final NodeInstance nodeInstance : currentView) {
-            if (nodeInstance.getNodeId() == nodeId) {
+            if (nodeInstance.getNodeId().equals(nodeId)) {
                 result.add(nodeInstance);
             }
         }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/ForEachNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/ForEachNodeInstance.java
index bae62dd1f2..0b5df806ff 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/ForEachNodeInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/ForEachNodeInstance.java
@@ -98,11 +98,7 @@ public class ForEachNodeInstance extends CompositeContextNodeInstance {
             nodeInstance.setNodeId(node.getId());
             nodeInstance.setNodeInstanceContainer(this);
             nodeInstance.setProcessInstance(getProcessInstance());
-            String uniqueID = (String) node.getMetaData().get("UniqueId");
-            if (uniqueID == null) {
-                uniqueID = node.getId() + "";
-            }
-            int level = this.getLevelForNode(uniqueID);
+            int level = this.getLevelForNode(node.getUniqueId());
             nodeInstance.setLevel(level);
             return nodeInstance;
 
@@ -116,7 +112,7 @@ public class ForEachNodeInstance extends CompositeContextNodeInstance {
                 nodeInstance.setNodeId(node.getId());
                 nodeInstance.setNodeInstanceContainer(this);
                 nodeInstance.setProcessInstance(getProcessInstance());
-                String uniqueID = (String) node.getMetaData().get("UniqueId");
+                String uniqueID = node.getUniqueId();
                 if (uniqueID == null) {
                     uniqueID = node.getId() + "";
                 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/JoinInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/JoinInstance.java
index 82b362ba49..2447373154 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/JoinInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/JoinInstance.java
@@ -40,6 +40,7 @@ import org.jbpm.workflow.core.node.Join;
 import org.jbpm.workflow.core.node.Split;
 import org.jbpm.workflow.instance.impl.NodeInstanceImpl;
 import org.kie.api.definition.process.Connection;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.runtime.process.NodeInstance;
 import org.kie.api.runtime.process.NodeInstanceContainer;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
@@ -52,7 +53,7 @@ public class JoinInstance extends NodeInstanceImpl {
 
     private static final long serialVersionUID = 510l;
 
-    private Map<Long, Integer> triggers = new HashMap<>();
+    private Map<WorkflowElementIdentifier, Integer> triggers = new HashMap<>();
 
     protected Join getJoin() {
         return (Join) getNode();
@@ -73,11 +74,9 @@ public class JoinInstance extends NodeInstanceImpl {
             case Join.TYPE_AND:
                 Integer count = this.triggers.get(from.getNodeId());
                 if (count == null) {
-                    this.triggers.put(from.getNodeId(),
-                            1);
+                    this.triggers.put(from.getNodeId(), 1);
                 } else {
-                    this.triggers.put(from.getNodeId(),
-                            count.intValue() + 1);
+                    this.triggers.put(from.getNodeId(), count.intValue() + 1);
                 }
                 if (checkAllActivated()) {
                     decreaseAllTriggers();
@@ -98,11 +97,9 @@ public class JoinInstance extends NodeInstanceImpl {
             case Join.TYPE_N_OF_M:
                 count = this.triggers.get(from.getNodeId());
                 if (count == null) {
-                    this.triggers.put(from.getNodeId(),
-                            1);
+                    this.triggers.put(from.getNodeId(), 1);
                 } else {
-                    this.triggers.put(from.getNodeId(),
-                            count.intValue() + 1);
+                    this.triggers.put(from.getNodeId(), count.intValue() + 1);
                 }
                 int counter = 0;
                 for (final Connection connection : getJoin().getDefaultIncomingConnections()) {
@@ -171,8 +168,7 @@ public class JoinInstance extends NodeInstanceImpl {
             if (count.intValue() == 1) {
                 this.triggers.remove(connection.getFrom().getId());
             } else {
-                this.triggers.put(connection.getFrom().getId(),
-                        count.intValue() - 1);
+                this.triggers.put(connection.getFrom().getId(), count.intValue() - 1);
             }
         }
     }
@@ -186,9 +182,9 @@ public class JoinInstance extends NodeInstanceImpl {
 
             @Override
             public int compare(NodeInstance o1, NodeInstance o2) {
-                if (o1.getNodeId() == lookFor.getId()) {
+                if (o1.getNodeId().equals(lookFor.getId())) {
                     return 1;
-                } else if (o2.getNodeId() == lookFor.getId()) {
+                } else if (o2.getNodeId().equals(lookFor.getId())) {
                     return -1;
                 }
                 return 0;
@@ -201,7 +197,7 @@ public class JoinInstance extends NodeInstanceImpl {
                 continue;
             }
             org.kie.api.definition.process.Node node = nodeInstance.getNode();
-            Set<Long> vistedNodes = new HashSet<>();
+            Set<WorkflowElementIdentifier> vistedNodes = new HashSet<>();
             checkNodes(vistedNodes, node, node, lookFor);
             if (vistedNodes.contains(lookFor.getId()) && !vistedNodes.contains(node.getId())) {
                 return true;
@@ -211,7 +207,8 @@ public class JoinInstance extends NodeInstanceImpl {
         return false;
     }
 
-    private boolean checkNodes(Set<Long> vistedNodes, org.kie.api.definition.process.Node startAt, org.kie.api.definition.process.Node currentNode, org.kie.api.definition.process.Node lookFor) {
+    private boolean checkNodes(Set<WorkflowElementIdentifier> vistedNodes, org.kie.api.definition.process.Node startAt, org.kie.api.definition.process.Node currentNode,
+            org.kie.api.definition.process.Node lookFor) {
         if (currentNode == null) {
             // for dynamic/ad hoc task there is no node 
             return false;
@@ -228,14 +225,14 @@ public class JoinInstance extends NodeInstanceImpl {
                 return false;
             }
             for (Connection conn : connections) {
-                Set<Long> xorCopy = new HashSet<>(vistedNodes);
+                Set<WorkflowElementIdentifier> xorCopy = new HashSet<>(vistedNodes);
 
                 org.kie.api.definition.process.Node nextNode = conn.getTo();
                 if (nextNode == null) {
                     continue;
                 } else {
                     xorCopy.add(nextNode.getId());
-                    if (nextNode.getId() != lookFor.getId()) {
+                    if (!nextNode.getId().equals(lookFor.getId())) {
 
                         checkNodes(xorCopy, currentNode, nextNode, lookFor);
                     }
@@ -258,14 +255,14 @@ public class JoinInstance extends NodeInstanceImpl {
                         // we have already been here so let's continue
                         continue;
                     }
-                    if (nextNode.getId() == lookFor.getId()) {
+                    if (nextNode.getId().equals(lookFor.getId())) {
                         // we found the node that we are looking for, add it and continue to find out other parts
                         // as it could be part of a loop
                         vistedNodes.add(nextNode.getId());
                         continue;
                     }
                     vistedNodes.add(nextNode.getId());
-                    if (startAt.getId() == nextNode.getId()) {
+                    if (startAt.getId().equals(nextNode.getId())) {
                         return true;
                     } else {
                         boolean nestedCheck = checkNodes(vistedNodes, startAt, nextNode, lookFor);
@@ -289,11 +286,11 @@ public class JoinInstance extends NodeInstanceImpl {
         triggerCompleted(Node.CONNECTION_DEFAULT_TYPE, triggers.isEmpty());
     }
 
-    public Map<Long, Integer> getTriggers() {
+    public Map<WorkflowElementIdentifier, Integer> getTriggers() {
         return triggers;
     }
 
-    public void internalSetTriggers(Map<Long, Integer> triggers) {
+    public void internalSetTriggers(Map<WorkflowElementIdentifier, Integer> triggers) {
         this.triggers = triggers;
     }
 }
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/SplitInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/SplitInstance.java
index 47fb7610c8..5d6d2c4d61 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/SplitInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/SplitInstance.java
@@ -41,6 +41,7 @@ import org.jbpm.workflow.instance.NodeInstanceContainer;
 import org.jbpm.workflow.instance.WorkflowRuntimeException;
 import org.jbpm.workflow.instance.impl.NodeInstanceImpl;
 import org.kie.api.definition.process.Connection;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
 
@@ -248,13 +249,13 @@ public class SplitInstance extends NodeInstanceImpl {
     }
 
     protected boolean hasLoop(org.kie.api.definition.process.Node startAt, final org.kie.api.definition.process.Node lookFor) {
-        Set<Long> vistedNodes = new HashSet<>();
+        Set<WorkflowElementIdentifier> vistedNodes = new HashSet<>();
 
         return checkNodes(startAt, lookFor, vistedNodes);
 
     }
 
-    protected boolean checkNodes(org.kie.api.definition.process.Node currentNode, final org.kie.api.definition.process.Node lookFor, Set<Long> vistedNodes) {
+    protected boolean checkNodes(org.kie.api.definition.process.Node currentNode, final org.kie.api.definition.process.Node lookFor, Set<WorkflowElementIdentifier> vistedNodes) {
         List<Connection> connections = currentNode.getOutgoingConnections(Node.CONNECTION_DEFAULT_TYPE);
 
         for (Connection conn : connections) {
@@ -265,7 +266,7 @@ public class SplitInstance extends NodeInstanceImpl {
                 continue;
             } else {
                 vistedNodes.add(nextNode.getId());
-                if (nextNode.getId() == lookFor.getId()) {
+                if (nextNode.getId().equals(lookFor.getId())) {
                     return true;
                 }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java
index 68d8150838..554da5acc5 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateBasedNodeInstance.java
@@ -124,7 +124,7 @@ public abstract class StateBasedNodeInstance extends ExtendedNodeInstanceImpl im
             }
         }
 
-        ((WorkflowProcessInstanceImpl) getProcessInstance()).addActivatingNodeId((String) getNode().getMetaData().get("UniqueId"));
+        ((WorkflowProcessInstanceImpl) getProcessInstance()).addActivatingNodeId((String) getNode().getUniqueId());
     }
 
     @Override
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateNodeInstance.java
index 37a928a293..4ce5145a29 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateNodeInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/StateNodeInstance.java
@@ -52,6 +52,7 @@ public class StateNodeInstance extends CompositeContextNodeInstance implements E
         Connection selected = null;
         int priority = Integer.MAX_VALUE;
         for (Connection connection : stateNode.getOutgoingConnections(Node.CONNECTION_DEFAULT_TYPE)) {
+
             Collection<Constraint> constraints = stateNode.getConstraints(connection);
 
             if (constraints != null) {
@@ -162,7 +163,7 @@ public class StateNodeInstance extends CompositeContextNodeInstance implements E
             Collection<Constraint> constraints = getStateNode().getConstraints(connection);
             if (constraints != null) {
                 String constraintName = getActivationEventType() + "-"
-                        + connection.getTo().getId() + "-" + connection.getToType();
+                        + connection.getTo().getId().toExternalFormat() + "-" + connection.getToType();
                 if (constraintName.equals(event.getMatch().getRule().getName())
                         && checkProcessInstance((InternalMatch) event.getMatch())) {
                     selected = connection;
diff --git a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java
index a2399fba1f..8f4dc4df82 100755
--- a/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/jbpm/workflow/instance/node/WorkItemNodeInstance.java
@@ -341,7 +341,7 @@ public class WorkItemNodeInstance extends StateBasedNodeInstance implements Even
             workItemAborted((InternalKogitoWorkItem) event);
         } else if (("processInstanceCompleted:" + exceptionHandlingProcessInstanceId).equals(type)) {
             exceptionHandlingCompleted((WorkflowProcessInstance) event, null);
-        } else if (type.equals("RuleFlow-Activate" + getProcessInstance().getProcessId() + "-" + getNode().getMetaData().get("UniqueId"))) {
+        } else if (type.equals("RuleFlow-Activate" + getProcessInstance().getProcessId() + "-" + getNode().getUniqueId())) {
 
             trigger(null, Node.CONNECTION_DEFAULT_TYPE);
         } else {
diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java
index bc23614f1b..355431254c 100644
--- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java
+++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcess.java
@@ -187,16 +187,20 @@ public abstract class AbstractProcess<T extends Model> implements Process<T>, Pr
 
     }
 
+    public KogitoProcessRuntime getProcessRuntime() {
+        return this.processRuntime;
+    }
+
     @Override
     public void activate() {
         if (this.activated) {
             return;
         }
+        this.processRuntime = createProcessRuntime().getKogitoProcessRuntime();
         WorkflowProcessImpl p = (WorkflowProcessImpl) get();
         configure();
         List<StartNode> startNodes = p.getTimerStart();
         if (startNodes != null && !startNodes.isEmpty()) {
-            this.processRuntime = createProcessRuntime().getKogitoProcessRuntime();
             for (StartNode startNode : startNodes) {
                 if (startNode != null && startNode.getTimer() != null) {
                     String timerId = processRuntime.getJobsService().scheduleProcessJob(ProcessJobDescription.of(configureTimerInstance(startNode.getTimer()), this));
diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java
index 218a51da75..9f49340e95 100644
--- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java
+++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/AbstractProcessInstance.java
@@ -443,7 +443,7 @@ public abstract class AbstractProcessInstance<T extends Model> implements Proces
 
         org.kie.api.definition.process.Node node = rfp.getNodesRecursively()
                 .stream()
-                .filter(ni -> Objects.equals(nodeId, ni.getNodeUniqueId()) || Objects.equals(nodeId, ni.getName()) || Objects.equals(nodeId, String.valueOf(ni.getId())))
+                .filter(ni -> Objects.equals(nodeId, ni.getUniqueId()) || Objects.equals(nodeId, ni.getName()) || Objects.equals(nodeId, ni.getId().toExternalFormat()))
                 .findFirst()
                 .orElseThrow(() -> new NodeNotFoundException(this.id, nodeId));
 
@@ -509,7 +509,7 @@ public abstract class AbstractProcessInstance<T extends Model> implements Proces
                 .orElseThrow(() -> new WorkItemNotFoundException("Work item with id " + workItemId + " was not found in process instance " + id(), workItemId));
         return new BaseWorkItem(workItemInstance.getStringId(),
                 workItemInstance.getWorkItem().getStringId(),
-                Long.toString(workItemInstance.getNode().getId()),
+                workItemInstance.getNode().getId(),
                 (String) workItemInstance.getWorkItem().getParameters().getOrDefault("TaskName", workItemInstance.getNodeName()),
                 workItemInstance.getWorkItem().getState(),
                 workItemInstance.getWorkItem().getPhaseId(),
@@ -530,7 +530,7 @@ public abstract class AbstractProcessInstance<T extends Model> implements Proces
             if (p.test(ni) && ((WorkItemNodeInstance) ni).getWorkItem().enforce(policies)) {
                 BaseWorkItem taskName = new BaseWorkItem(ni.getStringId(),
                         ((WorkItemNodeInstance) ni).getWorkItemId(),
-                        Long.toString(ni.getNode().getId()),
+                        ni.getNode().getId(),
                         (String) ((WorkItemNodeInstance) ni).getWorkItem().getParameters().getOrDefault("TaskName", ni.getNodeName()),
                         ((WorkItemNodeInstance) ni).getWorkItem().getState(),
                         ((WorkItemNodeInstance) ni).getWorkItem().getPhaseId(),
diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/BaseWorkItem.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/BaseWorkItem.java
index 72650bde83..3b5d1f72de 100644
--- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/BaseWorkItem.java
+++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/BaseWorkItem.java
@@ -20,13 +20,14 @@ package org.kie.kogito.process.impl;
 
 import java.util.Map;
 
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.process.WorkItem;
 
 public class BaseWorkItem implements WorkItem {
 
     private final String id;
     private final String nodeInstanceId;
-    private final String nodeId;
+    private final WorkflowElementIdentifier nodeId;
     private final String name;
 
     private final int state;
@@ -37,7 +38,8 @@ public class BaseWorkItem implements WorkItem {
     private Map<String, Object> results;
 
     @SuppressWarnings("squid:S107")
-    public BaseWorkItem(String nodeInstanceId, String id, String nodeId, String name, int state, String phase, String phaseStatus, Map<String, Object> parameters, Map<String, Object> results) {
+    public BaseWorkItem(String nodeInstanceId, String id, WorkflowElementIdentifier nodeId, String name, int state, String phase, String phaseStatus, Map<String, Object> parameters,
+            Map<String, Object> results) {
         this.id = id;
         this.nodeInstanceId = nodeInstanceId;
         this.nodeId = nodeId;
@@ -55,7 +57,7 @@ public class BaseWorkItem implements WorkItem {
     }
 
     @Override
-    public String getNodeId() {
+    public WorkflowElementIdentifier getNodeId() {
         return nodeId;
     }
 
diff --git a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/ProcessServiceImpl.java b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/ProcessServiceImpl.java
index ec004f755f..3a59ab4569 100644
--- a/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/ProcessServiceImpl.java
+++ b/jbpm/jbpm-flow/src/main/java/org/kie/kogito/process/impl/ProcessServiceImpl.java
@@ -114,6 +114,16 @@ public class ProcessServiceImpl implements ProcessService {
         return mappable.map(MappableToModel::toModel);
     }
 
+    @Override
+    public <T> void migrateProcessInstances(Process<T> process, String targetProcessId, String targetProcessVersion, String... processIds) throws UnsupportedOperationException {
+        process.instances().migrateProcessInstances(targetProcessId, targetProcessVersion, processIds);
+    }
+
+    @Override
+    public <T> long migrateAll(Process<T> process, String targetProcessId, String targetProcessVersion) throws UnsupportedOperationException {
+        return process.instances().migrateAll(targetProcessId, targetProcessVersion);
+    }
+
     @Override
     public <T extends MappableToModel<R>, R> Optional<R> delete(Process<T> process, String id) {
         return UnitOfWorkExecutor.executeInUnitOfWork(
@@ -400,4 +410,5 @@ public class ProcessServiceImpl implements ProcessService {
                 new Policy<?>[] { policy },
                 JsonSchemaUtil.load(Thread.currentThread().getContextClassLoader(), process.id(), taskName));
     }
+
 }
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/event/process/ProcessEventSupportTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/event/process/ProcessEventSupportTest.java
index bd34daacd3..7b85efad7d 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/event/process/ProcessEventSupportTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/event/process/ProcessEventSupportTest.java
@@ -25,6 +25,7 @@ import org.jbpm.process.core.event.EventFilter;
 import org.jbpm.process.core.event.EventTypeFilter;
 import org.jbpm.process.instance.impl.Action;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.test.util.AbstractBaseTest;
 import org.jbpm.workflow.core.DroolsAction;
 import org.jbpm.workflow.core.Node;
@@ -36,6 +37,7 @@ import org.jbpm.workflow.core.node.EventNode;
 import org.jbpm.workflow.core.node.EventTrigger;
 import org.jbpm.workflow.core.node.StartNode;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.event.process.ProcessCompletedEvent;
 import org.kie.api.event.process.ProcessEvent;
 import org.kie.api.event.process.ProcessEventListener;
@@ -51,6 +53,11 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 public class ProcessEventSupportTest extends AbstractBaseTest {
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("two");
+    private static WorkflowElementIdentifier three = WorkflowElementIdentifierFactory.fromExternalFormat("three");
+    private static WorkflowElementIdentifier four = WorkflowElementIdentifierFactory.fromExternalFormat("four");
+
     public void addLogger() {
         logger = LoggerFactory.getLogger(this.getClass());
     }
@@ -63,7 +70,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
 
         StartNode startNode = new StartNode();
         startNode.setName("Start");
-        startNode.setId(1);
+        startNode.setId(one);
         process.addNode(startNode);
 
         ActionNode actionNode = new ActionNode();
@@ -71,7 +78,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
         DroolsAction action = new DroolsConsequenceAction("java", null);
         action.setMetaData("Action", (Action) context -> logger.info("Executed action"));
         actionNode.setAction(action);
-        actionNode.setId(2);
+        actionNode.setId(two);
         process.addNode(actionNode);
         new ConnectionImpl(
                 startNode, Node.CONNECTION_DEFAULT_TYPE,
@@ -79,7 +86,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
 
         EndNode endNode = new EndNode();
         endNode.setName("End");
-        endNode.setId(3);
+        endNode.setId(three);
         process.addNode(endNode);
         new ConnectionImpl(
                 actionNode, Node.CONNECTION_DEFAULT_TYPE,
@@ -162,7 +169,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
 
         StartNode startNode = new StartNode();
         startNode.setName("Start");
-        startNode.setId(1);
+        startNode.setId(one);
         process.addNode(startNode);
 
         ActionNode actionNode = new ActionNode();
@@ -170,13 +177,13 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
         DroolsAction action = new DroolsConsequenceAction("java", null);
         action.setMetaData("Action", (Action) context -> logger.info("Executed action"));
         actionNode.setAction(action);
-        actionNode.setId(2);
+        actionNode.setId(two);
         process.addNode(actionNode);
         new ConnectionImpl(startNode, Node.CONNECTION_DEFAULT_TYPE, actionNode, Node.CONNECTION_DEFAULT_TYPE);
 
         EndNode endNode = new EndNode();
         endNode.setName("End");
-        endNode.setId(3);
+        endNode.setId(three);
         process.addNode(endNode);
         new ConnectionImpl(actionNode, Node.CONNECTION_DEFAULT_TYPE, endNode, Node.CONNECTION_DEFAULT_TYPE);
 
@@ -235,7 +242,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
 
         StartNode startNode = new StartNode();
         startNode.setName("Start");
-        startNode.setId(1);
+        startNode.setId(one);
         process.addNode(startNode);
 
         ActionNode actionNode = new ActionNode();
@@ -243,7 +250,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
         DroolsAction action = new DroolsConsequenceAction("java", null);
         action.setMetaData("Action", (Action) context -> logger.info("Executed action"));
         actionNode.setAction(action);
-        actionNode.setId(2);
+        actionNode.setId(two);
         process.addNode(actionNode);
         new ConnectionImpl(
                 startNode, Node.CONNECTION_DEFAULT_TYPE,
@@ -251,7 +258,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
 
         EventNode eventNode = new EventNode();
         eventNode.setName("Event");
-        eventNode.setId(3);
+        eventNode.setId(three);
 
         List<EventFilter> filters = new ArrayList<EventFilter>();
         EventTypeFilter filter = new EventTypeFilter();
@@ -265,7 +272,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
 
         EndNode endNode = new EndNode();
         endNode.setName("End");
-        endNode.setId(4);
+        endNode.setId(four);
         process.addNode(endNode);
         new ConnectionImpl(
                 eventNode, Node.CONNECTION_DEFAULT_TYPE,
@@ -353,7 +360,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
 
         StartNode startNode = new StartNode();
         startNode.setName("Start");
-        startNode.setId(1);
+        startNode.setId(one);
         process.addNode(startNode);
 
         ActionNode actionNode = new ActionNode();
@@ -361,7 +368,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
         DroolsAction action = new DroolsConsequenceAction("java", null);
         action.setMetaData("Action", (Action) context -> logger.info("Executed action"));
         actionNode.setAction(action);
-        actionNode.setId(2);
+        actionNode.setId(two);
         process.addNode(actionNode);
         new ConnectionImpl(
                 startNode, Node.CONNECTION_DEFAULT_TYPE,
@@ -369,7 +376,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
 
         EndNode endNode = new EndNode();
         endNode.setName("End");
-        endNode.setId(3);
+        endNode.setId(three);
         endNode.setTerminate(false);
         process.addNode(endNode);
         new ConnectionImpl(
@@ -450,7 +457,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
 
         StartNode startNode = new StartNode();
         startNode.setName("Start");
-        startNode.setId(1);
+        startNode.setId(one);
         EventTrigger trigger = new EventTrigger();
         EventTypeFilter eventFilter = new EventTypeFilter();
         eventFilter.setType("signal");
@@ -463,7 +470,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
         DroolsAction action = new DroolsConsequenceAction("java", null);
         action.setMetaData("Action", (Action) context -> logger.info("Executed action"));
         actionNode.setAction(action);
-        actionNode.setId(2);
+        actionNode.setId(two);
         process.addNode(actionNode);
         new ConnectionImpl(
                 startNode, Node.CONNECTION_DEFAULT_TYPE,
@@ -471,7 +478,7 @@ public class ProcessEventSupportTest extends AbstractBaseTest {
 
         EndNode endNode = new EndNode();
         endNode.setName("End");
-        endNode.setId(3);
+        endNode.setId(three);
         process.addNode(endNode);
         new ConnectionImpl(
                 actionNode, Node.CONNECTION_DEFAULT_TYPE,
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/CompensationTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/CompensationTest.java
index 6ef5c45fed..fcaacc4f33 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/CompensationTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/CompensationTest.java
@@ -138,7 +138,7 @@ public class CompensationTest extends AbstractBaseTest {
         kruntime = createKogitoProcessRuntime(process);
 
         Node compensatedNode = findNode(process, "work1");
-        String compensationEvent = (String) compensatedNode.getMetaData().get("UniqueId");
+        String compensationEvent = (String) compensatedNode.getUniqueId();
 
         runCompensationBoundaryEventSpecificTest(kruntime, process, processId, workItemNames, eventList, compensationEvent);
     }
@@ -264,7 +264,7 @@ public class CompensationTest extends AbstractBaseTest {
         RuleFlowProcess process = createCompensationEventSubProcessProcess(processId, workItemNames, eventList);
 
         Node toCompensateNode = findNode(process, "sub0");
-        String compensationEvent = (String) toCompensateNode.getMetaData().get("UniqueId");
+        String compensationEvent = (String) toCompensateNode.getUniqueId();
 
         // run process
         kruntime = createKogitoProcessRuntime(process);
@@ -388,7 +388,7 @@ public class CompensationTest extends AbstractBaseTest {
         eventFilter.setType("Compensation");
         espNode.addEvent(eventFilter);
 
-        addCompensationScope(espNode, process, (String) compositeNode.getMetaData("UniqueId"));
+        addCompensationScope(espNode, process, compositeNode.getUniqueId());
 
         startNodeCreator.setNodeContainer(espNode);
         endNodeCreator.setNodeContainer(espNode);
@@ -420,7 +420,7 @@ public class CompensationTest extends AbstractBaseTest {
         RuleFlowProcess process = createNestedCompensationEventSubProcessProcess(processId, workItemNames, eventList);
 
         Node toCompensateNode = findNode(process, "sub1");
-        String compensationEvent = (String) toCompensateNode.getMetaData().get("UniqueId");
+        String compensationEvent = toCompensateNode.getUniqueId();
 
         kruntime = createKogitoProcessRuntime(process);
 
@@ -435,7 +435,7 @@ public class CompensationTest extends AbstractBaseTest {
         RuleFlowProcess process = createNestedCompensationEventSubProcessProcess(processId, workItemNames, eventList);
 
         Node toCompensateNode = findNode(process, "sub0");
-        String compensationEvent = CompensationScope.IMPLICIT_COMPENSATION_PREFIX + toCompensateNode.getMetaData().get("UniqueId");
+        String compensationEvent = CompensationScope.IMPLICIT_COMPENSATION_PREFIX + toCompensateNode.getUniqueId();
 
         kruntime = createKogitoProcessRuntime(process);
 
@@ -519,7 +519,7 @@ public class CompensationTest extends AbstractBaseTest {
             eventFilter.setType("Compensation");
             espNode.addEvent(eventFilter);
 
-            addCompensationScope(espNode, compensationScopeContainerNode, (String) compositeNode.getMetaData("UniqueId"));
+            addCompensationScope(espNode, compensationScopeContainerNode, compositeNode.getUniqueId());
 
             StartNode startNode = startNodeCreator.createNode("start3*");
             ActionNode actionNode = actionNodeCreator.createNode("action3*");
@@ -551,7 +551,7 @@ public class CompensationTest extends AbstractBaseTest {
         kruntime = createKogitoProcessRuntime(process);
 
         Node compensatedNode = findNode(process, "work-comp-1");
-        String compensationEvent = (String) compensatedNode.getMetaData().get("UniqueId");
+        String compensationEvent = (String) compensatedNode.getUniqueId();
 
         runCompensationBoundaryEventSpecificTest(kruntime, process, processId, workItemNames, eventList, compensationEvent);
     }
@@ -567,7 +567,7 @@ public class CompensationTest extends AbstractBaseTest {
         kruntime = createKogitoProcessRuntime(process);
         Node toCompensateNode = findNode(process, "sub2");
         String compensationEvent = CompensationScope.IMPLICIT_COMPENSATION_PREFIX
-                + toCompensateNode.getMetaData().get("UniqueId");
+                + toCompensateNode.getUniqueId();
 
         runCompensationBoundaryEventGeneralTest(kruntime, process, processId, workItemNames, eventList, compensationEvent);
     }
@@ -674,7 +674,7 @@ public class CompensationTest extends AbstractBaseTest {
 
         NodeCreator<BoundaryEventNode> boundaryNodeCreator = new NodeCreator<BoundaryEventNode>(nodeContainer, BoundaryEventNode.class);
         BoundaryEventNode boundaryNode = boundaryNodeCreator.createNode("boundary" + id);
-        String attachedTo = (String) attachedToNode.getMetaData().get("UniqueId");
+        String attachedTo = attachedToNode.getUniqueId();
         boundaryNode.setMetaData("AttachedTo", attachedTo);
         boundaryNode.setAttachedToNodeId(attachedTo);
 
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/FactoryTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/FactoryTest.java
index de083c1c10..126c6c33c8 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/FactoryTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/FactoryTest.java
@@ -26,13 +26,20 @@ import java.util.Objects;
 
 import org.jbpm.process.core.datatype.impl.type.ObjectDataType;
 import org.jbpm.ruleflow.core.RuleFlowProcessFactory;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.test.util.AbstractBaseTest;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
 import org.slf4j.LoggerFactory;
 
 public class FactoryTest extends AbstractBaseTest {
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("two");
+    private static WorkflowElementIdentifier three = WorkflowElementIdentifierFactory.fromExternalFormat("three");
+    private static WorkflowElementIdentifier four = WorkflowElementIdentifierFactory.fromExternalFormat("four");
+
     public void addLogger() {
         logger = LoggerFactory.getLogger(this.getClass());
     }
@@ -50,12 +57,11 @@ public class FactoryTest extends AbstractBaseTest {
         factory.version("1.0");
         factory.visibility("Private");
         factory.metaData("TargetNamespace", "http://www.example.org/MinimalExample");
-        factory.startNode(1)
+        factory.startNode(one)
                 .name("StartProcess")
                 .done();
 
-        factory.dynamicNode(2)
-                .metaData("UniqueId", "_2")
+        factory.dynamicNode(two)
                 .metaData("MICollectionOutput", "_2_listOutOutput")
                 .metaData("x", 96)
                 .metaData("y", 16)
@@ -66,7 +72,7 @@ public class FactoryTest extends AbstractBaseTest {
                 .language("java")
                 .done();
 
-        factory.humanTaskNode(3)
+        factory.humanTaskNode(three)
                 .name("Task")
                 .taskName("Task Name")
                 .actorId("Actor")
@@ -79,14 +85,14 @@ public class FactoryTest extends AbstractBaseTest {
                 .timer("1s", null, "java", "")
                 .done();
 
-        factory.faultNode(4).name("Fault")
+        factory.faultNode(four).name("Fault")
                 .faultName("Fault Name")
                 .faultVariable("x")
                 .done();
 
-        factory.connection(1, 2, "_1-_2")
-                .connection(2, 3, "_2-_3")
-                .connection(3, 4, "_3-_4");
+        factory.connection(one, two, "_1-_2")
+                .connection(two, three, "_2-_3")
+                .connection(three, four, "_3-_4");
 
         factory.validate();
 
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/ForEachTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/ForEachTest.java
index 87a3766f51..6ccb9aa95a 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/ForEachTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/ForEachTest.java
@@ -25,13 +25,20 @@ import java.util.Map;
 
 import org.jbpm.process.core.datatype.impl.type.ObjectDataType;
 import org.jbpm.ruleflow.core.RuleFlowProcessFactory;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.test.util.AbstractBaseTest;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
 import org.slf4j.LoggerFactory;
 
 public class ForEachTest extends AbstractBaseTest {
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("two");
+    private static WorkflowElementIdentifier three = WorkflowElementIdentifierFactory.fromExternalFormat("three");
+    private static WorkflowElementIdentifier five = WorkflowElementIdentifierFactory.fromExternalFormat("five");
+
     public void addLogger() {
         logger = LoggerFactory.getLogger(this.getClass());
     }
@@ -49,11 +56,10 @@ public class ForEachTest extends AbstractBaseTest {
         factory.version("1.0");
         factory.visibility("Private");
         factory.metaData("TargetNamespace", "http://www.example.org/MinimalExample");
-        org.jbpm.ruleflow.core.factory.StartNodeFactory startNode1 = factory.startNode(1);
+        org.jbpm.ruleflow.core.factory.StartNodeFactory startNode1 = factory.startNode(one);
         startNode1.name("StartProcess");
         startNode1.done();
-        org.jbpm.ruleflow.core.factory.ForEachNodeFactory forEachNode2 = factory.forEachNode(2);
-        forEachNode2.metaData("UniqueId", "_2");
+        org.jbpm.ruleflow.core.factory.ForEachNodeFactory forEachNode2 = factory.forEachNode(two);
         forEachNode2.metaData("MICollectionOutput", "_2_listOutOutput");
         forEachNode2.metaData("x", 96);
         forEachNode2.metaData("width", 110);
@@ -65,17 +71,17 @@ public class ForEachTest extends AbstractBaseTest {
         forEachNode2.outputCollectionExpression("listOut");
         forEachNode2.outputVariable("y", new ObjectDataType("java.lang.String"));
 
-        forEachNode2.actionNode(5).action((kcontext) -> System.out.println(kcontext.getVariable("x"))).done();
-        forEachNode2.linkIncomingConnections(5);
-        forEachNode2.linkOutgoingConnections(5);
+        forEachNode2.actionNode(five).action((kcontext) -> System.out.println(kcontext.getVariable("x"))).done();
+        forEachNode2.linkIncomingConnections(five);
+        forEachNode2.linkOutgoingConnections(five);
 
         forEachNode2.done();
-        org.jbpm.ruleflow.core.factory.EndNodeFactory endNode3 = factory.endNode(3);
+        org.jbpm.ruleflow.core.factory.EndNodeFactory endNode3 = factory.endNode(three);
         endNode3.name("EndProcess");
         endNode3.terminate(true);
         endNode3.done();
-        factory.connection(1, 2, "_1-_2");
-        factory.connection(2, 3, "_2-_3");
+        factory.connection(one, two, "_1-_2");
+        factory.connection(two, three, "_2-_3");
         factory.validate();
 
         List<String> list = new ArrayList<String>();
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/ProcessFactoryTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/ProcessFactoryTest.java
index c9aa4c873b..f970ef874d 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/ProcessFactoryTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/ProcessFactoryTest.java
@@ -19,12 +19,20 @@
 package org.jbpm.process;
 
 import org.jbpm.ruleflow.core.RuleFlowProcessFactory;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.test.util.AbstractBaseTest;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.slf4j.LoggerFactory;
 
 public class ProcessFactoryTest extends AbstractBaseTest {
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("two");
+    private static WorkflowElementIdentifier three = WorkflowElementIdentifierFactory.fromExternalFormat("three");
+    private static WorkflowElementIdentifier four = WorkflowElementIdentifierFactory.fromExternalFormat("four");
+    private static WorkflowElementIdentifier five = WorkflowElementIdentifierFactory.fromExternalFormat("five");
+
     public void addLogger() {
         logger = LoggerFactory.getLogger(this.getClass());
     }
@@ -36,17 +44,17 @@ public class ProcessFactoryTest extends AbstractBaseTest {
                 // header
                 .name("My process").packageName("org.drools")
                 // nodes
-                .startNode(1).name("Start").done()
-                .actionNode(2).name("Action")
+                .startNode(one).name("Start").done()
+                .actionNode(two).name("Action")
                 .action("java",
                         "System.out.println(\"Action\");")
                 .done()
-                .endNode(3).name("End").done()
+                .endNode(three).name("End").done()
                 // connections
-                .connection(1,
-                        2)
-                .connection(2,
-                        3);
+                .connection(one,
+                        two)
+                .connection(two,
+                        three);
         factory.validate().getProcess();
     }
 }
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/SubProcessTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/SubProcessTest.java
index 2e9bf74489..7cc41835e8 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/SubProcessTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/SubProcessTest.java
@@ -19,6 +19,7 @@
 package org.jbpm.process;
 
 import org.jbpm.ruleflow.core.RuleFlowProcess;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.test.util.AbstractBaseTest;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.impl.ConnectionImpl;
@@ -26,6 +27,7 @@ import org.jbpm.workflow.core.node.EndNode;
 import org.jbpm.workflow.core.node.StartNode;
 import org.jbpm.workflow.core.node.SubProcessNode;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
 import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
 import org.slf4j.LoggerFactory;
@@ -34,6 +36,10 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 public class SubProcessTest extends AbstractBaseTest {
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("two");
+    private static WorkflowElementIdentifier three = WorkflowElementIdentifierFactory.fromExternalFormat("three");
+
     public void addLogger() {
         logger = LoggerFactory.getLogger(this.getClass());
     }
@@ -46,14 +52,14 @@ public class SubProcessTest extends AbstractBaseTest {
         process.setName("Process");
         StartNode startNode = new StartNode();
         startNode.setName("Start");
-        startNode.setId(1);
+        startNode.setId(one);
         SubProcessNode subProcessNode = new SubProcessNode();
         subProcessNode.setName("SubProcessNode");
-        subProcessNode.setId(2);
+        subProcessNode.setId(two);
         subProcessNode.setProcessId(nonExistentSubProcessName);
         EndNode endNode = new EndNode();
         endNode.setName("End");
-        endNode.setId(3);
+        endNode.setId(three);
 
         connect(startNode, subProcessNode);
         connect(subProcessNode, endNode);
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/WorkItemTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/WorkItemTest.java
index 726355ab3c..20186b16a0 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/WorkItemTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/WorkItemTest.java
@@ -37,6 +37,7 @@ import org.jbpm.process.instance.impl.demo.DoNothingWorkItemHandler;
 import org.jbpm.process.instance.impl.demo.MockDataWorkItemHandler;
 import org.jbpm.process.test.Person;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.test.util.AbstractBaseTest;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.impl.ConnectionImpl;
@@ -45,6 +46,7 @@ import org.jbpm.workflow.core.node.StartNode;
 import org.jbpm.workflow.core.node.WorkItemNode;
 import org.jbpm.workflow.instance.WorkflowProcessInstance;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
 import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
 import org.kie.kogito.process.workitems.KogitoWorkItemHandlerNotFoundException;
@@ -55,6 +57,10 @@ import static org.assertj.core.api.Assertions.fail;
 
 public class WorkItemTest extends AbstractBaseTest {
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("two");
+    private static WorkflowElementIdentifier three = WorkflowElementIdentifierFactory.fromExternalFormat("three");
+
     public void addLogger() {
         logger = LoggerFactory.getLogger(this.getClass());
     }
@@ -216,11 +222,11 @@ public class WorkItemTest extends AbstractBaseTest {
 
         StartNode startNode = new StartNode();
         startNode.setName("Start");
-        startNode.setId(1);
+        startNode.setId(one);
 
         WorkItemNode workItemNode = new WorkItemNode();
         workItemNode.setName("workItemNode");
-        workItemNode.setId(2);
+        workItemNode.setId(two);
         workItemNode.getIoSpecification().addInputMapping("#{Person.name}", "Comment");
         workItemNode.getIoSpecification().addInputMapping("MyObject", "Attachment");
         workItemNode.getIoSpecification().addOutputMapping("Result", "MyObject");
@@ -244,7 +250,7 @@ public class WorkItemTest extends AbstractBaseTest {
 
         EndNode endNode = new EndNode();
         endNode.setName("End");
-        endNode.setId(3);
+        endNode.setId(three);
 
         connect(startNode,
                 workItemNode);
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/instance/LightProcessRuntimeTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/instance/LightProcessRuntimeTest.java
index 12f1f10155..61a3c1f28a 100644
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/instance/LightProcessRuntimeTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/instance/LightProcessRuntimeTest.java
@@ -22,7 +22,9 @@ import java.util.Collections;
 
 import org.jbpm.ruleflow.core.RuleFlowProcess;
 import org.jbpm.ruleflow.core.RuleFlowProcessFactory;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.Application;
 import org.kie.kogito.process.Processes;
 
@@ -32,6 +34,10 @@ import static org.mockito.Mockito.when;
 
 class LightProcessRuntimeTest {
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("two");
+    private static WorkflowElementIdentifier three = WorkflowElementIdentifierFactory.fromExternalFormat("three");
+
     static class MyProcess {
         String result;
         RuleFlowProcess process = RuleFlowProcessFactory.createProcess("org.kie.api2.MyProcessUnit")
@@ -40,15 +46,15 @@ class LightProcessRuntimeTest {
                 .version("1.0")
                 .packageName("org.jbpm")
                 // Nodes
-                .startNode(1).name("Start").done()
-                .actionNode(2).name("Action")
+                .startNode(one).name("Start").done()
+                .actionNode(two).name("Action")
                 .action(ctx -> {
                     result = "Hello!";
                 }).done()
-                .endNode(3).name("End").done()
+                .endNode(three).name("End").done()
                 // Connections
-                .connection(1, 2)
-                .connection(2, 3).validate().getProcess();
+                .connection(one, two)
+                .connection(two, three).validate().getProcess();
     }
 
     @Test
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/test/NodeCreator.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/test/NodeCreator.java
index 9343631e6c..c85b5cf021 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/process/test/NodeCreator.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/process/test/NodeCreator.java
@@ -22,6 +22,7 @@ import java.lang.reflect.Constructor;
 
 import org.jbpm.process.core.Work;
 import org.jbpm.process.core.impl.WorkImpl;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.NodeContainer;
 import org.jbpm.workflow.core.impl.ConnectionImpl;
@@ -41,7 +42,7 @@ public class NodeCreator<T extends NodeImpl> {
 
     public T createNode(String name) throws Exception {
         T result = this.constructor.newInstance(new Object[0]);
-        result.setId(idGen++);
+        result.setId(WorkflowElementIdentifierFactory.fromExternalFormat(String.valueOf(idGen++)));
         result.setName(name);
         this.nodeContainer.addNode(result);
 
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidatorTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidatorTest.java
index a465961644..f6e52f25e7 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidatorTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/ruleflow/core/validation/RuleFlowProcessValidatorTest.java
@@ -25,6 +25,7 @@ import org.jbpm.process.core.context.variable.Variable;
 import org.jbpm.process.core.datatype.impl.type.StringDataType;
 import org.jbpm.process.core.validation.ProcessValidationError;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.workflow.core.DroolsAction;
 import org.jbpm.workflow.core.Node;
 import org.jbpm.workflow.core.impl.DroolsConsequenceAction;
@@ -42,6 +43,7 @@ import org.jbpm.workflow.core.node.WorkItemNode;
 import org.jbpm.workflow.instance.rule.RuleType;
 import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 
 import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
@@ -50,6 +52,11 @@ import static org.mockito.Mockito.when;
 
 public class RuleFlowProcessValidatorTest {
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("1");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("2");
+    private static WorkflowElementIdentifier three = WorkflowElementIdentifierFactory.fromExternalFormat("3");
+    private static WorkflowElementIdentifier four = WorkflowElementIdentifierFactory.fromExternalFormat("4");
+
     private RuleFlowProcessValidator validator;
 
     private List<ProcessValidationError> errors;
@@ -73,7 +80,7 @@ public class RuleFlowProcessValidatorTest {
     @Test
     void testAddErrorMessage() {
         when(node.getName()).thenReturn("nodeName");
-        when(node.getId()).thenReturn(Long.MAX_VALUE);
+        when(node.getId()).thenReturn(WorkflowElementIdentifierFactory.fromExternalFormat(Long.MAX_VALUE));
         validator.addErrorMessage(process,
                 node,
                 errors,
@@ -86,7 +93,7 @@ public class RuleFlowProcessValidatorTest {
     void testDynamicNodeValidationInNotDynamicProcess() {
         DynamicNode dynamicNode = new DynamicNode();
         dynamicNode.setName("MyDynamicNode");
-        dynamicNode.setId(1);
+        dynamicNode.setId(one);
         dynamicNode.setAutoComplete(false);
         // empty completion expression to trigger validation error
         process.addNode(dynamicNode);
@@ -109,7 +116,7 @@ public class RuleFlowProcessValidatorTest {
 
         DynamicNode dynamicNode = new DynamicNode();
         dynamicNode.setName("MyDynamicNode");
-        dynamicNode.setId(1);
+        dynamicNode.setId(one);
         dynamicNode.setAutoComplete(false);
         dynamicNode.setCompletionExpression(kcontext -> true);
         process.addNode(dynamicNode);
@@ -122,7 +129,7 @@ public class RuleFlowProcessValidatorTest {
         process.removeNode(dynamicNode);
         DynamicNode dynamicNode2 = new DynamicNode();
         dynamicNode2.setName("MyDynamicNode");
-        dynamicNode2.setId(1);
+        dynamicNode2.setId(one);
         dynamicNode2.setAutoComplete(false);
         process.addNode(dynamicNode2);
 
@@ -152,11 +159,11 @@ public class RuleFlowProcessValidatorTest {
     void testIdVariableName() {
         StartNode startNode = new StartNode();
         startNode.setName("Start");
-        startNode.setId(1);
+        startNode.setId(one);
         process.addNode(startNode);
         EndNode endNode = new EndNode();
         endNode.setName("EndNode");
-        endNode.setId(2);
+        endNode.setId(two);
         process.addNode(endNode);
         new org.jbpm.workflow.core.impl.ConnectionImpl(
                 startNode,
@@ -178,15 +185,15 @@ public class RuleFlowProcessValidatorTest {
     void testCompositeNodeNoStart() {
         StartNode startNode = new StartNode();
         startNode.setName("Start");
-        startNode.setId(1);
+        startNode.setId(one);
         process.addNode(startNode);
         EndNode endNode = new EndNode();
         endNode.setName("EndNode");
-        endNode.setId(2);
+        endNode.setId(two);
         process.addNode(endNode);
         CompositeNode compositeNode = new CompositeNode();
         compositeNode.setName("CompositeNode");
-        compositeNode.setId(3);
+        compositeNode.setId(three);
         process.addNode(compositeNode);
         new org.jbpm.workflow.core.impl.ConnectionImpl(
                 startNode,
@@ -213,7 +220,7 @@ public class RuleFlowProcessValidatorTest {
         testNodeOnEntryOnExit(ruleSetNode);
         testNodeOnEntryOnExit(new SubProcessNode());
         testNodeOnEntryOnExit(new WorkItemNode());
-        testNodeOnEntryOnExit(new ForEachNode());
+        testNodeOnEntryOnExit(new ForEachNode(one));
         testNodeOnEntryOnExit(new DynamicNode());
         testNodeOnEntryOnExit(new CompositeNode());
     }
@@ -221,34 +228,34 @@ public class RuleFlowProcessValidatorTest {
     private void testNodeOnEntryOnExit(ExtendedNodeImpl node) {
         List<ProcessValidationError> errors = new ArrayList<>();
         node.setName("name");
-        node.setId(1);
+        node.setId(node.getId());
         node.setActions(ExtendedNodeImpl.EVENT_NODE_ENTER, singletonList(new DroolsAction()));
         node.setActions(ExtendedNodeImpl.EVENT_NODE_EXIT, singletonList(new DroolsAction()));
         validator.validateNodes(new org.kie.api.definition.process.Node[] { node }, errors, process);
         assertThat(errors).extracting("message").contains(
-                "Node 'name' [1] On Entry Action is not yet supported in Kogito",
-                "Node 'name' [1] On Exit Action is not yet supported in Kogito");
+                "Node 'name' [" + node.getId().toExternalFormat() + "] On Entry Action is not yet supported in Kogito",
+                "Node 'name' [" + node.getId().toExternalFormat() + "] On Exit Action is not yet supported in Kogito");
     }
 
     @Test
     void testScriptTaskDialect() {
         StartNode startNode = new StartNode();
         startNode.setName("Start");
-        startNode.setId(1);
+        startNode.setId(one);
         process.addNode(startNode);
         EndNode endNode = new EndNode();
         endNode.setName("EndNode");
-        endNode.setId(2);
+        endNode.setId(two);
         process.addNode(endNode);
         ActionNode actionNode1 = new ActionNode();
         actionNode1.setName("ActionNode1");
         actionNode1.setAction(new DroolsConsequenceAction("mvel", "System.out.println();"));
-        actionNode1.setId(3);
+        actionNode1.setId(three);
         process.addNode(actionNode1);
         ActionNode actionNode2 = new ActionNode();
         actionNode2.setName("ActionNode2");
         actionNode2.setAction(new DroolsConsequenceAction("java", "System.out.println();"));
-        actionNode2.setId(4);
+        actionNode2.setId(four);
         process.addNode(actionNode2);
         new org.jbpm.workflow.core.impl.ConnectionImpl(
                 startNode,
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/core/node/NodeInnerClassesTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/core/node/NodeInnerClassesTest.java
index 29985f0952..f21eaa7b9b 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/core/node/NodeInnerClassesTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/core/node/NodeInnerClassesTest.java
@@ -24,10 +24,13 @@ import java.util.List;
 import org.jbpm.process.core.context.variable.Variable;
 import org.jbpm.process.core.datatype.impl.type.ObjectDataType;
 import org.jbpm.process.test.TestProcessEventListener;
+import org.jbpm.ruleflow.core.Metadata;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.test.util.AbstractBaseTest;
 import org.jbpm.workflow.core.Node;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoProcessInstance;
 import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
 import org.slf4j.LoggerFactory;
@@ -36,6 +39,8 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 public class NodeInnerClassesTest extends AbstractBaseTest {
 
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+
     @Override
     public void addLogger() {
         logger = LoggerFactory.getLogger(this.getClass());
@@ -60,13 +65,13 @@ public class NodeInnerClassesTest extends AbstractBaseTest {
         process.setDynamic(true);
         CompositeNode compositeNode = new CompositeNode();
         compositeNode.setName("CompositeNode");
-        compositeNode.setId(2);
+        compositeNode.setId(two);
 
         ForEachNode forEachNode = new ForEachNode();
         ForEachNode.ForEachSplitNode split = new ForEachNode.ForEachSplitNode();
         split.setName("ForEachSplit");
         split.setMetaData("hidden", true);
-        split.setMetaData("UniqueId", forEachNode.getMetaData("Uniqueid") + ":foreach:split");
+        split.setMetaData(Metadata.UNIQUE_ID, forEachNode.getUniqueId() + ":foreach:split");
         forEachNode.internalAddNode(split);
         forEachNode.linkIncomingConnections(
                 Node.CONNECTION_DEFAULT_TYPE,
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/EndNodeInstanceTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/EndNodeInstanceTest.java
index fd0e8e3bda..eedfd40faf 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/EndNodeInstanceTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/EndNodeInstanceTest.java
@@ -20,6 +20,7 @@ package org.jbpm.workflow.instance.node;
 
 import org.drools.core.common.InternalKnowledgeRuntime;
 import org.jbpm.process.instance.ProcessInstance;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.ruleflow.instance.RuleFlowProcessInstance;
 import org.jbpm.test.util.AbstractBaseTest;
 import org.jbpm.workflow.core.Node;
@@ -28,6 +29,7 @@ import org.jbpm.workflow.core.impl.WorkflowProcessImpl;
 import org.jbpm.workflow.core.node.EndNode;
 import org.jbpm.workflow.instance.impl.NodeInstanceFactoryRegistry;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
 import org.slf4j.LoggerFactory;
 
@@ -35,6 +37,9 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 public class EndNodeInstanceTest extends AbstractBaseTest {
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("two");
+
     public void addLogger() {
         logger = LoggerFactory.getLogger(this.getClass());
     }
@@ -48,10 +53,10 @@ public class EndNodeInstanceTest extends AbstractBaseTest {
 
         WorkflowProcessImpl process = new WorkflowProcessImpl();
         Node endNode = new EndNode();
-        endNode.setId(1);
+        endNode.setId(one);
         endNode.setName("end node");
 
-        mockNode.setId(2);
+        mockNode.setId(two);
         new ConnectionImpl(mockNode, Node.CONNECTION_DEFAULT_TYPE, endNode, Node.CONNECTION_DEFAULT_TYPE);
 
         process.addNode(mockNode);
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstance.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstance.java
index 993d8e550f..4eb032001e 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstance.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstance.java
@@ -70,7 +70,7 @@ public class MockNodeInstance extends NodeInstanceImpl {
     }
 
     public int hashCode() {
-        return (int) getNodeId();
+        return getNodeId().hashCode();
     }
 
     public boolean equals(Object object) {
@@ -78,7 +78,7 @@ public class MockNodeInstance extends NodeInstanceImpl {
             return false;
         }
         MockNodeInstance other = (MockNodeInstance) object;
-        return getNodeId() == other.getNodeId();
+        return getNodeId().equals(other.getNodeId());
     }
 
     public void triggerCompleted() {
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
index 67817ad20c..19611f70bf 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/MockNodeInstanceFactory.java
@@ -41,6 +41,7 @@ public class MockNodeInstanceFactory implements NodeInstanceFactory {
     }
 
     public NodeInstance getNodeInstance(Node node, WorkflowProcessInstance processInstance, NodeInstanceContainer nodeInstanceContainer) {
+        instance.setNodeId(node.getId());
         instance.setProcessInstance(processInstance);
         instance.setNodeInstanceContainer((KogitoNodeInstanceContainer) nodeInstanceContainer);
         return instance;
diff --git a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/StartNodeInstanceTest.java b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/StartNodeInstanceTest.java
index 6369996eea..0d5fbabc22 100755
--- a/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/StartNodeInstanceTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/jbpm/workflow/instance/node/StartNodeInstanceTest.java
@@ -23,6 +23,7 @@ import java.util.List;
 import org.drools.core.common.InternalKnowledgeRuntime;
 import org.jbpm.process.instance.ProcessInstance;
 import org.jbpm.ruleflow.core.RuleFlowProcess;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.ruleflow.instance.RuleFlowProcessInstance;
 import org.jbpm.test.util.AbstractBaseTest;
 import org.jbpm.workflow.core.Node;
@@ -30,6 +31,7 @@ import org.jbpm.workflow.core.impl.ConnectionImpl;
 import org.jbpm.workflow.core.node.StartNode;
 import org.jbpm.workflow.instance.impl.NodeInstanceFactoryRegistry;
 import org.junit.jupiter.api.Test;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.runtime.process.NodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
 import org.slf4j.LoggerFactory;
@@ -38,6 +40,9 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 public class StartNodeInstanceTest extends AbstractBaseTest {
 
+    private static WorkflowElementIdentifier one = WorkflowElementIdentifierFactory.fromExternalFormat("one");
+    private static WorkflowElementIdentifier two = WorkflowElementIdentifierFactory.fromExternalFormat("two");
+
     public void addLogger() {
         logger = LoggerFactory.getLogger(this.getClass());
     }
@@ -47,16 +52,17 @@ public class StartNodeInstanceTest extends AbstractBaseTest {
 
         KogitoProcessRuntime kruntime = createKogitoProcessRuntime();
         MockNode mockNode = new MockNode();
+        mockNode.setId(one);
         MockNodeInstanceFactory mockNodeFactory = new MockNodeInstanceFactory(new MockNodeInstance(mockNode));
         NodeInstanceFactoryRegistry.getInstance(kruntime.getKieRuntime().getEnvironment()).register(mockNode.getClass(), mockNodeFactory);
 
         RuleFlowProcess process = new RuleFlowProcess();
 
         StartNode startNode = new StartNode();
-        startNode.setId(1);
+        startNode.setId(one);
         startNode.setName("start node");
 
-        mockNode.setId(2);
+        mockNode.setId(two);
         new ConnectionImpl(
                 startNode, Node.CONNECTION_DEFAULT_TYPE,
                 mockNode, Node.CONNECTION_DEFAULT_TYPE);
diff --git a/jbpm/jbpm-flow/src/test/java/org/kie/kogito/process/impl/AbstractProcessInstanceTest.java b/jbpm/jbpm-flow/src/test/java/org/kie/kogito/process/impl/AbstractProcessInstanceTest.java
index 6de802b2d0..d2b9ec8cf3 100644
--- a/jbpm/jbpm-flow/src/test/java/org/kie/kogito/process/impl/AbstractProcessInstanceTest.java
+++ b/jbpm/jbpm-flow/src/test/java/org/kie/kogito/process/impl/AbstractProcessInstanceTest.java
@@ -116,7 +116,7 @@ public class AbstractProcessInstanceTest {
         RuleFlowProcess process = mock(RuleFlowProcess.class);
         when(wpi.getProcess()).thenReturn(process);
         org.kie.api.definition.process.Node node = mock(org.kie.api.definition.process.Node.class);
-        when(node.getNodeUniqueId()).thenReturn(nodeId);
+        when(node.getUniqueId()).thenReturn(nodeId);
         when(process.getNodesRecursively()).thenReturn(Arrays.asList(node));
 
         NodeInstance nodeInstance = mock(NodeInstance.class);
diff --git a/jbpm/pom.xml b/jbpm/pom.xml
index 5403377b21..5925fbe239 100755
--- a/jbpm/pom.xml
+++ b/jbpm/pom.xml
@@ -41,6 +41,7 @@
     <module>jbpm-flow</module>
     <module>jbpm-flow-builder</module>
     <module>jbpm-bpmn2</module>
+    <module>jbpm-flow-migration</module>
     <module>process-serialization-protobuf</module>
     <module>process-workitems</module>
   </modules>
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerContext.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerContext.java
similarity index 96%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerContext.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerContext.java
index 75e63041fd..66f8f0ffb0 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerContext.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerContext.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process;
+package org.jbpm.flow.serialization;
 
 import com.google.protobuf.Any;
 
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerContextName.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerContextName.java
similarity index 89%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerContextName.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerContextName.java
index 2a6ee94f24..e3253299d8 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerContextName.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerContextName.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process;
+package org.jbpm.flow.serialization;
 
 import org.kie.kogito.process.Process;
 
@@ -26,6 +26,7 @@ public final class MarshallerContextName<T> {
     public static final MarshallerContextName<String> MARSHALLER_FORMAT = new MarshallerContextName<>("FORMAT");
     public static final MarshallerContextName<Process<?>> MARSHALLER_PROCESS = new MarshallerContextName<>("PROCESS");
     public static final MarshallerContextName<Boolean> MARSHALLER_INSTANCE_READ_ONLY = new MarshallerContextName<>("READ_ONLY");
+    public static final MarshallerContextName<ProcessInstanceMarshallerListener[]> MARSHALLER_INSTANCE_LISTENER = new MarshallerContextName<>("MARSHALLER_INSTANCE_LISTENERS");
 
     public static final String MARSHALLER_FORMAT_JSON = "json";
 
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerReaderContext.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerReaderContext.java
similarity index 95%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerReaderContext.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerReaderContext.java
index fe5da7b44d..2ded4cc7b8 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerReaderContext.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerReaderContext.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process;
+package org.jbpm.flow.serialization;
 
 import java.io.InputStream;
 
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerWriterContext.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerWriterContext.java
similarity index 95%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerWriterContext.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerWriterContext.java
index 63a1d93498..0e1cb715b0 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/MarshallerWriterContext.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/MarshallerWriterContext.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process;
+package org.jbpm.flow.serialization;
 
 import java.io.OutputStream;
 
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ObjectMarshallerStrategy.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ObjectMarshallerStrategy.java
similarity index 96%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ObjectMarshallerStrategy.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ObjectMarshallerStrategy.java
index 679049ef7c..d8ff56b924 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ObjectMarshallerStrategy.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ObjectMarshallerStrategy.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process;
+package org.jbpm.flow.serialization;
 
 import com.google.protobuf.Any;
 
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshaller.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshaller.java
similarity index 97%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshaller.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshaller.java
index 8866f05bca..bf9e781cdc 100755
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshaller.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshaller.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process;
+package org.jbpm.flow.serialization;
 
 import java.io.IOException;
 
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerException.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerException.java
similarity index 96%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerException.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerException.java
index 8ec1bf0596..14ee48fc65 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerException.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerException.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process;
+package org.jbpm.flow.serialization;
 
 public class ProcessInstanceMarshallerException extends RuntimeException {
 
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerFactory.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerFactory.java
similarity index 96%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerFactory.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerFactory.java
index 13a4c3c320..fb1acf8553 100755
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerFactory.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerFactory.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process;
+package org.jbpm.flow.serialization;
 
 import java.io.InputStream;
 import java.io.OutputStream;
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/persistence/InstantProtostreamBaseMarshaller.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerListener.java
similarity index 53%
copy from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/persistence/InstantProtostreamBaseMarshaller.java
copy to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerListener.java
index f1f6d13283..080c40873e 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/persistence/InstantProtostreamBaseMarshaller.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerListener.java
@@ -16,33 +16,28 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.persistence;
+package org.jbpm.flow.serialization;
 
-import java.io.IOException;
-import java.time.Instant;
+import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
+import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
+import org.kie.kogito.internal.process.runtime.KogitoWorkflowProcessInstance;
 
-import org.infinispan.protostream.MessageMarshaller;
+public interface ProcessInstanceMarshallerListener {
 
-public class InstantProtostreamBaseMarshaller implements MessageMarshaller<Instant> {
+    default void afterUnmarshallProcess(KogitoProcessRuntime runtime, KogitoWorkflowProcessInstance processInstance) {
 
-    @Override
-    public Class<? extends Instant> getJavaClass() {
-        return Instant.class;
     }
 
-    @Override
-    public String getTypeName() {
-        return "kogito.Instant";
+    default void afterUnmarshallNode(KogitoProcessRuntime runtime, KogitoNodeInstance node) {
+
     }
 
-    @Override
-    public Instant readFrom(ProtoStreamReader reader) throws IOException {
-        return reader.readInstant("data");
+    default void beforeMarshallNode(KogitoProcessRuntime runtime, KogitoNodeInstance node) {
+
     }
 
-    @Override
-    public void writeTo(ProtoStreamWriter writer, Instant instant) throws IOException {
-        writer.writeInstant("data", instant);
+    default void beforeMarshallProcess(KogitoProcessRuntime runtime, KogitoWorkflowProcessInstance node) {
+
     }
 
 }
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerService.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerService.java
similarity index 79%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerService.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerService.java
index a378ab6a85..0b55ca2033 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/ProcessInstanceMarshallerService.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/ProcessInstanceMarshallerService.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process;
+package org.jbpm.flow.serialization;
 
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
@@ -30,11 +30,11 @@ import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Supplier;
 
+import org.jbpm.flow.serialization.impl.ProtobufProcessInstanceMarshallerFactory;
 import org.kie.kogito.process.Process;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.ProcessInstanceReadMode;
 import org.kie.kogito.process.impl.AbstractProcessInstance;
-import org.kie.kogito.serialization.process.impl.ProtobufProcessInstanceMarshallerFactory;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -43,6 +43,8 @@ public class ProcessInstanceMarshallerService {
 
     private List<ObjectMarshallerStrategy> strats;
 
+    private List<ProcessInstanceMarshallerListener> listeners;
+
     private Map<MarshallerContextName<Object>, Object> contextEntries;
 
     private ProcessInstanceMarshallerFactory processInstanceMarshallerFactory;
@@ -65,6 +67,15 @@ public class ProcessInstanceMarshallerService {
             return this;
         }
 
+        public Builder withDefaultListeners() {
+            ServiceLoader<ProcessInstanceMarshallerListener> loader = ServiceLoader.load(ProcessInstanceMarshallerListener.class);
+
+            for (ProcessInstanceMarshallerListener strategy : loader) {
+                ProcessInstanceMarshallerService.this.listeners.add(strategy);
+            }
+            return this;
+        }
+
         public Builder withDefaultObjectMarshallerStrategies() {
             ServiceLoader<ObjectMarshallerStrategy> loader = ServiceLoader.load(ObjectMarshallerStrategy.class);
 
@@ -74,6 +85,13 @@ public class ProcessInstanceMarshallerService {
             return this;
         }
 
+        public Builder withListeners(ProcessInstanceMarshallerListener... strategies) {
+            for (ProcessInstanceMarshallerListener strategy : strategies) {
+                ProcessInstanceMarshallerService.this.listeners.add(strategy);
+            }
+            return this;
+        }
+
         public Builder withObjectMarshallerStrategies(ObjectMarshallerStrategy... strategies) {
             for (ObjectMarshallerStrategy strategy : strategies) {
                 ProcessInstanceMarshallerService.this.strats.add(strategy);
@@ -93,6 +111,7 @@ public class ProcessInstanceMarshallerService {
     }
 
     private ProcessInstanceMarshallerService() {
+        this.listeners = new ArrayList<>();
         this.strats = new ArrayList<>();
         this.contextEntries = new HashMap<>();
     }
@@ -108,8 +127,10 @@ public class ProcessInstanceMarshallerService {
     public byte[] marshallProcessInstance(ProcessInstance<?> processInstance) {
         try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
             MarshallerWriterContext context = processInstanceMarshallerFactory.newWriterContext(baos);
+            context.set(MarshallerContextName.MARSHALLER_PROCESS, processInstance.process());
+            context.set(MarshallerContextName.MARSHALLER_INSTANCE_LISTENER, listeners.toArray(ProcessInstanceMarshallerListener[]::new));
             setupEnvironment(context);
-            org.kie.kogito.serialization.process.ProcessInstanceMarshaller marshaller = processInstanceMarshallerFactory.newKogitoProcessInstanceMarshaller();
+            org.jbpm.flow.serialization.ProcessInstanceMarshaller marshaller = processInstanceMarshallerFactory.newKogitoProcessInstanceMarshaller();
             marshaller.writeProcessInstance(context, processInstance);
             return baos.toByteArray();
         } catch (Exception e) {
@@ -122,8 +143,9 @@ public class ProcessInstanceMarshallerService {
             MarshallerReaderContext context = processInstanceMarshallerFactory.newReaderContext(bais);
             context.set(MarshallerContextName.MARSHALLER_PROCESS, process);
             context.set(MarshallerContextName.MARSHALLER_INSTANCE_READ_ONLY, readOnly);
+            context.set(MarshallerContextName.MARSHALLER_INSTANCE_LISTENER, listeners.toArray(ProcessInstanceMarshallerListener[]::new));
             setupEnvironment(context);
-            org.kie.kogito.serialization.process.ProcessInstanceMarshaller marshaller = processInstanceMarshallerFactory.newKogitoProcessInstanceMarshaller();
+            org.jbpm.flow.serialization.ProcessInstanceMarshaller marshaller = processInstanceMarshallerFactory.newKogitoProcessInstanceMarshaller();
             return marshaller.readProcessInstance(context);
         } catch (Exception e) {
             throw new ProcessInstanceMarshallerException("Error while unmarshalling process instance", e);
@@ -147,8 +169,9 @@ public class ProcessInstanceMarshallerService {
             try (ByteArrayInputStream bais = new ByteArrayInputStream(data)) {
                 MarshallerReaderContext context = processInstanceMarshallerFactory.newReaderContext(bais);
                 context.set(MarshallerContextName.MARSHALLER_PROCESS, processInstance.process());
+                context.set(MarshallerContextName.MARSHALLER_INSTANCE_LISTENER, listeners.toArray(ProcessInstanceMarshallerListener[]::new));
                 setupEnvironment(context);
-                org.kie.kogito.serialization.process.ProcessInstanceMarshaller marshaller =
+                org.jbpm.flow.serialization.ProcessInstanceMarshaller marshaller =
                         processInstanceMarshallerFactory.newKogitoProcessInstanceMarshaller();
                 marshaller.reloadProcessInstance(context, processInstance);
             } catch (Exception e) {
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufAbstractMarshallerContext.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufAbstractMarshallerContext.java
similarity index 87%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufAbstractMarshallerContext.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufAbstractMarshallerContext.java
index 318e3a7a60..e0eb9d51cf 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufAbstractMarshallerContext.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufAbstractMarshallerContext.java
@@ -16,16 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl;
+package org.jbpm.flow.serialization.impl;
 
 import java.util.HashMap;
 import java.util.Map;
 import java.util.function.BiPredicate;
 
-import org.kie.kogito.serialization.process.MarshallerContext;
-import org.kie.kogito.serialization.process.MarshallerContextName;
-import org.kie.kogito.serialization.process.ObjectMarshallerStrategy;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerException;
+import org.jbpm.flow.serialization.MarshallerContext;
+import org.jbpm.flow.serialization.MarshallerContextName;
+import org.jbpm.flow.serialization.ObjectMarshallerStrategy;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerException;
 
 import com.google.protobuf.Any;
 
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufMarshallerReaderContext.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufMarshallerReaderContext.java
similarity index 90%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufMarshallerReaderContext.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufMarshallerReaderContext.java
index 3191a30ef2..8ebb519caa 100755
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufMarshallerReaderContext.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufMarshallerReaderContext.java
@@ -16,11 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl;
+package org.jbpm.flow.serialization.impl;
 
 import java.io.InputStream;
 
-import org.kie.kogito.serialization.process.MarshallerReaderContext;
+import org.jbpm.flow.serialization.MarshallerReaderContext;
 
 public class ProtobufMarshallerReaderContext extends ProtobufAbstractMarshallerContext implements MarshallerReaderContext {
 
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceMarshaller.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceMarshaller.java
similarity index 88%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceMarshaller.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceMarshaller.java
index d5df5a3550..592a09ae55 100755
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceMarshaller.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceMarshaller.java
@@ -16,18 +16,18 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl;
+package org.jbpm.flow.serialization.impl;
 
 import java.io.IOException;
 
+import org.jbpm.flow.serialization.MarshallerContextName;
+import org.jbpm.flow.serialization.MarshallerReaderContext;
+import org.jbpm.flow.serialization.MarshallerWriterContext;
+import org.jbpm.flow.serialization.ProcessInstanceMarshaller;
 import org.jbpm.ruleflow.instance.RuleFlowProcessInstance;
 import org.kie.kogito.process.ProcessInstance;
 import org.kie.kogito.process.impl.AbstractProcess;
 import org.kie.kogito.process.impl.AbstractProcessInstance;
-import org.kie.kogito.serialization.process.MarshallerContextName;
-import org.kie.kogito.serialization.process.MarshallerReaderContext;
-import org.kie.kogito.serialization.process.MarshallerWriterContext;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshaller;
 
 /**
  * Marshaller class for RuleFlowProcessInstances
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceMarshallerFactory.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceMarshallerFactory.java
similarity index 80%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceMarshallerFactory.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceMarshallerFactory.java
index 61f9075934..dce02fa6fa 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceMarshallerFactory.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceMarshallerFactory.java
@@ -16,15 +16,15 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl;
+package org.jbpm.flow.serialization.impl;
 
 import java.io.InputStream;
 import java.io.OutputStream;
 
-import org.kie.kogito.serialization.process.MarshallerReaderContext;
-import org.kie.kogito.serialization.process.MarshallerWriterContext;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshaller;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerFactory;
+import org.jbpm.flow.serialization.MarshallerReaderContext;
+import org.jbpm.flow.serialization.MarshallerWriterContext;
+import org.jbpm.flow.serialization.ProcessInstanceMarshaller;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerFactory;
 
 public class ProtobufProcessInstanceMarshallerFactory implements ProcessInstanceMarshallerFactory {
 
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceReader.java
similarity index 88%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceReader.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceReader.java
index a182931c15..afb3f851c4 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceReader.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceReader.java
@@ -16,13 +16,14 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl;
+package org.jbpm.flow.serialization.impl;
 
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.URI;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.HashMap;
 import java.util.List;
@@ -32,6 +33,30 @@ import java.util.UUID;
 import java.util.function.Function;
 import java.util.stream.Collectors;
 
+import org.jbpm.flow.serialization.MarshallerContextName;
+import org.jbpm.flow.serialization.MarshallerReaderContext;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerException;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerListener;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.AsyncEventNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.CompositeContextNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.DynamicNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventSubProcessNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.ForEachNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.LambdaSubProcessNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.MilestoneNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.RuleSetNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.StateNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.SubProcessNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.TimerNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.WorkItemNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoProcessInstanceProtobuf;
+import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf;
+import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf.SLAContext;
+import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf.WorkflowContext;
+import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf;
+import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData;
 import org.jbpm.process.core.context.exclusive.ExclusiveGroup;
 import org.jbpm.process.core.context.swimlane.SwimlaneContext;
 import org.jbpm.process.core.context.variable.VariableScope;
@@ -41,6 +66,7 @@ import org.jbpm.process.instance.context.variable.VariableScopeInstance;
 import org.jbpm.process.instance.impl.humantask.HumanTaskWorkItemImpl;
 import org.jbpm.process.instance.impl.humantask.InternalHumanTaskWorkItem;
 import org.jbpm.process.instance.impl.humantask.Reassignment;
+import org.jbpm.ruleflow.core.WorkflowElementIdentifierFactory;
 import org.jbpm.ruleflow.instance.RuleFlowProcessInstance;
 import org.jbpm.workflow.core.node.AsyncEventNodeInstance;
 import org.jbpm.workflow.instance.impl.NodeInstanceImpl;
@@ -58,56 +84,41 @@ import org.jbpm.workflow.instance.node.StateNodeInstance;
 import org.jbpm.workflow.instance.node.SubProcessNodeInstance;
 import org.jbpm.workflow.instance.node.TimerNodeInstance;
 import org.jbpm.workflow.instance.node.WorkItemNodeInstance;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstanceContainer;
+import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
 import org.kie.kogito.process.impl.AbstractProcess;
 import org.kie.kogito.process.workitem.Attachment;
 import org.kie.kogito.process.workitem.Comment;
 import org.kie.kogito.process.workitems.InternalKogitoWorkItem;
 import org.kie.kogito.process.workitems.impl.KogitoWorkItemImpl;
-import org.kie.kogito.serialization.process.MarshallerContextName;
-import org.kie.kogito.serialization.process.MarshallerReaderContext;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerException;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.AsyncEventNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.CompositeContextNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.DynamicNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.EventNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.EventSubProcessNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.ForEachNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.LambdaSubProcessNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.MilestoneNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.RuleSetNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.StateNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.SubProcessNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.TimerNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.WorkItemNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoProcessInstanceProtobuf;
-import org.kie.kogito.serialization.process.protobuf.KogitoTypesProtobuf;
-import org.kie.kogito.serialization.process.protobuf.KogitoTypesProtobuf.SLAContext;
-import org.kie.kogito.serialization.process.protobuf.KogitoTypesProtobuf.WorkflowContext;
-import org.kie.kogito.serialization.process.protobuf.KogitoWorkItemsProtobuf;
-import org.kie.kogito.serialization.process.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.protobuf.Any;
 import com.google.protobuf.InvalidProtocolBufferException;
 import com.google.protobuf.util.JsonFormat;
 
-import static org.kie.kogito.serialization.process.protobuf.ProtobufTypeRegistryFactory.protobufTypeRegistryFactoryInstance;
+import static org.jbpm.flow.serialization.protobuf.ProtobufTypeRegistryFactory.protobufTypeRegistryFactoryInstance;
 
 public class ProtobufProcessInstanceReader {
-
+    private static final Logger LOGGER = LoggerFactory.getLogger(ProtobufProcessInstanceReader.class);
     private RuleFlowProcessInstance ruleFlowProcessInstance;
     private MarshallerReaderContext context;
     private ProtobufVariableReader varReader;
+    private ProcessInstanceMarshallerListener[] listeners;
 
     public ProtobufProcessInstanceReader(MarshallerReaderContext context) {
         this.context = context;
         this.ruleFlowProcessInstance = new RuleFlowProcessInstance();
         this.varReader = new ProtobufVariableReader(context);
+        this.listeners = context.get(MarshallerContextName.MARSHALLER_INSTANCE_LISTENER);
+        this.listeners = this.listeners != null ? this.listeners : new ProcessInstanceMarshallerListener[0];
     }
 
     public RuleFlowProcessInstance read(InputStream input) throws IOException {
+        LOGGER.debug("read process");
         KogitoProcessInstanceProtobuf.ProcessInstance processInstanceProtobuf;
 
         String format = this.context.get(MarshallerContextName.MARSHALLER_FORMAT);
@@ -124,10 +135,12 @@ public class ProtobufProcessInstanceReader {
     private RuleFlowProcessInstance buildWorkflow(KogitoProcessInstanceProtobuf.ProcessInstance processInstanceProtobuf) {
 
         RuleFlowProcessInstance processInstance = ruleFlowProcessInstance;
-        processInstance.setProcess(((AbstractProcess<?>) context.get(MarshallerContextName.MARSHALLER_PROCESS)).get());
+        processInstance.setProcessId(processInstanceProtobuf.getProcessId());
+        processInstance.setProcessVersion(processInstanceProtobuf.getProcessVersion());
+
+        processInstance.setInternalProcess(((AbstractProcess<?>) context.get(MarshallerContextName.MARSHALLER_PROCESS)).get());
 
         processInstance.setId(processInstanceProtobuf.getId());
-        processInstance.setProcessId(processInstanceProtobuf.getProcessId());
         processInstance.setState(processInstanceProtobuf.getState());
         processInstance.setSignalCompletion(processInstanceProtobuf.getSignalCompletion());
 
@@ -218,7 +231,8 @@ public class ProtobufProcessInstanceReader {
         if (workflowContext.getIterationLevelsCount() > 0) {
             processInstance.getIterationLevels().putAll(buildIterationLevels(workflowContext.getIterationLevelsList()));
         }
-
+        KogitoProcessRuntime runtime = ((AbstractProcess<?>) context.get(MarshallerContextName.MARSHALLER_PROCESS)).getProcessRuntime();
+        Arrays.stream(listeners).forEach(e -> e.afterUnmarshallProcess(runtime, processInstance));
         return processInstance;
     }
 
@@ -228,8 +242,8 @@ public class ProtobufProcessInstanceReader {
             nodeInstanceImpl.setId(nodeInstanceProtobuf.getId());
         }
 
-        if (nodeInstanceImpl.getNodeId() == 0) {
-            nodeInstanceImpl.setNodeId(nodeInstanceProtobuf.getNodeId());
+        if (nodeInstanceImpl.getNodeId() == null) {
+            nodeInstanceImpl.setNodeId(WorkflowElementIdentifierFactory.fromExternalFormat(nodeInstanceProtobuf.getNodeId()));
         }
 
         if (nodeInstanceImpl.getNodeInstanceContainer() == null) {
@@ -305,6 +319,9 @@ public class ProtobufProcessInstanceReader {
                 result.internalSetTriggerTime(new Date(nodeInstance.getTriggerDate()));
             }
 
+            KogitoNodeInstance kogitoNodeInstance = (KogitoNodeInstance) result;
+            KogitoProcessRuntime runtime = ((AbstractProcess<?>) context.get(MarshallerContextName.MARSHALLER_PROCESS)).getProcessRuntime();
+            Arrays.stream(listeners).forEach(e -> e.afterUnmarshallNode(runtime, kogitoNodeInstance));
             return result;
         } catch (IOException e) {
             throw new IllegalArgumentException("Cannot read node instance content");
@@ -404,9 +421,10 @@ public class ProtobufProcessInstanceReader {
     private NodeInstanceImpl buildJoinInstance(JoinNodeInstanceContent content) {
         JoinInstance nodeInstance = new JoinInstance();
         if (content.getTriggerCount() > 0) {
-            Map<Long, Integer> triggers = new HashMap<>();
+            Map<WorkflowElementIdentifier, Integer> triggers = new HashMap<>();
             for (JoinNodeInstanceContent.JoinTrigger _join : content.getTriggerList()) {
-                triggers.put(_join.getNodeId(), _join.getCounter());
+                LOGGER.info("unmarshalling join {}", _join.getNodeId());
+                triggers.put(WorkflowElementIdentifierFactory.fromExternalFormat(_join.getNodeId()), _join.getCounter());
             }
             nodeInstance.internalSetTriggers(triggers);
         }
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceWriter.java
similarity index 87%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceWriter.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceWriter.java
index 875c033898..23ffb8bece 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessInstanceWriter.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessInstanceWriter.java
@@ -16,11 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl;
+package org.jbpm.flow.serialization.impl;
 
 import java.io.IOException;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Comparator;
@@ -31,6 +32,29 @@ import java.util.Map;
 import java.util.Map.Entry;
 import java.util.stream.Collectors;
 
+import org.jbpm.flow.serialization.MarshallerContextName;
+import org.jbpm.flow.serialization.MarshallerWriterContext;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerListener;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.AsyncEventNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.CompositeContextNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.DynamicNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.EventSubProcessNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.ForEachNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent.JoinTrigger;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.LambdaSubProcessNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.MilestoneNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.RuleSetNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.StateNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.SubProcessNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.TimerNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoNodeInstanceContentsProtobuf.WorkItemNodeInstanceContent;
+import org.jbpm.flow.serialization.protobuf.KogitoProcessInstanceProtobuf;
+import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf;
+import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf.WorkflowContext;
+import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf;
+import org.jbpm.flow.serialization.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData;
 import org.jbpm.process.core.context.exclusive.ExclusiveGroup;
 import org.jbpm.process.core.context.swimlane.SwimlaneContext;
 import org.jbpm.process.core.context.variable.VariableScope;
@@ -55,52 +79,41 @@ import org.jbpm.workflow.instance.node.StateNodeInstance;
 import org.jbpm.workflow.instance.node.SubProcessNodeInstance;
 import org.jbpm.workflow.instance.node.TimerNodeInstance;
 import org.jbpm.workflow.instance.node.WorkItemNodeInstance;
+import org.kie.api.definition.process.WorkflowElementIdentifier;
 import org.kie.api.runtime.process.NodeInstance;
 import org.kie.kogito.internal.process.runtime.KogitoNodeInstance;
+import org.kie.kogito.internal.process.runtime.KogitoProcessRuntime;
 import org.kie.kogito.internal.process.runtime.KogitoWorkItem;
+import org.kie.kogito.process.impl.AbstractProcess;
 import org.kie.kogito.process.workitem.Attachment;
 import org.kie.kogito.process.workitem.Comment;
 import org.kie.kogito.process.workitem.HumanTaskWorkItem;
-import org.kie.kogito.serialization.process.MarshallerWriterContext;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.AsyncEventNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.CompositeContextNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.DynamicNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.EventNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.EventSubProcessNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.ForEachNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.JoinNodeInstanceContent.JoinTrigger;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.LambdaSubProcessNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.MilestoneNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.RuleSetNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.StateNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.SubProcessNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.TimerNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoNodeInstanceContentsProtobuf.WorkItemNodeInstanceContent;
-import org.kie.kogito.serialization.process.protobuf.KogitoProcessInstanceProtobuf;
-import org.kie.kogito.serialization.process.protobuf.KogitoTypesProtobuf;
-import org.kie.kogito.serialization.process.protobuf.KogitoTypesProtobuf.WorkflowContext;
-import org.kie.kogito.serialization.process.protobuf.KogitoWorkItemsProtobuf;
-import org.kie.kogito.serialization.process.protobuf.KogitoWorkItemsProtobuf.HumanTaskWorkItemData;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.protobuf.Any;
 import com.google.protobuf.util.JsonFormat;
 
-import static org.kie.kogito.serialization.process.MarshallerContextName.MARSHALLER_FORMAT;
-import static org.kie.kogito.serialization.process.MarshallerContextName.MARSHALLER_FORMAT_JSON;
-import static org.kie.kogito.serialization.process.protobuf.ProtobufTypeRegistryFactory.protobufTypeRegistryFactoryInstance;
+import static org.jbpm.flow.serialization.MarshallerContextName.MARSHALLER_FORMAT;
+import static org.jbpm.flow.serialization.MarshallerContextName.MARSHALLER_FORMAT_JSON;
+import static org.jbpm.flow.serialization.protobuf.ProtobufTypeRegistryFactory.protobufTypeRegistryFactoryInstance;
 
 public class ProtobufProcessInstanceWriter {
-
+    private static final Logger LOGGER = LoggerFactory.getLogger(ProtobufProcessInstanceWriter.class);
     private MarshallerWriterContext context;
     private ProtobufVariableWriter varWriter;
+    private ProcessInstanceMarshallerListener[] listeners;
 
     public ProtobufProcessInstanceWriter(MarshallerWriterContext context) {
         this.context = context;
         this.varWriter = new ProtobufVariableWriter(context);
+        this.listeners = context.get(MarshallerContextName.MARSHALLER_INSTANCE_LISTENER);
+        this.listeners = this.listeners != null ? this.listeners : new ProcessInstanceMarshallerListener[0];
     }
 
     public void writeProcessInstance(WorkflowProcessInstanceImpl workFlow, OutputStream os) throws IOException {
+        KogitoProcessRuntime runtime = ((AbstractProcess<?>) context.get(MarshallerContextName.MARSHALLER_PROCESS)).getProcessRuntime();
+        Arrays.stream(listeners).forEach(e -> e.beforeMarshallProcess(runtime, workFlow));
 
         KogitoProcessInstanceProtobuf.ProcessInstance.Builder instance = KogitoProcessInstanceProtobuf.ProcessInstance.newBuilder()
                 .setId(workFlow.getStringId())
@@ -109,6 +122,9 @@ public class ProtobufProcessInstanceWriter {
                 .setProcessType(workFlow.getProcess().getType())
                 .setSignalCompletion(workFlow.isSignalCompletion());
 
+        if (workFlow.getProcessVersion() != null) {
+            instance.setProcessVersion(workFlow.getProcessVersion());
+        }
         if (workFlow.getStartDate() != null) {
             instance.setStartDate(workFlow.getStartDate().getTime());
         }
@@ -210,7 +226,7 @@ public class ProtobufProcessInstanceWriter {
 
     }
 
-    private List<org.kie.kogito.serialization.process.protobuf.KogitoTypesProtobuf.NodeInstance> buildNodeInstances(List<NodeInstance> nodeInstances) {
+    private List<org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf.NodeInstance> buildNodeInstances(List<NodeInstance> nodeInstances) {
         Comparator<NodeInstance> comparator = (o1, o2) -> ((KogitoNodeInstance) o1).getStringId().compareTo(((KogitoNodeInstance) o2).getStringId());
         Collections.sort(nodeInstances, comparator);
 
@@ -218,7 +234,7 @@ public class ProtobufProcessInstanceWriter {
         for (NodeInstance nodeInstance : nodeInstances) {
             KogitoTypesProtobuf.NodeInstance.Builder node = KogitoTypesProtobuf.NodeInstance.newBuilder()
                     .setId(((KogitoNodeInstance) nodeInstance).getStringId())
-                    .setNodeId(nodeInstance.getNodeId())
+                    .setNodeId(nodeInstance.getNodeId().toExternalFormat())
                     .setLevel(((org.jbpm.workflow.instance.NodeInstance) nodeInstance).getLevel());
 
             Date triggerDate = ((org.jbpm.workflow.instance.NodeInstance) nodeInstance).getTriggerTime();
@@ -238,6 +254,9 @@ public class ProtobufProcessInstanceWriter {
     }
 
     private Any buildNodeInstanceContent(NodeInstance nodeInstance) {
+        KogitoProcessRuntime runtime = ((AbstractProcess<?>) context.get(MarshallerContextName.MARSHALLER_PROCESS)).getProcessRuntime();
+        Arrays.stream(listeners).forEach(e -> e.beforeMarshallNode(runtime, (KogitoNodeInstance) nodeInstance));
+
         if (nodeInstance instanceof RuleSetNodeInstance) {
             return buildRuleSetNodeInstance((RuleSetNodeInstance) nodeInstance);
         } else if (nodeInstance instanceof ForEachNodeInstance) {
@@ -357,14 +376,14 @@ public class ProtobufProcessInstanceWriter {
 
     private Any buildJoinInstance(JoinInstance nodeInstance) {
         JoinNodeInstanceContent.Builder joinBuilder = JoinNodeInstanceContent.newBuilder();
-        Map<Long, Integer> triggers = nodeInstance.getTriggers();
-        List<Long> keys = new ArrayList<>(triggers.keySet());
-        Comparator<Long> comparator = (o1, o2) -> o1.compareTo(o2);
-        Collections.sort(keys, comparator);
+        Map<WorkflowElementIdentifier, Integer> triggers = nodeInstance.getTriggers();
+        List<WorkflowElementIdentifier> keys = new ArrayList<>(triggers.keySet());
+        Collections.sort(keys);
 
-        for (Long key : keys) {
+        for (WorkflowElementIdentifier key : keys) {
+            LOGGER.info("marshalling join {}", key.toExternalFormat());
             joinBuilder.addTrigger(JoinTrigger.newBuilder()
-                    .setNodeId(key)
+                    .setNodeId(key.toExternalFormat())
                     .setCounter(triggers.get(key))
                     .build());
         }
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessMarshallerWriteContext.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessMarshallerWriteContext.java
similarity index 91%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessMarshallerWriteContext.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessMarshallerWriteContext.java
index 7135e1eae4..906bd9da1a 100755
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufProcessMarshallerWriteContext.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufProcessMarshallerWriteContext.java
@@ -16,11 +16,11 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl;
+package org.jbpm.flow.serialization.impl;
 
 import java.io.OutputStream;
 
-import org.kie.kogito.serialization.process.MarshallerWriterContext;
+import org.jbpm.flow.serialization.MarshallerWriterContext;
 
 /**
  * Extension to default <code>MarshallerWriteContext</code>
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufVariableReader.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufVariableReader.java
similarity index 88%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufVariableReader.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufVariableReader.java
index 5725c8ac64..9a64180126 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufVariableReader.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufVariableReader.java
@@ -16,16 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl;
+package org.jbpm.flow.serialization.impl;
 
 import java.util.ArrayList;
 import java.util.List;
 
+import org.jbpm.flow.serialization.MarshallerReaderContext;
+import org.jbpm.flow.serialization.ObjectMarshallerStrategy;
+import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf;
 import org.jbpm.process.core.context.variable.Variable;
 import org.jbpm.process.core.datatype.DataTypeResolver;
-import org.kie.kogito.serialization.process.MarshallerReaderContext;
-import org.kie.kogito.serialization.process.ObjectMarshallerStrategy;
-import org.kie.kogito.serialization.process.protobuf.KogitoTypesProtobuf;
 
 import com.google.protobuf.Any;
 
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufVariableWriter.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufVariableWriter.java
similarity index 89%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufVariableWriter.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufVariableWriter.java
index 5bffa8ed91..b710498b47 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/ProtobufVariableWriter.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/ProtobufVariableWriter.java
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl;
+package org.jbpm.flow.serialization.impl;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -24,9 +24,9 @@ import java.util.Comparator;
 import java.util.List;
 import java.util.Map;
 
-import org.kie.kogito.serialization.process.MarshallerWriterContext;
-import org.kie.kogito.serialization.process.ObjectMarshallerStrategy;
-import org.kie.kogito.serialization.process.protobuf.KogitoTypesProtobuf;
+import org.jbpm.flow.serialization.MarshallerWriterContext;
+import org.jbpm.flow.serialization.ObjectMarshallerStrategy;
+import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf;
 
 import com.google.protobuf.Any;
 import com.google.protobuf.ByteString;
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufBooleanMarshallerStrategy.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufBooleanMarshallerStrategy.java
similarity index 89%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufBooleanMarshallerStrategy.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufBooleanMarshallerStrategy.java
index c72836d203..2d582852f1 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufBooleanMarshallerStrategy.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufBooleanMarshallerStrategy.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl.marshallers;
+package org.jbpm.flow.serialization.impl.marshallers;
 
-import org.kie.kogito.serialization.process.ObjectMarshallerStrategy;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerException;
+import org.jbpm.flow.serialization.ObjectMarshallerStrategy;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerException;
 
 import com.google.protobuf.Any;
 import com.google.protobuf.BoolValue;
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufDateMarshallerStrategy.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufDateMarshallerStrategy.java
similarity index 90%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufDateMarshallerStrategy.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufDateMarshallerStrategy.java
index 2e46e0b0c1..67be0d37a0 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufDateMarshallerStrategy.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufDateMarshallerStrategy.java
@@ -16,13 +16,13 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl.marshallers;
+package org.jbpm.flow.serialization.impl.marshallers;
 
 import java.time.Instant;
 import java.util.Date;
 
-import org.kie.kogito.serialization.process.ObjectMarshallerStrategy;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerException;
+import org.jbpm.flow.serialization.ObjectMarshallerStrategy;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerException;
 
 import com.google.protobuf.Any;
 import com.google.protobuf.InvalidProtocolBufferException;
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufDoubleMarshallerStrategy.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufDoubleMarshallerStrategy.java
similarity index 89%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufDoubleMarshallerStrategy.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufDoubleMarshallerStrategy.java
index e48aaa06c6..2d1ad320dc 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufDoubleMarshallerStrategy.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufDoubleMarshallerStrategy.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl.marshallers;
+package org.jbpm.flow.serialization.impl.marshallers;
 
-import org.kie.kogito.serialization.process.ObjectMarshallerStrategy;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerException;
+import org.jbpm.flow.serialization.ObjectMarshallerStrategy;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerException;
 
 import com.google.protobuf.Any;
 import com.google.protobuf.DoubleValue;
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufFloatMarshallerStrategy.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufFloatMarshallerStrategy.java
similarity index 89%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufFloatMarshallerStrategy.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufFloatMarshallerStrategy.java
index f32e66e5f7..207b45f326 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufFloatMarshallerStrategy.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufFloatMarshallerStrategy.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl.marshallers;
+package org.jbpm.flow.serialization.impl.marshallers;
 
-import org.kie.kogito.serialization.process.ObjectMarshallerStrategy;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerException;
+import org.jbpm.flow.serialization.ObjectMarshallerStrategy;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerException;
 
 import com.google.protobuf.Any;
 import com.google.protobuf.FloatValue;
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufIntegerMarshallerStrategy.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufIntegerMarshallerStrategy.java
similarity index 89%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufIntegerMarshallerStrategy.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufIntegerMarshallerStrategy.java
index 5e30d134ac..1bad772eb0 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufIntegerMarshallerStrategy.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufIntegerMarshallerStrategy.java
@@ -16,10 +16,10 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl.marshallers;
+package org.jbpm.flow.serialization.impl.marshallers;
 
-import org.kie.kogito.serialization.process.ObjectMarshallerStrategy;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerException;
+import org.jbpm.flow.serialization.ObjectMarshallerStrategy;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerException;
 
 import com.google.protobuf.Any;
 import com.google.protobuf.Int32Value;
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufJsonNodeMessageMarshaller.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufJsonNodeMessageMarshaller.java
similarity index 88%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufJsonNodeMessageMarshaller.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufJsonNodeMessageMarshaller.java
index 33c560d215..ce7f6d16cf 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufJsonNodeMessageMarshaller.java
+++ b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufJsonNodeMessageMarshaller.java
@@ -16,12 +16,12 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.kie.kogito.serialization.process.impl.marshallers;
+package org.jbpm.flow.serialization.impl.marshallers;
 
+import org.jbpm.flow.serialization.ObjectMarshallerStrategy;
+import org.jbpm.flow.serialization.ProcessInstanceMarshallerException;
+import org.jbpm.flow.serialization.protobuf.KogitoTypesProtobuf;
 import org.kie.kogito.jackson.utils.ObjectMapperFactory;
-import org.kie.kogito.serialization.process.ObjectMarshallerStrategy;
-import org.kie.kogito.serialization.process.ProcessInstanceMarshallerException;
-import org.kie.kogito.serialization.process.protobuf.KogitoTypesProtobuf;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.JsonNode;
diff --git a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufListMarshallerStrategy.java b/jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufListMarshallerStrategy.java
similarity index 94%
rename from jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufListMarshallerStrategy.java
rename to jbpm/process-serialization-protobuf/src/main/java/org/jbpm/flow/serialization/impl/marshallers/ProtobufListMarshallerStrategy.java
index 152e56c35c..90f66df70e 100644
--- a/jbpm/process-serialization-protobuf/src/main/java/org/kie/kogito/serialization/process/impl/marshallers/ProtobufListMarshallerStrategy.java
... 78604 lines suppressed ...


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@kie.apache.org
For additional commands, e-mail: commits-help@kie.apache.org