# File temp/parsers/baseparser.rb, line 182
                        def pull
                                if @closed
                                        x, @closed = @closed, nil
                                        return [ :end_element, x ]
                                end
                                return [ :end_document ] if empty?
                                return @stack.shift if @stack.size > 0
                                @source.read if @source.buffer.size<2
                                if @document_status == nil
                                        @source.consume( /^\s*/um )
                                        word = @source.match( /(<[^>]*)>/um )
                                        word = word[1] unless word.nil?
                                        case word
                                        when COMMENT_START
                                                return [ :comment, @source.match( COMMENT_PATTERN, true )[1] ]
                                        when XMLDECL_START
                                                results = @source.match( XMLDECL_PATTERN, true )[1]
                                                version = VERSION.match( results )
                                                version = version[1] unless version.nil?
                                                encoding = ENCODING.match(results)
                                                encoding = encoding[1] unless encoding.nil?
                                                @source.encoding = encoding
                                                standalone = STANDALONE.match(results)
                                                standalone = standalone[1] unless standalone.nil?
                                                return [ :xmldecl, version, encoding, standalone]
                                        when INSTRUCTION_START
                                                return [ :processing_instruction, *@source.match(INSTRUCTION_PATTERN, true)[1,2] ]
                                        when DOCTYPE_START
                                                md = @source.match( DOCTYPE_PATTERN, true )
                                                identity = md[1]
                                                close = md[2]
                                                identity =~ IDENTITY
                                                name = $1
                                                raise REXML::ParseException("DOCTYPE is missing a name") if name.nil?
                                                pub_sys = $2.nil? ? nil : $2.strip
                                                long_name = $3.nil? ? nil : $3.strip
                                                uri = $4.nil? ? nil : $4.strip
                                                args = [ :start_doctype, name, pub_sys, long_name, uri ]
                                                if close == ">"
                                                        @document_status = :after_doctype
                                                        @source.read if @source.buffer.size<2
                                                        md = @source.match(/^\s*/um, true)
                                                        @stack << [ :end_doctype ]
                                                else
                                                        @document_status = :in_doctype
                                                end
                                                return args
                                        else
                                                @document_status = :after_doctype
                                                @source.read if @source.buffer.size<2
                                                md = @source.match(/\s*/um, true)
                                        end
                                end
                                if @document_status == :in_doctype
                                        md = @source.match(/\s*(.*?>)/um)
                                        case md[1]
                                        when SYSTEMENTITY 
                                                match = @source.match( SYSTEMENTITY, true )[1]
                                                return [ :externalentity, match ]

                                        when ELEMENTDECL_START
                                                return [ :elementdecl, @source.match( ELEMENTDECL_PATTERN, true )[1] ]

                                        when ENTITY_START
                                                match = @source.match( ENTITYDECL, true ).to_a.compact
                                                match[0] = :entitydecl
                                                ref = false
                                                if match[1] == '%'
                                                        ref = true
                                                        match.delete_at 1
                                                end
                                                # Now we have to sort out what kind of entity reference this is
                                                if match[2] == 'SYSTEM'
                                                        # External reference
                                                        match[3] = match[3][1..-2] # PUBID
                                                        match.delete_at(4) if match.size > 4 # Chop out NDATA decl
                                                        # match is [ :entity, name, SYSTEM, pubid(, ndata)? ]
                                                elsif match[2] == 'PUBLIC'
                                                        # External reference
                                                        match[3] = match[3][1..-2] # PUBID
                                                        match[4] = match[4][1..-2] # HREF
                                                        # match is [ :entity, name, PUBLIC, pubid, href ]
                                                else
                                                        match[2] = match[2][1..-2]
                                                        match.pop if match.size == 4
                                                        # match is [ :entity, name, value ]
                                                end
                                                match << '%' if ref
                                                return match
                                        when ATTLISTDECL_START
                                                md = @source.match( ATTLISTDECL_PATTERN, true )
                                                raise REXML::ParseException.new( "Bad ATTLIST declaration!", @source ) if md.nil?
                                                element = md[1]
                                                contents = md[0]

                                                pairs = {}
                                                values = md[0].scan( ATTDEF_RE )
                                                values.each do |attdef|
                                                        unless attdef[3] == "#IMPLIED"
                                                                attdef.compact!
                                                                val = attdef[3]
                                                                val = attdef[4] if val == "#FIXED "
                                                                pairs[attdef[0]] = val
                                                        end
                                                end
                                                return [ :attlistdecl, element, pairs, contents ]
                                        when NOTATIONDECL_START
                                                md = nil
                                                if @source.match( PUBLIC )
                                                        md = @source.match( PUBLIC, true )
                                                elsif @source.match( SYSTEM )
                                                        md = @source.match( SYSTEM, true )
                                                else
                                                        raise REXML::ParseException.new( "error parsing notation: no matching pattern", @source )
                                                end
                                                return [ :notationdecl, md[1], md[2], md[3] ]
                                        when CDATA_END
                                                @document_status = :after_doctype
                                                @source.match( CDATA_END, true )
                                                return [ :end_doctype ]
                                        end
                                end
                                begin
                                        if @source.buffer[0] == ?<
                                                if @source.buffer[1] == ?/
                                                        last_tag = @tags.pop
                                                        #md = @source.match_to_consume( '>', CLOSE_MATCH)
                                                        md = @source.match( CLOSE_MATCH, true )
                                                        raise REXML::ParseException.new( "Missing end tag for "+
                "'#{last_tag}' (got \"#{md[1]}\")", 
                @source) unless last_tag == md[1]
                                                        return [ :end_element, last_tag ]
                                                elsif @source.buffer[1] == ?!
                                                        md = @source.match(/\A(\s*[^>]*>)/um)
                                                        #puts "SOURCE BUFFER = #{source.buffer}, #{source.buffer.size}"
                                                        raise REXML::ParseException.new("Malformed node", @source) unless md
                                                        if md[0][2] == ?-
                                                                md = @source.match( COMMENT_PATTERN, true )
                                                                return [ :comment, md[1] ] if md
                                                        else
                                                                md = @source.match( CDATA_PATTERN, true )
                                                                return [ :cdata, md[1] ] if md
                                                        end
                                                        raise REXML::ParseException.new( "Declarations can only occur "+
                                                                "in the doctype declaration.", @source)
                                                elsif @source.buffer[1] == ??
                                                        md = @source.match( INSTRUCTION_PATTERN, true )
                                                        return [ :processing_instruction, md[1], md[2] ] if md
                                                        raise REXML::ParseException.new( "Bad instruction declaration",
                                                                @source)
                                                else
                                                        # Get the next tag
                                                        md = @source.match(TAG_MATCH, true)
                                                        raise REXML::ParseException.new("malformed XML: missing tag start", @source) unless md
                                                        attrs = []
                                                        if md[2].size > 0
                                                                attrs = md[2].scan( ATTRIBUTE_PATTERN )
                                                                raise REXML::ParseException.new( "error parsing attributes: [#{attrs.join ', '}], excess = \"#$'\"", @source) if $' and $'.strip.size > 0
                                                        end
                                
                                                        if md[4]
                                                                @closed = md[1]
                                                        else
                                                                @tags.push( md[1] )
                                                        end
                                                        attributes = {}
                                                        attrs.each { |a,b,c| attributes[a] = c }
                                                        return [ :start_element, md[1], attributes ]
                                                end
                                        else
                                                md = @source.match( TEXT_PATTERN, true )
            if md[0].length == 0
              #puts "EMPTY = #{empty?}"
              #puts "BUFFER = \"#{@source.buffer}\""
              @source.match( /(\s+)/, true )
            end
            #return [ :text, "" ] if md[0].length == 0
                                                # unnormalized = Text::unnormalize( md[1], self )
                                                # return PullEvent.new( :text, md[1], unnormalized )
                                                return [ :text, md[1] ]
                                        end
                                rescue REXML::ParseException
                                        raise
                                rescue Exception, NameError => error
                                        raise REXML::ParseException.new( "Exception parsing",
                                                @source, self, (error ? error : $!) )
                                end
                                return [ :dummy ]
                        end