/**************************************************************
 *
 * 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_sfx2.hxx"

#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/util/DateTime.hpp>
#include <com/sun/star/util/Date.hpp>
#include <com/sun/star/util/Time.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/beans/StringPair.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/xml/sax/XParser.hpp>
#include <com/sun/star/document/XImporter.hpp>
#include <com/sun/star/document/XExporter.hpp>
#include <com/sun/star/io/XActiveDataSource.hpp>
#include <com/sun/star/document/XFilter.hpp>
#include <com/sun/star/embed/XTransactedObject.hpp>
#include <com/sun/star/lang/Locale.hpp>
#include <com/sun/star/util/XModifiable.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>

#include <unotools/configmgr.hxx>
#include <tools/inetdef.hxx>
#include <unotools/bootstrap.hxx>
#include <cppuhelper/interfacecontainer.hxx>
#include <osl/mutex.hxx>
#include <rtl/ustrbuf.hxx>
#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>

#include <tools/errcode.hxx>
#include <svl/cntwids.hrc>
#include <comphelper/string.hxx>
#include <comphelper/sequenceasvector.hxx>
#include <comphelper/storagehelper.hxx>
#include <sot/storage.hxx>

#include <sfx2/objuno.hxx>
#include <sfx2/sfx.hrc>

#include <vector>
#include <algorithm>

#include "sfx2/sfxresid.hxx"
#include "doc.hrc"

using namespace ::com::sun::star;

// TODO/REFACTOR: provide service for MS formats
// TODO/REFACTOR: IsEncrypted is never set nor read
// Generator is not saved ATM; which value?!
// Generator handling must be implemented
// Deprecate "Theme", rework IDL
// AutoLoadEnabled is deprecated?!
// Reasonable defaults for DateTime
// MIMEType readonly?!
// Announce changes about Theme, Language, Generator, removed entries etc.
// IsEncrypted is necessary for binary formats!
// Open: When to call PrepareDocInfoForSave? Currently only called for own formats and HTML/Writer
// Open: How to load and save EditingTime to MS formats
// PPT-Export should use SavePropertySet

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

// The number of user defined fields handled by the evil XDocumentInfo
// interface. There are exactly 4. No more, no less.
#define FOUR 4

#define PROPERTY_UNBOUND 0
#define PROPERTY_MAYBEVOID ::com::sun::star::beans::PropertyAttribute::MAYBEVOID

const SfxItemPropertyMapEntry* lcl_GetDocInfoPropertyMap()
{
    static SfxItemPropertyMapEntry aDocInfoPropertyMap_Impl[] =
    {
        { "Author"          , 6 , WID_FROM,           &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        { "AutoloadEnabled" , 15, MID_DOCINFO_AUTOLOADENABLED, &::getBooleanCppuType(),   PROPERTY_UNBOUND, 0 },
        { "AutoloadSecs"    , 12, MID_DOCINFO_AUTOLOADSECS, &::getCppuType((const sal_Int32*)0),     PROPERTY_UNBOUND, 0 },
        { "AutoloadURL"     , 11, MID_DOCINFO_AUTOLOADURL, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        { "CreationDate"    , 12, WID_DATE_CREATED,   &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
        { "DefaultTarget"   , 13, MID_DOCINFO_DEFAULTTARGET, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        { "Description"     , 11, MID_DOCINFO_DESCRIPTION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        { "DocumentStatistic", 17 , MID_DOCINFO_STATISTIC, &::getCppuType((const uno::Sequence< beans::NamedValue >*)0), PROPERTY_UNBOUND, 0 },
        { "EditingCycles"   , 13, MID_DOCINFO_REVISION, &::getCppuType((const sal_Int16*)0),   PROPERTY_UNBOUND, 0 },
        { "EditingDuration" , 15, MID_DOCINFO_EDITTIME, &::getCppuType((const sal_Int32*)0),   PROPERTY_UNBOUND, 0 },
        { "Generator"       , 9,  SID_APPLICATION, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        { "Keywords"        , 8 , WID_KEYWORDS,       &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        { "Language"        , 8,  MID_DOCINFO_CHARLOCALE, &::getCppuType((const lang::Locale*)0), PROPERTY_UNBOUND, 0 },
        { "MIMEType"        , 8 , WID_CONTENT_TYPE,   &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND | ::com::sun::star::beans::PropertyAttribute::READONLY, 0 },
        { "ModifiedBy"      , 10, MID_DOCINFO_MODIFICATIONAUTHOR, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        { "ModifyDate"      , 10, WID_DATE_MODIFIED,  &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
        { "PrintDate"       , 9 , MID_DOCINFO_PRINTDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
        { "PrintedBy"       , 9 , MID_DOCINFO_PRINTEDBY, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        { "Subject"         , 7 , MID_DOCINFO_SUBJECT, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        { "Template"        , 8 , MID_DOCINFO_TEMPLATE, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        { "TemplateFileName", 16, SID_TEMPLATE_NAME, &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        { "TemplateDate"    , 12, MID_DOCINFO_TEMPLATEDATE, &::getCppuType((const ::com::sun::star::util::DateTime*)0),PROPERTY_MAYBEVOID, 0 },
        { "Title"           , 5 , WID_TITLE,          &::getCppuType((const ::rtl::OUString*)0), PROPERTY_UNBOUND, 0 },
        {0,0,0,0,0,0}
    };
    return aDocInfoPropertyMap_Impl;
}

static sal_uInt16 aDaysInMonth[12] = { 31, 28, 31, 30, 31, 30,
								   31, 31, 30, 31, 30, 31 };

inline sal_uInt16 DaysInMonth( sal_uInt16 nMonth, sal_uInt16 nYear )
{
	if ( nMonth != 2 )
		return aDaysInMonth[nMonth-1];
	else
	{
		if ( (((nYear % 4) == 0) && ((nYear % 100) != 0)) ||
			 ((nYear % 400) == 0) )
			return aDaysInMonth[nMonth-1] + 1;
		else
			return aDaysInMonth[nMonth-1];
	}
}

bool IsValidDateTime( const util::DateTime& rDT )
{
	if ( !rDT.Month || (rDT.Month > 12) )
		return false;
	if ( !rDT.Day || (rDT.Day > DaysInMonth( rDT.Month, rDT.Year )) )
		return false;
	else if ( rDT.Year <= 1582 )
	{
		if ( rDT.Year < 1582 )
			return false;
		else if ( rDT.Month < 10 )
			return false;
		else if ( (rDT.Month == 10) && (rDT.Day < 15) )
			return false;
	}

	return true;
}

struct OUStringHashCode
{
    size_t operator()( const ::rtl::OUString& sString ) const
	{
		return sString.hashCode();
	}
};

struct SfxExtendedItemPropertyMap : public SfxItemPropertyMapEntry
{
    ::com::sun::star::uno::Any aValue;
};

void Copy( const uno::Reference < document::XStandaloneDocumentInfo >& rSource, const uno::Reference < document::XStandaloneDocumentInfo >& rTarget )
{
    try
    {
        uno::Reference< beans::XPropertySet > xSet( rSource, uno::UNO_QUERY );
        uno::Reference< beans::XPropertySet > xTarget( rTarget, uno::UNO_QUERY );
        uno::Reference< beans::XPropertySetInfo > xSetInfo = xSet->getPropertySetInfo();
        uno::Reference< beans::XPropertyContainer > xContainer( rTarget, uno::UNO_QUERY );
        uno::Sequence< beans::Property > lProps = xSetInfo->getProperties();
        const beans::Property* pProps = lProps.getConstArray();
        sal_Int32 c = lProps.getLength();
        sal_Int32 i = 0;
        for (i=0; i<c; ++i)
        {
            uno::Any aValue = xSet->getPropertyValue( pProps[i].Name );
            if ( pProps[i].Attributes & ::com::sun::star::beans::PropertyAttribute::REMOVABLE )
                // QUESTION: DefaultValue?!
                xContainer->addProperty( pProps[i].Name, pProps[i].Attributes, aValue );
            try
            {
                // it is possible that the propertysets from XML and binary files differ; we shouldn't break then
                xTarget->setPropertyValue( pProps[i].Name, aValue );
            }
            catch ( uno::Exception& ) {}
        }

        sal_Int16 nCount = rSource->getUserFieldCount();
        sal_Int16 nSupportedCount = rTarget->getUserFieldCount();
        for ( sal_Int16 nInd = 0; nInd < nCount && nInd < nSupportedCount; nInd++ )
        {
            ::rtl::OUString aPropName = rSource->getUserFieldName( nInd );
            rTarget->setUserFieldName( nInd, aPropName );
            ::rtl::OUString aPropVal = rSource->getUserFieldValue( nInd );
            rTarget->setUserFieldValue( nInd, aPropVal );
        }
    }
    catch ( uno::Exception& ) {}
}

class MixedPropertySetInfo : public ::cppu::WeakImplHelper1< ::com::sun::star::beans::XPropertySetInfo >
{
    private:

        SfxItemPropertyMap  _aPropertyMap;
        ::rtl::OUString* _pUserKeys;
        uno::Reference<beans::XPropertySet> _xUDProps;

    public:

        MixedPropertySetInfo( const SfxItemPropertyMapEntry* pFixProps,
                             ::rtl::OUString* pUserKeys,
                             uno::Reference<beans::XPropertySet> xUDProps);

        virtual ~MixedPropertySetInfo();

        virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties(  ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
        virtual ::sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) throw (::com::sun::star::uno::RuntimeException);
};

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

MixedPropertySetInfo::MixedPropertySetInfo(const SfxItemPropertyMapEntry* pFixProps,
                     ::rtl::OUString* pUserKeys,
                     uno::Reference<beans::XPropertySet> xUDProps)
    : _aPropertyMap( pFixProps )
    , _pUserKeys(pUserKeys)
    , _xUDProps(xUDProps)
{
}

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

MixedPropertySetInfo::~MixedPropertySetInfo()
{
}

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

::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL MixedPropertySetInfo::getProperties()
    throw(::com::sun::star::uno::RuntimeException)
{
    ::comphelper::SequenceAsVector< ::com::sun::star::beans::Property > lProps;

    // copy "fix" props
    //todo: os: this ugly thing should be replaced
    const SfxItemPropertyMapEntry* pFixProp = lcl_GetDocInfoPropertyMap();

    while(pFixProp && pFixProp->pName)
    {
        ::com::sun::star::beans::Property aProp;

        aProp.Name       = ::rtl::OUString::createFromAscii(pFixProp->pName);
        aProp.Handle     = pFixProp->nWID;
        aProp.Type       = *(pFixProp->pType);
        aProp.Attributes = (sal_Int16)(pFixProp->nFlags);

        lProps.push_back(aProp);
        ++pFixProp;
    }

    // copy "dynamic" props

    // NB: this is really ugly:
    // The returned properties must _not_ include the 4 user-defined fields!
    // These are _not_ properties of the XDocumentInfo interface.
    // Some things rely on this, e.g. Copy would break otherwise.
    // This will have interesting consequences if someone expects to insert
    // a property with the same name as an user-defined key, but nobody
    // sane does that.
    uno::Sequence<beans::Property> udProps =
        _xUDProps->getPropertySetInfo()->getProperties();
    for (sal_Int32 i = 0; i < udProps.getLength(); ++i) {
        if (std::find(_pUserKeys, _pUserKeys+FOUR, udProps[i].Name)
            == _pUserKeys+FOUR) {
                // #i100027#: handles from udProps are not valid here
                udProps[i].Handle = -1;
                lProps.push_back(udProps[i]);
        }
    }

    return lProps.getAsConstList();
}

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

::com::sun::star::beans::Property SAL_CALL MixedPropertySetInfo::getPropertyByName(
    const ::rtl::OUString& sName )
    throw(::com::sun::star::beans::UnknownPropertyException,
          ::com::sun::star::uno::RuntimeException          )
{
    ::com::sun::star::beans::Property aProp;

    // search it as "fix" prop
    if( _aPropertyMap.hasPropertyByName( sName ) )
        return _aPropertyMap.getPropertyByName( sName );
    else
    // search it as "dynamic" prop
    return _xUDProps->getPropertySetInfo()->getPropertyByName(sName);
}

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

::sal_Bool SAL_CALL MixedPropertySetInfo::hasPropertyByName(const ::rtl::OUString& sName)
    throw(::com::sun::star::uno::RuntimeException)
{
    return _aPropertyMap.hasPropertyByName( sName ) ? // "fix" prop?
        sal_True :
        _xUDProps->getPropertySetInfo()->hasPropertyByName(sName); // "dynamic" prop?
}

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

struct SfxDocumentInfoObject_Impl
{
	::osl::Mutex						_aMutex;
	::cppu::OInterfaceContainerHelper	_aDisposeContainer;

    sal_Bool            bDisposed;

    // this contains the names of the 4 user defined properties
    // which are accessible via the evil XDocumentInfo interface
    ::rtl::OUString m_UserDefined[FOUR];

    // the actual contents
    uno::Reference<document::XDocumentProperties> m_xDocProps;
    SfxItemPropertyMap      m_aPropertyMap;

    SfxDocumentInfoObject_Impl()
        : _aDisposeContainer( _aMutex )
        , bDisposed(sal_False)
        , m_xDocProps()
        , m_aPropertyMap( lcl_GetDocInfoPropertyMap() )
	{
        // the number of user fields is not changeable from the outside
        // we can't set it too high because every name/value pair will be written to the file (even if empty)
        // currently our dialog has only 4 user keys so 4 is still a reasonable number
	}

    /// the initialization function
    void Reset(uno::Reference<document::XDocumentProperties> xDocProps, ::rtl::OUString* pUserDefined = 0);
};

void SfxDocumentInfoObject_Impl::Reset(uno::Reference<document::XDocumentProperties> xDocProps, ::rtl::OUString* pUserDefined)
{
    if (pUserDefined == 0) {
        // NB: this is an ugly hack; the "Properties" ui dialog displays
        //     exactly 4 user-defined fields and expects these to be available
        //     (should be redesigned), but I do not want to do this in
        //     DocumentProperties; do it here instead
        uno::Reference<beans::XPropertyAccess> xPropAccess(
            xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
        uno::Reference<beans::XPropertyContainer> xPropContainer(
            xPropAccess, uno::UNO_QUERY_THROW);
        uno::Sequence< beans::PropertyValue >
            props = xPropAccess->getPropertyValues();
        sal_Int32 oldLength = props.getLength();
        if (oldLength < FOUR) {
            std::vector< ::rtl::OUString > names;
            for (sal_Int32 i = 0; i < oldLength; ++i) {
                names.push_back(props[i].Name);
            }
            const ::rtl::OUString sInfo(
                        String( SfxResId( STR_DOCINFO_INFOFIELD ) ));
            for (sal_Int32 i = oldLength; i < FOUR; ++i) {
                ::rtl::OUString sName(sInfo);
                sal_Int32 idx = sName.indexOfAsciiL("%1", 2);
                ::rtl::OUString name = (idx > 0)
                    ? sName.replaceAt(idx, 2, ::rtl::OUString::valueOf(i+1))
                    : sName + ::rtl::OUString::valueOf(i+1);
                while (std::find(names.begin(), names.end(), name)
                       != names.end()) {
                    name += ::rtl::OUString::createFromAscii("'");
                }
                // FIXME there is a race condition here
                try {
                    xPropContainer->addProperty(name,
                        beans::PropertyAttribute::REMOVEABLE,
                        uno::makeAny(::rtl::OUString::createFromAscii("")));
                } catch (uno::RuntimeException) {
                    throw;
                } catch (uno::Exception) {
                    // ignore
                }
            }
        }
        props = xPropAccess->getPropertyValues();
        for (sal_Int32 i = 0; i < FOUR; ++i) {
            m_UserDefined[i] = props[i].Name;
        }
    } else {
        std::copy(pUserDefined, pUserDefined+FOUR, m_UserDefined);
    }
    m_xDocProps = xDocProps;
}

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

SfxDocumentInfoObject::SfxDocumentInfoObject()
    : _pImp( new SfxDocumentInfoObject_Impl() )
{
}

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

SfxDocumentInfoObject::~SfxDocumentInfoObject()
{
	delete _pImp;
}

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

// ::com::sun::star::lang::XInitialization:
void SAL_CALL
SfxDocumentInfoObject::initialize(const uno::Sequence< uno::Any > & aArguments)
    throw (uno::RuntimeException, uno::Exception)
{
    if (aArguments.getLength() >= 1) {
        uno::Any any = aArguments[0];
        uno::Reference<document::XDocumentProperties> xDoc;
        if (!(any >>= xDoc) || !xDoc.is()) throw lang::IllegalArgumentException(
            ::rtl::OUString::createFromAscii(
                "SfxDocumentInfoObject::initialize: no XDocumentProperties given"),
                *this, 0);
        _pImp->Reset(xDoc);
    } else {
        throw lang::IllegalArgumentException(
            ::rtl::OUString::createFromAscii(
                "SfxDocumentInfoObject::initialize: no argument given"),
                *this, 0);
    }
}

// ::com::sun::star::util::XCloneable:
uno::Reference<util::XCloneable> SAL_CALL
SfxDocumentInfoObject::createClone() throw (uno::RuntimeException)
{
    SfxDocumentInfoObject *pNew = new SfxDocumentInfoObject;
    uno::Reference< util::XCloneable >
        xCloneable(_pImp->m_xDocProps, uno::UNO_QUERY_THROW);
    uno::Reference<document::XDocumentProperties> xDocProps(
        xCloneable->createClone(), uno::UNO_QUERY_THROW);
    pNew->_pImp->Reset(xDocProps, _pImp->m_UserDefined);
    return pNew;
}

// ::com::sun::star::document::XDocumentProperties:
uno::Reference< document::XDocumentProperties > SAL_CALL
SfxDocumentInfoObject::getDocumentProperties()
    throw(::com::sun::star::uno::RuntimeException)
{
    return _pImp->m_xDocProps;
}

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

const SfxDocumentInfoObject& SfxDocumentInfoObject::operator=( const SfxDocumentInfoObject & rOther)
{
    uno::Reference< util::XCloneable >
        xCloneable(rOther._pImp->m_xDocProps, uno::UNO_QUERY_THROW);
    uno::Reference<document::XDocumentProperties> xDocProps(
        xCloneable->createClone(), uno::UNO_QUERY_THROW);
    _pImp->Reset(xDocProps, rOther._pImp->m_UserDefined);
    return *this;
}

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

void SAL_CALL SfxDocumentInfoObject::dispose() throw( ::com::sun::star::uno::RuntimeException )
{
	::com::sun::star::lang::EventObject aEvent( (::cppu::OWeakObject *)this );
	_pImp->_aDisposeContainer.disposeAndClear( aEvent );
	::osl::MutexGuard aGuard( _pImp->_aMutex );
    _pImp->m_xDocProps = 0;
    // NB: do not call m_xDocProps->dispose(), there could be other refs
    _pImp->bDisposed = sal_True;
}

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

void SAL_CALL  SfxDocumentInfoObject::addEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException )
{
	_pImp->_aDisposeContainer.addInterface( aListener );
}

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

void SAL_CALL  SfxDocumentInfoObject::removeEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException )
{
	_pImp->_aDisposeContainer.removeInterface( aListener );
}
//-----------------------------------------------------------------------------

::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >  SAL_CALL  SfxDocumentInfoObject::getPropertySetInfo()  throw( ::com::sun::star::uno::RuntimeException )
{
    ::osl::MutexGuard aGuard( _pImp->_aMutex );

    uno::Reference<beans::XPropertySet> xPropSet(
        _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
    MixedPropertySetInfo* pInfo = new MixedPropertySetInfo( lcl_GetDocInfoPropertyMap(), _pImp->m_UserDefined, xPropSet);
    uno::Reference< beans::XPropertySetInfo > xInfo(
        static_cast< beans::XPropertySetInfo* >(pInfo), uno::UNO_QUERY_THROW);
    return xInfo;
}

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

void SAL_CALL  SfxDocumentInfoObject::setPropertyValue(const ::rtl::OUString& aPropertyName, const uno::Any& aValue) throw (
        uno::RuntimeException, beans::UnknownPropertyException,
        beans::PropertyVetoException, lang::IllegalArgumentException,
        lang::WrappedTargetException)
{
    const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName );
    // fix prop!
    if ( pEntry )
        setFastPropertyValue( pEntry->nWID, aValue );
    else
    // dynamic prop!
    {
        uno::Reference<beans::XPropertySet> xPropSet(
            _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
        return xPropSet->setPropertyValue(aPropertyName, aValue);
    }
}

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

uno::Any  SAL_CALL  SfxDocumentInfoObject::getPropertyValue(const ::rtl::OUString& aPropertyName)  throw(
        uno::RuntimeException, beans::UnknownPropertyException,
        lang::WrappedTargetException)
{
    const SfxItemPropertySimpleEntry* pEntry = _pImp->m_aPropertyMap.getByName( aPropertyName );
    // fix prop!
    if ( pEntry )
        return getFastPropertyValue( pEntry->nWID );
	else
    // dynamic prop!
    {
        uno::Reference<beans::XPropertySet> xPropSet(
            _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
        return xPropSet->getPropertyValue(aPropertyName);
    }
}

sal_Bool SAL_CALL SfxDocumentInfoObject::isModified() throw(::com::sun::star::uno::RuntimeException)
{
    uno::Reference<util::XModifiable> xModif(
            _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
    return xModif->isModified();
}

void SAL_CALL SfxDocumentInfoObject::setModified( sal_Bool bModified )
        throw (::com::sun::star::beans::PropertyVetoException, ::com::sun::star::uno::RuntimeException)
{
    uno::Reference<util::XModifiable> xModif(
            _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
    return xModif->setModified(bModified);
}

void SAL_CALL SfxDocumentInfoObject::addModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException )
{
    uno::Reference<util::XModifiable> xModif(
            _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
    return xModif->addModifyListener(xListener);
}

void SAL_CALL SfxDocumentInfoObject::removeModifyListener( const uno::Reference< util::XModifyListener >& xListener) throw( uno::RuntimeException )
{
    uno::Reference<util::XModifiable> xModif(
            _pImp->m_xDocProps, uno::UNO_QUERY_THROW);
    return xModif->removeModifyListener(xListener);
}

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

void SAL_CALL  SfxDocumentInfoObject::addPropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw(
        uno::RuntimeException, beans::UnknownPropertyException,
        lang::WrappedTargetException)
{}

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

void SAL_CALL  SfxDocumentInfoObject::removePropertyChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XPropertyChangeListener > & ) throw(
        uno::RuntimeException, beans::UnknownPropertyException,
        lang::WrappedTargetException)
{}

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

void SAL_CALL  SfxDocumentInfoObject::addVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw(
        uno::RuntimeException, beans::UnknownPropertyException,
        lang::WrappedTargetException)
{}

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

void SAL_CALL  SfxDocumentInfoObject::removeVetoableChangeListener(const ::rtl::OUString&, const uno::Reference< beans::XVetoableChangeListener > & ) throw(
        uno::RuntimeException, beans::UnknownPropertyException,
        lang::WrappedTargetException)
{}

uno::Sequence< beans::PropertyValue > SAL_CALL  SfxDocumentInfoObject::getPropertyValues( void ) throw( uno::RuntimeException )
{
	::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo >  xInfo = getPropertySetInfo();
	::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > aProps = xInfo->getProperties();

	const ::com::sun::star::beans::Property* pProps  = aProps.getConstArray();
	sal_uInt32 nCount = aProps.getLength();

	::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >aSeq( nCount );
	::com::sun::star::beans::PropertyValue*  pValues = aSeq.getArray();

	for ( sal_uInt32 n = 0; n < nCount; ++n )
	{
		::com::sun::star::beans::PropertyValue& rCurrValue = pValues[n];
		const ::com::sun::star::beans::Property& rCurrProp = pProps[n];

		rCurrValue.Name = rCurrProp.Name;
		rCurrValue.Handle = rCurrProp.Handle;
		rCurrValue.Value = getPropertyValue( rCurrProp.Name );
	}

	return aSeq;
}

void SAL_CALL  SfxDocumentInfoObject::setPropertyValues( const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& aProps )
        throw( ::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException )
{
	const ::com::sun::star::beans::PropertyValue* pProps  = aProps.getConstArray();
	sal_uInt32 nCount = aProps.getLength();

	for ( sal_uInt32 n = 0; n < nCount; ++n )
	{
		const ::com::sun::star::beans::PropertyValue& rProp = pProps[n];
		setPropertyValue( rProp.Name, rProp.Value );
	}
}

void SAL_CALL SfxDocumentInfoObject::addProperty(const ::rtl::OUString&            sName        ,
                                                       sal_Int16                   nAttributes  ,
                                                 const ::com::sun::star::uno::Any& aDefaultValue)
    throw(::com::sun::star::beans::PropertyExistException ,
          ::com::sun::star::beans::IllegalTypeException   ,
          ::com::sun::star::lang::IllegalArgumentException,
          ::com::sun::star::uno::RuntimeException         )
{
    // clash with "fix" properties ?
    sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0;
    if ( bFixProp )
    {
        ::rtl::OUStringBuffer sMsg(256);
        sMsg.appendAscii("The property \""   );
        sMsg.append     (sName               );
        sMsg.appendAscii("\" "               );
        if ( bFixProp )
            sMsg.appendAscii(" already exists as a fix property. Please have a look into the IDL documentation of the DocumentInfo service.");

        throw ::com::sun::star::beans::PropertyExistException(
                sMsg.makeStringAndClear(),
                static_cast< ::cppu::OWeakObject* >(this));
    }

    uno::Reference<beans::XPropertyContainer> xPropSet(
        _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
    return xPropSet->addProperty(sName, nAttributes, aDefaultValue);
}

void SAL_CALL SfxDocumentInfoObject::removeProperty(const ::rtl::OUString& sName)
    throw(::com::sun::star::beans::UnknownPropertyException,
          ::com::sun::star::beans::NotRemoveableException  ,
          ::com::sun::star::uno::RuntimeException          )
{
    // clash with "fix" properties ?
    sal_Bool bFixProp = _pImp->m_aPropertyMap.getByName( sName ) != 0;
    if ( bFixProp )
    {
        ::rtl::OUStringBuffer sMsg(256);
        sMsg.appendAscii("The property \""                                                    );
        sMsg.append     (sName                                                                );
        sMsg.appendAscii("\" can't be removed. Its a fix property of the DocumentInfo service.");

        throw ::com::sun::star::beans::NotRemoveableException(
                sMsg.makeStringAndClear(),
                static_cast< ::cppu::OWeakObject* >(this));
    }

    uno::Reference<beans::XPropertyContainer> xPropSet(
        _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
    return xPropSet->removeProperty(sName);
}

sal_Bool equalsDateTime( const util::DateTime& D1, const util::DateTime& D2 )
{
    return D1.HundredthSeconds == D2.HundredthSeconds &&
           D1.Seconds == D2.Seconds &&
           D1.Minutes == D2.Minutes &&
           D1.Hours == D2.Hours &&
           D1.Day == D2.Day &&
           D1.Month == D2.Month &&
           D1.Year == D2.Year;
}

void SAL_CALL  SfxDocumentInfoObject::setFastPropertyValue(sal_Int32 nHandle, const ::com::sun::star::uno::Any& aValue) throw(
        uno::RuntimeException, beans::UnknownPropertyException,
        beans::PropertyVetoException, lang::IllegalArgumentException,
        lang::WrappedTargetException)
{
    // Attention: Only fix properties should be provided by this method.
    // Dynamic properties has no handle in real ... because it can't be used inside multithreaded environments :-)

    ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );

    if ( aValue.getValueType() == ::getCppuType((const ::rtl::OUString*)0) )
	{
		::rtl::OUString sTemp ;
		aValue >>= sTemp ;
		switch ( nHandle )
		{
            case SID_APPLICATION :
                _pImp->m_xDocProps->setGenerator(sTemp);
                break;
			case WID_FROM :
			{
                // QUESTION: do we still need this?
                /*
                // String aStrVal( sTemp );
				if ( aStrVal.Len() > TIMESTAMP_MAXLENGTH )
				{
					SvAddressParser aParser( aStrVal );
					if ( aParser.Count() > 0 )
					{
						String aEmail = aParser.GetEmailAddress(0);
						String aRealname = aParser.GetRealName(0);

						if ( aRealname.Len() <= TIMESTAMP_MAXLENGTH )
							aStrVal = aRealname;
						else if ( aEmail.Len() <= TIMESTAMP_MAXLENGTH )
							aStrVal = aEmail;
					}
                } */

                if ( _pImp->m_xDocProps->getAuthor() != sTemp )
                    _pImp->m_xDocProps->setAuthor(sTemp);
				break;
			}
            case MID_DOCINFO_PRINTEDBY:
                if ( _pImp->m_xDocProps->getPrintedBy() != sTemp )
                    _pImp->m_xDocProps->setPrintedBy(sTemp);
                break;
			case MID_DOCINFO_MODIFICATIONAUTHOR:
                if ( _pImp->m_xDocProps->getModifiedBy() != sTemp )
                    _pImp->m_xDocProps->setModifiedBy(sTemp);
				break;
			case WID_TITLE :
            {
                if ( _pImp->m_xDocProps->getTitle() != sTemp )
                    _pImp->m_xDocProps->setTitle(sTemp);
				break;
            }
			case MID_DOCINFO_SUBJECT :
                if ( _pImp->m_xDocProps->getSubject() != sTemp )
                    _pImp->m_xDocProps->setSubject(sTemp);
				break;
			case WID_KEYWORDS :
                {
                    _pImp->m_xDocProps->setKeywords(
                        ::comphelper::string::convertCommaSeparated(sTemp));
                }
				break;
			case MID_DOCINFO_TEMPLATE:
                if ( _pImp->m_xDocProps->getTemplateName() != sTemp )
                    _pImp->m_xDocProps->setTemplateName(sTemp);
				break;
			case SID_TEMPLATE_NAME:
                if ( _pImp->m_xDocProps->getTemplateURL() != sTemp )
                    _pImp->m_xDocProps->setTemplateURL(sTemp);
				break;
			case MID_DOCINFO_DESCRIPTION:
                if ( _pImp->m_xDocProps->getDescription() != sTemp )
                    _pImp->m_xDocProps->setDescription(sTemp);
				break;
			case MID_DOCINFO_AUTOLOADURL:
                if ( _pImp->m_xDocProps->getAutoloadURL() != sTemp )
                    _pImp->m_xDocProps->setAutoloadURL(sTemp);
				break;
			case MID_DOCINFO_DEFAULTTARGET:
                if ( _pImp->m_xDocProps->getDefaultTarget() != sTemp )
                    _pImp->m_xDocProps->setDefaultTarget(sTemp);
				break;
//            case WID_CONTENT_TYPE : // this is readonly!
			default:
				break;
		}
	}
    else if ( aValue.getValueType() == ::getCppuType((const ::com::sun::star::util::DateTime*)0) )
	{
        com::sun::star::util::DateTime aTemp;
        aValue >>= aTemp ;
		switch ( nHandle )
		{
			case WID_DATE_CREATED :
			{
                if ( !equalsDateTime(_pImp->m_xDocProps->getCreationDate(), aTemp ) )
				{
					_pImp->m_xDocProps->setCreationDate(aTemp);
				}
				break;
			}
			case WID_DATE_MODIFIED :
			{
                if ( !equalsDateTime(_pImp->m_xDocProps->getModificationDate(), aTemp ) )
				{
					_pImp->m_xDocProps->setModificationDate(aTemp);
				}
				break;
			}
            case MID_DOCINFO_PRINTDATE :
			{
                if ( !equalsDateTime(_pImp->m_xDocProps->getPrintDate(), aTemp ) )
				{
					_pImp->m_xDocProps->setPrintDate(aTemp);
				}
				break;
			}
            case MID_DOCINFO_TEMPLATEDATE :
			{
                if ( !equalsDateTime(_pImp->m_xDocProps->getTemplateDate(), aTemp ) )
				{
					_pImp->m_xDocProps->setTemplateDate(aTemp);
				}
				break;
			}
			default:
				break;
		}
	}

    else if ( aValue.getValueType() == ::getBooleanCppuType() )
	{
		sal_Bool bBoolVal = false;
		aValue >>= bBoolVal ;
		switch ( nHandle )
		{
			case MID_DOCINFO_AUTOLOADENABLED:
                // NB: this property does not exist any more
                //     it is emulated as enabled iff delay > 0
                if ( bBoolVal && (0 == _pImp->m_xDocProps->getAutoloadSecs()) ) {
                    _pImp->m_xDocProps->setAutoloadSecs(60); // default
                } else if ( !bBoolVal && (0 != _pImp->m_xDocProps->getAutoloadSecs()) ) {
                    _pImp->m_xDocProps->setAutoloadSecs(0);
                    _pImp->m_xDocProps->setAutoloadURL(::rtl::OUString::createFromAscii(""));
                }
				break;
			default:
				break;
		}
	}
    else if ( aValue.getValueType() == ::getCppuType((const sal_Int32*)0) )
	{
		sal_Int32 nIntVal = 0;
		aValue >>= nIntVal ;
		switch ( nHandle )
		{
			case MID_DOCINFO_AUTOLOADSECS:
                if ( nIntVal != _pImp->m_xDocProps->getAutoloadSecs())
                    _pImp->m_xDocProps->setAutoloadSecs(nIntVal);
				break;
			case MID_DOCINFO_EDITTIME:
                if ( nIntVal != _pImp->m_xDocProps->getEditingDuration())
                    _pImp->m_xDocProps->setEditingDuration(nIntVal);
				break;
			default:
				break;
		}
	}
    else if ( aValue.getValueType() == ::getCppuType((const sal_Int16*)0) )
	{
		short nIntVal = 0;
		aValue >>= nIntVal ;
		switch ( nHandle )
		{
            case MID_DOCINFO_REVISION:
                if ( nIntVal != _pImp->m_xDocProps->getEditingCycles())
                    _pImp->m_xDocProps->setEditingCycles(nIntVal);
				break;
			default:
				break;
		}
	}
	else if ( aValue.getValueType() == ::getCppuType((const uno::Sequence< beans::NamedValue >*)0) )
	{
        if ( nHandle == MID_DOCINFO_STATISTIC )
		{
            uno::Sequence < beans::NamedValue > aData;
            aValue >>= aData;
            {
                _pImp->m_xDocProps->setDocumentStatistics(aData);
            }
		}
	}
	else if ( aValue.getValueType() == ::getCppuType((const lang::Locale*)0) )
	{
        if ( nHandle == MID_DOCINFO_CHARLOCALE )
		{
            lang::Locale aLocale;
            aValue >>= aLocale;
            lang::Locale oldLocale = _pImp->m_xDocProps->getLanguage();
            if ( aLocale.Language != oldLocale.Language ||
                 aLocale.Country  != oldLocale.Country  ||
                 aLocale.Variant  != oldLocale.Variant   )
			{
				_pImp->m_xDocProps->setLanguage(aLocale);
			}
		}
	}
}

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

::com::sun::star::uno::Any SAL_CALL  SfxDocumentInfoObject::getFastPropertyValue(sal_Int32 nHandle) throw(
        uno::RuntimeException, beans::UnknownPropertyException,
        lang::WrappedTargetException)
{
    // Attention: Only fix properties should be provided by this method.
    // Dynamic properties has no handle in real ... because it can't be used inside multithreaded environments :-)

    ::osl::MutexGuard aGuard( _pImp->_aMutex );
	::com::sun::star::uno::Any aValue;
    switch ( nHandle )
    {
        case SID_APPLICATION :
            aValue <<= _pImp->m_xDocProps->getGenerator();
            break;
        case WID_CONTENT_TYPE :
// FIXME this is not available anymore
            aValue <<= ::rtl::OUString();
            break;
        case MID_DOCINFO_REVISION :
            aValue <<= _pImp->m_xDocProps->getEditingCycles();
            break;
        case MID_DOCINFO_EDITTIME :
            aValue <<= _pImp->m_xDocProps->getEditingDuration();
            break;
        case WID_FROM :
			aValue <<= _pImp->m_xDocProps->getAuthor();
            break;
        case WID_DATE_CREATED :
            if ( IsValidDateTime( _pImp->m_xDocProps->getCreationDate() ) )
	            aValue <<= _pImp->m_xDocProps->getCreationDate();
            break;
        case WID_TITLE :
            aValue <<= _pImp->m_xDocProps->getTitle();
            break;
        case MID_DOCINFO_SUBJECT:
            aValue <<= _pImp->m_xDocProps->getSubject();
            break;
        case MID_DOCINFO_MODIFICATIONAUTHOR:
            aValue <<= _pImp->m_xDocProps->getModifiedBy();
            break;
        case WID_DATE_MODIFIED :
            if ( IsValidDateTime( _pImp->m_xDocProps->getModificationDate() ) )
	            aValue <<= _pImp->m_xDocProps->getModificationDate();
            break;
        case MID_DOCINFO_PRINTEDBY:
            aValue <<= _pImp->m_xDocProps->getPrintedBy();
            break;
        case MID_DOCINFO_PRINTDATE:
            if ( IsValidDateTime( _pImp->m_xDocProps->getPrintDate() ) )
	            aValue <<= _pImp->m_xDocProps->getPrintDate();
            break;
        case WID_KEYWORDS :
            aValue <<= ::comphelper::string::convertCommaSeparated(
                _pImp->m_xDocProps->getKeywords());
            break;
        case MID_DOCINFO_DESCRIPTION:
            aValue <<= _pImp->m_xDocProps->getDescription();
            break;
        case MID_DOCINFO_TEMPLATE:
            aValue <<= _pImp->m_xDocProps->getTemplateName();
            break;
        case SID_TEMPLATE_NAME:
            aValue <<= _pImp->m_xDocProps->getTemplateURL();
            break;
        case MID_DOCINFO_TEMPLATEDATE:
            if ( IsValidDateTime( _pImp->m_xDocProps->getTemplateDate() ) )
				aValue <<= _pImp->m_xDocProps->getTemplateDate();
            break;
        case MID_DOCINFO_AUTOLOADENABLED:
            aValue <<= static_cast<sal_Bool>
                        (   (_pImp->m_xDocProps->getAutoloadSecs() != 0)
                        || !(_pImp->m_xDocProps->getAutoloadURL().equalsAscii("")));
            break;
        case MID_DOCINFO_AUTOLOADURL:
            aValue <<= _pImp->m_xDocProps->getAutoloadURL();
            break;
        case MID_DOCINFO_AUTOLOADSECS:
            aValue <<= _pImp->m_xDocProps->getAutoloadSecs();
            break;
        case MID_DOCINFO_DEFAULTTARGET:
            aValue <<= _pImp->m_xDocProps->getDefaultTarget();
            break;
        case MID_DOCINFO_STATISTIC:
            aValue <<= _pImp->m_xDocProps->getDocumentStatistics();
            break;
        case MID_DOCINFO_CHARLOCALE:
            aValue <<= _pImp->m_xDocProps->getLanguage();
            break;
        default:
            aValue <<= ::rtl::OUString();
            break;
    }

	return aValue;
}

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

sal_Int16 SAL_CALL  SfxDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException )
{
//    uno::Reference<beans::XPropertyAccess> xPropSet(
//        _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
//    return xPropSet->getPropertyValues().getLength();
    return FOUR;
}

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

::rtl::OUString SAL_CALL  SfxDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
{
    ::osl::MutexGuard aGuard( _pImp->_aMutex );
    if (nIndex < FOUR)
        return _pImp->m_UserDefined[nIndex];
	else
		return ::rtl::OUString();
}

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

::rtl::OUString SAL_CALL  SfxDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
{
    ::osl::MutexGuard aGuard( _pImp->_aMutex );
    if (nIndex < FOUR) {
        ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
        uno::Reference<beans::XPropertySet> xPropSet(
            _pImp->m_xDocProps->getUserDefinedProperties(), uno::UNO_QUERY_THROW);
        ::rtl::OUString val;
        try {
            xPropSet->getPropertyValue(name) >>= val;
            return val;
        } catch (uno::RuntimeException &) {
            throw;
        } catch (uno::Exception &) {
            return ::rtl::OUString(); // ignore
        }
    } else
		return ::rtl::OUString();
}

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

void  SAL_CALL SfxDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException )
{
    ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
    if (nIndex < FOUR) // yes, four!
    {
        // FIXME this is full of race conditions because the PropertyBag
        // can be accessed from clients of the DocumentProperties!
        ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
        if (name != aName) {
            uno::Reference<beans::XPropertySet> xPropSet(
                _pImp->m_xDocProps->getUserDefinedProperties(),
                uno::UNO_QUERY_THROW);
            uno::Reference<beans::XPropertyContainer> xPropContainer(
                _pImp->m_xDocProps->getUserDefinedProperties(),
                uno::UNO_QUERY_THROW);
            uno::Any value;
            try {
                value = xPropSet->getPropertyValue(name);
                xPropContainer->removeProperty(name);
                xPropContainer->addProperty(aName,
                    beans::PropertyAttribute::REMOVEABLE, value);
                _pImp->m_UserDefined[nIndex] = aName;
            } catch (beans::UnknownPropertyException) {
                try {
                    xPropContainer->addProperty(aName,
                        beans::PropertyAttribute::REMOVEABLE,
                        uno::makeAny(::rtl::OUString::createFromAscii("")));
                    _pImp->m_UserDefined[nIndex] = aName;
                } catch (beans::PropertyExistException) {
                    _pImp->m_UserDefined[nIndex] = aName;
                    // ignore
                }
            } catch (beans::PropertyExistException) {
                try {
                    xPropContainer->addProperty(name,
                        beans::PropertyAttribute::REMOVEABLE, value);
                } catch (beans::PropertyExistException) {
                    // bugger...
                }
            } catch (uno::RuntimeException &) {
                throw;
            } catch (uno::Exception &) {
                // ignore everything else; xPropSet _may_ be corrupted
            }
		}
    }
}

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

void SAL_CALL  SfxDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException )
{
    ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
    if (nIndex < FOUR) // yes, four!
    {
        ::rtl::OUString name = _pImp->m_UserDefined[nIndex];
        uno::Reference<beans::XPropertySet> xPropSet(
            _pImp->m_xDocProps->getUserDefinedProperties(),
            uno::UNO_QUERY_THROW);
        uno::Reference<beans::XPropertyContainer> xPropContainer(
            _pImp->m_xDocProps->getUserDefinedProperties(),
            uno::UNO_QUERY_THROW);
        uno::Any aAny;
        aAny <<= aValue;
        try {
            uno::Any value = xPropSet->getPropertyValue(name);
            if (value != aAny) {
                xPropSet->setPropertyValue(name, aAny);
            }
        } catch (beans::UnknownPropertyException) {
            try {
                // someone removed it, add it back again
                xPropContainer->addProperty(name,
                    beans::PropertyAttribute::REMOVEABLE, aAny);
            } catch (uno::RuntimeException &) {
                throw;
            } catch (uno::Exception &) {
                // ignore everything else
            }
        } catch (uno::RuntimeException &) {
            throw;
        } catch (uno::Exception &) {
            // ignore everything else
        }
    }
}

//-----------------------------------------------------------------------------
SFX_IMPL_XINTERFACE_2( SfxStandaloneDocumentInfoObject, SfxDocumentInfoObject, ::com::sun::star::lang::XServiceInfo, ::com::sun::star::document::XStandaloneDocumentInfo  )
SFX_IMPL_XTYPEPROVIDER_10( SfxStandaloneDocumentInfoObject, ::com::sun::star::document::XDocumentInfo, ::com::sun::star::lang::XComponent,
    ::com::sun::star::beans::XPropertySet, ::com::sun::star::beans::XFastPropertySet, ::com::sun::star::beans::XPropertyAccess,
    ::com::sun::star::beans::XPropertyContainer, ::com::sun::star::util::XModifiable, ::com::sun::star::util::XModifyBroadcaster,
    ::com::sun::star::document::XStandaloneDocumentInfo, ::com::sun::star::lang::XServiceInfo )

SFX_IMPL_XSERVICEINFO( SfxStandaloneDocumentInfoObject, "com.sun.star.document.StandaloneDocumentInfo", "com.sun.star.comp.sfx2.StandaloneDocumentInfo" )
SFX_IMPL_SINGLEFACTORY( SfxStandaloneDocumentInfoObject )

SfxStandaloneDocumentInfoObject::SfxStandaloneDocumentInfoObject( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xFactory )
    : SfxDocumentInfoObject()
    , _xFactory( xFactory )
{
    uno::Reference< lang::XInitialization > xDocProps(
        _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
            "com.sun.star.document.DocumentProperties"))), uno::UNO_QUERY_THROW);
//    xDocProps->initialize(uno::Sequence<uno::Any>());
    uno::Any a;
    a <<= xDocProps;
    uno::Sequence<uno::Any> args(1);
    args[0] = a;
    initialize(args);
}

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

SfxStandaloneDocumentInfoObject::~SfxStandaloneDocumentInfoObject()
{
}

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

uno::Reference< embed::XStorage > GetStorage_Impl( const ::rtl::OUString& rName, sal_Bool bWrite, uno::Reference < lang::XMultiServiceFactory >& xFactory )
{
    // catch unexpected exceptions under solaris
    // Client code checks the returned reference but is not interested on error details.
    try
    {
		::vos::OGuard aSolarGuard( Application::GetSolarMutex() );
        return ::comphelper::OStorageHelper::GetStorageFromURL(
						rName,
						bWrite ? embed::ElementModes::READWRITE : embed::ElementModes::READ,
                        xFactory );
    }
    catch(const uno::Exception&)
    {}

    return uno::Reference< embed::XStorage >();
}

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

sal_Int16 SAL_CALL SfxStandaloneDocumentInfoObject::getUserFieldCount() throw( ::com::sun::star::uno::RuntimeException )
{
	return SfxDocumentInfoObject::getUserFieldCount();
}

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

::rtl::OUString SAL_CALL  SfxStandaloneDocumentInfoObject::getUserFieldName(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
{
	return SfxDocumentInfoObject::getUserFieldName(nIndex);
}

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

::rtl::OUString SAL_CALL  SfxStandaloneDocumentInfoObject::getUserFieldValue(sal_Int16 nIndex) throw( ::com::sun::star::uno::RuntimeException )
{
	return SfxDocumentInfoObject::getUserFieldValue(nIndex);
}

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

void  SAL_CALL SfxStandaloneDocumentInfoObject::setUserFieldName(sal_Int16 nIndex, const ::rtl::OUString& aName ) throw( ::com::sun::star::uno::RuntimeException )
{
	SfxDocumentInfoObject::setUserFieldName( nIndex, aName );
}

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

void SAL_CALL  SfxStandaloneDocumentInfoObject::setUserFieldValue( sal_Int16 nIndex, const ::rtl::OUString& aValue ) throw( ::com::sun::star::uno::RuntimeException )
{
	SfxDocumentInfoObject::setUserFieldValue( nIndex, aValue );
}

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

void SAL_CALL  SfxStandaloneDocumentInfoObject::loadFromURL(const ::rtl::OUString& aURL)
	throw( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException )
{
	sal_Bool bOK = sal_False;

    ::osl::ClearableMutexGuard aGuard( _pImp->_aMutex );
    uno::Reference< document::XDocumentProperties > xDocProps(
        _xFactory->createInstance( ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
            "com.sun.star.document.DocumentProperties"))), uno::UNO_QUERY_THROW);
//    uno::Reference< lang::XInitialization > xInit(xDocProps, uno::UNO_QUERY_THROW);
//    xInit->initialize(uno::Sequence<uno::Any>());
    _pImp->Reset(xDocProps);
	aGuard.clear();

    uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_False, _xFactory );
    if ( xStorage.is() )
	{
		try
		{
            uno::Sequence<beans::PropertyValue> medium(2);
            medium[0].Name = ::rtl::OUString::createFromAscii("DocumentBaseURL");
            medium[0].Value <<= aURL;
            medium[1].Name = ::rtl::OUString::createFromAscii("URL");
            medium[1].Value <<= aURL;
            _pImp->m_xDocProps->loadFromStorage(xStorage, medium);
            _pImp->Reset(_pImp->m_xDocProps);
            bOK = sal_True;
		}
		catch( uno::Exception& )
		{
		}
    }
	else
	{
        uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance(
            ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStandaloneDocumentInfo" ) ) ), uno::UNO_QUERY );
        if ( xBinary.is() )
        {
            xBinary->loadFromURL( aURL );
            bOK = sal_True;
            uno::Reference < document::XStandaloneDocumentInfo > xTarget( static_cast < document::XStandaloneDocumentInfo*> (this), uno::UNO_QUERY );
            Copy( xBinary, xTarget );
        }
	}

	if ( !bOK )
		throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTREAD );
}

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

void SAL_CALL  SfxStandaloneDocumentInfoObject::storeIntoURL(const ::rtl::OUString& aURL) throw( ::com::sun::star::io::IOException )
{
	sal_Bool bOK = sal_False;
    uno::Reference< embed::XStorage > xStorage = GetStorage_Impl( aURL, sal_True, _xFactory );
	if ( xStorage.is() )
	{
		try
		{
            uno::Sequence<beans::PropertyValue> medium(2);
            medium[0].Name = ::rtl::OUString::createFromAscii("DocumentBaseURL");
            medium[0].Value <<= aURL;
            medium[1].Name = ::rtl::OUString::createFromAscii("URL");
            medium[1].Value <<= aURL;

            _pImp->m_xDocProps->storeToStorage(xStorage, medium);
            bOK = sal_True;
		}
		catch( io::IOException & )
		{
			throw;
		}
		catch( uno::RuntimeException& )
		{
			throw;
		}
		catch( uno::Exception& )
		{
		}
	}
	else
	{
        uno::Reference < document::XStandaloneDocumentInfo > xBinary( _xFactory->createInstance(
			::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.document.BinaryStandaloneDocumentInfo" ) ) ), uno::UNO_QUERY );
        if ( xBinary.is() )
        {
            Copy( this, xBinary );
            xBinary->storeIntoURL( aURL );
            bOK = sal_True;
        }
	}

	if ( !bOK )
		throw task::ErrorCodeIOException( ::rtl::OUString(), uno::Reference< uno::XInterface >(), ERRCODE_IO_CANTWRITE );
}
