/**************************************************************
 *
 * 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/uno/Reference.h>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/frame/XComponentLoader.hpp>
#include <com/sun/star/frame/XNotifyingDispatch.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/frame/XFrame.hpp>
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/frame/DispatchResultState.hpp>
#include <com/sun/star/frame/XDispatchResultListener.hpp>
#include <com/sun/star/util/URL.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/system/SystemShellExecute.hpp>
#include <com/sun/star/document/XTypeDetection.hpp>
#include <com/sun/star/system/SystemShellExecuteFlags.hpp>
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/document/UpdateDocMode.hpp>
#include <com/sun/star/task/ErrorCodeRequest.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/embed/ElementModes.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/uno/Sequence.h>
#include <comphelper/processfactory.hxx>
#include <cppuhelper/implbase1.hxx>
#include <rtl/ustring.hxx>


#include <comphelper/storagehelper.hxx>
#include <comphelper/synchronousdispatch.hxx>
#include <comphelper/configurationhelper.hxx>
#include <comphelper/sequenceasvector.hxx>

#include <vcl/wrkwin.hxx>
#include <svl/intitem.hxx>
#include <vcl/msgbox.hxx>
#include <svl/stritem.hxx>
#include <svl/eitem.hxx>
#include <sfx2/doctempl.hxx>
#include <svtools/sfxecode.hxx>
#include <framework/preventduplicateinteraction.hxx>
#include <svtools/ehdl.hxx>
#include <basic/sbxobj.hxx>
#include <svl/urihelper.hxx>
#include <unotools/localfilehelper.hxx>
#include <unotools/pathoptions.hxx>
#include <unotools/moduleoptions.hxx>
#include <svtools/templdlg.hxx>
#include <osl/file.hxx>
#include <unotools/extendedsecurityoptions.hxx>
#include <comphelper/docpasswordhelper.hxx>
#include <vcl/svapp.hxx>

#include <vos/mutex.hxx>

#include <rtl/logfile.hxx>

#include <sfx2/app.hxx>
#include <sfx2/bindings.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/docfile.hxx>
#include <sfx2/fcontnr.hxx>
#include <sfx2/new.hxx>
#include <sfx2/objitem.hxx>
#include <sfx2/objsh.hxx>
#include <svl/slstitm.hxx>
#include "objshimp.hxx"
#include "openflag.hxx"
#include <sfx2/passwd.hxx>
#include "referers.hxx"
#include <sfx2/request.hxx>
#include "sfx2/sfxresid.hxx"
#include <sfx2/viewsh.hxx>
#include "app.hrc"
#include <sfx2/viewfrm.hxx>
#include <sfx2/sfxuno.hxx>
#include <sfx2/objface.hxx>
#include <sfx2/filedlghelper.hxx>
#include <sfx2/docfac.hxx>
#include <sfx2/event.hxx>

#define _SVSTDARR_STRINGSDTOR
#include <svl/svstdarr.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::beans;
using namespace ::com::sun::star::frame;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::util;
using namespace ::com::sun::star::system;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::container;
using namespace ::cppu;
using namespace ::sfx2;

namespace css = ::com::sun::star;

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

class SfxOpenDocStatusListener_Impl : public WeakImplHelper1< XDispatchResultListener >
{
public:
    sal_Bool    bFinished;
    sal_Bool    bSuccess;
    virtual void SAL_CALL   dispatchFinished( const DispatchResultEvent& Event ) throw(RuntimeException);
    virtual void SAL_CALL   disposing( const EventObject& Source ) throw(RuntimeException);
                            SfxOpenDocStatusListener_Impl()
                                : bFinished( sal_False )
                                , bSuccess( sal_False )
                            {}
};

void SAL_CALL SfxOpenDocStatusListener_Impl::dispatchFinished( const DispatchResultEvent& aEvent ) throw(RuntimeException)
{
    bSuccess = ( aEvent.State == DispatchResultState::SUCCESS );
    bFinished = sal_True;
}

void SAL_CALL SfxOpenDocStatusListener_Impl::disposing( const EventObject& ) throw(RuntimeException)
{
}

SfxObjectShellRef SfxApplication::DocAlreadyLoaded
(
    const String&   rName,      // Name of the Document including path
    sal_Bool            bSilent,    // sal_True: do not ask for new view
    sal_Bool            bActivate,   // should current view be activated
    sal_Bool            bForbidVisible,
	const String*   pPostStr
)

/*  [description]
    assert if Document with the name 'rname' has been loaded and delivers the
    pointer. Otherwise a zeropointer will be returned
*/

{
    // create URL from searchable name
    INetURLObject aUrlToFind( rName );
    DBG_ASSERT( aUrlToFind.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL" );
	String aPostString;
	if (  pPostStr )
		aPostString = *pPostStr;

    // still open?
    SfxObjectShellRef xDoc;

    if ( !aUrlToFind.HasError() )
    {
		// check at normal opened documents
		if ( !xDoc.Is() )
		{
			xDoc = SfxObjectShell::GetFirst( 0, sal_False ); // include hidden files
			while( xDoc.Is() )
			{
				if ( xDoc->GetMedium() &&
					 xDoc->GetCreateMode() == SFX_CREATE_MODE_STANDARD &&
					 !xDoc->IsAbortingImport() && !xDoc->IsLoading() )
				{
					// compare by URLs
                    INetURLObject aUrl( xDoc->GetMedium()->GetName() );
					if ( !aUrl.HasError() && aUrl == aUrlToFind &&
                         (!bForbidVisible || !SfxViewFrame::GetFirst( xDoc, sal_True )) &&
						 !xDoc->IsLoading())
					{
							break;
					}
				}
				xDoc = SfxObjectShell::GetNext( *xDoc, 0, sal_False );
			}
		}
    }

    // found?
    if ( xDoc.Is() && bActivate )
    {
        DBG_ASSERT(
            !bForbidVisible, "Invisible files cannot be activated" );

		SfxViewFrame* pFrame;
        for( pFrame = SfxViewFrame::GetFirst( xDoc );
             pFrame && !pFrame->IsVisible();
             pFrame = SfxViewFrame::GetNext( *pFrame, xDoc ) ) ;
		if ( pFrame )
		{
		    SfxViewFrame *pCur = SfxViewFrame::Current();
		    if ( !bSilent && pFrame == pCur )
		        InfoBox( 0, SfxResId(RID_DOCALREADYLOADED_DLG)).Execute();
		    if ( bActivate )
            {
                pFrame->MakeActive_Impl( sal_True );
            }
		}
    }
    return xDoc;
}

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

void SetTemplate_Impl( const String &rFileName,
						const String &rLongName,
						SfxObjectShell *pDoc)
{
    // write TemplateName to DocumentInfo of document
    // TemplateDate stays as default (=current date)
    pDoc->ResetFromTemplate( rLongName, rFileName );
}

//====================================================================
class SfxDocPasswordVerifier : public ::comphelper::IDocPasswordVerifier
{
public:
    inline explicit     SfxDocPasswordVerifier( const Reference< embed::XStorage >& rxStorage ) :
                            mxStorage( rxStorage ) {}

    virtual ::comphelper::DocPasswordVerifierResult
                        verifyPassword( const ::rtl::OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData );
    virtual ::comphelper::DocPasswordVerifierResult
                        verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData );


private:
    Reference< embed::XStorage > mxStorage;
};

//--------------------------------------------------------------------
::comphelper::DocPasswordVerifierResult SfxDocPasswordVerifier::verifyPassword( const ::rtl::OUString& rPassword, uno::Sequence< beans::NamedValue >& o_rEncryptionData )
{
    o_rEncryptionData = ::comphelper::OStorageHelper::CreatePackageEncryptionData( rPassword );
    return verifyEncryptionData( o_rEncryptionData );
}


//--------------------------------------------------------------------
::comphelper::DocPasswordVerifierResult SfxDocPasswordVerifier::verifyEncryptionData( const uno::Sequence< beans::NamedValue >& rEncryptionData )
{
    ::comphelper::DocPasswordVerifierResult eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
    try
    {
        // check the encryption data
        // if the data correct is the stream will be opened successfully
        // and immediately closed
        ::comphelper::OStorageHelper::SetCommonStorageEncryptionData( mxStorage, rEncryptionData );

        mxStorage->openStreamElement(
                ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "content.xml" ) ),
                embed::ElementModes::READ | embed::ElementModes::NOCREATE );

        // no exception -> success
        eResult = ::comphelper::DocPasswordVerifierResult_OK;
    }
    catch( const packages::WrongPasswordException& )
    {
        eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
    }
    catch( const uno::Exception& )
    {
        // unknown error, report it as wrong password
        // TODO/LATER: we need an additional way to report unknown problems in this case
        eResult = ::comphelper::DocPasswordVerifierResult_WRONG_PASSWORD;
    }
    return eResult;
}

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

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

sal_uInt32 CheckPasswd_Impl
(
    //Window *pWin,             // Parent of dialog
    SfxObjectShell*  pDoc,
    SfxItemPool&     /*rPool*/, // Pool, if we need to create a set
    SfxMedium*       pFile      // Medium that needs a password (if necessary)
)

/*  [description]
    To query a passwort on a medium works only if the medium is a storage.
    If in documentinfo the password-flag is set, a dialog will query the user
    for the password. The password will be saved in a set. If the set does not
    exist, a set will be created.
*/
{
    sal_uIntPtr nRet = ERRCODE_NONE;

    if( ( !pFile->GetFilter() || pFile->IsStorage() ) )
    {
		uno::Reference< embed::XStorage > xStorage = pFile->GetStorage( sal_True );
        if( xStorage.is() )
        {
			uno::Reference< beans::XPropertySet > xStorageProps( xStorage, uno::UNO_QUERY );
			if ( xStorageProps.is() )
			{
            	sal_Bool bIsEncrypted = sal_False;
				try {
					xStorageProps->getPropertyValue( ::rtl::OUString::createFromAscii("HasEncryptedEntries") )
						>>= bIsEncrypted;
				} catch( uno::Exception& )
				{
                    // TODO/LATER:
					// the storage either has no encrypted elements or it's just
					// does not allow to detect it, probably it should be implemented laiter
					/*
                	bIsEncrypted = ( aInfo.Load( xStorage ) && aInfo.IsPasswd() );
					*/
				}

            	if ( bIsEncrypted )
            	{
			    	Window* pWin = pDoc ? pDoc->GetDialogParent( pFile ) : NULL;
                	if ( pWin )
                    	pWin->Show();

					nRet = ERRCODE_SFX_CANTGETPASSWD;

                	SfxItemSet *pSet = pFile->GetItemSet();
					if( pSet )
					{
                        Reference< ::com::sun::star::task::XInteractionHandler > xInteractionHandler = pFile->GetInteractionHandler();
                        if( xInteractionHandler.is() )
						{
                            // use the comphelper password helper to request a password
                            ::rtl::OUString aPassword;
                            SFX_ITEMSET_ARG( pSet, pPasswordItem, SfxStringItem, SID_PASSWORD, sal_False);
                            if ( pPasswordItem )
                                aPassword = pPasswordItem->GetValue();

                            uno::Sequence< beans::NamedValue > aEncryptionData;
                            SFX_ITEMSET_ARG( pSet, pEncryptionDataItem, SfxUnoAnyItem, SID_ENCRYPTIONDATA, sal_False);
                            if ( pEncryptionDataItem )
                                pEncryptionDataItem->GetValue() >>= aEncryptionData;

                            ::rtl::OUString aDocumentName = INetURLObject( pFile->GetOrigURL() ).GetMainURL( INetURLObject::DECODE_WITH_CHARSET );

                            SfxDocPasswordVerifier aVerifier( xStorage );
                            aEncryptionData = ::comphelper::DocPasswordHelper::requestAndVerifyDocPassword(
                                aVerifier, aEncryptionData, aPassword, xInteractionHandler, aDocumentName, comphelper::DocPasswordRequestType_STANDARD );

                            pSet->ClearItem( SID_PASSWORD );
                            pSet->ClearItem( SID_ENCRYPTIONDATA );

                            if ( aEncryptionData.getLength() > 0 )
                            {
                    			pSet->Put( SfxUnoAnyItem( SID_ENCRYPTIONDATA, uno::makeAny( aEncryptionData ) ) );

								try
								{
									// update the version list of the medium using the new password
									pFile->GetVersionList();
								}
								catch( uno::Exception& )
								{
									// TODO/LATER: set the error code
								}

								nRet = ERRCODE_NONE;
							}
							else
								nRet = ERRCODE_IO_ABORT;
						}
					}
            	}
        	}
			else
			{
				OSL_ENSURE( sal_False, "A storage must implement XPropertySet interface!" );
				nRet = ERRCODE_SFX_CANTGETPASSWD;
			}
    	}
	}

    return nRet;
}

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


sal_uIntPtr SfxApplication::LoadTemplate( SfxObjectShellLock& xDoc, const String &rFileName, sal_Bool bCopy, SfxItemSet* pSet )
{
    const SfxFilter* pFilter = NULL;
    SfxMedium aMedium( rFileName,  ( STREAM_READ | STREAM_SHARE_DENYNONE ), sal_False );

    if ( !aMedium.GetStorage( sal_True ).is() )
        aMedium.GetInStream();

    if ( aMedium.GetError() )
	{
		delete pSet;
        return aMedium.GetErrorCode();
	}

    aMedium.UseInteractionHandler( sal_True );
    sal_uIntPtr nErr = GetFilterMatcher().GuessFilter( aMedium,&pFilter,SFX_FILTER_TEMPLATE, 0 );
    if ( 0 != nErr)
    {
		delete pSet;
        return ERRCODE_SFX_NOTATEMPLATE;
    }

    if( !pFilter || !pFilter->IsAllowedAsTemplate() )
    {
		delete pSet;
        return ERRCODE_SFX_NOTATEMPLATE;
    }

	if ( pFilter->GetFilterFlags() & SFX_FILTER_STARONEFILTER )
	{
		DBG_ASSERT( !xDoc.Is(), "Sorry, not implemented!" );
		delete pSet;
		SfxStringItem aName( SID_FILE_NAME, rFileName );
		SfxStringItem aReferer( SID_REFERER, String::CreateFromAscii("private:user") );
		SfxStringItem aFlags( SID_OPTIONS, String::CreateFromAscii("T") );
		SfxBoolItem aHidden( SID_HIDDEN, sal_True );
		const SfxPoolItem *pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, &aName, &aHidden, &aReferer, &aFlags, 0L );
		const SfxObjectItem *pObj = PTR_CAST( SfxObjectItem, pRet );
        if ( pObj )
            xDoc = PTR_CAST( SfxObjectShell, pObj->GetShell() );
        else
        {
            const SfxViewFrameItem *pView = PTR_CAST( SfxViewFrameItem, pRet );
            if ( pView )
            {
                SfxViewFrame *pFrame = pView->GetFrame();
                if ( pFrame )
                    xDoc = pFrame->GetObjectShell();
            }
        }

		if ( !xDoc.Is() )
			return ERRCODE_SFX_DOLOADFAILED;
	}
	else
	{
		if ( !xDoc.Is() )
			xDoc = SfxObjectShell::CreateObject( pFilter->GetServiceName() );

		SfxMedium *pMedium = new SfxMedium( rFileName, STREAM_STD_READ, sal_False, pFilter, pSet );
		if(!xDoc->DoLoad(pMedium))
		{
			ErrCode nErrCode = xDoc->GetErrorCode();
			xDoc->DoClose();
			xDoc.Clear();
			return nErrCode;
		}
	}

    if( bCopy )
    {
		try
		{
            // TODO: introduce error handling

			uno::Reference< embed::XStorage > xTempStorage = ::comphelper::OStorageHelper::GetTemporaryStorage();
        	if( !xTempStorage.is() )
				throw uno::RuntimeException();

       		xDoc->GetStorage()->copyToStorage( xTempStorage );

//REMOVE				// the following operations should be done in one step
//REMOVE	       		xDoc->DoHandsOff();
            if ( !xDoc->DoSaveCompleted( new SfxMedium( xTempStorage, String() ) ) )
				throw uno::RuntimeException();
		}
		catch( uno::Exception& )
		{
			xDoc->DoClose();
			xDoc.Clear();

            // TODO: transfer correct error outside
			return ERRCODE_SFX_GENERAL;
		}

        SetTemplate_Impl( rFileName, String(), xDoc );
    }
    else
        SetTemplate_Impl( rFileName, String(), xDoc );

    xDoc->SetNoName();
    xDoc->InvalidateName();
    xDoc->SetModified(sal_False);
    xDoc->ResetError();

    ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel >  xModel ( xDoc->GetModel(), ::com::sun::star::uno::UNO_QUERY );
    if ( xModel.is() )
    {
        SfxItemSet* pNew = xDoc->GetMedium()->GetItemSet()->Clone();
        pNew->ClearItem( SID_PROGRESS_STATUSBAR_CONTROL );
		pNew->ClearItem( SID_FILTER_NAME );
        //pNew->Put( SfxStringItem( SID_FILTER_NAME, xDoc->GetFactory().GetFilter(0)->GetFilterName() ) );
        ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue > aArgs;
        TransformItems( SID_OPENDOC, *pNew, aArgs );
        sal_Int32 nLength = aArgs.getLength();
        aArgs.realloc( nLength + 1 );
        aArgs[nLength].Name = DEFINE_CONST_UNICODE("Title");
        aArgs[nLength].Value <<= ::rtl::OUString( xDoc->GetTitle( SFX_TITLE_DETECT ) );
        xModel->attachResource( ::rtl::OUString(), aArgs );
        delete pNew;
    }

    return xDoc->GetErrorCode();
}

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

void SfxApplication::NewDocDirectExec_Impl( SfxRequest& rReq )
{
    DBG_MEMTEST();

    SFX_REQUEST_ARG( rReq, pFactoryItem, SfxStringItem, SID_NEWDOCDIRECT, sal_False);
    String aFactName;
    if ( pFactoryItem )
        aFactName = pFactoryItem->GetValue();
   else
    	aFactName = SvtModuleOptions().GetDefaultModuleName();


    SfxRequest aReq( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, GetPool() );
    String aFact = String::CreateFromAscii("private:factory/");
    aFact += aFactName;
    aReq.AppendItem( SfxStringItem( SID_FILE_NAME, aFact ) );
    aReq.AppendItem( SfxFrameItem( SID_DOCFRAME, GetFrame() ) );
    aReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii( "_default" ) ) );

    // TODO/LATER: Should the other arguments be transferred as well?
    SFX_REQUEST_ARG( rReq, pDefaultPathItem, SfxStringItem, SID_DEFAULTFILEPATH, sal_False);
    if ( pDefaultPathItem )
        aReq.AppendItem( *pDefaultPathItem );
    SFX_REQUEST_ARG( rReq, pDefaultNameItem, SfxStringItem, SID_DEFAULTFILENAME, sal_False);
    if ( pDefaultNameItem )
        aReq.AppendItem( *pDefaultNameItem );

    SFX_APP()->ExecuteSlot( aReq );
    const SfxViewFrameItem* pItem = PTR_CAST( SfxViewFrameItem, aReq.GetReturnValue() );
    if ( pItem )
        rReq.SetReturnValue( SfxFrameItem( 0, pItem->GetFrame() ) );
}

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

void SfxApplication::NewDocExec_Impl( SfxRequest& rReq )
{
    DBG_MEMTEST();

    // No Parameters given and only factory given by BASIC ?
    SFX_REQUEST_ARG(rReq, pTemplNameItem, SfxStringItem, SID_TEMPLATE_NAME, sal_False);
    SFX_REQUEST_ARG(rReq, pTemplFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False);
    SFX_REQUEST_ARG(rReq, pTemplRegionNameItem, SfxStringItem, SID_TEMPLATE_REGIONNAME, sal_False);

    SfxObjectShellLock xDoc;

    String  aTemplateRegion, aTemplateName, aTemplateFileName;
    sal_Bool    bDirect = sal_False; // use filename instead of region/template
    SfxErrorContext aEc(ERRCTX_SFX_NEWDOC);
    if ( !pTemplNameItem && !pTemplFileNameItem )
    {
		Window* pTopWin = GetTopWindow();
		SvtDocumentTemplateDialog* pDocTemplDlg = new SvtDocumentTemplateDialog( NULL );
        int nRet = pDocTemplDlg->Execute();
		sal_Bool bNewWin = sal_False;
        if ( nRet == RET_OK )
		{
            rReq.Done();
            if ( pTopWin != GetTopWindow() )
            {
                // the dialogue opens a document -> a new TopWindow appears
                pTopWin = GetTopWindow();
                bNewWin = sal_True;
            }
		}

		delete pDocTemplDlg;
        if ( bNewWin && pTopWin )
			// after the destruction of the dialogue its parent comes to top,
			// but we want that the new document is on top
			pTopWin->ToTop();

		return;
    }
    else
    {
        // Template-Name
        if ( pTemplNameItem )
            aTemplateName = pTemplNameItem->GetValue();

        // Template-Region
        if ( pTemplRegionNameItem )
            aTemplateRegion = pTemplRegionNameItem->GetValue();

        // Template-File-Name
        if ( pTemplFileNameItem )
        {
            aTemplateFileName = pTemplFileNameItem->GetValue();
            bDirect = sal_True;
        }
    }

	sal_uIntPtr lErr = 0;
	SfxItemSet* pSet = new SfxAllItemSet( GetPool() );
	pSet->Put( SfxBoolItem( SID_TEMPLATE, sal_True ) );
    if ( !bDirect )
	{
		SfxDocumentTemplates aTmpFac;
		if( !aTemplateFileName.Len() )
			aTmpFac.GetFull( aTemplateRegion, aTemplateName, aTemplateFileName );

        if( !aTemplateFileName.Len() )
			lErr = ERRCODE_SFX_TEMPLATENOTFOUND;
	}

    INetURLObject aObj( aTemplateFileName );
    SfxErrorContext aEC( ERRCTX_SFX_LOADTEMPLATE, aObj.PathToFileName() );

    if ( lErr != ERRCODE_NONE )
    {
        sal_uIntPtr lFatalErr = ERRCODE_TOERROR(lErr);
        if ( lFatalErr )
            ErrorHandler::HandleError(lErr);
    }
    else
    {
        SfxCallMode eMode = SFX_CALLMODE_SYNCHRON;

        const SfxPoolItem *pRet=0;
        SfxStringItem aReferer( SID_REFERER, DEFINE_CONST_UNICODE("private:user") );
        SfxStringItem aTarget( SID_TARGETNAME, DEFINE_CONST_UNICODE("_default") );
        if ( aTemplateFileName.Len() )
        {
            DBG_ASSERT( aObj.GetProtocol() != INET_PROT_NOT_VALID, "Illegal URL!" );

            SfxStringItem aName( SID_FILE_NAME, aObj.GetMainURL( INetURLObject::NO_DECODE ) );
            SfxStringItem aTemplName( SID_TEMPLATE_NAME, aTemplateName );
            SfxStringItem aTemplRegionName( SID_TEMPLATE_REGIONNAME, aTemplateRegion );
            pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, &aTemplName, &aTemplRegionName, 0L );
        }
        else
        {
            SfxStringItem aName( SID_FILE_NAME, DEFINE_CONST_UNICODE("private:factory") );
            pRet = GetDispatcher_Impl()->Execute( SID_OPENDOC, eMode, &aName, &aTarget, &aReferer, 0L );
        }

        if ( pRet )
            rReq.SetReturnValue( *pRet );
    }
}

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

void SfxApplication::OpenDocExec_Impl( SfxRequest& rReq )
{
    DBG_MEMTEST();

	sal_uInt16 nSID = rReq.GetSlot();
    SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False );
    if ( pFileNameItem )
    {
        String aCommand( pFileNameItem->GetValue() );
        const SfxSlot* pSlot = GetInterface()->GetSlot( aCommand );
        if ( pSlot )
        {
            pFileNameItem = NULL;
        }
        else
        {
            sal_Int32 nIndex = aCommand.SearchAscii("slot:");
            if ( !nIndex )
            {
                sal_uInt16 nSlotId = (sal_uInt16) String( aCommand, 5, aCommand.Len()-5 ).ToInt32();
                if ( nSlotId == SID_OPENDOC )
                    pFileNameItem = NULL;
            }
        }
    }

    if ( !pFileNameItem )
    {
        // get FileName from dialog
        SvStringsDtor* pURLList = NULL;
        String aFilter;
        SfxItemSet* pSet = NULL;
        String aPath;
	    SFX_REQUEST_ARG( rReq, pFolderNameItem, SfxStringItem, SID_PATH, sal_False );
		if ( pFolderNameItem )
			aPath = pFolderNameItem->GetValue();
        else if ( nSID == SID_OPENTEMPLATE )
        {
			aPath = SvtPathOptions().GetTemplatePath();
			sal_Int32 nTokenCount = aPath.GetTokenCount( ';' );
            aPath = aPath.GetToken(
                sal::static_int_cast< xub_StrLen >(
                    nTokenCount ? ( nTokenCount - 1 ) : 0 ),
                ';' );
        }

		sal_Int16 nDialog = SFX2_IMPL_DIALOG_CONFIG;
		SFX_REQUEST_ARG( rReq, pSystemDialogItem, SfxBoolItem, SID_FILE_DIALOG, sal_False );
		if ( pSystemDialogItem )
			nDialog = pSystemDialogItem->GetValue() ? SFX2_IMPL_DIALOG_SYSTEM : SFX2_IMPL_DIALOG_OOO;

		String sStandardDir;

		SFX_REQUEST_ARG( rReq, pStandardDirItem, SfxStringItem, SID_STANDARD_DIR, sal_False );
		if ( pStandardDirItem )
			sStandardDir = pStandardDirItem->GetValue();

		::com::sun::star::uno::Sequence< ::rtl::OUString >	aBlackList;

		SFX_REQUEST_ARG( rReq, pBlackListItem, SfxStringListItem, SID_BLACK_LIST, sal_False );
		if ( pBlackListItem )
			pBlackListItem->GetStringList( aBlackList );


        sal_uIntPtr nErr = sfx2::FileOpenDialog_Impl(
                WB_OPEN | SFXWB_MULTISELECTION | SFXWB_SHOWVERSIONS, String(), pURLList, aFilter, pSet, &aPath, nDialog, sStandardDir, aBlackList );

        if ( nErr == ERRCODE_ABORT )
        {
            delete pURLList;
            return;
        }

        rReq.SetArgs( *(SfxAllItemSet*)pSet );
        if (aFilter.Len() >0 )
            rReq.AppendItem( SfxStringItem( SID_FILTER_NAME, aFilter ) );
        rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
        rReq.AppendItem( SfxStringItem( SID_REFERER, String::CreateFromAscii(SFX_REFERER_USER) ) );
        delete pSet;

        if ( pURLList->Count() )
        {
    		if ( nSID == SID_OPENTEMPLATE )
        		rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_False ) );

            // This helper wraps an existing (or may new created InteractionHandler)
            // intercept all incoming interactions and provide useful informations
            // later if the following transaction was finished.

            ::framework::PreventDuplicateInteraction*                 pHandler       = new ::framework::PreventDuplicateInteraction(::comphelper::getProcessServiceFactory());
            css::uno::Reference< css::task::XInteractionHandler >     xHandler       (static_cast< css::task::XInteractionHandler* >(pHandler), css::uno::UNO_QUERY);
            css::uno::Reference< css::task::XInteractionHandler >     xWrappedHandler;

            // wrap existing handler or create new UUI handler
            SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False);
            if (pInteractionItem)
            {
                pInteractionItem->GetValue() >>= xWrappedHandler;
    			rReq.RemoveItem( SID_INTERACTIONHANDLER );
            }
            if (xWrappedHandler.is())
                pHandler->setHandler(xWrappedHandler);
            else
                pHandler->useDefaultUUIHandler();
            rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHandler)) );

            // define rules for this handler
            css::uno::Type                                            aInteraction = ::getCppuType(static_cast< css::task::ErrorCodeRequest* >(0));
            ::framework::PreventDuplicateInteraction::InteractionInfo aRule        (aInteraction, 1);
            pHandler->addInteractionRule(aRule);

            for ( sal_uInt16 i = 0; i < pURLList->Count(); ++i )
            {
                String aURL = *(pURLList->GetObject(i));
                rReq.RemoveItem( SID_FILE_NAME );
                rReq.AppendItem( SfxStringItem( SID_FILE_NAME, aURL ) );

                // execute synchronous, to avoid next document load at reschedule
                // TODO/LATER: use URLList argument and always remove one document after another, each step in asychronous execution, until finished
                // but only if reschedule is a problem
                GetDispatcher_Impl()->Execute( SID_OPENDOC, SFX_CALLMODE_SYNCHRON, *rReq.GetArgs() );

                // check for special interaction "NO MORE DOCUMENTS ALLOWED" and
                // break loop then. Otherwise we risk showing the same interaction more then once.
                if ( pHandler->getInteractionInfo(aInteraction, &aRule) )
                {
                    if (aRule.m_nCallCount > 0)
                    {
                        if (aRule.m_xRequest.is())
                        {
                            css::task::ErrorCodeRequest aRequest;
                            if (aRule.m_xRequest->getRequest() >>= aRequest)
                            {
                                if (aRequest.ErrCode ==
                                    sal::static_int_cast< sal_Int32 >(
                                        ERRCODE_SFX_NOMOREDOCUMENTSALLOWED))
                                    break;
                            }
                        }
                    }
                }
            }

            delete pURLList;
            return;
        }
        delete pURLList;
    }

    if ( !rReq.IsSynchronCall() )
    {
        // now check whether a stream is already there
        // if not: download it in a thread and restart the call
        // return;
    }

    sal_Bool bHyperlinkUsed = sal_False;

	if ( SID_OPENURL == nSID )
	{
        // SID_OPENURL does the same as SID_OPENDOC!
		rReq.SetSlot( SID_OPENDOC );
		nSID = SID_OPENDOC;
	}
    else if ( nSID == SID_OPENTEMPLATE )
    {
        rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_False ) );
    }
    // pass URL to OS by using ShellExecuter or open it internal
    // if it seems to be an own format.
    /* Attention!
            There exist two possibilities to open hyperlinks:
            a) using SID_OPENHYPERLINK (new)
            b) using SID_BROWSE        (old)
     */
    else if ( nSID == SID_OPENHYPERLINK )
    {
        rReq.SetSlot( SID_OPENDOC );
        nSID = SID_OPENDOC;
        bHyperlinkUsed = sal_True;
    }

    // no else here! It's optional ...
    if (!bHyperlinkUsed)
    {
        SFX_REQUEST_ARG(rReq, pHyperLinkUsedItem, SfxBoolItem, SID_BROWSE, sal_False);
        if ( pHyperLinkUsedItem )
            bHyperlinkUsed = pHyperLinkUsedItem->GetValue();
        // no "official" item, so remove it from ItemSet before using UNO-API
        rReq.RemoveItem( SID_BROWSE );
    }

	SFX_REQUEST_ARG( rReq, pFileName, SfxStringItem, SID_FILE_NAME, sal_False );
	String aFileName = pFileName->GetValue();

    String aReferer;
    SFX_REQUEST_ARG( rReq, pRefererItem, SfxStringItem, SID_REFERER, sal_False );
    if ( pRefererItem )
        aReferer = pRefererItem->GetValue();

    SFX_REQUEST_ARG( rReq, pFileFlagsItem, SfxStringItem, SID_OPTIONS, sal_False);
    if ( pFileFlagsItem )
    {
        String aFileFlags = pFileFlagsItem->GetValue();
        aFileFlags.ToUpperAscii();
        if ( STRING_NOTFOUND != aFileFlags.Search( 0x0054 ) )               // T = 54h
		{
			rReq.RemoveItem( SID_TEMPLATE );
            rReq.AppendItem( SfxBoolItem( SID_TEMPLATE, sal_True ) );
		}

        if ( STRING_NOTFOUND != aFileFlags.Search( 0x0048 ) )               // H = 48h
		{
			rReq.RemoveItem( SID_HIDDEN );
            rReq.AppendItem( SfxBoolItem( SID_HIDDEN, sal_True ) );
		}

        if ( STRING_NOTFOUND != aFileFlags.Search( 0x0052 ) )               // R = 52h
		{
			rReq.RemoveItem( SID_DOC_READONLY );
            rReq.AppendItem( SfxBoolItem( SID_DOC_READONLY, sal_True ) );
		}

        if ( STRING_NOTFOUND != aFileFlags.Search( 0x0042 ) )               // B = 42h
		{
			rReq.RemoveItem( SID_PREVIEW );
            rReq.AppendItem( SfxBoolItem( SID_PREVIEW, sal_True ) );
		}

        if ( STRING_NOTFOUND != aFileFlags.Search( 0x0053 ) )               // S = 53h
		{
			// not supported anymore
			//rReq.RemoveItem( SID_SILENT );
            //rReq.AppendItem( SfxBoolItem( SID_SILENT, sal_True ) );
		}

		rReq.RemoveItem( SID_OPTIONS );
    }

	// Mark without URL cannot be handled by hyperlink code
	if ( bHyperlinkUsed && aFileName.Len() && aFileName.GetChar(0) != '#' )
	{
		Reference< ::com::sun::star::document::XTypeDetection >	xTypeDetection(
																	::comphelper::getProcessServiceFactory()->createInstance(
																	::rtl::OUString::createFromAscii( "com.sun.star.document.TypeDetection" )),
																	UNO_QUERY );
		if ( xTypeDetection.is() )
		{
			URL				aURL;
			::rtl::OUString	aTypeName;

			aURL.Complete = aFileName;
			Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance(
													::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
			xTrans->parseStrict( aURL );
            INetURLObject aINetURLObject(aURL.Complete);
			INetProtocol aINetProtocol = aINetURLObject.GetProtocol();
			SvtExtendedSecurityOptions aExtendedSecurityOptions;
			SvtExtendedSecurityOptions::OpenHyperlinkMode eMode = aExtendedSecurityOptions.GetOpenHyperlinkMode();
            if ( eMode == SvtExtendedSecurityOptions::OPEN_NEVER && aINetProtocol != INET_PROT_VND_SUN_STAR_HELP )
			{
                vos::OGuard aGuard( Application::GetSolarMutex() );
                Window *pWindow = SFX_APP()->GetTopWindow();

                String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE ));
                WarningBox  aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_NO_HYPERLINKS ));
                aSecurityWarningBox.SetText( aSecurityWarningBoxTitle );
                aSecurityWarningBox.Execute();
				return;
			}

			aTypeName = xTypeDetection->queryTypeByURL( aURL.Main );
			SfxFilterMatcher& rMatcher = SFX_APP()->GetFilterMatcher();
			const SfxFilter* pFilter = rMatcher.GetFilter4EA( aTypeName );
			if ( !pFilter || !( pFilter->IsOwnFormat() ))
			{
				// hyperlink does not link to own type => special handling (http, ftp) browser and (other external protocols) OS
				Reference< XSystemShellExecute > xSystemShellExecute(
                    com::sun::star::system::SystemShellExecute::create(
                        ::comphelper::getProcessComponentContext() ) );
				if ( xSystemShellExecute.is() )
				{
					if ( aINetProtocol == INET_PROT_MAILTO )
					{
						// don't dispatch mailto hyperlink to desktop dispatcher
						rReq.RemoveItem( SID_TARGETNAME );
						rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_self") ) );
					}
					else if ( aINetProtocol == INET_PROT_FTP ||
						 aINetProtocol == INET_PROT_HTTP ||
						 aINetProtocol == INET_PROT_HTTPS )
					{
						try
						{
							// start browser
							::rtl::OUString aURLString( aURL.Complete );
							xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS );
						}
						catch ( ::com::sun::star::lang::IllegalArgumentException& )
						{
							vos::OGuard aGuard( Application::GetSolarMutex() );
                            Window *pWindow = SFX_APP()->GetTopWindow();
							ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
						}
						catch ( ::com::sun::star::system::SystemShellExecuteException& )
						{
							vos::OGuard aGuard( Application::GetSolarMutex() );
                            Window *pWindow = SFX_APP()->GetTopWindow();
							ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
						}

						return;
					}
					else
					{
						// check for "internal" protocols that should not be forwarded to the system
						Sequence < ::rtl::OUString > aProtocols(2);

						// add special protocols that always should be treated as internal
						aProtocols[0] = ::rtl::OUString::createFromAscii("private:*");
						aProtocols[1] = ::rtl::OUString::createFromAscii("vnd.sun.star.*");

						try
						{
							// get registered protocol handlers from configuration
							Reference < XNameAccess > xAccess( ::comphelper::ConfigurationHelper::openConfig( ::comphelper::getProcessServiceFactory(),
								::rtl::OUString::createFromAscii("org.openoffice.Office.ProtocolHandler/HandlerSet"), ::comphelper::ConfigurationHelper::E_READONLY ), UNO_QUERY );
							if ( xAccess.is() )
							{
								Sequence < ::rtl::OUString > aNames = xAccess->getElementNames();
								for ( sal_Int32 nName = 0; nName < aNames.getLength(); nName ++)
								{
									Reference < XPropertySet > xSet;
									Any aRet = xAccess->getByName( aNames[nName] );
									aRet >>= xSet;
									if ( xSet.is() )
									{
										// copy protocols
										aRet = xSet->getPropertyValue( ::rtl::OUString::createFromAscii("Protocols") );
										Sequence < ::rtl::OUString > aTmp;
										aRet >>= aTmp;

										// todo: add operator+= to SequenceAsVector class and use SequenceAsVector for aProtocols
										sal_Int32 nLength = aProtocols.getLength();
										aProtocols.realloc( nLength+aTmp.getLength() );
										for ( sal_Int32 n=0; n<aTmp.getLength(); n++ )
											aProtocols[(++nLength)-1] = aTmp[n];
									}
								}
							}
						}
						catch ( Exception& )
						{
							// registered protocols could not be read
						}

						sal_Bool bFound = sal_False;
						for ( sal_Int32 nProt=0; nProt<aProtocols.getLength(); nProt++ )
						{
							WildCard aPattern(aProtocols[nProt]);
							if ( aPattern.Matches( aURL.Complete ) )
							{
								bFound = sal_True;
								break;
							}
						}

						if ( !bFound )
						{
							sal_Bool bLoadInternal = sal_False;

							// security reservation: => we have to check the referer before executing
							if (SFX_APP()->IsSecureURL(rtl::OUString(), &aReferer))
							{
								::rtl::OUString aURLString( aURL.Complete );
                                // Before letting the OS execute the URL, we may have to request for
                                // confirmation
                                if ( eMode == SvtExtendedSecurityOptions::OPEN_WITHSECURITYCHECK ) {
                                    // Check if file URL is a directory. This is not insecure!
                                    sal_Bool bIsDir = aINetURLObject.hasFinalSlash() ||
                                        ( osl::Directory(aURL.Main).open() ==
                                          osl::Directory::E_None );
                                    // Use SvtExtendedSecurityOptions::IsSecureHyperlink()
                                    // to check the extension of the link destination.
                                    sal_Bool bSafeExtension = aExtendedSecurityOptions.IsSecureHyperlink(aURL.Complete);
                                    if (!bIsDir && !bSafeExtension) {
                                        // Security check for local files depending on the extension
                                        vos::OGuard aGuard( Application::GetSolarMutex() );
                                        Window *pWindow = SFX_APP()->GetTopWindow();

                                        String aSecurityWarningBoxTitle( SfxResId( RID_SECURITY_WARNING_TITLE ));
                                        WarningBox	aSecurityWarningBox( pWindow, SfxResId( RID_SECURITY_WARNING_HYPERLINK ));
                                        aSecurityWarningBox.SetText( aSecurityWarningBoxTitle );

                                        // Replace %s with the real file name
                                        String aMsgText = aSecurityWarningBox.GetMessText();
                                        String aMainURL( aURL.Main );
                                        String aFileNameInMsg;

                                        if (!utl::LocalFileHelper::ConvertURLToPhysicalName( aMainURL, aFileNameInMsg )) {
                                            aFileNameInMsg = aMainURL;
                                        }
                                        aMsgText.SearchAndReplaceAscii( "%s", aFileNameInMsg );
                                        aSecurityWarningBox.SetMessText( aMsgText );

                                        if( aSecurityWarningBox.Execute() == RET_NO )
                                            return;
                                    }
                                }
								try
								{
									// give os this file
									xSystemShellExecute->execute( aURLString, ::rtl::OUString(), SystemShellExecuteFlags::DEFAULTS );
								}
								catch ( ::com::sun::star::lang::IllegalArgumentException& )
								{
									vos::OGuard aGuard( Application::GetSolarMutex() );
									Window *pWindow = SFX_APP()->GetTopWindow();
									ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
								}
								catch ( ::com::sun::star::system::SystemShellExecuteException& )
								{
									if ( !pFilter )
									{
										vos::OGuard aGuard( Application::GetSolarMutex() );
										Window *pWindow = SFX_APP()->GetTopWindow();
										ErrorBox( pWindow, SfxResId( MSG_ERR_NO_WEBBROWSER_FOUND )).Execute();
									}
									else
									{
										rReq.RemoveItem( SID_TARGETNAME );
										rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
										bLoadInternal = sal_True;
									}
								}
							}
							else
							{
								SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aURL.Complete );
								ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED );
							}

							if ( !bLoadInternal )
								return;
						}
					}
				}
			}
			else
			{
                // hyperlink document must be loaded into a new frame
				rReq.RemoveItem( SID_TARGETNAME );
                rReq.AppendItem( SfxStringItem( SID_TARGETNAME, String::CreateFromAscii("_default") ) );
			}
		}
	}

    if ( !SFX_APP()->IsSecureURL( INetURLObject(aFileName), &aReferer ) )
    {
        SfxErrorContext aCtx( ERRCTX_SFX_OPENDOC, aFileName );
        ErrorHandler::HandleError( ERRCODE_IO_ACCESSDENIED );
        return;
    }

	SfxFrame* pTargetFrame = NULL;
    Reference< XFrame > xTargetFrame;

    SFX_REQUEST_ARG(rReq, pFrameItem, SfxFrameItem, SID_DOCFRAME, sal_False);
	if ( pFrameItem )
		pTargetFrame = pFrameItem->GetFrame();

    if ( !pTargetFrame )
    {
        SFX_REQUEST_ARG(rReq, pUnoFrameItem, SfxUnoFrameItem, SID_FILLFRAME, sal_False);
	    if ( pUnoFrameItem )
		    xTargetFrame = pUnoFrameItem->GetFrame();
    }

    if ( !pTargetFrame && !xTargetFrame.is() && SfxViewFrame::Current() )
        pTargetFrame = &SfxViewFrame::Current()->GetFrame();

    // check if caller has set a callback
    SFX_REQUEST_ARG(rReq, pLinkItem, SfxLinkItem, SID_DONELINK, sal_False );

	// remove from Itemset, because it confuses the parameter transformation
	if ( pLinkItem )
		pLinkItem = (SfxLinkItem*) pLinkItem->Clone();

	rReq.RemoveItem( SID_DONELINK );

    // check if the view must be hidden
    sal_Bool bHidden = sal_False;
    SFX_REQUEST_ARG(rReq, pHidItem, SfxBoolItem, SID_HIDDEN, sal_False);
    if ( pHidItem )
        bHidden = pHidItem->GetValue();

    // This request is a UI call. We have to set the right values inside the MediaDescriptor
    // for: InteractionHandler, StatusIndicator, MacroExecutionMode and DocTemplate.
    // But we have to look for already existing values or for real hidden requests.
    SFX_REQUEST_ARG(rReq, pPreviewItem, SfxBoolItem, SID_PREVIEW, sal_False);
    if (!bHidden && ( !pPreviewItem || !pPreviewItem->GetValue() ) )
    {
        SFX_REQUEST_ARG(rReq, pInteractionItem, SfxUnoAnyItem, SID_INTERACTIONHANDLER, sal_False);
        SFX_REQUEST_ARG(rReq, pMacroExecItem  , SfxUInt16Item, SID_MACROEXECMODE     , sal_False);
        SFX_REQUEST_ARG(rReq, pDocTemplateItem, SfxUInt16Item, SID_UPDATEDOCMODE     , sal_False);

        if (!pInteractionItem)
        {
            Reference < ::com::sun::star::task::XInteractionHandler > xHdl( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.comp.uui.UUIInteractionHandler")), UNO_QUERY );
            if (xHdl.is())
                rReq.AppendItem( SfxUnoAnyItem(SID_INTERACTIONHANDLER,::com::sun::star::uno::makeAny(xHdl)) );
        }
        if (!pMacroExecItem)
            rReq.AppendItem( SfxUInt16Item(SID_MACROEXECMODE,::com::sun::star::document::MacroExecMode::USE_CONFIG) );
        if (!pDocTemplateItem)
            rReq.AppendItem( SfxUInt16Item(SID_UPDATEDOCMODE,::com::sun::star::document::UpdateDocMode::ACCORDING_TO_CONFIG) );
    }

    // extract target name
    ::rtl::OUString aTarget;
    SFX_REQUEST_ARG(rReq, pTargetItem, SfxStringItem, SID_TARGETNAME, sal_False);
    if ( pTargetItem )
        aTarget = pTargetItem->GetValue();
    else
    {
        SFX_REQUEST_ARG( rReq, pNewViewItem, SfxBoolItem, SID_OPEN_NEW_VIEW, sal_False );
        if ( pNewViewItem && pNewViewItem->GetValue() )
            aTarget = String::CreateFromAscii("_blank" );
    }

    if ( bHidden )
    {
        aTarget = String::CreateFromAscii("_blank");
        DBG_ASSERT( rReq.IsSynchronCall() || pLinkItem, "Hidden load process must be done synchronously!" );
    }

    Reference < XController > xController;
//    if ( ( !bIsBlankTarget && pFrame ) || pLinkItem || !rReq.IsSynchronCall() )
//    {
        // if a frame is given, it must be used for the starting point of the targeting mechanism
        // this code is also used if asynchronous loading is possible, because loadComponent always is synchron
        if ( !xTargetFrame.is() )
        {
            if ( pTargetFrame )
            {
                xTargetFrame = pTargetFrame->GetFrameInterface();
            }
            else
            {
                xTargetFrame.set( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY );
            }
        }

        // make URL ready
        SFX_REQUEST_ARG( rReq, pURLItem, SfxStringItem, SID_FILE_NAME, sal_False );
        aFileName = pURLItem->GetValue();
        if( aFileName.Len() && aFileName.GetChar(0) == '#' ) // Mark without URL
        {
            SfxViewFrame *pView = pTargetFrame ? pTargetFrame->GetCurrentViewFrame() : 0;
            if ( !pView )
                pView = SfxViewFrame::Current();
            pView->GetViewShell()->JumpToMark( aFileName.Copy(1) );
            rReq.SetReturnValue( SfxViewFrameItem( 0, pView ) );
            return;
        }

        // convert items to properties for framework API calls
        Sequence < PropertyValue > aArgs;
        TransformItems( SID_OPENDOC, *rReq.GetArgs(), aArgs );

        // TODO/LATER: either remove LinkItem or create an asynchronous process for it
        if( bHidden || pLinkItem || rReq.IsSynchronCall() )
        {
            // if loading must be done synchron, we must wait for completion to get a return value
            // find frame by myself; I must know the exact frame to get the controller for the return value from it
            //if( aTarget.getLength() )
            //    xTargetFrame = xTargetFrame->findFrame( aTarget, FrameSearchFlag::ALL );
            Reference < XComponent > xComp;

            try
            {
                xComp = ::comphelper::SynchronousDispatch::dispatch( xTargetFrame, aFileName, aTarget, 0, aArgs );
//                Reference < XComponentLoader > xLoader( xTargetFrame, UNO_QUERY );
//                xComp = xLoader->loadComponentFromURL( aFileName, aTarget, 0, aArgs );
            }
            catch(const RuntimeException&)
            {
                throw;
            }
            catch(const ::com::sun::star::uno::Exception&)
            {
            }

            Reference < XModel > xModel( xComp, UNO_QUERY );
            if ( xModel.is() )
                xController = xModel->getCurrentController();
            else
                xController = Reference < XController >( xComp, UNO_QUERY );

        }
        else
        {
            URL aURL;
            aURL.Complete = aFileName;
            Reference < XURLTransformer > xTrans( ::comphelper::getProcessServiceFactory()->createInstance( rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer" )), UNO_QUERY );
            xTrans->parseStrict( aURL );

            Reference < XDispatchProvider > xProv( xTargetFrame, UNO_QUERY );
            Reference < XDispatch > xDisp = xProv.is() ? xProv->queryDispatch( aURL, aTarget, FrameSearchFlag::ALL ) : Reference < XDispatch >();
			RTL_LOGFILE_PRODUCT_CONTEXT( aLog2, "PERFORMANCE - SfxApplication::OpenDocExec_Impl" );
            if ( xDisp.is() )
                xDisp->dispatch( aURL, aArgs );
        }
    /*
    }
    else
    {
        // synchron loading without a given frame or as blank frame
        SFX_REQUEST_ARG( rReq, pFileNameItem, SfxStringItem, SID_FILE_NAME, sal_False );

        // Desktop service must exists! dont catch() or check for problems here ...
        // But loading of documents can fail by other reasons. Handle it more gracefully.
        Reference < XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance(::rtl::OUString::createFromAscii("com.sun.star.frame.Desktop")), UNO_QUERY );
        Reference < XComponent >       xComp;
        try
        {
            xComp = xDesktop->loadComponentFromURL( pFileNameItem->GetValue(), aTarget, 0, aArgs );
        }
        catch(const RuntimeException&)
        {
            throw;
        }
        catch(const ::com::sun::star::uno::Exception&)
        {
            xDesktop.clear();
            xComp.clear();
        }

		Reference < XModel > xModel( xComp, UNO_QUERY );
        if ( xModel.is() )
            xController = xModel->getCurrentController();
		else
			xController = Reference < XController >( xComp, UNO_QUERY );
    }*/

	if ( xController.is() )
	{
		// try to find the SfxFrame for the controller
		SfxFrame* pCntrFrame = NULL;
		for ( SfxViewShell* pShell = SfxViewShell::GetFirst( 0, sal_False ); pShell; pShell = SfxViewShell::GetNext( *pShell, 0, sal_False ) )
		{
		    if ( pShell->GetController() == xController )
		    {
		        pCntrFrame = &pShell->GetViewFrame()->GetFrame();
		        break;
		    }
		}

		if ( pCntrFrame )
		{
		    SfxObjectShell* pSh = pCntrFrame->GetCurrentDocument();
		    DBG_ASSERT( pSh, "Controller without ObjectShell ?!" );

	        rReq.SetReturnValue( SfxViewFrameItem( 0, pCntrFrame->GetCurrentViewFrame() ) );

		    if ( bHidden )
		        pSh->RestoreNoDelete();
		}
	}

	if ( pLinkItem )
	{
		SfxPoolItem* pRet = rReq.GetReturnValue()->Clone();
		pLinkItem->GetValue().Call(pRet);
		delete pLinkItem;
	}
}
