/**************************************************************
 *
 * 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_scripting.hxx"
#include "stringresource.hxx"
#include <com/sun/star/io/XTextInputStream.hpp>
#include <com/sun/star/io/XTextOutputStream.hpp>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/io/XStream.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/lang/XMultiComponentFactory.hpp>
#ifndef _CPPUHELPER_IMPLEMENTATIONENTRY_HXX_
#include <cppuhelper/implementationentry.hxx>
#endif
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/container/XNameAccess.hpp>


#include <rtl/ustrbuf.hxx>
#include <rtl/strbuf.hxx>
#include <tools/urlobj.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::embed;
using namespace ::com::sun::star::container;


//.........................................................................
namespace stringresource
{
//.........................................................................

// =============================================================================
// mutex
// =============================================================================

::osl::Mutex& getMutex()
{
    static ::osl::Mutex* s_pMutex = 0;
    if ( !s_pMutex )
    {
        ::osl::MutexGuard aGuard( ::osl::Mutex::getGlobalMutex() );
	    if ( !s_pMutex )
	    {
            static ::osl::Mutex s_aMutex;
		    s_pMutex = &s_aMutex;
	    }
    }
    return *s_pMutex;
}


// =============================================================================
// StringResourceImpl
// =============================================================================

// component operations
static Sequence< ::rtl::OUString > getSupportedServiceNames_StringResourceImpl()
{
    Sequence< ::rtl::OUString > names(1);
    names[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.resource.StringResource") );
    return names;
}

static ::rtl::OUString getImplementationName_StringResourceImpl()
{
    return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.scripting.StringResource") );
}

static Reference< XInterface > SAL_CALL create_StringResourceImpl(
    Reference< XComponentContext > const & xContext )
    SAL_THROW( () )
{
    return static_cast< ::cppu::OWeakObject * >( new StringResourcePersistenceImpl( xContext ) );
}


// =============================================================================

StringResourceImpl::StringResourceImpl( const Reference< XComponentContext >& rxContext )
    : m_xContext( rxContext )
	, m_pCurrentLocaleItem( NULL )
	, m_pDefaultLocaleItem( NULL )
	, m_bDefaultModified( false )
	, m_aListenerContainer( getMutex() )
	, m_bModified( false )
	, m_bReadOnly( false )
	, m_nNextUniqueNumericId( UNIQUE_NUMBER_NEEDS_INITIALISATION )
{
}

// =============================================================================

StringResourceImpl::~StringResourceImpl()
{
	for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ )
	{
		LocaleItem* pLocaleItem = *it;
		delete pLocaleItem;
	}

	for( LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin(); it != m_aDeletedLocaleItemVector.end(); it++ )
	{
		LocaleItem* pLocaleItem = *it;
		delete pLocaleItem;
	}
}


// =============================================================================
// XServiceInfo

::rtl::OUString StringResourceImpl::getImplementationName(  ) throw (RuntimeException)
{
    return getImplementationName_StringResourceImpl();
}

sal_Bool StringResourceImpl::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
{
	Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
	const ::rtl::OUString* pNames = aNames.getConstArray();
	const ::rtl::OUString* pEnd = pNames + aNames.getLength();
	for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
		;

	return pNames != pEnd;
}

Sequence< ::rtl::OUString > StringResourceImpl::getSupportedServiceNames(  ) throw (RuntimeException)
{
    return getSupportedServiceNames_StringResourceImpl();
}


// =============================================================================
// XModifyBroadcaster

void StringResourceImpl::addModifyListener( const Reference< XModifyListener >& aListener )
	throw (RuntimeException)
{
	if( !aListener.is() )
		throw RuntimeException();

    ::osl::MutexGuard aGuard( getMutex() );
	Reference< XInterface > xIface( aListener, UNO_QUERY );
	m_aListenerContainer.addInterface( xIface );
}

void StringResourceImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
	throw (RuntimeException)
{
	if( !aListener.is() )
		throw RuntimeException();

    ::osl::MutexGuard aGuard( getMutex() );
	Reference< XInterface > xIface( aListener, UNO_QUERY );
	m_aListenerContainer.removeInterface( xIface );
}


// =============================================================================
// XStringResourceResolver

::rtl::OUString StringResourceImpl::implResolveString
	( const ::rtl::OUString& ResourceID, LocaleItem* pLocaleItem )
		throw (::com::sun::star::resource::MissingResourceException)
{
	::rtl::OUString aRetStr;
	bool bSuccess = false;
	if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
	{
		IdToStringMap::iterator it = pLocaleItem->m_aIdToStringMap.find( ResourceID );
		if( !( it == pLocaleItem->m_aIdToStringMap.end() ) )
		{
			aRetStr = (*it).second;
			bSuccess = true;
		}
	}
	if( !bSuccess )
	{
		::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceImpl: No entry for ResourceID: " );
        errorMsg.concat( ResourceID );
        throw ::com::sun::star::resource::MissingResourceException( errorMsg, Reference< XInterface >() );
	}
	return aRetStr;
}

::rtl::OUString StringResourceImpl::resolveString( const ::rtl::OUString& ResourceID )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	return implResolveString( ResourceID, m_pCurrentLocaleItem );
}

::rtl::OUString StringResourceImpl::resolveStringForLocale( const ::rtl::OUString& ResourceID, const Locale& locale )
	throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	LocaleItem* pLocaleItem = getItemForLocale( locale, false );
	return implResolveString( ResourceID, pLocaleItem );
}

sal_Bool StringResourceImpl::implHasEntryForId( const ::rtl::OUString& ResourceID, LocaleItem* pLocaleItem )
{
	bool bSuccess = false;
	if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
	{
		IdToStringMap::iterator it = pLocaleItem->m_aIdToStringMap.find( ResourceID );
		if( !( it == pLocaleItem->m_aIdToStringMap.end() ) )
			bSuccess = true;
	}
	return bSuccess;
}

sal_Bool StringResourceImpl::hasEntryForId( const ::rtl::OUString& ResourceID )
	throw (RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	return implHasEntryForId( ResourceID, m_pCurrentLocaleItem );
}

sal_Bool StringResourceImpl::hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID,
	const Locale& locale )
		throw (RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	LocaleItem* pLocaleItem = getItemForLocale( locale, false );
	return implHasEntryForId( ResourceID, pLocaleItem );
}

Sequence< ::rtl::OUString > StringResourceImpl::implGetResourceIDs( LocaleItem* pLocaleItem )
{
	Sequence< ::rtl::OUString > aIDSeq( 0 );
	if( pLocaleItem && loadLocale( pLocaleItem ) )
	{
		const IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;
		sal_Int32 nResourceIDCount = rHashMap.size();
		aIDSeq.realloc( nResourceIDCount );
		::rtl::OUString* pStrings = aIDSeq.getArray();

		IdToStringMap::const_iterator it;
		int iTarget = 0;
		for( it = rHashMap.begin(); it != rHashMap.end(); it++ )
		{
			::rtl::OUString aStr = (*it).first;
			pStrings[iTarget] = aStr;
			iTarget++;
		}
	}
	return aIDSeq;
}

Sequence< ::rtl::OUString > StringResourceImpl::getResourceIDsForLocale
	( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	LocaleItem* pLocaleItem = getItemForLocale( locale, false );
	return implGetResourceIDs( pLocaleItem );
}

Sequence< ::rtl::OUString > StringResourceImpl::getResourceIDs(  )
	throw (RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	return implGetResourceIDs( m_pCurrentLocaleItem );
}

Locale StringResourceImpl::getCurrentLocale()
	throw (RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );

	Locale aRetLocale;
	if( m_pCurrentLocaleItem != NULL )
		aRetLocale = m_pCurrentLocaleItem->m_locale;
	return aRetLocale;
}

Locale StringResourceImpl::getDefaultLocale(  )
	throw (RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );

	Locale aRetLocale;
	if( m_pDefaultLocaleItem != NULL )
		aRetLocale = m_pDefaultLocaleItem->m_locale;
	return aRetLocale;
}

Sequence< Locale > StringResourceImpl::getLocales(  )
	throw (RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );

	sal_Int32 nSize = m_aLocaleItemVector.size();
	Sequence< Locale > aLocalSeq( nSize );
	Locale* pLocales = aLocalSeq.getArray();
	int iTarget = 0;
    for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ )
    {
		LocaleItem* pLocaleItem = *it;
		pLocales[iTarget] = pLocaleItem->m_locale;
		iTarget++;
	}
	return aLocalSeq;
}


// =============================================================================
// XStringResourceManager

void StringResourceImpl::implCheckReadOnly( const sal_Char* pExceptionMsg )
	throw (NoSupportException)
{
	if( m_bReadOnly )
	{
		::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( pExceptionMsg );
        throw NoSupportException( errorMsg, Reference< XInterface >() );
	}
}

sal_Bool StringResourceImpl::isReadOnly()
	throw (RuntimeException)
{
	return m_bReadOnly;
}

void StringResourceImpl::implSetCurrentLocale( const Locale& locale,
	sal_Bool FindClosestMatch, sal_Bool bUseDefaultIfNoMatch )
		throw (IllegalArgumentException, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );

	LocaleItem* pLocaleItem = NULL;
	if( FindClosestMatch )
		pLocaleItem = getClosestMatchItemForLocale( locale );
	else
		pLocaleItem = getItemForLocale( locale, true );

	if( pLocaleItem == NULL && bUseDefaultIfNoMatch )
		pLocaleItem = m_pDefaultLocaleItem;

	if( pLocaleItem != NULL )
	{
		loadLocale( pLocaleItem );
		m_pCurrentLocaleItem = pLocaleItem;

		// Only notify without modifying
		implNotifyListeners();
	}
}

void StringResourceImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
	throw (IllegalArgumentException, RuntimeException)
{
	sal_Bool bUseDefaultIfNoMatch = false;
	implSetCurrentLocale( locale, FindClosestMatch, bUseDefaultIfNoMatch );
}

void StringResourceImpl::setDefaultLocale( const Locale& locale )
	throw (IllegalArgumentException, RuntimeException,NoSupportException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	implCheckReadOnly( "StringResourceImpl::setDefaultLocale(): Read only" );

	LocaleItem* pLocaleItem = getItemForLocale( locale, true );
	if( pLocaleItem && pLocaleItem != m_pDefaultLocaleItem )
	{
		if( m_pDefaultLocaleItem )
		{
			LocaleItem* pChangedDefaultLocaleItem = new LocaleItem( m_pDefaultLocaleItem->m_locale );
			m_aChangedDefaultLocaleVector.push_back( pChangedDefaultLocaleItem );
		}

		m_pDefaultLocaleItem = pLocaleItem;
		m_bDefaultModified = true;
		implModified();
	}
}

void StringResourceImpl::implSetString( const ::rtl::OUString& ResourceID,
	const ::rtl::OUString& Str, LocaleItem* pLocaleItem )
{
	if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
	{
		IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;

		IdToStringMap::iterator it = rHashMap.find( ResourceID );
		bool bNew = ( it == rHashMap.end() );
		if( bNew )
		{
			IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap;
			rIndexMap[ ResourceID ] = pLocaleItem->m_nNextIndex++;
			implScanIdForNumber( ResourceID );
		}
		rHashMap[ ResourceID ] = Str;
		pLocaleItem->m_bModified = true;
		implModified();
	}
}

void StringResourceImpl::setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str )
	throw (NoSupportException, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	implCheckReadOnly( "StringResourceImpl::setString(): Read only" );
	implSetString( ResourceID, Str, m_pCurrentLocaleItem );
}

void StringResourceImpl::setStringForLocale
	( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, const Locale& locale )
		throw (NoSupportException, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	implCheckReadOnly( "StringResourceImpl::setStringForLocale(): Read only" );
	LocaleItem* pLocaleItem = getItemForLocale( locale, false );
	implSetString( ResourceID, Str, pLocaleItem );
}

void StringResourceImpl::implRemoveId( const ::rtl::OUString& ResourceID, LocaleItem* pLocaleItem )
	throw (::com::sun::star::resource::MissingResourceException)
{
	if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
	{
		IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;
		IdToStringMap::iterator it = rHashMap.find( ResourceID );
		if( it == rHashMap.end() )
		{
			::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceImpl: No entries for ResourceID: " );
			errorMsg.concat( ResourceID );
			throw ::com::sun::star::resource::MissingResourceException( errorMsg, Reference< XInterface >() );
		}
		rHashMap.erase( it );
		pLocaleItem->m_bModified = true;
		implModified();
	}
}

void StringResourceImpl::removeId( const ::rtl::OUString& ResourceID )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	implCheckReadOnly( "StringResourceImpl::removeId(): Read only" );
	implRemoveId( ResourceID, m_pCurrentLocaleItem );
}

void StringResourceImpl::removeIdForLocale( const ::rtl::OUString& ResourceID, const Locale& locale )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	implCheckReadOnly( "StringResourceImpl::removeIdForLocale(): Read only" );
	LocaleItem* pLocaleItem = getItemForLocale( locale, false );
	implRemoveId( ResourceID, pLocaleItem );
}

void StringResourceImpl::newLocale( const Locale& locale )
	throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	implCheckReadOnly( "StringResourceImpl::newLocale(): Read only" );

	if( getItemForLocale( locale, false ) != NULL )
	{
        ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceImpl: locale already exists" );
        throw ElementExistException( errorMsg, Reference< XInterface >() );
	}

	// TODO?: Check if locale is valid? How?
	bool bValid = true;
	if( bValid )
	{
		LocaleItem* pLocaleItem = new LocaleItem( locale );
		m_aLocaleItemVector.push_back( pLocaleItem );
		pLocaleItem->m_bModified = true;

		// Copy strings from default locale
		LocaleItem* pCopyFromItem = m_pDefaultLocaleItem;
		if( pCopyFromItem == NULL )
			pCopyFromItem = m_pCurrentLocaleItem;
		if( pCopyFromItem != NULL && loadLocale( pCopyFromItem ) )
		{
			const IdToStringMap& rSourceMap = pCopyFromItem->m_aIdToStringMap;
			IdToStringMap& rTargetMap = pLocaleItem->m_aIdToStringMap;
			IdToStringMap::const_iterator it;
			for( it = rSourceMap.begin(); it != rSourceMap.end(); it++ )
			{
				::rtl::OUString aId  = (*it).first;
				::rtl::OUString aStr = (*it).second;
				rTargetMap[ aId ] = aStr;
			}

			const IdToIndexMap& rSourceIndexMap = pCopyFromItem->m_aIdToIndexMap;
			IdToIndexMap& rTargetIndexMap = pLocaleItem->m_aIdToIndexMap;
			IdToIndexMap::const_iterator it_index;
			for( it_index = rSourceIndexMap.begin(); it_index != rSourceIndexMap.end(); it_index++ )
			{
				::rtl::OUString aId  = (*it_index).first;
				sal_Int32 nIndex = (*it_index).second;
				rTargetIndexMap[ aId ] = nIndex;
			}
			pLocaleItem->m_nNextIndex = pCopyFromItem->m_nNextIndex;
		}

		if( m_pCurrentLocaleItem == NULL )
			m_pCurrentLocaleItem = pLocaleItem;

		if( m_pDefaultLocaleItem == NULL )
		{
			m_pDefaultLocaleItem = pLocaleItem;
			m_bDefaultModified = true;
		}

		implModified();
	}
	else
	{
        ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceImpl: Invalid locale" );
        throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
	}
}

void StringResourceImpl::removeLocale( const Locale& locale )
	throw (IllegalArgumentException, RuntimeException, NoSupportException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	implCheckReadOnly( "StringResourceImpl::removeLocale(): Read only" );

	LocaleItem* pRemoveItem = getItemForLocale( locale, true );
	if( pRemoveItem )
	{
		// Last locale?
		sal_Int32 nLocaleCount = m_aLocaleItemVector.size();
		if( nLocaleCount > 1 )
		{
			LocaleItem* pFallbackItem = NULL;
			if( m_pCurrentLocaleItem == pRemoveItem ||
				m_pDefaultLocaleItem  == pRemoveItem )
			{
				for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ )
				{
					LocaleItem* pLocaleItem = *it;
					if( pLocaleItem != pRemoveItem )
					{
						pFallbackItem = pLocaleItem;
						break;
					}
				}
				if( m_pCurrentLocaleItem == pRemoveItem )
				{
					sal_Bool FindClosestMatch = false;
					setCurrentLocale( pFallbackItem->m_locale, FindClosestMatch );
				}
				if( m_pDefaultLocaleItem == pRemoveItem )
				{
					setDefaultLocale( pFallbackItem->m_locale );
				}
			}
		}
		for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ )
		{
			LocaleItem* pLocaleItem = *it;
			if( pLocaleItem == pRemoveItem )
			{
				// Remember locale item to delete file while storing
				m_aDeletedLocaleItemVector.push_back( pLocaleItem );

				// Last locale?
				if( nLocaleCount == 1 )
				{
					m_nNextUniqueNumericId = 0;
					if( m_pDefaultLocaleItem )
					{
						LocaleItem* pChangedDefaultLocaleItem = new LocaleItem( m_pDefaultLocaleItem->m_locale );
						m_aChangedDefaultLocaleVector.push_back( pChangedDefaultLocaleItem );
					}
					m_pCurrentLocaleItem = NULL;
					m_pDefaultLocaleItem = NULL;
				}

				m_aLocaleItemVector.erase( it );

				implModified();
				break;
			}
		}
	}
}

void StringResourceImpl::implScanIdForNumber( const ::rtl::OUString& ResourceID )
{
	const sal_Unicode* pSrc = ResourceID.getStr();
	sal_Int32 nLen = ResourceID.getLength();

	sal_Int32 nNumber = 0;
	for( sal_Int32 i = 0 ; i < nLen ; i++ )
	{
		sal_Unicode c = pSrc[i];
		if( c >= '0' && c <= '9' )
		{
			sal_uInt16 nDigitVal = c - '0';
			nNumber = 10*nNumber + nDigitVal;
		}
		else
			break;
	}

	if( m_nNextUniqueNumericId < nNumber + 1 )
		m_nNextUniqueNumericId = nNumber + 1;
}

sal_Int32 StringResourceImpl::getUniqueNumericId(  )
	throw (RuntimeException, NoSupportException)
{
	if( m_nNextUniqueNumericId == UNIQUE_NUMBER_NEEDS_INITIALISATION )
	{
		implLoadAllLocales();
		m_nNextUniqueNumericId = 0;
	}

	if( m_nNextUniqueNumericId < UNIQUE_NUMBER_NEEDS_INITIALISATION )
	{
        ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "getUniqueNumericId: Extended sal_Int32 range" );
        throw NoSupportException( errorMsg, Reference< XInterface >() );
	}
	return m_nNextUniqueNumericId;
}


// =============================================================================
// Private helper methods

LocaleItem* StringResourceImpl::getItemForLocale
	( const Locale& locale, sal_Bool bException )
		throw (::com::sun::star::lang::IllegalArgumentException)
{
	LocaleItem* pRetItem = NULL;

	// Search for locale
    for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ )
    {
		LocaleItem* pLocaleItem = *it;
		if( pLocaleItem )
		{
			Locale& cmp_locale = pLocaleItem->m_locale;
			if( cmp_locale.Language == locale.Language &&
				cmp_locale.Country  == locale.Country &&
				cmp_locale.Variant  == locale.Variant )
			{
				pRetItem = pLocaleItem;
				break;
			}
		}
    }

	if( pRetItem == NULL && bException )
	{
        ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceImpl: Invalid locale" );
        throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
	}
	return pRetItem;
}

// Returns the LocalItem for a given locale, if it exists, otherwise NULL
// This method performs a closest match search, at least the language must match
LocaleItem* StringResourceImpl::getClosestMatchItemForLocale( const Locale& locale )
{
	LocaleItem* pRetItem = NULL;

	// Search for locale
	for( sal_Int32 iPass = 0 ; iPass <= 2 ; ++iPass )
	{
		for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ )
		{
			LocaleItem* pLocaleItem = *it;
			if( pLocaleItem )
			{
				Locale& cmp_locale = pLocaleItem->m_locale;
				if( cmp_locale.Language == locale.Language &&
					(iPass > 1 || cmp_locale.Country  == locale.Country) &&
					(iPass > 0 || cmp_locale.Variant  == locale.Variant) )
				{
					pRetItem = pLocaleItem;
					break;
				}
			}
		}
		if( pRetItem )
			break;
	}

	return pRetItem;
}

void StringResourceImpl::implModified( void )
{
	m_bModified = true;
	implNotifyListeners();
}

void StringResourceImpl::implNotifyListeners( void )
{
	EventObject aEvent;
	aEvent.Source = static_cast< XInterface* >( (OWeakObject*)this );

	::cppu::OInterfaceIteratorHelper it( m_aListenerContainer );
	while( it.hasMoreElements() )
	{
		Reference< XInterface > xIface = it.next();
		Reference< XModifyListener > xListener( xIface, UNO_QUERY );
        try
        {
            xListener->modified( aEvent );
        }
        catch(RuntimeException&)
        {
            it.remove();
        }
	}
}


// =============================================================================
// Loading

bool StringResourceImpl::loadLocale( LocaleItem* pLocaleItem )
{
	// Base implementation has nothing to load
	(void)pLocaleItem;
	return true;
}

void StringResourceImpl::implLoadAllLocales( void )
{
	// Base implementation has nothing to load
}


Reference< XMultiComponentFactory > StringResourceImpl::getMultiComponentFactory( void )
{
    ::osl::MutexGuard aGuard( getMutex() );

	if( !m_xMCF.is() )
	{
		Reference< XMultiComponentFactory > xSMgr( m_xContext->getServiceManager(), UNO_QUERY );
		if( !xSMgr.is() )
		{
			throw RuntimeException(
				::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StringResourceImpl::getMultiComponentFactory: Couldn't instantiate MultiComponentFactory" ) ),
					Reference< XInterface >() );
		}
		m_xMCF = xSMgr;
	}
	return m_xMCF;
}


// =============================================================================
// StringResourcePersistenceImpl
// =============================================================================

StringResourcePersistenceImpl::StringResourcePersistenceImpl( const Reference< XComponentContext >& rxContext )
    : StringResourcePersistenceImpl_BASE( rxContext )
{
}

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

StringResourcePersistenceImpl::~StringResourcePersistenceImpl()
{
}

// -----------------------------------------------------------------------------
// XServiceInfo
// -----------------------------------------------------------------------------

::rtl::OUString StringResourcePersistenceImpl::getImplementationName(  )
	throw (RuntimeException)
{
    return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM
		( "com.sun.star.comp.scripting.StringResourceWithLocation") );
}

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

sal_Bool StringResourcePersistenceImpl::supportsService( const ::rtl::OUString& rServiceName )
	throw (RuntimeException)
{
	return StringResourceImpl::supportsService( rServiceName );
}

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

Sequence< ::rtl::OUString > StringResourcePersistenceImpl::getSupportedServiceNames(  )
	throw (RuntimeException)
{
    return StringResourceImpl::getSupportedServiceNames();
}

// -----------------------------------------------------------------------------
// XInitialization base functionality for derived classes
// -----------------------------------------------------------------------------

static ::rtl::OUString aNameBaseDefaultStr = ::rtl::OUString::createFromAscii( "strings" );

void StringResourcePersistenceImpl::implInitializeCommonParameters
	( const Sequence< Any >& aArguments )
		throw (Exception, RuntimeException)
{
	bool bReadOnlyOk = (aArguments[1] >>= m_bReadOnly);
	if( !bReadOnlyOk )
    {
        ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "XInitialization::initialize: Expected ReadOnly flag" );
        throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 1 );
	}

	com::sun::star::lang::Locale aCurrentLocale;
	bool bLocaleOk = (aArguments[2] >>= aCurrentLocale);
	if( !bLocaleOk )
    {
        ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "XInitialization::initialize: Expected Locale" );
        throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 2 );
	}

	bool bNameBaseOk = (aArguments[3] >>= m_aNameBase);
	if( !bNameBaseOk )
    {
        ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "XInitialization::initialize: Expected NameBase string" );
        throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 3 );
	}
	if( m_aNameBase.getLength() == 0 )
		m_aNameBase = aNameBaseDefaultStr;

	bool bCommentOk = (aArguments[4] >>= m_aComment);
	if( !bCommentOk )
    {
        ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "XInitialization::initialize: Expected Comment string" );
        throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 4 );
	}

	implScanLocales();

	sal_Bool FindClosestMatch = true;
	sal_Bool bUseDefaultIfNoMatch = true;
	implSetCurrentLocale( aCurrentLocale, FindClosestMatch, bUseDefaultIfNoMatch );
}

// -----------------------------------------------------------------------------
// Forwarding calls to base class

// XModifyBroadcaster
void StringResourcePersistenceImpl::addModifyListener( const Reference< XModifyListener >& aListener )
	throw (RuntimeException)
{
	StringResourceImpl::addModifyListener( aListener );
}
void StringResourcePersistenceImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
	throw (RuntimeException)
{
	StringResourceImpl::removeModifyListener( aListener );
}

// XStringResourceResolver
::rtl::OUString StringResourcePersistenceImpl::resolveString( const ::rtl::OUString& ResourceID )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException)
{
	return StringResourceImpl::resolveString( ResourceID ) ;
}
::rtl::OUString StringResourcePersistenceImpl::resolveStringForLocale( const ::rtl::OUString& ResourceID, const Locale& locale )
	throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException)
{
	return StringResourceImpl::resolveStringForLocale( ResourceID, locale );
}
sal_Bool StringResourcePersistenceImpl::hasEntryForId( const ::rtl::OUString& ResourceID )
	throw (RuntimeException)
{
	return StringResourceImpl::hasEntryForId( ResourceID ) ;
}
sal_Bool StringResourcePersistenceImpl::hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID,
	const Locale& locale )
		throw (RuntimeException)
{
	return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale );
}
Locale StringResourcePersistenceImpl::getCurrentLocale()
	throw (RuntimeException)
{
	return StringResourceImpl::getCurrentLocale();
}
Locale StringResourcePersistenceImpl::getDefaultLocale(  )
	throw (RuntimeException)
{
	return StringResourceImpl::getDefaultLocale();
}
Sequence< Locale > StringResourcePersistenceImpl::getLocales(  )
	throw (RuntimeException)
{
	return StringResourceImpl::getLocales();
}

// XStringResourceManager
sal_Bool StringResourcePersistenceImpl::isReadOnly()
	throw (RuntimeException)
{
	return StringResourceImpl::isReadOnly();
}
void StringResourcePersistenceImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
	throw (IllegalArgumentException, RuntimeException)
{
	StringResourceImpl::setCurrentLocale( locale, FindClosestMatch );
}
void StringResourcePersistenceImpl::setDefaultLocale( const Locale& locale )
	throw (IllegalArgumentException, RuntimeException,NoSupportException)
{
	StringResourceImpl::setDefaultLocale( locale );
}
Sequence< ::rtl::OUString > StringResourcePersistenceImpl::getResourceIDs(  )
	throw (RuntimeException)
{
	return StringResourceImpl::getResourceIDs();
}
void StringResourcePersistenceImpl::setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str )
	throw (NoSupportException, RuntimeException)
{
	StringResourceImpl::setString( ResourceID, Str );
}
void StringResourcePersistenceImpl::setStringForLocale
	( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, const Locale& locale )
		throw (NoSupportException, RuntimeException)
{
	StringResourceImpl::setStringForLocale( ResourceID, Str, locale );
}
Sequence< ::rtl::OUString > StringResourcePersistenceImpl::getResourceIDsForLocale
	( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException)
{
	return StringResourceImpl::getResourceIDsForLocale( locale );
}
void StringResourcePersistenceImpl::removeId( const ::rtl::OUString& ResourceID )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException)
{
	StringResourceImpl::removeId( ResourceID );
}
void StringResourcePersistenceImpl::removeIdForLocale( const ::rtl::OUString& ResourceID, const Locale& locale )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException)
{
	StringResourceImpl::removeIdForLocale( ResourceID, locale );
}
void StringResourcePersistenceImpl::newLocale( const Locale& locale )
	throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException)
{
	StringResourceImpl::newLocale( locale );
}
void StringResourcePersistenceImpl::removeLocale( const Locale& locale )
	throw (IllegalArgumentException, RuntimeException, NoSupportException)
{
	StringResourceImpl::removeLocale( locale );
}
sal_Int32 StringResourcePersistenceImpl::getUniqueNumericId(  )
	throw (RuntimeException, NoSupportException)
{
	return StringResourceImpl::getUniqueNumericId();
}

// -----------------------------------------------------------------------------
// XStringResourcePersistence

void StringResourcePersistenceImpl::store()
	throw (NoSupportException, Exception, RuntimeException)
{
}

sal_Bool StringResourcePersistenceImpl::isModified(  )
	throw (RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );

	return m_bModified;
}

void StringResourcePersistenceImpl::setComment( const ::rtl::OUString& Comment )
	throw (::com::sun::star::uno::RuntimeException)
{
	m_aComment = Comment;
}

void StringResourcePersistenceImpl::storeToStorage( const Reference< XStorage >& Storage,
	const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment )
		throw (Exception, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );

	bool bUsedForStore = false;
	bool bStoreAll = true;
	implStoreAtStorage( NameBase, Comment, Storage, bUsedForStore, bStoreAll );
}

void StringResourcePersistenceImpl::implStoreAtStorage
(
	const ::rtl::OUString& aNameBase,
	const ::rtl::OUString& aComment,
	const Reference< ::com::sun::star::embed::XStorage >& Storage,
	bool bUsedForStore,
	bool bStoreAll
)
	throw (Exception, RuntimeException)
{
	// Delete files for deleted locales
	if( bUsedForStore )
	{
		while( m_aDeletedLocaleItemVector.size() > 0 )
		{
			LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin();
			LocaleItem* pLocaleItem = *it;
			if( pLocaleItem != NULL )
			{
				::rtl::OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase );
				aStreamName += ::rtl::OUString::createFromAscii( ".properties" );

				try
				{
					Storage->removeElement( aStreamName );
				}
				catch( Exception& )
				{}

				m_aDeletedLocaleItemVector.erase( it );
				delete pLocaleItem;
			}
		}
	}

    for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ )
    {
		LocaleItem* pLocaleItem = *it;
		if( pLocaleItem != NULL && (bStoreAll || pLocaleItem->m_bModified) &&
			loadLocale( pLocaleItem ) )
		{
			::rtl::OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, aNameBase );
			aStreamName += ::rtl::OUString::createFromAscii( ".properties" );

			Reference< io::XStream > xElementStream =
					Storage->openStreamElement( aStreamName, ElementModes::READWRITE );

			::rtl::OUString aPropName = ::rtl::OUString::createFromAscii( "MediaType" );
			::rtl::OUString aMime = ::rtl::OUString::createFromAscii( "text/plain" );

			uno::Reference< beans::XPropertySet > xProps( xElementStream, uno::UNO_QUERY );
			OSL_ENSURE( xProps.is(), "The StorageStream must implement XPropertySet interface!\n" );
            if ( xProps.is() )
            {
                xProps->setPropertyValue( aPropName, uno::makeAny( aMime ) );

                aPropName = ::rtl::OUString::createFromAscii( "UseCommonStoragePasswordEncryption" );
                xProps->setPropertyValue( aPropName, uno::makeAny( sal_True ) );
            }

            Reference< io::XOutputStream > xOutputStream = xElementStream->getOutputStream();
			if( xOutputStream.is() )
				implWritePropertiesFile( pLocaleItem, xOutputStream, aComment );
            xOutputStream->closeOutput();

			if( bUsedForStore )
				pLocaleItem->m_bModified = false;
		}
	}

	// Delete files for changed defaults
	if( bUsedForStore )
	{
		for( LocaleItemVectorIt it = m_aChangedDefaultLocaleVector.begin();
			 it != m_aChangedDefaultLocaleVector.end(); it++ )
		{
			LocaleItem* pLocaleItem = *it;
			if( pLocaleItem != NULL )
			{
				::rtl::OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase );
				aStreamName += ::rtl::OUString::createFromAscii( ".default" );

				try
				{
					Storage->removeElement( aStreamName );
				}
				catch( Exception& )
				{}

				delete pLocaleItem;
			}
		}
		m_aChangedDefaultLocaleVector.clear();
	}

	// Default locale
	if( m_pDefaultLocaleItem != NULL && (bStoreAll || m_bDefaultModified) )
	{
		::rtl::OUString aStreamName = implGetFileNameForLocaleItem( m_pDefaultLocaleItem, aNameBase );
		aStreamName += ::rtl::OUString::createFromAscii( ".default" );

		Reference< io::XStream > xElementStream =
				Storage->openStreamElement( aStreamName, ElementModes::READWRITE );

		::rtl::OUString aPropName = ::rtl::OUString::createFromAscii( "MediaType" );
		::rtl::OUString aMime = ::rtl::OUString::createFromAscii( "text/plain" );

		// Only create stream without content
		Reference< io::XOutputStream > xOutputStream = xElementStream->getOutputStream();
		xOutputStream->closeOutput();

		if( bUsedForStore )
			m_bDefaultModified = false;
	}
}

void StringResourcePersistenceImpl::storeToURL( const ::rtl::OUString& URL,
	const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment,
	const Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
		throw (Exception, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );

	bool bUsedForStore = false;
	bool bStoreAll = true;

	Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory();
	Reference< ucb::XSimpleFileAccess > xFileAccess;
	xFileAccess = Reference< ucb::XSimpleFileAccess >( xMCF->createInstanceWithContext
		( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ),
			m_xContext ), UNO_QUERY );
	if( xFileAccess.is() && Handler.is() )
		xFileAccess->setInteractionHandler( Handler );

	implStoreAtLocation( URL, NameBase, Comment, xFileAccess, bUsedForStore, bStoreAll );
}

void StringResourcePersistenceImpl::implKillRemovedLocaleFiles
(
	const ::rtl::OUString& Location,
	const ::rtl::OUString& aNameBase,
	const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess
)
	throw (Exception, RuntimeException)
{
	// Delete files for deleted locales
	while( m_aDeletedLocaleItemVector.size() > 0 )
	{
		LocaleItemVectorIt it = m_aDeletedLocaleItemVector.begin();
		LocaleItem* pLocaleItem = *it;
		if( pLocaleItem != NULL )
		{
			::rtl::OUString aCompleteFileName =
				implGetPathForLocaleItem( pLocaleItem, aNameBase, Location );
			if( xFileAccess->exists( aCompleteFileName ) )
				xFileAccess->kill( aCompleteFileName );

			m_aDeletedLocaleItemVector.erase( it );
			delete pLocaleItem;
		}
	}
}

void StringResourcePersistenceImpl::implKillChangedDefaultFiles
(
	const ::rtl::OUString& Location,
	const ::rtl::OUString& aNameBase,
	const ::com::sun::star::uno::Reference< ::com::sun::star::ucb::XSimpleFileAccess >& xFileAccess
)
	throw (Exception, RuntimeException)
{
	// Delete files for changed defaults
	for( LocaleItemVectorIt it = m_aChangedDefaultLocaleVector.begin();
		 it != m_aChangedDefaultLocaleVector.end(); it++ )
	{
		LocaleItem* pLocaleItem = *it;
		if( pLocaleItem != NULL )
		{
			::rtl::OUString aCompleteFileName =
				implGetPathForLocaleItem( pLocaleItem, aNameBase, Location, true );
			if( xFileAccess->exists( aCompleteFileName ) )
				xFileAccess->kill( aCompleteFileName );

			delete pLocaleItem;
		}
	}
	m_aChangedDefaultLocaleVector.clear();
}

void StringResourcePersistenceImpl::implStoreAtLocation
(
	const ::rtl::OUString& Location,
	const ::rtl::OUString& aNameBase,
	const ::rtl::OUString& aComment,
	const Reference< ucb::XSimpleFileAccess >& xFileAccess,
	bool bUsedForStore,
	bool bStoreAll,
	bool bKillAll
)
	throw (Exception, RuntimeException)
{
	// Delete files for deleted locales
	if( bUsedForStore || bKillAll )
		implKillRemovedLocaleFiles( Location, aNameBase, xFileAccess );

    for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ )
    {
		LocaleItem* pLocaleItem = *it;
		if( pLocaleItem != NULL && (bStoreAll || bKillAll || pLocaleItem->m_bModified) &&
			loadLocale( pLocaleItem ) )
		{
			::rtl::OUString aCompleteFileName =
				implGetPathForLocaleItem( pLocaleItem, aNameBase, Location );
			if( xFileAccess->exists( aCompleteFileName ) )
				xFileAccess->kill( aCompleteFileName );

			if( !bKillAll )
			{
				// Create Output stream
				Reference< io::XOutputStream > xOutputStream = xFileAccess->openFileWrite( aCompleteFileName );
				if( xOutputStream.is() )
				{
					implWritePropertiesFile( pLocaleItem, xOutputStream, aComment );
					xOutputStream->closeOutput();
				}
				if( bUsedForStore )
					pLocaleItem->m_bModified = false;
			}
		}
	}

	// Delete files for changed defaults
	if( bUsedForStore || bKillAll )
		implKillChangedDefaultFiles( Location, aNameBase, xFileAccess );

	// Default locale
	if( m_pDefaultLocaleItem != NULL && (bStoreAll || bKillAll || m_bDefaultModified) )
	{
		::rtl::OUString aCompleteFileName =
			implGetPathForLocaleItem( m_pDefaultLocaleItem, aNameBase, Location, true );
		if( xFileAccess->exists( aCompleteFileName ) )
			xFileAccess->kill( aCompleteFileName );

		if( !bKillAll )
		{
			// Create Output stream
			Reference< io::XOutputStream > xOutputStream = xFileAccess->openFileWrite( aCompleteFileName );
			if( xOutputStream.is() )
				xOutputStream->closeOutput();

			if( bUsedForStore )
				m_bDefaultModified = false;
		}
	}
}


// -----------------------------------------------------------------------------
// BinaryOutput, helper class for exportBinary

class BinaryOutput
{
	Reference< XMultiComponentFactory >		m_xMCF;
    Reference< XComponentContext >	        m_xContext;
	Reference< XInterface >					m_xTempFile;
	Reference< io::XOutputStream >			m_xOutputStream;

public:
	BinaryOutput( Reference< XMultiComponentFactory > xMCF,
		Reference< XComponentContext > xContext );

	Reference< io::XOutputStream > getOutputStream( void )
		{ return m_xOutputStream; }

	Sequence< ::sal_Int8 > closeAndGetData( void );

	// Template to be used with sal_Int16 and sal_Unicode
	template< class T >
	void write16BitInt( T n );
	void writeInt16( sal_Int16 n )
		{ write16BitInt( n ); }
	void writeUnicodeChar( sal_Unicode n )
		{ write16BitInt( n ); }
	void writeInt32( sal_Int32 n );
	void writeString( const ::rtl::OUString& aStr );
};

BinaryOutput::BinaryOutput( Reference< XMultiComponentFactory > xMCF,
	Reference< XComponentContext > xContext )
		: m_xMCF( xMCF )
		, m_xContext( xContext )
{
	m_xTempFile = m_xMCF->createInstanceWithContext
		( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ), m_xContext );
	if( m_xTempFile.is() )
		m_xOutputStream = Reference< io::XOutputStream >( m_xTempFile, UNO_QUERY );
}

template< class T >
void BinaryOutput::write16BitInt( T n )
{
	if( !m_xOutputStream.is() )
		return;

	Sequence< sal_Int8 > aSeq( 2 );
	sal_Int8* p = aSeq.getArray();

	sal_Int8 nLow  = sal_Int8( n & 0xff );
	sal_Int8 nHigh = sal_Int8( n >> 8 );

	p[0] = nLow;
	p[1] = nHigh;
	m_xOutputStream->writeBytes( aSeq );
}

void BinaryOutput::writeInt32( sal_Int32 n )
{
	if( !m_xOutputStream.is() )
		return;

	Sequence< sal_Int8 > aSeq( 4 );
	sal_Int8* p = aSeq.getArray();

	for( sal_Int16 i = 0 ; i < 4 ; i++ )
	{
		p[i] = sal_Int8( n & 0xff );
		n >>= 8;
	}
	m_xOutputStream->writeBytes( aSeq );
}

void BinaryOutput::writeString( const ::rtl::OUString& aStr )
{
	sal_Int32 nLen = aStr.getLength();
	const sal_Unicode* pStr = aStr.getStr();

	for( sal_Int32 i = 0 ; i < nLen ; i++ )
		writeUnicodeChar( pStr[i] );

	writeUnicodeChar( 0 );
}

Sequence< ::sal_Int8 > BinaryOutput::closeAndGetData( void )
{
	Sequence< ::sal_Int8 > aRetSeq;
	if( !m_xOutputStream.is() )
		return aRetSeq;

	m_xOutputStream->closeOutput();

	Reference< io::XSeekable> xSeekable( m_xTempFile, UNO_QUERY );
	if( !xSeekable.is() )
		return aRetSeq;

	sal_Int32 nSize = (sal_Int32)xSeekable->getPosition();

	Reference< io::XInputStream> xInputStream( m_xTempFile, UNO_QUERY );
	if( !xInputStream.is() )
		return aRetSeq;

	xSeekable->seek( 0 );
	sal_Int32 nRead = xInputStream->readBytes( aRetSeq, nSize );
	(void)nRead;
	OSL_ENSURE( nRead == nSize, "BinaryOutput::closeAndGetData: nRead != nSize" );

	return aRetSeq;
}


// Binary format:

// Header
// Byte			Content
// 0 + 1		sal_Int16:	Version, currently 0, low byte first
// 2 + 3		sal_Int16:	Locale count = n, low byte first
// 4 + 5		sal_Int16:	Default Locale position in Locale list, == n if none
// 6 - 7		sal_Int32:	Start index locale block 0, lowest byte first
// (n-1) *		sal_Int32:	Start index locale block 1 to n, lowest byte first
// 6 + 4*n		sal_Int32:	"Start index" non existing locale block n+1,
//							marks the first invalid index, kind of EOF

// Locale block
// All strings are stored as 2-Byte-0 terminated sequence
// of 16 bit Unicode characters, each with low byte first
// Empty strings only contain the 2-Byte-0

// Members of com.sun.star.lang.Locale
// with l1 = Locale.Language.getLength()
// with l2 = Locale.Country.getLength()
// with l3 = Locale.Variant.getLength()
// pos0 = 0						Locale.Language
// pos1 = 2 * (l1 + 1)			Locale.Country
// pos2 = pos1 + 2 * (l2 + 1)	Locale.Variant
// pos3 = pos2 + 2 * (l3 + 1)
// pos3							Properties file written by implWritePropertiesFile

Sequence< sal_Int8 > StringResourcePersistenceImpl::exportBinary(  )
	throw (RuntimeException)
{
	Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory();
	BinaryOutput aOut( xMCF, m_xContext );

	sal_Int32 nLocaleCount = m_aLocaleItemVector.size();
	Sequence< sal_Int8 >* pLocaleDataSeq = new Sequence< sal_Int8 >[ nLocaleCount ];

	sal_Int32 iLocale = 0;
	sal_Int32 iDefault = 0;
    for( LocaleItemVectorConstIt it = m_aLocaleItemVector.begin();
		 it != m_aLocaleItemVector.end(); it++,iLocale++ )
    {
		LocaleItem* pLocaleItem = *it;
		if( pLocaleItem != NULL && loadLocale( pLocaleItem ) )
		{
			if( m_pDefaultLocaleItem == pLocaleItem )
				iDefault = iLocale;

			BinaryOutput aLocaleOut( m_xMCF, m_xContext );
			implWriteLocaleBinary( pLocaleItem, aLocaleOut );

			pLocaleDataSeq[iLocale] = aLocaleOut.closeAndGetData();
		}
	}

	// Write header
	sal_Int16 nVersion = 0;
	sal_Int16 nLocaleCount16 = (sal_Int16)nLocaleCount;
	sal_Int16 iDefault16 = (sal_Int16)iDefault;
	aOut.writeInt16( nVersion );
	aOut.writeInt16( nLocaleCount16 );
	aOut.writeInt16( iDefault16 );

	// Write data positions
	sal_Int32 nDataPos = 6 + 4 * (nLocaleCount + 1);
	for( iLocale = 0; iLocale < nLocaleCount; iLocale++ )
	{
		aOut.writeInt32( nDataPos );

		Sequence< sal_Int8 >& rSeq = pLocaleDataSeq[iLocale];
	    sal_Int32 nSeqLen = rSeq.getLength();
		nDataPos += nSeqLen;
	}
	// Write final position
	aOut.writeInt32( nDataPos );

	// Write data
	Reference< io::XOutputStream > xOutputStream = aOut.getOutputStream();
	if( xOutputStream.is() )
	{
		for( iLocale = 0; iLocale < nLocaleCount; iLocale++ )
		{
			Sequence< sal_Int8 >& rSeq = pLocaleDataSeq[iLocale];
			xOutputStream->writeBytes( rSeq );
		}
	}

	delete[] pLocaleDataSeq;

	Sequence< sal_Int8 > aRetSeq = aOut.closeAndGetData();
	return aRetSeq;
}

void StringResourcePersistenceImpl::implWriteLocaleBinary
	( LocaleItem* pLocaleItem, BinaryOutput& rOut )
{
	Reference< io::XOutputStream > xOutputStream = rOut.getOutputStream();
	if( !xOutputStream.is() )
		return;

	Locale& rLocale = pLocaleItem->m_locale;
	rOut.writeString( rLocale.Language );
	rOut.writeString( rLocale.Country );
	rOut.writeString( rLocale.Variant );
	implWritePropertiesFile( pLocaleItem, xOutputStream, m_aComment );
}

// -----------------------------------------------------------------------------
// BinaryOutput, helper class for exportBinary

class BinaryInput
{
	Sequence< sal_Int8 >					m_aData;
	Reference< XMultiComponentFactory >		m_xMCF;
	Reference< XComponentContext >	        m_xContext;

	const sal_Int8*							m_pData;
	sal_Int32								m_nCurPos;
	sal_Int32								m_nSize;

public:
	BinaryInput( Sequence< ::sal_Int8 > aData, Reference< XMultiComponentFactory > xMCF,
		Reference< XComponentContext > xContext );

	Reference< io::XInputStream > getInputStreamForSection( sal_Int32 nSize );

	void seek( sal_Int32 nPos );
	sal_Int32 getPosition( void )
		{ return m_nCurPos; }

	sal_Int16 readInt16( void );
	sal_Int32 readInt32( void );
	sal_Unicode readUnicodeChar( void );
	::rtl::OUString readString( void );
};

BinaryInput::BinaryInput( Sequence< ::sal_Int8 > aData, Reference< XMultiComponentFactory > xMCF,
	Reference< XComponentContext > xContext )
		: m_aData( aData )
		, m_xMCF( xMCF )
		, m_xContext( xContext )
{
	m_pData = m_aData.getConstArray();
	m_nCurPos = 0;
	m_nSize = m_aData.getLength();
}

Reference< io::XInputStream > BinaryInput::getInputStreamForSection( sal_Int32 nSize )
{
	Reference< io::XInputStream > xIn;
	if( m_nCurPos + nSize <= m_nSize )
	{
		Reference< io::XOutputStream > xTempOut( m_xMCF->createInstanceWithContext
			( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ), m_xContext ), UNO_QUERY );
		if( xTempOut.is() )
		{
			Sequence< sal_Int8 > aSection( m_pData + m_nCurPos, nSize );
			xTempOut->writeBytes( aSection );

			Reference< io::XSeekable> xSeekable( xTempOut, UNO_QUERY );
			if( xSeekable.is() )
				xSeekable->seek( 0 );

			xIn = Reference< io::XInputStream>( xTempOut, UNO_QUERY );
		}
	}
	else
		OSL_ENSURE( false, "BinaryInput::getInputStreamForSection(): Read past end" );

	return xIn;
}

void BinaryInput::seek( sal_Int32 nPos )
{
	if( nPos <= m_nSize )
		m_nCurPos = nPos;
	else
		OSL_ENSURE( false, "BinaryInput::seek(): Position past end" );
}


sal_Int16 BinaryInput::readInt16( void )
{
	sal_Int16 nRet = 0;
	if( m_nCurPos + 2 <= m_nSize )
	{
		nRet = nRet + sal_Int16( sal_uInt8( m_pData[m_nCurPos++] ) );
		nRet += 256 * sal_Int16( sal_uInt8( m_pData[m_nCurPos++] ) );
	}
	else
		OSL_ENSURE( false, "BinaryInput::readInt16(): Read past end" );

	return nRet;
}

sal_Int32 BinaryInput::readInt32( void )
{
	sal_Int32 nRet = 0;
	if( m_nCurPos + 4 <= m_nSize )
	{
		sal_Int32 nFactor = 1;
		for( sal_Int16 i = 0; i < 4; i++ )
		{
			nRet += sal_uInt8( m_pData[m_nCurPos++] ) * nFactor;
			nFactor *= 256;
		}
	}
	else
		OSL_ENSURE( false, "BinaryInput::readInt32(): Read past end" );

	return nRet;
}

sal_Unicode BinaryInput::readUnicodeChar( void )
{
	sal_uInt16 nRet = 0;
	if( m_nCurPos + 2 <= m_nSize )
	{
		nRet = nRet + sal_uInt8( m_pData[m_nCurPos++] );
		nRet += 256 * sal_uInt8( m_pData[m_nCurPos++] );
	}
	else
		OSL_ENSURE( false, "BinaryInput::readUnicodeChar(): Read past end" );

	sal_Unicode cRet = nRet;
	return cRet;
}

::rtl::OUString BinaryInput::readString( void )
{
	::rtl::OUStringBuffer aBuf;
	sal_Unicode c;
	do
	{
		c = readUnicodeChar();
		if( c != 0 )
			aBuf.append( c );
	}
	while( c != 0 );

	::rtl::OUString aRetStr = aBuf.makeStringAndClear();
	return aRetStr;
}

void StringResourcePersistenceImpl::importBinary( const Sequence< ::sal_Int8 >& Data )
	throw (IllegalArgumentException, RuntimeException)
{
	// Init: Remove all locales
	sal_Int32 nOldLocaleCount = 0;
	do
	{
		Sequence< Locale > aLocaleSeq = getLocales();
		nOldLocaleCount = aLocaleSeq.getLength();
		if( nOldLocaleCount > 0 )
		{
			Locale aLocale = aLocaleSeq[0];
			removeLocale( aLocale );
		}
	}
	while( nOldLocaleCount > 0 );

	// Import data
	Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory();
	BinaryInput aIn( Data, xMCF, m_xContext );

	sal_Int32 nVersion = aIn.readInt16();
	(void)nVersion;
	sal_Int32 nLocaleCount = aIn.readInt16();
	sal_Int32 iDefault = aIn.readInt16();
	(void)iDefault;

	sal_Int32* pPositions = new sal_Int32[nLocaleCount + 1];
	for( sal_Int32 i = 0; i < nLocaleCount + 1; i++ )
		pPositions[i] = aIn.readInt32();

	// Import locales
	LocaleItem* pUseAsDefaultItem = NULL;
	for( sal_Int32 i = 0; i < nLocaleCount; i++ )
	{
		sal_Int32 nPos = pPositions[i];
		aIn.seek( nPos );

		Locale aLocale;
		aLocale.Language = aIn.readString();
		aLocale.Country = aIn.readString();
		aLocale.Variant = aIn.readString();

		sal_Int32 nAfterStringPos = aIn.getPosition();
		sal_Int32 nSize = pPositions[i+1] - nAfterStringPos;
		Reference< io::XInputStream > xInput = aIn.getInputStreamForSection( nSize );
		if( xInput.is() )
		{
			LocaleItem* pLocaleItem = new LocaleItem( aLocale );
			if( iDefault == i )
				pUseAsDefaultItem = pLocaleItem;
			m_aLocaleItemVector.push_back( pLocaleItem );
			implReadPropertiesFile( pLocaleItem, xInput );
		}
	}

	if( pUseAsDefaultItem != NULL )
		setDefaultLocale( pUseAsDefaultItem->m_locale );

	delete[] pPositions;
}


// =============================================================================
// Private helper methods

bool checkNamingSceme( const ::rtl::OUString& aName, const ::rtl::OUString& aNameBase,
					   Locale& aLocale )
{
	bool bSuccess = false;

	sal_Int32 nNameLen = aName.getLength();
	sal_Int32 nNameBaseLen = aNameBase.getLength();

	// Name has to start with NameBase followed
	// by a '_' and at least one more character
    if( aName.indexOf( aNameBase ) == 0 && nNameBaseLen < nNameLen-1 &&
		aName.getStr()[nNameBaseLen] == '_' )
	{
		bSuccess = true;

		sal_Int32 iStart = nNameBaseLen + 1;
		sal_Int32 iNext_ = aName.indexOf( '_', iStart );
		if( iNext_ != -1 && iNext_ < nNameLen-1 )
		{
			aLocale.Language = aName.copy( iStart, iNext_ - iStart );

			iStart = iNext_ + 1;
			iNext_ = aName.indexOf( '_', iStart );
			if( iNext_ != -1 && iNext_ < nNameLen-1 )
			{
				aLocale.Country = aName.copy( iStart, iNext_ - iStart );
				aLocale.Variant = aName.copy( iNext_ + 1 );
			}
			else
				aLocale.Country = aName.copy( iStart );
		}
		else
			aLocale.Language = aName.copy( iStart );
	}
	return bSuccess;
}

void StringResourcePersistenceImpl::implLoadAllLocales( void )
{
	for( LocaleItemVectorIt it = m_aLocaleItemVector.begin(); it != m_aLocaleItemVector.end(); it++ )
	{
		LocaleItem* pLocaleItem = *it;
		if( pLocaleItem != NULL )
			loadLocale( pLocaleItem );
	}
}

// Scan locale properties files helper
void StringResourcePersistenceImpl::implScanLocaleNames( const Sequence< ::rtl::OUString >& aContentSeq )
{
	Locale aDefaultLocale;
	bool bDefaultFound = false;

    sal_Int32 nCount = aContentSeq.getLength();
	const ::rtl::OUString* pFiles = aContentSeq.getConstArray();
	for( int i = 0 ; i < nCount ; i++ )
	{
		::rtl::OUString aCompleteName = pFiles[i];
		rtl::OUString aPureName;
		rtl::OUString aExtension;
		sal_Int32 iDot = aCompleteName.lastIndexOf( '.' );
		sal_Int32 iSlash = aCompleteName.lastIndexOf( '/' );
		if( iDot != -1 )
		{
			sal_Int32 iCopyFrom = (iSlash != -1) ? iSlash + 1 : 0;
			aPureName = aCompleteName.copy( iCopyFrom, iDot-iCopyFrom );
			aExtension = aCompleteName.copy( iDot + 1 );
		}

		if( aExtension.equalsAscii( "properties" ) )
		{
			//rtl::OUString aName = aInetObj.getBase();
			Locale aLocale;

			if( checkNamingSceme( aPureName, m_aNameBase, aLocale ) )
			{
				LocaleItem* pLocaleItem = new LocaleItem( aLocale, false );
				m_aLocaleItemVector.push_back( pLocaleItem );

				if( m_pCurrentLocaleItem == NULL )
					m_pCurrentLocaleItem = pLocaleItem;

				if( m_pDefaultLocaleItem == NULL )
				{
					m_pDefaultLocaleItem = pLocaleItem;
					m_bDefaultModified = true;
				}
			}
		}
		else if( !bDefaultFound && aExtension.equalsAscii( "default" ) )
		{
			//rtl::OUString aName = aInetObj.getBase();
			Locale aLocale;

			if( checkNamingSceme( aPureName, m_aNameBase, aDefaultLocale ) )
				bDefaultFound = true;
		}
	}
	if( bDefaultFound )
	{
		LocaleItem* pLocaleItem = getItemForLocale( aDefaultLocale, false );
		if( pLocaleItem )
		{
			m_pDefaultLocaleItem = pLocaleItem;
			m_bDefaultModified = false;
		}
	}
}

// Scan locale properties files
void StringResourcePersistenceImpl::implScanLocales( void )
{
	// Dummy implementation, method not called for this
	// base class, but pure virtual not possible-
}

bool StringResourcePersistenceImpl::loadLocale( LocaleItem* pLocaleItem )
{
	bool bSuccess = false;

	OSL_ENSURE( pLocaleItem, "StringResourcePersistenceImpl::loadLocale(): pLocaleItem == NULL" );
    if( pLocaleItem )
    {
		if( pLocaleItem->m_bLoaded )
		{
			bSuccess = true;
		}
		else
		{
			bSuccess = implLoadLocale( pLocaleItem );
			pLocaleItem->m_bLoaded = true;		// = bSuccess??? -> leads to more tries
		}
	}
	return bSuccess;
}

bool StringResourcePersistenceImpl::implLoadLocale( LocaleItem* )
{
	// Dummy implementation, method not called for this
	// base class, but pure virtual not possible-
	return false;
}

::rtl::OUString implGetNameScemeForLocaleItem( const LocaleItem* pLocaleItem )
{
	static ::rtl::OUString aUnder = ::rtl::OUString::createFromAscii( "_" );

	OSL_ENSURE( pLocaleItem,
		"StringResourcePersistenceImpl::implGetNameScemeForLocaleItem(): pLocaleItem == NULL" );
	Locale aLocale = pLocaleItem->m_locale;

	::rtl::OUString aRetStr = aUnder;
	aRetStr += aLocale.Language;

	::rtl::OUString aCountry  = aLocale.Country;
	if( aCountry.getLength() )
	{
		aRetStr += aUnder;
		aRetStr += aCountry;
	}

	::rtl::OUString aVariant  = aLocale.Variant;
	if( aVariant.getLength() )
	{
		aRetStr += aUnder;
		aRetStr += aVariant;
	}
	return aRetStr;
}

::rtl::OUString StringResourcePersistenceImpl::implGetFileNameForLocaleItem
	( LocaleItem* pLocaleItem, const ::rtl::OUString& aNameBase )
{
	::rtl::OUString aFileName = aNameBase;
	if( aFileName.getLength() == 0 )
		aFileName = aNameBaseDefaultStr;

	aFileName += implGetNameScemeForLocaleItem( pLocaleItem );
	return aFileName;
}

::rtl::OUString StringResourcePersistenceImpl::implGetPathForLocaleItem
	( LocaleItem* pLocaleItem, const ::rtl::OUString& aNameBase,
	  const ::rtl::OUString& aLocation, bool bDefaultFile )
{
	::rtl::OUString aFileName = implGetFileNameForLocaleItem( pLocaleItem, aNameBase );
	INetURLObject aInetObj( aLocation );
	aInetObj.insertName( aFileName, sal_True, INetURLObject::LAST_SEGMENT, sal_True, INetURLObject::ENCODE_ALL );
	if( bDefaultFile )
		aInetObj.setExtension( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("default") ) );
	else
		aInetObj.setExtension( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("properties") ) );
	::rtl::OUString aCompleteFileName = aInetObj.GetMainURL( INetURLObject::NO_DECODE );
	return aCompleteFileName;
}

// White space according to Java property files specification in
// http://java.sun.com/j2se/1.4.2/docs/api/java/util/Properties.html#load(java.io.InputStream)
inline bool isWhiteSpace( sal_Unicode c )
{
	bool bWhite = (	c == 0x0020 ||		// space
					c == 0x0009 ||		// tab
					c == 0x000a ||		// line feed, not always handled by TextInputStream
					c == 0x000d ||		// carriage return, not always handled by TextInputStream
					c == 0x000C );		// form feed
	return bWhite;
}

inline void skipWhites( const sal_Unicode* pBuf, sal_Int32 nLen, sal_Int32& ri )
{
	while( ri < nLen )
	{
		if( !isWhiteSpace( pBuf[ri] ) )
			break;
		ri++;
	}
}

inline bool isHexDigit( sal_Unicode c, sal_uInt16& nDigitVal )
{
	bool bRet = true;
	if( c >= '0' && c <= '9' )
		nDigitVal = c - '0';
	else if( c >= 'a' && c <= 'f' )
		nDigitVal = c - 'a' + 10;
	else if( c >= 'A' && c <= 'F' )
		nDigitVal = c - 'A' + 10;
	else
		bRet = false;
	return bRet;
}

sal_Unicode getEscapeChar( const sal_Unicode* pBuf, sal_Int32 nLen, sal_Int32& ri )
{
	sal_Int32 i = ri;

	sal_Unicode cRet = 0;
	sal_Unicode c = pBuf[i];
	switch( c )
	{
		case 't':
			cRet = 0x0009;
			break;
		case 'n':
			cRet = 0x000a;
			break;
		case 'f':
			cRet = 0x000c;
			break;
		case 'r':
			cRet = 0x000d;
			break;
		case '\\':
			cRet = '\\';
			break;
		case 'u':
		{
			// Skip multiple u
			i++;
			while( i < nLen && pBuf[i] == 'u' )
				i++;

			// Process hex digits
			sal_Int32 nDigitCount = 0;
			sal_uInt16 nDigitVal;
			while( i < nLen && isHexDigit( pBuf[i], nDigitVal ) )
			{
				cRet = 16 * cRet + nDigitVal;

				nDigitCount++;
				if( nDigitCount == 4 )
				{
					// Write back position
					ri = i;
					break;
				}
				i++;
			}
			break;
		}
		default:
			cRet = c;
	}

	return cRet;
}

void CheckContinueInNextLine( Reference< io::XTextInputStream > xTextInputStream,
	::rtl::OUString& aLine, bool& bEscapePending, const sal_Unicode*& pBuf,
	sal_Int32& nLen, sal_Int32& i )
{
	if( i == nLen && bEscapePending )
	{
		bEscapePending = false;

		if( !xTextInputStream->isEOF() )
		{
			aLine = xTextInputStream->readLine();
			nLen = aLine.getLength();
			pBuf = aLine.getStr();
			i = 0;

			skipWhites( pBuf, nLen, i );
		}
	}
}

bool StringResourcePersistenceImpl::implReadPropertiesFile
	( LocaleItem* pLocaleItem, const Reference< io::XInputStream >& xInputStream )
{
	if( !xInputStream.is() || pLocaleItem == NULL )
		return false;

	bool bSuccess = false;
	Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory();
	Reference< io::XTextInputStream > xTextInputStream( xMCF->createInstanceWithContext
		( ::rtl::OUString::createFromAscii( "com.sun.star.io.TextInputStream" ), m_xContext ), UNO_QUERY );

	if( xTextInputStream.is() )
	{
		Reference< io::XActiveDataSink> xActiveDataSink( xTextInputStream, UNO_QUERY );
		if( xActiveDataSink.is() )
		{
			bSuccess = true;

			xActiveDataSink->setInputStream( xInputStream );

			::rtl::OUString aEncodingStr = ::rtl::OUString::createFromAscii
				( rtl_getMimeCharsetFromTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) );
			xTextInputStream->setEncoding( aEncodingStr );

			::rtl::OUString aLine;
			while( !xTextInputStream->isEOF() )
			{
				aLine = xTextInputStream->readLine();

				sal_Int32 nLen = aLine.getLength();
				if( 0 == nLen )
					continue;
				const sal_Unicode* pBuf = aLine.getStr();
				::rtl::OUStringBuffer aBuf;
				sal_Unicode c = 0;
				sal_Int32 i = 0;

				skipWhites( pBuf, nLen, i );
				if( i == nLen )
					continue;	// line contains only white spaces

				// Comment?
				c = pBuf[i];
				if( c == '#' || c == '!' )
					continue;

				// Scan key
				::rtl::OUString aResourceID;
				bool bEscapePending = false;
				bool bStrComplete = false;
				while( i < nLen && !bStrComplete )
				{
					c = pBuf[i];
					if( bEscapePending )
					{
						aBuf.append( getEscapeChar( pBuf, nLen, i ) );
						bEscapePending = false;
					}
					else
					{
						if( c == '\\' )
						{
							bEscapePending = true;
						}
						else
						{
							if( c == ':' || c == '=' || isWhiteSpace( c ) )
								bStrComplete = true;
							else
								aBuf.append( c );
						}
					}
					i++;

					CheckContinueInNextLine( xTextInputStream, aLine, bEscapePending, pBuf, nLen, i );
					if( i == nLen )
						bStrComplete = true;

					if( bStrComplete )
						aResourceID = aBuf.makeStringAndClear();
				}

				// Ignore lines with empty keys
				if( 0 == aResourceID.getLength() )
					continue;

				// Scan value
				skipWhites( pBuf, nLen, i );

				::rtl::OUString aValueStr;
				bEscapePending = false;
				bStrComplete = false;
				while( i < nLen && !bStrComplete )
				{
					c = pBuf[i];
					if( c == 0x000a || c == 0x000d )	// line feed/carriage return, not always handled by TextInputStream
					{
						i++;
					}
					else
					{
						if( bEscapePending )
						{
							aBuf.append( getEscapeChar( pBuf, nLen, i ) );
							bEscapePending = false;
						}
						else if( c == '\\' )
							bEscapePending = true;
						else
							aBuf.append( c );
						i++;

						CheckContinueInNextLine( xTextInputStream, aLine, bEscapePending, pBuf, nLen, i );
					}
					if( i == nLen )
						bStrComplete = true;

					if( bStrComplete )
						aValueStr = aBuf.makeStringAndClear();
				}

				// Push into table
				pLocaleItem->m_aIdToStringMap[ aResourceID ] = aValueStr;
				implScanIdForNumber( aResourceID );
				IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap;
				rIndexMap[ aResourceID ] = pLocaleItem->m_nNextIndex++;
			}
		}
	}

	return bSuccess;
}


inline sal_Unicode getHexCharForDigit( sal_uInt16 nDigitVal )
{
	sal_Unicode cRet = ( nDigitVal < 10 ) ? ('0' + nDigitVal) : ('a' + (nDigitVal-10));
	return cRet;
}

void implWriteCharToBuffer( ::rtl::OUStringBuffer& aBuf, sal_Unicode cu, bool bKey )
{
	if( cu == '\\' )
	{
		aBuf.append( (sal_Unicode)'\\' );
		aBuf.append( (sal_Unicode)'\\' );
	}
	else if( cu == 0x000a )
	{
		aBuf.append( (sal_Unicode)'\\' );
		aBuf.append( (sal_Unicode)'n' );
	}
	else if( cu == 0x000d )
	{
		aBuf.append( (sal_Unicode)'\\' );
		aBuf.append( (sal_Unicode)'r' );
	}
	else if( bKey && cu == '=' )
	{
		aBuf.append( (sal_Unicode)'\\' );
		aBuf.append( (sal_Unicode)'=' );
	}
	else if( bKey && cu == ':' )
	{
		aBuf.append( (sal_Unicode)'\\' );
		aBuf.append( (sal_Unicode)':' );
	}
	// ISO/IEC 8859-1 range according to:
	// http://en.wikipedia.org/wiki/ISO/IEC_8859-1
	else if( (cu >= 0x20 && cu <= 0x7e) )
	//TODO: Check why (cu >= 0xa0 && cu <= 0xFF)
	//is encoded in sample properties files
	//else if( (cu >= 0x20 && cu <= 0x7e) ||
	//		 (cu >= 0xa0 && cu <= 0xFF) )
	{
		aBuf.append( cu );
	}
	else
	{
		// Unicode encoding
		aBuf.append( (sal_Unicode)'\\' );
		aBuf.append( (sal_Unicode)'u' );

		sal_uInt16 nVal = cu;
		for( sal_uInt16 i = 0 ; i < 4 ; i++ )
		{
			sal_uInt16 nDigit = nVal / 0x1000;
			nVal -= nDigit * 0x1000;
			nVal *= 0x10;
			aBuf.append( getHexCharForDigit( nDigit ) );
		}
	}
}

void implWriteStringWithEncoding( const ::rtl::OUString& aStr,
	Reference< io::XTextOutputStream > xTextOutputStream, bool bKey )
{
	static sal_Unicode cLineFeed = 0xa;

	(void)aStr;
	(void)xTextOutputStream;

	::rtl::OUStringBuffer aBuf;
	sal_Int32 nLen = aStr.getLength();
	const sal_Unicode* pSrc = aStr.getStr();
	for( sal_Int32 i = 0 ; i < nLen ; i++ )
	{
		sal_Unicode cu = pSrc[i];
		implWriteCharToBuffer( aBuf, cu, bKey );
		// TODO?: split long lines
	}
	if( !bKey )
		aBuf.append( cLineFeed );

	::rtl::OUString aWriteStr = aBuf.makeStringAndClear();
	xTextOutputStream->writeString( aWriteStr );
}

bool StringResourcePersistenceImpl::implWritePropertiesFile( LocaleItem* pLocaleItem,
	const Reference< io::XOutputStream >& xOutputStream, const ::rtl::OUString& aComment )
{
	static ::rtl::OUString aAssignmentStr = ::rtl::OUString::createFromAscii( "=" );
	static ::rtl::OUString aLineFeedStr = ::rtl::OUString::createFromAscii( "\n" );

	if( !xOutputStream.is() || pLocaleItem == NULL )
		return false;

	bool bSuccess = false;
	Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory();
	Reference< io::XTextOutputStream > xTextOutputStream( xMCF->createInstanceWithContext
		( ::rtl::OUString::createFromAscii( "com.sun.star.io.TextOutputStream" ), m_xContext ), UNO_QUERY );

	if( xTextOutputStream.is() )
	{
		Reference< io::XActiveDataSource> xActiveDataSource( xTextOutputStream, UNO_QUERY );
		if( xActiveDataSource.is() )
		{
			xActiveDataSource->setOutputStream( xOutputStream );

			::rtl::OUString aEncodingStr = ::rtl::OUString::createFromAscii
				( rtl_getMimeCharsetFromTextEncoding( RTL_TEXTENCODING_ISO_8859_1 ) );
			xTextOutputStream->setEncoding( aEncodingStr );

			xTextOutputStream->writeString( aComment );
			xTextOutputStream->writeString( aLineFeedStr );

			const IdToStringMap& rHashMap = pLocaleItem->m_aIdToStringMap;
			if( rHashMap.size() > 0 )
			{
				// Sort ids according to read order
				const IdToIndexMap& rIndexMap = pLocaleItem->m_aIdToIndexMap;
				IdToIndexMap::const_iterator it_index;

				// Find max/min index
				sal_Int32 nMinIndex = -1;
				sal_Int32 nMaxIndex = -1;
				for( it_index = rIndexMap.begin(); it_index != rIndexMap.end(); it_index++ )
				{
					sal_Int32 nIndex = (*it_index).second;
					if( nMinIndex > nIndex || nMinIndex == -1 )
						nMinIndex = nIndex;
					if( nMaxIndex < nIndex )
						nMaxIndex = nIndex;
				}
				sal_Int32 nTabSize = nMaxIndex - nMinIndex + 1;

				// Create sorted array of pointers to the id strings
				const ::rtl::OUString** pIdPtrs = new const ::rtl::OUString*[nTabSize];
				sal_Int32 i;
				for( i = 0 ; i < nTabSize ; i++ )
					pIdPtrs[i] = NULL;
				for( it_index = rIndexMap.begin(); it_index != rIndexMap.end(); it_index++ )
				{
					sal_Int32 nIndex = (*it_index).second;
					pIdPtrs[nIndex - nMinIndex] = &((*it_index).first);
				}

				// Write lines in correct order
				for( i = 0 ; i < nTabSize ; i++ )
				{
					const ::rtl::OUString* pStr = pIdPtrs[i];
					if( pStr != NULL )
					{
						::rtl::OUString aResourceID = *pStr;
						IdToStringMap::const_iterator it = rHashMap.find( aResourceID );
						if( !( it == rHashMap.end() ) )
						{
							implWriteStringWithEncoding( aResourceID, xTextOutputStream, true );
							xTextOutputStream->writeString( aAssignmentStr );
							::rtl::OUString aValStr = (*it).second;
							implWriteStringWithEncoding( aValStr, xTextOutputStream, false );
						}
					}
				}

				delete[] pIdPtrs;
			}

			bSuccess = true;
		}
	}
	return bSuccess;
}


// =============================================================================
// StringResourceWithStorageImpl
// =============================================================================

// component operations
static Sequence< ::rtl::OUString > getSupportedServiceNames_StringResourceWithStorageImpl()
{
    Sequence< ::rtl::OUString > names(1);
    names[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.resource.StringResourceWithStorage") );
    return names;
}

static ::rtl::OUString getImplementationName_StringResourceWithStorageImpl()
{
    return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.scripting.StringResourceWithStorage") );
}

static Reference< XInterface > SAL_CALL create_StringResourceWithStorageImpl(
    Reference< XComponentContext > const & xContext )
    SAL_THROW( () )
{
    return static_cast< ::cppu::OWeakObject * >( new StringResourceWithStorageImpl( xContext ) );
}

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

StringResourceWithStorageImpl::StringResourceWithStorageImpl( const Reference< XComponentContext >& rxContext )
    : StringResourceWithStorageImpl_BASE( rxContext )
	, m_bStorageChanged( false )
{
}

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

StringResourceWithStorageImpl::~StringResourceWithStorageImpl()
{
}

// -----------------------------------------------------------------------------
// XServiceInfo
// -----------------------------------------------------------------------------

::rtl::OUString StringResourceWithStorageImpl::getImplementationName(  ) throw (RuntimeException)
{
    return getImplementationName_StringResourceWithStorageImpl();
}

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

sal_Bool StringResourceWithStorageImpl::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
{
	Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
	const ::rtl::OUString* pNames = aNames.getConstArray();
	const ::rtl::OUString* pEnd = pNames + aNames.getLength();
	for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
		;

	return pNames != pEnd;
}

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

Sequence< ::rtl::OUString > StringResourceWithStorageImpl::getSupportedServiceNames(  ) throw (RuntimeException)
{
    return getSupportedServiceNames_StringResourceWithStorageImpl();
}

// -----------------------------------------------------------------------------
// XInitialization
// -----------------------------------------------------------------------------

void StringResourceWithStorageImpl::initialize( const Sequence< Any >& aArguments )
	throw (Exception, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );

    if ( aArguments.getLength() != 5 )
    {
        throw RuntimeException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StringResourceWithStorageImpl::initialize: invalid number of arguments!" ) ),
            Reference< XInterface >() );
    }

	bool bOk = (aArguments[0] >>= m_xStorage);
	if( bOk && !m_xStorage.is() )
		bOk = false;

	if( !bOk )
    {
        ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceWithStorageImpl::initialize: invalid storage" );
        throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
	}

	implInitializeCommonParameters( aArguments );
}

// -----------------------------------------------------------------------------
// Forwarding calls to base class

// XModifyBroadcaster
void StringResourceWithStorageImpl::addModifyListener( const Reference< XModifyListener >& aListener )
	throw (RuntimeException)
{
	StringResourceImpl::addModifyListener( aListener );
}
void StringResourceWithStorageImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
	throw (RuntimeException)
{
	StringResourceImpl::removeModifyListener( aListener );
}

// XStringResourceResolver
::rtl::OUString StringResourceWithStorageImpl::resolveString( const ::rtl::OUString& ResourceID )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException)
{
	return StringResourceImpl::resolveString( ResourceID ) ;
}
::rtl::OUString StringResourceWithStorageImpl::resolveStringForLocale( const ::rtl::OUString& ResourceID, const Locale& locale )
	throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException)
{
	return StringResourceImpl::resolveStringForLocale( ResourceID, locale );
}
sal_Bool StringResourceWithStorageImpl::hasEntryForId( const ::rtl::OUString& ResourceID )
	throw (RuntimeException)
{
	return StringResourceImpl::hasEntryForId( ResourceID ) ;
}
sal_Bool StringResourceWithStorageImpl::hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID,
	const Locale& locale )
		throw (RuntimeException)
{
	return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale );
}
Sequence< ::rtl::OUString > StringResourceWithStorageImpl::getResourceIDs(  )
	throw (RuntimeException)
{
	return StringResourceImpl::getResourceIDs();
}
Sequence< ::rtl::OUString > StringResourceWithStorageImpl::getResourceIDsForLocale
	( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException)
{
	return StringResourceImpl::getResourceIDsForLocale( locale );
}
Locale StringResourceWithStorageImpl::getCurrentLocale()
	throw (RuntimeException)
{
	return StringResourceImpl::getCurrentLocale();
}
Locale StringResourceWithStorageImpl::getDefaultLocale(  )
	throw (RuntimeException)
{
	return StringResourceImpl::getDefaultLocale();
}
Sequence< Locale > StringResourceWithStorageImpl::getLocales(  )
	throw (RuntimeException)
{
	return StringResourceImpl::getLocales();
}

// XStringResourceManager
sal_Bool StringResourceWithStorageImpl::isReadOnly()
	throw (RuntimeException)
{
	return StringResourceImpl::isReadOnly();
}
void StringResourceWithStorageImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
	throw (IllegalArgumentException, RuntimeException)
{
	StringResourceImpl::setCurrentLocale( locale, FindClosestMatch );
}
void StringResourceWithStorageImpl::setDefaultLocale( const Locale& locale )
	throw (IllegalArgumentException, RuntimeException,NoSupportException)
{
	StringResourceImpl::setDefaultLocale( locale );
}
void StringResourceWithStorageImpl::setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str )
	throw (NoSupportException, RuntimeException)
{
	StringResourceImpl::setString( ResourceID, Str );
}
void StringResourceWithStorageImpl::setStringForLocale
	( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, const Locale& locale )
		throw (NoSupportException, RuntimeException)
{
	StringResourceImpl::setStringForLocale( ResourceID, Str, locale );
}
void StringResourceWithStorageImpl::removeId( const ::rtl::OUString& ResourceID )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException)
{
	StringResourceImpl::removeId( ResourceID );
}
void StringResourceWithStorageImpl::removeIdForLocale( const ::rtl::OUString& ResourceID, const Locale& locale )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException)
{
	StringResourceImpl::removeIdForLocale( ResourceID, locale );
}
void StringResourceWithStorageImpl::newLocale( const Locale& locale )
	throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException)
{
	StringResourceImpl::newLocale( locale );
}
void StringResourceWithStorageImpl::removeLocale( const Locale& locale )
	throw (IllegalArgumentException, RuntimeException, NoSupportException)
{
	StringResourceImpl::removeLocale( locale );
}
sal_Int32 StringResourceWithStorageImpl::getUniqueNumericId(  )
	throw (RuntimeException, NoSupportException)
{
	return StringResourceImpl::getUniqueNumericId();
}

// XStringResourcePersistence
void StringResourceWithStorageImpl::store()
	throw (NoSupportException, Exception, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	implCheckReadOnly( "StringResourceWithStorageImpl::store(): Read only" );

	bool bUsedForStore = true;
	bool bStoreAll = m_bStorageChanged;
	m_bStorageChanged = false;
	if( !m_bModified && !bStoreAll )
		return;

	implStoreAtStorage( m_aNameBase, m_aComment, m_xStorage, bUsedForStore, bStoreAll );
	m_bModified = false;
}

sal_Bool StringResourceWithStorageImpl::isModified(  )
	throw (RuntimeException)
{
	return StringResourcePersistenceImpl::isModified();
}
void StringResourceWithStorageImpl::setComment( const ::rtl::OUString& Comment )
	throw (::com::sun::star::uno::RuntimeException)
{
	StringResourcePersistenceImpl::setComment( Comment );
}
void StringResourceWithStorageImpl::storeToStorage( const Reference< XStorage >& Storage,
	const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment )
		throw (Exception, RuntimeException)
{
	StringResourcePersistenceImpl::storeToStorage( Storage, NameBase, Comment );
}
void StringResourceWithStorageImpl::storeToURL( const ::rtl::OUString& URL,
	const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment,
	const Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
		throw (Exception, RuntimeException)
{
	StringResourcePersistenceImpl::storeToURL( URL, NameBase, Comment, Handler );
}
Sequence< ::sal_Int8 > StringResourceWithStorageImpl::exportBinary(  )
	throw (RuntimeException)
{
	return StringResourcePersistenceImpl::exportBinary();
}
void StringResourceWithStorageImpl::importBinary( const Sequence< ::sal_Int8 >& Data )
	throw (IllegalArgumentException, RuntimeException)
{
	StringResourcePersistenceImpl::importBinary( Data );
}

// -----------------------------------------------------------------------------
// XStringResourceWithStorage

void StringResourceWithStorageImpl::storeAsStorage( const Reference< XStorage >& Storage )
	throw (Exception, RuntimeException)
{
	setStorage( Storage );
	store();
}

void StringResourceWithStorageImpl::setStorage( const Reference< XStorage >& Storage )
	throw (IllegalArgumentException, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );

	if( !Storage.is() )
    {
        ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii
			( "StringResourceWithStorageImpl::setStorage: invalid storage" );
        throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
	}

	implLoadAllLocales();

	m_xStorage = Storage;
	m_bStorageChanged = true;
}


// =============================================================================
// Private helper methods
// =============================================================================

// Scan locale properties files
void StringResourceWithStorageImpl::implScanLocales( void )
{
	Reference< container::XNameAccess > xNameAccess( m_xStorage, UNO_QUERY );
    if( xNameAccess.is() )
    {
		Sequence< ::rtl::OUString > aContentSeq = xNameAccess->getElementNames();
		implScanLocaleNames( aContentSeq );
	}

	implLoadAllLocales();
}

// Loading
bool StringResourceWithStorageImpl::implLoadLocale( LocaleItem* pLocaleItem )
{
	bool bSuccess = false;
	try
	{
		::rtl::OUString aStreamName = implGetFileNameForLocaleItem( pLocaleItem, m_aNameBase );
		aStreamName += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(".properties") );

		Reference< io::XStream > xElementStream =
			m_xStorage->openStreamElement( aStreamName, ElementModes::READ );

		if( xElementStream.is() )
		{
			Reference< io::XInputStream > xInputStream = xElementStream->getInputStream();
			if( xInputStream.is() )
			{
				bSuccess = StringResourcePersistenceImpl::implReadPropertiesFile( pLocaleItem, xInputStream );
				xInputStream->closeInput();
			}
		}
	}
	catch( uno::Exception& )
	{}

	return bSuccess;
}


// =============================================================================
// StringResourceWithLocationImpl
// =============================================================================

// component operations
static Sequence< ::rtl::OUString > getSupportedServiceNames_StringResourceWithLocationImpl()
{
    Sequence< ::rtl::OUString > names(1);
    names[0] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.resource.StringResourceWithLocation") );
    return names;
}

static ::rtl::OUString getImplementationName_StringResourceWithLocationImpl()
{
    return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.scripting.StringResourceWithLocation") );
}

static Reference< XInterface > SAL_CALL create_StringResourceWithLocationImpl(
    Reference< XComponentContext > const & xContext )
    SAL_THROW( () )
{
    return static_cast< ::cppu::OWeakObject * >( new StringResourceWithLocationImpl( xContext ) );
}

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

StringResourceWithLocationImpl::StringResourceWithLocationImpl( const Reference< XComponentContext >& rxContext )
    : StringResourceWithLocationImpl_BASE( rxContext )
	, m_bLocationChanged( false )
{
}

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

StringResourceWithLocationImpl::~StringResourceWithLocationImpl()
{
}

// -----------------------------------------------------------------------------
// XServiceInfo
// -----------------------------------------------------------------------------

::rtl::OUString StringResourceWithLocationImpl::getImplementationName(  ) throw (RuntimeException)
{
    return getImplementationName_StringResourceWithLocationImpl();
}

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

sal_Bool StringResourceWithLocationImpl::supportsService( const ::rtl::OUString& rServiceName ) throw (RuntimeException)
{
	Sequence< ::rtl::OUString > aNames( getSupportedServiceNames() );
	const ::rtl::OUString* pNames = aNames.getConstArray();
	const ::rtl::OUString* pEnd = pNames + aNames.getLength();
	for ( ; pNames != pEnd && !pNames->equals( rServiceName ); ++pNames )
		;

	return pNames != pEnd;
}

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

Sequence< ::rtl::OUString > StringResourceWithLocationImpl::getSupportedServiceNames(  ) throw (RuntimeException)
{
    return getSupportedServiceNames_StringResourceWithLocationImpl();
}

// -----------------------------------------------------------------------------
// XInitialization
// -----------------------------------------------------------------------------

void StringResourceWithLocationImpl::initialize( const Sequence< Any >& aArguments )
	throw (Exception, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );

    if ( aArguments.getLength() != 6 )
    {
        throw RuntimeException(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM
				( "XInitialization::initialize: invalid number of arguments!" ) ),
            Reference< XInterface >() );
    }

	bool bOk = (aArguments[0] >>= m_aLocation);
	sal_Int32 nLen = m_aLocation.getLength();
	if( bOk && nLen == 0 )
	{
		bOk = false;
	}
	else
	{
		if( m_aLocation.getStr()[nLen - 1] != '/' )
			m_aLocation += ::rtl::OUString::createFromAscii( "/" );
	}

	if( !bOk )
    {
		::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "XInitialization::initialize: invalid URL" );
		throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
	}


	bOk = (aArguments[5] >>= m_xInteractionHandler);
	if( !bOk )
    {
        ::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii( "StringResourceWithStorageImpl::initialize: invalid type" );
        throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 5 );
	}

	implInitializeCommonParameters( aArguments );
}

// -----------------------------------------------------------------------------
// Forwarding calls to base class

// XModifyBroadcaster
void StringResourceWithLocationImpl::addModifyListener( const Reference< XModifyListener >& aListener )
	throw (RuntimeException)
{
	StringResourceImpl::addModifyListener( aListener );
}
void StringResourceWithLocationImpl::removeModifyListener( const Reference< XModifyListener >& aListener )
	throw (RuntimeException)
{
	StringResourceImpl::removeModifyListener( aListener );
}

// XStringResourceResolver
::rtl::OUString StringResourceWithLocationImpl::resolveString( const ::rtl::OUString& ResourceID )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException)
{
	return StringResourceImpl::resolveString( ResourceID ) ;
}
::rtl::OUString StringResourceWithLocationImpl::resolveStringForLocale( const ::rtl::OUString& ResourceID, const Locale& locale )
	throw ( ::com::sun::star::resource::MissingResourceException, RuntimeException)
{
	return StringResourceImpl::resolveStringForLocale( ResourceID, locale );
}
sal_Bool StringResourceWithLocationImpl::hasEntryForId( const ::rtl::OUString& ResourceID )
	throw (RuntimeException)
{
	return StringResourceImpl::hasEntryForId( ResourceID ) ;
}
sal_Bool StringResourceWithLocationImpl::hasEntryForIdAndLocale( const ::rtl::OUString& ResourceID,
	const Locale& locale )
		throw (RuntimeException)
{
	return StringResourceImpl::hasEntryForIdAndLocale( ResourceID, locale );
}
Sequence< ::rtl::OUString > StringResourceWithLocationImpl::getResourceIDs(  )
	throw (RuntimeException)
{
	return StringResourceImpl::getResourceIDs();
}
Sequence< ::rtl::OUString > StringResourceWithLocationImpl::getResourceIDsForLocale
	( const Locale& locale ) throw (::com::sun::star::uno::RuntimeException)
{
	return StringResourceImpl::getResourceIDsForLocale( locale );
}
Locale StringResourceWithLocationImpl::getCurrentLocale()
	throw (RuntimeException)
{
	return StringResourceImpl::getCurrentLocale();
}
Locale StringResourceWithLocationImpl::getDefaultLocale(  )
	throw (RuntimeException)
{
	return StringResourceImpl::getDefaultLocale();
}
Sequence< Locale > StringResourceWithLocationImpl::getLocales(  )
	throw (RuntimeException)
{
	return StringResourceImpl::getLocales();
}

// XStringResourceManager
sal_Bool StringResourceWithLocationImpl::isReadOnly()
	throw (RuntimeException)
{
	return StringResourceImpl::isReadOnly();
}
void StringResourceWithLocationImpl::setCurrentLocale( const Locale& locale, sal_Bool FindClosestMatch )
	throw (IllegalArgumentException, RuntimeException)
{
	StringResourceImpl::setCurrentLocale( locale, FindClosestMatch );
}
void StringResourceWithLocationImpl::setDefaultLocale( const Locale& locale )
	throw (IllegalArgumentException, RuntimeException,NoSupportException)
{
	StringResourceImpl::setDefaultLocale( locale );
}
void StringResourceWithLocationImpl::setString( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str )
	throw (NoSupportException, RuntimeException)
{
	StringResourceImpl::setString( ResourceID, Str );
}
void StringResourceWithLocationImpl::setStringForLocale
	( const ::rtl::OUString& ResourceID, const ::rtl::OUString& Str, const Locale& locale )
		throw (NoSupportException, RuntimeException)
{
	StringResourceImpl::setStringForLocale( ResourceID, Str, locale );
}
void StringResourceWithLocationImpl::removeId( const ::rtl::OUString& ResourceID )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException)
{
	StringResourceImpl::removeId( ResourceID );
}
void StringResourceWithLocationImpl::removeIdForLocale( const ::rtl::OUString& ResourceID, const Locale& locale )
	throw (::com::sun::star::resource::MissingResourceException, RuntimeException, NoSupportException)
{
	StringResourceImpl::removeIdForLocale( ResourceID, locale );
}
void StringResourceWithLocationImpl::newLocale( const Locale& locale )
	throw (ElementExistException, IllegalArgumentException, RuntimeException, NoSupportException)
{
	StringResourceImpl::newLocale( locale );
}
void StringResourceWithLocationImpl::removeLocale( const Locale& locale )
	throw (IllegalArgumentException, RuntimeException, NoSupportException)
{
	StringResourceImpl::removeLocale( locale );
}
sal_Int32 StringResourceWithLocationImpl::getUniqueNumericId(  )
	throw (RuntimeException, NoSupportException)
{
	return StringResourceImpl::getUniqueNumericId();
}

// XStringResourcePersistence
void StringResourceWithLocationImpl::store()
	throw (NoSupportException, Exception, RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	implCheckReadOnly( "StringResourceWithLocationImpl::store(): Read only" );

	bool bUsedForStore = true;
	bool bStoreAll = m_bLocationChanged;
	m_bLocationChanged = false;
	if( !m_bModified && !bStoreAll )
		return;

	Reference< ucb::XSimpleFileAccess > xFileAccess = getFileAccess();
	implStoreAtLocation( m_aLocation, m_aNameBase, m_aComment,
		xFileAccess, bUsedForStore, bStoreAll );
	m_bModified = false;
}

sal_Bool StringResourceWithLocationImpl::isModified(  )
	throw (RuntimeException)
{
	return StringResourcePersistenceImpl::isModified();
}
void StringResourceWithLocationImpl::setComment( const ::rtl::OUString& Comment )
	throw (::com::sun::star::uno::RuntimeException)
{
	StringResourcePersistenceImpl::setComment( Comment );
}
void StringResourceWithLocationImpl::storeToStorage( const Reference< XStorage >& Storage,
	const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment )
		throw (Exception, RuntimeException)
{
	StringResourcePersistenceImpl::storeToStorage( Storage, NameBase, Comment );
}
void StringResourceWithLocationImpl::storeToURL( const ::rtl::OUString& URL,
	const ::rtl::OUString& NameBase, const ::rtl::OUString& Comment,
	const Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
		throw (Exception, RuntimeException)
{
	StringResourcePersistenceImpl::storeToURL( URL, NameBase, Comment, Handler );
}
Sequence< ::sal_Int8 > StringResourceWithLocationImpl::exportBinary(  )
	throw (RuntimeException)
{
	return StringResourcePersistenceImpl::exportBinary();
}
void StringResourceWithLocationImpl::importBinary( const Sequence< ::sal_Int8 >& Data )
	throw (IllegalArgumentException, RuntimeException)
{
	StringResourcePersistenceImpl::importBinary( Data );
}

// -----------------------------------------------------------------------------
// XStringResourceWithLocation

// XStringResourceWithLocation
void StringResourceWithLocationImpl::storeAsURL( const ::rtl::OUString& URL )
	throw (::com::sun::star::uno::Exception, ::com::sun::star::uno::RuntimeException)
{
	setURL( URL );
	store();
}

void StringResourceWithLocationImpl::setURL( const ::rtl::OUString& URL )
	throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
{
    ::osl::MutexGuard aGuard( getMutex() );
	implCheckReadOnly( "StringResourceWithLocationImpl::setURL(): Read only" );

	sal_Int32 nLen = URL.getLength();
	if( nLen == 0 )
    {
		::rtl::OUString errorMsg = ::rtl::OUString::createFromAscii
			( "StringResourceWithLocationImpl::setURL: invalid URL" );
		throw IllegalArgumentException( errorMsg, Reference< XInterface >(), 0 );
	}

	implLoadAllLocales();

	// Delete files at old location
	bool bUsedForStore = false;
	bool bStoreAll = false;
	bool bKillAll = true;
	implStoreAtLocation( m_aLocation, m_aNameBase, m_aComment,
		getFileAccess(), bUsedForStore, bStoreAll, bKillAll );

	m_aLocation = URL;
	m_bLocationChanged = true;
}


// =============================================================================
// Private helper methods
// =============================================================================

// Scan locale properties files
void StringResourceWithLocationImpl::implScanLocales( void )
{
	const Reference< ucb::XSimpleFileAccess > xFileAccess = getFileAccess();
    if( xFileAccess.is() && xFileAccess->isFolder( m_aLocation ) )
    {
		Sequence< ::rtl::OUString > aContentSeq = xFileAccess->getFolderContents( m_aLocation, false );
		implScanLocaleNames( aContentSeq );
	}
}

// Loading
bool StringResourceWithLocationImpl::implLoadLocale( LocaleItem* pLocaleItem )
{
	bool bSuccess = false;

	const Reference< ucb::XSimpleFileAccess > xFileAccess = getFileAccess();
	if( xFileAccess.is() )
	{
		::rtl::OUString aCompleteFileName =
			implGetPathForLocaleItem( pLocaleItem, m_aNameBase, m_aLocation );

		Reference< io::XInputStream > xInputStream;
		try
		{
			xInputStream = xFileAccess->openFileRead( aCompleteFileName );
		}
		catch( Exception& )
		{}
		if( xInputStream.is() )
		{
			bSuccess = StringResourcePersistenceImpl::implReadPropertiesFile( pLocaleItem, xInputStream );
			xInputStream->closeInput();
		}
	}

	return bSuccess;
}

const Reference< ucb::XSimpleFileAccess > StringResourceWithLocationImpl::getFileAccess( void )
{
    ::osl::MutexGuard aGuard( getMutex() );

	if( !m_xSFI.is() )
	{
		Reference< XMultiComponentFactory > xMCF = getMultiComponentFactory();
		m_xSFI = Reference< ucb::XSimpleFileAccess >( xMCF->createInstanceWithContext
			( ::rtl::OUString::createFromAscii( "com.sun.star.ucb.SimpleFileAccess" ), m_xContext ), UNO_QUERY );

		if( m_xSFI.is() && m_xInteractionHandler.is() )
			m_xSFI->setInteractionHandler( m_xInteractionHandler );
	}
	return m_xSFI;
}


// =============================================================================
// component export operations
// =============================================================================

static struct ::cppu::ImplementationEntry s_component_entries [] =
{
    {
        create_StringResourceImpl, getImplementationName_StringResourceImpl,
        getSupportedServiceNames_StringResourceImpl,
		::cppu::createSingleComponentFactory,
        0, 0
    },
    {
        create_StringResourceWithLocationImpl, getImplementationName_StringResourceWithLocationImpl,
        getSupportedServiceNames_StringResourceWithLocationImpl,
        ::cppu::createSingleComponentFactory,
        0, 0
    },
    {
        create_StringResourceWithStorageImpl, getImplementationName_StringResourceWithStorageImpl,
        getSupportedServiceNames_StringResourceWithStorageImpl,
        ::cppu::createSingleComponentFactory,
        0, 0
    },
    { 0, 0, 0, 0, 0, 0 }
};


//.........................................................................
}	// namespace dlgprov
//.........................................................................


// =============================================================================
// component exports
// =============================================================================

extern "C"
{
    void SAL_CALL component_getImplementationEnvironment(
        const sal_Char ** ppEnvTypeName, uno_Environment ** ppEnv )
    {
		(void)ppEnv;

        *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
    }

    void * SAL_CALL component_getFactory(
        const sal_Char * pImplName, lang::XMultiServiceFactory * pServiceManager,
        registry::XRegistryKey * pRegistryKey )
    {
        return ::cppu::component_getFactoryHelper(
            pImplName, pServiceManager, pRegistryKey, ::stringresource::s_component_entries );
    }
}
