/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.
 */

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.axiom.om.impl.util.OMSerializerUtil;
import org.apache.axis2.databinding.ADBBean;
import org.apache.axis2.databinding.typemapping.SimpleTypeMapper;
import org.apache.axis2.databinding.utils.BeanUtil;
import org.apache.axis2.databinding.utils.ConverterUtil;
import org.apache.axis2.description.java2wsdl.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.*;
import java.lang.reflect.Array;

/**
 * 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;

    //This is to store the QName which are in the typeTable after setting the correct prefix
    private HashMap qnameMap = new HashMap();

    //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;
        if(this.typeTable!=null){
            Map complexTypeMap = this.typeTable.getComplexSchemaMap();
            if(complexTypeMap !=null){
                Iterator keys = complexTypeMap.keySet().iterator();
                while (keys.hasNext()) {
                    String key = (String) keys.next();
                    QName qname = (QName) complexTypeMap.get(key);
                    if(qname !=null){
                        String prefix =qname.getPrefix();
                        if(prefix ==null && "".equals(prefix)){
                            prefix = OMSerializerUtil.getNextNSPrefix();
                        }
                        qname = new QName(qname.getNamespaceURI(),qname.getLocalPart(),prefix);
                        this.typeTable.getComplexSchemaMap().put(key,qname);
                        qnameMap.put(qname.getNamespaceURI(),prefix);
                        addToNsMap(prefix, qname.getNamespaceURI());
                    }
                }
            }
        }
    }

    /** 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) {
                        if (omAttribObj instanceof QName){
                           QName attributeQName = (QName) omAttribObj;
                           // first check it is already there if not add the namespace.
                           String prefix = namespaceContext.getPrefix(attributeQName.getNamespaceURI());
                           if (prefix == null){
                               prefix = OMSerializerUtil.getNextNSPrefix();
                               addToNsMap(prefix,attributeQName.getNamespaceURI());
                           }

                           String attributeValue = null;
                           if (prefix.equals("")){
                               // i.e. this is the default namespace
                               attributeValue = attributeQName.getLocalPart();
                           } else {
                               attributeValue = prefix + ":" + attributeQName.getLocalPart();
                           }
                           return attributeValue;
                        } else {
                            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) {
            Object property = properties[currentPropertyIndex - 1];
            if (property instanceof DataHandler){
                return ConverterUtil.getStringFromDatahandler((DataHandler)property);
            } else {
                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);
        }

        if(propertyQName!=null){
            String prefix = (String) qnameMap.get(propertyQName.getNamespaceURI());
            if(prefix!=null){
                propertyQName = new QName(propertyQName.getNamespaceURI(),propertyQName.getLocalPart(),prefix);
            }
        }

        //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.getClass().isArray()) {
            // this is an arrary object and we need to get the pull parser for that
            int length = Array.getLength(propertyValue);
            if (length == 0) {
                //advance the index
                currentPropertyIndex = currentPropertyIndex + 2;
                return processProperties();
            } else {
                List objects = new ArrayList();
                Object valueObject = null;
                for (int i = 0; i < length; i++) {
                    //for innter Arrary Complex types we use the special local name array
                    objects.add(new QName(propertyQName.getNamespaceURI(), "array"));
                    valueObject = Array.get(propertyValue, i);
                    if ((valueObject != null) && SimpleTypeMapper.isSimpleType(valueObject)){
                        objects.add(SimpleTypeMapper.getStringValue(valueObject));
                    } else {
                        objects.add(valueObject);
                    }
                }

                ADBXMLStreamReader reader = new ADBXMLStreamReaderImpl(propertyQName,
                        objects.toArray(), new ArrayList().toArray(), typeTable, qualified);
                childReader = new WrappingXMLStreamReader(reader);
            }
        } 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, false));
            //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;
        // If necessary, discard the START_DOCUMENT element (AXIS2-4271)
        int eventType = childReader.getEventType();
        return eventType == START_DOCUMENT ? childReader.next() : eventType;
    }

    /** are we done ? */
    public boolean isDone() {
        return (state == END_ELEMENT_STATE);
    }

}
