/// <summary>Loads edits file, uses visitor to process all elements</summary>
 /// <exception cref="System.IO.IOException"/>
 public override void LoadEdits()
 {
     try
     {
         visitor.Start(inputStream.GetVersion(true));
         while (true)
         {
             try
             {
                 FSEditLogOp op = inputStream.ReadOp();
                 if (op == null)
                 {
                     break;
                 }
                 if (fixTxIds)
                 {
                     if (nextTxId <= 0)
                     {
                         nextTxId = op.GetTransactionId();
                         if (nextTxId <= 0)
                         {
                             nextTxId = 1;
                         }
                     }
                     op.SetTransactionId(nextTxId);
                     nextTxId++;
                 }
                 visitor.VisitOp(op);
             }
             catch (IOException e)
             {
                 if (!recoveryMode)
                 {
                     // Tell the visitor to clean up, then re-throw the exception
                     Log.Error("Got IOException at position " + inputStream.GetPosition());
                     visitor.Close(e);
                     throw;
                 }
                 Log.Error("Got IOException while reading stream!  Resyncing.", e);
                 inputStream.Resync();
             }
             catch (RuntimeException e)
             {
                 if (!recoveryMode)
                 {
                     // Tell the visitor to clean up, then re-throw the exception
                     Log.Error("Got RuntimeException at position " + inputStream.GetPosition());
                     visitor.Close(e);
                     throw;
                 }
                 Log.Error("Got RuntimeException while reading stream!  Resyncing.", e);
                 inputStream.Resync();
             }
         }
         visitor.Close(null);
     }
     finally
     {
         IOUtils.Cleanup(Log, inputStream);
     }
 }
        public override void EndElement(string uri, string name, string qName)
        {
            string str = XMLUtils.UnmangleXmlString(cbuf.ToString(), false).Trim();

            cbuf = new StringBuilder();
            switch (state)
            {
            case OfflineEditsXmlLoader.ParseState.ExpectEditsTag:
            {
                throw new XMLUtils.InvalidXmlException("expected <EDITS/>");
            }

            case OfflineEditsXmlLoader.ParseState.ExpectVersion:
            {
                if (!name.Equals("EDITS_VERSION"))
                {
                    throw new XMLUtils.InvalidXmlException("expected </EDITS_VERSION>");
                }
                try
                {
                    int version = System.Convert.ToInt32(str);
                    visitor.Start(version);
                }
                catch (IOException e)
                {
                    // Can't throw IOException from a SAX method, sigh.
                    throw new RuntimeException(e);
                }
                state = OfflineEditsXmlLoader.ParseState.ExpectRecord;
                break;
            }

            case OfflineEditsXmlLoader.ParseState.ExpectRecord:
            {
                if (name.Equals("EDITS"))
                {
                    state = OfflineEditsXmlLoader.ParseState.ExpectEnd;
                }
                else
                {
                    if (!name.Equals("RECORD"))
                    {
                        throw new XMLUtils.InvalidXmlException("expected </EDITS> or </RECORD>");
                    }
                }
                break;
            }

            case OfflineEditsXmlLoader.ParseState.ExpectOpcode:
            {
                if (!name.Equals("OPCODE"))
                {
                    throw new XMLUtils.InvalidXmlException("expected </OPCODE>");
                }
                opCode = FSEditLogOpCodes.ValueOf(str);
                state  = OfflineEditsXmlLoader.ParseState.ExpectData;
                break;
            }

            case OfflineEditsXmlLoader.ParseState.ExpectData:
            {
                throw new XMLUtils.InvalidXmlException("expected <DATA/>");
            }

            case OfflineEditsXmlLoader.ParseState.HandleData:
            {
                stanza.SetValue(str);
                if (stanzaStack.Empty())
                {
                    if (!name.Equals("DATA"))
                    {
                        throw new XMLUtils.InvalidXmlException("expected </DATA>");
                    }
                    state = OfflineEditsXmlLoader.ParseState.ExpectRecord;
                    FSEditLogOp op = opCache.Get(opCode);
                    opCode = null;
                    try
                    {
                        op.DecodeXml(stanza);
                        stanza = null;
                    }
                    finally
                    {
                        if (stanza != null)
                        {
                            System.Console.Error.WriteLine("fromXml error decoding opcode " + opCode + "\n" +
                                                           stanza.ToString());
                            stanza = null;
                        }
                    }
                    if (fixTxIds)
                    {
                        if (nextTxId <= 0)
                        {
                            nextTxId = op.GetTransactionId();
                            if (nextTxId <= 0)
                            {
                                nextTxId = 1;
                            }
                        }
                        op.SetTransactionId(nextTxId);
                        nextTxId++;
                    }
                    try
                    {
                        visitor.VisitOp(op);
                    }
                    catch (IOException e)
                    {
                        // Can't throw IOException from a SAX method, sigh.
                        throw new RuntimeException(e);
                    }
                    state = OfflineEditsXmlLoader.ParseState.ExpectRecord;
                }
                else
                {
                    stanza = stanzaStack.Pop();
                }
                break;
            }

            case OfflineEditsXmlLoader.ParseState.ExpectEnd:
            {
                throw new XMLUtils.InvalidXmlException("not expecting anything after </EDITS>");
            }
            }
        }