/**************************************************************
 *
 * 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_framework.hxx"
//_______________________________________________
// includes of own project
#include <loadenv/loadenv.hxx>

#ifndef __FRAMEWORK_LOADENV_TARGETHELPER_HXX_
#include <loadenv/targethelper.hxx>
#endif
#include <framework/framelistanalyzer.hxx>

#ifndef __FRAMEWORK_CONSTANT_FRAMELOADER_HXX_
#include <constant/frameloader.hxx>
#endif

#ifndef __FRAMEWORK_CONSTANT_CONTENTHANDLER_HXX_
#include <constant/contenthandler.hxx>
#endif

#ifndef __FRAMEWORK_CONSTANT_CONTAINERQUERY_HXX_
#include <constant/containerquery.hxx>
#endif
#include <interaction/quietinteraction.hxx>
#include <threadhelp/writeguard.hxx>
#include <threadhelp/readguard.hxx>
#include <threadhelp/resetableguard.hxx>
#include <properties.h>
#include <protocols.h>
#include <services.h>
#include <comphelper/interaction.hxx>
#include <framework/interaction.hxx>

//_______________________________________________
// includes of uno interface
#include <com/sun/star/task/ErrorCodeRequest.hpp>
#include <com/sun/star/uno/RuntimeException.hpp>
#include <com/sun/star/frame/DispatchResultState.hpp>
#include <com/sun/star/frame/FrameSearchFlag.hpp>
#include <com/sun/star/util/XURLTransformer.hpp>
#include <com/sun/star/ucb/XContentProviderManager.hpp>
#include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/awt/XWindow.hpp>
#include <com/sun/star/awt/XWindow2.hpp>
#include <com/sun/star/awt/XTopWindow.hpp>
#include <com/sun/star/frame/XModel.hpp>
#include <com/sun/star/frame/XFrameLoader.hpp>
#include <com/sun/star/frame/XSynchronousFrameLoader.hpp>
#include <com/sun/star/frame/XNotifyingDispatch.hpp>
#include <com/sun/star/task/XStatusIndicatorFactory.hpp>
#include <com/sun/star/task/XStatusIndicator.hpp>
#include <com/sun/star/util/XModifiable.hpp>
#include <com/sun/star/frame/XDispatchProvider.hpp>
#include <com/sun/star/document/XTypeDetection.hpp>
#include <com/sun/star/document/XActionLockable.hpp>
#include <com/sun/star/io/XInputStream.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/container/XNameAccess.hpp>
#include <com/sun/star/container/XContainerQuery.hpp>
#include <com/sun/star/container/XEnumeration.hpp>
#include <com/sun/star/document/MacroExecMode.hpp>
#include <com/sun/star/document/UpdateDocMode.hpp>

//_______________________________________________
// includes of an other project
#include <vcl/window.hxx>
#include <vcl/wrkwin.hxx>
#include <vcl/syswin.hxx>

#ifndef _TOOLKIT_HELPER_VCLUNOHELPER_HXX_
#include <toolkit/helper/vclunohelper.hxx>
#endif
#include <unotools/moduleoptions.hxx>
#include <svtools/sfxecode.hxx>
#include <unotools/processfactory.hxx>
#include <unotools/ucbhelper.hxx>
#include <comphelper/configurationhelper.hxx>
#include <rtl/ustrbuf.hxx>
#include <vcl/svapp.hxx>

//_______________________________________________
// namespace

namespace framework{

// may there exist already a define .-(
#ifndef css
namespace css = ::com::sun::star;
#endif

//_______________________________________________
// declarations

class LoadEnvListener : private ThreadHelpBase
                      , public ::cppu::WeakImplHelper2< css::frame::XLoadEventListener      ,
                                                        css::frame::XDispatchResultListener >
{
    private:

        void**   m_ppCheck ;
        LoadEnv* m_pLoadEnv;

    public:

        //_______________________________________
        LoadEnvListener(void*    pCheck  ,
                        LoadEnv* pLoadEnv)
        {
            m_ppCheck  = &pCheck ;
            m_pLoadEnv = pLoadEnv;
        }

        //_______________________________________
        // frame.XLoadEventListener
        virtual void SAL_CALL loadFinished(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
            throw(css::uno::RuntimeException);

        virtual void SAL_CALL loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >& xLoader)
            throw(css::uno::RuntimeException);

        //_______________________________________
        // frame.XDispatchResultListener
        virtual void SAL_CALL dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
            throw(css::uno::RuntimeException);

        //_______________________________________
        // lang.XEventListener
        virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent)
            throw(css::uno::RuntimeException);
};

/*-----------------------------------------------
    14.10.2003 13:43
-----------------------------------------------*/
LoadEnv::LoadEnv(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
    throw(LoadEnvException, css::uno::RuntimeException)
    : ThreadHelpBase(     )
    , m_xSMGR       (xSMGR)
    , m_pCheck      (this )
	, m_pQuietInteraction( 0 )
{
}

/*-----------------------------------------------
    14.10.2003 13:43
-----------------------------------------------*/
LoadEnv::~LoadEnv()
{
    m_pCheck = 0;
}

/*-----------------------------------------------
    10.09.2003 14:05
-----------------------------------------------*/
css::uno::Reference< css::lang::XComponent > LoadEnv::loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >&    xLoader,
                                                                           const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR  ,
                                                                           const ::rtl::OUString&                                        sURL   ,
                                                                           const ::rtl::OUString&                                        sTarget,
                                                                                 sal_Int32                                               nFlags ,
                                                                           const css::uno::Sequence< css::beans::PropertyValue >&        lArgs  )
    throw(css::lang::IllegalArgumentException,
          css::io::IOException               ,
          css::uno::RuntimeException         )
{
#ifdef WNT
	CEnableAccessInterface e;
#endif
    css::uno::Reference< css::lang::XComponent > xComponent;

    try
    {
        LoadEnv aEnv(xSMGR);

        aEnv.initializeLoading(sURL,
                               lArgs,
                               css::uno::Reference< css::frame::XFrame >(xLoader, css::uno::UNO_QUERY),
                               sTarget,
                               nFlags,
                               LoadEnv::E_NO_FEATURE);
        aEnv.startLoading();
        aEnv.waitWhileLoading(); // wait for ever!

        xComponent = aEnv.getTargetComponent();
    }
    catch(const LoadEnvException& ex)
    {
        switch(ex.m_nID)
        {
            case LoadEnvException::ID_INVALID_MEDIADESCRIPTOR:
                    throw css::lang::IllegalArgumentException(
                            ::rtl::OUString::createFromAscii("Optional list of arguments seem to be corrupted."),
                            xLoader,
                            4);

            case LoadEnvException::ID_UNSUPPORTED_CONTENT:
                    throw css::lang::IllegalArgumentException(
                            ::rtl::OUString::createFromAscii("URL seems to be an unsupported one."),
                            xLoader,
                            1);

			default: xComponent.clear();
                    break;
        }
    }

    return xComponent;
}

//-----------------------------------------------
::comphelper::MediaDescriptor impl_mergeMediaDescriptorWithMightExistingModelArgs(const css::uno::Sequence< css::beans::PropertyValue >& lOutsideDescriptor)
{
    ::comphelper::MediaDescriptor lDescriptor(lOutsideDescriptor);
    css::uno::Reference< css::frame::XModel > xModel     = lDescriptor.getUnpackedValueOrDefault(
                                                            ::comphelper::MediaDescriptor::PROP_MODEL (),
                                                            css::uno::Reference< css::frame::XModel > ());
    if (xModel.is ())
    {
        ::comphelper::MediaDescriptor lModelDescriptor(xModel->getArgs());
        ::comphelper::MediaDescriptor::iterator pIt = lModelDescriptor.find( ::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE() );
		if ( pIt != lModelDescriptor.end() )
			lDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] = pIt->second;
    }

    return lDescriptor;
}

/*-----------------------------------------------
    20.08.2003 09:49
-----------------------------------------------*/
void LoadEnv::initializeLoading(const ::rtl::OUString&                                           sURL            ,
                                const css::uno::Sequence< css::beans::PropertyValue >&           lMediaDescriptor,
                                const css::uno::Reference< css::frame::XFrame >&                 xBaseFrame      ,
                                const ::rtl::OUString&                                           sTarget         ,
                                      sal_Int32                                                  nSearchFlags    ,
                                      EFeature                                                   eFeature        , // => use default ...
                                      EContentType                                               eContentType    ) // => use default ...
    throw(LoadEnvException, css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);

    // Handle still running processes!
    if (m_xAsynchronousJob.is())
        throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);

    // take over all new parameters.
    m_xTargetFrame.clear();
    m_xBaseFrame                    = xBaseFrame        ;
    m_lMediaDescriptor              = impl_mergeMediaDescriptorWithMightExistingModelArgs(lMediaDescriptor);
    m_sTarget                       = sTarget           ;
    m_nSearchFlags                  = nSearchFlags      ;
    m_eFeature                      = eFeature          ;
    m_eContentType                  = eContentType      ;
    m_bCloseFrameOnError            = sal_False         ;
    m_bReactivateControllerOnError  = sal_False         ;
    m_bLoaded                       = sal_False         ;

    // try to find out, if its really a content, which can be loaded or must be "handled"
    // We use a default value for this in-parameter. Then we have to start a complex check method
    // internally. But if this check was already done outside it can be suppressed to perform
    // the load request. We take over the result then!
    if (m_eContentType == E_UNSUPPORTED_CONTENT)
    {
        m_eContentType = LoadEnv::classifyContent(sURL, lMediaDescriptor);
        if (m_eContentType == E_UNSUPPORTED_CONTENT)
            throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);
    }

    // make URL part of the MediaDescriptor
    // It doesn't mater, if its already an item of it.
    // It must be the same value ... so we can overwrite it :-)
    m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_URL()] <<= sURL;

    // parse it - because some following code require that
    m_aURL.Complete = sURL;
    css::uno::Reference< css::util::XURLTransformer > xParser(m_xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY);
    xParser->parseStrict(m_aURL);

    // BTW: Split URL and JumpMark ...
    // Because such mark is an explicit value of the media descriptor!
    if (m_aURL.Mark.getLength())
        m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_JUMPMARK()] <<= m_aURL.Mark;

    // By the way: remove the old and deprecated value "FileName" from the descriptor!
    ::comphelper::MediaDescriptor::iterator pIt = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FILENAME());
    if (pIt != m_lMediaDescriptor.end())
        m_lMediaDescriptor.erase(pIt);

    // patch the MediaDescriptor, so it fulfill the outside requirements
    // Means especially items like e.g. UI InteractionHandler, Status Indicator,
    // MacroExecutionMode etcpp.

    /*TODO progress is bound to a frame ... How can we set it here? */

    // UI mode
    const bool bUIMode =
        ( ( m_eFeature & E_WORK_WITH_UI )                                                                          == E_WORK_WITH_UI ) &&
        ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_HIDDEN() , sal_False ) == sal_False      ) &&
        ( m_lMediaDescriptor.getUnpackedValueOrDefault( ::comphelper::MediaDescriptor::PROP_PREVIEW(), sal_False ) == sal_False      );

    initializeUIDefaults(
        m_xSMGR,
        m_lMediaDescriptor,
        bUIMode,
        &m_pQuietInteraction
    );

    aWriteLock.unlock();
    // <- SAFE ----------------------------------
}

/*-----------------------------------------------
    22.01.2010
-----------------------------------------------*/
void LoadEnv::initializeUIDefaults( const css::uno::Reference< css::lang::XMultiServiceFactory >& i_rSMGR,
                                    ::comphelper::MediaDescriptor& io_lMediaDescriptor, const bool i_bUIMode,
                                    QuietInteraction** o_ppQuietInteraction )
{
    css::uno::Reference< css::task::XInteractionHandler > xInteractionHandler;
    sal_Int16                                             nMacroMode         ;
    sal_Int16                                             nUpdateMode        ;

    if ( i_bUIMode )
    {
        nMacroMode  = css::document::MacroExecMode::USE_CONFIG;
        nUpdateMode = css::document::UpdateDocMode::ACCORDING_TO_CONFIG;
        try
        {
            xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(i_rSMGR->createInstance(IMPLEMENTATIONNAME_UIINTERACTIONHANDLER), css::uno::UNO_QUERY);
        }
        catch(const css::uno::RuntimeException&) {throw;}
        catch(const css::uno::Exception&       ) {      }
    }
    // hidden mode
    else
    {
        nMacroMode  = css::document::MacroExecMode::NEVER_EXECUTE;
        nUpdateMode = css::document::UpdateDocMode::NO_UPDATE;
        QuietInteraction* pQuietInteraction = new QuietInteraction();
        xInteractionHandler = css::uno::Reference< css::task::XInteractionHandler >(static_cast< css::task::XInteractionHandler* >(pQuietInteraction), css::uno::UNO_QUERY);
        if ( o_ppQuietInteraction != NULL )
        {
            *o_ppQuietInteraction = pQuietInteraction;
            (*o_ppQuietInteraction)->acquire();
        }
    }

    if (
        (xInteractionHandler.is()                                                                                       ) &&
        (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()) == io_lMediaDescriptor.end())
       )
    {
        io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER()] <<= xInteractionHandler;
        io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_AUTHENTICATIONHANDLER()] <<= xInteractionHandler;
    }

    if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()) == io_lMediaDescriptor.end())
        io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_MACROEXECUTIONMODE()] <<= nMacroMode;

    if (io_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()) == io_lMediaDescriptor.end())
        io_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_UPDATEDOCMODE()] <<= nUpdateMode;
}

/*-----------------------------------------------
    15.08.2003 08:16
-----------------------------------------------*/
void LoadEnv::startLoading()
    throw(LoadEnvException, css::uno::RuntimeException)
{
    // SAFE ->
    ReadGuard aReadLock(m_aLock);

    // Handle still running processes!
    if (m_xAsynchronousJob.is())
        throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);

    // content can not be loaded or handled
    // check "classifyContent()" failed before ...
    if (m_eContentType == E_UNSUPPORTED_CONTENT)
        throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);

    // <- SAFE
    aReadLock.unlock();

    // detect its type/filter etcpp.
    // These information will be available by the
    // used descriptor member afterwards and is needed
    // for all following operations!
    // Note: An exception will be thrown, in case operation was not successfully ...
    if (m_eContentType != E_CAN_BE_SET)/* Attention: special feature to set existing component on a frame must ignore type detection! */
        impl_detectTypeAndFilter();

    // start loading the content ...
    // Attention: Dont check m_eContentType deeper then UNSUPPORTED/SUPPORTED!
    // Because it was made in th easiest way ... may a flat detection was made only.
    // And such simple detection can fail some times .-)
    // Use another strategy here. Try it and let it run into the case "loading not possible".
    sal_Bool bStarted = sal_False;
    if (
        ((m_eFeature & E_ALLOW_CONTENTHANDLER) == E_ALLOW_CONTENTHANDLER) &&
        (m_eContentType                        != E_CAN_BE_SET          )   /* Attention: special feature to set existing component on a frame must ignore type detection! */
       )
    {
        bStarted = impl_handleContent();
    }

    if (!bStarted)
        bStarted = impl_loadContent();

    // not started => general error
    // We can't say - what was the reason for.
    if (!bStarted)
        throw LoadEnvException(LoadEnvException::ID_GENERAL_ERROR);
}

/*-----------------------------------------------
    15.08.2003 09:50
    TODO
        First draft does not implement timeout using [ms].
        Current implementation counts yield calls only ...
-----------------------------------------------*/
sal_Bool LoadEnv::waitWhileLoading(sal_uInt32 nTimeout)
    throw(LoadEnvException, css::uno::RuntimeException)
{
    // Because its not a good idea to block the main thread
    // (and we can't be sure that we are currently not used inside the
    // main thread!), we can't use conditions here really. We must yield
    // in an intellegent manner :-)

    sal_Int32 nTime = nTimeout;
    while(true)
    {
        // SAFE -> ------------------------------
        ReadGuard aReadLock1(m_aLock);
        if (!m_xAsynchronousJob.is())
            break;
        aReadLock1.unlock();
        // <- SAFE ------------------------------

        Application::Yield();

        // forever!
        if (nTimeout==0)
            continue;

        // timed out?
        --nTime;
        if (nTime<1)
            break;
    }

    // SAFE -> ----------------------------------
    ReadGuard aReadLock2(m_aLock);
    return !m_xAsynchronousJob.is();
    // <- SAFE ----------------------------------
}

/*-----------------------------------------------
    20.08.2003 10:00
-----------------------------------------------*/
void LoadEnv::cancelLoading()
    throw(LoadEnvException, css::uno::RuntimeException)
{
    // PARTIAL(!) SAFE -> ------------------------------
    ReadGuard aReadLock(m_aLock);

    // Still running? Might waitWhileLoading()
    // runned into the timeout!
    if (m_xAsynchronousJob.is())
    {
        // try to cancel it ... if its an asynchronous frame loader
        css::uno::Reference< css::frame::XFrameLoader > xAsyncLoader(m_xAsynchronousJob, css::uno::UNO_QUERY);
        if (xAsyncLoader.is())
        {
            aReadLock.unlock();
            // <- BREAK SAFE ------------------------------
            xAsyncLoader->cancel();
            // <- RESTART SAFE ----------------------------
            aReadLock.lock();
            /* Attention:
                After returning from any cancel/dispose call, neither the frame nor weself
                may be called back. Because only we can cancel this job, we already know
                the result! => That's why it's not useful nor necessary to wait for any
                asynchronous listener notification.
            */
            m_bLoaded = sal_False;
            m_xAsynchronousJob.clear();
        }
        // or may be it's a content handler? Such handler can't be cancelled in its running
        // operation :-( And we can't deregister us there again :-(
        // => The only chance is an exception :-)
        else
            throw LoadEnvException(LoadEnvException::ID_STILL_RUNNING);
    }

    impl_reactForLoadingState();

    aReadLock.unlock();
    // <- PARTIAL(!) SAFE ------------------------------
}

/*-----------------------------------------------
    14.08.2003 13:33
-----------------------------------------------*/
css::uno::Reference< css::frame::XFrame > LoadEnv::getTarget() const
{
    // SAFE ->
    ReadGuard aReadLock(m_aLock);
    return m_xTargetFrame;
    // <- SAFE
}

/*-----------------------------------------------
    14.08.2003 13:35
-----------------------------------------------*/
css::uno::Reference< css::lang::XComponent > LoadEnv::getTargetComponent() const
{
    // SAFE ->
    ReadGuard aReadLock(m_aLock);

    if (!m_xTargetFrame.is())
        return css::uno::Reference< css::lang::XComponent >();

    css::uno::Reference< css::frame::XController > xController = m_xTargetFrame->getController();
    if (!xController.is())
        return css::uno::Reference< css::lang::XComponent >(m_xTargetFrame->getComponentWindow(), css::uno::UNO_QUERY);

    css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
    if (!xModel.is())
        return css::uno::Reference< css::lang::XComponent >(xController, css::uno::UNO_QUERY);

    return css::uno::Reference< css::lang::XComponent >(xModel, css::uno::UNO_QUERY);
    // <- SAFE
}

/*-----------------------------------------------
    15.08.2003 11:15
-----------------------------------------------*/
void SAL_CALL LoadEnvListener::loadFinished(const css::uno::Reference< css::frame::XFrameLoader >&)
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);

    if (m_ppCheck && *m_ppCheck)
        m_pLoadEnv->impl_setResult(sal_True);
    m_ppCheck = NULL;

    aWriteLock.unlock();
    // <- SAFE ----------------------------------
}

/*-----------------------------------------------
    14.10.2003 12:23
-----------------------------------------------*/
void SAL_CALL LoadEnvListener::loadCancelled(const css::uno::Reference< css::frame::XFrameLoader >&)
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);

    if (m_ppCheck && *m_ppCheck)
        m_pLoadEnv->impl_setResult(sal_False);
    m_ppCheck = NULL;

    aWriteLock.unlock();
    // <- SAFE ----------------------------------
}

/*-----------------------------------------------
    14.10.2003 12:23
-----------------------------------------------*/
void SAL_CALL LoadEnvListener::dispatchFinished(const css::frame::DispatchResultEvent& aEvent)
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);

    if (!m_ppCheck || !*m_ppCheck)
        return;

    switch(aEvent.State)
    {
        case css::frame::DispatchResultState::FAILURE :
            m_pLoadEnv->impl_setResult(sal_False);
            break;

        case css::frame::DispatchResultState::SUCCESS :
            m_pLoadEnv->impl_setResult(sal_False);
            break;

        case css::frame::DispatchResultState::DONTKNOW :
            m_pLoadEnv->impl_setResult(sal_False);
            break;
    }
    m_ppCheck = NULL;

    aWriteLock.unlock();
    // <- SAFE ----------------------------------
}

/*-----------------------------------------------
    14.10.2003 12:24
-----------------------------------------------*/
void SAL_CALL LoadEnvListener::disposing(const css::lang::EventObject&)
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);

    if (m_ppCheck && *m_ppCheck)
        m_pLoadEnv->impl_setResult(sal_False);
    m_ppCheck = NULL;

    aWriteLock.unlock();
    // <- SAFE ----------------------------------
}

/*-----------------------------------------------
    14.10.2003 12:20
-----------------------------------------------*/
void LoadEnv::impl_setResult(sal_Bool bResult)
{
    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);

    m_bLoaded = bResult;

    impl_reactForLoadingState();

    // clearing of this reference will unblock waitWhileLoading()!
    // So we must be sure, that loading process was really finished.
    // => do it as last operation of this method ...
    m_xAsynchronousJob.clear();

    aWriteLock.unlock();
    // <- SAFE ----------------------------------
}

/*-----------------------------------------------
    06.02.2004 14:03
    TODO: Is it a good idea to change Sequence<>
          parameter to stl-adapter?
-----------------------------------------------*/
LoadEnv::EContentType LoadEnv::classifyContent(const ::rtl::OUString&                                 sURL            ,
                                               const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor)
{
    //-------------------------------------------
    // (i) Filter some special well known URL protocols,
    //     which can not be handled or loaded in general.
    //     Of course an empty URL must be ignored here too.
    //     Note: These URL schemata are fix and well known ...
    //     But there can be some additional ones, which was not
    //     defined at implementation time of this class :-(
    //     So we have to make sure, that the following code
    //     can detect such protocol schemata too :-)

    if(
        (!sURL.getLength()                                       ) ||
        (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_UNO    )) ||
        (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SLOT   )) ||
        (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MACRO  )) ||
        (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_SERVICE)) ||
        (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_MAILTO )) ||
        (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_NEWS   ))
      )
    {
        return E_UNSUPPORTED_CONTENT;
    }

    //-------------------------------------------
    // (ii) Some special URLs indicates a given input stream,
    //      a full featured document model directly or
    //      specify a request for opening an empty document.
    //      Such contents are loadable in general.
    //      But we have to check, if the media descriptor contains
    //      all needed resources. If they are missing - the following
    //      load request will fail.

    /* Attention: The following code can't work on such special URLs!
                  It should not break the office .. but it make no sense
                  to start expensive object creations and complex search
                  algorithm if its clear, that such URLs must be handled
                  in a special way .-)
    */

    // creation of new documents
    if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_FACTORY))
        return E_CAN_BE_LOADED;

    // using of an existing input stream
    ::comphelper::MediaDescriptor                 stlMediaDescriptor(lMediaDescriptor);
    ::comphelper::MediaDescriptor::const_iterator pIt;
    if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_STREAM))
    {
        pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_INPUTSTREAM());
        css::uno::Reference< css::io::XInputStream > xStream;
        if (pIt != stlMediaDescriptor.end())
            pIt->second >>= xStream;
        if (xStream.is())
            return E_CAN_BE_LOADED;
        LOG_WARNING("LoadEnv::classifyContent()", "loading from stream with right URL but invalid stream detected")
        return E_UNSUPPORTED_CONTENT;
    }

    // using of a full featured document
    if (ProtocolCheck::isProtocol(sURL,ProtocolCheck::E_PRIVATE_OBJECT))
    {
        pIt = stlMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_MODEL());
        css::uno::Reference< css::frame::XModel > xModel;
        if (pIt != stlMediaDescriptor.end())
            pIt->second >>= xModel;
        if (xModel.is())
            return E_CAN_BE_SET;
        LOG_WARNING("LoadEnv::classifyContent()", "loading with object with right URL but invalid object detected")
        return E_UNSUPPORTED_CONTENT;
    }

    // following operations can work on an internal type name only :-(
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = ::utl::getProcessServiceFactory();
    css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY);

    ::rtl::OUString sType = xDetect->queryTypeByURL(sURL);

    css::uno::Sequence< css::beans::NamedValue >           lQuery(1)   ;
    css::uno::Reference< css::container::XContainerQuery > xContainer  ;
    css::uno::Reference< css::container::XEnumeration >    xSet        ;
    css::uno::Sequence< ::rtl::OUString >                  lTypesReg(1);

    /*
    //-------------------------------------------
    lQuery[0].Name    = ::framework::constant::Filter::PROP_TYPE;
    lQuery[0].Value <<= sType;

    xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY);
    xSet       = xContainer->createSubSetEnumerationByProperties(lQuery);
    // at least one registered frame loader is enough!
    if (xSet->hasMoreElements())
        return E_CAN_BE_LOADED;
    */

    //-------------------------------------------
    // (iii) If a FrameLoader service (or at least
    //      a Filter) can be found, which supports
    //      this URL - it must be a loadable content.
    //      Because both items are registered for types
    //      its enough to check for frame loaders only.
    //      Mos of our filters are handled by our global
    //      default loader. But there exist some specialized
    //      loader, which does not work on top of filters!
    //      So its not enough to search on the filter configuration.
    //      Further its not enough to search for types!
    //      Because there exist some types, which are referenced by
    //      other objects ... but not by filters nor frame loaders!

    lTypesReg[0]      = sType;
    lQuery[0].Name    = ::framework::constant::FrameLoader::PROP_TYPES;
    lQuery[0].Value <<= lTypesReg;

    xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY);
    xSet       = xContainer->createSubSetEnumerationByProperties(lQuery);
    // at least one registered frame loader is enough!
    if (xSet->hasMoreElements())
        return E_CAN_BE_LOADED;

    //-------------------------------------------
    // (iv) Some URL protocols are supported by special services.
    //      E.g. ContentHandler.
    //      Such contents can be handled ... but not loaded.

    lTypesReg[0]      = sType;
    lQuery[0].Name    = ::framework::constant::ContentHandler::PROP_TYPES;
    lQuery[0].Value <<= lTypesReg;

    xContainer = css::uno::Reference< css::container::XContainerQuery >(xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY);
    xSet       = xContainer->createSubSetEnumerationByProperties(lQuery);
    // at least one registered content handler is enough!
    if (xSet->hasMoreElements())
        return E_CAN_BE_HANDLED;

    //-------------------------------------------
    // (v) Last but not least the UCB is used inside office to
    //     load contents. He has a special configuration to know
    //     which URL schemata can be used inside office.
    css::uno::Reference< css::ucb::XContentProviderManager > xUCB(xSMGR->createInstance(SERVICENAME_UCBCONTENTBROKER), css::uno::UNO_QUERY);
    if (xUCB->queryContentProvider(sURL).is())
        return E_CAN_BE_LOADED;

    //-------------------------------------------
    // (TODO) At this point, we have no idea .-)
    //        But it seems to be better, to break all
    //        further requests for this URL. Otherwise
    //        we can run into some trouble.
    return E_UNSUPPORTED_CONTENT;
}

/*-----------------------------------------------
    03.11.2003 09:31
-----------------------------------------------*/
void LoadEnv::impl_detectTypeAndFilter()
    throw(LoadEnvException, css::uno::RuntimeException)
{
    static ::rtl::OUString TYPEPROP_PREFERREDFILTER = ::rtl::OUString::createFromAscii("PreferredFilter");
    static ::rtl::OUString FILTERPROP_FLAGS         = ::rtl::OUString::createFromAscii("Flags"          );
    static sal_Int32       FILTERFLAG_TEMPLATEPATH  = 16;

    // SAFE ->
    ReadGuard aReadLock(m_aLock);

    // Attention: Because our stl media descriptor is a copy of an uno sequence
    // we can't use as an in/out parameter here. Copy it before and dont forget to
    // update structure afterwards again!
    css::uno::Sequence< css::beans::PropertyValue >        lDescriptor = m_lMediaDescriptor.getAsConstPropertyValueList();
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR       = m_xSMGR;

    aReadLock.unlock();
    // <- SAFE

    ::rtl::OUString sType;
    css::uno::Reference< css::document::XTypeDetection > xDetect(xSMGR->createInstance(SERVICENAME_TYPEDETECTION), css::uno::UNO_QUERY);
    if (xDetect.is())
        sType = xDetect->queryTypeByDescriptor(lDescriptor, sal_True); /*TODO should deep detection be able for enable/disable it from outside? */

    // no valid content -> loading not possible
    if (!sType.getLength())
        throw LoadEnvException(LoadEnvException::ID_UNSUPPORTED_CONTENT);

    // SAFE ->
    WriteGuard aWriteLock(m_aLock);

    // detection was successfully => update the descriptor member of this class
    m_lMediaDescriptor << lDescriptor;
    m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_TYPENAME()] <<= sType;
    // Is there an already detected (may be preselected) filter?
    // see below ...
    ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_FILTERNAME(), ::rtl::OUString());

    aWriteLock.unlock();
    // <- SAFE

    // But the type isn't enough. For loading sometimes we need more informations.
    // E.g. for our "_default" feature, where we recylce any frame which contains
    // and "Untitled" document, we must know if the new document is based on a template!
    // But this information is available as a filter property only.
    // => We must try(!) to detect the right filter for this load request.
    // On the other side ... if no filter is available .. ignore it.
    // Then the type information must be enough.
    if (!sFilter.getLength())
    {
        // no -> try to find a preferred filter for the detected type.
        // Dont forget to updatet he media descriptor.
        css::uno::Reference< css::container::XNameAccess > xTypeCont(xDetect, css::uno::UNO_QUERY_THROW);
        try
        {
            ::comphelper::SequenceAsHashMap lTypeProps(xTypeCont->getByName(sType));
            sFilter = lTypeProps.getUnpackedValueOrDefault(TYPEPROP_PREFERREDFILTER, ::rtl::OUString());
            if (sFilter.getLength())
            {
                // SAFE ->
                aWriteLock.lock();
                m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_FILTERNAME()] <<= sFilter;
                aWriteLock.unlock();
                // <- SAFE
            }
        }
        catch(const css::container::NoSuchElementException&)
            {}
    }

    // check if the filter (if one exists) points to a template format filter.
    // Then we have to add the property "AsTemplate".
    // We need this information to decide afterwards if we can use a "recycle frame"
    // for target "_default" or has to create a new one everytimes.
    // On the other side we have to suppress that, if this property already exists
    // and should trigger a special handling. Then the outside calli of this method here,
    // has to know, what he is doing .-)

    sal_Bool bIsOwnTemplate = sal_False;
    if (sFilter.getLength())
    {
        css::uno::Reference< css::container::XNameAccess > xFilterCont(xSMGR->createInstance(SERVICENAME_FILTERFACTORY), css::uno::UNO_QUERY_THROW);
        try
        {
            ::comphelper::SequenceAsHashMap lFilterProps(xFilterCont->getByName(sFilter));
            sal_Int32 nFlags         = lFilterProps.getUnpackedValueOrDefault(FILTERPROP_FLAGS, (sal_Int32)0);
                      bIsOwnTemplate = ((nFlags & FILTERFLAG_TEMPLATEPATH) == FILTERFLAG_TEMPLATEPATH);
        }
        catch(const css::container::NoSuchElementException&)
            {}
    }
    if (bIsOwnTemplate)
    {
        // SAFE ->
        aWriteLock.lock();
        // Dont overwrite external decisions! See comments before ...
        ::comphelper::MediaDescriptor::const_iterator pAsTemplateItem = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_ASTEMPLATE());
        if (pAsTemplateItem == m_lMediaDescriptor.end())
            m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_ASTEMPLATE()] <<= sal_True;
        aWriteLock.unlock();
        // <- SAFE
    }
}

/*-----------------------------------------------
    15.08.2003 09:38
-----------------------------------------------*/
sal_Bool LoadEnv::impl_handleContent()
    throw(LoadEnvException, css::uno::RuntimeException)
{
    // SAFE -> -----------------------------------
    ReadGuard aReadLock(m_aLock);

    // the type must exist inside the descriptor ... otherwise this class is implemented wrong :-)
    ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString());
    if (!sType.getLength())
        throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);

    // convert media descriptor and URL to right format for later interface call!
    css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
    m_lMediaDescriptor >> lDescriptor;
    css::util::URL aURL = m_aURL;

    // get necessary container to query for a handler object
    css::uno::Reference< css::lang::XMultiServiceFactory > xFactory(m_xSMGR->createInstance(SERVICENAME_CONTENTHANDLERFACTORY), css::uno::UNO_QUERY);
    css::uno::Reference< css::container::XContainerQuery > xQuery  (xFactory                                                  , css::uno::UNO_QUERY);

    aReadLock.unlock();
    // <- SAFE -----------------------------------

    // query
    css::uno::Sequence< ::rtl::OUString > lTypeReg(1);
    lTypeReg[0] = sType;

    css::uno::Sequence< css::beans::NamedValue > lQuery(1);
    lQuery[0].Name    = ::framework::constant::ContentHandler::PROP_TYPES;
    lQuery[0].Value <<= lTypeReg;

    css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery);
    while(xSet->hasMoreElements())
    {
        ::comphelper::SequenceAsHashMap lProps   (xSet->nextElement());
        ::rtl::OUString                 sHandler = lProps.getUnpackedValueOrDefault(::framework::constant::ContentHandler::PROP_NAME, ::rtl::OUString());

        css::uno::Reference< css::frame::XNotifyingDispatch > xHandler;
        try
        {
            xHandler = css::uno::Reference< css::frame::XNotifyingDispatch >(xFactory->createInstance(sHandler), css::uno::UNO_QUERY);
            if (!xHandler.is())
                continue;
        }
        catch(const css::uno::RuntimeException&)
            { throw; }
        catch(const css::uno::Exception&)
            { continue; }

        // SAFE -> -----------------------------------
        WriteGuard aWriteLock(m_aLock);
        m_xAsynchronousJob = xHandler;
        m_pCheck           = this;
        LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this);
        aWriteLock.unlock();
        // <- SAFE -----------------------------------

        css::uno::Reference< css::frame::XDispatchResultListener > xListener(static_cast< css::frame::XDispatchResultListener* >(pListener), css::uno::UNO_QUERY);
        xHandler->dispatchWithNotification(aURL, lDescriptor, xListener);

        return sal_True;
    }

    return sal_False;
}

//-----------------------------------------------
sal_Bool LoadEnv::impl_furtherDocsAllowed()
{
    // SAFE ->
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
    aReadLock.unlock();
    // <- SAFE

    sal_Bool bAllowed = sal_True;

    try
    {
        css::uno::Any aVal = ::comphelper::ConfigurationHelper::readDirectKey(
                                xSMGR,
                                ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/"),
                                ::rtl::OUString::createFromAscii("Misc"),
                                ::rtl::OUString::createFromAscii("MaxOpenDocuments"),
                                ::comphelper::ConfigurationHelper::E_READONLY);

        // NIL means: count of allowed documents = infinite !
        //     => return sal_True
        if ( ! aVal.hasValue())
            bAllowed = sal_True;
        else
        {
            sal_Int32 nMaxOpenDocuments = 0;
            aVal >>= nMaxOpenDocuments;

            css::uno::Reference< css::frame::XFramesSupplier > xDesktop(
                xSMGR->createInstance(SERVICENAME_DESKTOP),
                css::uno::UNO_QUERY_THROW);

            FrameListAnalyzer aAnalyzer(xDesktop,
                                        css::uno::Reference< css::frame::XFrame >(),
                                        FrameListAnalyzer::E_HELP |
                                        FrameListAnalyzer::E_BACKINGCOMPONENT |
                                        FrameListAnalyzer::E_HIDDEN);

            sal_Int32 nOpenDocuments = aAnalyzer.m_lOtherVisibleFrames.getLength();
                      bAllowed       = (nOpenDocuments < nMaxOpenDocuments);
        }
    }
    catch(const css::uno::Exception&)
        { bAllowed = sal_True; } // !! internal errors are no reason to disturb the office from opening documents .-)

    if ( ! bAllowed )
    {
        // SAFE ->
        aReadLock.lock();
        css::uno::Reference< css::task::XInteractionHandler > xInteraction = m_lMediaDescriptor.getUnpackedValueOrDefault(
                                                                                ::comphelper::MediaDescriptor::PROP_INTERACTIONHANDLER(),
                                                                                css::uno::Reference< css::task::XInteractionHandler >());
        aReadLock.unlock();
        // <- SAFE

        if (xInteraction.is())
        {
            css::uno::Any                                                                    aInteraction;
            css::uno::Sequence< css::uno::Reference< css::task::XInteractionContinuation > > lContinuations(2);

            comphelper::OInteractionAbort*   pAbort   = new comphelper::OInteractionAbort();
            comphelper::OInteractionApprove* pApprove = new comphelper::OInteractionApprove();

            lContinuations[0] = css::uno::Reference< css::task::XInteractionContinuation >(
                                    static_cast< css::task::XInteractionContinuation* >(pAbort),
                                    css::uno::UNO_QUERY_THROW);
            lContinuations[1] = css::uno::Reference< css::task::XInteractionContinuation >(
                                    static_cast< css::task::XInteractionContinuation* >(pApprove),
                                    css::uno::UNO_QUERY_THROW);

            css::task::ErrorCodeRequest aErrorCode;
            aErrorCode.ErrCode = ERRCODE_SFX_NOMOREDOCUMENTSALLOWED;
            aInteraction <<= aErrorCode;
            xInteraction->handle( InteractionRequest::CreateRequest(aInteraction, lContinuations) );
        }
    }

    return bAllowed;
}

//-----------------------------------------------
sal_Bool LoadEnv::impl_loadContent()
    throw(LoadEnvException, css::uno::RuntimeException)
{
    // SAFE -> -----------------------------------
    WriteGuard aWriteLock(m_aLock);

    // search or create right target frame
    ::rtl::OUString sTarget = m_sTarget;
    if (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT))
    {
        m_xTargetFrame = impl_searchAlreadyLoaded();
        if (m_xTargetFrame.is())
		{
			impl_setResult(sal_True);
			return sal_True;
		}
        m_xTargetFrame = impl_searchRecycleTarget();
    }

    if (! m_xTargetFrame.is())
    {
        if (
            (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_BLANK  )) ||
            (TargetHelper::matchSpecialTarget(sTarget, TargetHelper::E_DEFAULT))
           )
        {
            if (! impl_furtherDocsAllowed())
                return sal_False;
            m_xTargetFrame       = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0);
            m_bCloseFrameOnError = m_xTargetFrame.is();
        }
        else
        {
            sal_Int32 nFlags = m_nSearchFlags & ~css::frame::FrameSearchFlag::CREATE;
            m_xTargetFrame   = m_xBaseFrame->findFrame(sTarget, nFlags);
            if (! m_xTargetFrame.is())
            {
                if (! impl_furtherDocsAllowed())
                    return sal_False;
                m_xTargetFrame       = m_xBaseFrame->findFrame(SPECIALTARGET_BLANK, 0);
                m_bCloseFrameOnError = m_xTargetFrame.is();
            }
        }
    }

    // If we couldn't find a valid frame or the frame has no container window
    // we have to throw an exception.
    if (
        ( ! m_xTargetFrame.is()                       ) ||
        ( ! m_xTargetFrame->getContainerWindow().is() )
       )
        throw LoadEnvException(LoadEnvException::ID_NO_TARGET_FOUND);

    css::uno::Reference< css::frame::XFrame > xTargetFrame = m_xTargetFrame;

    // Now we have a valid frame ... and type detection was already done.
    // We should apply the module dependend window position and size to the
    // frame window.
    impl_applyPersistentWindowState(xTargetFrame->getContainerWindow());

    // Don't forget to lock task for following load process. Otherwise it could die
    // during this operation runs by terminating the office or closing this task via api.
    // If we set this lock "close()" will return false and closing will be broken.
    // Attention: Don't forget to reset this lock again after finishing operation.
    // Otherwise task AND office couldn't die!!!
    // This includes gracefully handling of Exceptions (Runtime!) too ...
    // That's why we use a specialized guard, which will reset the lock
    // if it will be run out of scope.

    // Note further: ignore if this internal guard already contains a resource.
    // Might impl_searchRecylcTarget() set it before. But incase this impl-method wasn't used
    // and the target frame was new created ... this lock here must be set!
    css::uno::Reference< css::document::XActionLockable > xTargetLock(xTargetFrame, css::uno::UNO_QUERY);
    m_aTargetLock.setResource(xTargetLock);

    // Add status indicator to descriptor. Loader can show an progresses then.
    // But don't do it, if loading should be hidden or preview is used ...!
    // So we prevent our code against wrong using. Why?
    // It could be, that using of this progress could make trouble. e.g. He make window visible ...
    // but shouldn't do that. But if no indicator is available ... nobody has a chance to do that!
    sal_Bool                                           bHidden    = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN()         , sal_False                                           );
    sal_Bool                                           bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED()      , sal_False                                           );
    sal_Bool                                           bPreview   = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_PREVIEW()        , sal_False                                           );
    css::uno::Reference< css::task::XStatusIndicator > xProgress  = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_STATUSINDICATOR(), css::uno::Reference< css::task::XStatusIndicator >());

    if (!bHidden && !bMinimized && !bPreview && !xProgress.is())
    {
        // Note: its an optional interface!
        css::uno::Reference< css::task::XStatusIndicatorFactory > xProgressFactory(xTargetFrame, css::uno::UNO_QUERY);
        if (xProgressFactory.is())
        {
            xProgress = xProgressFactory->createStatusIndicator();
            if (xProgress.is())
                m_lMediaDescriptor[::comphelper::MediaDescriptor::PROP_STATUSINDICATOR()] <<= xProgress;
        }
    }

    // convert media descriptor and URL to right format for later interface call!
    css::uno::Sequence< css::beans::PropertyValue > lDescriptor;
    m_lMediaDescriptor >> lDescriptor;
    ::rtl::OUString sURL = m_aURL.Complete;

    // try to locate any interested frame loader
    css::uno::Reference< css::uno::XInterface >                xLoader     = impl_searchLoader();
    css::uno::Reference< css::frame::XFrameLoader >            xAsyncLoader(xLoader, css::uno::UNO_QUERY);
    css::uno::Reference< css::frame::XSynchronousFrameLoader > xSyncLoader (xLoader, css::uno::UNO_QUERY);

    if (xAsyncLoader.is())
    {
        // SAFE -> -----------------------------------
        aWriteLock.lock();
        m_xAsynchronousJob = xAsyncLoader;
        m_pCheck           = this;
        LoadEnvListener* pListener = new LoadEnvListener(m_pCheck, this);
        aWriteLock.unlock();
        // <- SAFE -----------------------------------

        css::uno::Reference< css::frame::XLoadEventListener > xListener(static_cast< css::frame::XLoadEventListener* >(pListener), css::uno::UNO_QUERY);
        xAsyncLoader->load(xTargetFrame, sURL, lDescriptor, xListener);

        return sal_True;
    }
    else
    if (xSyncLoader.is())
    {
        sal_Bool bResult = xSyncLoader->load(lDescriptor, xTargetFrame);
        // react for the result here, so the outside waiting
        // code can ask for it later.
        impl_setResult(bResult);
        // But the return value indicates a valid started(!) operation.
        // And that's true every time we reach this line :-)
        return sal_True;
    }

    aWriteLock.unlock();
    // <- SAFE

    return sal_False;
}

/*-----------------------------------------------
    06.02.2004 14:40
-----------------------------------------------*/
css::uno::Reference< css::uno::XInterface > LoadEnv::impl_searchLoader()
{
    // SAFE -> -----------------------------------
    ReadGuard aReadLock(m_aLock);

    // special mode to set an existing component on this frame
    // In such case the laoder is fix. It must be the SFX based implementation,
    // which can create a view on top of such xModel components :-)
    if (m_eContentType == E_CAN_BE_SET)
    {
        try
        {
            return m_xSMGR->createInstance(IMPLEMENTATIONNAME_GENERICFRAMELOADER);
        }
        catch(const css::uno::RuntimeException&)
            { throw; }
        catch(const css::uno::Exception&)
            {}
        throw LoadEnvException(LoadEnvException::ID_INVALID_ENVIRONMENT);
    }

    // Otherwise ...
    // We need this type information to locate an registered frame loader
    // Without such information we can't work!
    ::rtl::OUString sType = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_TYPENAME(), ::rtl::OUString());
    if (!sType.getLength())
        throw LoadEnvException(LoadEnvException::ID_INVALID_MEDIADESCRIPTOR);

    // try to locate any interested frame loader
    css::uno::Reference< css::lang::XMultiServiceFactory > xLoaderFactory(m_xSMGR->createInstance(SERVICENAME_FRAMELOADERFACTORY), css::uno::UNO_QUERY);
    css::uno::Reference< css::container::XContainerQuery > xQuery        (xLoaderFactory                                         , css::uno::UNO_QUERY);

    aReadLock.unlock();
    // <- SAFE -----------------------------------

    css::uno::Sequence< ::rtl::OUString > lTypesReg(1);
    lTypesReg[0] = sType;

    css::uno::Sequence< css::beans::NamedValue > lQuery(1);
    lQuery[0].Name    = ::framework::constant::FrameLoader::PROP_TYPES;
    lQuery[0].Value <<= lTypesReg;

    css::uno::Reference< css::container::XEnumeration > xSet = xQuery->createSubSetEnumerationByProperties(lQuery);
    while(xSet->hasMoreElements())
    {
        // try everyone ...
        // Ignore any loader, which makes trouble :-)
        ::comphelper::SequenceAsHashMap             lLoaderProps(xSet->nextElement());
        ::rtl::OUString                             sLoader     = lLoaderProps.getUnpackedValueOrDefault(::framework::constant::FrameLoader::PROP_NAME, ::rtl::OUString());
        css::uno::Reference< css::uno::XInterface > xLoader     ;
        try
        {
            xLoader = xLoaderFactory->createInstance(sLoader);
            if (xLoader.is())
                return xLoader;
        }
        catch(const css::uno::RuntimeException&)
            { throw; }
        catch(const css::uno::Exception&)
            { continue; }
    }

    return css::uno::Reference< css::uno::XInterface >();
}

/*-----------------------------------------------
    24.01.2006 15:11
-----------------------------------------------*/
void LoadEnv::impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame,
                              const css::util::URL&                            aURL  )
{
    if (! aURL.Mark.getLength())
        return;

    css::uno::Reference< css::frame::XDispatchProvider > xProvider(xFrame, css::uno::UNO_QUERY);
    if (! xProvider.is())
        return;

    // SAFE ->
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
    aReadLock.unlock();
    // <- SAFE

    css::util::URL aCmd;
    aCmd.Complete = ::rtl::OUString::createFromAscii(".uno:JumpToMark");

    css::uno::Reference< css::util::XURLTransformer > xParser(xSMGR->createInstance(SERVICENAME_URLTRANSFORMER), css::uno::UNO_QUERY_THROW);
    xParser->parseStrict(aCmd);

    css::uno::Reference< css::frame::XDispatch > xDispatcher = xProvider->queryDispatch(aCmd, SPECIALTARGET_SELF, 0);
    if (! xDispatcher.is())
        return;

    ::comphelper::SequenceAsHashMap lArgs;
    lArgs[::rtl::OUString::createFromAscii("Bookmark")] <<= aURL.Mark;
    xDispatcher->dispatch(aCmd, lArgs.getAsConstPropertyValueList());
}

/*-----------------------------------------------
    31.07.2003 09:02
-----------------------------------------------*/
css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchAlreadyLoaded()
    throw(LoadEnvException, css::uno::RuntimeException)
{
    // SAFE ->
    ReadGuard aReadLock(m_aLock);

    // such search is allowed for special requests only ...
    // or better its not allowed for some requests in general :-)
    if (
        ( ! TargetHelper::matchSpecialTarget(m_sTarget, TargetHelper::E_DEFAULT)                                               ) ||
        (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) ||
//      (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN()     , sal_False) == sal_True) ||
        (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True)
       )
    {
        return css::uno::Reference< css::frame::XFrame >();
    }

    // check URL
    // May its not useful to start expensive document search, if it
    // can fail only .. because we load from a stream or model directly!
    if (
        (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM )) ||
        (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT ))
        /*TODO should be private:factory here tested too? */
       )
    {
        return css::uno::Reference< css::frame::XFrame >();
    }

    // otherwise - iterate through the tasks of the desktop container
    // to find out, which of them might contain the requested document
    css::uno::Reference< css::frame::XFramesSupplier >  xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
    css::uno::Reference< css::container::XIndexAccess > xTaskList(xSupplier->getFrames()                      , css::uno::UNO_QUERY);

    if (!xTaskList.is())
        return css::uno::Reference< css::frame::XFrame >(); // task list can be empty!

    // Note: To detect if a document was already loaded before
    // we check URLs here only. But might the existing and the required
    // document has different versions! Then its URLs are the same ...
    sal_Int16 nNewVersion = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int16)(-1));

    // will be used to save the first hidden frame referring the searched model
    // Normally we are interested in visible frames ... but if there is no such visible
    // frame we refer to any hidden frame also (but as fallback only).
    css::uno::Reference< css::frame::XFrame > xHiddenTask;
    css::uno::Reference< css::frame::XFrame > xTask;

    sal_Int32 count = xTaskList->getCount();
    for (sal_Int32 i=0; i<count; ++i)
    {
        try
        {
            // locate model of task
            // Note: Without a model there is no chance to decide if
            // this task contains the searched document or not!
            xTaskList->getByIndex(i) >>= xTask;
            if (!xTask.is())
                continue;

            css::uno::Reference< css::frame::XController > xController = xTask->getController();
            if (!xController.is())
			{
				xTask.clear ();
                continue;
			}

            css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
            if (!xModel.is())
			{
				xTask.clear ();
                continue;
			}

            // don't check the complete URL here.
            // use its main part - ignore optional jumpmarks!
			const ::rtl::OUString sURL = xModel->getURL();
            if (!::utl::UCBContentHelper::EqualURLs( m_aURL.Main, sURL ))
			{
				xTask.clear ();
                continue;
			}

            // get the original load arguments from the current document
            // and decide if its really the same then the one will be.
            // It must be visible and must use the same file revision ...
            // or must not have any file revision set (-1 == -1!)
            ::comphelper::MediaDescriptor lOldDocDescriptor(xModel->getArgs());

            if (lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_VERSION(), (sal_Int32)(-1)) != nNewVersion)
			{
				xTask.clear ();
                continue;
			}

            // Hidden frames are special.
            // They will be used as "last chance" if there is no visible frame pointing to the same model.
            // Safe the result but continue with current loop might be looking for other visible frames.
            ::sal_Bool bIsHidden = lOldDocDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False);
            if (
                (   bIsHidden       ) &&
                ( ! xHiddenTask.is())
               )
            {
                xHiddenTask = xTask;
                xTask.clear ();
                continue;
            }

            // We found a visible task pointing to the right model ...
            // Break search.
            break;
        }
        catch(const css::uno::RuntimeException& exRun)
            { throw exRun; }
        catch(const css::uno::Exception&)
            { continue; }
    }

    css::uno::Reference< css::frame::XFrame > xResult;
    if (xTask.is())
        xResult = xTask;
    else
    if (xHiddenTask.is())
        xResult = xHiddenTask;

    if (xResult.is())
    {
        // Now we are sure, that this task includes the searched document.
        // It's time to activate it. As special feature we try to jump internally
        // if an optional jumpmark is given too.
        if (m_aURL.Mark.getLength())
            impl_jumpToMark(xResult, m_aURL);

        // bring it to front and make sure it's visible...
        impl_makeFrameWindowVisible(xResult->getContainerWindow(), sal_True);
    }

    aReadLock.unlock();
    // <- SAFE

    return xResult;
}

/*-----------------------------------------------
    30.03.2004 09:12
-----------------------------------------------*/
sal_Bool LoadEnv::impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const
{
    css::uno::Reference< css::document::XActionLockable > xLock(xFrame, css::uno::UNO_QUERY);

    // ? no lock interface ?
    // Might its an external written frame implementation :-(
    // Allowing using of it ... but it can fail if its not synchronized with our processes !
    if (!xLock.is())
        return sal_False;

    // Otherwise we have to look for any other existing lock.
    return xLock->isActionLocked();
}

/*-----------------------------------------------
    30.03.2004 09:12
-----------------------------------------------*/
css::uno::Reference< css::frame::XFrame > LoadEnv::impl_searchRecycleTarget()
    throw(LoadEnvException, css::uno::RuntimeException)
{
    // SAFE -> ..................................
    ReadGuard aReadLock(m_aLock);

    // The special backing mode frame will be recycled by definition!
    // It doesn't matter if somewhere wishes to create a new view
    // or open a new untitled document ...
    // The only exception form that - hidden frames!
    if (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False) == sal_True)
        return css::uno::Reference< css::frame::XFrame >();

    css::uno::Reference< css::frame::XFramesSupplier > xSupplier(m_xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY);
    FrameListAnalyzer aTasksAnalyzer(xSupplier, css::uno::Reference< css::frame::XFrame >(), FrameListAnalyzer::E_BACKINGCOMPONENT);
    if (aTasksAnalyzer.m_xBackingComponent.is())
    {
        if (!impl_isFrameAlreadyUsedForLoading(aTasksAnalyzer.m_xBackingComponent))
        {
            // bring it to front ...
            impl_makeFrameWindowVisible(aTasksAnalyzer.m_xBackingComponent->getContainerWindow(), sal_True);
            return aTasksAnalyzer.m_xBackingComponent;
        }
    }

    // These states indicates the wishing for creation of a new view in general.
    if (
        (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_ASTEMPLATE() , sal_False) == sal_True) ||
        (m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_OPENNEWVIEW(), sal_False) == sal_True)
       )
    {
        return css::uno::Reference< css::frame::XFrame >();
    }

	// On the other side some special URLs will open a new frame everytimes (expecting
	// they can use the backing-mode frame!)
    if (
        (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_FACTORY )) ||
        (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_STREAM  )) ||
        (ProtocolCheck::isProtocol(m_aURL.Complete, ProtocolCheck::E_PRIVATE_OBJECT  ))
       )
    {
        return css::uno::Reference< css::frame::XFrame >();
    }

	// No backing frame! No special URL => recycle active task - if possible.
	// Means - if it does not already contains a modified document, or
	// use another office module.
    css::uno::Reference< css::frame::XFrame > xTask = xSupplier->getActiveFrame();

    // not a real error - but might a focus problem!
    if (!xTask.is())
        return css::uno::Reference< css::frame::XFrame >();

    // not a real error - may its a view only
    css::uno::Reference< css::frame::XController > xController = xTask->getController();
    if (!xController.is())
        return css::uno::Reference< css::frame::XFrame >();

    // not a real error - may its a db component instead of a full feartured office document
    css::uno::Reference< css::frame::XModel > xModel = xController->getModel();
    if (!xModel.is())
        return css::uno::Reference< css::frame::XFrame >();

    // get some more informations ...

    // A valid set URL means: there is already a location for this document.
    // => it was saved there or opened from there. Such Documents can not be used here.
    // We search for empty document ... created by a private:factory/ URL!
    if (xModel->getURL().getLength()>0)
        return css::uno::Reference< css::frame::XFrame >();

    // The old document must be unmodified ...
    css::uno::Reference< css::util::XModifiable > xModified(xModel, css::uno::UNO_QUERY);
    if (xModified->isModified())
        return css::uno::Reference< css::frame::XFrame >();

    Window* pWindow = VCLUnoHelper::GetWindow(xTask->getContainerWindow());
    if (pWindow && pWindow->IsInModalMode())
        return css::uno::Reference< css::frame::XFrame >();

    // find out the application type of this document
    // We can recycle only documents, which uses the same application
    // then the new one.
    SvtModuleOptions::EFactory eOldApp = SvtModuleOptions::ClassifyFactoryByModel(xModel);
    SvtModuleOptions::EFactory eNewApp = SvtModuleOptions::ClassifyFactoryByURL  (m_aURL.Complete, m_lMediaDescriptor.getAsConstPropertyValueList());

    aReadLock.unlock();
    // <- SAFE ..................................

    if (eOldApp != eNewApp)
        return css::uno::Reference< css::frame::XFrame >();

    // OK this task seems to be useable for recycling
    // But we should mark it as such - means set an action lock.
    // Otherwise it would be used more than once or will be destroyed
    // by a close() or terminate() request.
    // But if such lock already exists ... it means this task is used for
    // any other operation already. Don't use it then.
    if (impl_isFrameAlreadyUsedForLoading(xTask))
        return css::uno::Reference< css::frame::XFrame >();

    // OK - there is a valid target frame.
    // But may be it contains already a document.
    // Then we have to ask it, if it allows recylcing of this frame .-)
    sal_Bool bReactivateOldControllerOnError = sal_False;
    css::uno::Reference< css::frame::XController > xOldDoc = xTask->getController();
    if (xOldDoc.is())
    {
        bReactivateOldControllerOnError = xOldDoc->suspend(sal_True);
        if (! bReactivateOldControllerOnError)
            return css::uno::Reference< css::frame::XFrame >();
    }

    // SAFE -> ..................................
    WriteGuard aWriteLock(m_aLock);

    css::uno::Reference< css::document::XActionLockable > xLock(xTask, css::uno::UNO_QUERY);
    if (!m_aTargetLock.setResource(xLock))
        return css::uno::Reference< css::frame::XFrame >();

    m_bReactivateControllerOnError = bReactivateOldControllerOnError;
    aWriteLock.unlock();
    // <- SAFE ..................................

    // bring it to front ...
    impl_makeFrameWindowVisible(xTask->getContainerWindow(), sal_True);

    return xTask;
}

/*-----------------------------------------------
    15.08.2003 12:39
-----------------------------------------------*/
void LoadEnv::impl_reactForLoadingState()
    throw(LoadEnvException, css::uno::RuntimeException)
{
    /*TODO reset action locks */

    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);

    if (m_bLoaded)
    {
        // Bring the new loaded document to front (if allowed!).
        // Note: We show new created frames here only.
        // We dont hide already visible frames here ...
        css::uno::Reference< css::awt::XWindow > xWindow      = m_xTargetFrame->getContainerWindow();
        sal_Bool                                 bHidden      = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_HIDDEN(), sal_False);
        sal_Bool                                 bMinimized = m_lMediaDescriptor.getUnpackedValueOrDefault(::comphelper::MediaDescriptor::PROP_MINIMIZED(), sal_False);

        if (bMinimized)
        {
            ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex());
            Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
            // check for system window is necessary to guarantee correct pointer cast!
            if (pWindow && pWindow->IsSystemWindow())
                ((WorkWindow*)pWindow)->Minimize();
        }
        else
        if (!bHidden)
        {
            // show frame ... if it's not still visible ...
            // But do nothing if it's already visible!
            impl_makeFrameWindowVisible(xWindow, sal_False);
        }

        // Note: Only if an existing property "FrameName" is given by this media descriptor,
        // it should be used. Otherwise we should do nothing. Maybe the outside code has already
        // set a frame name on the target!
        ::comphelper::MediaDescriptor::const_iterator pFrameName = m_lMediaDescriptor.find(::comphelper::MediaDescriptor::PROP_FRAMENAME());
        if (pFrameName != m_lMediaDescriptor.end())
        {
            ::rtl::OUString sFrameName;
            pFrameName->second >>= sFrameName;
            // Check the name again. e.g. "_default" isn't allowed.
            // On the other side "_beamer" is a valid name :-)
            if (TargetHelper::isValidNameForFrame(sFrameName))
                m_xTargetFrame->setName(sFrameName);
        }
    }
    else if (m_bReactivateControllerOnError)
	{
		// Try to reactivate the old document (if any exists!)
		css::uno::Reference< css::frame::XController > xOldDoc = m_xTargetFrame->getController();
		// clear does not depend from reactivation state of a might existing old document!
		// We must make sure, that a might following getTargetComponent() call does not return
		// the old document!
		m_xTargetFrame.clear();
		if (xOldDoc.is())
		{
			sal_Bool bReactivated = xOldDoc->suspend(sal_False);
			if (!bReactivated)
				throw LoadEnvException(LoadEnvException::ID_COULD_NOT_REACTIVATE_CONTROLLER);
			m_bReactivateControllerOnError = sal_False;
		}
	}
	else if (m_bCloseFrameOnError)
	{
		// close empty frames
		css::uno::Reference< css::util::XCloseable > xCloseable (m_xTargetFrame, css::uno::UNO_QUERY);
		css::uno::Reference< css::lang::XComponent > xDisposable(m_xTargetFrame, css::uno::UNO_QUERY);

		try
		{
			if (xCloseable.is())
				xCloseable->close(sal_True);
			else
			if (xDisposable.is())
				xDisposable->dispose();
		}
		catch(const css::util::CloseVetoException&)
		{}
		catch(const css::lang::DisposedException&)
		{}
		m_xTargetFrame.clear();
	}

    // This max force an implicit closing of our target frame ...
    // e.g. in case close(sal_True) was called before and the frame
    // kill itself if our external use-lock is released here!
    // That's why we release this lock AFTER ALL OPERATIONS on this frame
    // are finished. The frame itself must handle then
    // this situation gracefully.
    m_aTargetLock.freeResource();

    // Last but not least :-)
    // We have to clear the current media descriptor.
    // Otherwise it hold a might existing stream open!
    m_lMediaDescriptor.clear();

	css::uno::Any aRequest;
	bool bThrow = false;
	if ( !m_bLoaded && m_pQuietInteraction && m_pQuietInteraction->wasUsed() )
	{
		aRequest = m_pQuietInteraction->getRequest();
		m_pQuietInteraction->release();
		m_pQuietInteraction = 0;
		bThrow = true;
	}

    aReadLock.unlock();

	if (bThrow)
	{
        if  ( aRequest.isExtractableTo( ::cppu::UnoType< css::uno::Exception >::get() ) )
			throw LoadEnvException( LoadEnvException::ID_GENERAL_ERROR, aRequest );
	}

    // <- SAFE ----------------------------------
}

/*-----------------------------------------------
    16.01.2005 13:04
-----------------------------------------------*/
void LoadEnv::impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow      ,
                                                sal_Bool bForceToFront)
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR( m_xSMGR.get(), css::uno::UNO_QUERY );
    aReadLock.unlock();
    // <- SAFE ----------------------------------

    ::vos::OClearableGuard aSolarGuard(Application::GetSolarMutex());
    Window* pWindow = VCLUnoHelper::GetWindow(xWindow);
    if ( pWindow )
    {
        bool bForceFrontAndFocus(false);
        css::uno::Any a = ::comphelper::ConfigurationHelper::readDirectKey(
            xSMGR,
            ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/View"),
            ::rtl::OUString::createFromAscii("NewDocumentHandling"),
            ::rtl::OUString::createFromAscii("ForceFocusAndToFront"),
            ::comphelper::ConfigurationHelper::E_READONLY);
        a >>= bForceFrontAndFocus;

        if( pWindow->IsVisible() && (bForceFrontAndFocus || bForceToFront) )
            pWindow->ToTop();
        else
            pWindow->Show(sal_True, (bForceFrontAndFocus || bForceToFront) ? SHOW_FOREGROUNDTASK : 0 );
    }

/* #i19976#
    We tried to prevent a toFront() call in case the user putted the
    loading document into the background ..
    But we had several errors trying that. So we decided to
    rollback these changes and bring the new loaded document to front hardly !

    css::uno::Reference< css::awt::XWindow2 > xWindow2(xWindow, css::uno::UNO_QUERY);

    sal_Bool bIsVisible = sal_False;
    if (xWindow2.is())
        bIsVisible = xWindow2->isVisible(); // TODO is parent visible too ? .-)

    if (!bIsVisible)
    {
        xWindow->setVisible(sal_True);
        bForceToFront = sal_True;
    }

    if (
        (bForceToFront  ) &&
        (xTopWindow.is())
       )
    {
        xTopWindow->toFront();
    }
*/
}

/*-----------------------------------------------
    15.03.2005 11:12
-----------------------------------------------*/
void LoadEnv::impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow)
{
    static ::rtl::OUString PACKAGE_SETUP_MODULES = ::rtl::OUString::createFromAscii("/org.openoffice.Setup/Office/Factories");

    // no window -> action not possible
    if (!xWindow.is())
        return;

    // window already visible -> do nothing! If we use a "recycle frame" for loading ...
    // the current position and size must be used.
    css::uno::Reference< css::awt::XWindow2 > xVisibleCheck(xWindow, css::uno::UNO_QUERY);
    if (
        (xVisibleCheck.is()        ) &&
        (xVisibleCheck->isVisible())
       )
       return;

    // SOLAR SAFE ->
    ::vos::OClearableGuard aSolarLock1(Application::GetSolarMutex());

    Window*  pWindow       = VCLUnoHelper::GetWindow(xWindow);
    sal_Bool bSystemWindow = pWindow->IsSystemWindow();
    sal_Bool bWorkWindow   = (pWindow->GetType() == WINDOW_WORKWINDOW);

    if (!bSystemWindow && !bWorkWindow)
        return;

    // dont overwrite this special state!
    WorkWindow* pWorkWindow = (WorkWindow*)pWindow;
    if (pWorkWindow->IsMinimized())
        return;

    aSolarLock1.clear();
    // <- SOLAR SAFE

    // SAFE ->
    ReadGuard aReadLock(m_aLock);

    // no filter -> no module -> no persistent window state
    ::rtl::OUString sFilter = m_lMediaDescriptor.getUnpackedValueOrDefault(
                                    ::comphelper::MediaDescriptor::PROP_FILTERNAME(),
                                    ::rtl::OUString());
    if (!sFilter.getLength())
        return;

    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;

    aReadLock.unlock();
    // <- SAFE

    try
    {
        // retrieve the module name from the filter configuration
        css::uno::Reference< css::container::XNameAccess > xFilterCfg(
            xSMGR->createInstance(SERVICENAME_FILTERFACTORY),
            css::uno::UNO_QUERY_THROW);
        ::comphelper::SequenceAsHashMap lProps (xFilterCfg->getByName(sFilter));
        ::rtl::OUString                 sModule = lProps.getUnpackedValueOrDefault(FILTER_PROPNAME_DOCUMENTSERVICE, ::rtl::OUString());

        // get access to the configuration of this office module
        css::uno::Reference< css::container::XNameAccess > xModuleCfg(::comphelper::ConfigurationHelper::openConfig(
                                                                        xSMGR,
                                                                        PACKAGE_SETUP_MODULES,
                                                                        ::comphelper::ConfigurationHelper::E_READONLY),
                                                                      css::uno::UNO_QUERY_THROW);

        // read window state from the configuration
        // and apply it on the window.
        // Do nothing, if no configuration entry exists!
        ::rtl::OUString sWindowState ;
        ::comphelper::ConfigurationHelper::readRelativeKey(xModuleCfg, sModule, OFFICEFACTORY_PROPNAME_WINDOWATTRIBUTES) >>= sWindowState;
        if (sWindowState.getLength())
        {
            // SOLAR SAFE ->
            ::vos::OClearableGuard aSolarLock2(Application::GetSolarMutex());

            // We have to retrieve the window pointer again. Because nobody can guarantee
            // that the XWindow was not disposed inbetween .-)
            // But if we get a valid pointer we can be sure, that it's the system window pointer
            // we already checked and used before. Because nobody recylce the same uno reference for
            // a new internal c++ implementation ... hopefully .-))
            Window* pWindowCheck  = VCLUnoHelper::GetWindow(xWindow);
            if (! pWindowCheck)
                return;

            SystemWindow* pSystemWindow = (SystemWindow*)pWindowCheck;
            pSystemWindow->SetWindowState(U2B_ENC(sWindowState,RTL_TEXTENCODING_UTF8));

            aSolarLock2.clear();
            // <- SOLAR SAFE
        }
    }
    catch(const css::uno::RuntimeException& exRun)
        { throw exRun; }
    catch(const css::uno::Exception&)
        {}
}

} // namespace framework
