package org.apache.axis2.databinding.utils.reader;

import org.apache.axiom.om.OMAttribute;
import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMNamespace;
import org.apache.axis2.databinding.ADBBean;
import org.apache.axis2.databinding.utils.BeanUtil;
import org.apache.ws.java2wsdl.utils.TypeTable;

import javax.activation.DataHandler;
import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
/*
 * Copyright 2004,2005 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/**
 * This is the new implementation of the ADBpullaparser. The approach here is simple
 * When the pull parser needs to generate events for a particular name-value(s) pair
 * it always handes over (delegates) the task to another pull parser which knows how
 * to deal with it
 * The common types of name value pairs we'll come across are
 * 1. String name/QName name - String value
 * 2. String name/QName name - String[] value
 * 3. OMElementkey - OMElement value
 * 4. QName name/String name  - ADBBean value
 * 5. QName name/String name  - Java bean
 * 5. QName name/String name  - Datahandler
 * <p/>
 * As for the attributes, these are the possible combinations in the
 * array
 * 1. String name/QName name - String value
 * 2. OMAttributeKey - OMAttribute
 * <p/>
 * Note that certain array methods have  been deliberately removed to avoid
 * complications. The generated code will take the trouble to lay the
 * elements of the array in the correct order
 * <p/>
 * <p/>
 * Hence there will be a parser impl that knows how to handle these types, and
 * this parent parser will always delegate these tasks to the child pullparasers
 * in effect this is one huge state machine that has only a few states and delegates
 * things down to the child parsers whenever possible
 * <p/>
 */
public class ADBXMLStreamReaderImpl implements ADBXMLStreamReader {

    private Object[] properties;
    private Object[] attributes;
    private QName elementQName;
    //we always create a new namespace context
    private ADBNamespaceContext namespaceContext = new ADBNamespaceContext();

    private Map declaredNamespaceMap = new HashMap();

    //states for this pullparser - it can only have four states
    private static final int START_ELEMENT_STATE = 0;
    private static final int END_ELEMENT_STATE = 1;
    private static final int DELEGATED_STATE = 2;
    private static final int TEXT_STATE = 3;

    //integer field that keeps the state of this
    //parser.
    private int state = START_ELEMENT_STATE;

    //reference to the child reader
    private ADBXMLStreamReader childReader;

    //current property index
    //initialized at zero
    private int currentPropertyIndex = 0;

    //To keep element formdefault qualified or not
    private boolean qualified = false;

    //to keep the current types which are in AxisService
    private TypeTable typeTable = null;


    /*
     * we need to pass in a namespace context since when delegated, we've no
    * idea of the current namespace context. So it needs to be passed on
    * here!
    */
    public ADBXMLStreamReaderImpl(QName adbBeansQName,
                                  Object[] properties,
                                  Object[] attributes) {
        //validate the lengths, since both the arrays are supposed
        //to have
        this.properties = properties;
        this.elementQName = adbBeansQName;
        this.attributes = attributes;
    }

    public ADBXMLStreamReaderImpl(QName adbBeansQName,
                                  Object[] properties,
                                  Object[] attributes,
                                  TypeTable typeTable,
                                  boolean qualified) {
        this(adbBeansQName, properties, attributes);
        this.qualified = qualified;
        this.typeTable = typeTable;
    }

    /**
     * add the namespace context
     */

    public void addNamespaceContext(NamespaceContext nsContext) {
        // register the namespace context passed in to this
        this.namespaceContext.setParentNsContext(nsContext);


    }

    /**
     * we need to split out the calling to the populate namespaces
     * seperately since this needs to be done *after* setting the
     * parent namespace context. We cannot assume it will happen at
     * construction!
     */
    public void init() {
        // here we have an extra issue to attend to. we need to look at the
        // prefixes and uris (the combination) and populate a hashmap of
        // namespaces. The hashmap of namespaces will be used to serve the
        // namespace context

        populateNamespaceContext();
    }

    /**
     * @param key
     * @throws IllegalArgumentException
     */
    public Object getProperty(String key) throws IllegalArgumentException {
        if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) {
            if (OPTIMIZATION_ENABLED.equals(key)) {
                return Boolean.TRUE;
            } else {
                return null;
            }
        } else if (state == TEXT_STATE) {
            if (IS_BINARY.equals(key)) {
                return Boolean.FALSE;
            } else {
                return null;
            }
        } else if (state == DELEGATED_STATE) {
            return childReader.getProperty(key);
        } else {
            return null;
        }

    }

    public void require(int i, String string, String string1)
            throws XMLStreamException {
        throw new UnsupportedOperationException();
    }

    /**
     * todo implement the right contract for this
     *
     * @throws XMLStreamException
     */
    public String getElementText() throws XMLStreamException {
        if (state == DELEGATED_STATE) {
            return childReader.getElementText();
        } else {
            return null;
        }

    }

    /**
     * todo implement this
     *
     * @throws XMLStreamException
     */
    public int nextTag() throws XMLStreamException {
        return 0;
    }

    /**
     * @throws XMLStreamException
     */
    public boolean hasNext() throws XMLStreamException {
        if (state == DELEGATED_STATE) {
            if (childReader.isDone()) {
                //the child reader is done. We shouldn't be getting the
                //hasnext result from the child pullparser then
                return true;
            } else {
                return childReader.hasNext();
            }
        } else {
            return (state == START_ELEMENT_STATE
                    || state == TEXT_STATE);


        }
    }

    public void close() throws XMLStreamException {
        //do nothing here - we have no resources to free
    }

    public String getNamespaceURI(String prefix) {
        return namespaceContext.getNamespaceURI(prefix);
    }

    public boolean isStartElement() {
        if (state == START_ELEMENT_STATE) {
            return true;
        } else if (state == END_ELEMENT_STATE) {
            return false;
        }
        return childReader.isStartElement();
    }

    public boolean isEndElement() {
        if (state == START_ELEMENT_STATE) {
            return false;
        } else if (state == END_ELEMENT_STATE) {
            return true;
        }
        return childReader.isEndElement();
    }

    public boolean isCharacters() {
        if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) {
            return false;
        }
        return childReader.isCharacters();
    }

    public boolean isWhiteSpace() {
        if (state == START_ELEMENT_STATE || state == END_ELEMENT_STATE) {
            return false;
        }
        return childReader.isWhiteSpace();
    }

    ///////////////////////////////////////////////////////////////////////////
    ///  attribute handling
    ///////////////////////////////////////////////////////////////////////////

    public String getAttributeValue(String nsUri, String localName) {

        int attribCount = getAttributeCount();
        String returnValue = null;
        QName attribQualifiedName;
        for (int i = 0; i < attribCount; i++) {
            attribQualifiedName = getAttributeName(i);
            if (nsUri == null) {
                if (localName.equals(attribQualifiedName.getLocalPart())) {
                    returnValue = getAttributeValue(i);
                    break;
                }
            } else {
                if (localName.equals(attribQualifiedName.getLocalPart())
                        && nsUri.equals(attribQualifiedName.getNamespaceURI())) {
                    returnValue = getAttributeValue(i);
                    break;
                }
            }

        }


        return returnValue;
    }

    public int getAttributeCount() {
        return (state == DELEGATED_STATE) ?
                childReader.getAttributeCount() :
                ((attributes != null) && (state == START_ELEMENT_STATE) ? attributes.length / 2 : 0);
    }

    /**
     * @param i
     */
    public QName getAttributeName(int i) {
        if (state == DELEGATED_STATE) {
            return childReader.getAttributeName(i);
        } else if (state == START_ELEMENT_STATE) {
            if (attributes == null) {
                return null;
            } else {
                if ((i >= (attributes.length / 2)) || i < 0) { //out of range
                    return null;
                } else {
                    //get the attribute pointer
                    Object attribPointer = attributes[i * 2];
                    //case one - attrib name is null
                    //this should be the pointer to the OMAttribute then
                    if (attribPointer == null) {
                        Object omAttribObj = attributes[(i * 2) + 1];
                        if (omAttribObj == null ||
                                !(omAttribObj instanceof OMAttribute)) {
                            // wrong object set to have in the attrib array -
                            // this should have been detected by now but just be
                            // sure
                            throw new UnsupportedOperationException();
                        }
                        OMAttribute att = (OMAttribute) omAttribObj;
                        return att.getQName();
                    } else if (attribPointer instanceof OMAttribKey) {
                        Object omAttribObj = attributes[(i * 2) + 1];
                        if (omAttribObj == null ||
                                !(omAttribObj instanceof OMAttribute)) {
                            // wrong object set to have in the attrib array -
                            // this should have been detected by now but just be
                            // sure
                            throw new UnsupportedOperationException();
                        }
                        OMAttribute att = (OMAttribute) omAttribObj;
                        return att.getQName();
                        //case two - attrib name is a plain string
                    } else if (attribPointer instanceof String) {
                        return new QName((String) attribPointer);
                    } else if (attribPointer instanceof QName) {
                        return (QName) attribPointer;
                    } else {
                        return null;
                    }
                }
            }
        } else {
            throw new IllegalStateException();//as per the api contract
        }

    }

    public String getAttributeNamespace(int i) {
        if (state == DELEGATED_STATE) {
            return childReader.getAttributeNamespace(i);
        } else if (state == START_ELEMENT_STATE) {
            QName name = getAttributeName(i);
            if (name == null) {
                return null;
            } else {
                return name.getNamespaceURI();
            }
        } else {
            throw new IllegalStateException();
        }
    }

    public String getAttributeLocalName(int i) {
        if (state == DELEGATED_STATE) {
            return childReader.getAttributeLocalName(i);
        } else if (state == START_ELEMENT_STATE) {
            QName name = getAttributeName(i);
            if (name == null) {
                return null;
            } else {
                return name.getLocalPart();
            }
        } else {
            throw new IllegalStateException();
        }
    }

    public String getAttributePrefix(int i) {
        if (state == DELEGATED_STATE) {
            return childReader.getAttributePrefix(i);
        } else if (state == START_ELEMENT_STATE) {
            QName name = getAttributeName(i);
            if (name == null) {
                return null;
            } else {
                return name.getPrefix();
            }
        } else {
            throw new IllegalStateException();
        }
    }

    public String getAttributeType(int i) {
        return null;  //not supported
    }

    public String getAttributeValue(int i) {
        if (state == DELEGATED_STATE) {
            return childReader.getAttributeValue(i);
        } else if (state == START_ELEMENT_STATE) {
            if (attributes == null) {
                return null;
            } else {
                if ((i >= (attributes.length / 2)) || i < 0) { //out of range
                    return null;
                } else {
                    //get the attribute pointer
                    Object attribPointer = attributes[i * 2];
                    Object omAttribObj = attributes[(i * 2) + 1];
                    //case one - attrib name is null
                    //this should be the pointer to the OMAttribute then
                    if (attribPointer == null) {

                        if (omAttribObj == null ||
                                !(omAttribObj instanceof OMAttribute)) {
                            // wrong object set to have in the attrib array -
                            // this should have been detected by now but just be
                            // sure
                            throw new UnsupportedOperationException();
                        }
                        OMAttribute att = (OMAttribute) omAttribObj;
                        return att.getAttributeValue();
                    } else if (attribPointer instanceof OMAttribKey) {
                        if (omAttribObj == null ||
                                !(omAttribObj instanceof OMAttribute)) {
                            // wrong object set to have in the attrib array -
                            // this should have been detected by now but just be
                            // sure
                            throw new UnsupportedOperationException();
                        }
                        OMAttribute att = (OMAttribute) omAttribObj;
                        return att.getAttributeValue();
                        //case two - attrib name is a plain string
                    } else if (attribPointer instanceof String) {
                        return (String) omAttribObj;
                    } else if (attribPointer instanceof QName) {
                        return (String) omAttribObj;
                    } else {
                        return null;
                    }
                }
            }
        } else {
            throw new IllegalStateException();
        }

    }

    public boolean isAttributeSpecified(int i) {
        return false;  //not supported
    }

///////////////////////////////////////////////////////////////////////////
//////////////  end of attribute handling
///////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////
//////////////   namespace handling
////////////////////////////////////////////////////////////////////////////

    public int getNamespaceCount() {
        if (state == DELEGATED_STATE) {
            return childReader.getNamespaceCount();
        } else {
            return declaredNamespaceMap.size();
        }
    }

    /**
     * @param i
     */
    public String getNamespacePrefix(int i) {
        if (state == DELEGATED_STATE) {
            return childReader.getNamespacePrefix(i);
        } else if (state != TEXT_STATE) {
            //order the prefixes
            String[] prefixes = makePrefixArray();
            if ((i >= prefixes.length) || (i < 0)) {
                return null;
            } else {
                return prefixes[i];
            }

        } else {
            throw new IllegalStateException();
        }

    }

    /**
     * Get the prefix list from the hastable and take that into an array
     */
    private String[] makePrefixArray() {
        String[] prefixes =
                (String[]) declaredNamespaceMap.keySet().
                        toArray(new String[declaredNamespaceMap.size()]);
        Arrays.sort(prefixes);
        return prefixes;
    }

    public String getNamespaceURI(int i) {
        if (state == DELEGATED_STATE) {
            return childReader.getNamespaceURI(i);
        } else if (state != TEXT_STATE) {
            String namespacePrefix = getNamespacePrefix(i);
            return namespacePrefix == null ? null :
                    (String) declaredNamespaceMap.get(namespacePrefix);
        } else {
            throw new IllegalStateException();
        }

    }

    public NamespaceContext getNamespaceContext() {
        if (state == DELEGATED_STATE) {
            return childReader.getNamespaceContext();
        } else {
            return namespaceContext;
        }


    }

///////////////////////////////////////////////////////////////////////////
/////////  end of namespace handling
///////////////////////////////////////////////////////////////////////////

    public int getEventType() {
        if (state == START_ELEMENT_STATE) {
            return START_ELEMENT;
        } else if (state == END_ELEMENT_STATE) {
            return END_ELEMENT;
        } else { // this is the delegated state
            return childReader.getEventType();
        }

    }

    public String getText() {
        if (state == DELEGATED_STATE) {
            return childReader.getText();
        } else if (state == TEXT_STATE) {
            return (String) properties[currentPropertyIndex - 1];
        } else {
            throw new IllegalStateException();
        }
    }

    public char[] getTextCharacters() {
        if (state == DELEGATED_STATE) {
            return childReader.getTextCharacters();
        } else if (state == TEXT_STATE) {
            return properties[currentPropertyIndex - 1] == null ? new char[0] :
                    ((String) properties[currentPropertyIndex - 1]).toCharArray();
        } else {
            throw new IllegalStateException();
        }
    }

    public int getTextCharacters(int i, char[] chars, int i1, int i2)
            throws XMLStreamException {
        if (state == DELEGATED_STATE) {
            return childReader.getTextCharacters(i, chars, i1, i2);
        } else if (state == TEXT_STATE) {
            //todo  - implement this
            return 0;
        } else {
            throw new IllegalStateException();
        }
    }

    public int getTextStart() {
        if (state == DELEGATED_STATE) {
            return childReader.getTextStart();
        } else if (state == TEXT_STATE) {
            return 0;//assume text always starts at 0
        } else {
            throw new IllegalStateException();
        }
    }

    public int getTextLength() {
        if (state == DELEGATED_STATE) {
            return childReader.getTextLength();
        } else if (state == TEXT_STATE) {
            return 0;//assume text always starts at 0
        } else {
            throw new IllegalStateException();
        }
    }

    public String getEncoding() {
        if (state == DELEGATED_STATE) {
            return childReader.getEncoding();
        } else {
            //we've no idea what the encoding is going to be in this case
            //perhaps we ought to return some constant here, which the user might
            //have access to change!
            return null;
        }
    }

    /**
     * check the validity of this implementation
     */
    public boolean hasText() {
        if (state == DELEGATED_STATE) {
            return childReader.hasText();
        } else return state == TEXT_STATE;

    }

    /**
     */
    public Location getLocation() {
        //return a default location
        return new Location() {
            public int getLineNumber() {
                return 0;
            }

            public int getColumnNumber() {
                return 0;
            }

            public int getCharacterOffset() {
                return 0;
            }

            public String getPublicId() {
                return null;
            }

            public String getSystemId() {
                return null;
            }
        };
    }

    public QName getName() {
        if (state == DELEGATED_STATE) {
            return childReader.getName();
        } else if (state != TEXT_STATE) {
            return elementQName;
        } else {
            throw new IllegalStateException();
        }

    }

    public String getLocalName() {
        if (state == DELEGATED_STATE) {
            return childReader.getLocalName();
        } else if (state != TEXT_STATE) {
            return elementQName.getLocalPart();
        } else {
            throw new IllegalStateException();
        }
    }

    public boolean hasName() {
        //since this parser always has a name, the hasname
        //has to return true if we are still navigating this element
        //if not we should ask the child reader for it.
        if (state == DELEGATED_STATE) {
            return childReader.hasName();
        } else return state != TEXT_STATE;
    }

    public String getNamespaceURI() {
        if (state == DELEGATED_STATE) {
            return childReader.getNamespaceURI();
        } else if (state == TEXT_STATE) {
            return null;
        } else {
            return elementQName.getNamespaceURI();
        }
    }

    public String getPrefix() {
        if (state == DELEGATED_STATE) {
            return childReader.getPrefix();
        } else if (state == TEXT_STATE) {
            return null;
        } else {
            String prefix = elementQName.getPrefix();
            return "".equals(prefix) ? null : prefix;
        }
    }

    public String getVersion() {
        return null;
    }

    public boolean isStandalone() {
        return true;
    }

    public boolean standaloneSet() {
        return true;
    }

    public String getCharacterEncodingScheme() {
        return null;   //todo - should we return something for this ?
    }

    public String getPITarget() {
        throw new UnsupportedOperationException("Yet to be implemented !!");
    }

    public String getPIData() {
        throw new UnsupportedOperationException("Yet to be implemented !!");
    }

///////////////////////////////////////////////////////////////////////////
/// Other utility methods
//////////////////////////////////////////////////////////////////////////


    /**
     * Populates a namespace context
     */
    private void populateNamespaceContext() {

        //first add the current element namespace to the namespace context
        //declare it if not found
        addToNsMap(elementQName.getPrefix(), elementQName.getNamespaceURI());

        //traverse through the attributes and populate the namespace context
        //the attrib list can be of many combinations
        // the valid combinations are
        // String - String
        // QName - QName
        // null - OMAttribute

        if (attributes != null) {
            for (int i = 0; i < attributes.length; i = i + 2) { //jump in two
                Object attribName = attributes[i];
                if (attribName == null) {
                    //this should be the OMAttrib case!
                    OMAttribute OMAttrib = (OMAttribute) attributes[i + 1];
                    OMNamespace namespace = OMAttrib.getNamespace();
                    if (namespace != null) {
                        addToNsMap(namespace.getPrefix(),
                                namespace.getNamespaceURI());
                    }
                } else if (attribName instanceof OMAttribKey) {
                    //this is definitely the OMAttribute case
                    OMAttribute OMAttrib = (OMAttribute) attributes[i + 1];
                    OMNamespace namespace = OMAttrib.getNamespace();
                    if (namespace != null) {
                        addToNsMap(namespace.getPrefix(),
                                namespace.getNamespaceURI());
                    }
                } else if (attribName instanceof String) {
                    //ignore this case - Nothing to do
                } else if (attribName instanceof QName) {
                    QName attribQName = ((QName) attribName);
                    addToNsMap(attribQName.getPrefix(),
                            attribQName.getNamespaceURI());

                }
            }
        }


    }

    /**
     * @param prefix
     * @param uri
     */
    private void addToNsMap(String prefix, String uri) {
        if (!uri.equals(namespaceContext.getNamespaceURI(prefix))) {
            namespaceContext.pushNamespace(prefix, uri);
            declaredNamespaceMap.put(prefix, uri);
        }
    }

    /**
     * By far this should be the most important method in this class
     * this method changes the state of the parser
     */
    public int next() throws XMLStreamException {
        int returnEvent = -1; //invalid state is the default state
        switch (state) {
            case START_ELEMENT_STATE:
                //current element is start element. We should be looking at the
                //property list and making a pullparser for the property value
                if (properties == null || properties.length == 0) {
                    //no properties - move to the end element state straightaway
                    state = END_ELEMENT_STATE;
                    returnEvent = END_ELEMENT;
                } else {
                    //there are properties. now we should delegate this task to a
                    //child reader depending on the property type
                    returnEvent = processProperties();


                }
                break;
            case END_ELEMENT_STATE:
                //we've reached the end element already. If the user tries to push
                // further ahead then it is an exception
                throw new XMLStreamException(
                        "Trying to go beyond the end of the pullparser");


            case DELEGATED_STATE:
                if (childReader.isDone()) {
                    //we've reached the end!
                    if (currentPropertyIndex > (properties.length - 1)) {
                        state = END_ELEMENT_STATE;
                        returnEvent = END_ELEMENT;
                    } else {
                        returnEvent = processProperties();
                    }
                } else {
                    returnEvent = childReader.next();
                }
                break;

            case TEXT_STATE:
                // if there are any more event we should be delegating to
                // processProperties. if not we just return an end element
                if (currentPropertyIndex > (properties.length - 1)) {
                    state = END_ELEMENT_STATE;
                    returnEvent = END_ELEMENT;
                } else {
                    returnEvent = processProperties();
                }
                break;
        }
        return returnEvent;
    }

    /**
     * A convenient method to reuse the properties
     *
     * @return event to be thrown
     * @throws XMLStreamException
     */
    private int processProperties() throws XMLStreamException {
        //move to the next property depending on the current property
        //index
        Object propPointer = properties[currentPropertyIndex];
        QName propertyQName = null;
        boolean textFound = false;
        if (propPointer == null) {
            throw new XMLStreamException("property key cannot be null!");
        } else if (propPointer instanceof String) {
            // propPointer being a String has a special case
            // that is it can be a the special constant ELEMENT_TEXT that
            // says this text event
            if (ELEMENT_TEXT.equals(propPointer)) {
                textFound = true;
            } else {
                propertyQName = new QName((String) propPointer);
            }
        } else if (propPointer instanceof QName) {
            propertyQName = (QName) propPointer;
        } else if (propPointer instanceof OMElementKey) {
            // ah - in this case there's nothing to be done
            //about the propertyQName in this case - we'll just leave
            //it as it is
        } else {
            //oops - we've no idea what kind of key this is
            throw new XMLStreamException(
                    "unidentified property key!!!" + propPointer);
        }

        //ok! we got the key. Now look at the value
        Object propertyValue = properties[currentPropertyIndex + 1];
        //cater for the special case now
        if (textFound) {
            //no delegation here - make the parser null and immediately
            //return with the event characters
            childReader = null;
            state = TEXT_STATE;
            currentPropertyIndex = currentPropertyIndex + 2;
            return CHARACTERS;
        } else if (propertyValue == null) {
            //if the value is null we delegate the work to a nullable
            // parser
            childReader = new NullXMLStreamReader(propertyQName);
            childReader.addNamespaceContext(this.namespaceContext);
            childReader.init();

            //we've a special pullparser for a datahandler!
        } else if (propertyValue instanceof DataHandler) {
            childReader = new ADBDataHandlerStreamReader(propertyQName,
                    (DataHandler) propertyValue);
            childReader.addNamespaceContext(this.namespaceContext);
            childReader.init();

        } else if (propertyValue instanceof String) {
            //strings are handled by the NameValuePairStreamReader
            childReader =
                    new NameValuePairStreamReader(propertyQName,
                            (String) propertyValue);
            childReader.addNamespaceContext(this.namespaceContext);
            childReader.init();
        } else if (propertyValue instanceof String[]) {
            //string[] are handled by the  NameValueArrayStreamReader
            //if the array is empty - skip it
            if (((String[]) propertyValue).length == 0) {
                //advance the index
                currentPropertyIndex = currentPropertyIndex + 2;
                return processProperties();
            } else {
                childReader =
                        new NameValueArrayStreamReader(propertyQName,
                                (String[]) propertyValue);
                childReader.addNamespaceContext(this.namespaceContext);
                childReader.init();
            }

        } else if (propertyValue instanceof ADBBean) {
            //ADBbean has it's own method to get a reader
            XMLStreamReader reader = ((ADBBean) propertyValue).
                    getPullParser(propertyQName);
            // we know for sure that this is an ADB XMLStreamreader.
            // However we need to make sure that it is compatible
            if (reader instanceof ADBXMLStreamReader) {
                childReader = (ADBXMLStreamReader) reader;
                childReader.addNamespaceContext(this.namespaceContext);
                childReader.init();
            } else {
                //wrap it to make compatible
                childReader = new WrappingXMLStreamReader(
                        reader);
            }
        } else if (propertyValue instanceof OMElement) {
            //OMElements do not provide the kind of parser we need
            //there is no other option than wrapping
            childReader = new WrappingXMLStreamReader(
                    ((OMElement) propertyValue).getXMLStreamReader());
            //we cannot register the namespace context here!!

        } else {
            //all special possiblilities has been tried! Let's treat
            //the thing as a bean and try generating events from it
            childReader = new WrappingXMLStreamReader
                    (BeanUtil.getPullParser(propertyValue,
                            propertyQName, typeTable, qualified));
            //we cannot register the namespace context here
        }

        //set the state here
        state = DELEGATED_STATE;
        //we are done with the delegation
        //increment the property index
        currentPropertyIndex = currentPropertyIndex + 2;
        return childReader.getEventType();
    }

    /**
     * are we done ?
     */
    public boolean isDone() {
        return (state == END_ELEMENT_STATE);
    }

}
