public static bool PerliminaryMapping(Parameter _p, Component _direct_parent, TypeNode _tn, bool _as_example, bool _match_name, out MappingError err)
        {
            err = MappingError.NONE;
            if (_p == null || _direct_parent == null || _tn == null)
            {
                err = MappingError.MISSING_MAPPING_END;
                return(false);
            }
            // parameters can be mapped only to simple types (e.g. int)
            if (_tn.BindingType != TypeNodeContentBindingType.SIMPLE)
            {
                err = MappingError.PARAM_TO_TYPE_MISMATCH;
                return(false);
            }

            if (_match_name)
            {
                return(MappingObject.StringsCouldMeanTheSame(_p.Name, _tn.Label));
            }
            else
            {
                return(true);
            }
        }
        /// <summary>
        /// This method accepts both a partial and a full matching.
        /// The matching rules are: 1. Components can match only COMPLEX TypeNodes. 2. Parameters can match only SIMPLE TypeNodes.
        /// 3. GeometricRelationshipscan only match a NON_BINDABLE TypeNode with exactly one SubNode of COMPLEX type.
        /// </summary>
        public static void MatchStructure(Component _comp, TypeNode _tn, ref List <KeyValuePair <string, TypeNode> > correspondencies, out MappingError err)
        {
            if (correspondencies == null)
            {
                correspondencies = new List <KeyValuePair <string, TypeNode> >();
            }
            err = MappingError.NONE;

            if (_comp == null || _tn == null)
            {
                err = MappingError.MISSING_MAPPING_END;
                return;
            }

            if (_tn.BindingType == TypeNodeContentBindingType.NOT_BINDABLE ||
                _tn.BindingType == TypeNodeContentBindingType.SIMPLE)
            {
                err = MappingError.COMPONENT_TO_TYPE_MISMATCH;
                return;
            }
            if (_tn.BindingType == TypeNodeContentBindingType.KEY)
            {
                err = MappingError.NO_MAPPING_TO_ID_ALLOWED;
                return;
            }

            if (correspondencies.Where(x => x.Key == MappingComponent.PREFIX_COMP + _comp.ID.ToString()).Count() > 0)
            {
                err = MappingError.ID_DUPLICATION;
                return;
            }

            // at least top-level matching is possible
            List <KeyValuePair <string, TypeNode> > new_correspondencies = new List <KeyValuePair <string, TypeNode> >();

            new_correspondencies.Add(new KeyValuePair <string, TypeNode>(MappingComponent.PREFIX_COMP + _comp.ID.ToString(), _tn));
            bool transferred_id = false;

            if (_tn.SubNodes == null || _tn.SubNodes.Count == 0)
            {
                return;
            }

            // attempt matching of structure
            foreach (TypeNode sN in _tn.SubNodes)
            {
                if (sN.BindingType == TypeNodeContentBindingType.SIMPLE)
                {
                    // look for an existing mapping
                    bool found_existing = false;
                    if (sN.AllMappings != null && sN.AllMappings.Count > 0)
                    {
                        MappingObject mo = sN.AllMappings.FirstOrDefault(x => (x is MappingParameter) && _comp.ContainedParameters.ContainsKey((x as MappingParameter).MappedParameter.ID));
                        if (mo != null)
                        {
                            string p_key = MappingComponent.PREFIX_PARAM + (mo as MappingParameter).MappedParameter.ID.ToString();
                            if (!(correspondencies.Where(x => x.Key == p_key).Count() > 0) && !(new_correspondencies.Where(x => x.Key == p_key).Count() > 0))
                            {
                                new_correspondencies.Add(new KeyValuePair <string, TypeNode>(p_key, sN));
                            }
                            found_existing = true;
                        }
                    }
                    // try to match it to a parameter
                    if (!found_existing && _comp.ContainedParameters.Count() > 0)
                    {
                        Parameter p = _comp.ContainedParameters.FirstOrDefault(x => x.Value != null && MappingObject.StringsCouldMeanTheSame(x.Value.Name, sN.Label)).Value;
                        if (p != null)
                        {
                            string p_key = MappingComponent.PREFIX_PARAM + p.ID.ToString();
                            if (!(correspondencies.Where(x => x.Key == p_key).Count() > 0) && !(new_correspondencies.Where(x => x.Key == p_key).Count() > 0))
                            {
                                new_correspondencies.Add(new KeyValuePair <string, TypeNode>(p_key, sN));
                            }
                        }
                    }
                }
                else if (sN.BindingType == TypeNodeContentBindingType.NOT_BINDABLE)
                {
                    // try to match it to a geometric relationship
                    if (sN.IsEnumerable && sN.SubNodes != null && sN.SubNodes.Count == 1)
                    {
                        TypeNode sN_1 = sN.SubNodes[0];
                        if (sN_1.BindingType == TypeNodeContentBindingType.COMPLEX)
                        {
                            bool match_w_geometry_found = false;
                            foreach (GeometricRelationship gr in _comp.R2GInstances)
                            {
                                // get the path points as identifiable containers
                                List <HierarchicalContainer> geometry = gr.GeometricContent;
                                if (geometry.Count == 0)
                                {
                                    continue;
                                }

                                foreach (HierarchicalContainer hc in geometry)
                                {
                                    Point3DContainer p3dc = hc as Point3DContainer;
                                    if (p3dc == null)
                                    {
                                        continue;
                                    }

                                    // CHECK IF A MAPPING IS AT ALL POSSIBLE
                                    MappingError sN_1_test_err = MappingError.NONE;
                                    MappingSinglePoint.PreliminaryMapping(p3dc, _comp, sN_1, false, out sN_1_test_err);
                                    if (sN_1_test_err != MappingError.NONE)
                                    {
                                        break;
                                    }

                                    // look for an existing mapping
                                    bool found_existing = false;
                                    if (sN_1.AllMappings != null && sN_1.AllMappings.Count > 0)
                                    {
                                        MappingObject mo = sN_1.AllMappings.FirstOrDefault(x => (x is MappingSinglePoint) &&
                                                                                           (x as MappingSinglePoint).MappedPointC.ID_primary == p3dc.ID_primary && (x as MappingSinglePoint).MappedPointC.ID_secondary == p3dc.ID_secondary);
                                        if (mo != null)
                                        {
                                            string p_key = MappingComponent.PREFIX_P3DC + (mo as MappingSinglePoint).MappedPointC.ID_primary.ToString() +
                                                           "_" + (mo as MappingSinglePoint).MappedPointC.ID_secondary.ToString();
                                            if (!(correspondencies.Where(x => x.Key == p_key).Count() > 0) && !(new_correspondencies.Where(x => x.Key == p_key).Count() > 0))
                                            {
                                                new_correspondencies.Add(new KeyValuePair <string, TypeNode>(p_key, sN_1));
                                            }
                                            found_existing         = true;
                                            match_w_geometry_found = true;
                                        }
                                    }
                                    // try to create a new mapping
                                    if (!found_existing)
                                    {
                                        MappingError sN_1_m_err = MappingError.NONE;
                                        MappingSinglePoint.PreliminaryMapping(p3dc, _comp, sN_1, false, out sN_1_m_err);
                                        if (sN_1_m_err == MappingError.NONE)
                                        {
                                            // mapping successful
                                            string p_key = MappingComponent.PREFIX_P3DC + p3dc.ID_primary.ToString() +
                                                           "_" + p3dc.ID_secondary.ToString();
                                            if (!(correspondencies.Where(x => x.Key == p_key).Count() > 0) && !(new_correspondencies.Where(x => x.Key == p_key).Count() > 0))
                                            {
                                                new_correspondencies.Add(new KeyValuePair <string, TypeNode>(p_key, sN_1));
                                            }
                                            match_w_geometry_found = true;
                                        }
                                    }
                                }
                            }

                            if (!match_w_geometry_found)
                            {
                                // try to match it to a sub-component -> RECURSION
                                if (sN.SubNodes != null && sN.SubNodes.Count > 0)
                                {
                                    foreach (TypeNode ssN in sN.SubNodes)
                                    {
                                        int nr_current_correspondencies = correspondencies.Count;
                                        // attempt a matching
                                        foreach (var entry in _comp.ContainedComponents)
                                        {
                                            Component sC = entry.Value;
                                            if (sC == null)
                                            {
                                                continue;
                                            }

                                            MappingError sC_err = MappingError.NONE;
                                            MappingComponent.MatchStructure(sC, ssN, ref correspondencies, out sC_err);
                                            if (sC_err == MappingError.NONE && correspondencies.Count > nr_current_correspondencies)
                                            {
                                                // success
                                                break;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else if (sN.BindingType == TypeNodeContentBindingType.KEY)
                {
                    // pass the ID of the component
                    string key_id = MappingComponent.PREFIX_ID + _comp.ID.ToString();
                    if (!(correspondencies.Where(x => x.Key == key_id).Count() > 0) && !(new_correspondencies.Where(x => x.Key == key_id).Count() > 0))
                    {
                        new_correspondencies.Add(new KeyValuePair <string, TypeNode>(key_id, sN));
                        transferred_id = true;
                    }
                }
                else if (sN.BindingType == TypeNodeContentBindingType.COMPLEX)
                {
                    // try to match it to a sub-component -> RECURSION
                    if (sN.SubNodes != null && sN.SubNodes.Count > 0)
                    {
                        foreach (TypeNode ssN in sN.SubNodes)
                        {
                            int nr_current_correspondencies = correspondencies.Count;
                            // attempt a matching
                            foreach (var entry in _comp.ContainedComponents)
                            {
                                Component sC = entry.Value;
                                if (sC == null)
                                {
                                    continue;
                                }

                                MappingError sC_err = MappingError.NONE;
                                MappingComponent.MatchStructure(sC, ssN, ref correspondencies, out sC_err);
                                if (sC_err == MappingError.NONE && correspondencies.Count > nr_current_correspondencies)
                                {
                                    // success
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            if ((new_correspondencies.Count < 2) || (new_correspondencies.Count < 3 && transferred_id))
            {
                // only a match at the highest level -> not enough -> do not add
            }
            else
            {
                // the method traverses the component from BOTTOM to TOP
                // the mapping is performed TOP to BOTTOM -> insert at the start
                for (int i = 0; i < new_correspondencies.Count; i++)
                {
                    var entry = new_correspondencies[i];
                    correspondencies.Insert(i, new KeyValuePair <string, TypeNode>(entry.Key, entry.Value));
                }
            }
        }
        public static Dictionary <string, TypeNode> PreliminaryMapping(Point3DContainer _point_container, Component _direct_parent, TypeNode _tn, bool _as_example, out MappingError err)
        {
            err = MappingError.NONE;
            if (_point_container == null || _direct_parent == null || _tn == null)
            {
                err = MappingError.MISSING_MAPPING_END;
                return(null);
            }

            // check if the mapping is possible...
            if (_tn.SubNodes == null)
            {
                err = MappingError.TOO_FEW_PARAMETERS_FOR_TYPE;
                return(null);
            }
            if (_tn.BindingType == TypeNodeContentBindingType.NOT_BINDABLE)
            {
                err = MappingError.COMPONENT_TO_TYPE_MISMATCH;
                return(null);
            }
            if (_tn.BindingType == TypeNodeContentBindingType.KEY)
            {
                err = MappingError.NO_MAPPING_TO_ID_ALLOWED;
                return(null);
            }

            if (_tn.SubNodes.Count != 3)
            {
                err = MappingError.INSTANTIATION_OF_TYPE_IMPOSSIBLE;
                return(null);
            }

            // attempt a preliminary mapping of coordinates
            Dictionary <string, TypeNode> coords_mapping = new Dictionary <string, TypeNode>()
            {
                { "x", null },
                { "y", null },
                { "z", null }
            };

            foreach (TypeNode stn in _tn.SubNodes)
            {
                if (stn.BindingType != TypeNodeContentBindingType.SIMPLE)
                {
                    err = MappingError.TOO_FEW_PARAMETERS_FOR_TYPE;
                    return(null);
                }
                if (coords_mapping["x"] == null && MappingObject.StringsCouldMeanTheSame("x", stn.Label))
                {
                    coords_mapping["x"] = stn;
                }
                else if (coords_mapping["y"] == null && MappingObject.StringsCouldMeanTheSame("y", stn.Label))
                {
                    coords_mapping["y"] = stn;
                }
                else if (coords_mapping["z"] == null && MappingObject.StringsCouldMeanTheSame("z", stn.Label))
                {
                    coords_mapping["z"] = stn;
                }
            }

            return(coords_mapping);
        }