/// <summary>IModfileViewElement interface.</summary>
        public void SetModfileView(ModfileView view)
        {
            // early out
            if (this.m_view == view)
            {
                return;
            }

            // unhook
            if (this.m_view != null)
            {
                this.m_view.onModfileChanged.RemoveListener(DisplayModfile);
            }

            // assign
            this.m_view = view;

            // hook
            if (this.m_view != null)
            {
                this.m_view.onModfileChanged.AddListener(DisplayModfile);
                this.DisplayModfile(this.m_view.modfile);
            }
            else
            {
                this.DisplayModfile(null);
            }
        }
        /// <summary>Initialize template.</summary>
        protected virtual void Start()
        {
            // check template
            #if DEBUG
            string message;
            if (!ModfileContainer.HasValidTemplate(this, out message))
            {
                Debug.LogError("[mod.io] " + message, this);
                return;
            }
            #endif

            // get template vars
            Transform templateParent         = this.containerTemplate.parent;
            string    templateInstance_name  = this.containerTemplate.gameObject.name + " (Instance)";
            int       templateInstance_index = this.containerTemplate.GetSiblingIndex() + 1;
            this.m_itemTemplate = this.containerTemplate.GetComponentInChildren <ModfileView>(true);

            // duplication protection
            bool isInstantiated = (templateParent.childCount > templateInstance_index &&
                                   templateParent.GetChild(templateInstance_index).gameObject.name == templateInstance_name);
            if (isInstantiated)
            {
                this.m_templateClone = templateParent.GetChild(templateInstance_index).gameObject;
                ModfileView[] viewInstances = this.m_templateClone.GetComponentsInChildren <ModfileView>(true);

                if (viewInstances == null ||
                    viewInstances.Length == 0)
                {
                    isInstantiated = false;
                    GameObject.Destroy(this.m_templateClone);
                }
                else
                {
                    this.m_container = (RectTransform)viewInstances[0].transform.parent;

                    foreach (ModfileView view in viewInstances)
                    {
                        GameObject.Destroy(view.gameObject);
                    }
                }
            }

            if (!isInstantiated)
            {
                this.m_templateClone = GameObject.Instantiate(this.containerTemplate.gameObject, templateParent);
                this.m_templateClone.transform.SetSiblingIndex(templateInstance_index);
                this.m_templateClone.name = templateInstance_name;

                ModfileView viewInstance = this.m_templateClone.GetComponentInChildren <ModfileView>(true);
                this.m_container = (RectTransform)viewInstance.transform.parent;
                GameObject.Destroy(viewInstance.gameObject);

                this.m_templateClone.SetActive(true);
            }

            this.DisplayModfiles(this.m_modfiles);
        }
        // ---------[ UTILITY ]---------
        /// <summary>Checks a ModfileContainer's template structure.</summary>
        public static bool HasValidTemplate(ModfileContainer container, out string helpMessage)
        {
            helpMessage = null;
            bool isValid = true;

            ModfileView itemTemplate = null;

            // null check
            if (container.containerTemplate == null)
            {
                helpMessage = ("Invalid template:"
                               + " The container template is unassigned.");
                isValid = false;
            }
            // containerTemplate is child of Component
            else if (!container.containerTemplate.IsChildOf(container.transform) ||
                     container.containerTemplate == container.transform)
            {
                helpMessage = ("Invalid template:"
                               + " The container template must be a child of this object.");
                isValid = false;
            }
            // ModfileView is found under containerTemplate
            else if ((itemTemplate = container.containerTemplate.gameObject.GetComponentInChildren <ModfileView>()) == null)
            {
                helpMessage = ("Invalid template:"
                               + " No ModfileView component found in the children of the container template.");
                isValid = false;
            }
            // ModfileView is on same gameObject as containerTemplate
            else if (itemTemplate.transform == container.containerTemplate)
            {
                helpMessage = ("Invalid template:"
                               + " The ModfileView component cannot share a GameObject with the container template.");
                isValid = false;
            }

            return(isValid);
        }
        // ---------[ INITIALIZATION ]---------
        protected virtual void Awake()
        {
            #if DEBUG
            ModfileView nested = this.gameObject.GetComponentInChildren <ModfileView>(true);
            if (nested != null && nested != this)
            {
                Debug.LogError("[mod.io] Nesting ModfileViews is currently not supported due to the"
                               + " way IModfileViewElement component parenting works."
                               + "\nThe nested ModfileViews must be removed to allow ModfileView functionality."
                               + "\nthis=" + this.gameObject.name
                               + "\nnested=" + nested.gameObject.name,
                               this);
                return;
            }
            #endif

            // assign modfile view elements to this
            var modfileViewElements = this.gameObject.GetComponentsInChildren <IModfileViewElement>(true);
            foreach (IModfileViewElement viewElement in modfileViewElements)
            {
                viewElement.SetModfileView(this);
            }
        }