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



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_xmloff.hxx"
#include <rtl/ref.hxx>
#include <rtl/ustrbuf.hxx>
#include <com/sun/star/i18n/XCharacterClassification.hpp>
#include <com/sun/star/i18n/UnicodeType.hpp>
#include <comphelper/processfactory.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include "IgnoreTContext.hxx"
#include "RenameElemTContext.hxx"
#include "ProcAttrTContext.hxx"
#include "ProcAddAttrTContext.hxx"
#include "MergeElemTContext.hxx"
#include "CreateElemTContext.hxx"
#include "MutableAttrList.hxx"
#include "TransformerActions.hxx"
#include "ElemTransformerAction.hxx"
// --> OD 2005-06-29 #i50322#
#include "PropertyActionsOOo.hxx"
// <--
#ifndef _XMLOFF_TRANSFORMERTOKENMAP_HXX
#include "TransformerTokenMap.hxx"
#endif
#include <xmloff/xmluconv.hxx>

#ifndef _XMLOFF_TRANSFORMERBASE_HXX
#include "TransformerBase.hxx"
#endif
#include "TContextVector.hxx"

using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using namespace ::osl;
using namespace ::xmloff::token;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::i18n;
using namespace ::com::sun::star::xml::sax;

// -----------------------------------------------------------------------------

namespace
{
bool lcl_ConvertAttr( OUString & rOutAttribute, sal_Int32 nParam )
{
    bool bResult = false;
    enum XMLTokenEnum eTokenToRename =
        static_cast< enum XMLTokenEnum >( nParam & 0xffff );
    if( eTokenToRename != XML_TOKEN_INVALID &&
        IsXMLToken( rOutAttribute, eTokenToRename ))
    {
        enum XMLTokenEnum eReplacementToken =
            static_cast< enum XMLTokenEnum >( nParam >> 16 );
        rOutAttribute = GetXMLToken( eReplacementToken );
        bResult = true;
    }
    return bResult;
}
} // anonymous namespace

// -----------------------------------------------------------------------------

XMLTransformerContext *XMLTransformerBase::CreateContext( sal_uInt16 nPrefix,
	const OUString& rLocalName, const OUString& rQName )
{
	XMLTransformerActions::key_type aKey( nPrefix, rLocalName );
	XMLTransformerActions::const_iterator aIter =
		GetElemActions().find( aKey );

	if( !(aIter == GetElemActions().end()) )
	{
		sal_uInt32 nActionType = (*aIter).second.m_nActionType;
		if( (nActionType & XML_ETACTION_USER_DEFINED) != 0 )
		{
			XMLTransformerContext *pContext =
				CreateUserDefinedContext( (*aIter).second,
									rQName );
			OSL_ENSURE( pContext && !pContext->IsPersistent(),
						"unknown or not persistent action" );
			return pContext;
		}

		switch( nActionType )
		{
		case XML_ETACTION_COPY_CONTENT:
			return new XMLIgnoreTransformerContext( *this, rQName, sal_False,
												sal_False );
		case XML_ETACTION_COPY:
			return new XMLTransformerContext( *this, rQName );
		case XML_ETACTION_RENAME_ELEM:
			return new XMLRenameElemTransformerContext( *this, rQName,
					(*aIter).second.GetQNamePrefixFromParam1(),
					(*aIter).second.GetQNameTokenFromParam1() );
		case XML_ETACTION_RENAME_ELEM_ADD_ATTR:
			return new XMLRenameElemTransformerContext( *this, rQName,
					(*aIter).second.GetQNamePrefixFromParam1(),
					(*aIter).second.GetQNameTokenFromParam1(),
					(*aIter).second.GetQNamePrefixFromParam2(),
					(*aIter).second.GetQNameTokenFromParam2(),
				   	static_cast< XMLTokenEnum >( (*aIter).second.m_nParam3 ) );
		case XML_ETACTION_RENAME_ELEM_PROC_ATTRS:
			return new XMLProcAttrTransformerContext( *this, rQName,
					(*aIter).second.GetQNamePrefixFromParam1(),
					(*aIter).second.GetQNameTokenFromParam1(),
				   	static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
		case XML_ETACTION_RENAME_ELEM_ADD_PROC_ATTR:
			return new XMLProcAddAttrTransformerContext( *this, rQName,
					(*aIter).second.GetQNamePrefixFromParam1(),
					(*aIter).second.GetQNameTokenFromParam1(),
				   	static_cast< sal_uInt16 >(
						(*aIter).second.m_nParam3  >> 16 ),
					(*aIter).second.GetQNamePrefixFromParam2(),
					(*aIter).second.GetQNameTokenFromParam2(),
				   	static_cast< XMLTokenEnum >(
						(*aIter).second.m_nParam3 & 0xffff ) );
		case XML_ETACTION_RENAME_ELEM_COND:
			{
				const XMLTransformerContext *pCurrent = GetCurrentContext();
				if( pCurrent->HasQName(
							(*aIter).second.GetQNamePrefixFromParam2(),
							(*aIter).second.GetQNameTokenFromParam2() ) )
					return new XMLRenameElemTransformerContext( *this, rQName,
							(*aIter).second.GetQNamePrefixFromParam1(),
							(*aIter).second.GetQNameTokenFromParam1() );
			}
			break;
		case XML_ETACTION_RENAME_ELEM_PROC_ATTRS_COND:
			{
				const XMLTransformerContext *pCurrent = GetCurrentContext();
				if( pCurrent->HasQName(
							(*aIter).second.GetQNamePrefixFromParam3(),
							(*aIter).second.GetQNameTokenFromParam3() ) )
					return new XMLProcAttrTransformerContext( *this, rQName,
							(*aIter).second.GetQNamePrefixFromParam1(),
							(*aIter).second.GetQNameTokenFromParam1(),
							static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
				else
					return new XMLProcAttrTransformerContext( *this, rQName,
							static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
			}
		case XML_ETACTION_PROC_ATTRS:
			return new XMLProcAttrTransformerContext( *this, rQName,
				   	static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
		case XML_ETACTION_PROC_ATTRS_COND:
			{
				const XMLTransformerContext *pCurrent = GetCurrentContext();
				if( pCurrent->HasQName(
							(*aIter).second.GetQNamePrefixFromParam1(),
							(*aIter).second.GetQNameTokenFromParam1() ) )
					return new XMLProcAttrTransformerContext( *this, rQName,
							static_cast< sal_uInt16 >( (*aIter).second.m_nParam2 ) );
			}
			break;
		case XML_ETACTION_MOVE_ATTRS_TO_ELEMS:
			return new XMLCreateElemTransformerContext( *this, rQName,
				   	static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
		case XML_ETACTION_MOVE_ELEMS_TO_ATTRS:
			return new XMLMergeElemTransformerContext( *this, rQName,
				   	static_cast< sal_uInt16 >( (*aIter).second.m_nParam1 ) );
		default:
			OSL_ENSURE( !this, "unknown action" );
			break;
		}
	}

	// default is copying
	return new XMLTransformerContext( *this, rQName );
}

XMLTransformerActions *XMLTransformerBase::GetUserDefinedActions( sal_uInt16 )
{
	return 0;
}

XMLTransformerBase::XMLTransformerBase( XMLTransformerActionInit *pInit,
									::xmloff::token::XMLTokenEnum *pTKMapInit )
	throw () :
	m_pNamespaceMap( new SvXMLNamespaceMap ),
	m_pReplaceNamespaceMap( new SvXMLNamespaceMap ),
	m_pContexts( new XMLTransformerContextVector ),
	m_pElemActions( new XMLTransformerActions( pInit ) ),
	m_pTokenMap( new XMLTransformerTokenMap( pTKMapInit ) )
{
	GetNamespaceMap().Add( GetXMLToken(XML_NP_XLINK), GetXMLToken(XML_N_XLINK), XML_NAMESPACE_XLINK );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_DC), GetXMLToken(XML_N_DC), XML_NAMESPACE_DC );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_MATH), GetXMLToken(XML_N_MATH), XML_NAMESPACE_MATH );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_OOO), GetXMLToken(XML_N_OOO), XML_NAMESPACE_OOO );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_DOM), GetXMLToken(XML_N_DOM), XML_NAMESPACE_DOM );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_OOOW), GetXMLToken(XML_N_OOOW), XML_NAMESPACE_OOOW );
	GetNamespaceMap().Add( GetXMLToken(XML_NP_OOOC), GetXMLToken(XML_N_OOOC), XML_NAMESPACE_OOOC );
}

XMLTransformerBase::~XMLTransformerBase() throw ()
{
	ResetTokens();

	delete m_pNamespaceMap;
	delete m_pReplaceNamespaceMap;
	delete m_pContexts;
	delete m_pElemActions;
	delete m_pTokenMap;
}

void SAL_CALL XMLTransformerBase::startDocument( void )
	throw( SAXException, RuntimeException )
{
	m_xHandler->startDocument();
}

void SAL_CALL XMLTransformerBase::endDocument( void )
	throw( SAXException, RuntimeException)
{
	m_xHandler->endDocument();
}

void SAL_CALL XMLTransformerBase::startElement( const OUString& rName,
										 const Reference< XAttributeList >& rAttrList )
	throw(SAXException, RuntimeException)
{
	SvXMLNamespaceMap *pRewindMap = 0;

	bool bRect = rName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "presentation:show-shape" ) );
	(void)bRect;

	// Process namespace attributes. This must happen before creating the
	// context, because namespace decaration apply to the element name itself.
	XMLMutableAttributeList *pMutableAttrList = 0;
	Reference< XAttributeList > xAttrList( rAttrList );
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for( sal_Int16 i=0; i < nAttrCount; i++ )
	{
		const OUString& rAttrName = xAttrList->getNameByIndex( i );
		if( ( rAttrName.getLength() >= 5 ) &&
            ( rAttrName.compareTo( GetXMLToken(XML_XMLNS), 5 ) == 0 ) &&
			( rAttrName.getLength() == 5 || ':' == rAttrName[5] ) )
		{
			if( !pRewindMap )
			{
				pRewindMap = m_pNamespaceMap;
				m_pNamespaceMap = new SvXMLNamespaceMap( *m_pNamespaceMap );
			}
			const OUString& rAttrValue = xAttrList->getValueByIndex( i );

            OUString aPrefix( ( rAttrName.getLength() == 5 )
                                 ? OUString()
                                 : rAttrName.copy( 6 ) );
			// Add namespace, but only if it is known.
			sal_uInt16 nKey = m_pNamespaceMap->AddIfKnown( aPrefix, rAttrValue );
			// If namespace is unknwon, try to match a name with similar
			// TC Id an version
            if( XML_NAMESPACE_UNKNOWN == nKey  )
			{
				OUString aTestName( rAttrValue );
				if( SvXMLNamespaceMap::NormalizeOasisURN( aTestName ) )
					nKey = m_pNamespaceMap->AddIfKnown( aPrefix, aTestName );
			}
			// If that namespace is not known, too, add it as unknown
            if( XML_NAMESPACE_UNKNOWN == nKey  )
				nKey = m_pNamespaceMap->Add( aPrefix, rAttrValue );

			const OUString& rRepName = m_pReplaceNamespaceMap->GetNameByKey( nKey );
			if( rRepName.getLength() )
			{
				if( !pMutableAttrList )
				{
					pMutableAttrList = new XMLMutableAttributeList( xAttrList );
					xAttrList = pMutableAttrList;
				}

				pMutableAttrList->SetValueByIndex( i, rRepName );
			}
		}
	}

	// Get element's namespace and local name.
	OUString aLocalName;
	sal_uInt16 nPrefix =
		m_pNamespaceMap->GetKeyByAttrName( rName, &aLocalName );

	// If there are contexts already, call a CreateChildContext at the topmost
	// context. Otherwise, create a default context.
	::rtl::Reference < XMLTransformerContext > xContext;
	if( !m_pContexts->empty() )
	{
		xContext = m_pContexts->back()->CreateChildContext( nPrefix,
														  aLocalName,
														  rName,
														  xAttrList );
	}
	else
	{
		xContext = CreateContext( nPrefix, aLocalName, rName );
	}

	OSL_ENSURE( xContext.is(), "XMLTransformerBase::startElement: missing context" );
	if( !xContext.is() )
		xContext = new XMLTransformerContext( *this, rName );

	// Remember old namespace map.
	if( pRewindMap )
		xContext->SetRewindMap( pRewindMap );

	// Push context on stack.
	m_pContexts->push_back( xContext );

	// Call a startElement at the new context.
	xContext->StartElement( xAttrList );
}

void SAL_CALL XMLTransformerBase::endElement( const OUString&
#ifdef DBG_UTIL
rName
#endif
)
	throw(SAXException, RuntimeException)
{
	if( !m_pContexts->empty() )
	{
		// Get topmost context
		::rtl::Reference< XMLTransformerContext > xContext = m_pContexts->back();

#ifdef DBG_UTIL
		OSL_ENSURE( xContext->GetQName() == rName,
				"XMLTransformerBase::endElement: popped context has wrong lname" );
#endif

		// Call a EndElement at the current context.
		xContext->EndElement();

		// and remove it from the stack.
		m_pContexts->pop_back();

		// Get a namespace map to rewind.
		SvXMLNamespaceMap *pRewindMap = xContext->GetRewindMap();

		// Delete the current context.
		xContext = 0;

		// Rewind a namespace map.
		if( pRewindMap )
		{
			delete m_pNamespaceMap;
			m_pNamespaceMap = pRewindMap;
		}
	}
}

void SAL_CALL XMLTransformerBase::characters( const OUString& rChars )
	throw(SAXException, RuntimeException)
{
	if( !m_pContexts->empty() )
	{
		m_pContexts->back()->Characters( rChars );
	}
}

void SAL_CALL XMLTransformerBase::ignorableWhitespace( const OUString& rWhitespaces )
	throw(SAXException, RuntimeException)
{
	m_xHandler->ignorableWhitespace( rWhitespaces );
}

void SAL_CALL XMLTransformerBase::processingInstruction( const OUString& rTarget,
									   const OUString& rData )
	throw(SAXException, RuntimeException)
{
	m_xHandler->processingInstruction( rTarget, rData );
}

void SAL_CALL XMLTransformerBase::setDocumentLocator( const Reference< XLocator >& rLocator )
	throw(SAXException, RuntimeException)
{
	m_xLocator = rLocator;
}

// XExtendedDocumentHandler
void SAL_CALL XMLTransformerBase::startCDATA( void ) throw(SAXException, RuntimeException)
{
	if( m_xExtHandler.is() )
		m_xExtHandler->startCDATA();
}

void SAL_CALL XMLTransformerBase::endCDATA( void ) throw(RuntimeException)
{
	if( m_xExtHandler.is() )
		m_xExtHandler->endCDATA();
}

void SAL_CALL XMLTransformerBase::comment( const OUString& rComment )
	throw(SAXException, RuntimeException)
{
	if( m_xExtHandler.is() )
		m_xExtHandler->comment( rComment );
}

void SAL_CALL XMLTransformerBase::allowLineBreak( void )
	throw(SAXException, RuntimeException)
{
	if( m_xExtHandler.is() )
		m_xExtHandler->allowLineBreak();
}

void SAL_CALL XMLTransformerBase::unknown( const OUString& rString )
	throw(SAXException, RuntimeException)
{
	if( m_xExtHandler.is() )
		m_xExtHandler->unknown( rString );
}

// XInitialize
void SAL_CALL XMLTransformerBase::initialize( const Sequence< Any >& aArguments )
	throw(Exception, RuntimeException)
{
	const sal_Int32 nAnyCount = aArguments.getLength();
	const Any* pAny = aArguments.getConstArray();

	for( sal_Int32 nIndex = 0; nIndex < nAnyCount; nIndex++, pAny++ )
    {
        // #b6236750# use isAssignableFrom instead of comparing the types to
        // allow XExtendedDocumentHandler instead of XDocumentHandler (used in
        // writeOasis2OOoLibraryElement in sfx2).
        // The Any shift operator can't be used to query the type because it
        // uses queryInterface, and the model also has a XPropertySet interface.

        // document handler
		if( ::getCppuType( (const Reference< XDocumentHandler >*) 0 ).isAssignableFrom( pAny->getValueType() ) )
			m_xHandler.set( *pAny, UNO_QUERY );

        // property set to transport data across
		if( ::getCppuType( (const Reference< XPropertySet >*) 0 ).isAssignableFrom( pAny->getValueType() ) )
			m_xPropSet.set( *pAny, UNO_QUERY );

		// xmodel
		if( ::getCppuType( (const Reference< ::com::sun::star::frame::XModel >*) 0 ).isAssignableFrom( pAny->getValueType() ) )
			mxModel.set( *pAny, UNO_QUERY );
	}

	if( m_xPropSet.is() )
	{
		Any aAny;
		OUString sRelPath, sName;
		Reference< XPropertySetInfo > xPropSetInfo =
			m_xPropSet->getPropertySetInfo();
		OUString sPropName( RTL_CONSTASCII_USTRINGPARAM("StreamRelPath" ) );
		if( xPropSetInfo->hasPropertyByName(sPropName) )
		{
			aAny = m_xPropSet->getPropertyValue(sPropName);
			aAny >>= sRelPath;
		}
		sPropName = OUString( RTL_CONSTASCII_USTRINGPARAM("StreamName" ) );
		if( xPropSetInfo->hasPropertyByName(sPropName) )
		{
			aAny = m_xPropSet->getPropertyValue(sPropName);
			aAny >>= sName;
		}
		if( sName.getLength() )
		{
			m_aExtPathPrefix = OUString( RTL_CONSTASCII_USTRINGPARAM("../" ) );

			// If there is a rel path within a package, then append
			// additional '../'. If the rel path contains an ':', then it is
			// an absolute URI (or invalid URI, because zip files don't
			// permit ':'), and it will be ignored.
			if( sRelPath.getLength() )
			{
				sal_Int32 nColPos = sRelPath.indexOf( ':' );
				OSL_ENSURE( -1 == nColPos,
							"StreamRelPath contains ':', absolute URI?" );

				if( -1 == nColPos )
				{
					OUString sTmp = m_aExtPathPrefix;
					sal_Int32 nPos = 0;
					do
					{
						m_aExtPathPrefix += sTmp;
						nPos = sRelPath.indexOf( '/', nPos + 1 );
					}
					while( -1 != nPos );
				}
			}

		}
	}
}

static MapUnit lcl_getUnit( const OUString& rValue )
{
	MapUnit nDestUnit;
	if( rValue.endsWithIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "cm" ) ) )
		nDestUnit = MAP_CM;
	else if ( rValue.endsWithIgnoreAsciiCaseAsciiL( RTL_CONSTASCII_STRINGPARAM( "mm" ) ) )
		nDestUnit = MAP_MM;
	else
		nDestUnit = MAP_INCH;
	return nDestUnit;
}

XMLMutableAttributeList *XMLTransformerBase::ProcessAttrList(
		Reference< XAttributeList >& rAttrList, sal_uInt16 nActionMap,
	   	sal_Bool bClone	)
{
	XMLMutableAttributeList *pMutableAttrList = 0;
	XMLTransformerActions *pActions = GetUserDefinedActions( nActionMap );
	OSL_ENSURE( pActions, "go no actions" );
	if( pActions )
	{
		sal_Int16 nAttrCount = rAttrList.is() ? rAttrList->getLength() : 0;
		for( sal_Int16 i=0; i < nAttrCount; ++i )
		{
			const OUString& rAttrName = rAttrList->getNameByIndex( i );
			const OUString& rAttrValue = rAttrList->getValueByIndex( i );
			OUString aLocalName;
			sal_uInt16 nPrefix = GetNamespaceMap().GetKeyByAttrName( rAttrName,
														   &aLocalName );

			XMLTransformerActions::key_type aKey( nPrefix, aLocalName );
			XMLTransformerActions::const_iterator aIter =
					pActions->find( aKey );
			if( !(aIter == pActions->end() ) )
			{
				if( !pMutableAttrList )
				{
					pMutableAttrList = new XMLMutableAttributeList( rAttrList,
																	bClone );
					rAttrList = pMutableAttrList;
				}

				sal_uInt32 nAction = (*aIter).second.m_nActionType;
				sal_Bool bRename = sal_False;
				switch( nAction )
				{
				case XML_ATACTION_RENAME:
					bRename = sal_True;
					break;
				case XML_ATACTION_COPY:
					break;
				case XML_ATACTION_REMOVE:
				case XML_ATACTION_STYLE_DISPLAY_NAME:
					pMutableAttrList->RemoveAttributeByIndex( i );
					--i;
					--nAttrCount;
					break;
				case XML_ATACTION_RENAME_IN2INCH:
					bRename = sal_True;
				case XML_ATACTION_IN2INCH:
					{
						OUString aAttrValue( rAttrValue );
						if( ReplaceSingleInWithInch( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_INS2INCHS:
					{
						OUString aAttrValue( rAttrValue );
						if( ReplaceInWithInch( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_RENAME_INCH2IN:
					bRename = sal_True;
				case XML_ATACTION_INCH2IN:
					{
						OUString aAttrValue( rAttrValue );
						if( ReplaceSingleInchWithIn( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_INCHS2INS:
					{
						OUString aAttrValue( rAttrValue );
						if( ReplaceInchWithIn( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_TWIPS2IN:
					{
						OUString aAttrValue( rAttrValue );

						XMLTransformerBase::ReplaceSingleInchWithIn( aAttrValue );
						if( isWriter() )
						{
							MapUnit nDestUnit = lcl_getUnit( aAttrValue );

							// convert twips value to inch
							sal_Int32 nMeasure;
							if( SvXMLUnitConverter::convertMeasure(nMeasure, aAttrValue, MAP_100TH_MM ) )
							{

                                // --> OD 2004-10-29 #i13778#,#i36248#
                                // apply correct twip-to-1/100mm
                                nMeasure = (sal_Int32)( nMeasure >= 0
                                                        ? ((nMeasure*127+36)/72)
                                                        : ((nMeasure*127-36)/72) );
                                // <--

								rtl::OUStringBuffer aBuffer;
								SvXMLUnitConverter::convertMeasure( aBuffer, nMeasure, MAP_100TH_MM, nDestUnit );
								aAttrValue = aBuffer.makeStringAndClear();
							}
						}

						pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_RENAME_DECODE_STYLE_NAME_REF:
					bRename = sal_True;
				case XML_ATACTION_DECODE_STYLE_NAME:
				case XML_ATACTION_DECODE_STYLE_NAME_REF:
					{
						OUString aAttrValue( rAttrValue );
						if( DecodeStyleName(aAttrValue) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_ENCODE_STYLE_NAME:
					{
						OUString aAttrValue( rAttrValue );
						if( EncodeStyleName(aAttrValue) )
						{
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
							OUString aNewAttrQName(
								GetNamespaceMap().GetQNameByKey(
									nPrefix,
								::xmloff::token::GetXMLToken(
								XML_DISPLAY_NAME ) ) );
							pMutableAttrList->AddAttribute( aNewAttrQName,
															rAttrValue );
						}
					}
					break;
				case XML_ATACTION_RENAME_ENCODE_STYLE_NAME_REF:
					bRename = sal_True;
				case XML_ATACTION_ENCODE_STYLE_NAME_REF:
					{
						OUString aAttrValue( rAttrValue );
						if( EncodeStyleName(aAttrValue) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_RENAME_NEG_PERCENT:
					bRename = sal_True;
				case XML_ATACTION_NEG_PERCENT:
					{
						OUString aAttrValue( rAttrValue );
						if( NegPercent( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_RENAME_ADD_NAMESPACE_PREFIX:
					bRename = sal_True;
				case XML_ATACTION_ADD_NAMESPACE_PREFIX:
					{
						OUString aAttrValue( rAttrValue );
						sal_uInt16 nValPrefix =
							static_cast<sal_uInt16>(
									bRename ? (*aIter).second.m_nParam2
											: (*aIter).second.m_nParam1);
						if( AddNamespacePrefix( aAttrValue, nValPrefix ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_ADD_APP_NAMESPACE_PREFIX:
					{
						OUString aAttrValue( rAttrValue );
						sal_uInt16 nValPrefix =
							static_cast<sal_uInt16>((*aIter).second.m_nParam1);
						if( IsXMLToken( GetClass(), XML_SPREADSHEET  ) )
							nValPrefix = XML_NAMESPACE_OOOC;
						else if( IsXMLToken( GetClass(), XML_TEXT  ) )
							nValPrefix = XML_NAMESPACE_OOOW;
						if( AddNamespacePrefix( aAttrValue, nValPrefix ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_RENAME_REMOVE_NAMESPACE_PREFIX:
					bRename = sal_True;
				case XML_ATACTION_REMOVE_NAMESPACE_PREFIX:
					{
						OUString aAttrValue( rAttrValue );
						sal_uInt16 nValPrefix =
							static_cast<sal_uInt16>(
									bRename ? (*aIter).second.m_nParam2
											: (*aIter).second.m_nParam1);
						if( RemoveNamespacePrefix( aAttrValue, nValPrefix ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_REMOVE_ANY_NAMESPACE_PREFIX:
					{
						OUString aAttrValue( rAttrValue );
						if( RemoveNamespacePrefix( aAttrValue ) )
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_URI_OOO:
					{
						OUString aAttrValue( rAttrValue );
						if( ConvertURIToOASIS( aAttrValue,
							static_cast< sal_Bool >((*aIter).second.m_nParam1)))
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_URI_OASIS:
					{
						OUString aAttrValue( rAttrValue );
						if( ConvertURIToOOo( aAttrValue,
							static_cast< sal_Bool >((*aIter).second.m_nParam1)))
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
                case XML_ATACTION_RENAME_ATTRIBUTE:
                    {
                        OUString aAttrValue( rAttrValue );
                        RenameAttributeValue(
                            aAttrValue,
                            (*aIter).second.m_nParam1,
                            (*aIter).second.m_nParam2,
                            (*aIter).second.m_nParam3 );
                        pMutableAttrList->SetValueByIndex( i, aAttrValue );
                    }
                    break;
                case XML_ATACTION_RNG2ISO_DATETIME:
                    {
						OUString aAttrValue( rAttrValue );
						if( ConvertRNGDateTimeToISO( aAttrValue ))
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
                    }
                    break;
                case XML_ATACTION_RENAME_RNG2ISO_DATETIME:
                    {
						OUString aAttrValue( rAttrValue );
						if( ConvertRNGDateTimeToISO( aAttrValue ))
							pMutableAttrList->SetValueByIndex( i, aAttrValue );
                        bRename = sal_True;
                    }
                    break;
				case XML_ATACTION_IN2TWIPS:
					{
						OUString aAttrValue( rAttrValue );
						XMLTransformerBase::ReplaceSingleInWithInch( aAttrValue );

						if( isWriter() )
						{
							MapUnit nDestUnit = lcl_getUnit( aAttrValue );

							// convert inch value to twips and export as faked inch
							sal_Int32 nMeasure;
							if( SvXMLUnitConverter::convertMeasure(nMeasure, aAttrValue, MAP_100TH_MM ) )
							{

                                // --> OD 2004-10-29 #i13778#,#i36248#
                                // apply correct 1/100mm-to-twip conversion
                                nMeasure = (sal_Int32)( nMeasure >= 0
                                                        ? ((nMeasure*72+63)/127)
                                                        : ((nMeasure*72-63)/127) );
                                // <--

								OUStringBuffer aBuffer;
								SvXMLUnitConverter::convertMeasure( aBuffer, nMeasure, MAP_100TH_MM, nDestUnit );
								aAttrValue = aBuffer.makeStringAndClear();
							}
						}

						pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_SVG_WIDTH_HEIGHT_OOO:
					{
						OUString aAttrValue( rAttrValue );
						ReplaceSingleInchWithIn( aAttrValue );

						MapUnit nDestUnit = lcl_getUnit( aAttrValue );

						sal_Int32 nMeasure;
						if( SvXMLUnitConverter::convertMeasure(nMeasure, aAttrValue, MAP_100TH_MM ) )
						{

							if( nMeasure > 0 )
								nMeasure -= 1;
							else if( nMeasure < 0 )
								nMeasure += 1;


							OUStringBuffer aBuffer;
							SvXMLUnitConverter::convertMeasure( aBuffer, nMeasure, MAP_100TH_MM, nDestUnit );
                            aAttrValue = aBuffer.makeStringAndClear();
						}

						pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_SVG_WIDTH_HEIGHT_OASIS:
					{
						OUString aAttrValue( rAttrValue );
						ReplaceSingleInWithInch( aAttrValue );

						MapUnit nDestUnit = lcl_getUnit( aAttrValue );

						sal_Int32 nMeasure;
						if( SvXMLUnitConverter::convertMeasure(nMeasure, aAttrValue, MAP_100TH_MM ) )
						{

							if( nMeasure > 0 )
								nMeasure += 1;
							else if( nMeasure < 0 )
								nMeasure -= 1;


							OUStringBuffer aBuffer;
							SvXMLUnitConverter::convertMeasure( aBuffer, nMeasure, MAP_100TH_MM, nDestUnit );
                            aAttrValue = aBuffer.makeStringAndClear();
						}

						pMutableAttrList->SetValueByIndex( i, aAttrValue );
					}
					break;
				case XML_ATACTION_DECODE_ID:
					{
						OUString aAttrValue;

						const sal_Int32 nLen = rAttrValue.getLength();
						OUStringBuffer aBuffer;

						sal_Int32 pos;
						for( pos = 0; pos < nLen; pos++ )
						{
							sal_Unicode c = rAttrValue[pos];
							if( (c >= '0') && (c <= '9') )
								aBuffer.append( c );
							else
								aBuffer.append( (sal_Int32)c );
						}

						pMutableAttrList->SetValueByIndex( i, aBuffer.makeStringAndClear() );
					}
					break;
                // --> OD 2005-06-10 #i50322# - special handling for the
                // transparency of writer background graphics.
                case XML_ATACTION_WRITER_BACK_GRAPHIC_TRANSPARENCY:
                    {
                        // determine, if it's the transparency of a document style
                        XMLTransformerContext* pFirstContext = (*m_pContexts)[0].get();
                        OUString aFirstContextLocalName;
                        /* sal_uInt16 nFirstContextPrefix = */
                            GetNamespaceMap().GetKeyByAttrName( pFirstContext->GetQName(),
                                                                &aFirstContextLocalName );
                        bool bIsDocumentStyle(
                            ::xmloff::token::IsXMLToken( aFirstContextLocalName,
                                                         XML_DOCUMENT_STYLES ) );
                        // no conversion of transparency value for document
                        // styles, because former OpenOffice.org version writes
                        // writes always a transparency value of 100% and doesn't
                        // read the value. Thus, it's intepreted as 0%
                        if ( !bIsDocumentStyle )
                        {
                            OUString aAttrValue( rAttrValue );
                            NegPercent(aAttrValue);
                            pMutableAttrList->SetValueByIndex( i, aAttrValue );
                        }
                        bRename = sal_True;
                    }
                    break;
                // <--
				case XML_ATACTION_SHAPEID:
				{
					OUString sNewValue( RTL_CONSTASCII_USTRINGPARAM( "shape" ) );
					sNewValue += rAttrValue;
					pMutableAttrList->SetValueByIndex( i, sNewValue );
					break;
				}

				default:
					OSL_ENSURE( !this, "unknown action" );
					break;
				}

				if( bRename )
				{
					OUString aNewAttrQName(
						GetNamespaceMap().GetQNameByKey(
							(*aIter).second.GetQNamePrefixFromParam1(),
							::xmloff::token::GetXMLToken(
								(*aIter).second.GetQNameTokenFromParam1()) ) );
					pMutableAttrList->RenameAttributeByIndex( i,
															  aNewAttrQName );
				}
			}
		}
	}

	return pMutableAttrList;
}

sal_Bool XMLTransformerBase::ReplaceSingleInchWithIn( OUString& rValue )
{
	sal_Bool bRet = sal_False;
	sal_Int32 nPos = rValue.getLength();
	while( nPos && rValue[nPos-1] <= ' ' )
		--nPos;
	if( nPos > 2 &&
		('c'==rValue[nPos-2] || 'C'==rValue[nPos-2]) &&
		('h'==rValue[nPos-1] || 'H'==rValue[nPos-1]) )
	{
		rValue =rValue.copy( 0, nPos-2 );
		bRet = sal_True;
	}

	return bRet;
}

sal_Bool XMLTransformerBase::ReplaceInchWithIn( OUString& rValue )
{
	sal_Bool bRet = sal_False;
	sal_Int32 nPos = 1;
	while( nPos < rValue.getLength()-3 )
	{
		sal_Unicode c = rValue[nPos];
		if( 'i'==c || 'I'==c )
		{
			c = rValue[nPos-1];
			if( (c >= '0' && c <= '9') || '.' == c )
			{
				c = rValue[nPos+1];
				if( 'n'==c || 'N'==c )
				{
					c = rValue[nPos+2];
					if( 'c'==c || 'C'==c )
					{
						c = rValue[nPos+3];
						if( 'h'==c || 'H'==c )
						{
							rValue = rValue.replaceAt( nPos,
								4, GetXMLToken(XML_UNIT_INCH) );
							nPos += 2;
							bRet = sal_True;
							continue;
						}
					}
				}
			}
		}
		++nPos;
	}

	return bRet;
}

sal_Bool XMLTransformerBase::ReplaceSingleInWithInch( OUString& rValue )
{
	sal_Bool bRet = sal_False;

	sal_Int32 nPos = rValue.getLength();
	while( nPos && rValue[nPos-1] <= ' ' )
		--nPos;
	if( nPos > 2 &&
		('i'==rValue[nPos-2] ||
			'I'==rValue[nPos-2]) &&
		('n'==rValue[nPos-1] ||
			'N'==rValue[nPos-1]) )
	{
		nPos -= 2;
		rValue = rValue.replaceAt( nPos, rValue.getLength() - nPos,
										   GetXMLToken(XML_INCH) );
		bRet = sal_True;
	}

	return bRet;
}

sal_Bool XMLTransformerBase::ReplaceInWithInch( OUString& rValue )
{
	sal_Bool bRet = sal_False;
	sal_Int32 nPos = 1;
	while( nPos < rValue.getLength()-1 )
	{
		sal_Unicode c = rValue[nPos];
		if( 'i'==c || 'I'==c )
		{
			c = rValue[nPos-1];
			if( (c >= '0' && c <= '9') || '.' == c )
			{
				c = rValue[nPos+1];
				if( 'n'==c || 'N'==c )
				{
					rValue = rValue.replaceAt( nPos,
									2, GetXMLToken(XML_INCH) );
					nPos += 4;
					bRet = sal_True;
					continue;
				}
			}
		}
		++nPos;
	}

	return bRet;
}

sal_Bool XMLTransformerBase::EncodeStyleName( OUString& rName ) const
{
	static sal_Char aHexTab[] = "0123456789abcdef";

	sal_Bool bEncoded = sal_False;

	sal_Int32 nLen = rName.getLength();
	OUStringBuffer aBuffer( nLen );

	for( sal_Int32 i = 0; i < nLen; i++ )
	{
		sal_Unicode c = rName[i];
		sal_Bool bValidChar = sal_False;
		if( c < 0x00ffU )
		{
			bValidChar =
				(c >= 0x0041 && c <= 0x005a) ||
				(c >= 0x0061 && c <= 0x007a) ||
				(c >= 0x00c0 && c <= 0x00d6) ||
				(c >= 0x00d8 && c <= 0x00f6) ||
				(c >= 0x00f8 && c <= 0x00ff) ||
				( i > 0 && ( (c >= 0x0030 && c <= 0x0039) ||
							 c == 0x00b7 || c == '-' || c == '.') );
		}
		else
		{
			if( (c >= 0xf900U && c <= 0xfffeU) ||
			 	(c >= 0x20ddU && c <= 0x20e0U))
			{
				bValidChar = sal_False;
			}
			else if( (c >= 0x02bbU && c <= 0x02c1U) || c == 0x0559 ||
					 c == 0x06e5 || c == 0x06e6 )
			{
				bValidChar = sal_True;
			}
			else if( c == 0x0387 )
			{
				bValidChar = i > 0;
			}
			else
			{
				if( !xCharClass.is() )
				{
					Reference< XMultiServiceFactory > xFactory =
						comphelper::getProcessServiceFactory();
					if( xFactory.is() )
					{
						try
						{
							const_cast < XMLTransformerBase * >(this)
								->xCharClass =
									Reference < XCharacterClassification >(
								xFactory->createInstance(
									OUString::createFromAscii(
						"com.sun.star.i18n.CharacterClassification_Unicode") ),
								UNO_QUERY );

							OSL_ENSURE( xCharClass.is(),
					"can't instantiate character clossification component" );
						}
						catch( com::sun::star::uno::Exception& )
						{
						}
					}
				}
				if( xCharClass.is() )
				{
					sal_Int16 nType = xCharClass->getType( rName, i );

					switch( nType )
					{
					case UnicodeType::UPPERCASE_LETTER:		// Lu
					case UnicodeType::LOWERCASE_LETTER:		// Ll
					case UnicodeType::TITLECASE_LETTER:		// Lt
					case UnicodeType::OTHER_LETTER:			// Lo
					case UnicodeType::LETTER_NUMBER: 		// Nl
						bValidChar = sal_True;
						break;
					case UnicodeType::NON_SPACING_MARK:		// Ms
					case UnicodeType::ENCLOSING_MARK:		// Me
					case UnicodeType::COMBINING_SPACING_MARK:	//Mc
					case UnicodeType::MODIFIER_LETTER:		// Lm
					case UnicodeType::DECIMAL_DIGIT_NUMBER:	// Nd
						bValidChar = i > 0;
						break;
					}
				}
			}
		}
		if( bValidChar )
		{
			aBuffer.append( c );
		}
		else
		{
			aBuffer.append( static_cast< sal_Unicode >( '_' ) );
			if( c > 0x0fff )
				aBuffer.append( static_cast< sal_Unicode >(
							aHexTab[ (c >> 12) & 0x0f ]  ) );
			if( c > 0x00ff )
				aBuffer.append( static_cast< sal_Unicode >(
						aHexTab[ (c >> 8) & 0x0f ] ) );
			if( c > 0x000f )
				aBuffer.append( static_cast< sal_Unicode >(
						aHexTab[ (c >> 4) & 0x0f ] ) );
			aBuffer.append( static_cast< sal_Unicode >(
						aHexTab[ c & 0x0f ] ) );
			aBuffer.append( static_cast< sal_Unicode >( '_' ) );
			bEncoded = sal_True;
		}
	}

	if( aBuffer.getLength() > (1<<15)-1 )
		bEncoded = sal_False;

	if( bEncoded )
		rName = aBuffer.makeStringAndClear();
	return bEncoded;
}

sal_Bool XMLTransformerBase::DecodeStyleName( OUString& rName )
{
	sal_Bool bEncoded = sal_False;

	sal_Int32 nLen = rName.getLength();
	OUStringBuffer aBuffer( nLen );

	sal_Bool bWithinHex = sal_False;
	sal_Unicode cEnc = 0;
	for( sal_Int32 i = 0; i < nLen; i++ )
	{
		sal_Unicode c = rName[i];
		if( '_' == c )
		{
			if( bWithinHex )
			{
				aBuffer.append( cEnc );
				cEnc = 0;
			}
			else
			{
				bEncoded = sal_True;
			}
			bWithinHex = !bWithinHex;
		}
		else if( bWithinHex )
		{
			sal_Unicode cDigit;
			if( c >= '0' && c <= '9' )
			{
				cDigit = c - '0';
			}
    		else if( c >= 'a' && c <= 'f' )
			{
				cDigit = c - 'a' + 10;
			}
			else if( c >= 'A' && c <= 'F' )
			{
				cDigit = c - 'A' + 10;
			}
			else
			{
				// error
				bEncoded = sal_False;
				break;
			}
			cEnc = (cEnc << 4) + cDigit;
		}
		else
		{
			aBuffer.append( c );
		}
	}

	if( bEncoded )
		rName = aBuffer.makeStringAndClear();
	return bEncoded;
}

sal_Bool XMLTransformerBase::NegPercent( OUString& rValue )
{
	sal_Bool bRet = sal_False;
    sal_Bool bNeg = sal_False;
    double nVal = 0;

    sal_Int32 nPos = 0;
    sal_Int32 nLen = rValue.getLength();

    // skip white space
    while( nPos < nLen && sal_Unicode(' ') == rValue[nPos] )
        nPos++;

    if( nPos < nLen && sal_Unicode('-') == rValue[nPos] )
    {
        bNeg = sal_True;
        nPos++;
    }

    // get number
    while( nPos < nLen &&
           sal_Unicode('0') <= rValue[nPos] &&
           sal_Unicode('9') >= rValue[nPos] )
    {
        // TODO: check overflow!
        nVal *= 10;
        nVal += (rValue[nPos] - sal_Unicode('0'));
        nPos++;
    }
    double nDiv = 1.;
    if( nPos < nLen && sal_Unicode('.') == rValue[nPos] )
    {
        nPos++;

        while( nPos < nLen &&
               sal_Unicode('0') <= rValue[nPos] &&
               sal_Unicode('9') >= rValue[nPos] )
        {
            // TODO: check overflow!
            nDiv *= 10;
            nVal += ( static_cast<double>(rValue[nPos] - sal_Unicode('0')) / nDiv );
            nPos++;
        }
    }

    // skip white space
    while( nPos < nLen && sal_Unicode(' ') == rValue[nPos] )
        nPos++;

    if( nPos < nLen &&  sal_Unicode('%') == rValue[nPos] )
    {
    	if( bNeg )
       		nVal = -nVal;
		nVal += .5;

		sal_Int32 nIntVal = 100 - static_cast<sal_Int32>( nVal );

		OUStringBuffer aNewValBuffer;
		aNewValBuffer.append( nIntVal );
    	aNewValBuffer.append( sal_Unicode('%' ) );

		rValue = aNewValBuffer.makeStringAndClear();
		bRet = sal_True;
	}

	return bRet;
}

sal_Bool XMLTransformerBase::AddNamespacePrefix( ::rtl::OUString& rName,
							 sal_uInt16 nPrefix ) const
{
	rName = GetNamespaceMap().GetQNameByKey( nPrefix, rName, sal_False );
	return sal_True;
}

sal_Bool XMLTransformerBase::RemoveNamespacePrefix( ::rtl::OUString& rName,
							sal_uInt16 nPrefixOnly ) const
{
	OUString aLocalName;
	sal_uInt16 nPrefix =
		GetNamespaceMap()._GetKeyByAttrName( rName, &aLocalName, sal_False );
	sal_Bool bRet = XML_NAMESPACE_UNKNOWN != nPrefix &&
					(USHRT_MAX == nPrefixOnly || nPrefix == nPrefixOnly);
	if( bRet )
		rName = aLocalName;

	return bRet;
}

sal_Bool XMLTransformerBase::ConvertURIToOASIS( ::rtl::OUString& rURI,
										sal_Bool bSupportPackage ) const
{
	sal_Bool bRet = sal_False;
	if( m_aExtPathPrefix.getLength() && rURI.getLength() )
	{
		sal_Bool bRel = sal_False;
		switch( rURI[0] )
		{
		case '#':
			// no rel path, but
			// for package URIs, the '#' has to be removed
			if( bSupportPackage )
			{
				rURI = rURI.copy( 1 );
				bRet = sal_True;
			}
			break;
		case '/':
			// no rel path; nothing to do
			break;
		case '.':
			// a rel path; to keep URI simple, remove './', if there
			bRel = sal_True;
			if( rURI.getLength() > 1 && '/' == rURI[1] )
			{
				rURI = rURI.copy( 2 );
				bRet = sal_True;
			}
			break;
		default:
			// check for a RFC2396 schema
			{
				bRel = sal_True;
				sal_Int32 nPos = 1;
				sal_Int32 nLen = rURI.getLength();
				while( nPos < nLen )
				{
					switch( rURI[nPos] )
					{
					case '/':
						// a relative path segement
						nPos = nLen;	// leave loop
						break;
					case ':':
						// a schema
						bRel = sal_False;
						nPos = nLen;	// leave loop
						break;
					default:
						// we don't care about any other characters
						break;
					}
					++nPos;
				}
			}
		}

		if( bRel )
		{
			OUString sTmp( m_aExtPathPrefix );
			sTmp += rURI;
			rURI = sTmp;
			bRet = sal_True;
		}
	}

	return bRet;
}

sal_Bool XMLTransformerBase::ConvertURIToOOo( ::rtl::OUString& rURI,
										sal_Bool bSupportPackage ) const
{
	sal_Bool bRet = sal_False;
	if( rURI.getLength() )
	{
		sal_Bool bPackage = sal_False;
		switch( rURI[0] )
		{
		case '/':
			// no rel path; nothing to to
			break;
		case '.':
			// a rel path
			if( 0 == rURI.compareTo( m_aExtPathPrefix,
									 m_aExtPathPrefix.getLength() ) )
			{
				// an external URI; remove '../'
				rURI = rURI.copy( m_aExtPathPrefix.getLength() );
				bRet = sal_True;
			}
			else
			{
				bPackage = sal_True;
			}
			break;
		default:
			// check for a RFC2396 schema
			{
				bPackage = sal_True;
				sal_Int32 nPos = 1;
				sal_Int32 nLen = rURI.getLength();
				while( nPos < nLen )
				{
					switch( rURI[nPos] )
					{
					case '/':
						// a relative path segement within the package
						nPos = nLen;	// leave loop
						break;
					case ':':
						// a schema
						bPackage = sal_False;
						nPos = nLen;	// leave loop
						break;
					default:
						// we don't care about any other characters
						break;
					}
					++nPos;
				}
			}
		}

		if( bPackage && bSupportPackage )
		{
			OUString sTmp( OUString::valueOf( sal_Unicode( '#' ) ) );
			if( 0 == rURI.compareToAscii( "./", 2 ) )
				rURI = rURI.copy( 2 );
			sTmp += rURI;
			rURI = sTmp;
			bRet = sal_True;
		}
	}

	return bRet;
}

sal_Bool XMLTransformerBase::RenameAttributeValue(
    OUString& rOutAttributeValue,
    sal_Int32 nParam1,
    sal_Int32 nParam2,
    sal_Int32 nParam3 )
{
    return ( lcl_ConvertAttr( rOutAttributeValue, nParam1) ||
             lcl_ConvertAttr( rOutAttributeValue, nParam2) ||
             lcl_ConvertAttr( rOutAttributeValue, nParam3) );
}

// static
bool XMLTransformerBase::ConvertRNGDateTimeToISO( ::rtl::OUString& rDateTime )
{
    if( rDateTime.getLength() > 0 &&
        rDateTime.indexOf( sal_Unicode('.')) != -1 )
    {
        rDateTime = rDateTime.replace( sal_Unicode('.'), sal_Unicode(','));
        return true;
    }

    return false;
}

XMLTokenEnum XMLTransformerBase::GetToken( const OUString& rStr ) const
{
	XMLTransformerTokenMap::const_iterator aIter =
		m_pTokenMap->find( rStr );
	if( aIter == m_pTokenMap->end() )
		return XML_TOKEN_END;
	else
		return (*aIter).second;
}



const XMLTransformerContext *XMLTransformerBase::GetCurrentContext() const
{
	OSL_ENSURE( !m_pContexts->empty(), "empty stack" );


	return m_pContexts->empty() ? 0 : m_pContexts->back().get();
}

const XMLTransformerContext *XMLTransformerBase::GetAncestorContext(
														sal_uInt32 n ) const
{
	XMLTransformerContextVector::size_type nSize =
		m_pContexts->size();
	XMLTransformerContextVector::size_type nPos =
		static_cast<XMLTransformerContextVector::size_type>( n );

	OSL_ENSURE( nSize >nPos+2 , "invalid context" );

	return nSize > nPos+2 ? (*m_pContexts)[nSize-(nPos+2)].get() : 0;
}

bool XMLTransformerBase::isWriter() const
{
	Reference< XServiceInfo > xSI( mxModel, UNO_QUERY );
	return	xSI.is() &&
		(	xSI->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.TextDocument" ) ) ) ||
			xSI->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.WebDocument" ) ) ) ||
			xSI->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.text.GlobalDocument" ) ) ) );
}
