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


#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>
#include <osl/mutex.hxx>
#include <svl/itemprop.hxx>
#include <svl/urihelper.hxx>
#include <svx/dataaccessdescriptor.hxx>
#include <tools/shl.hxx>    // GetAppData
#include <tools/tempfile.hxx>
#include <sfx2/app.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/docfilt.hxx>
#include <comphelper/processfactory.hxx>
#include <vcl/timer.hxx>
#include <com/sun/star/sdb/CommandType.hpp>
#include <com/sun/star/text/MailMergeType.hpp>
#include <com/sun/star/text/MailMergeEvent.hpp>
#include <com/sun/star/text/XMailMergeListener.hpp>
#include <com/sun/star/text/XMailMergeBroadcaster.hpp>
#include <com/sun/star/beans/PropertyAttribute.hpp>
#include <com/sun/star/lang/XUnoTunnel.hpp>
#include <com/sun/star/sdbc/XResultSet.hpp>
#include <com/sun/star/sdbc/XConnection.hpp>
#include <com/sun/star/sdbc/XRowSet.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#ifndef _COM_SUN_STAR_UTIL_CloseVetoException_HPP_
#include <com/sun/star/util/CloseVetoException.hpp>
#endif
#include <com/sun/star/sdbcx/XRowLocate.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include "com/sun/star/mail/XSmtpService.hpp"
#include <sfx2/viewfrm.hxx>
#include <sfx2/event.hxx>
#include <swevent.hxx>
#include <unomailmerge.hxx>
#include <swdll.hxx>
#include <swmodule.hxx>
#include <unoprnms.hxx>
#include <unomap.hxx>
#include <swunohelper.hxx>
#include <docsh.hxx>
#ifndef IDOCUMENTDEVICEACCESS_HXX_INCLUDED
#include <IDocumentDeviceAccess.hxx>
#endif
#include <view.hxx>
#include <dbmgr.hxx>
#include <unotxdoc.hxx>
#include <prtopt.hxx>
#include <wrtsh.hxx>
#include <shellio.hxx>
#include <mmconfigitem.hxx>
#include <mailmergehelper.hxx>
#include <memory>

#include <unomid.h>


#define SN_MAIL_MERGE               "com.sun.star.text.MailMerge"
#define SN_DATA_ACCESS_DESCRIPTOR   "com.sun.star.sdb.DataAccessDescriptor"

using namespace ::com::sun::star;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::text;
using ::rtl::OUString;
using namespace SWUnoHelper;

////////////////////////////////////////////////////////////

typedef ::utl::SharedUNOComponent< XInterface > SharedComponent;

////////////////////////////////////////////////////////////

osl::Mutex &    GetMailMergeMutex()
{
    static osl::Mutex   aMutex;
    return aMutex;
}

////////////////////////////////////////////////////////////

enum CloseResult
{
	eSuccess,		// successfully closed
	eVetoed,		// vetoed, ownership transferred to the vetoing instance
	eFailed			// failed for some unknown reason
};
static CloseResult CloseModelAndDocSh(
       Reference< frame::XModel > &rxModel,
       SfxObjectShellRef &rxDocSh )
{
	CloseResult eResult = eSuccess;

    rxDocSh = 0;

    //! models/documents should never be disposed (they may still be
    //! used for printing which is called asynchronously for example)
    //! instead call close
    Reference< util::XCloseable > xClose( rxModel, UNO_QUERY );
    if (xClose.is())
    {
        try
        {
            //! 'sal_True' -> transfer ownership to vetoing object if vetoed!
            //! I.e. now that object is responsible for closing the model and doc shell.
            xClose->close( sal_True );
        }
        catch (util::CloseVetoException &)
        {
            //! here we have the problem that the temporary file that is
			//! currently being printed will never be deleted. :-(
			eResult = eVetoed;
        }
		catch ( const uno::RuntimeException& )
		{
			eResult = eFailed;
		}
    }
	return eResult;
}

////////////////////////////////////////////////////////////

static sal_Bool LoadFromURL_impl(
        Reference< frame::XModel > &rxModel,
        SfxObjectShellRef &rxDocSh,
        const String &rURL,
        sal_Bool bClose )
    throw (RuntimeException)
{
    // try to open the document readonly and hidden
    Reference< frame::XModel > xTmpModel;
    Sequence < PropertyValue > aArgs( 1 );
    aArgs[0].Name = C2U("Hidden");
    sal_Bool bVal = sal_True;
    aArgs[0].Value <<= bVal;
    try
    {
        Reference < XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->
                createInstance( C2U("com.sun.star.frame.Desktop") ), UNO_QUERY );
        xTmpModel = Reference < XModel >( xDesktop->loadComponentFromURL(
                rURL, C2U("_blank"), 0, aArgs ), UNO_QUERY );
    }
    catch( Exception & )
    {
        return sal_False;
    }

    // try to get the DocShell
    SwDocShell *pTmpDocShell = 0;
    Reference < XUnoTunnel > xTunnel( xTmpModel, UNO_QUERY );
    if (xTunnel.is())
    {
        SwXTextDocument* pTextDoc = reinterpret_cast<SwXTextDocument *>(
                xTunnel->getSomething( SwXTextDocument::getUnoTunnelId() ));
        pTmpDocShell = pTextDoc ? pTextDoc->GetDocShell() : 0;
    }

    sal_Bool bRes = sal_False;
    if (xTmpModel.is() && pTmpDocShell)    // everything available?
    {
        if (bClose)
            CloseModelAndDocSh( rxModel, rxDocSh );
        // set new stuff
        rxModel = xTmpModel;
        rxDocSh = pTmpDocShell;
        bRes = sal_True;
    }
    else
    {
        // SfxObjectShellRef is ok here, since the document will be explicitly closed
        SfxObjectShellRef xTmpDocSh = pTmpDocShell;
        CloseModelAndDocSh( xTmpModel, xTmpDocSh );
    }

    return bRes;
}

//==========================================================
namespace
{
    class DelayedFileDeletion : public ::cppu::WeakImplHelper1< util::XCloseListener >
	{
	protected:
		::osl::Mutex					m_aMutex;
		Reference< util::XCloseable >	m_xDocument;
		Timer							m_aDeleteTimer;
		String							m_sTemporaryFile;
		sal_Int32						m_nPendingDeleteAttempts;

	public:
		DelayedFileDeletion( const Reference< XModel >& _rxModel,
							 const String& _rTemporaryFile );

	protected:
		~DelayedFileDeletion( );

		// XCloseListener
		virtual void SAL_CALL queryClosing( const EventObject& _rSource, sal_Bool _bGetsOwnership ) throw (util::CloseVetoException, RuntimeException);
		virtual void SAL_CALL notifyClosing( const EventObject& _rSource ) throw (RuntimeException);

		// XEventListener
		virtual void SAL_CALL disposing( const EventObject& Source ) throw (RuntimeException);

	private:
		void implTakeOwnership( );
		DECL_LINK( OnTryDeleteFile, void* );

	private:
		DelayedFileDeletion( const DelayedFileDeletion& );					// never implemented
		DelayedFileDeletion& operator=( const DelayedFileDeletion& );		// never implemented
	};

	DBG_NAME( DelayedFileDeletion )
	//------------------------------------------------------
	DelayedFileDeletion::DelayedFileDeletion( const Reference< XModel >& _rxModel, const String& _rTemporaryFile )
        :
        m_xDocument( _rxModel, UNO_QUERY )
        ,m_sTemporaryFile( _rTemporaryFile )
		,m_nPendingDeleteAttempts( 0 )
	{
		DBG_CTOR( DelayedFileDeletion, NULL );

		osl_incrementInterlockedCount( &m_refCount );
		try
		{
			if ( m_xDocument.is() )
			{
				m_xDocument->addCloseListener( this );
				// successfully added -> keep ourself alive
				acquire();
			}
			else {
				DBG_ERROR( "DelayedFileDeletion::DelayedFileDeletion: model is no component!" );
            }
		}
		catch( const Exception& )
		{
			DBG_ERROR( "DelayedFileDeletion::DelayedFileDeletion: could not register as event listener at the model!" );
		}
		osl_decrementInterlockedCount( &m_refCount );
	}

	//--------------------------------------------------------------------
    IMPL_LINK( DelayedFileDeletion, OnTryDeleteFile, void*, EMPTYARG )
	{
		::osl::ClearableMutexGuard aGuard( m_aMutex );

		sal_Bool bSuccess = sal_False;
		try
		{
			sal_Bool bDeliverOwnership = ( 0 == m_nPendingDeleteAttempts );
				// if this is our last attempt, then anybody which vetoes this has to take the consequences
				// (means take the ownership)
			m_xDocument->close( bDeliverOwnership );
			bSuccess = sal_True;
		}
		catch( const util::CloseVetoException& )
		{
			// somebody vetoed -> next try
			if ( m_nPendingDeleteAttempts )
			{
				// next attempt
				--m_nPendingDeleteAttempts;
				m_aDeleteTimer.Start();
			}
			else
				bSuccess = sal_True;	// can't do anything here ...
		}
		catch( const Exception& )
		{
			DBG_ERROR( "DelayedFileDeletion::OnTryDeleteFile: caught a strange exception!" );
			bSuccess = sal_True;
				// can't do anything here ...
		}

		if ( bSuccess )
		{
			SWUnoHelper::UCB_DeleteFile( m_sTemporaryFile );
			aGuard.clear();
			release();	// this should be our last reference, we should be dead after this
		}
		return 0L;
	}

	//--------------------------------------------------------------------
	void DelayedFileDeletion::implTakeOwnership( )
	{
		// revoke ourself as listener
		try
		{
			m_xDocument->removeCloseListener( this );
		}
		catch( const Exception & )
		{
			DBG_ERROR( "DelayedFileDeletion::implTakeOwnership: could not revoke the listener!" );
		}

		m_aDeleteTimer.SetTimeout( 3000 );	// 3 seconds
		m_aDeleteTimer.SetTimeoutHdl( LINK( this, DelayedFileDeletion, OnTryDeleteFile ) );
		m_nPendingDeleteAttempts = 3;	// try 3 times at most
		m_aDeleteTimer.Start( );
	}

	//--------------------------------------------------------------------
    void SAL_CALL DelayedFileDeletion::queryClosing( const EventObject& , sal_Bool _bGetsOwnership ) throw (util::CloseVetoException, RuntimeException)
	{
		::osl::MutexGuard aGuard( m_aMutex );
		if ( _bGetsOwnership )
			implTakeOwnership( );

		// always veto: We want to take the ownership ourself, as this is the only chance to delete
		// the temporary file which the model is based on
		throw util::CloseVetoException( );
	}

	//--------------------------------------------------------------------
    void SAL_CALL DelayedFileDeletion::notifyClosing( const EventObject&  ) throw (RuntimeException)
	{
		DBG_ERROR( "DelayedFileDeletion::notifyClosing: how this?" );
		// this should not happen:
		// Either, a foreign instance closes the document, then we should veto this, and take the ownership
		// Or, we ourself close the document, then we should not be a listener anymore
	}

	//------------------------------------------------------
    void SAL_CALL DelayedFileDeletion::disposing( const EventObject&  ) throw (RuntimeException)
	{
		DBG_ERROR( "DelayedFileDeletion::disposing: how this?" );
		// this should not happen:
		// Either, a foreign instance closes the document, then we should veto this, and take the ownership
		// Or, we ourself close the document, then we should not be a listener anymore
	}

	//------------------------------------------------------
	DelayedFileDeletion::~DelayedFileDeletion( )
	{
		DBG_DTOR( DelayedFileDeletion, NULL );
	}
}

////////////////////////////////////////////////////////////

static sal_Bool DeleteTmpFile_Impl(
        Reference< frame::XModel > &rxModel,
        SfxObjectShellRef &rxDocSh,
        const String &rTmpFileURL )
{
    sal_Bool bRes = sal_False;
    if (rTmpFileURL.Len())
    {
		sal_Bool bDelete = sal_True;
		if ( eVetoed == CloseModelAndDocSh( rxModel, rxDocSh ) )
		{
			// somebody vetoed the closing, and took the ownership of the document
			// -> ensure that the temporary file is deleted later on
			Reference< XEventListener > xEnsureDelete( new DelayedFileDeletion( rxModel, rTmpFileURL ) );
				// note: as soon as #106931# is fixed, the whole DelayedFileDeletion is to be superseeded by
				// a better solution
			bDelete = sal_False;
		}

        rxModel = 0;
        rxDocSh = 0; // destroy doc shell

		if ( bDelete )
		{
			if ( !SWUnoHelper::UCB_DeleteFile( rTmpFileURL ) )
			{
				Reference< XEventListener > xEnsureDelete( new DelayedFileDeletion( rxModel, rTmpFileURL ) );
					// same not as above: as soon as #106931#, ...
			}
		}
		else
			bRes = sal_True;	// file will be deleted delayed
    }
    return bRes;
}

////////////////////////////////////////////////////////////

SwXMailMerge::SwXMailMerge() :
    aEvtListeners   ( GetMailMergeMutex() ),
    aMergeListeners ( GetMailMergeMutex() ),
    aPropListeners  ( GetMailMergeMutex() ),
    pPropSet( aSwMapProvider.GetPropertySet( PROPERTY_MAP_MAILMERGE ) ),
    bSendAsHTML(sal_False),
    bSendAsAttachment(sal_False),
    bSaveAsSingleFile(sal_False)

{
    // create empty document
    // like in: SwModule::InsertEnv (appenv.cxx)
    SwDocShell *pDocShell = new SwDocShell( SFX_CREATE_MODE_STANDARD );
    xDocSh = pDocShell;
    xDocSh->DoInitNew( 0 );
    SfxViewFrame *pFrame = SfxViewFrame::LoadHiddenDocument( *xDocSh, 0 );
    SwView *pView = (SwView*) pFrame->GetViewShell();
    pView->AttrChangedNotify( &pView->GetWrtShell() );//Damit SelectShell gerufen wird.

    xModel = pDocShell->GetModel();

    nDataCommandType    = sdb::CommandType::TABLE;
    nOutputType         = MailMergeType::PRINTER;
    bEscapeProcessing   = sal_True;     //!! allow to process properties like "Filter", "Order", ...
    bSinglePrintJobs    = sal_False;
    bFileNameFromColumn = sal_False;

    bDisposing = sal_False;
}

SwXMailMerge::~SwXMailMerge()
{
	if (aTmpFileName.Len())
		DeleteTmpFile_Impl( xModel, xDocSh, aTmpFileName );
	else	// there was no temporary file in use
	{
		//! we still need to close the model and doc shell manually
		//! because there is no automatism that will do that later.
		//! #120086#
		if ( eVetoed == CloseModelAndDocSh( xModel, xDocSh ) )
			DBG_WARNING( "owner ship transferred to vetoing object!" );

        xModel = 0;
        xDocSh = 0; // destroy doc shell
	}
}

uno::Any SAL_CALL SwXMailMerge::execute(
        const uno::Sequence< beans::NamedValue >& rArguments )
    throw (IllegalArgumentException, Exception, RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    //
    // get property values to be used
    // (use values from the service as default and override them with
    // the values that are provided as arguments)
    //
    uno::Sequence< uno::Any >           aCurSelection   = aSelection;
    uno::Reference< sdbc::XResultSet >  xCurResultSet   = xResultSet;
    uno::Reference< sdbc::XConnection > xCurConnection  = xConnection;
    uno::Reference< frame::XModel >     xCurModel       = xModel;
    OUString   aCurDataSourceName       = aDataSourceName;
    OUString   aCurDataCommand          = aDataCommand;
    OUString   aCurFilter               = aFilter;
    OUString   aCurDocumentURL          = aDocumentURL;
    OUString   aCurOutputURL            = aOutputURL;
    OUString   aCurFileNamePrefix       = aFileNamePrefix;
    sal_Int32  nCurDataCommandType      = nDataCommandType;
    sal_Int16  nCurOutputType           = nOutputType;
    sal_Bool   bCurEscapeProcessing     = bEscapeProcessing;
    sal_Bool   bCurSinglePrintJobs      = bSinglePrintJobs;
    sal_Bool   bCurFileNameFromColumn   = bFileNameFromColumn;
    //
    SfxObjectShellRef xCurDocSh = xDocSh;   // the document
    //
    const beans::NamedValue *pArguments = rArguments.getConstArray();
    sal_Int32 nArgs = rArguments.getLength();
    for (sal_Int32 i = 0;  i < nArgs;  ++i)
    {
        const OUString &rName   = pArguments[i].Name;
        const Any &rValue       = pArguments[i].Value;

        sal_Bool bOK = sal_True;
        if (rName.equalsAscii( GetPropName( UNO_NAME_SELECTION ) ))
            bOK = rValue >>= aCurSelection;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_RESULT_SET ) ))
            bOK = rValue >>= xCurResultSet;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_CONNECTION ) ))
            bOK = rValue >>= xCurConnection;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_MODEL ) ))
            throw PropertyVetoException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + rName, static_cast < cppu::OWeakObject * > ( this ) );
        else if (rName.equalsAscii( GetPropName( UNO_NAME_DATA_SOURCE_NAME ) ))
            bOK = rValue >>= aCurDataSourceName;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_DAD_COMMAND ) ))
            bOK = rValue >>= aCurDataCommand;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_FILTER ) ))
            bOK = rValue >>= aCurFilter;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_DOCUMENT_URL ) ))
        {
            bOK = rValue >>= aCurDocumentURL;
            if (aCurDocumentURL.getLength()
                && !LoadFromURL_impl( xCurModel, xCurDocSh, aCurDocumentURL, sal_False ))
                throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to create document from URL: " ) ) + aCurDocumentURL, static_cast < cppu::OWeakObject * > ( this ) );
        }
        else if (rName.equalsAscii( GetPropName( UNO_NAME_OUTPUT_URL ) ))
        {
            bOK = rValue >>= aCurOutputURL;
            if (aCurOutputURL.getLength())
            {
                if (!UCB_IsDirectory(aCurOutputURL))
                    throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL does not point to a directory: " ) ) + aCurOutputURL, static_cast < cppu::OWeakObject * > ( this ), 0 );
                if (UCB_IsReadOnlyFileName(aCurOutputURL))
                    throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL is read-only: " ) ) + aCurOutputURL, static_cast < cppu::OWeakObject * > ( this ), 0 );
            }
        }
        else if (rName.equalsAscii( GetPropName( UNO_NAME_FILE_NAME_PREFIX ) ))
            bOK = rValue >>= aCurFileNamePrefix;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_DAD_COMMAND_TYPE ) ))
            bOK = rValue >>= nCurDataCommandType;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_OUTPUT_TYPE ) ))
            bOK = rValue >>= nCurOutputType;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_ESCAPE_PROCESSING ) ))
            bOK = rValue >>= bCurEscapeProcessing;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_SINGLE_PRINT_JOBS ) ))
            bOK = rValue >>= bCurSinglePrintJobs;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_FILE_NAME_FROM_COLUMN ) ))
            bOK = rValue >>= bCurFileNameFromColumn;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_SUBJECT ) ))
            bOK = rValue >>= sSubject;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_ADDRESS_FROM_COLUMN ) ))
            bOK = rValue >>= sAddressFromColumn;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_SEND_AS_HTML ) ))
            bOK = rValue >>= bSendAsHTML;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_MAIL_BODY ) ))
            bOK = rValue >>= sMailBody;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_ATTACHMENT_NAME ) ))
            bOK = rValue >>= sAttachmentName;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_ATTACHMENT_FILTER ) ))
            bOK = rValue >>= sAttachmentFilter;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_COPIES_TO ) ))
            bOK = rValue >>= aCopiesTo;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_BLIND_COPIES_TO ) ))
            bOK = rValue >>= aBlindCopiesTo;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_SEND_AS_ATTACHMENT ) ))
            bOK = rValue >>= bSendAsAttachment;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_PRINT_OPTIONS ) ))
            bOK = rValue >>= aPrintSettings;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_SAVE_AS_SINGLE_FILE ) ))
            bOK = rValue >>= bSaveAsSingleFile;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_SAVE_FILTER ) ))
            bOK = rValue >>= sSaveFilter;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_SAVE_FILTER_OPTIONS ) ))
            bOK = rValue >>= sSaveFilterOptions;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_SAVE_FILTER_DATA ) ))
            bOK = rValue >>= aSaveFilterData;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_IN_SERVER_PASSWORD ) ))
            bOK = rValue >>= sInServerPassword;
        else if (rName.equalsAscii( GetPropName( UNO_NAME_OUT_SERVER_PASSWORD ) ))
            bOK = rValue >>= sOutServerPassword;
        else
            throw UnknownPropertyException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is unknown: " ) ) + rName, static_cast < cppu::OWeakObject * > ( this ) );

        if (!bOK)
            throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property type mismatch or property not set: " ) ) + rName, static_cast < cppu::OWeakObject * > ( this ), 0 );
    }

	// need to translate the selection: the API here requires a sequence of bookmarks, but the MergeNew
	// method we will call below requires a sequence of indicies.
	if ( aCurSelection.getLength() )
	{
		Sequence< Any > aTranslated( aCurSelection.getLength() );

		sal_Bool bValid = sal_False;
		Reference< sdbcx::XRowLocate > xRowLocate( xCurResultSet, UNO_QUERY );
		if ( xRowLocate.is() )
		{

			const Any* pBookmarks = aCurSelection.getConstArray();
			const Any* pBookmarksEnd = pBookmarks + aCurSelection.getLength();
			Any* pTranslated = aTranslated.getArray();

			try
			{
				sal_Bool bEverythingsFine = sal_True;
				for ( ; ( pBookmarks != pBookmarksEnd ) && bEverythingsFine; ++pBookmarks )
				{
					if ( xRowLocate->moveToBookmark( *pBookmarks ) )
						*pTranslated <<= xCurResultSet->getRow();
					else
						bEverythingsFine = sal_False;
				}
				if ( bEverythingsFine )
					bValid = sal_True;
			}
			catch( const Exception& )
			{
				bValid = sal_False;
			}
		}

		if ( !bValid )
		{
            throw IllegalArgumentException(
				OUString ( RTL_CONSTASCII_USTRINGPARAM ( "The current 'Selection' does not describe a valid array of bookmarks, relative to the current 'ResultSet'." ) ),
				static_cast < cppu::OWeakObject * > ( this ),
				0
			);
		}

		aCurSelection = aTranslated;
	}

    SfxViewFrame*   pFrame = SfxViewFrame::GetFirst( xCurDocSh, sal_False);
    SwView *pView = dynamic_cast< SwView* >( pFrame->GetViewShell() );
    if (!pView)
        throw RuntimeException();
    SwWrtShell &rSh = *pView->GetWrtShellPtr();

    // avoid assertion in 'Update' from Sfx by supplying a shell
    // and thus avoiding the SelectShell call in Writers GetState function
    // while still in Update of Sfx.
    // (GetSelection in Update is not allowed)
    if (pView && aCurDocumentURL.getLength())
        pView->AttrChangedNotify( &pView->GetWrtShell() );//Damit SelectShell gerufen wird.

    SharedComponent aRowSetDisposeHelper;
    if (!xCurResultSet.is())
    {
        if (!aCurDataSourceName.getLength() || !aCurDataCommand.getLength() )
        {
            DBG_ERROR("PropertyValues missing or unset");
            throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Either the ResultSet or DataSourceName and DataCommand must be set." ) ), static_cast < cppu::OWeakObject * > ( this ), 0 );
        }

        //
        // build ResultSet from DataSourceName, DataCommand and DataCommandType
        //
        Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
        if (xMgr.is())
        {
            Reference< XInterface > xInstance = xMgr->createInstance(
                    C2U( "com.sun.star.sdb.RowSet" ));
            aRowSetDisposeHelper.reset( xInstance, SharedComponent::TakeOwnership );
            Reference< XPropertySet > xRowSetPropSet( xInstance, UNO_QUERY );
            DBG_ASSERT( xRowSetPropSet.is(), "failed to get XPropertySet interface from RowSet" );
            if (xRowSetPropSet.is())
            {
                if (xCurConnection.is())
                    xRowSetPropSet->setPropertyValue( C2U("ActiveConnection"),  makeAny( xCurConnection ) );
                xRowSetPropSet->setPropertyValue( C2U("DataSourceName"),    makeAny( aCurDataSourceName ) );
                xRowSetPropSet->setPropertyValue( C2U("Command"),           makeAny( aCurDataCommand ) );
                xRowSetPropSet->setPropertyValue( C2U("CommandType"),       makeAny( nCurDataCommandType ) );
                xRowSetPropSet->setPropertyValue( C2U("EscapeProcessing"),  makeAny( bCurEscapeProcessing ) );
                xRowSetPropSet->setPropertyValue( C2U("ApplyFilter"),       makeAny( sal_True ) );
                xRowSetPropSet->setPropertyValue( C2U("Filter"),            makeAny( aCurFilter ) );

                Reference< sdbc::XRowSet > xRowSet( xInstance, UNO_QUERY );
                if (xRowSet.is())
                    xRowSet->execute(); // build ResultSet from properties
                if( !xCurConnection.is() )
                    xCurConnection.set( xRowSetPropSet->getPropertyValue( C2U( "ActiveConnection" )), UNO_QUERY );
                xCurResultSet = Reference< sdbc::XResultSet >( xRowSet, UNO_QUERY );
                DBG_ASSERT( xCurResultSet.is(), "failed to build ResultSet" );
            }
        }
    }

    svx::ODataAccessDescriptor aDescriptor;
    aDescriptor.setDataSource(aCurDataSourceName);
    aDescriptor[ svx::daConnection ]         <<= xCurConnection;
    aDescriptor[ svx::daCommand ]            <<= aCurDataCommand;
    aDescriptor[ svx::daCommandType ]        <<= nCurDataCommandType;
    aDescriptor[ svx::daEscapeProcessing ]   <<= bCurEscapeProcessing;
    aDescriptor[ svx::daCursor ]             <<= xCurResultSet;
    // aDescriptor[ svx::daColumnName ]      not used
    // aDescriptor[ svx::daColumnObject ]    not used
    aDescriptor[ svx::daSelection ]          <<= aCurSelection;

    sal_uInt16 nMergeType;
    switch (nCurOutputType)
    {
        case MailMergeType::PRINTER : nMergeType = DBMGR_MERGE_MAILMERGE; break;
        case MailMergeType::FILE    : nMergeType = DBMGR_MERGE_MAILFILES; break;
        case MailMergeType::MAIL    : nMergeType = DBMGR_MERGE_MAILING; break;
        default:
            throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Invalid value of property:" ) ) + C2U("OutputType"), static_cast < cppu::OWeakObject * > ( this ), 0 );
    }

    SwNewDBMgr* pMgr = rSh.GetNewDBMgr();
    //force layout creation
    rSh.CalcLayout();
    DBG_ASSERT( pMgr, "database manager missing" );

    SwMergeDescriptor aMergeDesc( nMergeType, rSh, aDescriptor );

    std::auto_ptr< SwMailMergeConfigItem > pMMConfigItem;
    uno::Reference< mail::XMailService > xInService;
    if (MailMergeType::PRINTER == nCurOutputType)
    {
        IDocumentDeviceAccess* pIDDA = rSh.getIDocumentDeviceAccess();
        SwPrintData aPrtData( pIDDA->getPrintData() );
        aPrtData.SetPrintSingleJobs( bCurSinglePrintJobs );
        pIDDA->setPrintData( aPrtData );
        // #i25686# printing should not be done asynchronously to prevent dangling offices
        // when mail merge is called as command line macro
        aMergeDesc.bPrintAsync = sal_False;
        aMergeDesc.aPrintOptions = aPrintSettings;
        aMergeDesc.bCreateSingleFile = true;
    }
    else /* FILE and MAIL*/
    {
		INetURLObject aURLObj;
        aURLObj.SetSmartProtocol( INET_PROT_FILE );

		if (aCurDocumentURL.getLength())
		{
			// if OutputURL or FileNamePrefix are missing get
			// them from DocumentURL
            aURLObj.SetSmartURL( aCurDocumentURL );
			if (!aCurFileNamePrefix.getLength())
                aCurFileNamePrefix = aURLObj.GetBase(); // filename without extension
            if (!aCurOutputURL.getLength())
            {
                //aCurOutputURL = aURLObj.GetURLPath();
                aURLObj.removeSegment();
                aCurOutputURL = aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI );
            }
		}
		else	// default empty document without URL
		{
			if (!aCurOutputURL.getLength())
				throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "OutputURL is not set and can not be obtained." ) ), static_cast < cppu::OWeakObject * > ( this ) );
		}

		aURLObj.SetSmartURL( aCurOutputURL );
        String aPath = aURLObj.GetMainURL( INetURLObject::DECODE_TO_IURI );

        String aDelim( INET_PATH_TOKEN );
        if (aPath.Len() >= aDelim.Len() &&
            aPath.Copy( aPath.Len()-aDelim.Len() ).CompareTo( aDelim ) != COMPARE_EQUAL)
            aPath += aDelim;
        if (bCurFileNameFromColumn)
            pMgr->SetEMailColumn( aCurFileNamePrefix );
        else
        {
            aPath += String( aCurFileNamePrefix );
            pMgr->SetEMailColumn( String() );
        }
        pMgr->SetSubject( aPath );
        if(MailMergeType::FILE == nCurOutputType)
        {
            aMergeDesc.sSaveToFilter = sSaveFilter;
            aMergeDesc.sSaveToFilterOptions = sSaveFilterOptions;
            aMergeDesc.aSaveToFilterData = aSaveFilterData;
            aMergeDesc.bCreateSingleFile = bSaveAsSingleFile;
        }
        else /*if(MailMergeType::MAIL == nCurOutputType)*/
        {
            pMgr->SetEMailColumn( sAddressFromColumn );
            if(!sAddressFromColumn.getLength())
                throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Mail address column not set." ) ), static_cast < cppu::OWeakObject * > ( this ) );
            aMergeDesc.sSaveToFilter     = sAttachmentFilter;
            aMergeDesc.sSubject          = sSubject;
            aMergeDesc.sMailBody         = sMailBody;
            aMergeDesc.sAttachmentName   = sAttachmentName;
            aMergeDesc.aCopiesTo         = aCopiesTo;
            aMergeDesc.aBlindCopiesTo    = aBlindCopiesTo;
            aMergeDesc.bSendAsHTML       = bSendAsHTML;
            aMergeDesc.bSendAsAttachment = bSendAsAttachment;

            aMergeDesc.bCreateSingleFile = sal_False;
            pMMConfigItem = std::auto_ptr< SwMailMergeConfigItem >(new SwMailMergeConfigItem);
            aMergeDesc.pMailMergeConfigItem = pMMConfigItem.get();
            aMergeDesc.xSmtpServer = SwMailMergeHelper::ConnectToSmtpServer(
                    *pMMConfigItem,
                    xInService,
                    sInServerPassword, sOutServerPassword );
            if( !aMergeDesc.xSmtpServer.is() || !aMergeDesc.xSmtpServer->isConnected())
                throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to connect to mail server." ) ), static_cast < cppu::OWeakObject * > ( this ) );
        }
    }


    // save document with temporary filename
    const SfxFilter *pSfxFlt = SwIoSystem::GetFilterOfFormat(
            String::CreateFromAscii( FILTER_XML ),
            SwDocShell::Factory().GetFilterContainer() );
    String aExtension( pSfxFlt->GetDefaultExtension() );
    aExtension.EraseLeadingChars( '*' );
    TempFile aTempFile( C2U("SwMM"), &aExtension );
    aTmpFileName = aTempFile.GetName();

	Reference< XStorable > xStorable( xCurModel, UNO_QUERY );
	sal_Bool bStoredAsTemporary = sal_False;
	if ( xStorable.is() )
	{
		try
		{
			xStorable->storeAsURL( aTmpFileName, Sequence< PropertyValue >() );
			bStoredAsTemporary = sal_True;
		}
		catch( const Exception& )
		{
		}
	}
	if ( !bStoredAsTemporary )
        throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to save temporary file." ) ), static_cast < cppu::OWeakObject * > ( this ) );

    pMgr->SetMergeSilent( sal_True );       // suppress dialogs, message boxes, etc.
    const SwXMailMerge *pOldSrc = pMgr->GetMailMergeEvtSrc();
    DBG_ASSERT( !pOldSrc || pOldSrc == this, "Ooops... different event source already set." );
    pMgr->SetMailMergeEvtSrc( this );   // launch events for listeners

    SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE), xCurDocSh));
    sal_Bool bSucc = pMgr->MergeNew( aMergeDesc );
    SFX_APP()->NotifyEvent(SfxEventHint(SW_EVENT_MAIL_MERGE_END, SwDocShell::GetEventName(STR_SW_EVENT_MAIL_MERGE_END), xCurDocSh));

    pMgr->SetMailMergeEvtSrc( pOldSrc );

	if ( xCurModel.get() != xModel.get() )
	{	// in case it was a temporary model -> close it, and delete the file
	    DeleteTmpFile_Impl( xCurModel, xCurDocSh, aTmpFileName );
		aTmpFileName.Erase();
	}
	// (in case it wasn't a temporary model, it will be closed in the dtor, at the latest)

    if (!bSucc)
        throw Exception( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Mail merge failed. Sorry, no further information available." ) ), static_cast < cppu::OWeakObject * > ( this ) );

    //de-initialize services
    if(xInService.is() && xInService->isConnected())
        xInService->disconnect();
    if(aMergeDesc.xSmtpServer.is() && aMergeDesc.xSmtpServer->isConnected())
        aMergeDesc.xSmtpServer->disconnect();

    return makeAny( sal_True );
}

void SwXMailMerge::LaunchMailMergeEvent( const MailMergeEvent &rEvt ) const
{
    cppu::OInterfaceIteratorHelper aIt( ((SwXMailMerge *) this)->aMergeListeners );
    while (aIt.hasMoreElements())
    {
        Reference< XMailMergeListener > xRef( aIt.next(), UNO_QUERY );
        if (xRef.is())
            xRef->notifyMailMergeEvent( rEvt );
    }
}

void SwXMailMerge::launchEvent( const PropertyChangeEvent &rEvt ) const
{
    cppu::OInterfaceContainerHelper *pContainer =
            aPropListeners.getContainer( rEvt.PropertyHandle );
    if (pContainer)
    {
        cppu::OInterfaceIteratorHelper aIt( *pContainer );
        while (aIt.hasMoreElements())
        {
            Reference< XPropertyChangeListener > xRef( aIt.next(), UNO_QUERY );
            if (xRef.is())
                xRef->propertyChange( rEvt );
        }
    }
}


uno::Reference< beans::XPropertySetInfo > SAL_CALL SwXMailMerge::getPropertySetInfo(  )
    throw (RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );
    static Reference< XPropertySetInfo > aRef = pPropSet->getPropertySetInfo();
    return aRef;
}

void SAL_CALL SwXMailMerge::setPropertyValue(
        const OUString& rPropertyName, const uno::Any& rValue )
    throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap()->getByName( rPropertyName );
    if (!pCur)
        throw UnknownPropertyException();
    else if (pCur->nFlags & PropertyAttribute::READONLY)
        throw PropertyVetoException();
    else
    {
        void *pData = NULL;
        const uno::Type* pType = pCur->pType;
        switch (pCur->nWID)
        {
            case WID_SELECTION :                pData = &aSelection;  break;
            case WID_RESULT_SET :               pData = &xResultSet;  break;
            case WID_CONNECTION :               pData = &xConnection;  break;
            case WID_MODEL :                    pData = &xModel;  break;
            case WID_DATA_SOURCE_NAME :         pData = &aDataSourceName;  break;
            case WID_DATA_COMMAND :             pData = &aDataCommand;  break;
            case WID_FILTER :                   pData = &aFilter;  break;
            case WID_DOCUMENT_URL :             pData = &aDocumentURL;  break;
            case WID_OUTPUT_URL :               pData = &aOutputURL;  break;
            case WID_DATA_COMMAND_TYPE :        pData = &nDataCommandType;  break;
            case WID_OUTPUT_TYPE :              pData = &nOutputType;  break;
            case WID_ESCAPE_PROCESSING :        pData = &bEscapeProcessing;  break;
            case WID_SINGLE_PRINT_JOBS :        pData = &bSinglePrintJobs;  break;
            case WID_FILE_NAME_FROM_COLUMN :    pData = &bFileNameFromColumn;  break;
            case WID_FILE_NAME_PREFIX :         pData = &aFileNamePrefix;  break;
            case WID_MAIL_SUBJECT:              pData = &sSubject; break;
            case WID_ADDRESS_FROM_COLUMN:       pData = &sAddressFromColumn; break;
            case WID_SEND_AS_HTML:              pData = &bSendAsHTML; break;
            case WID_SEND_AS_ATTACHMENT:        pData = &bSendAsAttachment; break;
            case WID_MAIL_BODY:                 pData = &sMailBody; break;
            case WID_ATTACHMENT_NAME:           pData = &sAttachmentName; break;
            case WID_ATTACHMENT_FILTER:         pData = &sAttachmentFilter;break;
            case WID_PRINT_OPTIONS:             pData = &aPrintSettings; break;
            case WID_SAVE_AS_SINGLE_FILE:       pData = &bSaveAsSingleFile; break;
            case WID_SAVE_FILTER:               pData = &sSaveFilter; break;
            case WID_SAVE_FILTER_OPTIONS:       pData = &sSaveFilterOptions; break;
            case WID_SAVE_FILTER_DATA:          pData = &aSaveFilterData; break;
            case WID_COPIES_TO:                 pData = &aCopiesTo; break;
            case WID_BLIND_COPIES_TO:           pData = &aBlindCopiesTo;break;
            case WID_IN_SERVER_PASSWORD:        pData = &sInServerPassword; break;
            case WID_OUT_SERVER_PASSWORD:       pData = &sOutServerPassword; break;
            default :
                DBG_ERROR("unknown WID");
        }
        Any aOld( pData, *pType );

        sal_Bool bChanged = sal_False;
        sal_Bool bOK = sal_True;
        if (aOld != rValue)
        {
            if (pData == &aSelection)
                bOK = rValue >>= aSelection;
            else if (pData == &xResultSet)
                bOK = rValue >>= xResultSet;
            else if (pData == &xConnection)
                bOK = rValue >>= xConnection;
            else if (pData == &xModel)
                bOK = rValue >>= xModel;
            else if (pData == &aDataSourceName)
                bOK = rValue >>= aDataSourceName;
            else if (pData == &aDataCommand)
                bOK = rValue >>= aDataCommand;
            else if (pData == &aFilter)
                bOK = rValue >>= aFilter;
            else if (pData == &aDocumentURL)
            {
                OUString aText;
                bOK = rValue >>= aText;
                if (aText.getLength()
                    && !LoadFromURL_impl( xModel, xDocSh, aText, sal_True ))
                    throw RuntimeException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Failed to create document from URL: " ) ) + aText, static_cast < cppu::OWeakObject * > ( this ) );
                aDocumentURL = aText;
            }
            else if (pData == &aOutputURL)
            {
                OUString aText;
                bOK = rValue >>= aText;
                if (aText.getLength())
                {
                    if (!UCB_IsDirectory(aText))
                        throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL does not point to a directory: " ) ) + aText, static_cast < cppu::OWeakObject * > ( this ), 0 );
                    if (UCB_IsReadOnlyFileName(aText))
                        throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "URL is read-only: " ) ) + aText, static_cast < cppu::OWeakObject * > ( this ), 0 );
                }
                aOutputURL = aText;
            }
            else if (pData == &nDataCommandType)
                bOK = rValue >>= nDataCommandType;
            else if (pData == &nOutputType)
                bOK = rValue >>= nOutputType;
            else if (pData == &bEscapeProcessing)
                bOK = rValue >>= bEscapeProcessing;
            else if (pData == &bSinglePrintJobs)
                bOK = rValue >>= bSinglePrintJobs;
            else if (pData == &bFileNameFromColumn)
                bOK = rValue >>= bFileNameFromColumn;
            else if (pData == &aFileNamePrefix)
                bOK = rValue >>= aFileNamePrefix;
            else if (pData == &sSubject)
                bOK = rValue >>= sSubject;
            else if (pData == &sAddressFromColumn)
                bOK = rValue >>= sAddressFromColumn;
            else if (pData == &bSendAsHTML)
                bOK = rValue >>= bSendAsHTML;
            else if (pData == &bSendAsAttachment)
                bOK = rValue >>= bSendAsAttachment;
            else if (pData == &sMailBody)
                bOK = rValue >>= sMailBody;
            else if (pData == &sAttachmentName)
                bOK = rValue >>= sAttachmentName;
            else if (pData == &sAttachmentFilter)
                bOK = rValue >>= sAttachmentFilter;
            else if (pData == &aPrintSettings)
                bOK = rValue >>= aPrintSettings;
            else if (pData == &bSaveAsSingleFile)
                bOK = rValue >>= bSaveAsSingleFile;
            else if (pData == &sSaveFilter)
                bOK = rValue >>= sSaveFilter;
            else if (pData == &sSaveFilterOptions)
                bOK = rValue >>= sSaveFilterOptions;
            else if (pData == &aSaveFilterData)
                bOK = rValue >>= aSaveFilterData;
            else if (pData == &aCopiesTo)
                bOK = rValue >>= aCopiesTo;
            else if (pData == &aBlindCopiesTo)
                bOK = rValue >>= aBlindCopiesTo;
            else if(pData == &sInServerPassword)
                bOK = rValue >>= sInServerPassword;
            else if(pData == &sOutServerPassword)
                bOK = rValue >>= sInServerPassword;
            else {
                DBG_ERROR( "invalid pointer" );
            }
            DBG_ASSERT( bOK, "set value failed" );
            bChanged = sal_True;
        }
        if (!bOK)
            throw IllegalArgumentException( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property type mismatch or property not set: " ) ) + rPropertyName, static_cast < cppu::OWeakObject * > ( this ), 0 );

        if (bChanged)
        {
            PropertyChangeEvent aChgEvt( (XPropertySet *) this, rPropertyName,
                    sal_False, pCur->nWID, aOld, rValue );
            launchEvent( aChgEvt );
        }
    }
}

uno::Any SAL_CALL SwXMailMerge::getPropertyValue(
        const OUString& rPropertyName )
    throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    Any aRet;

    const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap()->getByName( rPropertyName );
    if (!pCur)
        throw UnknownPropertyException();
    else
    {
        switch (pCur->nWID)
        {
            case WID_SELECTION :                aRet <<= aSelection;  break;
            case WID_RESULT_SET :               aRet <<= xResultSet;  break;
            case WID_CONNECTION :               aRet <<= xConnection;  break;
            case WID_MODEL :                    aRet <<= xModel;  break;
            case WID_DATA_SOURCE_NAME :         aRet <<= aDataSourceName;  break;
            case WID_DATA_COMMAND :             aRet <<= aDataCommand;  break;
            case WID_FILTER :                   aRet <<= aFilter;  break;
            case WID_DOCUMENT_URL :             aRet <<= aDocumentURL;  break;
            case WID_OUTPUT_URL :               aRet <<= aOutputURL;  break;
            case WID_DATA_COMMAND_TYPE :        aRet <<= nDataCommandType;  break;
            case WID_OUTPUT_TYPE :              aRet <<= nOutputType;  break;
            case WID_ESCAPE_PROCESSING :        aRet <<= bEscapeProcessing;  break;
            case WID_SINGLE_PRINT_JOBS :        aRet <<= bSinglePrintJobs;  break;
            case WID_FILE_NAME_FROM_COLUMN :    aRet <<= bFileNameFromColumn;  break;
            case WID_FILE_NAME_PREFIX :         aRet <<= aFileNamePrefix;  break;
            case WID_MAIL_SUBJECT:              aRet <<= sSubject; break;
            case WID_ADDRESS_FROM_COLUMN:       aRet <<= sAddressFromColumn; break;
            case WID_SEND_AS_HTML:              aRet <<= bSendAsHTML; break;
            case WID_SEND_AS_ATTACHMENT:        aRet <<= bSendAsAttachment; break;
            case WID_MAIL_BODY:                 aRet <<= sMailBody; break;
            case WID_ATTACHMENT_NAME:           aRet <<= sAttachmentName; break;
            case WID_ATTACHMENT_FILTER:         aRet <<= sAttachmentFilter;break;
            case WID_PRINT_OPTIONS:             aRet <<= aPrintSettings; break;
            case WID_SAVE_AS_SINGLE_FILE:       aRet <<= bSaveAsSingleFile; break;
            case WID_SAVE_FILTER:               aRet <<= sSaveFilter; break;
            case WID_SAVE_FILTER_OPTIONS:       aRet <<= sSaveFilterOptions; break;
            case WID_SAVE_FILTER_DATA:          aRet <<= aSaveFilterData; break;
            case WID_COPIES_TO:                 aRet <<= aCopiesTo; break;
            case WID_BLIND_COPIES_TO:           aRet <<= aBlindCopiesTo;break;
            case WID_IN_SERVER_PASSWORD:        aRet <<= sInServerPassword; break;
            case WID_OUT_SERVER_PASSWORD:       aRet <<= sOutServerPassword; break;
            default :
                DBG_ERROR("unknown WID");
        }
    }

    return aRet;
}

void SAL_CALL SwXMailMerge::addPropertyChangeListener(
        const OUString& rPropertyName,
        const uno::Reference< beans::XPropertyChangeListener >& rListener )
    throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );
    if (!bDisposing && rListener.is())
    {
        const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap()->getByName( rPropertyName );
        if (pCur)
            aPropListeners.addInterface( pCur->nWID, rListener );
        else
            throw UnknownPropertyException();
    }
}

void SAL_CALL SwXMailMerge::removePropertyChangeListener(
        const OUString& rPropertyName,
        const uno::Reference< beans::XPropertyChangeListener >& rListener )
    throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );
    if (!bDisposing && rListener.is())
    {
        const SfxItemPropertySimpleEntry* pCur = pPropSet->getPropertyMap()->getByName( rPropertyName );
        if (pCur)
            aPropListeners.removeInterface( pCur->nWID, rListener );
        else
            throw UnknownPropertyException();
    }
}

void SAL_CALL SwXMailMerge::addVetoableChangeListener(
        const OUString& /*rPropertyName*/,
        const uno::Reference< beans::XVetoableChangeListener >& /*rListener*/ )
    throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
{
    // no vetoable property, thus no support for vetoable change listeners
    DBG_WARNING( "not implemented");
}

void SAL_CALL SwXMailMerge::removeVetoableChangeListener(
        const OUString& /*rPropertyName*/,
        const uno::Reference< beans::XVetoableChangeListener >& /*rListener*/ )
    throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
{
    // no vetoable property, thus no support for vetoable change listeners
    DBG_WARNING( "not implemented");
}


void SAL_CALL SwXMailMerge::dispose()
    throw(RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    if (!bDisposing)
    {
        bDisposing = sal_True;

        EventObject aEvtObj( (XPropertySet *) this );
        aEvtListeners.disposeAndClear( aEvtObj );
        aMergeListeners.disposeAndClear( aEvtObj );
        aPropListeners.disposeAndClear( aEvtObj );
    }
}

void SAL_CALL SwXMailMerge::addEventListener(
        const Reference< XEventListener >& rxListener )
    throw(RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );
    if (!bDisposing && rxListener.is())
        aEvtListeners.addInterface( rxListener );
}

void SAL_CALL SwXMailMerge::removeEventListener(
        const Reference< XEventListener >& rxListener )
    throw(RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );
    if (!bDisposing && rxListener.is())
        aEvtListeners.removeInterface( rxListener );
}

void SAL_CALL SwXMailMerge::addMailMergeEventListener(
        const uno::Reference< XMailMergeListener >& rxListener )
    throw (RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );
    if (!bDisposing && rxListener.is())
        aMergeListeners.addInterface( rxListener );
}

void SAL_CALL SwXMailMerge::removeMailMergeEventListener(
        const uno::Reference< XMailMergeListener >& rxListener )
    throw (RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );
    if (!bDisposing && rxListener.is())
        aMergeListeners.removeInterface( rxListener );
}

OUString SAL_CALL SwXMailMerge::getImplementationName()
    throw(RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );
    return SwXMailMerge_getImplementationName();
}

sal_Bool SAL_CALL SwXMailMerge::supportsService( const OUString& rServiceName )
    throw(RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );
    return C2U( SN_MAIL_MERGE ) == rServiceName ||
           C2U( SN_DATA_ACCESS_DESCRIPTOR ) == rServiceName;
}

uno::Sequence< OUString > SAL_CALL SwXMailMerge::getSupportedServiceNames()
    throw(RuntimeException)
{
    vos::OGuard aGuard( Application::GetSolarMutex() );
    return SwXMailMerge_getSupportedServiceNames();
}

////////////////////////////////////////////////////////////

uno::Sequence< OUString > SAL_CALL SwXMailMerge_getSupportedServiceNames()
    throw()
{
    uno::Sequence< OUString > aNames(2);
    OUString *pName = aNames.getArray();
    pName[0] = C2U( SN_MAIL_MERGE );
    pName[1] = C2U( SN_DATA_ACCESS_DESCRIPTOR );
    return aNames;
}

OUString SAL_CALL SwXMailMerge_getImplementationName()
    throw()
{
    return OUString( C2U( "SwXMailMerge" ) );
}

uno::Reference< uno::XInterface > SAL_CALL SwXMailMerge_createInstance(
        const uno::Reference< XMultiServiceFactory > & /*rSMgr*/)
    throw( uno::Exception )
{
    vos::OGuard aGuard( Application::GetSolarMutex() );

    //the module may not be loaded
	SwDLL::Init();
    uno::Reference< uno::XInterface > xRef = (cppu::OWeakObject *) new SwXMailMerge();
    return xRef;
}

