/**************************************************************
 * 
 * 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"

//_______________________________________________
// my own includes
#include <dispatch/closedispatcher.hxx>
#include <pattern/frame.hxx>
#include <threadhelp/readguard.hxx>
#include <threadhelp/writeguard.hxx>
#include <framework/framelistanalyzer.hxx>
#include <services.h>
#include <general.h>

//_______________________________________________
// interface includes
#include <com/sun/star/frame/XDesktop.hpp>
#include <com/sun/star/frame/XController.hpp>
#include <com/sun/star/frame/CommandGroup.hpp>
#include <com/sun/star/lang/DisposedException.hpp>
#include <com/sun/star/awt/XTopWindow.hpp>
#include <com/sun/star/document/XActionLockable.hpp>
#include "com/sun/star/beans/XFastPropertySet.hpp"
#include <toolkit/helper/vclunohelper.hxx>

//_______________________________________________
// includes of other projects

#include <vcl/window.hxx>
#include <vcl/svapp.hxx>
#include <vos/mutex.hxx>
#include <unotools/moduleoptions.hxx>

//_______________________________________________
// namespace

namespace framework{

#ifdef fpf
    #error "Who uses \"fpf\" as define. It will overwrite my namespace alias ..."
#endif
namespace fpf = ::framework::pattern::frame;

//_______________________________________________
// non exported const

static ::rtl::OUString URL_CLOSEDOC    = DECLARE_ASCII(".uno:CloseDoc"  );
static ::rtl::OUString URL_CLOSEWIN    = DECLARE_ASCII(".uno:CloseWin"  );
static ::rtl::OUString URL_CLOSEFRAME  = DECLARE_ASCII(".uno:CloseFrame");

//_______________________________________________
// declarations

DEFINE_XINTERFACE_4(CloseDispatcher                                           ,
                    OWeakObject                                               ,
                    DIRECT_INTERFACE(css::lang::XTypeProvider                ),
                    DIRECT_INTERFACE(css::frame::XNotifyingDispatch          ),
                    DIRECT_INTERFACE(css::frame::XDispatch                   ),
                    DIRECT_INTERFACE(css::frame::XDispatchInformationProvider))

// Note: XStatusListener is an implementation detail. Hide it for scripting!
DEFINE_XTYPEPROVIDER_4(CloseDispatcher                         ,
                       css::lang::XTypeProvider                ,
                       css::frame::XDispatchInformationProvider,
                       css::frame::XNotifyingDispatch          ,
                       css::frame::XDispatch                   )

//-----------------------------------------------
CloseDispatcher::CloseDispatcher(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR  ,
                                 const css::uno::Reference< css::frame::XFrame >&              xFrame ,
                                 const ::rtl::OUString&                                        sTarget)
    : ThreadHelpBase     (&Application::GetSolarMutex()                   )
    , ::cppu::OWeakObject(                                                )
    , m_xSMGR            (xSMGR                                           )
    , m_aAsyncCallback   (LINK( this, CloseDispatcher, impl_asyncCallback))
    , m_lStatusListener  (m_aLock.getShareableOslMutex()                  )
{
    m_xCloseFrame = CloseDispatcher::static_impl_searchRightTargetFrame(xFrame, sTarget);
}

//-----------------------------------------------
CloseDispatcher::~CloseDispatcher()
{
}

//-----------------------------------------------
void SAL_CALL CloseDispatcher::dispatch(const css::util::URL&                                  aURL      ,
                                        const css::uno::Sequence< css::beans::PropertyValue >& lArguments)
    throw(css::uno::RuntimeException)
{
    dispatchWithNotification(aURL, lArguments, css::uno::Reference< css::frame::XDispatchResultListener >());
}

//-----------------------------------------------
css::uno::Sequence< sal_Int16 > SAL_CALL CloseDispatcher::getSupportedCommandGroups()
    throw(css::uno::RuntimeException)
{
    css::uno::Sequence< sal_Int16 > lGroups(2);
    lGroups[0] = css::frame::CommandGroup::VIEW;
    lGroups[1] = css::frame::CommandGroup::DOCUMENT;
    return lGroups;
}

//-----------------------------------------------
css::uno::Sequence< css::frame::DispatchInformation > SAL_CALL CloseDispatcher::getConfigurableDispatchInformation(sal_Int16 nCommandGroup)
    throw(css::uno::RuntimeException)
{
    if (nCommandGroup == css::frame::CommandGroup::VIEW)
    {
        /* Attention: Dont add .uno:CloseFrame here. Because its not realy
                      a configurable feature ... and further it does not have
                      a valid UIName entry inside the GenericCommands.xcu ... */
        css::uno::Sequence< css::frame::DispatchInformation > lViewInfos(1);
        lViewInfos[0].Command = URL_CLOSEWIN;
        lViewInfos[0].GroupId = css::frame::CommandGroup::VIEW;
        return lViewInfos;
    }
    else
    if (nCommandGroup == css::frame::CommandGroup::DOCUMENT)
    {
        css::uno::Sequence< css::frame::DispatchInformation > lDocInfos(1);
        lDocInfos[0].Command = URL_CLOSEDOC;
        lDocInfos[0].GroupId = css::frame::CommandGroup::DOCUMENT;
        return lDocInfos;
    }

    return css::uno::Sequence< css::frame::DispatchInformation >();
}

//-----------------------------------------------
void SAL_CALL CloseDispatcher::addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
                                                 const css::util::URL&                                     /*aURL*/     )
    throw(css::uno::RuntimeException)
{
}

//-----------------------------------------------
void SAL_CALL CloseDispatcher::removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& /*xListener*/,
                                                    const css::util::URL&                                     /*aURL*/     )
    throw(css::uno::RuntimeException)
{
}

//-----------------------------------------------
void SAL_CALL CloseDispatcher::dispatchWithNotification(const css::util::URL&                                             aURL      ,
                                                        const css::uno::Sequence< css::beans::PropertyValue >&            lArguments,
                                                        const css::uno::Reference< css::frame::XDispatchResultListener >& xListener )
    throw(css::uno::RuntimeException)
{
    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);

    // This reference indicates, that we was already called before and
    // our asynchronous process was not finished yet.
    // We have to reject double calls. Otherwhise we risk,
    // that we try to close an already closed resource ...
    // And its no problem to do nothing then. The UI user will try it again, if
    // non of these jobs was successfully.
    if (m_xSelfHold.is())
    {
        aWriteLock.unlock();
        // <- SAFE ------------------------------

        implts_notifyResultListener(
            xListener,
            css::frame::DispatchResultState::DONTKNOW,
            css::uno::Any());
        return;
    }

    // First we have to check, if this dispatcher is used right. Means if valid URLs are used.
    // If not - we have to break this operation. But an optional listener must be informed.
    // BTW: We save the information about the requested operation. Because
    // we need it later.
    if (aURL.Complete.equals(URL_CLOSEDOC))
        m_eOperation = E_CLOSE_DOC;
    else
    if (aURL.Complete.equals(URL_CLOSEWIN))
        m_eOperation = E_CLOSE_WIN;
    else
    if (aURL.Complete.equals(URL_CLOSEFRAME))
        m_eOperation = E_CLOSE_FRAME;
    else
    {
        aWriteLock.unlock();
        // <- SAFE ------------------------------

        implts_notifyResultListener(
            xListener,
            css::frame::DispatchResultState::FAILURE,
            css::uno::Any());
        return;
    }

    // OK - URLs are the right ones.
    // But we cant execute synchronously :-)
    // May we are called from a generic key-input handler,
    // which isnt aware that this call kill its own environment ...
    // Do it asynchronous everytimes!

    // But dont forget to hold usself alive.
    // We are called back from an environment, which doesnt know an uno reference.
    // They call us back by using our c++ interface.

    m_xResultListener = xListener;
    m_xSelfHold       = css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY);

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

	sal_Bool bIsSynchron = sal_False;
	for (sal_Int32 nArgs=0; nArgs<lArguments.getLength(); nArgs++ )
	{
		if ( lArguments[nArgs].Name.equalsAscii("SynchronMode") )
		{
			lArguments[nArgs].Value >>= bIsSynchron;
			break;
		}
	}

	if ( bIsSynchron )
		impl_asyncCallback(0);
	else
		m_aAsyncCallback.Post(0);
}

//-----------------------------------------------
/**
    @short      asynchronous callback
    @descr      We start all actions inside this object asnychronoue.
                (see comments there).
                Now we do the following:
                - close all views to the same document, if needed and possible
                - make the current frame empty
                  ! This step is neccessary to handle errors during closing the
                    document inside the frame. May the document shows a dialog and
                    the user ignore it. Then the state of the office can be changed
                    during we try to close frame and document.
                - check the environment (menas count open frames - exlcuding our
                  current one)
                - decide then, if we must close this frame only, establish the backing mode
                  or shutdown the whole application.
*/
IMPL_LINK( CloseDispatcher, impl_asyncCallback, void*, EMPTYARG )
{
    try
    {

    // Allow calling of XController->suspend() everytimes.
    // Dispatch is an UI functionality. We implement such dispatch object here.
    // And further XController->suspend() was designed to bring an UI ...
    sal_Bool bAllowSuspend        = sal_True;
    sal_Bool bControllerSuspended = sal_False;

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

    // Closing of all views, related to the same document, is allowed
    // only if the dispatched URL was ".uno:CloseDoc"!
    sal_Bool bCloseAllViewsToo = (m_eOperation == E_CLOSE_DOC);

    // BTW: Make some copies, which are needed later ...
    EOperation                                                  eOperation  = m_eOperation;
    css::uno::Reference< css::lang::XMultiServiceFactory >      xSMGR       = m_xSMGR;
    css::uno::Reference< css::frame::XFrame >                   xCloseFrame (m_xCloseFrame.get(), css::uno::UNO_QUERY);
    css::uno::Reference< css::frame::XDispatchResultListener >  xListener   = m_xResultListener;

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

    // frame already dead ?!
    // Nothing to do !
    if (! xCloseFrame.is())
        return 0;

    sal_Bool bCloseFrame           = sal_False;
    sal_Bool bEstablishBackingMode = sal_False;
    sal_Bool bTerminateApp         = sal_False;

    // Analyze the environment a first time.
    // If we found some special cases, we can
    // make some decisions erliar!
    css::uno::Reference< css::frame::XFramesSupplier > xDesktop(xSMGR->createInstance(SERVICENAME_DESKTOP), css::uno::UNO_QUERY_THROW);
    FrameListAnalyzer aCheck1(xDesktop, xCloseFrame, FrameListAnalyzer::E_HELP | FrameListAnalyzer::E_BACKINGCOMPONENT);

    // a) If the curent frame (where the close dispatch was requested for) does not have
    //    any parent frame ... it will close this frame only. Such frame isnt part of the
    //    global desktop tree ... and such frames are used as "implementation details" only.
    //    E.g. the live previews of our wizards doing such things. And then the owner of the frame
    //    is responsible for closing the application or accepting closing of the application
    //    by others.
    if ( ! xCloseFrame->getCreator().is())
        bCloseFrame = sal_True;
    else

    // b) The help window cant disagree with any request.
    //    Because it doesnt implement a controller - it uses a window only.
    //    Further t cant be the last open frame - if we do all other things
    //    right inside this CloseDispatcher implementation.
    //    => close it!
    if (aCheck1.m_bReferenceIsHelp)
        bCloseFrame = sal_True;
    else

    // c) If we are already in "backing mode", we have to terminate
    //    the application, if this special frame is closed.
    //    It doesnt matter, how many other frames (can be the help or hidden frames only)
    //    are open then.
    //    => terminate the application!
    if (aCheck1.m_bReferenceIsBacking)
        bTerminateApp = sal_True;
    else

    // d) Otherwhise we have to: close all views to the same document, close the
    //    document inside our own frame and decide then again, what has to be done!
    {
        if (implts_prepareFrameForClosing(m_xCloseFrame, bAllowSuspend, bCloseAllViewsToo, bControllerSuspended))
        {
            // OK; this frame is empty now.
            // Check the environment again to decide, what is the next step.
            FrameListAnalyzer aCheck2(xDesktop, xCloseFrame, FrameListAnalyzer::E_ALL);

            // c1) there is as minimum 1 frame open, which is visible and contains a document
            //     different from our one. And its not the help!
            //     => close our frame only - nothing else.
            if (aCheck2.m_lOtherVisibleFrames.getLength()>0)
                bCloseFrame = sal_True;
            else

            // c2) if we close the current view ... but not all other views
            //     to the same document, we must close the current frame only!
            //     Because implts_closeView() suspended this view only - does not
            //     close the frame.
            if (
                (!bCloseAllViewsToo                    ) &&
                (aCheck2.m_lModelFrames.getLength() > 0)
               )
                bCloseFrame = sal_True;

			else
            // c3) there is no other (visible) frame open ...
            //     The help module will be ignored everytimes!
            //     But we have to decide if we must terminate the
            //     application or establish the backing mode now.
            //     And that depends from the dispatched URL ...
            {
                if (eOperation == E_CLOSE_FRAME)
                    bTerminateApp = sal_True;
                else if( SvtModuleOptions().IsModuleInstalled(SvtModuleOptions::E_SSTARTMODULE) )
                    bEstablishBackingMode = sal_True;
                else
                    bTerminateApp = sal_True;
            }
        }
    }

    // Do it now ...
    sal_Bool bSuccess = sal_False;
    if (bCloseFrame)
        bSuccess = implts_closeFrame();
    else
    if (bEstablishBackingMode)
    #if defined QUARTZ
    {
        // on mac close down, quickstarter keeps the process alive
        // however if someone has shut down the quickstarter
        // behave as any other platform

        bool bQuickstarterRunning = false;
        // get quickstart service
        try
        {
            css::uno::Reference< css::beans::XFastPropertySet > xSet( xSMGR->createInstance(IMPLEMENTATIONNAME_QUICKLAUNCHER), css::uno::UNO_QUERY_THROW );
            if( xSet.is() )
            {
                css::uno::Any aVal( xSet->getFastPropertyValue( 0 ) );
                sal_Bool bState = sal_False;
                if( aVal >>= bState )
                    bQuickstarterRunning = bState;
            }
        }
        catch( css::uno::Exception& )
        {
        }
        bSuccess = bQuickstarterRunning ? implts_terminateApplication() : implts_establishBackingMode();
    }
    #else
        bSuccess = implts_establishBackingMode();
    #endif
    else
    if (bTerminateApp)
        bSuccess = implts_terminateApplication();

    if (
        ( ! bSuccess             ) &&
        (   bControllerSuspended )
       )
    {
        css::uno::Reference< css::frame::XController > xController = xCloseFrame->getController();
        if (xController.is())
            xController->suspend(sal_False);
    }

    // inform listener
    sal_Int16 nState = css::frame::DispatchResultState::FAILURE;
    if (bSuccess)
        nState = css::frame::DispatchResultState::SUCCESS;
    implts_notifyResultListener(xListener, nState, css::uno::Any());

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

    // This method was called asynchronous from our main thread by using a pointer.
    // We reached this method only, by using a reference to ourself :-)
    // Further this member is used to detect still running and not yet finished
    // ansynchronous operations. So its time now to release this reference.
    // But hold it temp alive. Otherwhise we die before we can finish this method realy :-))
    css::uno::Reference< css::uno::XInterface > xTempHold = m_xSelfHold;
    m_xSelfHold.clear();
    m_xResultListener.clear();

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

    }
    catch(const css::lang::DisposedException&)
    {
        LOG_ERROR("CloseDispatcher::impl_asyncCallback", "Congratulation! You found the reason for bug #120310#. Please contact the right developer and show him a scenario, which trigger this bug. THX.")
    }

    return 0;
}

//-----------------------------------------------
sal_Bool CloseDispatcher::implts_prepareFrameForClosing(const css::uno::Reference< css::frame::XFrame >& xFrame                ,
                                                              sal_Bool                                   bAllowSuspend         ,
                                                              sal_Bool                                   bCloseAllOtherViewsToo,
                                                              sal_Bool&                                  bControllerSuspended  )
{
    // Frame already dead ... so this view is closed ... is closed ... is ... .-)
    if (! xFrame.is())
        return sal_True;

    // Close all views to the same document ... if forced to do so.
    // But dont touch our own frame here!
    // We must do so ... because the may be following controller->suspend()
    // will show the "save/discard/cancel" dialog for the last view only!
    if (bCloseAllOtherViewsToo)
    {
        // SAFE -> ----------------------------------
        ReadGuard aReadLock(m_aLock);
        css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR  = m_xSMGR;
        aReadLock.unlock();
        // <- SAFE ----------------------------------

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

        sal_Int32 c = aCheck.m_lModelFrames.getLength();
        sal_Int32 i = 0;
        for (i=0; i<c; ++i)
        {
            if (!fpf::closeIt(aCheck.m_lModelFrames[i], sal_False))
                return sal_False;
        }
    }

    // If allowed - inform user about modified documents or
    // still running jobs (e.g. printing).
    if (bAllowSuspend)
    {
        css::uno::Reference< css::frame::XController > xController = xFrame->getController();
        if (xController.is()) // some views dont uses a controller .-( (e.g. the help window)
        {
            bControllerSuspended = xController->suspend(sal_True);
            if (! bControllerSuspended)
                return sal_False;
        }
    }

    // dont remove the component realy by e.g. calling setComponent(null, null).
    // It's enough to suspend the controller.
    // If we close the frame later this controller doesnt show the same dialog again.
    return sal_True;
}

//-----------------------------------------------
sal_Bool CloseDispatcher::implts_closeFrame()
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::frame::XFrame > xFrame (m_xCloseFrame.get(), css::uno::UNO_QUERY);
    aReadLock.unlock();
    // <- SAFE ----------------------------------

    // frame already dead ? => so it's closed ... it's closed ...
    if ( ! xFrame.is() )
        return sal_True;

    // dont deliver owner ship; our "UI user" will try it again if it failed.
    // OK - he will get an empty frame then. But normaly an empty frame
    // should be closeable always :-)
    if (!fpf::closeIt(xFrame, sal_False))
        return sal_False;

    // SAFE -> ----------------------------------
    WriteGuard aWriteLock(m_aLock);
    m_xCloseFrame = css::uno::WeakReference< css::frame::XFrame >();
    aWriteLock.unlock();
    // <- SAFE ----------------------------------

    return sal_True;
}

//-----------------------------------------------
sal_Bool CloseDispatcher::implts_establishBackingMode()
{
    // SAFE -> ----------------------------------
    ReadGuard aReadLock(m_aLock);
    css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR  = m_xSMGR;
    css::uno::Reference< css::frame::XFrame >              xFrame (m_xCloseFrame.get(), css::uno::UNO_QUERY);
    aReadLock.unlock();
    // <- SAFE ----------------------------------

    if (!xFrame.is())
        return sal_False;

	css::uno::Reference < css::document::XActionLockable > xLock( xFrame, css::uno::UNO_QUERY );
	if ( xLock.is() && xLock->isActionLocked() )
		return sal_False;

    css::uno::Reference< css::awt::XWindow > xContainerWindow = xFrame->getContainerWindow();
    css::uno::Sequence< css::uno::Any > lArgs(1);
    lArgs[0] <<= xContainerWindow;

    css::uno::Reference< css::frame::XController > xBackingComp(
        xSMGR->createInstanceWithArguments(SERVICENAME_STARTMODULE, lArgs),
        css::uno::UNO_QUERY_THROW);

    // Attention: You MUST(!) call setComponent() before you call attachFrame().
    css::uno::Reference< css::awt::XWindow > xBackingWin(xBackingComp, css::uno::UNO_QUERY);
    xFrame->setComponent(xBackingWin, xBackingComp);
    xBackingComp->attachFrame(xFrame);
    xContainerWindow->setVisible(sal_True);

    return sal_True;
}

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

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

    return xDesktop->terminate();
}

//-----------------------------------------------
void CloseDispatcher::implts_notifyResultListener(const css::uno::Reference< css::frame::XDispatchResultListener >& xListener,
                                                        sal_Int16                                                   nState   ,
                                                  const css::uno::Any&                                              aResult  )
{
    if (!xListener.is())
        return;

    css::frame::DispatchResultEvent aEvent(
        css::uno::Reference< css::uno::XInterface >(static_cast< ::cppu::OWeakObject* >(this), css::uno::UNO_QUERY),
        nState,
        aResult);

    xListener->dispatchFinished(aEvent);
}

//-----------------------------------------------
css::uno::Reference< css::frame::XFrame > CloseDispatcher::static_impl_searchRightTargetFrame(const css::uno::Reference< css::frame::XFrame >& xFrame ,
                                                                                              const ::rtl::OUString&                           sTarget)
{
    if (sTarget.equalsIgnoreAsciiCaseAscii("_self"))
        return xFrame;

    OSL_ENSURE((sTarget.getLength() < 1), "CloseDispatch used for unexpected target. Magic things will happen now .-)");

    css::uno::Reference< css::frame::XFrame > xTarget = xFrame;
    while(sal_True)
    {
        // a) top frames wil be closed
        if (xTarget->isTop())
            return xTarget;

        // b) even child frame containing top level windows (e.g. query designer of database) will be closed
        css::uno::Reference< css::awt::XWindow >    xWindow        = xTarget->getContainerWindow();
        css::uno::Reference< css::awt::XTopWindow > xTopWindowCheck(xWindow, css::uno::UNO_QUERY);
        if (xTopWindowCheck.is())
        {
            // b1) Note: Toolkit interface XTopWindow sometimes is used by real VCL-child-windows also .-)
            //     Be sure that these window is realy a "top system window".
            //     Attention ! Checking Window->GetParent() isnt the right approach here.
            //     Because sometimes VCL create "implicit border windows" as parents even we created
            //     a simple XWindow using the toolkit only .-(
            ::vos::OGuard aSolarLock(&Application::GetSolarMutex());
            Window* pWindow = VCLUnoHelper::GetWindow( xWindow );
            if (
                (pWindow				  ) &&
                (pWindow->IsSystemWindow())
               )
                return xTarget;
        }

        // c) try to find better results on parent frame
        //    If no parent frame exists (because this frame is used outside the desktop tree)
        //    the given frame must be used directly.
        css::uno::Reference< css::frame::XFrame > xParent(xTarget->getCreator(), css::uno::UNO_QUERY);
        if ( ! xParent.is())
            return xTarget;

        // c1) check parent frame inside next loop ...
        xTarget = xParent;
    }
}

} // namespace framework
