/*   Copyright 2004 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.
 */

package org.apache.xmlbeans.impl.store;

import java.io.Reader;

import java.util.HashMap;
import java.util.Iterator;
import java.util.ConcurrentModificationException;

import javax.xml.namespace.NamespaceContext;
import javax.xml.namespace.QName;

import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.Location;

import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.XmlLineNumber;
import org.apache.xmlbeans.XmlDocumentProperties;

import org.w3c.dom.Node;

public class Jsr173
{
    public static Node nodeFromStream ( XMLStreamReader xs )
    {
        if (!(xs instanceof Jsr173GateWay))
            return null;

        Jsr173GateWay gw = (Jsr173GateWay) xs;

        Locale l = gw._l;

        if (l.noSync())         { l.enter(); try { return nodeFromStreamImpl( gw ); } finally { l.exit(); } }
        else synchronized ( l ) { l.enter(); try { return nodeFromStreamImpl( gw ); } finally { l.exit(); } }

    }

    public static Node nodeFromStreamImpl ( Jsr173GateWay gw )
    {
        Cur c = gw._xs.getStreamCur();

        return c.isNode() ? (Node) c.getDom() : (Node) null;
    }

    public static XMLStreamReader newXmlStreamReader ( Cur c, Object src, int off, int cch )
    {
        XMLStreamReaderBase xs = new XMLStreamReaderForString( c, src, off, cch );

        if (c._locale.noSync())
            return new UnsyncedJsr173( c._locale, xs );
        else
            return new SyncedJsr173( c._locale, xs );
    }

    public static XMLStreamReader newXmlStreamReader ( Cur c, XmlOptions options )
    {
        options = XmlOptions.maskNull( options );

        boolean inner =
            options.hasOption( XmlOptions.SAVE_INNER ) &&
                !options.hasOption( XmlOptions.SAVE_OUTER );

        XMLStreamReaderBase xs;

        int k = c.kind();

        if (k == Cur.TEXT || k < 0)
        {
            xs = new XMLStreamReaderForString( c, c.getChars( -1 ), c._offSrc, c._cchSrc );
        }
        else if (inner)
        {
            if (!c.hasAttrs() && !c.hasChildren())
                xs = new XMLStreamReaderForString( c, c.getFirstChars(), c._offSrc, c._cchSrc );
            else
            {
                assert c.isContainer();
                xs = new XMLStreamReaderForNode( c, true );
            }
        }
        else
            xs = new XMLStreamReaderForNode( c, false );

        if (c._locale.noSync())
            return new UnsyncedJsr173( c._locale, xs );
        else
            return new SyncedJsr173( c._locale, xs );
    }

    //
    //
    //

    private static final class XMLStreamReaderForNode extends XMLStreamReaderBase
    {
        public XMLStreamReaderForNode ( Cur c, boolean inner )
        {
            super( c );

            assert c.isContainer() || c.isComment() || c.isProcinst() || c.isAttr();

            // Iterate over everything *between* _cur and _end.  Do
            // not iterate the thing to the right of _end

            if (inner)
            {
                assert c.isContainer();

                _cur = c.weakCur( this );

                if (!_cur.toFirstAttr())
                    _cur.next();

                _end = c.weakCur( this );
                _end.toEnd();
            }
            else
            {
                _cur = c.weakCur( this );

                if (c.isRoot())
                    _wholeDoc = true;
                else
                {
                    _end = c.weakCur( this );

                    if (c.isAttr())
                    {
                        if (!_end.toNextAttr())
                        {
                            _end.toParent();
                            _end.next();
                        }
                    }
                    else
                        _end.skip();
                }
            }

            if (!_wholeDoc)
            {
                // Set the _done bit properly

                _cur.push();

                try
                {
                    next();
                }
                catch ( XMLStreamException e )
                {
                    throw new RuntimeException( e.getMessage(), e );
                }

                _cur.pop();
            }

            assert _wholeDoc || !_cur.isSamePos( _end );
        }

        protected Cur getStreamCur ( )
        {
            return _cur;
        }

        //
        //
        //

        public boolean hasNext ( ) throws XMLStreamException
        {
            checkChanged();

            return !_done;
        }

        public int getEventType ( )
        {
            switch ( _cur.kind() )
            {
                case  Cur.ROOT     : return START_DOCUMENT;
                case -Cur.ROOT     : return END_DOCUMENT;
                case  Cur.ELEM     : return START_ELEMENT;
                case -Cur.ELEM     : return END_ELEMENT;
                case  Cur.ATTR     : return _cur.isXmlns() ? NAMESPACE : ATTRIBUTE;
                case  Cur.TEXT     : return CHARACTERS;
                case  Cur.COMMENT  : return COMMENT;
                case  Cur.PROCINST : return PROCESSING_INSTRUCTION;
                default            : throw new IllegalStateException();
            }
        }

        public int next ( ) throws XMLStreamException
        {
            checkChanged();

            if (!hasNext())
                throw new IllegalStateException( "No next event in stream" );

            int kind = _cur.kind();

            if (kind == -Cur.ROOT)
            {
                assert _wholeDoc;
                _done = true;
            }
            else
            {
                if (kind == Cur.ATTR)
                {
                    if (!_cur.toNextAttr())
                    {
                        _cur.toParent();
                        _cur.next();
                    }
                }
                else if (kind == Cur.COMMENT || kind == Cur.PROCINST)
                    _cur.skip();
                else if (kind == Cur.ROOT)
                {
                    if (!_cur.toFirstAttr())
                        _cur.next();
                }
                else
                    _cur.next();

                assert _wholeDoc || _end != null;

                _done = _wholeDoc ? _cur.kind() == -Cur.ROOT : _cur.isSamePos( _end );
            }

            _textFetched = false;
            _srcFetched = false;

            return getEventType();
        }

        public String getText ( )
        {
            checkChanged();

            int k = _cur.kind();

            if (k == Cur.COMMENT)
                return _cur.getValueAsString();

            if (k == Cur.TEXT)
                return _cur.getCharsAsString();

            throw new IllegalStateException();
        }

        public boolean isStartElement ( )
        {
            return getEventType() == START_ELEMENT;
        }

        public boolean isEndElement ( )
        {
            return getEventType() == END_ELEMENT;
        }

        public boolean isCharacters ( )
        {
            return getEventType() == CHARACTERS;
        }

        public String getElementText ( ) throws XMLStreamException
        {
            checkChanged();

            if (!isStartElement())
                throw new IllegalStateException();

            StringBuilder sb = new StringBuilder();

            for ( ; ; )
            {
                if (!hasNext())
                    throw new XMLStreamException();

                int e = next();

                if (e == END_ELEMENT)
                    break;
                else if (e == START_ELEMENT)
                    throw new XMLStreamException();
                else if (e != COMMENT && e != PROCESSING_INSTRUCTION)
                    sb.append( getText() );
            }

            return sb.toString();
        }

        public int nextTag ( ) throws XMLStreamException
        {
            checkChanged();

            for ( ; ; )
            {
                if (isStartElement() || isEndElement())
                    return getEventType();

                if (!isWhiteSpace())
                    throw new XMLStreamException();

                if (!hasNext())
                    throw new XMLStreamException();

                next();
            }
        }

        private static boolean matchAttr ( Cur c, String uri, String local )
        {
            assert c.isNormalAttr();

            QName name = c.getName();

            return
                name.getLocalPart().equals( local ) &&
                    (uri == null || name.getNamespaceURI().equals( uri ));
        }

        private static Cur toAttr ( Cur c, String uri, String local )
        {
            if (uri == null || local == null || local.length() == 0)
                throw new IllegalArgumentException();

            Cur ca = c.tempCur();
            boolean match = false;

            if (c.isElem())
            {
                if (ca.toFirstAttr())
                {
                    do
                    {
                        if (ca.isNormalAttr() && matchAttr( ca, uri, local ))
                        {
                            match = true;
                            break;
                        }
                    }
                    while ( ca.toNextSibling() );
                }
            }
            else if (c.isNormalAttr())
                match = matchAttr( c, uri, local );
            else
                throw new IllegalStateException();

            if (!match)
            {
                ca.release();
                ca = null;
            }

            return ca;
        }

        public String getAttributeValue ( String uri, String local )
        {
            Cur ca = toAttr( _cur, uri, local );

            String value = null;

            if (ca != null)
            {
                value = ca.getValueAsString();
                ca.release();
            }

            return value;
        }

        private static Cur toAttr ( Cur c, int i )
        {
            if (i < 0)
                throw new IndexOutOfBoundsException( "Attribute index is negative" );

            Cur ca = c.tempCur();
            boolean match = false;

            if (c.isElem())
            {
                if (ca.toFirstAttr())
                {
                    do
                    {
                        if (ca.isNormalAttr() && i-- == 0)
                        {
                            match = true;
                            break;
                        }
                    }
                    while ( ca.toNextSibling() );
                }
            }
            else if (c.isNormalAttr())
                match = i == 0;
            else
                throw new IllegalStateException();

            if (!match)
            {
                ca.release();
                throw new IndexOutOfBoundsException( "Attribute index is too large" );
            }

            return ca;
        }

        public int getAttributeCount ( )
        {
            int n = 0;

            if (_cur.isElem())
            {
                Cur ca = _cur.tempCur();

                if (ca.toFirstAttr())
                {
                    do
                    {
                        if (ca.isNormalAttr())
                            n++;
                    }
                    while ( ca.toNextSibling() );
                }

                ca.release();
            }
            else if (_cur.isNormalAttr())
                n++;
            else
                throw new IllegalStateException();

            return n;
        }

        public QName getAttributeName ( int index )
        {
            Cur ca = toAttr( _cur, index );
            QName name = ca.getName();
            ca.release();
            return name;
        }

        public String getAttributeNamespace ( int index )
        {
            return getAttributeName( index ).getNamespaceURI();
        }

        public String getAttributeLocalName ( int index )
        {
            return getAttributeName( index ).getLocalPart();
        }

        public String getAttributePrefix ( int index )
        {
            return getAttributeName( index ).getPrefix();
        }

        public String getAttributeType ( int index )
        {
            toAttr( _cur, index ).release();
            return "CDATA";
        }

        public String getAttributeValue ( int index )
        {
            Cur ca = toAttr( _cur, index );

            String value = null;

            if (ca != null)
            {
                value = ca.getValueAsString();
                ca.release();
            }

            return value;
        }

        public boolean isAttributeSpecified ( int index )
        {
            // Go to attr to force index check
            Cur ca = toAttr( _cur, index );
            ca.release();

            return false;
        }

        public int getNamespaceCount ( )
        {
            int n = 0;

            if (_cur.isElem() || _cur.kind() == -Cur.ELEM)
            {
                Cur ca = _cur.tempCur();

                if (_cur.kind() == -Cur.ELEM)
                    ca.toParent();

                if (ca.toFirstAttr())
                {
                    do
                    {
                        if (ca.isXmlns())
                            n++;
                    }
                    while ( ca.toNextSibling() );
                }

                ca.release();
            }
            else if (_cur.isXmlns())
                n++;
            else
                throw new IllegalStateException();

            return n;
        }

        private static Cur toXmlns ( Cur c, int i )
        {
            if (i < 0)
                throw new IndexOutOfBoundsException( "Namespace index is negative" );

            Cur ca = c.tempCur();
            boolean match = false;

            if (c.isElem() || c.kind() == -Cur.ELEM)
            {
                if (c.kind() == -Cur.ELEM)
                    ca.toParent();

                if (ca.toFirstAttr())
                {
                    do
                    {
                        if (ca.isXmlns() && i-- == 0)
                        {
                            match = true;
                            break;
                        }
                    }
                    while ( ca.toNextSibling() );
                }
            }
            else if (c.isXmlns())
                match = i == 0;
            else
                throw new IllegalStateException();

            if (!match)
            {
                ca.release();
                throw new IndexOutOfBoundsException( "Namespace index is too large" );
            }

            return ca;
        }

        public String getNamespacePrefix ( int index )
        {
            Cur ca = toXmlns( _cur, index );
            String prefix = ca.getXmlnsPrefix();
            ca.release();
            return prefix;
        }

        public String getNamespaceURI ( int index )
        {
            Cur ca = toXmlns( _cur, index );
            String uri = ca.getXmlnsUri();
            ca.release();
            return uri;
        }

        private void fetchChars ( )
        {
            if (!_textFetched)
            {
                int k = _cur.kind();

                Cur cText = null;

                if (k == Cur.COMMENT)
                {
                    cText = _cur.tempCur();
                    cText.next();
                }
                else if (k == Cur.TEXT)
                    cText = _cur;
                else
                    throw new IllegalStateException();

                Object src = cText.getChars( -1 );

                ensureCharBufLen( cText._cchSrc );

                CharUtil.getChars(
                    _chars, _offChars = 0, src, cText._offSrc, _cchChars = cText._cchSrc );

                if (cText != _cur)
                    cText.release();

                _textFetched = true;
            }
        }

        private void ensureCharBufLen ( int cch )
        {
            if (_chars == null || _chars.length < cch)
            {
                int l = 256;

                while ( l < cch )
                    l *= 2;

                _chars = new char [ l ];
            }
        }

        public char[] getTextCharacters ( )
        {
            checkChanged();

            fetchChars();

            return _chars;
        }

        public int getTextStart ( )
        {
            checkChanged();

            fetchChars();

            return _offChars;
        }

        public int getTextLength ( )
        {
            checkChanged();

            fetchChars();

            return _cchChars;
        }

        public int getTextCharacters (
            int sourceStart, char[] target, int targetStart, int length )
                throws XMLStreamException
        {
            if (length < 0)
                throw new IndexOutOfBoundsException();

            if (targetStart < 0 || targetStart >= target.length)
                throw new IndexOutOfBoundsException();

            if (targetStart + length > target.length)
                throw new IndexOutOfBoundsException();

            if (!_srcFetched)
            {
                int k = _cur.kind();

                Cur cText = null;

                if (k == Cur.COMMENT)
                {
                    cText = _cur.tempCur();
                    cText.next();
                }
                else if (k == Cur.TEXT)
                    cText = _cur;
                else
                    throw new IllegalStateException();

                _src = cText.getChars( -1 );
                _offSrc = cText._offSrc;
                _cchSrc = cText._cchSrc;

                if (cText != _cur)
                    cText.release();

                _srcFetched = true;
            }

            if (sourceStart > _cchSrc)
                throw new IndexOutOfBoundsException();

            if (sourceStart + length > _cchSrc)
                length = _cchSrc - sourceStart;

            CharUtil.getChars( target, targetStart, _src, _offSrc, length );

            return length;
        }

        public boolean hasText ( )
        {
            int k = _cur.kind();

            return k == Cur.COMMENT || k == Cur.TEXT;
        }

        public boolean hasName ( )
        {
            int k = _cur.kind();
            return k == Cur.ELEM || k == -Cur.ELEM;
        }

        public QName getName ( )
        {
            if (!hasName())
                throw new IllegalStateException();

            return _cur.getName();
        }

        public String getNamespaceURI ( )
        {
            return getName().getNamespaceURI();
        }

        public String getLocalName ( )
        {
            return getName().getLocalPart();
        }

        public String getPrefix ( )
        {
            return getName().getPrefix();
        }

        public String getPITarget ( )
        {
            return _cur.kind() == Cur.PROCINST ? _cur.getName().getLocalPart() : null;
        }

        public String getPIData ( )
        {
            return _cur.kind() == Cur.PROCINST ? _cur.getValueAsString() : null;
        }

        //
        //
        //

        private boolean _wholeDoc;
        private boolean _done;

        private Cur _cur;
        private Cur _end;

        private boolean _srcFetched;
        private Object  _src;
        private int     _offSrc;
        private int     _cchSrc;

        private boolean _textFetched;
        private char[]  _chars;
        private int     _offChars;
        private int     _cchChars;
    }

    //
    //
    //

    private static abstract class XMLStreamReaderBase
        implements XMLStreamReader, NamespaceContext, Location
    {
        XMLStreamReaderBase ( Cur c )
        {
            _locale = c._locale;
            _version = _locale.version();
        }

        protected final void checkChanged ( )
        {
            if (_version != _locale.version())
                throw new ConcurrentModificationException( "Document changed while streaming" );
        }

        //
        // XMLStreamReader methods
        //

        public void close ( ) throws XMLStreamException
        {
            checkChanged();
        }

        public boolean isWhiteSpace ( )
        {
            checkChanged();

            // TODO - avoid creating a string here
            String s = getText();

            return _locale.getCharUtil().isWhiteSpace( s, 0, s.length() );
        }

        public Location getLocation ( )
        {
            checkChanged();

            Cur c = getStreamCur();

            XmlLineNumber ln = (XmlLineNumber) c.getBookmark( XmlLineNumber.class );

            // BUGBUG - put source name here
            _uri = null;

            if (ln != null)
            {
                _line = ln.getLine();
                _column = ln.getColumn();
                _offset = ln.getOffset();
            }
            else
            {
                _line = -1;
                _column = -1;
                _offset = -1;
            }

            return this;
        }


        public Object getProperty ( String name )
        {
            checkChanged();

            if (name == null)
                throw new IllegalArgumentException( "Property name is null" );

            // BUGBUG - I should implement some perperties here

            return null;
        }

        public String getCharacterEncodingScheme ( )
        {
            checkChanged();

            XmlDocumentProperties props = _locale.getDocProps( getStreamCur(), false );

            return props == null ? null : props.getEncoding();
        }

        public String getEncoding ( )
        {
            // BUGBUG - this should probably return the actual decoding used on the document
            return null;
        }

        public String getVersion ( )
        {
            checkChanged();

            XmlDocumentProperties props = _locale.getDocProps( getStreamCur(), false );

            return props == null ? null : props.getVersion();
        }

        public boolean isStandalone ( )
        {
            checkChanged();

            XmlDocumentProperties props = _locale.getDocProps( getStreamCur(), false );

            return props == null ? false : props.getStandalone();
        }

        public boolean standaloneSet ( )
        {
            checkChanged();

            return false;
        }

        public void require ( int type, String namespaceURI, String localName )
            throws XMLStreamException
        {
            checkChanged();

            if (type != getEventType())
                throw new XMLStreamException();

            if (namespaceURI != null && !getNamespaceURI().equals( namespaceURI ))
                throw new XMLStreamException();

            if (localName != null && !getLocalName().equals( localName ))
                throw new XMLStreamException();
        }

        //
        // Location methods do not need a gatway
        //

        public int    getCharacterOffset ( ) { return _offset; }
        public int    getColumnNumber    ( ) { return _column; }
        public int    getLineNumber      ( ) { return _line;   }
        public String getLocationURI     ( ) { return _uri;    }

        public String getPublicId ( ) { return null; }
        public String getSystemId ( ) { return null; }

        public NamespaceContext getNamespaceContext ( )
        {
            throw new RuntimeException( "This version of getNamespaceContext should not be called");
        }

        public String getNamespaceURI ( String prefix )
        {
            checkChanged();

            Cur c = getStreamCur();

            c.push();

            if (!c.isContainer())
                c.toParent();

            String ns = c.namespaceForPrefix( prefix, true );

            c.pop();

            return ns;
        }

        public String getPrefix ( String namespaceURI )
        {
            checkChanged();

            Cur c = getStreamCur();

            c.push();

            if (!c.isContainer())
                c.toParent();

            String prefix = c.prefixForNamespace( namespaceURI, null, false );

            c.pop();

            return prefix;
        }

        public Iterator getPrefixes ( String namespaceURI )
        {
            checkChanged();

            // BUGBUG - get only one for now ...

            HashMap map = new HashMap();

            map.put( namespaceURI, getPrefix( namespaceURI ) );

            return map.values().iterator();
        }

        //
        //
        //

        protected abstract Cur getStreamCur ( );

        //
        //
        //

        private Locale _locale;
        private long   _version;

        String _uri;

        int _line   = -1;
        int _column = -1;
        int _offset = -1;
    }

    //
    //
    //

    private static final class XMLStreamReaderForString extends XMLStreamReaderBase
    {
        XMLStreamReaderForString ( Cur c, Object src, int off, int cch )
        {
            super( c );

            _src = src;
            _off = off;
            _cch = cch;

            _cur = c;
        }

        protected Cur getStreamCur ( )
        {
            return _cur;
        }

        //
        // Legal stream methods
        //

        public String getText ( )
        {
            checkChanged();

            return CharUtil.getString( _src, _off, _cch );
        }

        public char[] getTextCharacters ( )
        {
            checkChanged();

            char[] chars = new char [ _cch ];

            CharUtil.getChars( chars, 0, _src, _off, _cch );

            return chars;
        }
        public int getTextStart ( )
        {
            checkChanged();

            return _off;
        }
        public int getTextLength ( )
        {
            checkChanged();

            return _cch;
        }

        public int getTextCharacters ( int sourceStart, char[] target, int targetStart, int length )
        {
            checkChanged();

            if (length < 0)
                throw new IndexOutOfBoundsException();

            if (sourceStart > _cch)
                throw new IndexOutOfBoundsException();

            if (sourceStart + length > _cch)
                length = _cch - sourceStart;

            CharUtil.getChars( target, targetStart, _src, _off + sourceStart, length );

            return length;
        }

        public int     getEventType      ( ) { checkChanged(); return CHARACTERS; }
        public boolean hasName           ( ) { checkChanged(); return false;      }
        public boolean hasNext           ( ) { checkChanged(); return false;      }
        public boolean hasText           ( ) { checkChanged(); return true;       }
        public boolean isCharacters      ( ) { checkChanged(); return true;       }
        public boolean isEndElement      ( ) { checkChanged(); return false;      }
        public boolean isStartElement    ( ) { checkChanged(); return false;      }

        //
        // Illegal stream methods
        //

        public int     getAttributeCount ( ) { throw new IllegalStateException(); }
        public String  getAttributeLocalName ( int index ) { throw new IllegalStateException(); }
        public QName   getAttributeName ( int index ) { throw new IllegalStateException(); }
        public String  getAttributeNamespace ( int index ) { throw new IllegalStateException(); }
        public String  getAttributePrefix ( int index ) { throw new IllegalStateException(); }
        public String  getAttributeType ( int index ) { throw new IllegalStateException(); }
        public String  getAttributeValue ( int index ) { throw new IllegalStateException(); }
        public String  getAttributeValue ( String namespaceURI, String localName ) { throw new IllegalStateException(); }
        public String  getElementText ( ) { throw new IllegalStateException(); }
        public String  getLocalName ( ) { throw new IllegalStateException(); }
        public QName   getName ( ) { throw new IllegalStateException(); }
        public int     getNamespaceCount ( ) { throw new IllegalStateException(); }
        public String  getNamespacePrefix ( int index ) { throw new IllegalStateException(); }
        public String  getNamespaceURI ( int index ) { throw new IllegalStateException(); }
        public String  getNamespaceURI ( ) { throw new IllegalStateException(); }
        public String  getPIData ( ) { throw new IllegalStateException(); }
        public String  getPITarget ( ) { throw new IllegalStateException(); }
        public String  getPrefix ( ) { throw new IllegalStateException(); }
        public boolean isAttributeSpecified ( int index ) { throw new IllegalStateException(); }
        public int     next ( ) { throw new IllegalStateException(); }
        public int     nextTag ( ) { throw new IllegalStateException(); }
        public String  getPublicId() { throw new IllegalStateException();  }
        public String  getSystemId() { throw new IllegalStateException();  }

        private Cur    _cur;
        private Object _src;
        private int    _off;
        private int    _cch;
    }

    //
    //
    //

    private static abstract class Jsr173GateWay
    {
        public Jsr173GateWay ( Locale l, XMLStreamReaderBase xs ) { _l = l; _xs = xs; }

        Locale              _l;
        XMLStreamReaderBase _xs;
    }

    private static final class SyncedJsr173 extends Jsr173GateWay implements XMLStreamReader, Location, NamespaceContext
    {
        public SyncedJsr173 ( Locale l, XMLStreamReaderBase xs ) { super( l, xs ); }

        public Object getProperty ( java.lang.String name ) { synchronized ( _l ) { _l.enter(); try { return _xs.getProperty( name ); } finally { _l.exit(); } } }
        public int next ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.next(); } finally { _l.exit(); } } }
        public void require ( int type, String namespaceURI, String localName ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { _xs.require( type, namespaceURI, localName ); } finally { _l.exit(); } } }
        public String getElementText ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.getElementText(); } finally { _l.exit(); } } }
        public int nextTag ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.nextTag(); } finally { _l.exit(); } } }
        public boolean hasNext ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.hasNext(); } finally { _l.exit(); } } }
        public void close ( ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { _xs.close(); } finally { _l.exit(); } } }
        public String getNamespaceURI ( String prefix ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceURI ( prefix ); } finally { _l.exit(); } } }
        public boolean isStartElement ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isStartElement(); } finally { _l.exit(); } } }
        public boolean isEndElement ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isEndElement(); } finally { _l.exit(); } } }
        public boolean isCharacters ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isCharacters(); } finally { _l.exit(); } } }
        public boolean isWhiteSpace ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isWhiteSpace(); } finally { _l.exit(); } } }
        public String getAttributeValue ( String namespaceURI, String localName ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeValue ( namespaceURI, localName ); } finally { _l.exit(); } } }
        public int getAttributeCount ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeCount(); } finally { _l.exit(); } } }
        public QName getAttributeName ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeName ( index ); } finally { _l.exit(); } } }
        public String getAttributeNamespace ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeNamespace ( index ); } finally { _l.exit(); } } }
        public String getAttributeLocalName ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeLocalName ( index ); } finally { _l.exit(); } } }
        public String getAttributePrefix ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributePrefix ( index ); } finally { _l.exit(); } } }
        public String getAttributeType ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeType ( index ); } finally { _l.exit(); } } }
        public String getAttributeValue ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getAttributeValue ( index ); } finally { _l.exit(); } } }
        public boolean isAttributeSpecified ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.isAttributeSpecified ( index ); } finally { _l.exit(); } } }
        public int getNamespaceCount ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceCount(); } finally { _l.exit(); } } }
        public String getNamespacePrefix ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespacePrefix ( index ); } finally { _l.exit(); } } }
        public String getNamespaceURI ( int index ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceURI ( index ); } finally { _l.exit(); } } }
        public NamespaceContext getNamespaceContext ( ) { return this; }
        public int getEventType ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getEventType(); } finally { _l.exit(); } } }
        public String getText ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getText(); } finally { _l.exit(); } } }
        public char[] getTextCharacters ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getTextCharacters(); } finally { _l.exit(); } } }
        public int getTextCharacters ( int sourceStart, char[] target, int targetStart, int length ) throws XMLStreamException { synchronized ( _l ) { _l.enter(); try { return _xs.getTextCharacters ( sourceStart, target, targetStart, length ); } finally { _l.exit(); } } }
        public int getTextStart ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getTextStart(); } finally { _l.exit(); } } }
        public int getTextLength ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getTextLength(); } finally { _l.exit(); } } }
        public String getEncoding ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getEncoding(); } finally { _l.exit(); } } }
        public boolean hasText ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.hasText(); } finally { _l.exit(); } } }
        public Location getLocation ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocation(); } finally { _l.exit(); } } }
        public QName getName ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getName(); } finally { _l.exit(); } } }
        public String getLocalName ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocalName(); } finally { _l.exit(); } } }
        public boolean hasName ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.hasName(); } finally { _l.exit(); } } }
        public String getNamespaceURI ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getNamespaceURI(); } finally { _l.exit(); } } }
        public String getPrefix ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPrefix(); } finally { _l.exit(); } } }
        public String getVersion ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getVersion(); } finally { _l.exit(); } } }
        public boolean isStandalone ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.isStandalone(); } finally { _l.exit(); } } }
        public boolean standaloneSet ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.standaloneSet(); } finally { _l.exit(); } } }
        public String getCharacterEncodingScheme ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getCharacterEncodingScheme(); } finally { _l.exit(); } } }
        public String getPITarget ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPITarget(); } finally { _l.exit(); } } }
        public String getPIData ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPIData(); } finally { _l.exit(); } } }
        public String getPrefix ( String namespaceURI ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPrefix( namespaceURI ); } finally { _l.exit(); } } }
        public Iterator getPrefixes ( String namespaceURI ) { synchronized ( _l ) { _l.enter(); try { return _xs.getPrefixes( namespaceURI ); } finally { _l.exit(); } } }
        public int getCharacterOffset ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getCharacterOffset(); } finally { _l.exit(); } } }
        public int getColumnNumber ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getColumnNumber(); } finally { _l.exit(); } } }
        public int getLineNumber ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLineNumber(); } finally { _l.exit(); } } }
        public String getLocationURI ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocationURI(); } finally { _l.exit(); } } }
        public String getPublicId() { synchronized ( _l ) { _l.enter(); try { return _xs.getPublicId(); } finally { _l.exit(); } } }
        public String getSystemId() { synchronized ( _l ) { _l.enter(); try { return _xs.getSystemId(); } finally { _l.exit(); } } }
    }

    private static final class UnsyncedJsr173 extends Jsr173GateWay implements XMLStreamReader, Location, NamespaceContext
    {
        public UnsyncedJsr173 ( Locale l, XMLStreamReaderBase xs ) { super( l, xs ); }

        public Object getProperty ( java.lang.String name ) { try { _l.enter(); return _xs.getProperty( name ); } finally { _l.exit(); } }
        public int next ( ) throws XMLStreamException { try { _l.enter(); return _xs.next(); } finally { _l.exit(); } }
        public void require ( int type, String namespaceURI, String localName ) throws XMLStreamException { try { _l.enter(); _xs.require( type, namespaceURI, localName ); } finally { _l.exit(); } }
        public String getElementText ( ) throws XMLStreamException { try { _l.enter(); return _xs.getElementText(); } finally { _l.exit(); } }
        public int nextTag ( ) throws XMLStreamException { try { _l.enter(); return _xs.nextTag(); } finally { _l.exit(); } }
        public boolean hasNext ( ) throws XMLStreamException { try { _l.enter(); return _xs.hasNext(); } finally { _l.exit(); } }
        public void close ( ) throws XMLStreamException { try { _l.enter(); _xs.close(); } finally { _l.exit(); } }
        public String getNamespaceURI ( String prefix ) { try { _l.enter(); return _xs.getNamespaceURI ( prefix ); } finally { _l.exit(); } }
        public boolean isStartElement ( ) { try { _l.enter(); return _xs.isStartElement(); } finally { _l.exit(); } }
        public boolean isEndElement ( ) { try { _l.enter(); return _xs.isEndElement(); } finally { _l.exit(); } }
        public boolean isCharacters ( ) { try { _l.enter(); return _xs.isCharacters(); } finally { _l.exit(); } }
        public boolean isWhiteSpace ( ) { try { _l.enter(); return _xs.isWhiteSpace(); } finally { _l.exit(); } }
        public String getAttributeValue ( String namespaceURI, String localName ) { try { _l.enter(); return _xs.getAttributeValue ( namespaceURI, localName ); } finally { _l.exit(); } }
        public int getAttributeCount ( ) { try { _l.enter(); return _xs.getAttributeCount(); } finally { _l.exit(); } }
        public QName getAttributeName ( int index ) { try { _l.enter(); return _xs.getAttributeName ( index ); } finally { _l.exit(); } }
        public String getAttributeNamespace ( int index ) { try { _l.enter(); return _xs.getAttributeNamespace ( index ); } finally { _l.exit(); } }
        public String getAttributeLocalName ( int index ) { try { _l.enter(); return _xs.getAttributeLocalName ( index ); } finally { _l.exit(); } }
        public String getAttributePrefix ( int index ) { try { _l.enter(); return _xs.getAttributePrefix ( index ); } finally { _l.exit(); } }
        public String getAttributeType ( int index ) { try { _l.enter(); return _xs.getAttributeType ( index ); } finally { _l.exit(); } }
        public String getAttributeValue ( int index ) { try { _l.enter(); return _xs.getAttributeValue ( index ); } finally { _l.exit(); } }
        public boolean isAttributeSpecified ( int index ) { try { _l.enter(); return _xs.isAttributeSpecified ( index ); } finally { _l.exit(); } }
        public int getNamespaceCount ( ) { try { _l.enter(); return _xs.getNamespaceCount(); } finally { _l.exit(); } }
        public String getNamespacePrefix ( int index ) { try { _l.enter(); return _xs.getNamespacePrefix ( index ); } finally { _l.exit(); } }
        public String getNamespaceURI ( int index ) { try { _l.enter(); return _xs.getNamespaceURI ( index ); } finally { _l.exit(); } }
        public NamespaceContext getNamespaceContext ( ) { return this; }
        public int getEventType ( ) { try { _l.enter(); return _xs.getEventType(); } finally { _l.exit(); } }
        public String getText ( ) { try { _l.enter(); return _xs.getText(); } finally { _l.exit(); } }
        public char[] getTextCharacters ( ) { try { _l.enter(); return _xs.getTextCharacters(); } finally { _l.exit(); } }
        public int getTextCharacters ( int sourceStart, char[] target, int targetStart, int length ) throws XMLStreamException { try { _l.enter(); return _xs.getTextCharacters ( sourceStart, target, targetStart, length ); } finally { _l.exit(); } }
        public int getTextStart ( ) { try { _l.enter(); return _xs.getTextStart(); } finally { _l.exit(); } }
        public int getTextLength ( ) { try { _l.enter(); return _xs.getTextLength(); } finally { _l.exit(); } }
        public String getEncoding ( ) { try { _l.enter(); return _xs.getEncoding(); } finally { _l.exit(); } }
        public boolean hasText ( ) { try { _l.enter(); return _xs.hasText(); } finally { _l.exit(); } }
        public Location getLocation ( ) { try { _l.enter(); return _xs.getLocation(); } finally { _l.exit(); } }
        public QName getName ( ) { try { _l.enter(); return _xs.getName(); } finally { _l.exit(); } }
        public String getLocalName ( ) { try { _l.enter(); return _xs.getLocalName(); } finally { _l.exit(); } }
        public boolean hasName ( ) { try { _l.enter(); return _xs.hasName(); } finally { _l.exit(); } }
        public String getNamespaceURI ( ) { try { _l.enter(); return _xs.getNamespaceURI(); } finally { _l.exit(); } }
        public String getPrefix ( ) { try { _l.enter(); return _xs.getPrefix(); } finally { _l.exit(); } }
        public String getVersion ( ) { try { _l.enter(); return _xs.getVersion(); } finally { _l.exit(); } }
        public boolean isStandalone ( ) { try { _l.enter(); return _xs.isStandalone(); } finally { _l.exit(); } }
        public boolean standaloneSet ( ) { try { _l.enter(); return _xs.standaloneSet(); } finally { _l.exit(); } }
        public String getCharacterEncodingScheme ( ) { try { _l.enter(); return _xs.getCharacterEncodingScheme(); } finally { _l.exit(); } }
        public String getPITarget ( ) { try { _l.enter(); return _xs.getPITarget(); } finally { _l.exit(); } }
        public String getPIData ( ) { try { _l.enter(); return _xs.getPIData(); } finally { _l.exit(); } }
        public String getPrefix ( String namespaceURI ) { try { _l.enter(); return _xs.getPrefix( namespaceURI ); } finally { _l.exit(); } }
        public Iterator getPrefixes ( String namespaceURI ) { try { _l.enter(); return _xs.getPrefixes( namespaceURI ); } finally { _l.exit(); } }
        public int getCharacterOffset ( ) { try { _l.enter(); return _xs.getCharacterOffset(); } finally { _l.exit(); } }
        public int getColumnNumber ( ) { try { _l.enter(); return _xs.getColumnNumber(); } finally { _l.exit(); } }
        public int getLineNumber ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLineNumber(); } finally { _l.exit(); } } }
        public String getLocationURI ( ) { synchronized ( _l ) { _l.enter(); try { return _xs.getLocationURI(); } finally { _l.exit(); } } }
        public String getPublicId() { synchronized ( _l ) { _l.enter(); try { return _xs.getPublicId(); } finally { _l.exit(); } } }
        public String getSystemId() { synchronized ( _l ) { _l.enter(); try { return _xs.getSystemId(); } finally { _l.exit(); } } }
    }
}

