public static MappingSinglePoint Create(Point3DContainer _point_container, Component _direct_parent, TypeNode _tn, bool _as_example, out MappingError err)
        {
            // attempt a preliminary mapping of coordinates
            Dictionary <string, TypeNode> coords_mapping = MappingSinglePoint.PreliminaryMapping(_point_container, _direct_parent, _tn, _as_example, out err);

            if (err != MappingError.NONE)
            {
                return(null);
            }

            // perform actual mapping
            if (coords_mapping["x"] != null && coords_mapping["y"] != null && coords_mapping["z"] != null)
            {
                MappingSinglePoint msp = new MappingSinglePoint(_point_container, _direct_parent, _tn, _as_example);
                msp.coords_mapping    = coords_mapping;
                _tn.MostRecentMapping = msp;
                return(msp);
            }
            else
            {
                err = MappingError.INSTANTIATION_OF_TYPE_IMPOSSIBLE;
                return(null);
            }
        }
        public static List <MappingObject> CreateMultipleFrom(Component _comp, TypeNode _tn, bool _as_example, List <KeyValuePair <string, TypeNode> > _correspondencies, out MappingError err)
        {
            err = MappingError.NONE;
            List <MappingObject> created_mappings = new List <MappingObject>();

            if (_comp == null || _tn == null || _correspondencies == null || _correspondencies.Count < 2)
            {
                err = MappingError.MISSING_MAPPING_END;
                return(created_mappings);
            }

            Component    current_comp = _comp;
            MappingError tmp_err      = MappingError.NONE;

            foreach (var entry in _correspondencies)
            {
                string[] key_comps = entry.Key.Split(new char[] { '_' }, StringSplitOptions.RemoveEmptyEntries);
                if (key_comps == null || key_comps.Length < 2)
                {
                    err = MappingError.MISSING_MAPPING_END;
                    return(created_mappings);
                }

                if ((key_comps[0] + "_") == MappingComponent.PREFIX_COMP)
                {
                    // -------------------------- COMPONENTS --------------------------- //
                    long comp_id = -1;
                    bool success = long.TryParse(key_comps[1], out comp_id);
                    if (!success)
                    {
                        err = MappingError.MISSING_MAPPING_END;
                        return(created_mappings);
                    }

                    if (comp_id != current_comp.ID)
                    {
                        // look for the component in the children of current_comp
                        List <Component> all_sub_comps = current_comp.GetFlatSubCompList();
                        Component        next          = all_sub_comps.FirstOrDefault(x => x.ID == comp_id);
                        if (next == null)
                        {
                            err = MappingError.MISSING_MAPPING_END;
                            return(created_mappings);
                        }
                        else
                        {
                            current_comp = next;
                        }
                    }
                }
                else if ((key_comps[0] + "_") == MappingComponent.PREFIX_ID)
                {
                    // ------------------------ COMPONENT IDS -------------------------- //
                    MappingString ms = MappingString.Create(current_comp, entry.Key, entry.Value, _as_example, out tmp_err);
                    if (tmp_err != MappingError.NONE)
                    {
                        err = tmp_err;
                        return(created_mappings);
                    }
                    else
                    {
                        created_mappings.Add(ms);
                    }
                }
                else if ((key_comps[0] + "_") == MappingComponent.PREFIX_PARAM)
                {
                    // -------------------------- PARAMETERS --------------------------- //
                    long param_id = -1;
                    bool success  = long.TryParse(key_comps[1], out param_id);
                    if (!success || !current_comp.ContainedParameters.ContainsKey(param_id))
                    {
                        err = MappingError.MISSING_MAPPING_END;
                        return(created_mappings);
                    }
                    Parameter        p  = current_comp.ContainedParameters[param_id];
                    MappingParameter mp = MappingParameter.Create(p, current_comp, entry.Value, _as_example, false, out tmp_err);
                    if (tmp_err != MappingError.NONE)
                    {
                        err = tmp_err;
                        return(created_mappings);
                    }
                    else
                    {
                        created_mappings.Add(mp);
                    }
                }
                else if ((key_comps[0] + "_") == MappingComponent.PREFIX_P3DC)
                {
                    // --------------------------- GEOMETRY ---------------------------- //
                    if (key_comps.Length < 3)
                    {
                        err = MappingError.MISSING_MAPPING_END;
                        return(created_mappings);
                    }
                    long id_primary = -1;
                    int  id_second  = -1;
                    bool success_1  = long.TryParse(key_comps[1], out id_primary);
                    bool success_2  = int.TryParse(key_comps[2], out id_second);
                    if (!success_1 || !success_2)
                    {
                        err = MappingError.MISSING_MAPPING_END;
                        return(created_mappings);
                    }
                    GeometricRelationship gr = current_comp.R2GInstances.FirstOrDefault(x => x.ID == id_primary);
                    if (gr == null)
                    {
                        err = MappingError.MISSING_MAPPING_END;
                        return(created_mappings);
                    }
                    Point3DContainer p3dc = gr.GeometricContent.FirstOrDefault(x => x.ID_primary == id_primary && x.ID_secondary == id_second) as Point3DContainer;
                    if (p3dc == null)
                    {
                        err = MappingError.MISSING_MAPPING_END;
                        return(created_mappings);
                    }

                    MappingSinglePoint msp = MappingSinglePoint.Create(p3dc, current_comp, entry.Value, _as_example, out tmp_err);
                    if (tmp_err != MappingError.NONE)
                    {
                        err = tmp_err;
                        return(created_mappings);
                    }
                    else
                    {
                        created_mappings.Add(msp);
                    }
                }
            }

            return(created_mappings);
        }
        /// <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));
                }
            }
        }