private void ProcessElementToPlan(IPlan parentPlan, IPlan rootPlan, XmlElement currentElement, List <IPlan> rootPlans, int depth, Func <IPlan, object, bool> filter) { switch (currentElement.LocalName) { case "gameObjectFolder": { foreach (var childElement in currentElement.ChildNodes.OfType <XmlElement>()) { ProcessElementToPlan(parentPlan, rootPlan, childElement, rootPlans, depth, filter); } break; } case "resource": { // This is used directly by the parent game object. break; } case "gameObject": { Type targetType = null; var xsiType = currentElement.GetAttribute("xsi:type"); if (xsiType == "gameObjectGroupType") { targetType = typeof(EntityGroup); } else if (xsiType == "locatorType") { targetType = typeof(LocatorEntity); } else if (xsiType == "DirLight") { targetType = typeof(DefaultDirectionalLightEntity); } else if (xsiType == "PointLight") { targetType = typeof(DefaultPointLightEntity); } var qualifiedName = currentElement.GetAttribute("qualifiedName"); if (!string.IsNullOrEmpty(qualifiedName)) { targetType = Type.GetType(qualifiedName); } if (targetType == null) { break; } var queryType = typeof(IEditorQuery <>).MakeGenericType(targetType); var plan = _kernel.Plan( targetType, (INode)parentPlan, null, null, (INode)rootPlan, null, null, new Dictionary <Type, List <IMapping> > { { queryType, new List <IMapping> { new DefaultMapping( null, ctx => ResolveEditorQueryForElement(ctx, queryType, targetType, currentElement), false, null, null, true, true, null) } } }); if (filter != null && !filter(plan, currentElement)) { // Discard this plan; it has been filtered out. _kernel.Discard(plan); } else { _hierarchy.AddChildNode(parentPlan, (INode)plan); if (rootPlan == null) { rootPlan = (INode)plan; } if (depth == 0) { rootPlans.Add(plan); } foreach (var childElement in currentElement.ChildNodes.OfType <XmlElement>()) { ProcessElementToPlan(plan, rootPlan, childElement, null, depth + 1, filter); } if (depth > 0) { parentPlan.PlannedCreatedNodes.InsertRange(0, plan.PlannedCreatedNodes); } } break; } } }