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

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


The following commit(s) were added to refs/heads/main by this push:
     new 5d06eb3546 [incubator-kie-issues#2065] Decision Services doesn't work 
If the import name and the inputName is same (#6427)
5d06eb3546 is described below

commit 5d06eb3546e42c5f9743f70c0a3f898e423dd834
Author: Gabriele Cardosi <[email protected]>
AuthorDate: Thu Aug 21 11:07:27 2025 +0200

    [incubator-kie-issues#2065] Decision Services doesn't work If the import 
name and the inputName is same (#6427)
    
    * [incubator-kie-issues#2065] WIP - more analysis, refactoring and unit 
test needed
    
    * [incubator-kie-issues#2065] WIP - Split DMNRuntimeImpl with 
DMNRuntimeUtils. Extend test cases with clashing complex type
    
    * [incubator-kie-issues#2065] Refactoring. Extending test coverage
    
    * [incubator-kie-issues#2065] Fix as per PR suggestion
    
    ---------
    
    Co-authored-by: Gabriele-Cardosi <[email protected]>
---
 .../dmn/core/ast/DMNDecisionServiceEvaluator.java  |   9 +-
 ...DecisionServiceFunctionDefinitionEvaluator.java |   9 +-
 .../dmn/core/ast/DMNFunctionWithReturnType.java    |  10 +-
 .../java/org/kie/dmn/core/impl/DMNRuntimeImpl.java | 173 ++------
 .../org/kie/dmn/core/impl/DMNRuntimeUtils.java     | 276 ++++++++++++
 .../org/kie/dmn/core/impl/DMNRuntimeImplTest.java  | 242 -----------
 .../org/kie/dmn/core/impl/DMNRuntimeUtilsTest.java | 461 +++++++++++++++++++++
 .../java/org/kie/dmn/core/imports/ImportsTest.java |  92 ++++
 .../InvalidModelImportInputDataNameClash.dmn       |  55 +++
 .../invalid_models/DMNv1_6/ParentModel.dmn         |  48 +++
 .../ImportedModel.dmn                              |  78 ++++
 .../ImportingModel.dmn                             |  69 +++
 .../ImportedModel.dmn                              |  70 ++++
 .../ImportingModel.dmn                             |  69 +++
 .../java/org/kie/dmn/validation/ValidatorTest.java |  44 ++
 15 files changed, 1307 insertions(+), 398 deletions(-)

diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java
 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java
index e8adbc9483..ff752b51c0 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceEvaluator.java
@@ -40,6 +40,7 @@ import org.kie.dmn.core.impl.DMNDecisionResultImpl;
 import org.kie.dmn.core.impl.DMNResultImpl;
 import org.kie.dmn.core.impl.DMNRuntimeEventManagerUtils;
 import org.kie.dmn.core.impl.DMNRuntimeImpl;
+import org.kie.dmn.core.impl.DMNRuntimeUtils;
 import org.kie.dmn.core.util.Msg;
 import org.kie.dmn.core.util.MsgUtil;
 import org.slf4j.Logger;
@@ -84,10 +85,10 @@ public class DMNDecisionServiceEvaluator implements 
DMNExpressionEvaluator {
         }
         boolean typeCheck = ((DMNRuntimeImpl) 
eventManager.getRuntime()).performRuntimeTypeCheck(result.getModel());
         if (typeCheck) {
-            Object c = DMNRuntimeImpl.coerceUsingType(decisionIDs.size() == 1 
? ctx.values().iterator().next() : ctx,
-                                                      dsNode.getResultType(),
-                                                      typeCheck,
-                                                      (rx, tx) -> 
MsgUtil.reportMessage(LOG,
+            Object c = DMNRuntimeUtils.coerceUsingType(decisionIDs.size() == 1 
? ctx.values().iterator().next() : ctx,
+                                                       dsNode.getResultType(),
+                                                       typeCheck,
+                                                       (rx, tx) -> 
MsgUtil.reportMessage(LOG,
                                                                                
         DMNMessage.Severity.WARN,
                                                                                
         dsNode.getDecisionService(),
                                                                                
         result,
diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java
 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java
index e612092067..d9053581c9 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNDecisionServiceFunctionDefinitionEvaluator.java
@@ -36,6 +36,7 @@ import org.kie.dmn.api.core.EvaluatorResult.ResultType;
 import org.kie.dmn.core.ast.DMNFunctionDefinitionEvaluator.FormalParameter;
 import org.kie.dmn.core.impl.DMNResultImpl;
 import org.kie.dmn.core.impl.DMNRuntimeImpl;
+import org.kie.dmn.core.impl.DMNRuntimeUtils;
 import org.kie.dmn.core.util.Msg;
 import org.kie.dmn.core.util.MsgUtil;
 import org.kie.dmn.feel.lang.EvaluationContext;
@@ -156,10 +157,10 @@ public class 
DMNDecisionServiceFunctionDefinitionEvaluator implements DMNExpress
 
         private Object performTypeCheckIfNeeded(Object param, int paramIndex) {
             DSFormalParameter dsFormalParameter = parameters.get(paramIndex);
-            Object result = DMNRuntimeImpl.coerceUsingType(param,
-                                                           
dsFormalParameter.type,
-                                                           typeCheck,
-                                                           (rx, tx) -> 
MsgUtil.reportMessage(LOG,
+            Object result = DMNRuntimeUtils.coerceUsingType(param,
+                                                            
dsFormalParameter.type,
+                                                            typeCheck,
+                                                            (rx, tx) -> 
MsgUtil.reportMessage(LOG,
                                                                                
              DMNMessage.Severity.ERROR,
                                                                                
              null,
                                                                                
              resultContext,
diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionWithReturnType.java
 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionWithReturnType.java
index d226ab2df3..ebad93794e 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionWithReturnType.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/ast/DMNFunctionWithReturnType.java
@@ -24,7 +24,7 @@ import org.kie.dmn.api.core.DMNMessage;
 import org.kie.dmn.api.core.DMNType;
 import org.kie.dmn.api.core.ast.BusinessKnowledgeModelNode;
 import org.kie.dmn.core.api.DMNMessageManager;
-import org.kie.dmn.core.impl.DMNRuntimeImpl;
+import org.kie.dmn.core.impl.DMNRuntimeUtils;
 import org.kie.dmn.core.util.Msg;
 import org.kie.dmn.core.util.MsgUtil;
 import org.kie.dmn.feel.lang.EvaluationContext;
@@ -59,10 +59,10 @@ public class DMNFunctionWithReturnType extends 
BaseFEELFunction {
     @Override
     public Object invokeReflectively(EvaluationContext ctx, Object[] params) {
         Object result = wrapped.invokeReflectively(ctx, params);
-        result = DMNRuntimeImpl.coerceUsingType(result,
-                                                returnType,
-                                                true, // this FN is created 
when typeCheck==true, hence here always true.
-                                                (r, t) -> 
MsgUtil.reportMessage(LOG,
+        result = DMNRuntimeUtils.coerceUsingType(result,
+                                                 returnType,
+                                                 true, // this FN is created 
when typeCheck==true, hence here always true.
+                                                 (r, t) -> 
MsgUtil.reportMessage(LOG,
                                                                                
 DMNMessage.Severity.WARN,
                                                                                
 node.getBusinessKnowledModel(),
                                                                                
 msgMgr,
diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java
index cef231ea66..967ca8b030 100644
--- 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeImpl.java
@@ -68,6 +68,11 @@ import static 
org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.EV
 import static 
org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.FAILED;
 import static 
org.kie.dmn.api.core.DMNDecisionResult.DecisionEvaluationStatus.SKIPPED;
 import static org.kie.dmn.core.compiler.UnnamedImportUtils.isInUnnamedImport;
+import static org.kie.dmn.core.impl.DMNRuntimeUtils.coerceUsingType;
+import static org.kie.dmn.core.impl.DMNRuntimeUtils.getDependencyIdentifier;
+import static org.kie.dmn.core.impl.DMNRuntimeUtils.getIdentifier;
+import static org.kie.dmn.core.impl.DMNRuntimeUtils.getObjectString;
+import static 
org.kie.dmn.core.impl.DMNRuntimeUtils.populateResultContextWithTopmostParentsValues;
 import static org.kie.dmn.core.util.CoerceUtil.coerceValue;
 
 public class DMNRuntimeImpl
@@ -91,84 +96,6 @@ public class DMNRuntimeImpl
         }
     }
 
-    static void populateResultContextWithTopmostParentsValues(DMNContext 
context, DMNModelImpl model) {
-        Optional<Set<DMNModelImpl.ModelImportTuple>> optionalTopmostModels = 
getTopmostModel(model);
-        optionalTopmostModels.ifPresent(topmostModels -> 
populateInputsFromTopmostModel(context, model, topmostModels));
-    }
-
-    static void populateInputsFromTopmostModel(DMNContext context,DMNModelImpl 
model, Set<DMNModelImpl.ModelImportTuple> topmostModels) {
-        for (DMNModelImpl.ModelImportTuple topmostModelTuple : topmostModels) {
-            processTopmostModelTuple(context, topmostModelTuple, model);
-        }
-    }
-
-    static void processTopmostModelTuple(DMNContext context, 
DMNModelImpl.ModelImportTuple topmostModelTuple, DMNModelImpl model) {
-        DMNModelImpl topmostModel = topmostModelTuple.getModel();
-        for (InputDataNode topmostInput : topmostModel.getInputs()) {
-            processTopmostModelInputDataNode(context, topmostInput.getName(), 
topmostModelTuple, model);
-        }
-    }
-
-    static void processTopmostModelInputDataNode( DMNContext context, String 
topmostInputName, DMNModelImpl.ModelImportTuple topmostModelTuple, DMNModelImpl 
model) {
-        Object storedValue = context.get(topmostInputName);
-        if (storedValue != null) {
-            Object parentData = context.get(topmostModelTuple.getImportName());
-            if (parentData instanceof Map mappedData) {
-                processTopmostModelMap(mappedData, topmostInputName, 
storedValue, parentData);
-            } else if (parentData == null) {
-                updateContextMap(context, model.getImportChainAliases(), 
topmostModelTuple, topmostInputName, storedValue);
-            }
-        }
-    }
-
-    /**
-     * Depending on how the context has been instantiated, the provided 
<code>Map</code> could be unmodifiable, which is an expected condition
-     * @param mappedData
-     * @param inputName
-     * @param storedValue
-     * @param parentData
-     */
-    static void processTopmostModelMap(Map mappedData, String inputName, 
Object storedValue, Object parentData) {
-        try {
-            mappedData.put(inputName, storedValue);
-        } catch (Exception e) {
-            logger.warn("Failed to add {} to map {} ", storedValue, 
parentData, e);
-        }
-    }
-
-    static void updateContextMap(DMNContext context, Map<String, 
Collection<List<String>>>  importChainAliases, DMNModelImpl.ModelImportTuple 
topmostModelTuple, String inputName, Object storedValue) {
-        Map mappedData = new HashMap<>();
-        mappedData.put(inputName, storedValue);
-        populateContextWithInheritedData(context, mappedData,
-                topmostModelTuple.getImportName(), 
topmostModelTuple.getModel().getNamespace(), importChainAliases);
-    }
-
-    static void populateContextWithInheritedData(DMNContext toPopulate, 
Map<String, Object> toStore, String importName, String 
topmostNamespace,Map<String, Collection<List<String>>> importChainAliases) {
-        for (List<String> chainedModels : 
importChainAliases.get(topmostNamespace)) {
-            // The order is: first one -> importing model; last one -> parent 
model
-            for (String chainedModel : chainedModels) {
-                if (chainedModel.equals(importName)) {
-                    continue;
-                }
-                if (toStore.get(chainedModel) != null && 
toStore.get(chainedModel) instanceof Map<?, ?> alreadyMapped) {
-                    try {
-                        ((Map<String, Object>) alreadyMapped).put(importName, 
toStore);
-                    } catch (Exception e) {
-                        logger.warn("Failed to add {} to map {} ", toStore, 
alreadyMapped, e);
-                    }
-                } else {
-                    Map<String, Object> chainedMap = new HashMap<>();
-                    chainedMap.put(importName, toStore);
-                    toPopulate.set(chainedModel, chainedMap);
-                }
-            }
-        }
-    }
-
-    static Optional<Set<DMNModelImpl.ModelImportTuple>> 
getTopmostModel(DMNModelImpl model) {
-        return model.getTopmostParents();
-    }
-
     @Override
     public List<DMNModel> getModels() {
         return runtimeKB.getModels();
@@ -196,7 +123,8 @@ public class DMNRuntimeImpl
         boolean strictMode = 
this.runtimeModeOption.equals(RuntimeModeOption.MODE.STRICT);
         DMNResultImpl result = createResult(model, context);
         DMNRuntimeEventManagerUtils.fireBeforeEvaluateAll(eventManager, model, 
result);
-        // the engine should evaluate all Decisions belonging to the "local" 
model namespace, not imported decision explicitly.
+        // the engine should evaluate all Decisions belonging to the "local" 
model namespace, not imported decision
+        // explicitly.
         Set<DecisionNode> decisions = model.getDecisions().stream()
                 .filter(d -> 
d.getModelNamespace().equals(model.getNamespace())).collect(Collectors.toSet());
         for (DecisionNode decision : decisions) {
@@ -347,7 +275,8 @@ public class DMNRuntimeImpl
     public DMNResult evaluateDecisionService(DMNModel model, DMNContext 
context, String decisionServiceName) {
         Objects.requireNonNull(model, () -> 
MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "model"));
         Objects.requireNonNull(context, () -> 
MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "context"));
-        Objects.requireNonNull(decisionServiceName, () -> 
MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "decisionServiceName"));
+        Objects.requireNonNull(decisionServiceName, () -> 
MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL,
+                                                                               
 "decisionServiceName"));
         boolean typeCheck = performRuntimeTypeCheck(model);
         DMNResultImpl result = createResultImpl(model, context);
 
@@ -539,49 +468,16 @@ public class DMNRuntimeImpl
         }
     }
 
-    public static Object coerceUsingType(Object value, DMNType type, boolean 
typeCheck,
-                                         BiConsumer<Object, DMNType> 
nullCallback) {
-        if (typeCheck) {
-            if (type.isAssignableValue(value)) {
-                return coerceSingleItemCollectionToValue(value, type);
-            } else {
-                nullCallback.accept(value, type);
-                return null;
-            }
-        } else {
-            return coerceSingleItemCollectionToValue(value, type);
-        }
-    }
-
-    /**
-     * Checks a type and if it is not a collection type, checks if the 
specified value is a collection
-     * that contains only a single value and if yes, coerces the collection to 
the single item itself.
-     * E.g. [1] becomes 1. Basically it unwraps the single item from a 
collection, if it is required.
-     * @param value Value that is checked and potentially coerced to a single 
item.
-     * @param type Required type. Based on this type, it is determined, if the 
coercion happens.
-     * If the requirement is for a non-collection type and the value is a 
single item collection,
-     * the coercion happens.
-     * @return If all requirements are met, returns coerced value. Otherwise 
returns the original value.
-     */
-    private static Object coerceSingleItemCollectionToValue(Object value, 
DMNType type) {
-        if (!type.isCollection() && value instanceof Collection && 
((Collection<?>) value).size() == 1) {
-            // as per Decision evaluation result.
-            return ((Collection<?>) value).toArray()[0];
-        } else {
-            return value;
-        }
-    }
-
     private boolean isNodeValueDefined(DMNResultImpl result, DMNNode 
callerNode, DMNNode calledNode) {
         if 
(calledNode.getModelNamespace().equals(result.getContext().scopeNamespace().orElse(result.getModel()
-                                                                               
                 .getNamespace()))) {
+                                                                               
                       .getNamespace()))) {
             return result.getContext().isDefined(calledNode.getName());
-        }  else if (isInUnnamedImport(calledNode, (DMNModelImpl) 
result.getModel())) {
+        } else if (isInUnnamedImport(calledNode, (DMNModelImpl) 
result.getModel())) {
             // the node is an unnamed import
             return result.getContext().isDefined(calledNode.getName());
         } else {
             Optional<String> importAlias = 
callerNode.getModelImportAliasFor(calledNode.getModelNamespace(), calledNode
-            .getModelName());
+                    .getModelName());
             if (importAlias.isPresent()) {
                 Object aliasContext = 
result.getContext().get(importAlias.get());
                 if (aliasContext instanceof Map<?, ?> mappedContext) {
@@ -598,7 +494,8 @@ public class DMNRuntimeImpl
             return false;
         } else {
             DMNModelImpl model = (DMNModelImpl) dmnModel;
-            Optional<String> importAlias = 
model.getImportAliasFor(destinationNode.getModelNamespace(), 
destinationNode.getModelName());
+            Optional<String> importAlias = 
model.getImportAliasFor(destinationNode.getModelNamespace(),
+                                                                   
destinationNode.getModelName());
             if (importAlias.isPresent()) {
                 result.getContext().pushScope(importAlias.get(), 
destinationNode.getModelNamespace());
                 return true;
@@ -625,7 +522,8 @@ public class DMNRuntimeImpl
                 // the destinationNode is an unnamed import
                 return false;
             } else {
-                Optional<String> importAlias = 
callerNode.getModelImportAliasFor(destinationNode.getModelNamespace(), 
destinationNode.getModelName());
+                Optional<String> importAlias = 
callerNode.getModelImportAliasFor(destinationNode.getModelNamespace(),
+                                                                               
  destinationNode.getModelName());
                 if (importAlias.isPresent()) {
                     result.getContext().pushScope(importAlias.get(), 
destinationNode.getModelNamespace());
                     return true;
@@ -637,7 +535,8 @@ public class DMNRuntimeImpl
                                           null,
                                           null,
                                           
Msg.IMPORT_NOT_FOUND_FOR_NODE_MISSING_ALIAS,
-                                          new 
QName(destinationNode.getModelNamespace(), destinationNode.getModelName()),
+                                          new 
QName(destinationNode.getModelNamespace(),
+                                                    
destinationNode.getModelName()),
                                           callerNode.getName()
                     );
                     return false;
@@ -660,7 +559,8 @@ public class DMNRuntimeImpl
                                           null,
                                           null,
                                           
Msg.IMPORT_NOT_FOUND_FOR_NODE_MISSING_ALIAS,
-                                          new 
QName(destinationNode.getModelNamespace(), destinationNode.getModelName()),
+                                          new 
QName(destinationNode.getModelNamespace(),
+                                                    
destinationNode.getModelName()),
                                           callerNode.getName());
                     return false;
                 }
@@ -678,16 +578,19 @@ public class DMNRuntimeImpl
             return true;
         } else {
             // check if the decision was already evaluated before and returned 
error
-            DMNDecisionResult.DecisionEvaluationStatus status = 
Optional.ofNullable(result.getDecisionResultById(decisionId))
+            DMNDecisionResult.DecisionEvaluationStatus status =
+                    
Optional.ofNullable(result.getDecisionResultById(decisionId))
                     .map(DMNDecisionResult::getEvaluationStatus)
-                    
.orElse(DMNDecisionResult.DecisionEvaluationStatus.NOT_EVALUATED); // it might 
be an imported Decision.
+                    
.orElse(DMNDecisionResult.DecisionEvaluationStatus.NOT_EVALUATED); // it might 
be an imported
+            // Decision.
             if (FAILED == status || SKIPPED == status || EVALUATING == status) 
{
                 return false;
             }
         }
         BeforeEvaluateDecisionEvent beforeEvaluateDecisionEvent = null;
         try {
-            beforeEvaluateDecisionEvent = 
DMNRuntimeEventManagerUtils.fireBeforeEvaluateDecision(eventManager, decision, 
result);
+            beforeEvaluateDecisionEvent = 
DMNRuntimeEventManagerUtils.fireBeforeEvaluateDecision(eventManager,
+                                                                               
                  decision, result);
             DMNDecisionResultImpl dr = (DMNDecisionResultImpl) 
result.getDecisionResultById(decisionId);
             if (dr == null) { // an imported Decision now evaluated, requires 
the creation of the decision result:
                 String decisionResultName = d.getName();
@@ -697,7 +600,8 @@ public class DMNRuntimeImpl
                     decisionResultName = importAliasFor.get() + "." + 
d.getName();
                 }
                 dr = new DMNDecisionResultImpl(decisionId, decisionResultName);
-                if (importAliasFor.isPresent()) { // otherwise is a 
transitive, skipped and not to be added to the results:
+                if (importAliasFor.isPresent()) { // otherwise is a 
transitive, skipped and not to be added to the
+                    // results:
                     result.addDecisionResult(dr);
                 }
             }
@@ -859,6 +763,7 @@ public class DMNRuntimeImpl
         try {
             if (typeCheck && !checkDependencyValueIsValid(dep, result)) {
                 toReturn = true;
+                String toPrint = 
getObjectString(result.getContext().get(dep.getName()));
                 DMNMessage message = MsgUtil.reportMessage(logger,
                                                            
DMNMessage.Severity.ERROR,
                                                            ((DMNBaseNode) 
dep).getSource(),
@@ -868,7 +773,7 @@ public class DMNRuntimeImpl
                                                            
Msg.ERROR_EVAL_NODE_DEP_WRONG_TYPE,
                                                            
getIdentifier(decision),
                                                            
getDependencyIdentifier(decision, dep),
-                                                           
MsgUtil.clipString(Objects.toString(result.getContext().get(dep.getName())), 
50),
+                                                           toPrint,
                                                            ((DMNBaseNode) 
dep).getType()
                 );
                 reportFailure(dr, message, 
DMNDecisionResult.DecisionEvaluationStatus.SKIPPED);
@@ -887,24 +792,6 @@ public class DMNRuntimeImpl
         return toReturn;
     }
 
-    private static String getIdentifier(DMNNode node) {
-        return node.getName() != null ? node.getName() : node.getId();
-    }
-
-    private static String getDependencyIdentifier(DMNNode callerNode, DMNNode 
node) {
-        if (node.getModelNamespace().equals(callerNode.getModelNamespace())) {
-            return getIdentifier(node);
-        } else {
-            Optional<String> importAlias = 
callerNode.getModelImportAliasFor(node.getModelNamespace(),
-                                                                             
node.getModelName());
-            String prefix = "{" + node.getModelNamespace() + "}";
-            if (importAlias.isPresent()) {
-                prefix = importAlias.get();
-            }
-            return prefix + "." + getIdentifier(node);
-        }
-    }
-
     public boolean performRuntimeTypeCheck(DMNModel model) {
         Objects.requireNonNull(model, () -> 
MsgUtil.createMessage(Msg.PARAM_CANNOT_BE_NULL, "model"));
         return overrideRuntimeTypeCheck || ((DMNModelImpl) 
model).isRuntimeTypeCheck();
diff --git 
a/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeUtils.java 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeUtils.java
new file mode 100644
index 0000000000..1158e1539a
--- /dev/null
+++ 
b/kie-dmn/kie-dmn-core/src/main/java/org/kie/dmn/core/impl/DMNRuntimeUtils.java
@@ -0,0 +1,276 @@
+/*
+ * 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.kie.dmn.core.impl;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.function.BiConsumer;
+import org.kie.dmn.api.core.DMNContext;
+import org.kie.dmn.api.core.DMNType;
+import org.kie.dmn.api.core.ast.DMNNode;
+import org.kie.dmn.api.core.ast.InputDataNode;
+import org.kie.dmn.core.util.MsgUtil;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Utility class to support <code>DMNRuntimeImpl</code>
+ */
+public class DMNRuntimeUtils {
+
+    private static final Logger logger = 
LoggerFactory.getLogger(DMNRuntimeUtils.class);
+
+    private DMNRuntimeUtils() {
+        // singleton
+    }
+
+
+    public static Object coerceUsingType(Object value, DMNType type, boolean 
typeCheck,
+                                         BiConsumer<Object, DMNType> 
nullCallback) {
+        if (typeCheck) {
+            if (type.isAssignableValue(value)) {
+                return coerceSingleItemCollectionToValue(value, type);
+            } else {
+                nullCallback.accept(value, type);
+                return null;
+            }
+        } else {
+            return coerceSingleItemCollectionToValue(value, type);
+        }
+    }
+
+    static void populateResultContextWithTopmostParentsValues(DMNContext 
context, DMNModelImpl model) {
+        Optional<Set<DMNModelImpl.ModelImportTuple>> optionalTopmostModels = 
getTopmostModel(model);
+        optionalTopmostModels.ifPresent(topmostModels -> 
populateInputsFromTopmostModel(context, model, topmostModels));
+    }
+
+    static void populateInputsFromTopmostModel(DMNContext context, 
DMNModelImpl model,
+                                               
Set<DMNModelImpl.ModelImportTuple> topmostModels) {
+        for (DMNModelImpl.ModelImportTuple topmostModelTuple : topmostModels) {
+            processTopmostModelTuple(context, topmostModelTuple, model);
+        }
+    }
+
+    static void processTopmostModelTuple(DMNContext context, 
DMNModelImpl.ModelImportTuple topmostModelTuple,
+                                         DMNModelImpl model) {
+        DMNModelImpl topmostModel = topmostModelTuple.getModel();
+        for (InputDataNode topmostInput : topmostModel.getInputs()) {
+            processTopmostModelInputDataNode(context, topmostInput.getName(), 
topmostModelTuple, model);
+        }
+    }
+
+    static void processTopmostModelInputDataNode(DMNContext context, String 
topmostInputName,
+                                                 DMNModelImpl.ModelImportTuple 
topmostModelTuple, DMNModelImpl model) {
+        if (Objects.equals(topmostInputName, 
topmostModelTuple.getImportName())) {
+            processTopmostModelInputDataNodeWithClashingNames(context, 
topmostInputName,
+                                                              
topmostModelTuple, model);
+        } else {
+            processTopmostModelInputDataNodeWithoutClashingNames(context, 
topmostInputName,
+                                                                 
topmostModelTuple, model);
+        }
+    }
+
+    static void processTopmostModelInputDataNodeWithClashingNames(DMNContext 
context, String topmostInputName,
+                                                                  
DMNModelImpl.ModelImportTuple topmostModelTuple,
+                                                                  DMNModelImpl 
model) {
+        Object storedValue = context.get(topmostInputName); // This could be 
either a raw value, or a map
+        if (storedValue instanceof Map storedMap && 
storedMap.containsKey(topmostInputName)) { // The check is needed to avoid 
looping reference
+            return;
+        }
+        // Eventually, we need to create a map with the importing name and 
populate it with the input data
+        replaceContextMap(context, topmostModelTuple, topmostInputName,
+                          storedValue);
+    }
+
+    static void 
processTopmostModelInputDataNodeWithoutClashingNames(DMNContext context, String 
topmostInputName,
+                                                                     
DMNModelImpl.ModelImportTuple topmostModelTuple,
+                                                                     
DMNModelImpl model) {
+        Object storedValue = context.get(topmostInputName);
+        if (storedValue != null) {
+            Object parentData = context.get(topmostModelTuple.getImportName());
+            if (parentData instanceof Map mappedData) {
+                addValueInsideMap(mappedData, topmostInputName, storedValue);
+            } else if (parentData == null) {
+                updateContextMap(context, model.getImportChainAliases(), 
topmostModelTuple, topmostInputName,
+                                 storedValue);
+            }
+        }
+    }
+
+    static void replaceContextMap(DMNContext context,
+                                  DMNModelImpl.ModelImportTuple 
topmostModelTuple, String inputName,
+                                  Object storedValue) {
+        Map<String, Object> mappedData = new HashMap<>();
+        mappedData.put(inputName, storedValue);
+        context.set(topmostModelTuple.getImportName(), mappedData);
+    }
+
+    static void updateContextMap(DMNContext context, Map<String, 
Collection<List<String>>> importChainAliases,
+                                 DMNModelImpl.ModelImportTuple 
topmostModelTuple, String inputName,
+                                 Object storedValue) {
+        Map<String, Object> mappedData = new HashMap<>();
+        mappedData.put(inputName, storedValue);
+        populateContextWithInheritedData(context, mappedData,
+                                         topmostModelTuple.getImportName(),
+                                         
topmostModelTuple.getModel().getNamespace(), importChainAliases);
+    }
+
+    /**
+     * This method populate the given <code>DMNContext</code> with a new entry 
whose key is the import name and whose value is the provided <code>Map</code> 
<b>toStore</b>,
+     * if those are related with the namespace of the topmost parent
+     * @param toPopulate
+     * @param toStore
+     * @param importName
+     * @param topmostNamespace
+     * @param importChainAliases
+     */
+    static void populateContextWithInheritedData(DMNContext toPopulate, 
Map<String, Object> toStore,
+                                                 String importName, String 
topmostNamespace, Map<String,
+                    Collection<List<String>>> importChainAliases) {
+        for (List<String> chainedModels : 
importChainAliases.get(topmostNamespace)) {
+            // The order is: first one -> importing model; last one -> parent 
model
+            for (String chainedModel : chainedModels) {
+                if (chainedModel.equals(importName)) {
+                    continue;
+                }
+                if (toStore.get(chainedModel) != null && 
toStore.get(chainedModel) instanceof Map alreadyMapped) {
+                    addValueInsideMap(alreadyMapped, importName, toStore);
+                } else {
+                    addNewMapToContext(toPopulate, importName, toStore, 
chainedModel);
+                }
+            }
+        }
+    }
+
+    /**
+     * Create a new <code>Map</code> with the given <code>importName</code> 
value set to the given <code>Map</code> <b>toStore</b>.
+     * Then, set this newly-created Map in the given <code>DMNContext</code> 
as <b>chainedModel</b>
+     * @param toPopulate
+     * @param importName
+     * @param toStore
+     * @param chainedModel
+     */
+    static void addNewMapToContext(DMNContext toPopulate, String importName, 
Map<String, Object> toStore, String chainedModel) {
+        Map<String, Object> chainedMap = new HashMap<>();
+        chainedMap.put(importName, toStore);
+        toPopulate.set(chainedModel, chainedMap);
+    }
+
+    /**
+     * Depending on how the context has been instantiated, the provided 
<code>Map</code> could be unmodifiable, which
+     * is an expected condition
+     * @param mappedData
+     * @param inputName
+     * @param storedValue
+     */
+    static void addValueInsideMap(Map<String, Object> mappedData, String 
inputName, Object storedValue) {
+        try {
+            mappedData.put(inputName, storedValue);
+        } catch (Exception e) {
+            logger.warn("Failed to put {} -> {} to map {} ", inputName, 
storedValue, mappedData, e);
+        }
+    }
+
+    /**
+     * Method to return the <b>topmost parents</b> of the given model.
+     * There could be more then one, since a model may import multiple others.
+     * It is a <code>Set</code> to avoid duplicating the same entry
+     * @param model
+     * @return
+     */
+    static Optional<Set<DMNModelImpl.ModelImportTuple>> 
getTopmostModel(DMNModelImpl model) {
+        return model.getTopmostParents();
+    }
+
+    /**
+     * Checks a type and if it is not a collection type, checks if the 
specified value is a collection
+     * that contains only a single value and if yes, coerces the collection to 
the single item itself.
+     * E.g. [1] becomes 1. Basically it unwraps the single item from a 
collection, if it is required.
+     * @param value Value that is checked and potentially coerced to a single 
item.
+     * @param type Required type. Based on this type, it is determined, if the 
coercion happens.
+     * If the requirement is for a non-collection type and the value is a 
single item collection,
+     * the coercion happens.
+     * @return If all requirements are met, returns coerced value. Otherwise 
returns the original value.
+     */
+    static Object coerceSingleItemCollectionToValue(Object value, DMNType 
type) {
+        if (!type.isCollection() && value instanceof Collection && 
((Collection<?>) value).size() == 1) {
+            // as per Decision evaluation result.
+            return ((Collection<?>) value).toArray()[0];
+        } else {
+            return value;
+        }
+    }
+
+    /**
+     * Method used to catch StackOverflowError and allow nice handling of them
+     * @return
+     */
+    static String getObjectString(Object toPrint) {
+        try {
+            return MsgUtil.clipString(Objects.toString(toPrint), 50);
+        } catch (StackOverflowError e) {
+            logger.error("Stack overflow error while trying to String {}", 
toPrint.getClass());
+            return "(_undefined_)";
+        }
+    }
+
+    /**
+     * If the given nodes have the same namespace, returns the 
<code>getIdentifier</code> of the <code>calledNode</code>
+     * Otherwise, returns the <code>getPrefixedIdentifier</code> of the 
<code>calledNode</code>
+     * @param callerNode
+     * @param calledNode
+     * @return
+     */
+    static String getDependencyIdentifier(DMNNode callerNode, DMNNode 
calledNode) {
+        if 
(calledNode.getModelNamespace().equals(callerNode.getModelNamespace())) {
+            return getIdentifier(calledNode);
+        } else {
+            return getPrefixedIdentifier(callerNode, calledNode);
+        }
+    }
+
+    /**
+     * Returns the <code>getIdentifier</code> of the <code>calledNode</code> 
prefixed.
+     * If the <code>callerNode</code> has an import alias for the 
<code>calledNode</code>, the prefix is the import
+     * alias, otherwise the prefix is the namespace of the 
<code>calledNode</code>
+     * @param callerNode
+     * @param calledNode
+     * @return
+     */
+    static String getPrefixedIdentifier(DMNNode callerNode, DMNNode 
calledNode) {
+        Optional<String> importAlias = 
callerNode.getModelImportAliasFor(calledNode.getModelNamespace(),
+                                                                         
calledNode.getModelName());
+        String prefix = importAlias.orElse(String.format("{%s}", 
calledNode.getModelNamespace()));
+        return prefix + "." + getIdentifier(calledNode);
+    }
+
+    /**
+     * Returns the name of the node, if set, otherwise the id
+     * @param node
+     * @return
+     */
+    static String getIdentifier(DMNNode node) {
+        return node.getName() != null ? node.getName() : node.getId();
+    }
+}
diff --git 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeImplTest.java
 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeImplTest.java
deleted file mode 100644
index 786e8c71c4..0000000000
--- 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeImplTest.java
+++ /dev/null
@@ -1,242 +0,0 @@
-/*
- * 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.kie.dmn.core.impl;
-
-import org.junit.jupiter.api.Test;
-import org.kie.dmn.api.core.DMNContext;
-import org.kie.dmn.api.core.ast.InputDataNode;
-import org.kie.dmn.core.ast.InputDataNodeImpl;
-import org.kie.dmn.model.api.Definitions;
-import org.kie.dmn.model.api.InputData;
-
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.kie.dmn.core.impl.DMNRuntimeImpl.getTopmostModel;
-import static 
org.kie.dmn.core.impl.DMNRuntimeImpl.populateContextWithInheritedData;
-import static 
org.kie.dmn.core.impl.DMNRuntimeImpl.populateInputsFromTopmostModel;
-import static 
org.kie.dmn.core.impl.DMNRuntimeImpl.populateResultContextWithTopmostParentsValues;
-import static org.kie.dmn.core.impl.DMNRuntimeImpl.processTopmostModelTuple;
-import static org.kie.dmn.core.impl.DMNRuntimeImpl.updateContextMap;
-import static org.mockito.Mockito.CALLS_REAL_METHODS;
-import static org.mockito.Mockito.doReturn;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.when;
-
-class DMNRuntimeImplTest {
-
-    @Test
-    void testGetTopmostModel() {
-        DMNModelImpl importingModel = mock(DMNModelImpl.class);
-        DMNModelImpl importedModel = mock(DMNModelImpl.class);
-
-        when(importedModel.getNamespace())
-                
.thenReturn("http://www.trisotech.com/definitions/_ae5b3c17-1ac3-4e1d-b4f9-2cf861aec6d9";);
-        when(importedModel.getName())
-                .thenReturn("ParentModel");
-
-        when(importingModel.getImportAliasFor(importedModel.getNamespace(), 
importedModel.getName()))
-                .thenReturn(Optional.of("parentModel"));
-
-        DMNModelImpl.ModelImportTuple tuple =
-                new DMNModelImpl.ModelImportTuple("parentModel", 
importedModel);
-        Optional<Set<DMNModelImpl.ModelImportTuple>> optionalTopmostModels = 
Optional.of(Set.of(tuple));
-
-        
when(importingModel.getTopmostParents()).thenReturn(optionalTopmostModels);
-
-        Optional<Set<DMNModelImpl.ModelImportTuple>> topmostModel = 
getTopmostModel(importingModel);
-
-        assertThat(topmostModel).isPresent();
-        topmostModel.ifPresent(set ->
-                assertThat(set)
-                        
.extracting(DMNModelImpl.ModelImportTuple::getImportName)
-                        .containsOnly("parentModel")
-        );
-    }
-
-    @Test
-    void testPopulateResultContextWithTopmostParentsValues() {
-        Definitions defs = mock(Definitions.class);
-        when(defs.getNamespace()).thenReturn("ns1");
-        when(defs.getName()).thenReturn("model1");
-        DMNModelImpl model = spy(new DMNModelImpl(defs));
-
-        Definitions parentDefs = mock(Definitions.class);
-        when(parentDefs.getNamespace()).thenReturn("ns2");
-        when(parentDefs.getName()).thenReturn("parentModel");
-        DMNModelImpl parent = new DMNModelImpl(parentDefs);
-
-        InputDataNode inputNode = mock(InputDataNode.class);
-        when(inputNode.getName()).thenReturn("inputA");
-        when(inputNode.getModelNamespace()).thenReturn("ns2");
-        when(inputNode.getId()).thenReturn("idA");
-        parent.addInput(inputNode);
-
-        model.setImportAliasForNS("parentAlias", "ns2", "parentModel");
-        Set<DMNModelImpl.ModelImportTuple> topmostParents =
-                Set.of(new DMNModelImpl.ModelImportTuple("parentAlias", 
parent));
-        doReturn(Optional.of(topmostParents)).when(model).getTopmostParents();
-
-        DMNContext context = new DMNContextImpl();
-        Map<String, Object> parentAliasMap = new HashMap<>();
-        parentAliasMap.put("inputA", "valueA");
-        context.set("parentAlias", parentAliasMap);
-
-        DMNModelImpl.ModelImportTuple tuple = new 
DMNModelImpl.ModelImportTuple("parentModel", parent);
-        Optional<Set<DMNModelImpl.ModelImportTuple>> optionalTopmostModels = 
Optional.of(Set.of(tuple));
-        when(getTopmostModel(model)).thenReturn(optionalTopmostModels);
-
-        Map<String, Collection<List<String>>> mockImportChainAliases = new 
HashMap<>();
-        mockImportChainAliases.put("ns2", List.of(List.of("parentAlias")));
-        when(model.getImportChainAliases()).thenReturn(mockImportChainAliases);
-
-        populateResultContextWithTopmostParentsValues(context, model);
-
-        DMNContext expectedContext = new DMNContextImpl();
-        expectedContext.set("parentAlias",Map.of("inputA", "valueA"));
-
-        assertThat(context)
-                .usingRecursiveComparison()
-                .isEqualTo(expectedContext);
-    }
-
-    @Test
-    void testPopulateInputsFromTopmostModels() {
-        DMNModelImpl importingModel = mock(DMNModelImpl.class);
-        DMNContext context = new DMNContextImpl();
-        context.set("Person Name", "Klaus");
-
-        InputData mockInputData = mock(InputData.class);
-        when(mockInputData.getName()).thenReturn("Person Name");
-        InputDataNodeImpl node = new InputDataNodeImpl(mockInputData);
-
-        DMNModelImpl topmostModel = mock(DMNModelImpl.class);
-        when(topmostModel.getInputs()).thenReturn(Set.of(node));
-
-        String namespace = "test-namespace";
-        DMNModelImpl.ModelImportTuple tupleA = 
mock(DMNModelImpl.ModelImportTuple.class);
-        when(tupleA.getModel()).thenReturn(topmostModel);
-        when(tupleA.getImportName()).thenReturn("parentModel");
-        when(tupleA.getModel().getNamespace()).thenReturn(namespace);
-
-        Map<String, Collection<List<String>>> importChainAliases = new 
HashMap<>();
-        List<String> chain = Arrays.asList("Child A", "parentModel");
-        importChainAliases.put(namespace, Collections.singletonList(chain));
-        
when(importingModel.getImportChainAliases()).thenReturn(importChainAliases);
-
-        Set<DMNModelImpl.ModelImportTuple> topmostModels = Set.of(tupleA);
-
-        populateInputsFromTopmostModel(context, importingModel, topmostModels);
-
-        assertThat(context.get("Person Name")).isEqualTo("Klaus");
-    }
-
-    @Test
-    void testPopulateContextWithInheritedData() {
-        DMNContext toPopulate = new DMNContextImpl();
-        toPopulate.set("Person Name", "Klaus");
-
-        List<String> chainedModels = List.of("Child A", "parentModel");
-        Map toStore = Map.of("Person Name", "Klaus");
-        String importName = "parentModel";
-        String topMostNamespace = 
"https://www.apache.org/customnamespace/_ae5b3c17-1ac3-4e1d-b4f9-2cf861aec6d9";;
-
-        DMNContext context = new DMNContextImpl();
-        Map<String, Object> parentModel = Map.of("Person Name", "Klaus");
-        Map<String, Object> childA = Map.of("parentModel", parentModel);
-        context.set("Person Name", "Klaus");
-        context.set("Child A", childA);
-
-        Map<String, Collection<List<String>>> importChainAliases = 
mock(Map.class);
-        
when(importChainAliases.get(topMostNamespace)).thenReturn(Collections.singletonList(chainedModels));
-
-        populateContextWithInheritedData(toPopulate, toStore, importName, 
topMostNamespace, importChainAliases);
-        assertThat(toPopulate).usingRecursiveComparison().isEqualTo(context);
-    }
-
-    @Test
-    void testProcessTopmostModelTuple() {
-        DMNModelImpl model = mock(DMNModelImpl.class);
-        DMNModelImpl.ModelImportTuple topmostModelTuple = 
mock(DMNModelImpl.ModelImportTuple.class);
-        DMNModelImpl topmostModel = mock(DMNModelImpl.class);
-
-        DMNContext context = new DMNContextImpl();
-        context.set("Person Name", "Klaus");
-
-        InputData topmostInput = mock(InputData.class);
-        InputDataNodeImpl node = new InputDataNodeImpl(topmostInput);
-
-        when(topmostModelTuple.getModel()).thenReturn(topmostModel);
-        when(topmostModel.getInputs()).thenReturn(Set.of(node));
-        when(topmostInput.getName()).thenReturn("Person Name");
-        when(topmostModelTuple.getImportName()).thenReturn("parentModel");
-        
-        String namespace = "test-namespace";
-        
when(topmostModelTuple.getModel().getNamespace()).thenReturn(namespace);
-        
-        Map<String, Collection<List<String>>> importChainAliases = new 
HashMap<>();
-        List<String> chain = Arrays.asList("Child A", "parentModel");
-        importChainAliases.put(namespace, Collections.singletonList(chain));
-        when(model.getImportChainAliases()).thenReturn(importChainAliases);
-
-        processTopmostModelTuple(context, topmostModelTuple, model);
-
-        assertThat(context.get("Person Name")).isEqualTo("Klaus");
-    }
-
-    @Test
-    void testUpdateContextMap() {
-        DMNModelImpl topmostModel = mock(DMNModelImpl.class);
-        String namespace = "namespace";
-        String topmostModelImportName = "parentModel";
-        String importingModelName = "Child A";
-        when(topmostModel.getNamespace()).thenReturn(namespace);
-        when(topmostModel.getName()).thenReturn(topmostModelImportName);
-
-        String inputName = "Person Name";
-        String storedValue = "Klaus";
-
-        Map<String, Collection<List<String>>> importChainAliases = new 
HashMap<>();
-        // Order is from bottom - i.e. executed model - to topmost - i.e. 
imported
-        List<String> chain = Arrays.asList(importingModelName, 
topmostModelImportName);
-        importChainAliases.put(namespace, Collections.singletonList(chain));
-
-        DMNContextImpl context = new DMNContextImpl();
-
-        DMNModelImpl.ModelImportTuple topmostModelTuple =
-                new DMNModelImpl.ModelImportTuple(topmostModelImportName, 
topmostModel);
-
-        updateContextMap(context, importChainAliases, topmostModelTuple, 
inputName, storedValue);
-
-        @SuppressWarnings("unchecked")
-        Map<String, Object> childA = (Map<String, Object>) 
context.get(importingModelName);
-        @SuppressWarnings("unchecked")
-        Map<String, Object> parentMap = (Map<String, Object>) 
childA.get(topmostModelImportName);
-        assertThat(parentMap).containsEntry(inputName, storedValue);
-    }
-
-}
\ No newline at end of file
diff --git 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeUtilsTest.java
 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeUtilsTest.java
new file mode 100644
index 0000000000..fb19c68a80
--- /dev/null
+++ 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/impl/DMNRuntimeUtilsTest.java
@@ -0,0 +1,461 @@
+/*
+ * 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.kie.dmn.core.impl;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.stream.IntStream;
+import org.junit.jupiter.api.Test;
+import org.kie.dmn.api.core.DMNContext;
+import org.kie.dmn.api.core.DMNType;
+import org.kie.dmn.api.core.ast.DMNNode;
+import org.kie.dmn.api.core.ast.InputDataNode;
+import org.kie.dmn.core.ast.InputDataNodeImpl;
+import org.kie.dmn.model.api.Definitions;
+import org.kie.dmn.model.api.InputData;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.when;
+
+class DMNRuntimeUtilsTest {
+
+    @Test
+    void populateResultContextWithTopmostParentsValues() {
+        Definitions defs = mock(Definitions.class);
+        when(defs.getNamespace()).thenReturn("ns1");
+        when(defs.getName()).thenReturn("model1");
+        DMNModelImpl model = spy(new DMNModelImpl(defs));
+
+        Definitions parentDefs = mock(Definitions.class);
+        when(parentDefs.getNamespace()).thenReturn("ns2");
+        when(parentDefs.getName()).thenReturn("parentModel");
+        DMNModelImpl parent = new DMNModelImpl(parentDefs);
+
+        InputDataNode inputNode = mock(InputDataNode.class);
+        when(inputNode.getName()).thenReturn("inputA");
+        when(inputNode.getModelNamespace()).thenReturn("ns2");
+        when(inputNode.getId()).thenReturn("idA");
+        parent.addInput(inputNode);
+
+        model.setImportAliasForNS("parentAlias", "ns2", "parentModel");
+        Set<DMNModelImpl.ModelImportTuple> topmostParents =
+                Set.of(new DMNModelImpl.ModelImportTuple("parentAlias", 
parent));
+        doReturn(Optional.of(topmostParents)).when(model).getTopmostParents();
+
+        DMNContext context = new DMNContextImpl();
+        Map<String, Object> parentAliasMap = new HashMap<>();
+        parentAliasMap.put("inputA", "valueA");
+        context.set("parentAlias", parentAliasMap);
+
+        DMNModelImpl.ModelImportTuple tuple = new 
DMNModelImpl.ModelImportTuple("parentModel", parent);
+        Optional<Set<DMNModelImpl.ModelImportTuple>> optionalTopmostModels = 
Optional.of(Set.of(tuple));
+        
when(DMNRuntimeUtils.getTopmostModel(model)).thenReturn(optionalTopmostModels);
+
+        Map<String, Collection<List<String>>> mockImportChainAliases = new 
HashMap<>();
+        mockImportChainAliases.put("ns2", List.of(List.of("parentAlias")));
+        when(model.getImportChainAliases()).thenReturn(mockImportChainAliases);
+
+        DMNRuntimeUtils.populateResultContextWithTopmostParentsValues(context, 
model);
+
+        DMNContext expectedContext = new DMNContextImpl();
+        expectedContext.set("parentAlias", Map.of("inputA", "valueA"));
+
+        assertThat(context)
+                .usingRecursiveComparison()
+                .isEqualTo(expectedContext);
+    }
+
+    @Test
+    void populateInputsFromTopmostModels() {
+        DMNModelImpl importingModel = mock(DMNModelImpl.class);
+        DMNContext context = new DMNContextImpl();
+        context.set("Person Name", "Klaus");
+
+        InputData mockInputData = mock(InputData.class);
+        when(mockInputData.getName()).thenReturn("Person Name");
+        InputDataNodeImpl node = new InputDataNodeImpl(mockInputData);
+
+        DMNModelImpl topmostModel = mock(DMNModelImpl.class);
+        when(topmostModel.getInputs()).thenReturn(Set.of(node));
+
+        String namespace = "test-namespace";
+        DMNModelImpl.ModelImportTuple tupleA = 
mock(DMNModelImpl.ModelImportTuple.class);
+        when(tupleA.getModel()).thenReturn(topmostModel);
+        when(tupleA.getImportName()).thenReturn("parentModel");
+        when(tupleA.getModel().getNamespace()).thenReturn(namespace);
+
+        Map<String, Collection<List<String>>> importChainAliases = new 
HashMap<>();
+        List<String> chain = Arrays.asList("Child A", "parentModel");
+        importChainAliases.put(namespace, Collections.singletonList(chain));
+        
when(importingModel.getImportChainAliases()).thenReturn(importChainAliases);
+
+        Set<DMNModelImpl.ModelImportTuple> topmostModels = Set.of(tupleA);
+
+        DMNRuntimeUtils.populateInputsFromTopmostModel(context, 
importingModel, topmostModels);
+
+        assertThat(context.get("Person Name")).isEqualTo("Klaus");
+    }
+
+    @Test
+    void processTopmostModelTuple() {
+        DMNModelImpl model = mock(DMNModelImpl.class);
+        DMNModelImpl.ModelImportTuple topmostModelTuple = 
mock(DMNModelImpl.ModelImportTuple.class);
+        DMNModelImpl topmostModel = mock(DMNModelImpl.class);
+
+        DMNContext context = new DMNContextImpl();
+        context.set("Person Name", "Klaus");
+
+        InputData topmostInput = mock(InputData.class);
+        InputDataNodeImpl node = new InputDataNodeImpl(topmostInput);
+
+        when(topmostModelTuple.getModel()).thenReturn(topmostModel);
+        when(topmostModel.getInputs()).thenReturn(Set.of(node));
+        when(topmostInput.getName()).thenReturn("Person Name");
+        when(topmostModelTuple.getImportName()).thenReturn("parentModel");
+
+        String namespace = "test-namespace";
+        
when(topmostModelTuple.getModel().getNamespace()).thenReturn(namespace);
+
+        Map<String, Collection<List<String>>> importChainAliases = new 
HashMap<>();
+        List<String> chain = Arrays.asList("Child A", "parentModel");
+        importChainAliases.put(namespace, Collections.singletonList(chain));
+        when(model.getImportChainAliases()).thenReturn(importChainAliases);
+
+        DMNRuntimeUtils.processTopmostModelTuple(context, topmostModelTuple, 
model);
+
+        assertThat(context.get("Person Name")).isEqualTo("Klaus");
+    }
+
+    @Test
+    void updateContextMap() {
+        DMNModelImpl topmostModel = mock(DMNModelImpl.class);
+        String namespace = "namespace";
+        String topmostModelImportName = "parentModel";
+        String importingModelName = "Child A";
+        when(topmostModel.getNamespace()).thenReturn(namespace);
+        when(topmostModel.getName()).thenReturn(topmostModelImportName);
+
+        String inputName = "Person Name";
+        String storedValue = "Klaus";
+
+        Map<String, Collection<List<String>>> importChainAliases = new 
HashMap<>();
+        // Order is from bottom - i.e. executed model - to topmost - i.e. 
imported
+        List<String> chain = Arrays.asList(importingModelName, 
topmostModelImportName);
+        importChainAliases.put(namespace, Collections.singletonList(chain));
+
+        DMNContextImpl context = new DMNContextImpl();
+
+        DMNModelImpl.ModelImportTuple topmostModelTuple =
+                new DMNModelImpl.ModelImportTuple(topmostModelImportName, 
topmostModel);
+
+        DMNRuntimeUtils.updateContextMap(context, importChainAliases, 
topmostModelTuple, inputName, storedValue);
+
+        @SuppressWarnings("unchecked")
+        Map<String, Object> childA = (Map<String, Object>) 
context.get(importingModelName);
+        @SuppressWarnings("unchecked")
+        Map<String, Object> parentMap = (Map<String, Object>) 
childA.get(topmostModelImportName);
+        assertThat(parentMap).containsEntry(inputName, storedValue);
+    }
+
+    @Test
+    void populateContextWithInheritedData() {
+        DMNContext toPopulate = new DMNContextImpl();
+        toPopulate.set("Person Name", "Klaus");
+
+        List<String> chainedModels = List.of("Child A", "parentModel");
+        Map toStore = Map.of("Person Name", "Klaus");
+        String importName = "parentModel";
+        String topMostNamespace = 
"https://www.apache.org/customnamespace/_ae5b3c17-1ac3-4e1d-b4f9-2cf861aec6d9";;
+
+        DMNContext context = new DMNContextImpl();
+        Map<String, Object> parentModel = Map.of("Person Name", "Klaus");
+        Map<String, Object> childA = Map.of("parentModel", parentModel);
+        context.set("Person Name", "Klaus");
+        context.set("Child A", childA);
+
+        Map<String, Collection<List<String>>> importChainAliases = 
mock(Map.class);
+        
when(importChainAliases.get(topMostNamespace)).thenReturn(Collections.singletonList(chainedModels));
+
+        DMNRuntimeUtils.populateContextWithInheritedData(toPopulate, toStore, 
importName, topMostNamespace,
+                                                         importChainAliases);
+        assertThat(toPopulate).usingRecursiveComparison().isEqualTo(context);
+    }
+
+    @Test
+    void addNewMapToContext() {
+        DMNContext toPopulate = new DMNContextImpl();
+        String importName = "parentModel";
+        Map<String, Object> toStore = Map.of("Person Name", "Klaus");
+        String chainedModel = "chainedModel";
+        DMNRuntimeUtils.addNewMapToContext(toPopulate, importName, toStore, 
chainedModel);
+        
assertThat(toPopulate.get(chainedModel)).isNotNull().isInstanceOf(Map.class);
+        Map<String, Object> retrieved = (Map<String, Object>) 
toPopulate.get(chainedModel);
+        assertThat(retrieved).containsEntry(importName, toStore);
+    }
+
+    @Test
+    void addValueInsideMap() {
+        Map<String, Object> map = new HashMap<>();
+        DMNRuntimeUtils.addValueInsideMap(map, "Person Name", "Klaus");
+        assertThat(map).containsEntry("Person Name", "Klaus");
+
+        map = Collections.unmodifiableMap(new HashMap<>());
+        DMNRuntimeUtils.addValueInsideMap(map, "Person Name", "Klaus");
+        assertThat(map).isEmpty();
+    }
+
+    @Test
+    void getTopmostModel() {
+        DMNModelImpl importingModel = mock(DMNModelImpl.class);
+        DMNModelImpl importedModel = mock(DMNModelImpl.class);
+
+        when(importedModel.getNamespace())
+                
.thenReturn("http://www.trisotech.com/definitions/_ae5b3c17-1ac3-4e1d-b4f9-2cf861aec6d9";);
+        when(importedModel.getName())
+                .thenReturn("ParentModel");
+
+        when(importingModel.getImportAliasFor(importedModel.getNamespace(), 
importedModel.getName()))
+                .thenReturn(Optional.of("parentModel"));
+
+        DMNModelImpl.ModelImportTuple tuple =
+                new DMNModelImpl.ModelImportTuple("parentModel", 
importedModel);
+        Optional<Set<DMNModelImpl.ModelImportTuple>> optionalTopmostModels = 
Optional.of(Set.of(tuple));
+
+        
when(importingModel.getTopmostParents()).thenReturn(optionalTopmostModels);
+
+        Optional<Set<DMNModelImpl.ModelImportTuple>> topmostModel = 
DMNRuntimeUtils.getTopmostModel(importingModel);
+
+        assertThat(topmostModel).isPresent();
+        topmostModel.ifPresent(set ->
+                                       assertThat(set)
+                                               
.extracting(DMNModelImpl.ModelImportTuple::getImportName)
+                                               .containsOnly("parentModel")
+        );
+    }
+
+    @Test
+    void coerceSingleItemCollectionToValueWithCollectionValue() {
+        String nestedValue = "value";
+        Object value = Collections.singletonList("value");
+        DMNType type = mock(DMNType.class);
+        when(type.isCollection()).thenReturn(false);
+        Object retrieved = 
DMNRuntimeUtils.coerceSingleItemCollectionToValue(value, type);
+        assertThat(retrieved).isEqualTo(nestedValue);
+
+        when(type.isCollection()).thenReturn(true);
+        retrieved = DMNRuntimeUtils.coerceSingleItemCollectionToValue(value, 
type);
+        assertThat(retrieved).isEqualTo(value);
+
+        value = Arrays.asList("value", "value2");
+        when(type.isCollection()).thenReturn(false);
+        retrieved = DMNRuntimeUtils.coerceSingleItemCollectionToValue(value, 
type);
+        assertThat(retrieved).isEqualTo(value);
+
+        when(type.isCollection()).thenReturn(true);
+        retrieved = DMNRuntimeUtils.coerceSingleItemCollectionToValue(value, 
type);
+        assertThat(retrieved).isEqualTo(value);
+    }
+
+    @Test
+    void coerceSingleItemCollectionToValueWithSingleValue() {
+        Object value = "value";
+        DMNType type = mock(DMNType.class);
+        when(type.isCollection()).thenReturn(false);
+        Object retrieved = 
DMNRuntimeUtils.coerceSingleItemCollectionToValue(value, type);
+        assertThat(retrieved).isEqualTo(value);
+
+        when(type.isCollection()).thenReturn(true);
+        retrieved = DMNRuntimeUtils.coerceSingleItemCollectionToValue(value, 
type);
+        assertThat(retrieved).isEqualTo(value);
+    }
+
+    @Test
+    void getObjectString() {
+        StringBuilder builder = new StringBuilder();
+        IntStream.range(0, 10).forEach(i -> 
builder.append("ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
+        String retrieved = DMNRuntimeUtils.getObjectString(builder.toString());
+        assertThat(retrieved).contains("[string clipped after 50 chars, total 
length is 260]");
+
+        OverflowingObject overflowingObject = new 
OverflowingObject("OVERFLOWING OBJECT");
+        retrieved = DMNRuntimeUtils.getObjectString(overflowingObject);
+        assertThat(retrieved).isEqualTo("(_undefined_)");
+    }
+
+    @Test
+    void getDependencyIdentifierSameNamespace() {
+        String namespace = "test-namespace";
+        String callerId = "callerId";
+        String callerName = "callerName";
+        DMNNode callerNode = mock(DMNNode.class);
+        when(callerNode.getName()).thenReturn(callerName);
+        when(callerNode.getId()).thenReturn(callerId);
+        when(callerNode.getModelNamespace()).thenReturn(namespace);
+
+        String calledId = "calledId";
+        String calledName = "calledName";
+        DMNNode calledNode = mock(DMNNode.class);
+        when(calledNode.getName()).thenReturn(calledName);
+        when(calledNode.getId()).thenReturn(calledId);
+        when(calledNode.getModelNamespace()).thenReturn(namespace);
+        assertThat(DMNRuntimeUtils.getDependencyIdentifier(callerNode, 
calledNode)).isEqualTo(calledName);
+    }
+
+    @Test
+    void getDependencyIdentifierDifferentNamespace() {
+        String callerId = "callerId";
+        String callerName = "callerName";
+        String callerNamespace = "callerNamespace";
+        String alias = "alias";
+        Optional<String> importAlias = Optional.of(alias);
+        String calledId = "calledId";
+        String calledName = "calledName";
+        String calledNamespace = "calledNamespace";
+        String calledModelName = "calledModelName";
+
+        DMNNode callerNode = mock(DMNNode.class);
+        when(callerNode.getName()).thenReturn(callerName);
+        when(callerNode.getId()).thenReturn(callerId);
+        when(callerNode.getModelNamespace()).thenReturn(callerNamespace);
+        when(callerNode.getModelImportAliasFor(calledNamespace, 
calledModelName)).thenReturn(importAlias);
+
+        DMNNode calledNode = mock(DMNNode.class);
+        when(calledNode.getName()).thenReturn(calledName);
+        when(calledNode.getId()).thenReturn(calledId);
+        when(calledNode.getModelNamespace()).thenReturn(calledNamespace);
+        when(calledNode.getModelName()).thenReturn(calledModelName);
+
+        String expected = alias + "." + calledName;
+        assertThat(DMNRuntimeUtils.getDependencyIdentifier(callerNode, 
calledNode)).isEqualTo(expected);
+    }
+
+    @Test
+    void getDependencyIdentifierDifferentNamespaceWithoutAlias() {
+        String callerId = "callerId";
+        String callerName = "callerName";
+        String callerNamespace = "callerNamespace";
+        String calledId = "calledId";
+        String calledName = "calledName";
+        String calledNamespace = "calledNamespace";
+        String calledModelName = "calledModelName";
+
+        DMNNode callerNode = mock(DMNNode.class);
+        when(callerNode.getName()).thenReturn(callerName);
+        when(callerNode.getId()).thenReturn(callerId);
+        when(callerNode.getModelNamespace()).thenReturn(callerNamespace);
+        when(callerNode.getModelImportAliasFor(calledNamespace, 
calledModelName)).thenReturn(Optional.empty());
+
+        DMNNode calledNode = mock(DMNNode.class);
+        when(calledNode.getName()).thenReturn(calledName);
+        when(calledNode.getId()).thenReturn(calledId);
+        when(calledNode.getModelNamespace()).thenReturn(calledNamespace);
+        when(calledNode.getModelName()).thenReturn(calledModelName);
+
+        String expected = "{" + calledNamespace + "}" + "." + calledName;
+        assertThat(DMNRuntimeUtils.getDependencyIdentifier(callerNode, 
calledNode)).isEqualTo(expected);
+    }
+
+    @Test
+    void getPrefixedIdentifierWithAlias() {
+        String callerId = "callerId";
+        String callerName = "callerName";
+        String callerNamespace = "callerNamespace";
+        String alias = "alias";
+        Optional<String> importAlias = Optional.of(alias);
+        String calledId = "calledId";
+        String calledName = "calledName";
+        String calledNamespace = "calledNamespace";
+        String calledModelName = "calledModelName";
+
+        DMNNode callerNode = mock(DMNNode.class);
+        when(callerNode.getName()).thenReturn(callerName);
+        when(callerNode.getId()).thenReturn(callerId);
+        when(callerNode.getModelNamespace()).thenReturn(callerNamespace);
+        when(callerNode.getModelImportAliasFor(calledNamespace, 
calledModelName)).thenReturn(importAlias);
+
+        DMNNode calledNode = mock(DMNNode.class);
+        when(calledNode.getName()).thenReturn(calledName);
+        when(calledNode.getId()).thenReturn(calledId);
+        when(calledNode.getModelNamespace()).thenReturn(calledNamespace);
+        when(calledNode.getModelName()).thenReturn(calledModelName);
+
+        String expected = alias + "." + calledName;
+        assertThat(DMNRuntimeUtils.getPrefixedIdentifier(callerNode, 
calledNode)).isEqualTo(expected);
+    }
+
+    @Test
+    void getPrefixedIdentifierWithoutAlias() {
+        String callerId = "callerId";
+        String callerName = "callerName";
+        String callerNamespace = "callerNamespace";
+        String calledId = "calledId";
+        String calledName = "calledName";
+        String calledNamespace = "calledNamespace";
+        String calledModelName = "calledModelName";
+
+        DMNNode callerNode = mock(DMNNode.class);
+        when(callerNode.getName()).thenReturn(callerName);
+        when(callerNode.getId()).thenReturn(callerId);
+        when(callerNode.getModelNamespace()).thenReturn(callerNamespace);
+        when(callerNode.getModelImportAliasFor(calledNamespace, 
calledModelName)).thenReturn(Optional.empty());
+
+        DMNNode calledNode = mock(DMNNode.class);
+        when(calledNode.getName()).thenReturn(calledName);
+        when(calledNode.getId()).thenReturn(calledId);
+        when(calledNode.getModelNamespace()).thenReturn(calledNamespace);
+        when(calledNode.getModelName()).thenReturn(calledModelName);
+
+        String expected = "{" + calledNamespace + "}" + "." + calledName;
+        assertThat(DMNRuntimeUtils.getPrefixedIdentifier(callerNode, 
calledNode)).isEqualTo(expected);
+    }
+
+    @Test
+    void getIdentifier() {
+        String id = "id";
+        String name = "name";
+        DMNNode dmnNode = mock(DMNNode.class);
+        when(dmnNode.getName()).thenReturn(null);
+        when(dmnNode.getId()).thenReturn(id);
+        assertThat(DMNRuntimeUtils.getIdentifier(dmnNode)).isEqualTo(id);
+        when(dmnNode.getName()).thenReturn(name);
+        assertThat(DMNRuntimeUtils.getIdentifier(dmnNode)).isEqualTo(name);
+    }
+
+    private static class OverflowingObject {
+
+        String string;
+
+        public OverflowingObject(String string) {
+            this.string = string;
+        }
+
+        @Override
+        public String toString() {
+            return this.toString();
+        }
+    }
+}
\ No newline at end of file
diff --git 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/imports/ImportsTest.java 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/imports/ImportsTest.java
index dd92e6311c..243375e944 100644
--- 
a/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/imports/ImportsTest.java
+++ 
b/kie-dmn/kie-dmn-core/src/test/java/org/kie/dmn/core/imports/ImportsTest.java
@@ -21,6 +21,7 @@ package org.kie.dmn.core.imports;
 import java.math.BigDecimal;
 import java.util.Arrays;
 import java.util.Collections;
+import java.util.Map;
 import java.util.function.Function;
 
 import org.junit.jupiter.params.ParameterizedTest;
@@ -44,6 +45,97 @@ public class ImportsTest extends 
BaseInterpretedVsCompiledTest {
 
     public static final Logger LOG = 
LoggerFactory.getLogger(ImportsTest.class);
 
+    @ParameterizedTest
+    @MethodSource("params")
+    void importingModelsWithSameImportAndInputNameSimpleData(boolean 
useExecModelCompiler) {
+        init(useExecModelCompiler);
+        String basePath = 
"valid_models/DMNv1_6/imports/same_import_and_input_name_simple_data";
+        String dmnImporting = String.format("%s/ImportingModel.dmn", basePath);
+        String dmnImported = String.format("%s/ImportedModel.dmn", basePath);
+        final DMNRuntime runtime = 
DMNRuntimeUtil.createRuntimeWithAdditionalResources(dmnImporting,
+                                                                               
        this.getClass(),
+                                                                               
        dmnImported);
+
+        final DMNModel importedModel = 
runtime.getModel("https://kie.org/dmn/_EDBCAD2C-5119-462A-8ACA-7E32C18A7837";,
+                                                        
"DMN_C66F78A2-4BD7-4BB7-A200-4C61D82AAFBD");
+        assertThat(importedModel).isNotNull();
+        
assertThat(importedModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(importedModel.getMessages())).isFalse();
+
+        final DMNModel importingModel = 
runtime.getModel("https://kie.org/dmn/_054766E3-2098-4E7B-8F48-576B5373F4EE";,
+                                                         
"ImportingModelSimpleType");
+        assertThat(importingModel).isNotNull();
+        
assertThat(importingModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(importingModel.getMessages())).isFalse();
+
+        DMNContext context = runtime.newContext(); // old syntax
+        context.set("My Input", "this is my input");
+        context.set("CLASHING_NAME", mapOf(entry("CLASHING_NAME", 21)));
+
+        DMNResult evaluateAll = runtime.evaluateAll(importingModel, context);
+        
assertThat(evaluateAll.hasErrors()).as(DMNRuntimeUtil.formatMessages(evaluateAll.getMessages())).isFalse();
+
+        LOG.debug("{}", evaluateAll);
+        assertThat(evaluateAll.getDecisionResultByName("My 
Decision")).isNotNull();
+        assertThat(evaluateAll.getDecisionResultByName("My 
Decision").getResult()).isEqualTo("this is my input: 21");
+
+
+        context = runtime.newContext();
+        context.set("My Input", "this is my input");
+        context.set("CLASHING_NAME", 21);
+
+        evaluateAll = runtime.evaluateAll(importingModel, context);
+        
assertThat(evaluateAll.hasErrors()).as(DMNRuntimeUtil.formatMessages(evaluateAll.getMessages())).isFalse();
+
+        LOG.debug("{}", evaluateAll);
+        assertThat(evaluateAll.getDecisionResultByName("My 
Decision")).isNotNull();
+        assertThat(evaluateAll.getDecisionResultByName("My 
Decision").getResult()).isEqualTo("this is my input: 21");
+    }
+
+    @ParameterizedTest
+    @MethodSource("params")
+    void importingModelsWithSameImportAndInputNameComplexData(boolean 
useExecModelCompiler) {
+        init(useExecModelCompiler);
+        String basePath = 
"valid_models/DMNv1_6/imports/same_import_and_input_name_complex_data";
+        String dmnImporting = String.format("%s/ImportingModel.dmn", basePath);
+        String dmnImported = String.format("%s/ImportedModel.dmn", basePath);
+        final DMNRuntime runtime = 
DMNRuntimeUtil.createRuntimeWithAdditionalResources(dmnImporting,
+                                                                               
        this.getClass(),
+                                                                               
        dmnImported);
+
+        final DMNModel importedModel = 
runtime.getModel("https://kie.org/dmn/_EDBCAD2C-5119-462A-8ACA-7E32C18A78EE";,
+                                                        
"DMN_C66F78A2-4BD7-4BB7-A200-4C61D82AAFBD");
+        assertThat(importedModel).isNotNull();
+        
assertThat(importedModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(importedModel.getMessages())).isFalse();
+
+        final DMNModel importingModel = 
runtime.getModel("https://kie.org/dmn/_054766E3-2098-4E7B-8F48-576B5373F4EE";,
+                                                         
"ImportingModelComplexType");
+        assertThat(importingModel).isNotNull();
+        
assertThat(importingModel.hasErrors()).as(DMNRuntimeUtil.formatMessages(importingModel.getMessages())).isFalse();
+
+        DMNContext context = runtime.newContext(); // old syntax
+        context.set("My Input", "this is my input");
+        Map<String, Object> clashingNameComplexObject =  mapOf(entry("Complex 
Type Number", 21), entry("Complex Type String", "A string"));
+        context.set("CLASHING_NAME", mapOf(entry("CLASHING_NAME", 
clashingNameComplexObject)));
+
+        DMNResult evaluateAll = runtime.evaluateAll(importingModel, context);
+        
assertThat(evaluateAll.hasErrors()).as(DMNRuntimeUtil.formatMessages(evaluateAll.getMessages())).isFalse();
+
+        LOG.debug("{}", evaluateAll);
+        assertThat(evaluateAll.getDecisionResultByName("My 
Decision")).isNotNull();
+        assertThat(evaluateAll.getDecisionResultByName("My 
Decision").getResult()).isEqualTo("this is my input: 21");
+
+
+        context = runtime.newContext();
+        context.set("My Input", "this is my input");
+        context.set("CLASHING_NAME", mapOf(entry("Complex Type Number", 21), 
entry("Complex Type String", "A string")));
+
+        evaluateAll = runtime.evaluateAll(importingModel, context);
+        
assertThat(evaluateAll.hasErrors()).as(DMNRuntimeUtil.formatMessages(evaluateAll.getMessages())).isFalse();
+
+        LOG.debug("{}", evaluateAll);
+        assertThat(evaluateAll.getDecisionResultByName("My 
Decision")).isNotNull();
+        assertThat(evaluateAll.getDecisionResultByName("My 
Decision").getResult()).isEqualTo("this is my input: 21");
+    }
+
     @ParameterizedTest
     @MethodSource("params")
     void importingOverridedInputDataInInheritedDecision(boolean 
useExecModelCompiler) {
diff --git 
a/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_6/InvalidModelImportInputDataNameClash.dmn
 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_6/InvalidModelImportInputDataNameClash.dmn
new file mode 100644
index 0000000000..b857cfefde
--- /dev/null
+++ 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_6/InvalidModelImportInputDataNameClash.dmn
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~ 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.
+-->
+<definitions xmlns="https://www.omg.org/spec/DMN/20240513/MODEL/"; 
expressionLanguage="https://www.omg.org/spec/DMN/20240513/FEEL/"; 
namespace="https://kie.org/dmn/_CB218CE4-3C32-44EC-986B-2509FD2DB804"; 
id="_AE7757F5-3E9F-4306-9498-4F777597ECB1" 
name="DMN_F57A0F3D-06A9-4591-AF2F-D4A1CDB33D00" 
xmlns:included0="https://kie.org/dmn/_19017424-534B-4943-9DD3-3B5C71E64554"; 
xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/"; 
xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"; xmlns:di="htt [...]
+  <import id="_5B34C986-A41B-4530-88CE-2ECDC0328F69" name="CLASHING_NAME" 
importType="https://www.omg.org/spec/DMN/20240513/MODEL/"; 
namespace="http://www.trisotech.com/definitions/_ae5b3c17-1ac3-4e1d-b4f9-2cf861aec6d9";
 locationURI="./ParentModel.dmn" />
+  <decision name="InvalidDecision" id="_4570A6F0-A31F-456B-B73C-A82F207AB645">
+    <variable name="InvalidDecision" 
id="_CDD34C93-2771-4627-BEDB-0130B8AB6968" />
+    <informationRequirement id="_01C626D2-8CC3-4B2E-8647-17D5920AE8F1">
+      <requiredInput 
href="http://www.trisotech.com/definitions/_ae5b3c17-1ac3-4e1d-b4f9-2cf861aec6d9#_4f6c136c-8512-4d71-8bbf-7c9eb6e74063";
 />
+    </informationRequirement>
+    <literalExpression id="_1D8D0D0B-80F9-49D3-8C00-E9A82574413D" 
label="InvalidDecision" typeRef="string">
+      <text>"Hello"</text>
+    </literalExpression>
+  </decision>
+  <inputData name="CLASHING_NAME" id="_BF9A3642-A804-4175-99B1-702C099F26AC">
+    <variable name="CLASHING_NAME" id="_FF16066D-357E-4F89-A7FE-44E36941EAAA" 
typeRef="number" />
+  </inputData>
+  <dmndi:DMNDI>
+    <dmndi:DMNDiagram id="_11C7251C-0054-4571-BFBD-663E56C5989F" name="Default 
DRD" useAlternativeInputDataShape="false">
+      <di:extension>
+        <kie:ComponentsWidthsExtension>
+          <kie:ComponentWidths 
dmnElementRef="_1D8D0D0B-80F9-49D3-8C00-E9A82574413D">
+            <kie:width>190</kie:width>
+          </kie:ComponentWidths>
+        </kie:ComponentsWidthsExtension>
+      </di:extension>
+      <dmndi:DMNShape id="_61FD3C47-BBA8-460E-8E0A-8CE9A94EAA18" 
dmnElementRef="included0:_D93251BA-B455-4041-9148-4491E3FBFC76">
+        <dc:Bounds x="360" y="140" width="160" height="80" />
+      </dmndi:DMNShape>
+      <dmndi:DMNShape id="_76BC9E04-F772-4BCD-A564-B25673B1A189" 
dmnElementRef="_4570A6F0-A31F-456B-B73C-A82F207AB645" isCollapsed="false" 
isListedInputData="false">
+        <dc:Bounds x="600" y="140" width="160" height="80" />
+      </dmndi:DMNShape>
+      <dmndi:DMNEdge id="_BDE31C3B-6FE5-4A4B-9375-77D25DB4939D" 
dmnElementRef="_01C626D2-8CC3-4B2E-8647-17D5920AE8F1" 
sourceElement="_61FD3C47-BBA8-460E-8E0A-8CE9A94EAA18" 
targetElement="_76BC9E04-F772-4BCD-A564-B25673B1A189">
+        <di:waypoint x="440" y="180" />
+        <di:waypoint x="600" y="180" />
+      </dmndi:DMNEdge>
+    </dmndi:DMNDiagram>
+  </dmndi:DMNDI>
+</definitions>
diff --git 
a/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_6/ParentModel.dmn
 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_6/ParentModel.dmn
new file mode 100644
index 0000000000..54aba9c4a7
--- /dev/null
+++ 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/invalid_models/DMNv1_6/ParentModel.dmn
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<!--
+  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.
+  -->
+<definitions xmlns:semantic="https://www.omg.org/spec/DMN/20240513/MODEL/";
+                      
xmlns:dmn11="https://www.omg.org/spec/DMN/20230324/DMN15.xsd";
+                      xmlns:rss="http://purl.org/rss/2.0/"; 
+                      xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/"; 
+                      xmlns:trisofeed="http://trisotech.com/feed"; 
+                      
xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/";
+                      xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"; 
+                      
xmlns:triso="http://www.trisotech.com/2015/triso/modeling"; 
+                      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
+                      xmlns:feel="https://www.omg.org/spec/DMN/20240513/FEEL/";
+                      xmlns:trisodmn="http://www.trisotech.com/2016/triso/dmn"; 
 
+                      xmlns:tc="http://www.omg.org/spec/DMN/20160719/testcase"; 
 
+                      xmlns:drools="http://www.drools.org/kie/dmn/1.1";  
+                      xmlns="https://www.omg.org/spec/DMN/20240513/MODEL/";
+                      id="_ae5b3c17-1ac3-4e1d-b4f9-2cf861aec6d9" 
name="ParentModel"
+                      
namespace="http://www.trisotech.com/definitions/_ae5b3c17-1ac3-4e1d-b4f9-2cf861aec6d9";
 exporter="DMN Modeler" exporterVersion="6.2.4.2" triso:logoChoice="Default">
+    <inputData id="_4f6c136c-8512-4d71-8bbf-7c9eb6e74063" name="Person name">
+        <variable name="Person name" 
id="_46b6677b-4a26-4bca-9532-9a57dd55b8ec" typeRef="string"/>
+    </inputData>
+    <decision id="_f7fdaec4-d669-4797-b3b4-12b860de2eb5" name="Greet the 
Person" triso:useOutputTypeAsAnswer="false">
+        <variable name="Greet the Person" 
id="_85193e88-cb32-41da-9181-fb8e5450753a" typeRef="string"/>
+        <informationRequirement id="b1507384-44a9-4da7-8223-fa49ffa65410">
+            <requiredInput href="#_4f6c136c-8512-4d71-8bbf-7c9eb6e74063"/>
+        </informationRequirement>
+        <literalExpression typeRef="string" 
id="_429b0c63-31e0-4f79-b457-32f565167702" 
triso:expressionId="_28c34a9a-ebce-4ae4-ae8e-7eb062aa35d3">
+            <text>"Hello, "+Person name</text>
+        </literalExpression>
+    </decision>
+</definitions>
diff --git 
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_complex_data/ImportedModel.dmn
 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_complex_data/ImportedModel.dmn
new file mode 100644
index 0000000000..481b163b6e
--- /dev/null
+++ 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_complex_data/ImportedModel.dmn
@@ -0,0 +1,78 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+  -->
+<definitions xmlns="https://www.omg.org/spec/DMN/20230324/MODEL/"; 
xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/";
+             xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"; 
xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/"; 
xmlns:kie="https://kie.org/dmn/extensions/1.0";
+             
xmlns:included0="https://kie.org/dmn/_9F4C1A60-CF94-41F1-9B9F-8D26FF617670"; 
xmlns:included1="https://kie.org/dmn/_D9035A17-CCDF-4D29-9A4C-005D2BF5EBDC";
+             expressionLanguage="https://www.omg.org/spec/DMN/20230324/FEEL/"; 
namespace="https://kie.org/dmn/_EDBCAD2C-5119-462A-8ACA-7E32C18A78EE"; 
id="_AF126883-5B66-4112-A49C-FBC9D85E9F4D"
+             name="DMN_C66F78A2-4BD7-4BB7-A200-4C61D82AAFBD">
+  <itemDefinition id="_complexType" name="ComplexType">
+    <itemComponent id="_complexTypeNumber" name="Complex Type Number">
+      <typeRef>number</typeRef>
+    </itemComponent>
+    <itemComponent id="_complexTypeString" name="Complex Type String">
+      <typeRef>string</typeRef>
+    </itemComponent>
+  </itemDefinition>
+  <decision name="Decision A" id="_A98A15BF-9E3E-4DBC-874C-E722A1DF082D">
+    <variable id="_D723085A-ED61-4A87-8933-65B5281A567D" typeRef="number" 
name="Decision A"/>
+    <informationRequirement id="_D4E08E55-7035-420D-9B8F-74EE9EB6B092">
+      <requiredInput href="#_C299FD32-7DA5-44F5-959E-A23470AA4F3F"/>
+    </informationRequirement>
+    <literalExpression id="_28293632-A28E-47D8-B25E-A7C934ED4537" 
typeRef="number" label="Decision A">
+      <text>CLASHING_NAME.Complex Type Number</text>
+    </literalExpression>
+  </decision>
+  <inputData name="CLASHING_NAME" id="_C299FD32-7DA5-44F5-959E-A23470AA4F3F">
+    <variable name="CLASHING_NAME" id="_6497C8B9-F48A-42D4-B299-534C12E45190" 
typeRef="ComplexType"/>
+  </inputData>
+  <dmndi:DMNDI>
+    <dmndi:DMNDiagram id="_EC7829BB-AA43-4C41-8CBD-02799F8E5CA2" name="Default 
DRD" useAlternativeInputDataShape="false">
+      <di:extension>
+        <kie:ComponentsWidthsExtension>
+          <kie:ComponentWidths 
dmnElementRef="_C7A7A9AA-CB35-4A90-ACCA-BAC1835410AF">
+            <kie:width>190</kie:width>
+          </kie:ComponentWidths>
+          <kie:ComponentWidths 
dmnElementRef="_E706443A-D7B7-4E86-A984-423B02CE91C3">
+            <kie:width>190</kie:width>
+          </kie:ComponentWidths>
+          <kie:ComponentWidths 
dmnElementRef="_AF9208AE-A31D-48C7-953F-D409C5781C4D">
+            <kie:width>512</kie:width>
+          </kie:ComponentWidths>
+          <kie:ComponentWidths 
dmnElementRef="_28293632-A28E-47D8-B25E-A7C934ED4537">
+            <kie:width>190</kie:width>
+          </kie:ComponentWidths>
+        </kie:ComponentsWidthsExtension>
+      </di:extension>
+      <dmndi:DMNShape id="_E5978038-2A5F-4BE5-A5F8-83E41802AF47" 
dmnElementRef="_C299FD32-7DA5-44F5-959E-A23470AA4F3F" isCollapsed="false" 
isListedInputData="false">
+        <dc:Bounds x="160" y="260" width="160" height="80"/>
+      </dmndi:DMNShape>
+      <dmndi:DMNShape id="_B142BA3C-808B-4BF0-98F1-EF003063D1D9" 
dmnElementRef="included0:_333AB4CE-C1BC-49BD-84B8-E6A2339C9E8D">
+        <dc:Bounds x="460" y="180" width="160" height="80"/>
+      </dmndi:DMNShape>
+      <dmndi:DMNShape id="_7A990C14-71C7-4405-8EE3-9FCEA81B28B7" 
dmnElementRef="_A98A15BF-9E3E-4DBC-874C-E722A1DF082D" isCollapsed="false" 
isListedInputData="false">
+        <dc:Bounds x="-280" y="60" width="160" height="80"/>
+      </dmndi:DMNShape>
+      <dmndi:DMNEdge id="_101FB2F5-7F7E-45BC-A4E4-F80FC2CB898E-AUTO-TARGET" 
dmnElementRef="_D4E08E55-7035-420D-9B8F-74EE9EB6B092" 
sourceElement="_D7639B3F-D677-4B3E-BBA7-D6D1077782DC" 
targetElement="_7A990C14-71C7-4405-8EE3-9FCEA81B28B7">
+        <di:waypoint x="-200" y="300"/>
+        <di:waypoint x="-200" y="100"/>
+      </dmndi:DMNEdge>
+    </dmndi:DMNDiagram>
+  </dmndi:DMNDI>
+</definitions>
diff --git 
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_complex_data/ImportingModel.dmn
 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_complex_data/ImportingModel.dmn
new file mode 100644
index 0000000000..f3ae1e69b7
--- /dev/null
+++ 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_complex_data/ImportingModel.dmn
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+  -->
+<definitions xmlns="https://www.omg.org/spec/DMN/20230324/MODEL/"; 
xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/"; 
xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/";
+             xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/"; 
xmlns:kie="https://kie.org/dmn/extensions/1.0"; 
xmlns:included1="https://kie.org/dmn/_9B908A38-2808-4AA6-8387-5A0063159BFD";
+             
xmlns:included0="https://kie.org/dmn/_EDBCAD2C-5119-462A-8ACA-7E32C18A78EE"; 
expressionLanguage="https://www.omg.org/spec/DMN/20230324/FEEL/";
+             
namespace="https://kie.org/dmn/_054766E3-2098-4E7B-8F48-576B5373F4EE"; 
id="_EC6DEDC6-F33D-4058-8C6C-7FAF676BB0FF"
+             name="ImportingModelComplexType">
+  <import id="_903A7C44-32F0-4453-B0A6-77216FF872D2" name="CLASHING_NAME" 
importType="https://www.omg.org/spec/DMN/20230324/MODEL/"; 
namespace="https://kie.org/dmn/_EDBCAD2C-5119-462A-8ACA-7E32C18A78EE"; 
locationURI="./ImportedModel.dmn" />
+  <decision name="My Decision" id="_27D3FDE5-2DF4-4BCD-8224-4FB16CC6731E">
+    <variable id="_98824C72-1DAC-4C04-84DF-8908AD40910F" name="My Decision" 
typeRef="string" />
+    <informationRequirement id="_46788B87-3143-4D6C-B05C-7C0B6B314256">
+      <requiredInput href="#_5BF60A32-996A-49EE-A041-08D0F886CB08" />
+    </informationRequirement>
+    <informationRequirement id="_7F9763EA-687A-4841-AFF5-03DA1DE2E099">
+      <requiredDecision 
href="https://kie.org/dmn/_EDBCAD2C-5119-462A-8ACA-7E32C18A78EE#_A98A15BF-9E3E-4DBC-874C-E722A1DF082D";
 />
+    </informationRequirement>
+    <literalExpression id="_1F1BC8D3-853D-48CA-80B3-4A65A87A3F76" 
typeRef="string" label="My Decision">
+      <text>My Input + &quot;: &quot; + string(CLASHING_NAME.Decision A) 
</text>
+    </literalExpression>
+  </decision>
+  <inputData name="My Input" id="_5BF60A32-996A-49EE-A041-08D0F886CB08">
+    <variable name="My Input" id="_5868E018-1C72-45A8-9CF0-665E42016411" 
typeRef="string" />
+  </inputData>
+  <dmndi:DMNDI>
+    <dmndi:DMNDiagram id="_A8B37C28-E077-4160-A9D0-A6BF5B374D23" name="Default 
DRD" useAlternativeInputDataShape="false">
+      <di:extension>
+        <kie:ComponentsWidthsExtension>
+          <kie:ComponentWidths 
dmnElementRef="_1F1BC8D3-853D-48CA-80B3-4A65A87A3F76">
+            <kie:width>434</kie:width>
+          </kie:ComponentWidths>
+        </kie:ComponentsWidthsExtension>
+      </di:extension>
+      <dmndi:DMNShape id="_A6171152-8E16-44D0-BCF5-87C0BCD7BA54" 
dmnElementRef="_5BF60A32-996A-49EE-A041-08D0F886CB08" isCollapsed="false" 
isListedInputData="false">
+        <dc:Bounds x="220" y="320" width="160" height="80" />
+      </dmndi:DMNShape>
+      <dmndi:DMNShape id="_5964FAD5-5E3E-402A-AE78-8D20114FD241" 
dmnElementRef="_27D3FDE5-2DF4-4BCD-8224-4FB16CC6731E" isCollapsed="false" 
isListedInputData="false">
+        <dc:Bounds x="220" y="120" width="160" height="80" />
+      </dmndi:DMNShape>
+      <dmndi:DMNShape id="_326986E1-A1CE-4A7A-94D1-8815908E7BC3" 
dmnElementRef="included0:_5DD887C6-45B9-4EE7-850F-C50FF1579258">
+        <dc:Bounds x="500" y="200" width="160" height="80" />
+      </dmndi:DMNShape>
+      <dmndi:DMNEdge id="_5B9A45AD-F65D-4445-8D88-9250C012B4CA-AUTO-TARGET" 
dmnElementRef="_46788B87-3143-4D6C-B05C-7C0B6B314256" 
sourceElement="_A6171152-8E16-44D0-BCF5-87C0BCD7BA54" 
targetElement="_5964FAD5-5E3E-402A-AE78-8D20114FD241">
+        <di:waypoint x="300" y="360" />
+        <di:waypoint x="300" y="160" />
+      </dmndi:DMNEdge>
+      <dmndi:DMNEdge id="_31AE5339-F989-4241-80CD-8988B356E162" 
dmnElementRef="_7F9763EA-687A-4841-AFF5-03DA1DE2E099" 
sourceElement="_326986E1-A1CE-4A7A-94D1-8815908E7BC3" 
targetElement="_5964FAD5-5E3E-402A-AE78-8D20114FD241">
+        <di:waypoint x="580" y="240" />
+        <di:waypoint x="380" y="160" />
+      </dmndi:DMNEdge>
+    </dmndi:DMNDiagram>
+  </dmndi:DMNDI>
+</definitions>
diff --git 
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_simple_data/ImportedModel.dmn
 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_simple_data/ImportedModel.dmn
new file mode 100644
index 0000000000..6200a4f631
--- /dev/null
+++ 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_simple_data/ImportedModel.dmn
@@ -0,0 +1,70 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+  -->
+<definitions xmlns="https://www.omg.org/spec/DMN/20230324/MODEL/"; 
xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/";
+             xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/"; 
xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/"; 
xmlns:kie="https://kie.org/dmn/extensions/1.0";
+             
xmlns:included0="https://kie.org/dmn/_9F4C1A60-CF94-41F1-9B9F-8D26FF617670"; 
xmlns:included1="https://kie.org/dmn/_D9035A17-CCDF-4D29-9A4C-005D2BF5EBDC";
+             expressionLanguage="https://www.omg.org/spec/DMN/20230324/FEEL/"; 
namespace="https://kie.org/dmn/_EDBCAD2C-5119-462A-8ACA-7E32C18A7837"; 
id="_AF126883-5B66-4112-A49C-FBC9D85E9F4D"
+             name="DMN_C66F78A2-4BD7-4BB7-A200-4C61D82AAFBD">
+  <decision name="Decision A" id="_A98A15BF-9E3E-4DBC-874C-E722A1DF082D">
+    <variable id="_D723085A-ED61-4A87-8933-65B5281A567D" typeRef="number" 
name="Decision A" />
+    <informationRequirement id="_D4E08E55-7035-420D-9B8F-74EE9EB6B092">
+      <requiredInput href="#_C299FD32-7DA5-44F5-959E-A23470AA4F3F" />
+    </informationRequirement>
+    <literalExpression id="_28293632-A28E-47D8-B25E-A7C934ED4537" 
typeRef="number" label="Decision A">
+      <text>CLASHING_NAME</text>
+    </literalExpression>
+  </decision>
+  <inputData name="CLASHING_NAME" id="_C299FD32-7DA5-44F5-959E-A23470AA4F3F">
+    <variable name="CLASHING_NAME" id="_6497C8B9-F48A-42D4-B299-534C12E45190" 
typeRef="number" />
+  </inputData>
+  <dmndi:DMNDI>
+    <dmndi:DMNDiagram id="_EC7829BB-AA43-4C41-8CBD-02799F8E5CA2" name="Default 
DRD" useAlternativeInputDataShape="false">
+      <di:extension>
+        <kie:ComponentsWidthsExtension>
+          <kie:ComponentWidths 
dmnElementRef="_C7A7A9AA-CB35-4A90-ACCA-BAC1835410AF">
+            <kie:width>190</kie:width>
+          </kie:ComponentWidths>
+          <kie:ComponentWidths 
dmnElementRef="_E706443A-D7B7-4E86-A984-423B02CE91C3">
+            <kie:width>190</kie:width>
+          </kie:ComponentWidths>
+          <kie:ComponentWidths 
dmnElementRef="_AF9208AE-A31D-48C7-953F-D409C5781C4D">
+            <kie:width>512</kie:width>
+          </kie:ComponentWidths>
+          <kie:ComponentWidths 
dmnElementRef="_28293632-A28E-47D8-B25E-A7C934ED4537">
+            <kie:width>190</kie:width>
+          </kie:ComponentWidths>
+        </kie:ComponentsWidthsExtension>
+      </di:extension>
+      <dmndi:DMNShape id="_E5978038-2A5F-4BE5-A5F8-83E41802AF47" 
dmnElementRef="_C299FD32-7DA5-44F5-959E-A23470AA4F3F" isCollapsed="false" 
isListedInputData="false">
+        <dc:Bounds x="160" y="260" width="160" height="80" />
+      </dmndi:DMNShape>
+      <dmndi:DMNShape id="_B142BA3C-808B-4BF0-98F1-EF003063D1D9" 
dmnElementRef="included0:_333AB4CE-C1BC-49BD-84B8-E6A2339C9E8D">
+        <dc:Bounds x="460" y="180" width="160" height="80" />
+      </dmndi:DMNShape>
+      <dmndi:DMNShape id="_7A990C14-71C7-4405-8EE3-9FCEA81B28B7" 
dmnElementRef="_A98A15BF-9E3E-4DBC-874C-E722A1DF082D" isCollapsed="false" 
isListedInputData="false">
+        <dc:Bounds x="-280" y="60" width="160" height="80" />
+      </dmndi:DMNShape>
+      <dmndi:DMNEdge id="_101FB2F5-7F7E-45BC-A4E4-F80FC2CB898E-AUTO-TARGET" 
dmnElementRef="_D4E08E55-7035-420D-9B8F-74EE9EB6B092" 
sourceElement="_D7639B3F-D677-4B3E-BBA7-D6D1077782DC" 
targetElement="_7A990C14-71C7-4405-8EE3-9FCEA81B28B7">
+        <di:waypoint x="-200" y="300" />
+        <di:waypoint x="-200" y="100" />
+      </dmndi:DMNEdge>
+    </dmndi:DMNDiagram>
+  </dmndi:DMNDI>
+</definitions>
diff --git 
a/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_simple_data/ImportingModel.dmn
 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_simple_data/ImportingModel.dmn
new file mode 100644
index 0000000000..e3128f06f7
--- /dev/null
+++ 
b/kie-dmn/kie-dmn-test-resources/src/test/resources/valid_models/DMNv1_6/imports/same_import_and_input_name_simple_data/ImportingModel.dmn
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  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.
+  -->
+<definitions xmlns="https://www.omg.org/spec/DMN/20230324/MODEL/"; 
xmlns:dmndi="https://www.omg.org/spec/DMN/20230324/DMNDI/"; 
xmlns:dc="http://www.omg.org/spec/DMN/20180521/DC/";
+             xmlns:di="http://www.omg.org/spec/DMN/20180521/DI/"; 
xmlns:kie="https://kie.org/dmn/extensions/1.0"; 
xmlns:included1="https://kie.org/dmn/_9B908A38-2808-4AA6-8387-5A0063159BFD";
+             
xmlns:included0="https://kie.org/dmn/_EDBCAD2C-5119-462A-8ACA-7E32C18A7837"; 
expressionLanguage="https://www.omg.org/spec/DMN/20230324/FEEL/";
+             
namespace="https://kie.org/dmn/_054766E3-2098-4E7B-8F48-576B5373F4EE"; 
id="_EC6DEDC6-F33D-4058-8C6C-7FAF676BB0FF"
+             name="ImportingModelSimpleType">
+  <import id="_903A7C44-32F0-4453-B0A6-77216FF872D2" name="CLASHING_NAME" 
importType="https://www.omg.org/spec/DMN/20230324/MODEL/"; 
namespace="https://kie.org/dmn/_EDBCAD2C-5119-462A-8ACA-7E32C18A7837"; 
locationURI="./ImportedModel.dmn" />
+  <decision name="My Decision" id="_27D3FDE5-2DF4-4BCD-8224-4FB16CC6731E">
+    <variable id="_98824C72-1DAC-4C04-84DF-8908AD40910F" name="My Decision" 
typeRef="string" />
+    <informationRequirement id="_46788B87-3143-4D6C-B05C-7C0B6B314256">
+      <requiredInput href="#_5BF60A32-996A-49EE-A041-08D0F886CB08" />
+    </informationRequirement>
+    <informationRequirement id="_7F9763EA-687A-4841-AFF5-03DA1DE2E099">
+      <requiredDecision 
href="https://kie.org/dmn/_EDBCAD2C-5119-462A-8ACA-7E32C18A7837#_A98A15BF-9E3E-4DBC-874C-E722A1DF082D";
 />
+    </informationRequirement>
+    <literalExpression id="_1F1BC8D3-853D-48CA-80B3-4A65A87A3F76" 
typeRef="string" label="My Decision">
+      <text>My Input + &quot;: &quot; + string(CLASHING_NAME.Decision A) 
</text>
+    </literalExpression>
+  </decision>
+  <inputData name="My Input" id="_5BF60A32-996A-49EE-A041-08D0F886CB08">
+    <variable name="My Input" id="_5868E018-1C72-45A8-9CF0-665E42016411" 
typeRef="string" />
+  </inputData>
+  <dmndi:DMNDI>
+    <dmndi:DMNDiagram id="_A8B37C28-E077-4160-A9D0-A6BF5B374D23" name="Default 
DRD" useAlternativeInputDataShape="false">
+      <di:extension>
+        <kie:ComponentsWidthsExtension>
+          <kie:ComponentWidths 
dmnElementRef="_1F1BC8D3-853D-48CA-80B3-4A65A87A3F76">
+            <kie:width>434</kie:width>
+          </kie:ComponentWidths>
+        </kie:ComponentsWidthsExtension>
+      </di:extension>
+      <dmndi:DMNShape id="_A6171152-8E16-44D0-BCF5-87C0BCD7BA54" 
dmnElementRef="_5BF60A32-996A-49EE-A041-08D0F886CB08" isCollapsed="false" 
isListedInputData="false">
+        <dc:Bounds x="220" y="320" width="160" height="80" />
+      </dmndi:DMNShape>
+      <dmndi:DMNShape id="_5964FAD5-5E3E-402A-AE78-8D20114FD241" 
dmnElementRef="_27D3FDE5-2DF4-4BCD-8224-4FB16CC6731E" isCollapsed="false" 
isListedInputData="false">
+        <dc:Bounds x="220" y="120" width="160" height="80" />
+      </dmndi:DMNShape>
+      <dmndi:DMNShape id="_326986E1-A1CE-4A7A-94D1-8815908E7BC3" 
dmnElementRef="included0:_5DD887C6-45B9-4EE7-850F-C50FF1579258">
+        <dc:Bounds x="500" y="200" width="160" height="80" />
+      </dmndi:DMNShape>
+      <dmndi:DMNEdge id="_5B9A45AD-F65D-4445-8D88-9250C012B4CA-AUTO-TARGET" 
dmnElementRef="_46788B87-3143-4D6C-B05C-7C0B6B314256" 
sourceElement="_A6171152-8E16-44D0-BCF5-87C0BCD7BA54" 
targetElement="_5964FAD5-5E3E-402A-AE78-8D20114FD241">
+        <di:waypoint x="300" y="360" />
+        <di:waypoint x="300" y="160" />
+      </dmndi:DMNEdge>
+      <dmndi:DMNEdge id="_31AE5339-F989-4241-80CD-8988B356E162" 
dmnElementRef="_7F9763EA-687A-4841-AFF5-03DA1DE2E099" 
sourceElement="_326986E1-A1CE-4A7A-94D1-8815908E7BC3" 
targetElement="_5964FAD5-5E3E-402A-AE78-8D20114FD241">
+        <di:waypoint x="580" y="240" />
+        <di:waypoint x="380" y="160" />
+      </dmndi:DMNEdge>
+    </dmndi:DMNDiagram>
+  </dmndi:DMNDI>
+</definitions>
diff --git 
a/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/ValidatorTest.java
 
b/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/ValidatorTest.java
index 997f5346c1..6f15423230 100644
--- 
a/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/ValidatorTest.java
+++ 
b/kie-dmn/kie-dmn-validation/src/test/java/org/kie/dmn/validation/ValidatorTest.java
@@ -22,10 +22,12 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStreamReader;
 import java.io.Reader;
+import java.math.BigDecimal;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.nio.file.Files;
 import java.nio.file.Path;
+import java.util.Arrays;
 import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
@@ -39,12 +41,16 @@ import org.drools.io.ClassPathResource;
 import org.drools.io.FileSystemResource;
 import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.MethodSource;
 import org.kie.api.builder.Message;
 import org.kie.api.builder.Message.Level;
 import org.kie.api.io.Resource;
+import org.kie.dmn.api.core.DMNContext;
 import org.kie.dmn.api.core.DMNMessage;
 import org.kie.dmn.api.core.DMNMessageType;
 import org.kie.dmn.api.core.DMNModel;
+import org.kie.dmn.api.core.DMNResult;
 import org.kie.dmn.api.core.DMNRuntime;
 import org.kie.dmn.api.marshalling.DMNMarshaller;
 import org.kie.dmn.backend.marshalling.v1x.DMNMarshallerFactory;
@@ -63,6 +69,8 @@ import org.slf4j.LoggerFactory;
 
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.fail;
+import static org.kie.dmn.core.util.DynamicTypeUtils.entry;
+import static org.kie.dmn.core.util.DynamicTypeUtils.mapOf;
 import static 
org.kie.dmn.validation.DMNValidator.Validation.VALIDATE_COMPILATION;
 import static org.kie.dmn.validation.DMNValidator.Validation.VALIDATE_MODEL;
 import static org.kie.dmn.validation.DMNValidator.Validation.VALIDATE_SCHEMA;
@@ -608,6 +616,42 @@ class ValidatorTest extends AbstractValidatorTest {
         }
     }
 
+    @Test
+    void 
validateValidModelsWithClashingInheritedImportAndInputNameSimpleData() {
+        String basePath = 
"valid_models/DMNv1_6/imports/same_import_and_input_name_simple_data";
+        String dmnImporting = String.format("%s/ImportingModel.dmn", basePath);
+        String dmnImported = String.format("%s/ImportedModel.dmn", basePath);
+        String[] modelFiles = new String[]{dmnImporting, dmnImported};
+        Resource[] resources = 
Arrays.stream(modelFiles).map(ClassPathResource::new).toArray(Resource[]::new);
+        List<DMNMessage> retrieved = validatorBuilder.theseModels(resources);
+        assertThat(retrieved).isNotNull().isEmpty();
+    }
+
+    @Test
+    void 
validateValidModelsWithClashingInheritedImportAndInputNameComplexData() {
+        String basePath = 
"valid_models/DMNv1_6/imports/same_import_and_input_name_complex_data";
+        String dmnImporting = String.format("%s/ImportingModel.dmn", basePath);
+        String dmnImported = String.format("%s/ImportedModel.dmn", basePath);
+        String[] modelFiles = new String[]{dmnImporting, dmnImported};
+        Resource[] resources = 
Arrays.stream(modelFiles).map(ClassPathResource::new).toArray(Resource[]::new);
+        List<DMNMessage> retrieved = validatorBuilder.theseModels(resources);
+        assertThat(retrieved).isNotNull().isEmpty();
+    }
+
+    @Test
+    void validateInvalidModelsWithSameImportAndInputName() {
+        String basePath = "invalid_models/DMNv1_6";
+        String dmnImporting = 
String.format("%s/InvalidModelImportInputDataNameClash.dmn", basePath);
+        String dmnImported = String.format("%s/ParentModel.dmn", basePath);
+        Resource importingResource = new ClassPathResource(dmnImporting);
+        Resource importedResource = new ClassPathResource(dmnImported);
+        List<DMNMessage> retrieved = 
validatorBuilder.theseModels(importingResource, importedResource);
+        assertThat(retrieved).isNotNull()
+                .hasSize(3) // There are other two messages
+                .anyMatch(dmnMessage -> 
dmnMessage.getLevel().equals(Message.Level.ERROR))
+                .anyMatch(dmnMessage -> dmnMessage.getText().contains("The 
referenced name is not unique with its scope"));
+    }
+
     @Test
     void validateInvalidNamespaceModels() {
         String modelFilePath = 
"invalid_models/DMNv1_5/DMN-invalid-namespaces.dmn";


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to