示例#1
0
        static void Main(string[] args)
        {
            string inputFilename = args[0];
            string outputFilename = args[1];
            string isaControlNumber = args.Length > 2 ? args[2] : "999";
            string gsControlNumber = args.Length > 3 ? args[3] : "99";

            var service = new X12AcknowledgmentService();

            using (FileStream fs = new FileStream(inputFilename, FileMode.Open, FileAccess.Read))
            {
                using (X12StreamReader reader = new X12StreamReader(fs, Encoding.UTF8))
                {
                    var firstTrans = reader.ReadNextTransaction();
                    if (reader.LastTransactionCode == "837")
                    {
                        if (reader.TransactionContainsSegment(firstTrans.Transactions[0], "SV2"))
                            service = new InstitutionalClaimAcknowledgmentService();
                        if (reader.TransactionContainsSegment(firstTrans.Transactions[0], "SV1"))
                            service = new X12AcknowledgmentService(new ProfessionalClaimSpecificationFinder());
                    }
                }
            }

            using (FileStream fs = new FileStream(inputFilename, FileMode.Open, FileAccess.Read))
            {
                // Create aknowledgements and identify errors
                var responses = service.AcknowledgeTransactions(fs);

                // Change any acknowledgment codes here to reject transactions with errors
                // CUSTOM BUSINESS LOGIC HERE

                // Transform to outbound interchange for serialization
                var interchange = new Interchange(DateTime.Now, int.Parse(isaControlNumber), true);
                interchange.AuthorInfoQualifier = ConfigurationManager.AppSettings["AuthorInfoQualifier"];
                interchange.AuthorInfo = ConfigurationManager.AppSettings["AuthorInfo"];
                interchange.SecurityInfoQualifier = ConfigurationManager.AppSettings["SecurityInfoQualifier"];
                interchange.SecurityInfo = ConfigurationManager.AppSettings["SecurityInfo"];
                interchange.InterchangeSenderIdQualifier = ConfigurationManager.AppSettings["InterchangeSenderIdQualifier"];
                interchange.InterchangeSenderId = ConfigurationManager.AppSettings["InterchangeSenderId"];
                interchange.InterchangeReceiverIdQualifier = responses.First().SenderIdQualifier;
                interchange.InterchangeReceiverId = responses.First().SenderId;
                interchange.SetElement(12, "00501");

                var group = interchange.AddFunctionGroup("FA", DateTime.Now, int.Parse(gsControlNumber));
                group.ApplicationSendersCode = ConfigurationManager.AppSettings["InterchangeSenderId"];
                group.VersionIdentifierCode = "005010X231A1";

                group.Add999Transaction(responses);

                // This is a demonstration example only, change true to false to create continous x12 without line feeds.
                File.WriteAllText(outputFilename, interchange.SerializeToX12(true));
            }
        }
示例#2
0
        static void Main(string[] args)
        {
            var opts = new ExecutionOptions();
            try
            {
                opts.LoadOptions(args);
            }
            catch (ArgumentException exc)
            {
                Console.Write(exc.Message);
                return;
            }

            X12Parser parser = new X12Parser();

            foreach (var filename in Directory.GetFiles(opts.InputDirectory, opts.FilenamePattern))
            {
                FileInfo inputFile = new FileInfo(filename);
                List<Interchange> list = new List<Interchange>();
                using (FileStream fs = new FileStream(inputFile.FullName, FileMode.Open, FileAccess.Read))
                {
                    X12StreamReader reader = new X12StreamReader(fs, Encoding.UTF8);
                    X12FlatTransaction transaction = reader.ReadNextTransaction();
                    while (!string.IsNullOrEmpty(transaction.Transactions.First()))
                    {
                        string x12 = transaction.ToString();
                        var interchange = parser.ParseMultiple(x12).First();
                        if (opts.LoopId == "ST")
                            list.Add(interchange);
                        else
                        {
                            list.AddRange(parser.UnbundleByLoop(interchange, opts.LoopId));
                        }
                        transaction = reader.ReadNextTransaction();
                    }
                }
                List<Interchange> interchanges = parser.ParseMultiple(new FileStream(filename, FileMode.Open, FileAccess.Read));
                for (int i = 0; i < list.Count; i++)
                {
                    string outputFilename = String.Format(opts.FormatString, opts.OutputDirectory, inputFile.Name, i + 1, inputFile.Extension);
                    using (FileStream outputFilestream = new FileStream(outputFilename, FileMode.Create, FileAccess.Write))
                    {
                        using (StreamWriter writer = new StreamWriter(outputFilestream))
                        {
                            writer.Write(list[i].SerializeToX12(opts.IncludeWhitespace));
                            writer.Close();
                        }
                        outputFilestream.Close();
                    }
                }
            }
        }
示例#3
0
        public List <Interchange> ParseMultiple(Stream stream, Encoding encoding)
        {
            var envelopes = new List <Interchange>();

            using (X12StreamReader reader = new X12StreamReader(stream, encoding))
            {
                Interchange envelop = new Interchange(_specFinder, reader.CurrentIsaSegment);
                envelopes.Add(envelop);
                Container     currentContainer = envelop;
                FunctionGroup fg = null;
                Transaction   tr = null;
                Dictionary <string, HierarchicalLoop> hloops = new Dictionary <string, HierarchicalLoop>();

                string segmentString = reader.ReadNextSegment();
                string segmentId     = reader.ReadSegmentId(segmentString);
                int    segmentIndex  = 1;
                while (segmentString.Length > 0)
                {
                    switch (segmentId)
                    {
                    case "ISA":
                        envelop = new Interchange(_specFinder, segmentString + reader.Delimiters.SegmentTerminator);
                        envelopes.Add(envelop);
                        currentContainer = envelop;
                        fg     = null;
                        tr     = null;
                        hloops = new Dictionary <string, HierarchicalLoop>();
                        break;

                    case "IEA":
                        if (envelop == null)
                        {
                            throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString));
                        }
                        envelop.SetTerminatingTrailerSegment(segmentString);
                        break;

                    case "GS":
                        if (envelop == null)
                        {
                            throw new InvalidOperationException(String.Format("Segment '{0}' cannot occur before and ISA segment.", segmentString));
                        }

                        currentContainer = fg = envelop.AddFunctionGroup(segmentString);;
                        break;

                    case "GE":
                        if (fg == null)
                        {
                            throw new InvalidOperationException(String.Format("Segment '{0}' does not have a matching GS segment precending it.", segmentString));
                        }
                        fg.SetTerminatingTrailerSegment(segmentString);
                        fg = null;
                        break;

                    case "ST":
                        if (fg == null)
                        {
                            throw new InvalidOperationException(string.Format("segment '{0}' cannot occur without a preceding GS segment.", segmentString));
                        }
                        segmentIndex     = 1;
                        currentContainer = tr = fg.AddTransaction(segmentString);
                        hloops           = new Dictionary <string, HierarchicalLoop>();
                        break;

                    case "SE":
                        if (tr == null)
                        {
                            throw new InvalidOperationException(string.Format("Segment '{0}' does not have a matching ST segment preceding it.", segmentString));
                        }

                        tr.SetTerminatingTrailerSegment(segmentString);
                        tr = null;
                        break;

                    case "HL":
                        Segment hlSegment = new Segment(null, reader.Delimiters, segmentString);
                        string  id        = hlSegment.GetElement(1);
                        string  parentId  = hlSegment.GetElement(2);

                        if (parentId == "")
                        {
                            currentContainer = tr.AddHLoop(segmentString);
                        }
                        else
                        {
                            if (hloops.ContainsKey(parentId))
                            {
                                currentContainer = hloops[parentId].AddHLoop(segmentString);
                            }
                            else
                            {
                                throw new InvalidOperationException(String.Format("Hierarchical Loop {0} expects Parent ID {1} which did not occur preceding it.", id, parentId));
                            }
                        }
                        if (hloops.ContainsKey(id))
                        {
                            throw new InvalidOperationException(String.Format("Hierarchical Loop {0} cannot be added to transaction {1} because the ID {2} already exists.", segmentString, tr.ControlNumber, id));
                        }
                        hloops.Add(id, (HierarchicalLoop)currentContainer);
                        break;

                    case "TA1":     // Technical acknowledgement
                        if (envelop == null)
                        {
                            throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString));
                        }
                        envelop.AddSegment(segmentString);
                        break;

                    default:
                        while (currentContainer != null)
                        {
                            if (currentContainer.AddSegment(segmentString) != null)
                            {
                                break;
                            }
                            else
                            {
                                if (currentContainer is LoopContainer)
                                {
                                    LoopContainer loopContainer = (LoopContainer)currentContainer;

                                    Loop newLoop = loopContainer.AddLoop(segmentString);
                                    if (newLoop != null)
                                    {
                                        currentContainer = newLoop;
                                        break;
                                    }
                                    else
                                    {
                                        if (currentContainer is Transaction)
                                        {
                                            var tran = (Transaction)currentContainer;

                                            throw new TransactionValidationException(
                                                      "Segment '{3}' in segment position {4} within transaction '{1}' cannot be identified within the supplied specification for transaction set {0}.", tran.IdentifierCode, tran.ControlNumber, "", segmentString, segmentIndex);
                                        }
                                        else
                                        {
                                            currentContainer = currentContainer.Parent;
                                            continue;
                                        }
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                        break;
                    }
                    segmentString = reader.ReadNextSegment();
                    segmentId     = reader.ReadSegmentId(segmentString);
                    segmentIndex++;
                }
                return(envelopes);
            }
        }
示例#4
0
        static void Main(string[] args)
        {
            int maxBatchSize = 10 * 1012 * 1012; // 10 Mbytes
            if (ConfigurationManager.AppSettings["MaxBatchSize"] != null)
                maxBatchSize = Convert.ToInt32(ConfigurationManager.AppSettings["MaxBatchSize"]);

            string x12Filename = args[0];
            string outputFilename = args.Length > 1 ? args[1] : x12Filename + ".xml";

            OopFactory.X12.Parsing.X12Parser parser = new Parsing.X12Parser();

            byte[] header = new byte[6];
            using (FileStream fs = new FileStream(x12Filename, FileMode.Open, FileAccess.Read))
            {
                // peak at first 6 characters to determine if this is a unicode file
                fs.Read(header, 0, 6);
                fs.Close();
            }
            Encoding encoding = (header[1] == 0 && header[3] == 0 && header[5] == 0) ? Encoding.Unicode : Encoding.UTF8;

            if (new FileInfo(x12Filename).Length <= maxBatchSize)
            {
                using (FileStream fs = new FileStream(x12Filename, FileMode.Open, FileAccess.Read))
                {
                    var interchanges = parser.ParseMultiple(fs, encoding);
                    if (interchanges.Count >= 1)
                    {
                        using (FileStream outputFs = new FileStream(outputFilename, FileMode.Create))
                        {
                            interchanges.First().Serialize(outputFs);
                        }
                    }
                    if (interchanges.Count > 1)
                    {
                        for (int i = 1; i < interchanges.Count; i++)
                        {
                            outputFilename = string.Format("{0}_{1}.xml", args.Length > 1 ? args[1] : x12Filename, i + 1);
                            using (FileStream outputFs = new FileStream(outputFilename, FileMode.Create))
                            {
                                interchanges[i].Serialize(outputFs);
                            }
                        }
                    }
                }
            }
            else
            {
                using (FileStream fs = new FileStream(x12Filename, FileMode.Open, FileAccess.Read))
                {
                    // Break up output files by batch size
                    X12StreamReader reader = new X12StreamReader(fs, encoding);
                    X12FlatTransaction currentTransactions = reader.ReadNextTransaction();
                    X12FlatTransaction nextTransaction = reader.ReadNextTransaction();
                    int i = 1;
                    while (!string.IsNullOrEmpty(nextTransaction.Transactions.First()))
                    {
                        if (currentTransactions.GetSize() + nextTransaction.GetSize() < maxBatchSize
                            && currentTransactions.IsaSegment == nextTransaction.IsaSegment
                            && currentTransactions.GsSegment == nextTransaction.GsSegment)
                        {
                            currentTransactions.Transactions.AddRange(nextTransaction.Transactions);
                        }
                        else
                        {
                            outputFilename = string.Format("{0}_{1}.xml", args.Length > 1 ? args[1] : x12Filename, i++);
                            using (FileStream outputFs = new FileStream(outputFilename, FileMode.Create))
                            {
                                parser.ParseMultiple(currentTransactions.ToString()).First().Serialize(outputFs);
                            }
                            currentTransactions = nextTransaction;

                        }

                        nextTransaction = reader.ReadNextTransaction();
                    }

                    outputFilename = string.Format("{0}_{1}.xml", args.Length > 1 ? args[1] : x12Filename, i++);
                    using (FileStream outputFs = new FileStream(outputFilename, FileMode.Create))
                    {
                        parser.ParseMultiple(currentTransactions.ToString()).First().Serialize(outputFs);
                    }
                }
            }
        }
示例#5
0
        public List<Interchange> ParseMultiple(Stream stream, Encoding encoding)
        {
            var envelopes = new List<Interchange>();

            using (X12StreamReader reader = new X12StreamReader(stream, encoding))
            {
                Interchange envelop = new Interchange(_specFinder, reader.CurrentIsaSegment);
                envelopes.Add(envelop);
                Container currentContainer = envelop;
                FunctionGroup fg = null;
                Transaction tr = null;
                Dictionary<string, HierarchicalLoop> hloops = new Dictionary<string, HierarchicalLoop>();

                string segmentString = reader.ReadNextSegment();
                string segmentId = reader.ReadSegmentId(segmentString);
                int segmentIndex = 1;
                while (segmentString.Length > 0)
                {
                    switch (segmentId)
                    {
                        case "ISA":
                            envelop = new Interchange(_specFinder, segmentString + reader.Delimiters.SegmentTerminator);
                            envelopes.Add(envelop);
                            currentContainer = envelop;
                            fg = null;
                            tr = null;
                            hloops = new Dictionary<string, HierarchicalLoop>();
                            break;
                        case "IEA":
                            if (envelop == null)
                                throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString));
                            envelop.SetTerminatingTrailerSegment(segmentString);
                            break;
                        case "GS":
                            if (envelop == null)
                                throw new InvalidOperationException(String.Format("Segment '{0}' cannot occur before and ISA segment.", segmentString));

                            currentContainer = fg = envelop.AddFunctionGroup(segmentString); ;
                            break;
                        case "GE":
                            if (fg == null)
                                throw new InvalidOperationException(String.Format("Segment '{0}' does not have a matching GS segment precending it.", segmentString));
                            fg.SetTerminatingTrailerSegment(segmentString);
                            fg = null;
                            break;
                        case "ST":
                            if (fg == null)
                                throw new InvalidOperationException(string.Format("segment '{0}' cannot occur without a preceding GS segment.", segmentString));
                            segmentIndex = 1;
                            currentContainer = tr = fg.AddTransaction(segmentString);
                            hloops = new Dictionary<string, HierarchicalLoop>();
                            break;
                        case "SE":
                            if (tr == null)
                                throw new InvalidOperationException(string.Format("Segment '{0}' does not have a matching ST segment preceding it.", segmentString));

                            tr.SetTerminatingTrailerSegment(segmentString);
                            tr = null;
                            break;
                        case "HL":
                            Segment hlSegment = new Segment(null, reader.Delimiters, segmentString);
                            string id = hlSegment.GetElement(1);
                            string parentId = hlSegment.GetElement(2);

                            if (parentId == "")
                                currentContainer = tr.AddHLoop(segmentString);
                            else
                            {
                                if (hloops.ContainsKey(parentId))
                                    currentContainer = hloops[parentId].AddHLoop(segmentString);
                                else
                                    throw new InvalidOperationException(String.Format("Hierarchical Loop {0} expects Parent ID {1} which did not occur preceding it.", id, parentId));
                            }
                            if (hloops.ContainsKey(id))
                                throw new InvalidOperationException(String.Format("Hierarchical Loop {0} cannot be added to transaction {1} because the ID {2} already exists.", segmentString, tr.ControlNumber, id));
                            hloops.Add(id, (HierarchicalLoop)currentContainer);
                            break;
                        case "TA1": // Technical acknowledgement
                            if (envelop == null)
                                throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString));
                            envelop.AddSegment(segmentString);
                            break;
                        default:
                            while (currentContainer != null)
                            {
                                if (currentContainer.AddSegment(segmentString) != null)
                                    break;
                                else
                                {
                                    if (currentContainer is LoopContainer)
                                    {
                                        LoopContainer loopContainer = (LoopContainer)currentContainer;

                                        Loop newLoop = loopContainer.AddLoop(segmentString);
                                        if (newLoop != null)
                                        {
                                            currentContainer = newLoop;
                                            break;
                                        }
                                        else
                                        {
                                            if (currentContainer is Transaction)
                                            {
                                                var tran = (Transaction)currentContainer;

                                                throw new TransactionValidationException(
                                                    "Segment '{3}' in segment position {4} within transaction '{1}' cannot be identified within the supplied specification for transaction set {0}.", tran.IdentifierCode, tran.ControlNumber, "", segmentString, segmentIndex);
                                            }
                                            else
                                            {
                                                currentContainer = currentContainer.Parent;
                                                continue;
                                            }
                                        }
                                    }
                                    else
                                        break;
                                }
                            }
                            break;

                    }
                    segmentString = reader.ReadNextSegment();
                    segmentId = reader.ReadSegmentId(segmentString);
                    segmentIndex++;
                }
                return envelopes;
            }
        }
示例#6
0
        public List <Interchange> ParseMultiple(Stream stream, Encoding encoding)
        {
            var envelopes = new List <Interchange>();

            using (X12StreamReader reader = new X12StreamReader(stream, encoding, _ignoredChars))
            {
                Interchange envelop = new Interchange(_specFinder, reader.CurrentIsaSegment);
                envelopes.Add(envelop);
                Container     currentContainer = envelop;
                FunctionGroup fg = null;
                Transaction   tr = null;
                Dictionary <string, HierarchicalLoop> hloops = new Dictionary <string, HierarchicalLoop>();

                string         segmentString  = reader.ReadNextSegment();
                string         segmentId      = reader.ReadSegmentId(segmentString);
                int            segmentIndex   = 1;
                Stack <string> containerStack = new Stack <string>();
                while (segmentString.Length > 0)
                {
                    switch (segmentId)
                    {
                    case "ISA":
                        envelop = new Interchange(_specFinder, segmentString + reader.Delimiters.SegmentTerminator);
                        envelopes.Add(envelop);
                        currentContainer = envelop;
                        fg     = null;
                        tr     = null;
                        hloops = new Dictionary <string, HierarchicalLoop>();
                        break;

                    case "IEA":
                        if (envelop == null)
                        {
                            throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString));
                        }
                        envelop.SetTerminatingTrailerSegment(segmentString);
                        break;

                    case "GS":
                        if (envelop == null)
                        {
                            throw new InvalidOperationException(String.Format("Segment '{0}' cannot occur before and ISA segment.", segmentString));
                        }

                        currentContainer = fg = envelop.AddFunctionGroup(segmentString);;
                        break;

                    case "GE":
                        if (fg == null)
                        {
                            throw new InvalidOperationException(String.Format("Segment '{0}' does not have a matching GS segment precending it.", segmentString));
                        }
                        fg.SetTerminatingTrailerSegment(segmentString);
                        fg = null;
                        break;

                    case "ST":
                        if (fg == null)
                        {
                            throw new InvalidOperationException(string.Format("segment '{0}' cannot occur without a preceding GS segment.", segmentString));
                        }
                        segmentIndex     = 1;
                        currentContainer = tr = fg.AddTransaction(segmentString);
                        hloops           = new Dictionary <string, HierarchicalLoop>();
                        break;

                    case "SE":
                        if (tr == null)
                        {
                            throw new InvalidOperationException(string.Format("Segment '{0}' does not have a matching ST segment preceding it.", segmentString));
                        }

                        tr.SetTerminatingTrailerSegment(segmentString);
                        tr = null;
                        break;

                    case "HL":
                        Segment hlSegment = new Segment(null, reader.Delimiters, segmentString);
                        string  id        = hlSegment.GetElement(1);
                        string  parentId  = hlSegment.GetElement(2);
                        string  levelCode = hlSegment.GetElement(3);

                        while (!(currentContainer is HierarchicalLoopContainer) || !((HierarchicalLoopContainer)currentContainer).AllowsHierarchicalLoop(levelCode))
                        {
                            if (currentContainer.Parent != null)
                            {
                                currentContainer = currentContainer.Parent;
                            }
                            else
                            {
                                throw new InvalidOperationException(String.Format("Heierchical Loop {0}  cannot be added to transaction set {1} because it's specification cannot be identified.", segmentString, tr.ControlNumber));
                            }
                        }
                        bool parentFound = false;
                        if (parentId != "")
                        {
                            if (hloops.ContainsKey(parentId))
                            {
                                parentFound      = true;
                                currentContainer = hloops[parentId].AddHLoop(segmentString);
                            }
                            else
                            {
                                if (_throwExceptionOnSyntaxErrors)
                                {
                                    throw new InvalidOperationException(String.Format("Hierarchical Loop {0} expects Parent ID {1} which did not occur preceding it.  To change this to a warning, pass throwExceptionOnSyntaxErrors = false to the X12Parser constructor.", id, parentId));
                                }
                                else
                                {
                                    OnParserWarning(new X12ParserWarningEventArgs
                                    {
                                        FileIsValid = false,
                                        InterchangeControlNumber     = envelop.InterchangeControlNumber,
                                        FunctionalGroupControlNumber = fg.ControlNumber,
                                        TransactionControlNumber     = tr.ControlNumber,
                                        SegmentPositionInInterchange = segmentIndex,
                                        Segment   = segmentString,
                                        SegmentId = segmentId,
                                        Message   = String.Format("Hierarchical Loop {0} expects Parent ID {1} which did not occur preceding it.  This will be parsed as if it has no parent, but the file may not be valid.", id, parentId)
                                    });
                                }
                            }
                        }

                        if (parentId == "" || !parentFound)
                        {
                            while (!(currentContainer is HierarchicalLoopContainer && ((HierarchicalLoopContainer)currentContainer).HasHierachicalSpecs()))
                            {
                                currentContainer = currentContainer.Parent;
                            }
                            currentContainer = ((HierarchicalLoopContainer)currentContainer).AddHLoop(segmentString);
                            //hloops = new Dictionary<string, HierarchicalLoop>();
                        }
                        if (hloops.ContainsKey(id))
                        {
                            throw new InvalidOperationException(String.Format("Hierarchical Loop {0} cannot be added to transaction {1} because the ID {2} already exists.", segmentString, tr.ControlNumber, id));
                        }
                        hloops.Add(id, (HierarchicalLoop)currentContainer);
                        break;

                    case "TA1":     // Technical acknowledgement
                        if (envelop == null)
                        {
                            throw new InvalidOperationException(string.Format("Segment {0} does not have a matching ISA segment preceding it.", segmentString));
                        }
                        envelop.AddSegment(segmentString);
                        break;

                    default:
                        var originalContainer = currentContainer;
                        containerStack.Clear();
                        while (currentContainer != null)
                        {
                            if (currentContainer.AddSegment(segmentString) != null)
                            {
                                if (segmentId == "LE")
                                {
                                    currentContainer = currentContainer.Parent;
                                }
                                break;
                            }
                            else
                            {
                                if (currentContainer is LoopContainer)
                                {
                                    LoopContainer loopContainer = (LoopContainer)currentContainer;

                                    Loop newLoop = loopContainer.AddLoop(segmentString);
                                    if (newLoop != null)
                                    {
                                        currentContainer = newLoop;
                                        break;
                                    }
                                    else
                                    {
                                        if (currentContainer is Transaction)
                                        {
                                            var tran = (Transaction)currentContainer;

                                            if (_throwExceptionOnSyntaxErrors)
                                            {
                                                throw new TransactionValidationException(
                                                          "Segment '{3}' in segment position {4} within transaction '{1}' cannot be identified within the supplied specification for transaction set {0} in any of the expected loops: {5}.  To change this to a warning, pass throwExceptionOnSyntaxErrors = false to the X12Parser constructor.", tran.IdentifierCode, tran.ControlNumber, "", segmentString, segmentIndex, string.Join(",", containerStack));
                                            }
                                            else
                                            {
                                                currentContainer = originalContainer;
                                                currentContainer.AddSegment(segmentString, true);
                                                OnParserWarning(new X12ParserWarningEventArgs
                                                {
                                                    FileIsValid = false,
                                                    InterchangeControlNumber     = envelop.InterchangeControlNumber,
                                                    FunctionalGroupControlNumber = fg.ControlNumber,
                                                    TransactionControlNumber     = tran.ControlNumber,
                                                    SegmentPositionInInterchange = segmentIndex,
                                                    SegmentId = segmentId,
                                                    Segment   = segmentString,
                                                    Message   = string.Format("Segment '{3}' in segment position {4} within transaction '{1}' cannot be identified within the supplied specification for transaction set {0} in any of the expected loops: {5}.  It will be added to loop {6}, but this may invalidate all subsequent segments.", tran.IdentifierCode, tran.ControlNumber, "", segmentString, segmentIndex, string.Join(",", containerStack), containerStack.LastOrDefault())
                                                });
                                                break;
                                            }
                                        }
                                        else
                                        {
                                            if (currentContainer is Loop)
                                            {
                                                containerStack.Push(((Loop)currentContainer).Specification.LoopId);
                                            }
                                            if (currentContainer is HierarchicalLoop)
                                            {
                                                var hloop = ((HierarchicalLoop)currentContainer);
                                                containerStack.Push(string.Format("{0}[{1}]", hloop.Specification.LoopId, hloop.Id));
                                            }

                                            currentContainer = currentContainer.Parent;
                                            continue;
                                        }
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                        }
                        break;
                    }
                    segmentString = reader.ReadNextSegment();
                    segmentId     = reader.ReadSegmentId(segmentString);
                    segmentIndex++;
                }
                return(envelopes);
            }
        }