#ifndef __FDOC_PARSER__
#define __FDOC_PARSER__

#include <iostream>
#include <iterator>
#include <string>
#include <vector>
#include <stack>

#include <boost/spirit/core.hpp>
#include <boost/spirit/utility/loops.hpp>

using namespace std;
using namespace boost;
using namespace boost::spirit;

#ifdef DEBUG
  #define debug_print(x) {cout << "<!-- " << x << " //-->" << endl;}
#else
  #define debug_print(x) {}
#endif

// FDoc パーザ
template<class IteratorT>
class FDocParser : public grammar<FDocParser<IteratorT> > {
  
  public:
    typedef FDocParser<IteratorT> self_t;
  
    class Header;
  protected:
    class List;
    struct status_t{
      typedef stack<List *> list_stack_t;
      typedef stack<Header *> header_stack_t;
      bool parse_started;
      list_stack_t list_stack;
      header_stack_t header_stack;
      status_t()
        : list_stack(),
          header_stack(), 
          parse_started(false) {} 
      void clear(){
        parse_started = false;
        while(!list_stack.empty()){list_stack.pop();}
        while(!header_stack.empty()){header_stack.pop();}
      }
    } status;
  
    class ParserContextBase;
    stack<ParserContextBase *> context_stack;
    
    class ParserBoundClass {
      protected:
        FDocParser &_parser;
      public:
        ParserBoundClass(const FDocParser &parser) : _parser(const_cast<FDocParser &>(parser)) {}
        void push(ParserContextBase *context) const {
          _parser.context_stack.push(context);
        }
        void commit() const {
          ParserContextBase *target(_parser.context_stack.top());
          _parser.context_stack.pop();
          _parser.context_stack.top()->add(target);
          target->committed();
        }
        void pop() const {
          ParserContextBase *target(_parser.context_stack.top());
          _parser.context_stack.pop();
          target->popped();
        }
    };
  
  public:
    class Evaler;
  
  protected:
    class ParserContextBase : public ParserBoundClass {
      protected:
        bool _block_context;
      public:
        ParserContextBase(const FDocParser &parser, bool is_block = false) 
            : ParserBoundClass(parser),
              _block_context(is_block) {}
        virtual ~ParserContextBase() {}
        bool is_block() const {return _block_context;}
        virtual void eval(Evaler &) const = 0;
        virtual string text() const = 0;
        virtual void add(string &) = 0;
        virtual void add(const char *) = 0;
        template <class InputIterator>
        void add(InputIterator first, InputIterator last){
#if _MSC_VER < 1300
          // なぜか VC6 だとコンストラクタによる初期化がうまくいかない
          string buf;
          buf.resize(distance(first, last));
          for(size_t i = 0; first != last; ++i){
            buf[i] = *first++;
          }
#else
          string buf(first, last);
#endif
          add(buf);
        }
        virtual void add(ParserContextBase *) = 0;
        virtual ParserContextBase *operator[](unsigned int index) const = 0;
        virtual unsigned int items() const = 0;
        virtual bool has_items() const = 0;
        virtual void committed(){}
        virtual void popped(){delete this;}
    };
    
  public:
    class ParserContext : public ParserContextBase {
      public:
        typedef vector<ParserContextBase *> item_t;
      protected:
        item_t _item;
      public:
        ParserContext(const FDocParser &parser, bool is_block = false) 
            : ParserContextBase(parser, is_block), 
              _item() {}
        virtual ~ParserContext() {
          for(typename item_t::iterator it = _item.begin(); it < _item.end(); it++){
            delete (*it);
          }
        }
        typename item_t::const_iterator begin() const {return _item.begin();}
        typename item_t::const_iterator end() const {return _item.end();}
      protected:
        class StringContext : public ParserContextBase {
          protected:
            string _str;
          public:
            StringContext(const FDocParser &parser) 
                : ParserContextBase(parser, false), _str() {}
            StringContext(const FDocParser &parser, string &str) 
                : ParserContextBase(parser, false),  
                  _str(str) {}
            StringContext(const FDocParser &parser, const char *str)
                : ParserContextBase(parser, false), 
                  _str(str) {}
            ~StringContext(){}
            void add(string &s){_str.append(s);}
            void add(const char *str){_str.append(str);}
            void add(ParserContextBase *context){
              ParserBoundClass::_parser.context_stack.pop();
              ParserBoundClass::_parser.context_stack.top()->add(this);
              ParserBoundClass::_parser.context_stack.top()->add(context);
            }
            ParserContextBase *operator[](unsigned int index) const {
              return NULL;
            }
            bool has_items() const {return false;}
            unsigned int items() const {return 0;}
            void eval(Evaler &evaler) const {evaler.eval(_str);}
            string text() const {return _str;}
            void committed(){ParserBoundClass::commit();}
            void popped(){ParserBoundClass::pop(); ParserContextBase::popped();}
        };
      public:
        virtual void eval(Evaler &evaler) const {
          evaler.eval(*this);
        }
        virtual string text() const {
          string buf;
          for(typename item_t::const_iterator it = _item.begin(); it < _item.end(); it++){
            buf.append((*it)->text());
          }
          return buf;
        }
        void add(string &str){push(new StringContext(ParserBoundClass::_parser, str));}
        void add(const char *str){push(new StringContext(ParserBoundClass::_parser, str));}
        virtual void add(ParserContextBase *context){_item.push_back(context);}
        ParserContextBase *operator[](unsigned int index) const {
          return _item[index];
        }
        unsigned int items() const {return _item.size();}
        bool has_items() const {return !(_item.empty());}
    };
    
    class AutoLinefeedContext;
    class Del;
    class DList;
    class Header;
    class Link;
    class OList;
    class Paragraph;
    class RootContext;
    class Strong;
    class UList;
    class UnderLine;
    
    class Evaler{
      
      public:
#define make_typedef(type) \
        typedef typename self_t::type type
        
        make_typedef(ParserContext);
        
        make_typedef(AutoLinefeedContext);
        make_typedef(Del);
        make_typedef(DList);
        make_typedef(Header);
        make_typedef(Link);
        make_typedef(OList);
        make_typedef(Paragraph);
        make_typedef(RootContext);
        make_typedef(Strong);
        make_typedef(UList);
        make_typedef(UnderLine);
#undef make_typedef
      
        Evaler() {}
        virtual ~Evaler() {}
      
        virtual void eval(const string &str) = 0;
        virtual void eval(const ParserContext &context) = 0;
        
      protected:
        void eval_recursive(const ParserContext &context){
          for(typename ParserContext::item_t::const_iterator it = context.begin();
                it < context.end();
                it++){
            (*it)->eval(*this);
          }
        }
      
      public:
#define make_eval_default(type) \
        virtual void eval(const type &context){eval_recursive(context);}
        
        make_eval_default(AutoLinefeedContext);
        make_eval_default(Del);
        make_eval_default(DList);
        make_eval_default(Header);
        make_eval_default(Link);
        make_eval_default(OList);
        make_eval_default(Paragraph);
        make_eval_default(RootContext);
        make_eval_default(Strong);
        make_eval_default(UList);
        make_eval_default(UnderLine);
#undef make_eval_default
    };
    
    class EvalerBoundFDocParser : public FDocParser<IteratorT>{
      protected:
        Evaler &_evaler;
      public:
        EvalerBoundFDocParser(FDocParser<IteratorT> &fdoc, Evaler &evaler)
          : FDocParser<IteratorT>(fdoc),
            _evaler(evaler) {}
        void eval() const {
          context_stack.top()->eval(_evaler);
        }
    };
    
    EvalerBoundFDocParser bind(Evaler &evaler){
      return EvalerBoundFDocParser(*this, evaler);
    }

#ifdef __GNUC__
  // GCCの厳密文法対策
  #define _item (ParserContext::_item)
  #define items() (ParserContext::items())
  #define has_items() (ParserContext::has_items())
#endif
#ifdef __GNUC__
  // GCCの厳密文法対策
  #define _parser (ParserBoundClass::_parser)
  #define push(x) ParserBoundClass::push(x)
  #define pop() ParserBoundClass::pop()
  #define commit() ParserBoundClass::commit()
#endif
    
    class FDocParserSemanticAction : public ParserBoundClass {
      protected:
        FDocParserSemanticAction(const FDocParser &parser) : ParserBoundClass(parser) {}
        virtual ~FDocParserSemanticAction() {}
      public:
        virtual void operator()(IteratorT first, IteratorT last) const = 0; // const が重要
    };
    
  protected:  
    class Add : public FDocParserSemanticAction {
      public:
        Add(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {
          if(first == last){return;} 
          _parser.context_stack.top()->add(first, last);
        }
    };
    
    template<class TargetContext>
    class PushContext : public FDocParserSemanticAction{
      protected:
        inline void exec() const{
          push(new TargetContext(_parser));
        }
      public:
        PushContext(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {exec();}
        template <typename CharT>
        void operator()(CharT ch) const {exec();}
        
    };
    
    class CommitContext : public FDocParserSemanticAction{
      protected:
        inline void exec() const {commit();}
      public:
        CommitContext(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {exec();}
        template <typename CharT>
        void operator()(CharT ch) const {exec();}
    };
    
    class PopContext : public FDocParserSemanticAction{
      protected:
        inline void exec() const {pop();}
      public:
        PopContext(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {exec();}
        template <typename CharT>
        void operator()(CharT ch) const {exec();}
    };
  
  public:
    class AutoLinefeedContext : public ParserContext {
      public:
        AutoLinefeedContext(const FDocParser &parser) : ParserContext(parser, true) {}
        void eval(Evaler &evaler) const{evaler.eval(*this);}
    };
  
    class Paragraph : public AutoLinefeedContext {
      public:
        Paragraph(const FDocParser &parser) : AutoLinefeedContext(parser) {}
        void add(ParserContextBase *context){
          if(context->is_block()){
            commit();
            _parser.context_stack.top()->add(context);
          }else{
            AutoLinefeedContext::add(context);
          }
        }
        void eval(Evaler &evaler) const{evaler.eval(*this);}
    };
    
    
    // {
    class RootContext : public ParserContext {
      public:
        RootContext(const FDocParser &parser)
            : ParserContext(parser, true) {}
        ~RootContext(){}
        void add(ParserContextBase *context){
          if(context->is_block()){
            ParserContext::add(context);
          }else{
            ParserContext *paragraph(new Paragraph(_parser));
            push(paragraph); 
            paragraph->add(context);
          }
        }
        void eval(Evaler &evaler) const{evaler.eval(*this);}
    };
  
  protected:  
    class BeginFDoc : public FDocParserSemanticAction {
      public:
        BeginFDoc(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const { 
          _parser.status.parse_started = true;
          push(new RootContext(_parser));
          debug_print("=begin");
        }
    };
    
    class EndFDoc : public FDocParserSemanticAction {
      public:
        EndFDoc(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {
          while(_parser.context_stack.size() > 1){commit();}
          debug_print("=end");
        }
    };
    // }
  
  public:  
    // {
    class Escaped : public ParserContext{
      public:
        Escaped(const FDocParser &parser) : ParserContext(parser) {}
        void eval(Evaler &evaler) const{
          string buf(ParserContext::text());
          string::size_type pos = 0;
          while(true){
            pos = buf.find("\\\"", pos);
            if (pos == string::npos) break;
            buf.erase(pos++, 1);
          }
          evaler.eval(buf);
        }
    };
  
  protected:  
    class LiteralDQuote : public FDocParserSemanticAction {
      public:
        LiteralDQuote(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {
          pop();
          _parser.context_stack.top()->add("\"\"");
          debug_print("literal \"\"(dqoute) ");
        }
    };
    // }
  
  public:
    // {
    class Link : public ParserContext{
      public:
        Link(const FDocParser &parser) : ParserContext(parser) {}
        string text() const {
          return _item[items() > 1 ? 1 : 0]->text();
        }
        void eval(Evaler &evaler) const{evaler.eval(*this);}
    };
    
  protected:
    class LiteralBraces : public FDocParserSemanticAction {
      public:
        LiteralBraces(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {
          pop();
          _parser.context_stack.top()->add("[[");
          debug_print("literal [[");
        }
    };
    // }
  
  public:
    // {
    class Strong : public ParserContext{
      public:
        Strong(const FDocParser &parser) : ParserContext(parser) {}
        void eval(Evaler &evaler) const{evaler.eval(*this);}
    };
  
  protected:
    class LiteralQuotes : public FDocParserSemanticAction {
      public:
        LiteralQuotes(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {
          pop(); 
          _parser.context_stack.top()->add("''");
          debug_print("literal ''(qoutes) ");
        }
    };
    // }
  
  public:
    // {
    class Del : public ParserContext{
      public:
        Del(const FDocParser &parser) : ParserContext(parser) {}
        void eval(Evaler &evaler) const{evaler.eval(*this);}
    };
  
  protected:
    class LiteralEquals : public FDocParserSemanticAction {
      public:
        LiteralEquals(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {
          pop(); 
          _parser.context_stack.top()->add("==");
          debug_print("literal ==(equals) ");
        }
    };
    // }
  
  public:
    // {
    class UnderLine : public ParserContext{
      public:
        UnderLine(const FDocParser &parser) : ParserContext(parser) {}
        void eval(Evaler &evaler) const{evaler.eval(*this);}
    };
  
  protected:
    class LiteralBars : public FDocParserSemanticAction {
      public:
        LiteralBars(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {
          pop(); 
          _parser.context_stack.top()->add("__");
          debug_print("literal __(equals) ");
        }
    };
    // }
#ifdef __GNUC__
  // GCCの厳密文法対策
  #undef push
  #undef pop
#endif

  
  public:
    // {
    class Header : public ParserContext{
      protected:
        const unsigned int _level;
      public:
        void committed(){}
        Header(const FDocParser &parser) 
            : ParserContext(parser, true),
              _level(_parser.status.header_stack.size() + 1) {
            _parser.status.header_stack.push(this);
          }
        void popped(){
          if(_parser.status.header_stack.top() == this){
            _parser.status.header_stack.pop();
          }
          ParserContext::popped();
        }
        const unsigned int level() const {return _level;}
        void eval(Evaler &evaler) const{evaler.eval(*this);}
    };
  
  protected:
    class BeginHeader : public FDocParserSemanticAction{
      protected:
        inline typename FDocParser<IteratorT>::status_t::header_stack_t::size_type current_level() const {
          return _parser.status.header_stack.size();
        }
      public:
        BeginHeader(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const { 
          unsigned int level(last - first);
          while(level <= current_level()){_parser.status.header_stack.pop();}
          while(_parser.context_stack.size() > 1){commit();}
          push(new Header(_parser)); 
        }
    };
  
  protected:
    // {
    class List : public ParserContext {
      protected:
        const unsigned int _level;
      public:
        void committed(){_parser.status.list_stack.pop();}
        List(const FDocParser &parser) 
            : ParserContext(parser, true),  
              _level(_parser.status.list_stack.size() + 1) {
          _parser.status.list_stack.push(this);
        }
        void popped(){committed(); ParserContext::popped();}
    };
  
    template <class ListType, class ElementContext = AutoLinefeedContext>
    class BeginList : public FDocParserSemanticAction{
      protected:
        inline typename FDocParser<IteratorT>::status_t::list_stack_t::size_type current_level() const {
          return _parser.status.list_stack.size();
        }
      public:
        BeginList(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {
          unsigned int level(last - first);
          bool is_continue('&' == *(last - 1));
          if(is_continue){level--;}
          
          if(level <= current_level()){
            while(level < current_level()){commit();}
            if(!dynamic_cast<ListType *>(_parser.status.list_stack.top())){
              while(level < current_level() + 1){commit();}
            }else if(is_continue){
              return;
            }else{
              commit();
            }
          }
          
          if(level > current_level()){ 
            push(new ListType(_parser));
          }
          push(new ElementContext(_parser));
        }
    };
  
  public:
    class UList : public List{
      public:
        UList(const FDocParser &parser) : List(parser){}
        void eval(Evaler &evaler) const{evaler.eval(*this);}
    };
    
    class OList : public List{
      public:
        OList(const FDocParser &parser) : List(parser){}
        void eval(Evaler &evaler) const{evaler.eval(*this);}
    };
    
    class DList : public List{
      protected:
        unsigned int terms;
      public:
        DList(const FDocParser &parser) : List(parser), terms(0){}
        void eval(Evaler &evaler) const{evaler.eval(*this);}
    };
  
  protected:
    class EndDTerm : public FDocParserSemanticAction{
      public:
        EndDTerm(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const { 
          commit();
          push(new AutoLinefeedContext(_parser));
        }
    };
    // }

    class BlankLine : public FDocParserSemanticAction {
      public:
        BlankLine(const FDocParser &parser) : FDocParserSemanticAction(parser) {}
        void operator()(IteratorT first, IteratorT last) const {
          while(_parser.status.list_stack.size() > 1){commit();}
          debug_print("=blank");
        }
    };
#ifdef __GNUC__
  // GCCの厳密文法対策
  #undef _item
  #undef items
  #undef has_items
  #undef _parser
  #undef commit
#endif

  public:
    void clean(){
      status.clear();
      while(!context_stack.empty()){
        context_stack.pop();
      }
    }
  
    FDocParser() : context_stack(), status(){
      
    }
    
    bool parsing(){return status.parse_started;}
    
    friend ostream &operator<<(ostream &out, const FDocParser &fdoc){
      out << fdoc.context_stack.top()->text();
      return out;
    }
    
    template <typename ScannerT>
    struct definition {
      rule<ScannerT> fdoc,
                     fdoc_begin, fdoc_end, fdoc_line, blank_line,
                     special_char_p, char_p,
                     escaped_p, link_p,
                     strong_p, del_p, uline_p,
                     nest_strong_p, nest_del_p, nest_uline_p,
                     nest_off_p,
                     delimiter_p, delm_default_p,
                     word_chars,
                     block, blocks,
                     header_element, 
                     ul_element, 
                     ol_element, 
                     dl_element, dl_next, dt_and_dd, dd_only,
                     table_element, delm_table_p,
                     other_element;
      
      struct ChangeRule{
        rule<ScannerT> &_r1, &_r2;
        ChangeRule(rule<ScannerT> &r1, rule<ScannerT> &r2) : _r1(r1), _r2(r2){}
        template <typename CharT>
        void operator()(CharT ch) const {
          _r1 = _r2;
        }
        void operator()(IteratorT first, IteratorT last) const {
          _r1 = _r2;
        }
      };
      
      template <class ContextType = ParserContext>
      struct gather_parser{
        typedef PushContext<ContextType> pusher;
        typedef CommitContext committer;
        typedef PopContext popper;
        const FDocParser<IteratorT>& _self;
        gather_parser(const FDocParser<IteratorT>& self) : _self(self) {}
        template <typename T1>
        inline sequence<
                  action<epsilon_parser, pusher>, 
                  alternative<
                    action<T1, committer>,
                    sequence<
                      action<epsilon_parser, popper>,
                      nothing_parser > > >
        operator()(const parser<T1> &p) const {
          return (eps_p[ pusher(_self) ] 
                    >> ((p)[ committer(_self) ]
                        | (eps_p[ popper(_self) ] >> nothing_p) ) );
        }
      };
      
      definition(const FDocParser<IteratorT>& self){
        
        gather_parser<> gather_p(self);
       
        fdoc            = fdoc_begin[ BeginFDoc(self) ]
                             >> *fdoc_line
                             >> fdoc_end[ EndFDoc(self) ];
        
        fdoc_begin      = str_p("=begin") >> *blank_p >> eol_p;
        fdoc_end        = str_p("=end") >> *blank_p >> (eol_p | end_p);
  
        
        special_char_p  = ch_p('<') | ch_p('>');
        char_p          = special_char_p | (anychar_p - eol_p - end_p);
        
        escaped_p       = str_p("\"\"")[ PushContext<Escaped>(self) ]
                             >> (( (*(str_p("\\\"")
                                         | (anychar_p - str_p("\"\"") - end_p)))[Add(self)] 
                                     >> str_p("\"\"")[ CommitContext(self) ] )
                                 | eps_p[ LiteralDQuote(self) ]);
        link_p          = str_p("[[")[ PushContext<Link>(self) ] 
                             >> (( gather_p(+(escaped_p | (char_p - blank_p - str_p("]]"))[Add(self)] ))
                                     >> (*blank_p) >> !( gather_p( +(escaped_p | (char_p - str_p("]]"))[Add(self)] ) ) )
                                     >> str_p("]]")[ CommitContext(self) ] )
                                 | eps_p[ LiteralBraces(self) ] );
        
        
        strong_p        = str_p("''")[ PushContext<Strong>(self) ][ ChangeRule(nest_strong_p, nest_off_p) ]
                             >> (( +(link_p
                                         | nest_del_p
                                         | nest_uline_p 
                                         | escaped_p 
                                         | (char_p - str_p("''"))[Add(self)] )
                                     >> str_p("''")[ CommitContext(self) ] )
                                 | eps_p[ LiteralQuotes(self) ] )[ ChangeRule(nest_strong_p, strong_p) ];
        del_p           = str_p("==")[ PushContext<Del>(self) ][ ChangeRule(nest_del_p, nest_off_p) ]
                             >> (( +(link_p
                                         | nest_strong_p
                                         | nest_uline_p 
                                         | escaped_p 
                                         | (char_p - str_p("=="))[Add(self)] )
                                     >> str_p("==")[ CommitContext(self) ] )
                                 | eps_p[ LiteralEquals(self) ] )[ ChangeRule(nest_del_p, del_p) ];
        uline_p         = str_p("__")[ PushContext<UnderLine>(self) ][ ChangeRule(nest_uline_p, nest_off_p) ]
                             >> (( +(link_p
                                         | nest_strong_p
                                         | nest_del_p 
                                         | escaped_p 
                                         | (char_p - str_p("__"))[Add(self)] )
                                     >> str_p("__")[ CommitContext(self) ] )
                                 | eps_p[ LiteralBars(self) ] )[ ChangeRule(nest_uline_p, uline_p) ];
        
        nest_off_p      = nothing_p;
        
        nest_strong_p   = strong_p;
        nest_del_p      = del_p;
        nest_uline_p    = uline_p;
        
        
        delm_default_p  = nothing_p;
        delimiter_p     = delm_default_p;
        word_chars      = +(strong_p | del_p | uline_p | link_p | escaped_p | (char_p - blank_p - delimiter_p)[Add(self)] );
        
        block           = word_chars >> (*blank_p)[Add(self)];
        blocks          = *blank_p >> *block;
        
        
        header_element  = (repeat_p(1, 5)[ ch_p('!') ])[ BeginHeader(self) ]
                              >> blocks
                              >> eol_p[ CommitContext(self) ];
        
        ul_element      = (repeat_p(1, 5)[ ch_p('-') ]
                                  >> !ch_p('&'))[ BeginList<UList>(self) ] 
                              >> gather_p(blocks)
                              >> eol_p;
        
        ol_element      = (repeat_p(1, 5)[ ch_p('+') ]
                                  >> !ch_p('&'))[ BeginList<OList>(self) ]
                              >> gather_p(blocks)
                              >> eol_p;
        
        dl_element      = (repeat_p(1, 5)[ ch_p(':') ] 
                                  >> (ch_p('&') >> eps_p[ ChangeRule(dl_next, dd_only) ] 
                                          | eps_p[ ChangeRule(dl_next, dt_and_dd) ])
                                      )[ BeginList<DList, ParserContext>(self) ] 
                              >> dl_next
                              >> eol_p;
        dt_and_dd       = *blank_p >> (word_chars | eps_p)[ EndDTerm(self) ]
                              >> gather_p(blocks);
        dd_only         = gather_p(blocks);
        
        delm_table_p    = ch_p('|');
        table_element   = ch_p('|')[ ChangeRule(delimiter_p, delm_table_p) ]
                              >> *(blocks >> delm_table_p)
                              >> eol_p
                              >> *(ch_p('|')
                                  >> *(blocks >> delm_table_p) 
                                  >> eol_p)
                              >> eps_p[ ChangeRule(delimiter_p, delm_default_p) ];
        
        other_element   = gather_p(blocks - fdoc_end)
                              >> eol_p;
        
  
  
        blank_line      = *blank_p 
                              >> eol_p[ BlankLine(self) ];
        fdoc_line       = blank_line
                              | header_element
                              | table_element
                              | ul_element
                              | ol_element
                              | dl_element
                              | other_element;
      }
  
      const rule<ScannerT>& start() const { return fdoc; }
    };
};

template<class IteratorT>
class ParserDebuger : public FDocParser<IteratorT>::Evaler {
  
  typedef typename FDocParser<IteratorT>::ParserContext::item_t item_t;
  typedef typename item_t::const_iterator iterator_t;
  
  public:
    int tab;
  
    ParserDebuger() : tab(0) {}
    ~ParserDebuger() {}
  
  
    void eval(const string &str){
      tab++;
      for(int i = tab; i > 0; i--) cout << "\t";
      cout << "eval(string):" << "\"" << str << "\"" << endl;
      tab--;
    }
    
    void eval_children(const typename ParserDebuger::ParserContext &context){
      int index = 0;
      for(iterator_t it = context.begin(); it < context.end(); it++){
        for(int i = tab; i > 0; i--) cout << "\t";
        cout << "item" << index << endl;
        tab++;
        (*it)->eval(*this);
        tab--;
        for(int i = tab; i > 0; i--) cout << "\t";
        cout << "item" << (index++) << endl;
      }
    }
    
    void eval(const typename ParserDebuger::ParserContext &context){
      for(int i = tab; i > 0; i--) cout << "\t";
      cout << "eval(context):in" << endl;
      eval_children(context);
      for(int i = tab; i > 0; i--) cout << "\t";
      cout << "eval(context):out" << endl;
    }
    
#define make_eval(type) \
    void eval(const typename ParserDebuger::type &context){ \
      for(int i = tab; i > 0; i--) cout << "\t"; \
      cout << #type << ":in" << endl; \
      eval_children(context); \
      for(int i = tab; i > 0; i--) cout << "\t"; \
      cout << #type << ":out" << endl; \
    }
    
    make_eval(AutoLinefeedContext);
    make_eval(Del);
    make_eval(DList);
    make_eval(Header);
    make_eval(Link);
    make_eval(OList);
    make_eval(Paragraph);
    make_eval(RootContext);
    make_eval(Strong);
    make_eval(UList);
    make_eval(UnderLine);
#undef make_eval
};

#endif /* __FDOC_PARSER__ */

