bool endElement(const QString &namespaceURI, const QString &localName, const QString &qName)
		{
			--depth;
			if(depth == 0) {
				Parser::Event *e = new Parser::Event;
				e->setDocumentClose(namespaceURI, localName, qName);
				e->setActualString(in->lastString());
				in->resetLastData();
				eventList.append(e);
				in->pause(true);
			}
			else {
				// done with a depth 1 element?
				if(depth == 1) {
					Parser::Event *e = new Parser::Event;
					e->setElement(elem);
					e->setActualString(in->lastString());
					in->resetLastData();
					eventList.append(e);
					in->pause(true);

					elem = QDomElement();
					current = QDomElement();
				}
				else
					current = current.parentNode().toElement();
			}

			if(in->lastRead() == '/')
				checkNeedMore();

			return true;
		}
		void checkNeedMore()
		{
			// Here we will work around QXmlSimpleReader strangeness and self-closing tags.
			// The problem is that endElement() is called when the '/' is read, not when
			// the final '>' is read.  This is a potential problem when obtaining unprocessed
			// bytes from StreamInput after this event, as the '>' character will end up
			// in the unprocessed chunk.  To work around this, we need to advance StreamInput's
			// internal byte processing, but not the xml character data.  This way, the '>'
			// will get processed and will no longer be in the unprocessed return, but
			// QXmlSimpleReader can still read it.  To do this, we call StreamInput::readNext
			// with 'peek' mode.
			QChar c = in->readNext(true); // peek
			if(c == QXmlInputSource::EndOfData) {
				needMore = true;
			}
			else {
				// We'll assume the next char is a '>'.  If it isn't, then
				// QXmlSimpleReader will deal with that problem on the next
				// parse.  We don't need to take any action here.
				needMore = false;

				// there should have been a pending event
				Parser::Event *e = eventList.first();
				if(!eventList.isEmpty()) {
					e->setActualString(e->actualString() + '>');
					in->resetLastData();
				}
			}
		}
		bool startElement(const QString &namespaceURI, const QString &localName, const QString &qName, const QXmlAttributes &atts)
		{
			if(depth == 0) {
				Parser::Event *e = new Parser::Event;
				QXmlAttributes a;
				for(int n = 0; n < atts.length(); ++n) {
					QString uri = atts.uri(n);
					QString ln = atts.localName(n);
					if(a.index(uri, ln) == -1)
						a.append(atts.qName(n), uri, ln, atts.value(n));
				}
				e->setDocumentOpen(namespaceURI, localName, qName, a, nsnames, nsvalues);
				nsnames.clear();
				nsvalues.clear();
				e->setActualString(in->lastString());

				in->resetLastData();
				eventList.append(e);
				in->pause(true);
			}
			else {
				QDomElement e = doc->createElementNS(namespaceURI, qName);
				for(int n = 0; n < atts.length(); ++n) {
					QString uri = atts.uri(n);
					QString ln = atts.localName(n);
					bool have;
					if(!uri.isEmpty()) {
						have = e.hasAttributeNS(uri, ln);
						if(qt_bug_have)
							have = !have;
					}
					else
						have = e.hasAttribute(ln);
					if(!have)
						e.setAttributeNS(uri, atts.qName(n), atts.value(n));
				}

				if(depth == 1) {
					elem = e;
					current = e;
				}
				else {
					current.appendChild(e);
					current = e;
				}
			}
			++depth;
			return true;
		}