// ReSharper restore UnassignedField.Global
#endif

        internal static void Process(List <Node> removals)
        {
            if (0 == removals.Count)
            {
                return;
            }

#if DEBUG
            if (DebugMode)
            {
                Debug.Log(string.Format("Processing {0} removals.", removals.Count));
            }
#endif
            //Debug.Log(string.Format("Processing {0} removals.", removals.Count));
            // TODO: do removals bottom up! nesting level should be used here

            foreach (Node node in removals)
            {
                //if (null == node.Transform)
                //    continue; // ROOT

                node.RemoveFromHierarchy();

                //Debug.Log("node.ParentTransform: " + node.ParentTransform);
                if (null == node.ParentTransform) //|| /*!*/(adapter is StageAdapter))
                {
                    continue;                     // not a stage, return (if stage, should process)
                }
                // consolidate parent transform

                ComponentAdapter adapter = node.Adapter;

                GroupAdapter parentGroupAdapter = GuiLookup.GetAdapter(node.ParentTransform) as GroupAdapter;
                if (null != parentGroupAdapter)
                {
                    /**
                     * Stop monitoring
                     * */
                    PersistenceManager.Instance.Unwatch(node.AdapterId);

                    //PersistenceManager.Instance.RemoveAdapter(node.AdapterId);

                    /**
                     * Note: if object removed from the hierarchy, the adapter is destroyed
                     * In that case following command doesn nothing (doesn not remove the slot from the parent)
                     * Thus we have the consolidation below (removing null)
                     * */
                    parentGroupAdapter.RemoveChild(adapter);

                    // TODO: consolidate only for top level removals (add parameter)

                    /*parentContainerAdapter.RemoveChild(adapter);*/
                    //parentContainerAdapter.RemoveAllChildren();
                    ChildGroupPack pack = ChildGroupPack.Read(parentGroupAdapter);
                    pack.Consolidate(); // there is a null slot here. We have to re-render children
                    //Debug.Log("*pack: " + pack);
                    parentGroupAdapter.InstantiateChildren(true);
                }
            }
        }
// ReSharper restore UnassignedField.Global
#endif

        /// <summary>
        /// Is processing additions, as well as top level additions
        /// </summary>
        /// <param name="topLevelAdditions">Needed for adding into order</param>
        /// <param name="additions">Needed for child instantiation</param>
        internal static void Process(List <Node> topLevelAdditions, List <Node> additions)
        {
            if (0 == topLevelAdditions.Count && 0 == additions.Count)
            {
                return;
            }

#if DEBUG
            if (DebugMode)
            {
                Debug.Log(string.Format("Processing {0} topLevelAdditions, {1} additions.", topLevelAdditions.Count, additions.Count));
            }
#endif
            foreach (Node node in additions)
            {
                bool isTopLevelAddition = topLevelAdditions.Contains(node);
                bool isPrefab           = PrefabUtility.GetPrefabType(node.Adapter) == PrefabType.PrefabInstance;

                /**
                 * 1. Process transforms
                 * */
                Transform transform = node.Transform;

                if (null == transform)
                {
                    continue; // ROOT
                }
                ComponentAdapter adapter = GuiLookup.GetAdapter(transform);
                bool             isStage = adapter is StageAdapter;

                Transform parentTransform = node.ParentTransform;

                if (null == parentTransform && !isStage)
                {
                    continue; // not a stage, return (if stage, should process)
                }
                GroupAdapter parentAdapter = null;

                if (null != parentTransform)
                {
                    parentAdapter = GuiLookup.GetAdapter(node.ParentTransform) as GroupAdapter;
                }

                /**
                 * 2. Process adapters
                 * */
                if (null != adapter)
                {
                    // this is eDriven.Gui component. process it properly
                    if (null == parentAdapter)
                    {
                        if (!isStage)
                        {
                            const string txt = "eDriven.Gui components could be added to containers only";
                            throw new Exception(txt);
                        }
                    }
                    else
                    {
                        /**
                         * Update parent ordering for top level additions only!
                         * */
                        if (isTopLevelAddition)
                        {
                            //node.Transform.parent = parentTransform;
                            parentAdapter.AddChild(adapter, true); // instantiate and change the parent collection

                            // ReSharper disable once RedundantCheckBeforeAssignment
                            if (adapter.transform.parent != parentTransform) // avoid multiple OnHierarchyChange callbacks
                            {
                                adapter.transform.parent = parentTransform;
                            }

                            //adapter.transform.parent = parentTransform;
                            ParentChildLinker.Instance.Update(parentAdapter);
                        }
                        else
                        {
                            //parentAdapter.DoInstantiate(adapter, true); // instantiate only
                            ChildGroupPack pack = ChildGroupPack.Read(parentAdapter);
                            pack.Consolidate(); // there is a null slot here. We have to re-render children
                            parentAdapter.InstantiateChildren(true);
                        }

                        /**
                         * Instantiate component
                         * */
                        if (!adapter.Instantiated)
                        {
                            adapter.DoInstantiate(true);
                        }

                        /**
                         * By now, the component should be instantiated
                         * */
                        var cmp = adapter.Component;
                        if (null == cmp)
                        {
                            throw new Exception("Component not found on ComponentAdapter: " + adapter);
                        }
                    }
                }

                /**
                 * 3. If adapter stuff went without a problem...
                 * */
                // ReSharper disable once RedundantCheckBeforeAssignment
                if (node.Transform.parent != parentTransform)
                {
                    node.Transform.parent = parentTransform;
                }
            }
        }