//https://docs.microsoft.com/en-us/azure/iot-pnp/concepts-model-parser
        public static async Task <Dictionary <string, DTDLContainer> > ParseDTDLAndBuildDynamicContentAsync(JArray dtdlArray)
        {
            if (dtdlArray == null)
            {
                throw new ArgumentNullException(nameof(dtdlArray));
            }

            Dictionary <string, DTDLContainer> globalResult = new Dictionary <string, DTDLContainer>();
            DTDLContainer itemResult = null;

            ModelParser parser = new ModelParser();

            IReadOnlyDictionary <Dtmi, DTEntityInfo> parseResult = await parser.ParseAsync(dtdlArray.Select(i => JsonConvert.SerializeObject(i)));

            foreach (JObject dtdl in dtdlArray)
            {
                try
                {
                    //PROCESS COMPONENTS
                    await ProcessComponentsWithDynamicContent(dtdlArray, dtdl, globalResult);

                    //ALL EXCEPT COMPONENTS
                    itemResult = BuildDynamicContent(dtdl);
                }
                catch (ParsingException pex)
                {
                    if (itemResult == null)
                    {
                        itemResult = new DTDLContainer();
                    }

                    itemResult.ParsingErrors = pex.Errors.Select(i => i.Message);
                }
                catch (Exception ex)
                {
                    itemResult = null;
                }
                finally
                {
                    if (itemResult != null)
                    {
                        if (!globalResult.ContainsKey(dtdl["@id"].Value <string>()))
                        {
                            globalResult.Add(dtdl["@id"].Value <string>(), itemResult);
                        }
                    }

                    itemResult = null;
                }
            }


            return(globalResult);
        }
        private static DTDLContainer BuildDynamicContent(JObject dtdl)
        {
            if (dtdl == null)
            {
                throw new ArgumentNullException(nameof(dtdl));
            }

            DTDLContainer result = new DTDLContainer {
                ModelId = dtdl["@id"].Value <string>(), DTDL = dtdl
            };

            //CONTENT
            if (!dtdl.ContainsKey("contents"))
            {
                throw new Exception("The DTDL model does not contain any 'contents' property.");
            }

            JArray contents = (JArray)dtdl["contents"];

            //Look for telemetries (JSON)
            JArray telemetries = ExtractTelemetries(contents);

            if (telemetries != null && telemetries.Any())
            {
                if (result.DTDLGeneratedData == null)
                {
                    result.DTDLGeneratedData = new DTDLGeneratedData();
                }

                result.DTDLGeneratedData.Telemetries = telemetries;
            }

            telemetries = ExtractTelemetriesWithUnit(contents);
            if (telemetries != null && telemetries.Any())
            {
                if (result.DTDLGeneratedData == null)
                {
                    result.DTDLGeneratedData = new DTDLGeneratedData();
                }

                if (result.DTDLGeneratedData.Telemetries == null)
                {
                    result.DTDLGeneratedData.Telemetries = telemetries;
                }
                else
                {
                    foreach (var item in telemetries)
                    {
                        result.DTDLGeneratedData.Telemetries.Add(item);
                    }
                }
            }

            //Look for properties (JSON)
            JArray readableProperties = ExtractReadableProperties(contents);

            if (readableProperties != null && readableProperties.Any())
            {
                if (result.DTDLGeneratedData == null)
                {
                    result.DTDLGeneratedData = new DTDLGeneratedData();
                }

                result.DTDLGeneratedData.ReadableProperties = readableProperties;
            }

            readableProperties = ExtractReadablePropertiesWithUnit(contents);
            if (readableProperties != null && readableProperties.Any())
            {
                if (result.DTDLGeneratedData == null)
                {
                    result.DTDLGeneratedData = new DTDLGeneratedData();
                }

                if (result.DTDLGeneratedData.ReadableProperties == null)
                {
                    result.DTDLGeneratedData.ReadableProperties = readableProperties;
                }
                else
                {
                    foreach (var item in readableProperties)
                    {
                        result.DTDLGeneratedData.ReadableProperties.Add(item);
                    }
                }
            }

            JArray writableProperties = ExtractWritableProperties(contents);

            if (writableProperties != null && writableProperties.Any())
            {
                if (result.DTDLGeneratedData == null)
                {
                    result.DTDLGeneratedData = new DTDLGeneratedData();
                }

                result.DTDLGeneratedData.WritableProperties = writableProperties;
            }

            writableProperties = ExtractWritablePropertiesWithUnit(contents);
            if (writableProperties != null && writableProperties.Any())
            {
                if (result.DTDLGeneratedData == null)
                {
                    result.DTDLGeneratedData = new DTDLGeneratedData();
                }

                if (result.DTDLGeneratedData.WritableProperties == null)
                {
                    result.DTDLGeneratedData.WritableProperties = writableProperties;
                }
                else
                {
                    foreach (var item in writableProperties)
                    {
                        result.DTDLGeneratedData.WritableProperties.Add(item);
                    }
                }
            }

            //Commands
            JArray commands = ExtractCommands(contents);

            if (commands != null && commands.Any())
            {
                if (result.DTDLGeneratedData == null)
                {
                    result.DTDLGeneratedData = new DTDLGeneratedData();
                }
                result.DTDLGeneratedData.Commands = commands;
            }

            commands = ExtractCommandsWithSemantic(contents);
            if (commands != null && commands.Any())
            {
                if (result.DTDLGeneratedData == null)
                {
                    result.DTDLGeneratedData = new DTDLGeneratedData();
                }

                if (result.DTDLGeneratedData.Commands == null)
                {
                    result.DTDLGeneratedData.Commands = commands;
                }
                else
                {
                    foreach (var item in commands)
                    {
                        result.DTDLGeneratedData.Commands.Add(item);
                    }
                }
            }

            return(result);
        }