/// <summary> /// Creates a context object from meta data. /// </summary> /// <param name="index">The index of the object.</param> /// <param name="group">The object group of the object.</param> /// <param name="isChildObject">is true if thi sobject is the child of another object.</param> /// <param name="data">The meta data.</param> /// <returns>A context object.</returns> private static ScriptingContextObject CreateContextObject(int index, string group, bool isChildObject, StructureValueCollection data, int wrapperIndex = -1) { string name = data.HasStringID("Name") ? data.GetStringID("Name") : data.GetString("Name"); var result = new ScriptingContextObject(name.ToLowerInvariant(), index, group, isChildObject, wrapperIndex); var childBlocks = data.GetTagBlocks(); if (childBlocks.Length > 0) { foreach (var block in childBlocks.Where(b => b.Value.Length > 0)) { // Handle child blocks, which are wrapped up in another block without a name field. if (IsWrapperBlock(block)) { var wrappedBlocks = new Dictionary <string, List <ScriptingContextObject> >(); // Iterate through the wrapper elements and collect all wrapped blocks and their objects. for (int i = 0; i < block.Value.Length; i++) { var innerChildrenBlocks = block.Value[i].GetTagBlocks(); foreach (var inner in innerChildrenBlocks) { var wrappedObjects = GetWrapperContextObjects(inner, i); if (wrappedBlocks.ContainsKey(inner.Key)) { wrappedBlocks[inner.Key].AddRange(wrappedObjects); } else { wrappedBlocks[inner.Key] = wrappedObjects.ToList(); } } } // Add the grouped blocks and objects to the result. foreach (var groupedBlock in wrappedBlocks) { result.AddChildBlock(new ScriptingContextBlock(groupedBlock.Key, groupedBlock.Value)); } } // Handle regular child blocks. else { result.AddChildBlock(CreateContextBlock(block, true)); } } } return(result); }