protected ContextResult CreateTopReferable(
            ImportCellMatchContextBase context,
            bool actInHierarchy = false)
        {
            // access
            if (context?.Parent == null || _sm == null)
            {
                return(null);
            }

            // what element to create? makes this sense?
            var fen = FilteredElementName.Parse(context.ParentElemName);

            if (fen == null)
            {
                return(null);
            }
            if (fen.Name != AdminShell.Key.Submodel &&
                fen.NameEnum != AdminShell.SubmodelElementWrapper.AdequateElementEnum.Unknown &&
                fen.NameEnum != AdminShell.SubmodelElementWrapper.AdequateElementEnum.SubmodelElementCollection)
            {
                return(null);
            }

            // special case: directly into the (existing) Submodel
            ContextResult res = null;

            if (fen.Name == AdminShell.Key.Submodel)
            {
                // prepare the result (already)
                res = new ContextResult()
                {
                    Elem     = _sm,
                    Wrappers = _sm.submodelElements
                };

                // kind of manually take over data
                // this changes the actual data of the Submodel the plugin is associated with!
                AasConvertHelper.TakeOverSmeToSm(context.Parent, _sm);

                // ok
                return(res);
            }

            // ok, if not, then ordinary case: create a SME and add it (somewhere) to the SM
            // this ALREADY should take over the most of the data
            // Note: value data is not required, as fixed to SMC!
            var sme = AdminShell.SubmodelElementWrapper.CreateAdequateType(fen.NameEnum, context.Parent);

            if (!(sme is AdminShell.SubmodelElementCollection smesmc))
            {
                return(null);
            }

            smesmc.value = new AdminShell.SubmodelElementWrapperCollection();

            res = new ContextResult()
            {
                Elem     = sme,
                Wrappers = smesmc.value
            };

            // try to act within the hierarchy
            // does only search SME but no SM, however, this is not a flaw, as adding to SM is the default
            if (actInHierarchy && context.ParentParentName.HasContent() && context.Parent.idShort.HasContent())
            {
                foreach (var rootsmc in _sm.submodelElements.FindDeep <AdminShell.SubmodelElementCollection>((testsmc) =>
                {
                    // first condition is, that the parents match!
                    if (!testsmc.idShort.HasContent() || testsmc.parent == null)
                    {
                        return(false);
                    }

                    // try testing of allowed parent names
                    if (!(testsmc.parent is AdminShell.Referable testsmcpar))
                    {
                        return(false);
                    }
                    var test1 = context.ParentParentName.ToLower().Contains(testsmcpar.idShort.ToLower().Trim());
                    var test2 = false;
                    if (_idShortToParentName.ContainsKey(testsmcpar.idShort))
                    {
                        foreach (var pn in _idShortToParentName[testsmcpar.idShort])
                        {
                            test2 = test2 || context.ParentParentName.ToLower().Contains(pn.ToLower().Trim());
                        }
                    }

                    if (!(test1 || test2))
                    {
                        return(false);
                    }

                    // next is, that some part of of given idShort match the idShort of children
                    // of investigated SMC
                    var parts = context.Parent.idShort.Split(new[] { ',', ';', '|' },
                                                             StringSplitOptions.RemoveEmptyEntries);
                    foreach (var part in parts)
                    {
                        if (part?.Trim().ToLower() == testsmc.idShort.Trim().ToLower())
                        {
                            return(true);
                        }
                    }

                    // or, maybe more meaningful, if the semantic ids are the same?
                    if (context.Parent.semanticId?.IsEmpty == false &&
                        testsmc.semanticId?.IsEmpty == false &&
                        testsmc.semanticId.Matches(context.Parent.semanticId, AdminShell.Key.MatchMode.Relaxed))
                    {
                        return(true);
                    }

                    // not found
                    return(false);
                }))
                {
                    // rootsmc contains a valid SMC to the above criteria
                    // NOTHING needs to be added; found SMC needs to be given back
                    res.Elem     = rootsmc;
                    res.Wrappers = rootsmc.value;

                    // this seems to be a valid ParentName, which is now "renamed" by the idShort
                    // of the SMC
                    _idShortToParentName.Add(rootsmc.idShort, context.Parent.idShort);

                    // need to adopt the rootsmc further by parent information??
                    ;

                    // ok
                    return(res);
                }
            }

            // simply add new SMC directly to SM
            _sm.Add(sme);
            return(res);
        }
        protected ContextResult CreateBodySme(
            ImportCellMatchContextBase context,
            ContextResult refTop)
        {
            // access
            if (context?.Sme == null || refTop?.Wrappers == null)
            {
                return(null);
            }

            // make sure, there is an 'ordniary' SME to create
            var fen = FilteredElementName.Parse(context.SmeElemName);

            if (fen == null)
            {
                return(null);
            }
            if (fen.NameEnum == AdminShellV20.SubmodelElementWrapper.AdequateElementEnum.Unknown)
            {
                return(null);
            }

            // create, add
            var sme = AdminShell.SubmodelElementWrapper.CreateAdequateType(fen.NameEnum, context.Sme);

            refTop.Wrappers.Add(sme);
            sme.parent = refTop.Elem; // unfortunately required, ass Wrapper.Add() cannot set parent
            var res = new ContextResult()
            {
                Elem = sme
            };

            // allow a selection a values
            if (sme is AdminShell.Property prop)
            {
                prop.value = context.SmeValue;

                // demux
                prop.valueType = fen.ValueType;
                if (!fen.ValueType.HasContent() && context.SmeValueType.HasContent())
                {
                    prop.valueType = context.SmeValueType;
                }
            }

            if (sme is AdminShell.MultiLanguageProperty mlp)
            {
                mlp.value = new AdminShell.LangStringSet(AdminShell.LangStr.LANG_DEFAULT, context.SmeValue);
            }

            if (sme is AdminShell.File file)
            {
                file.value = context.SmeValue;
            }

            if (sme is AdminShell.SubmodelElementCollection smc)
            {
                smc.value    = new AdminShell.SubmodelElementWrapperCollection();
                res.Wrappers = smc.value;
            }

            // ok
            return(res);
        }
            public static FilteredElementName Parse(string str)
            {
                // access
                if (str == null || str.Trim() == "")
                {
                    return(null);
                }

                FilteredElementName res = null;

                // match the most complex/ restricted format
                var m = Regex.Match(str, @"\[\s*(\w+)\s*\]\s*/\s*(\w+)");

                if (m.Success)
                {
                    res = new FilteredElementName()
                    {
                        Name      = m.Groups[1].ToString().Trim(),
                        ValueType = m.Groups[2].ToString().Trim()
                    }
                }
                ;

                // again an acceptable format
                m = Regex.Match(str, @"(\w+)\s*/\s*(\w+)");
                if (res == null && m.Success)
                {
                    res = new FilteredElementName()
                    {
                        Name      = m.Groups[1].ToString().Trim(),
                        ValueType = m.Groups[2].ToString().Trim()
                    }
                }
                ;

                // nothing with slash, but maybe only square?
                m = Regex.Match(str, @"\[\s*(\w+)\s*\]");
                if (res == null && m.Success)
                {
                    res = new FilteredElementName()
                    {
                        Name      = m.Groups[1].ToString().Trim(),
                        ValueType = ""
                    }
                }
                ;

                // if not, best guess
                if (res == null)
                {
                    res = new FilteredElementName()
                    {
                        Name      = str.Trim(),
                        ValueType = ""
                    }
                }
                ;

                // now check, if something meaningful was found
                if (res.Name.Trim().ToLower() == AdminShell.Key.Submodel.ToLower())
                {
                    // successful special case
                    res.Name = AdminShell.Key.Submodel;
                    return(res);
                }

                // has to be a SME type
                var ae = AdminShell.SubmodelElementWrapper.GetAdequateEnum2(res.Name, useShortName: true);

                if (ae == AdminShell.SubmodelElementWrapper.AdequateElementEnum.Unknown)
                {
                    return(null);
                }

                // ok, nice
                res.Name     = AdminShell.SubmodelElementWrapper.GetAdequateName(ae);
                res.NameEnum = ae;
                return(res);
            }
        }