Exemplo n.º 1
0
        public static ISet <IVariable> FindAllVariables(IRelationDomain domain, ISet <IVariable> bindedVariables)
        {
            ISet <IVariable> result = new HashSet <IVariable>();

            result.Add(domain.RootVariable);
            bindedVariables.Add(domain.RootVariable);
            foreach (IPropertyTemplateItem prop in FindAllPropertyTemplates(domain))
            {
                if (prop.Value is IVariableExp)
                {
                    IVariableExp cast = (IVariableExp)prop.Value;
                    result.Add(cast.ReferredVariable);
                    bindedVariables.Add(cast.ReferredVariable);
                }
                else if (prop.Value is IObjectTemplateExp)
                {
                    IObjectTemplateExp cast = (IObjectTemplateExp)prop.Value;
                    result.Add(cast.BindsTo);
                    bindedVariables.Add(cast.BindsTo);
                }
                else if (prop.Value is CSharpOpaqueExpression)
                {
                    CSharpOpaqueExpression cast = (CSharpOpaqueExpression)prop.Value;
                    result.UnionWith(cast.BindsTo);
                }
            }

            return(result);
        }
Exemplo n.º 2
0
 public static ISet <IVariable> FindBindedVariables(IPropertyTemplateItem prop)
 {
     if (!prop.ReferredProperty.isMany())
     {
         IObjectTemplateExp nonManyPropObjectTemplate = prop.Value as IObjectTemplateExp;
         if (nonManyPropObjectTemplate != null)
         {
             return(new HashSet <IVariable>()
             {
                 nonManyPropObjectTemplate.BindsTo
             });
         }
         else
         {
             IVariableExp nonManyPropVar = prop.Value as IVariableExp;
             if (nonManyPropVar != null)
             {
                 return(new HashSet <IVariable>()
                 {
                     nonManyPropVar.ReferredVariable
                 });
             }
             else
             {
                 CSharpOpaqueExpression cast = prop.Value as CSharpOpaqueExpression;
                 if (cast != null)
                 {
                     return(new HashSet <IVariable>(cast.BindsTo));
                 }
             }
         }
     }
     return(new HashSet <IVariable>());
 }
Exemplo n.º 3
0
        public static List <IObjectTemplateExp> FindAllObjectTemplates(IObjectTemplateExp template)
        {
            List <IObjectTemplateExp> result = new List <IObjectTemplateExp>();

            FindAllObjectTemplates(template, result);
            return(result);
        }
 /// <summary>
 /// Adds the given element to the collection
 /// </summary>
 /// <param name="item">The item to add</param>
 public override void Add(IModelElement item)
 {
     if ((this._parent.ObjContainer == null))
     {
         IObjectTemplateExp objContainerCasted = item.As <IObjectTemplateExp>();
         if ((objContainerCasted != null))
         {
             this._parent.ObjContainer = objContainerCasted;
             return;
         }
     }
     if ((this._parent.ReferredProperty == null))
     {
         IProperty referredPropertyCasted = item.As <IProperty>();
         if ((referredPropertyCasted != null))
         {
             this._parent.ReferredProperty = referredPropertyCasted;
             return;
         }
     }
     if ((this._parent.Value == null))
     {
         IOclExpression valueCasted = item.As <IOclExpression>();
         if ((valueCasted != null))
         {
             this._parent.Value = valueCasted;
             return;
         }
     }
 }
Exemplo n.º 5
0
        public static List <IObjectTemplateExp> FindAllObjectTemplates(IRelationDomain domain)
        {
            IObjectTemplateExp domainTemplate = domain.Pattern?.TemplateExpression as IObjectTemplateExp;

            if (domainTemplate != null)
            {
                return(FindAllObjectTemplates(domainTemplate));
            }
            return(new List <IObjectTemplateExp>());
        }
Exemplo n.º 6
0
 private static void FindAllObjectTemplates(IObjectTemplateExp template, ICollection <IObjectTemplateExp> foundSoFar)
 {
     foundSoFar.Add(template);
     foreach (IObjectTemplateExp subTemplate in template.Part.Select(prop => prop.Value).OfType <IObjectTemplateExp>().Where(t => !foundSoFar.Contains(t)))
     {
         foreach (IObjectTemplateExp res in FindAllObjectTemplates(subTemplate))
         {
             foundSoFar.Add(res);
         }
     }
 }
Exemplo n.º 7
0
        private static void AnalyzeObjectTemplateExpression(IObjectTemplateExp objectTemplateExp, DomainVariablesBindingsResult currentResult, bool enforce, ISet <IObjectTemplateExp> analyzedSoFar = null)
        {
            if (analyzedSoFar == null)
            {
                analyzedSoFar = new HashSet <IObjectTemplateExp>();
            }

            if (!analyzedSoFar.Contains(objectTemplateExp))
            {
                analyzedSoFar.Add(objectTemplateExp);
                if (!objectTemplateExp.IsAntiTemplate())
                {
                    currentResult.VariablesItCanBind.Add(objectTemplateExp.BindsTo);
                }
                foreach (IPropertyTemplateItem propertyTemplateItem in objectTemplateExp.Part)
                {
                    if (propertyTemplateItem.Value is IObjectTemplateExp)
                    {
                        IObjectTemplateExp casted = (IObjectTemplateExp)propertyTemplateItem.Value;
                        AnalyzeObjectTemplateExpression(casted, currentResult, enforce, analyzedSoFar);
                    }
                    else if (propertyTemplateItem.Value is IVariableExp)
                    {
                        IVariableExp casted = (IVariableExp)propertyTemplateItem.Value;
                        if (enforce)
                        {
                            if (!currentResult.IPropertyTemplateItemToVariablesRequired.ContainsKey(propertyTemplateItem))
                            {
                                currentResult.IPropertyTemplateItemToVariablesRequired[propertyTemplateItem] = new HashSet <IVariable>();
                            }
                            currentResult.IPropertyTemplateItemToVariablesRequired[propertyTemplateItem].Add(casted.ReferredVariable);
                        }
                        else
                        {
                            currentResult.VariablesItCanBind.Add(casted.ReferredVariable);
                        }
                    }
                    else if (propertyTemplateItem.Value is CSharpOpaqueExpression)
                    {
                        CSharpOpaqueExpression casted = (CSharpOpaqueExpression)propertyTemplateItem.Value;
                        if (!currentResult.IPropertyTemplateItemToVariablesRequired.ContainsKey(propertyTemplateItem))
                        {
                            currentResult.IPropertyTemplateItemToVariablesRequired[propertyTemplateItem] = new HashSet <IVariable>();
                        }
                        currentResult.IPropertyTemplateItemToVariablesRequired[propertyTemplateItem].UnionWith(casted.BindsTo);
                    }
                }
            }
        }
        /// <summary>
        /// Gets called when the parent model element of the current model element changes
        /// </summary>
        /// <param name="oldParent">The old parent model element</param>
        /// <param name="newParent">The new parent model element</param>
        protected override void OnParentChanged(IModelElement newParent, IModelElement oldParent)
        {
            IObjectTemplateExp oldObjContainer = ModelHelper.CastAs <IObjectTemplateExp>(oldParent);
            IObjectTemplateExp newObjContainer = ModelHelper.CastAs <IObjectTemplateExp>(newParent);

            if ((oldObjContainer != null))
            {
                oldObjContainer.Part.Remove(this);
            }
            if ((newObjContainer != null))
            {
                newObjContainer.Part.Add(this);
            }
            ValueChangedEventArgs e = new ValueChangedEventArgs(oldObjContainer, newObjContainer);

            this.OnObjContainerChanged(e);
            this.OnPropertyChanged("ObjContainer", e);
        }
 private void GenerateString(IObjectTemplateExp template, bool start = false)
 {
     if (template.BindsTo != null)
     {
         Write(template.BindsTo.Name + ":" + template.BindsTo.Type.GetRealTypeName());
         WriteLine(" {");
         PushIndent();
         foreach (IPropertyTemplateItem prop in template.Part)
         {
             Write(prop.ReferredProperty.Name + " = ");
             GenerateString(prop.Value);
             if (template.Part.Last() != prop)
             {
                 WriteLine(",");
             }
         }
         PopIndent();
         WriteLine(start ? "};" : "}");
     }
 }
        public static string GenerateConstructTarget(IRelationDomain targetDomain, bool useMetamodelInterface)
        {
            StringBuilder stringBuilder = new StringBuilder();
            ISet <string> postPonedSets = new HashSet <string>();

            List <IObjectTemplateExp> objectTemplates = QvtModelExplorer.FindAllObjectTemplates(targetDomain).Where(o => !o.IsAntiTemplate()).ToList();

            foreach (IObjectTemplateExp objectTemplate in objectTemplates)
            {
                IVariable variable = objectTemplate.BindsTo;
                stringBuilder.AppendLine("\n// Contructing " + variable.Name);

                foreach (IPropertyTemplateItem propertyTemplateItem in objectTemplate.Part)
                {
                    string             setStatement           = GenerateSetValue(propertyTemplateItem, variable.Name, (IRelation)targetDomain.Rule, useMetamodelInterface);
                    IVariableExp       targetVariableValue    = propertyTemplateItem.Value as IVariableExp;
                    IObjectTemplateExp targetObjTemplateValue = objectTemplates.FirstOrDefault(o => o.BindsTo == targetVariableValue?.ReferredVariable);
                    bool ok = targetObjTemplateValue == null || objectTemplates.IndexOf(targetObjTemplateValue) < objectTemplates.IndexOf(objectTemplate);

                    if (ok)
                    {
                        stringBuilder.AppendLine(setStatement);
                    }
                    else
                    {
                        postPonedSets.Add(setStatement);
                    }
                }
            }
            if (!postPonedSets.IsNullOrEmpty())
            {
                stringBuilder.AppendLine("// Setting cycling properties");
                foreach (string setStatement in postPonedSets)
                {
                    stringBuilder.AppendLine(setStatement);
                }
            }
            return(stringBuilder.ToString());
        }
Exemplo n.º 11
0
 public static bool IsAntiTemplate(this IObjectTemplateExp objectTemplateExp)
 {
     return(allValues.ContainsKey(objectTemplateExp) && allValues[objectTemplateExp]);
 }
Exemplo n.º 12
0
 public static void SetAntiTemplate(this IObjectTemplateExp objectTemplateExp, bool value)
 {
     allValues[objectTemplateExp] = value;
 }
        public static string GenerateDomainCheckMethodContent(IRelationDomain sourceDomain, ISet <IVariable> variablesBindedSoFar, DomainVariablesBindingsResult analysis, List <IObjectTemplateExp> remaining = null, StringBuilder stringBuilder = null, ISet <IPropertyTemplateItem> postPonedPropertiesToCheck = null)
        {
            if (remaining == null)
            {
                remaining = QvtModelExplorer.FindAllObjectTemplates(sourceDomain).Where(o => !o.IsAntiTemplate()).ToList();
            }
            if (stringBuilder == null)
            {
                stringBuilder = new StringBuilder();
            }
            if (postPonedPropertiesToCheck == null)
            {
                postPonedPropertiesToCheck = new HashSet <IPropertyTemplateItem>();
            }

            if (remaining.Count > 0)
            {
                IObjectTemplateExp current = remaining[0];
                remaining.RemoveAt(0);
                string currentVariableName = current.BindsTo.Name;
                variablesBindedSoFar.Add(current.BindsTo);

                // Generate conditional for the object template
                stringBuilder.AppendLine("if (" + currentVariableName + " != null) {");

                // Generate bindings for each non-many free variables
                ISet <IPropertyTemplateItem> managedProps = new HashSet <IPropertyTemplateItem>();
                foreach (IPropertyTemplateItem nonManyProp in current.Part.Where(prop =>
                                                                                 (prop.Value is ObjectTemplateExp || prop.Value is VariableExp) &&
                                                                                 !prop.ReferredProperty.isMany()))
                {
                    IVariable bindedVariable = QvtModelExplorer.FindBindedVariables(nonManyProp).Single();
                    if (bindedVariable != null && !variablesBindedSoFar.Contains(bindedVariable))
                    {
                        managedProps.Add(nonManyProp);
                        stringBuilder.AppendLine(GenerateBindingFreeNonMany(nonManyProp, bindedVariable));
                        variablesBindedSoFar.Add(bindedVariable);
                    }
                }

                // We compute the checks that we can do right now, and the ones that must be post poned because their variables are not binded yet
                // For now we only do checks on single value properties, the many valued one are simply exhaustively explored/binded later
                IEnumerable <IPropertyTemplateItem> candidatesInit = current.Part.Where(prop => !prop.ReferredProperty.isMany() && (prop.Value is CSharpOpaqueExpression || prop.Value is IVariableExp));
                ISet <IPropertyTemplateItem>        candidates     = new HashSet <IPropertyTemplateItem>();
                candidates.UnionWith(candidatesInit);
                candidates.UnionWith(postPonedPropertiesToCheck);
                candidates.ExceptWith(managedProps);
                ISet <IPropertyTemplateItem> propsToCheck = new HashSet <IPropertyTemplateItem>();
                foreach (IPropertyTemplateItem candidate in candidates)
                {
                    if (!variablesBindedSoFar.IsSupersetOf(QvtModelExplorer.FindBindedVariables(candidate)))
                    {
                        propsToCheck.Remove(candidate);
                        postPonedPropertiesToCheck.Add(candidate);
                    }
                    else
                    {
                        propsToCheck.Add(candidate);
                        postPonedPropertiesToCheck.Remove(candidate);
                    }
                }

                // We generate the checks for all the ones that can be made now
                if (propsToCheck.Count > 0)
                {
                    IEnumerable <string> conditions = propsToCheck.Select(u => GenerateConditionnalProperty(u, true));
                    string condition = string.Join(" && ", conditions);
                    stringBuilder.AppendLine("if (" + condition + ") {");
                }

                // We make a recursion for each object template not managed yet
                // - If the ref is many, then we make the binding first using a loop
                // - If the ref is not many, the binding was done before when managing non-many

                List <IPropertyTemplateItem> objectTemplatesManyRemaining = current.Part.Where(p => p.Value is ObjectTemplateExp && p.ReferredProperty.isMany() && remaining.Contains(p.Value)).ToList();
                foreach (IPropertyTemplateItem propWithTemplate in objectTemplatesManyRemaining)
                {
                    // Generate start for each, which binds the variable associated with the object template
                    ObjectTemplateExp objectTemplate = (ObjectTemplateExp)propWithTemplate.Value;
                    stringBuilder.AppendLine("foreach (" + objectTemplate.BindsTo.Type.GetRealTypeName() + " " + objectTemplate.BindsTo.Name + "  in " + currentVariableName + "." + propWithTemplate.ReferredProperty.Name + ".OfType<" + propWithTemplate.ReferredProperty.Type.GetRealTypeName() + ">()) {");
                    variablesBindedSoFar.Add(objectTemplate.BindsTo);
                }

                GenerateDomainCheckMethodContent(sourceDomain, variablesBindedSoFar, analysis, remaining, stringBuilder, postPonedPropertiesToCheck);

                foreach (IPropertyTemplateItem _ in objectTemplatesManyRemaining)
                {
                    // Generate end for each
                    stringBuilder.AppendLine("}");
                }

                // Generate end if checks all c# expressions
                if (propsToCheck.Count > 0)
                {
                    stringBuilder.Append("}");
                }

                // End conditional on the object template
                stringBuilder.AppendLine("}");
            }

            // We stop the recursion if there are no more object templates to manage
            else
            {
                string matchClassName = QvtCodeGeneratorStrings.MatchDomainClassName(sourceDomain);

                // Now we can finally create the Match object
                stringBuilder.AppendLine(matchClassName + " match = new " + matchClassName + "() {");

                foreach (IVariable variable in analysis.VariablesItCanBind)
                {
                    stringBuilder.AppendLine(variable.Name + " = " + variable.Name + ",");
                }

                stringBuilder.AppendLine("};");
                stringBuilder.AppendLine("result.Add(match);");
            }

            return(stringBuilder.ToString());
        }
        private static string GenerateSetValue(IPropertyTemplateItem propertyTemplateItem, string resultContainer, IRelation relation, bool useMetamodelInterface)
        {
            StringBuilder      sb = new StringBuilder();
            IObjectTemplateExp objectTemplateExpression = propertyTemplateItem.Value as IObjectTemplateExp;

            // Case ref value
            if (objectTemplateExpression != null)
            {
                IKey transformationKey = ((IRelationalTransformation)relation.Transformation).OwnedKey.FirstOrDefault(k => k.Identifies == objectTemplateExpression.ReferredClass);
                IList <IList <IPropertyTemplateItem> > propertyPathsTransformationKey = transformationKey != null?FindKeyApplicablePropertyPaths(objectTemplateExpression, transformationKey) : null;

                IKey relationKey = relation.Keys().FirstOrDefault(k => k.Identifies == objectTemplateExpression.ReferredClass);
                IList <IList <IPropertyTemplateItem> > propertyPathsRelationKey = relationKey != null?FindKeyApplicablePropertyPaths(objectTemplateExpression, relationKey) : null;

                // We always start by creating the empty variable that will contain the object
                sb.AppendLine(objectTemplateExpression.BindsTo.Type.GetRealTypeName() + " " + objectTemplateExpression.BindsTo.Name + " = null;");

                int nbBracketsOpened = 0;

                // If any part of a key applies, then we must generate a test to find a potential existing object
                if (propertyPathsTransformationKey != null || propertyPathsRelationKey != null)
                {
                    // We try to resolve globally and locally, if a global key applies here
                    if (propertyPathsTransformationKey != null)
                    {
                        sb.AppendLine();
                        sb.AppendLine("// Trying to resolve the object\'" + objectTemplateExpression.BindsTo.Name + "\' globally using the transformation key");
                        IList <string> tupleTypes      = propertyPathsTransformationKey.Select(pp => pp.Last().ReferredProperty.Type.GetRealTypeName()).Select(name => name + (cSharpPrimitiveTypes.Contains(name) ? "?" : "")).ToList();
                        IList <string> tupleValues     = propertyPathsTransformationKey.Select(pp => GenerateAccess(objectTemplateExpression.BindsTo.Name, pp)).ToList();
                        IList <string> tupleValuesRead = propertyPathsTransformationKey.Select(pp => GenerateExpression(pp.Last().Value, useMetamodelInterface)).ToList();

                        string tupleTypesCombined        = string.Join(",", tupleTypes);
                        string tupleValuesCombined       = string.Join(",", tupleValues);
                        string tupleValuesCombinedRead   = string.Join(",", tupleValuesRead);
                        string accessDictionnaryReadSafe = "transformation."
                                                           + QvtCodeGeneratorStrings.KeyDictionnaryName(transformationKey)
                                                           + ".TryGetValue(new Tuple<" + tupleTypesCombined + ">(" + tupleValuesCombinedRead + "), out " + objectTemplateExpression.BindsTo.Name + ")";
                        string accessDictionnaryWrite = "transformation."
                                                        + QvtCodeGeneratorStrings.KeyDictionnaryName(transformationKey)
                                                        + "[new Tuple<" + tupleTypesCombined + ">(" + tupleValuesCombined + ")]";
                        sb.AppendLine(accessDictionnaryReadSafe + ";");

                        // If not found globally with global key, we try to find locally with global key
                        sb.AppendLine("// If the object wasn't found globally, we try to find it locally");
                        sb.AppendLine("if (" + objectTemplateExpression.BindsTo.Name + "== null) {");
                        sb.AppendLine(GenerateFindValueWithKey(propertyTemplateItem, objectTemplateExpression, resultContainer, propertyPathsTransformationKey, useMetamodelInterface));
                        nbBracketsOpened++;

                        // If we found locally with global key, we add to the dictionnary
                        sb.AppendLine("// If the object was found locally, we add it to the global cache");
                        sb.AppendLine("if (" + objectTemplateExpression.BindsTo.Name + "!= null) {");
                        sb.AppendLine(accessDictionnaryWrite + " = " + objectTemplateExpression.BindsTo.Name + ";");

                        // Else we continue with other attempts (local key or object creation)
                        sb.AppendLine("}");
                    }

                    if (propertyPathsRelationKey != null)
                    {
                        sb.AppendLine("// Trying to resolve the object locally using the relation key");

                        if (propertyPathsTransformationKey != null)
                        {
                            sb.AppendLine("else {");
                            nbBracketsOpened++;
                        }

                        sb.AppendLine(GenerateFindValueWithKey(propertyTemplateItem, objectTemplateExpression, resultContainer, propertyPathsRelationKey, useMetamodelInterface));

                        // If we found something locally, once again we check in the dictionnary and try to update
                        sb.AppendLine("// If the object was found locally, we add it to the global cache");
                        sb.AppendLine("if (" + objectTemplateExpression.BindsTo.Name + "!= null) {");
                        sb.AppendLine(GenerateCheckAndAddDictionnary(propertyPathsTransformationKey, objectTemplateExpression.BindsTo.Name, transformationKey));
                        sb.AppendLine("}");
                    }

                    // In the end we generate a test if we found a candidate
                    sb.AppendLine("// If the object still doesn't exist, we create it");
                    sb.AppendLine("else {");
                    nbBracketsOpened++;
                }

                // In any case, we generate the code to create the object, even if it might end in the conditional due to the keys test
                string beginningCreation = objectTemplateExpression.BindsTo.Name + " = ";
                if (useMetamodelInterface)
                {
                    sb.AppendLine(beginningCreation + " (" + objectTemplateExpression.BindsTo.Type.GetRealTypeName() + ") editor." + nameof(IMetaModelInterface.CreateNewObjectInField) + "(" + resultContainer + ", \"" + propertyTemplateItem.ReferredProperty.Name + "\");");
                }
                else
                {
                    string res = beginningCreation;
                    res += "new " + objectTemplateExpression.BindsTo.Type.GetRealTypeName() + "();\n";
                    if (!propertyTemplateItem.ReferredProperty.isMany())
                    {
                        res += resultContainer + "." + propertyTemplateItem.ReferredProperty.Name + " = " + objectTemplateExpression.BindsTo.Name + ";";
                    }
                    else
                    {
                        res += resultContainer + "." + propertyTemplateItem.ReferredProperty.Name + ".Add(" + objectTemplateExpression.BindsTo.Name + ");";
                    }
                    sb.AppendLine(res);
                }

                if (propertyPathsTransformationKey != null)
                {
                    // TODO generate this all the time?
                    sb.AppendLine("// We add the created object to the global cache");
                    sb.AppendLine(GenerateCheckAndAddDictionnary(propertyPathsTransformationKey, objectTemplateExpression.BindsTo.Name, transformationKey));
                }
                // If we generated a conditional for the keys test, we close it now
                if (propertyPathsTransformationKey != null || propertyPathsRelationKey != null)
                {
                    sb.AppendLine("}");
                }

                for (int i = 0; i < nbBracketsOpened - 1; i++)
                {
                    sb.AppendLine("}");
                }
                return(sb.ToString());
            }
            // Case primitive value (variable use or c sharp expression)
            else
            {
                if (useMetamodelInterface)
                {
                    return("editor." + nameof(IMetaModelInterface.AddOrSetInField) + "(" + resultContainer + ", \"" + propertyTemplateItem.ReferredProperty.Name + "\", " + GenerateExpression(propertyTemplateItem.Value, true) + " );");
                }
                else
                {
                    return(resultContainer + "." + propertyTemplateItem.ReferredProperty.Name + "=" + GenerateExpression(propertyTemplateItem.Value, false) + ";");
                }
            }
        }
        private static string GenerateFindValueWithKey(IPropertyTemplateItem propertyTemplateItem, IObjectTemplateExp objectTemplateExpression, string resultContainer, IList <IList <IPropertyTemplateItem> > applicablePropertyPaths, bool useMetamodelInterface)
        {
            StringBuilder  sb           = new StringBuilder();
            IList <string> conditions   = new List <string>();
            string         variableName = "var" + new Random().Next();

            foreach (IList <IPropertyTemplateItem> applicablePropertyPath in applicablePropertyPaths)
            {
                string access    = GenerateAccess(variableName, applicablePropertyPath);
                string condition = access + " == " + GenerateExpression(applicablePropertyPath.Last().Value, useMetamodelInterface);
                conditions.Add(condition);
            }
            string completeCondition = string.Join(" && ", conditions);

            // If the candidate is in a collection, we generate a query to find it
            if (propertyTemplateItem.ReferredProperty.isMany())
            {
                sb.AppendLine(objectTemplateExpression.BindsTo.Name + " = "
                              + resultContainer + "." + propertyTemplateItem.ReferredProperty.Name
                              + ".OfType<" + propertyTemplateItem.ReferredProperty.Type.GetRealTypeName() + ">()"
                              + ".FirstOrDefault(" + variableName + " => " + completeCondition + ");");
            }

            // If the candidate is in a ref, we generate a conditional to find it
            else
            {
                sb.AppendLine("{"
                              + propertyTemplateItem.ReferredProperty.Type.GetRealTypeName()
                              + variableName + "= " + resultContainer + "." + propertyTemplateItem.ReferredProperty.Name + ";"
                              + "if (" + completeCondition + ") {"
                              + objectTemplateExpression.BindsTo.Name + " = "
                              + variableName + ";"
                              + "}"
                              + "}");
            }
            return(sb.ToString());
        }
        private static IList <IList <IPropertyTemplateItem> > FindKeyApplicablePropertyPaths(IObjectTemplateExp objectTemplateExpression, IKey candidateKey)
        {
            // First, we try to find if some keys applies here
            IList <IList <IPropertyTemplateItem> > result = new List <IList <IPropertyTemplateItem> >();

            IList <IList <IPropertyTemplateItem> > candidateKeyPropertyPaths = new List <IList <IPropertyTemplateItem> >();

            bool isApplicable = true;

            foreach (IProperty property in candidateKey.Part)
            {
                IPropertyTemplateItem candidate = objectTemplateExpression.Part.FirstOrDefault(p => p.ReferredProperty == property);
                if (candidate != null)
                {
                    List <IPropertyTemplateItem> propertyPath = new List <IPropertyTemplateItem>()
                    {
                        candidate
                    };
                    candidateKeyPropertyPaths.Add(propertyPath);
                }
                else
                {
                    isApplicable = false;
                    break;
                }
            }

            if (isApplicable)
            {
                foreach (PropertyPath propertyPath in candidateKey.PropertyPaths())
                {
                    IObjectTemplateExp currentobjectTemplateExpression = objectTemplateExpression;
                    bool isPathApplicable = true;
                    List <IPropertyTemplateItem> concretePropertyPath = new List <IPropertyTemplateItem>();
                    foreach (IProperty property in propertyPath.Properties)
                    {
                        IEnumerable <IPropertyTemplateItem> nextObjectTemplate = currentobjectTemplateExpression.Part.Where(p => p.ReferredProperty == property).ToList();
                        if (!nextObjectTemplate.IsNullOrEmpty())
                        {
                            concretePropertyPath.Add(nextObjectTemplate.Single());
                            currentobjectTemplateExpression = (IObjectTemplateExp)nextObjectTemplate.Single().Value;
                        }
                        else
                        {
                            isPathApplicable = false;
                            break;
                        }
                    }
                    if (isPathApplicable)
                    {
                        candidateKeyPropertyPaths.Add(concretePropertyPath);
                    }
                    else
                    {
                        isApplicable = false;
                        break;
                    }
                }
            }
            // If this key is valid, we merge all its contents into the result
            if (isApplicable)
            {
                foreach (IList <IPropertyTemplateItem> candidateKeyPropertyPath in candidateKeyPropertyPaths)
                {
                    IList <IPropertyTemplateItem> existing = result.FirstOrDefault(pp => AreEqual(pp, candidateKeyPropertyPath));
                    if (existing.IsNullOrEmpty())
                    {
                        result.Add(candidateKeyPropertyPath);
                    }
                }
                return(result);
            }
            return(null);
        }