protected virtual void ParseDerv(IFFFile.Node node, ITemplateRepository repo)
        {
            var dervOfNode = node.FindSubNode("XXXX");

            if (dervOfNode == null)
            {
                return;
            }

            var offset     = 0;
            var dervString = dervOfNode.Data.ReadAsciiString(ref offset);

            if (string.IsNullOrEmpty(dervString))
            {
                return;
            }


            if (_loadedDervs.Contains(dervString))
            {
                return;
            }

            var dervIff = repo.LoadIff(dervString);

            if (dervIff == null)
            {
                return;
            }

            _loadedDervs.Add(dervString);
            ReadFile(dervIff, repo);
        }
        protected void ParseData(IFFFile.Node node, ITemplateRepository repo, Action <IFFFile.Node, ITemplateRepository> parseDataAction, LogAbstraction.ILogger logger, Action <IFFFile.Node, ITemplateRepository> parseDerveAction = null, bool parseNext = true)
        {
            if (parseDerveAction == null)
            {
                parseDerveAction = ParseDerv;
            }

            var derv = node.FindSubNode("DERV");

            if (derv != null)
            {
                parseDerveAction(node, repo);
            }

            var nextNode = derv != null?derv.FindNextSibling() : node.Children.FirstOrDefault();

            if (nextNode == null)
            {
                _Logger.Trace("unable to locate next node for node {0}", node.Type);
                return;
            }

            var sizeNode = nextNode.FindSubNode("PCNT", true);

            if (sizeNode == null || nextNode.Children == null)
            {
                logger.Trace("Unable to locate PCNT node or its parent for node {0}", node.Type);
                return;
            }

            var nodeList = nextNode.Children.ToList();
            var size     = sizeNode.Data.ReadInt32();

            if (size == 0 || size != nodeList.Count - 1)
            {
                return;
            }

            for (int i = 0; i < size; i++)
            {
                switch (nodeList[i].Type)
                {
                case "PCNT":
                    continue;

                case "XXXX":
                    parseDataAction(nodeList[i], repo);
                    break;

                case "DERV":
                    parseDerveAction(nodeList[i], repo);
                    break;

                default:
                    logger.Warn("Invalid node type {0}", nodeList[i].Type);
                    break;
                }
            }

            nextNode = nextNode.FindNextSibling();

            if (parseNext && nextNode != null)
            {
                ReadNode(nextNode, repo);
            }
        }