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);
            }
        }