private XmlNode pullXmlNode() {
        // read from queue
        if(! nodeQueue.isEmpty()) {
            return nodeQueue.poll();
        }

        // read from stream
        try {
            while(reader.hasNext()) {
                int event = reader.next();
                switch(event) {
                    case XMLStreamConstants.START_ELEMENT:
                        return new XmlStartElement(reader.getLocalName(), getAttributes(reader));
                    case XMLStreamConstants.CHARACTERS:
                        // capture XML?
                        String text = filterWhitespace(reader.getText());
                        if(text.length() > 0) {
                            return new XmlContent(text);
                        }
                        break;
                    case XMLStreamConstants.END_ELEMENT:
                        return new XmlEndElement(reader.getLocalName());
                    default:
                        // do nothing
                }
            }
        } catch (XMLStreamException e) {
            throw new XmlReaderException(e);
        }
        // nothing to return
        return null;
    }