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



#include <stdio.h>
#include <vector>

#include "sal/main.h"
#include <osl/diagnose.h>
#include <osl/mutex.hxx>
#include <osl/conditn.hxx>
#include <osl/module.h>

#include <rtl/process.h>
#include <rtl/string.h>
#include <rtl/strbuf.hxx>
#include <rtl/ustrbuf.hxx>

#include <uno/environment.h>
#include <uno/mapping.hxx>

#include <cppuhelper/factory.hxx>
#include <cppuhelper/bootstrap.hxx>
#include <cppuhelper/servicefactory.hxx>
#include <cppuhelper/shlib.hxx>
#include <cppuhelper/implbase1.hxx>

#include <com/sun/star/lang/XMain.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <com/sun/star/lang/XSingleServiceFactory.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/lang/XEventListener.hpp>
#include <com/sun/star/container/XSet.hpp>
#include <com/sun/star/loader/XImplementationLoader.hpp>
#include <com/sun/star/registry/XSimpleRegistry.hpp>
#include <com/sun/star/registry/XRegistryKey.hpp>
#include <com/sun/star/connection/XAcceptor.hpp>
#include <com/sun/star/connection/XConnection.hpp>
#include <com/sun/star/bridge/XBridgeFactory.hpp>
#include <com/sun/star/bridge/XBridge.hpp>
#include <osl/process.h>
#include <osl/thread.h>
#include <osl/file.hxx>

#ifdef SAL_UNX
#define SEPARATOR '/'
#else
#define SEPARATOR '\\'
#endif

using namespace std;
using namespace rtl;
using namespace osl;
using namespace cppu;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::loader;
using namespace com::sun::star::registry;
using namespace com::sun::star::connection;
using namespace com::sun::star::bridge;
using namespace com::sun::star::container;

namespace unoexe
{

static sal_Bool isFileUrl(const OUString& fileName)
{
    if (fileName.indexOf(OUString::createFromAscii("file://")) == 0 )
        return sal_True;
    return sal_False;
}

static OUString convertToFileUrl(const OUString& fileName)
{
    if ( isFileUrl(fileName) )
    {
        return fileName;
    }

    OUString uUrlFileName;
    if ( fileName.indexOf('.') == 0 || fileName.indexOf(SEPARATOR) < 0 )
    {
        OUString uWorkingDir;
        if (osl_getProcessWorkingDir(&uWorkingDir.pData) != osl_Process_E_None) {
            OSL_ASSERT(false);
        }
        if (FileBase::getAbsoluteFileURL(uWorkingDir, fileName, uUrlFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
    } else
    {
        if (FileBase::getFileURLFromSystemPath(fileName, uUrlFileName)
            != FileBase::E_None)
        {
            OSL_ASSERT(false);
        }
    }

    return uUrlFileName;
}

static sal_Bool s_quiet = false;

//--------------------------------------------------------------------------------------------------
static inline void out( const sal_Char * pText )
{
    if (! s_quiet)
        fprintf( stderr, "%s", pText );
}
//--------------------------------------------------------------------------------------------------
static inline void out( const OUString & rText )
{
    if (! s_quiet)
    {
        OString aText( OUStringToOString( rText, RTL_TEXTENCODING_ASCII_US ) );
        fprintf( stderr, "%s", aText.getStr() );
    }
}

//--------------------------------------------------------------------------------------------------
static const char arUsingText[] =
"\nusing:\n\n"
"uno [-c ComponentImplementationName -l LocationUrl | -s ServiceName]\n"
"    [-ro ReadOnlyRegistry1] [-ro ReadOnlyRegistry2] ... [-rw ReadWriteRegistry]\n"
"    [-u uno:(socket[,host=HostName][,port=nnn]|pipe[,name=PipeName]);<protocol>;Name\n"
"        [--singleaccept] [--singleinstance]]\n"
"    [--quiet]\n"
"    [-- Argument1 Argument2 ...]\n";

//--------------------------------------------------------------------------------------------------
static sal_Bool readOption( OUString * pValue, const sal_Char * pOpt,
							sal_Int32 * pnIndex, const OUString & aArg)
	throw (RuntimeException)
{
	const OUString dash = OUString(RTL_CONSTASCII_USTRINGPARAM("-"));
	if(aArg.indexOf(dash) != 0)
		return sal_False;

	OUString aOpt = OUString::createFromAscii( pOpt );

	if (aArg.getLength() < aOpt.getLength())
		return sal_False;

	if (aOpt.equalsIgnoreAsciiCase( aArg.copy(1) ))
	{
		// take next argument
		++(*pnIndex);

		rtl_getAppCommandArg(*pnIndex, &pValue->pData);
		if (*pnIndex >= (sal_Int32)rtl_getAppCommandArgCount() || pValue->copy(1).equals(dash))
		{
			OUStringBuffer buf( 32 );
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("incomplete option \"-") );
			buf.appendAscii( pOpt );
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" given!") );
			throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
		}
		else
		{
#if OSL_DEBUG_LEVEL > 1
			out( "\n> identified option -" );
			out( pOpt );
			out( " = " );
			OString tmp = OUStringToOString(aArg, RTL_TEXTENCODING_ASCII_US);
  			out( tmp.getStr() );
#endif
			++(*pnIndex);
			return sal_True;
		}
	}
  	else if (aArg.indexOf(aOpt) == 1)
	{
		*pValue = aArg.copy(1 + aOpt.getLength());
#if OSL_DEBUG_LEVEL > 1
		out( "\n> identified option -" );
		out( pOpt );
		out( " = " );
		OString tmp = OUStringToOString(aArg.copy(aOpt.getLength()), RTL_TEXTENCODING_ASCII_US);
		out( tmp.getStr() );
#endif
		++(*pnIndex);

		return sal_True;
	}
	return sal_False;
}
//--------------------------------------------------------------------------------------------------
static sal_Bool readOption( sal_Bool * pbOpt, const sal_Char * pOpt,
							sal_Int32 * pnIndex, const OUString & aArg)
{
	const OUString dashdash(RTL_CONSTASCII_USTRINGPARAM("--"));
	OUString aOpt = OUString::createFromAscii(pOpt);

	if(aArg.indexOf(dashdash) == 0 && aOpt.equals(aArg.copy(2)))
	{
		++(*pnIndex);
		*pbOpt = sal_True;
#if OSL_DEBUG_LEVEL > 1
		out( "\n> identified option --" );
		out( pOpt );
#endif
		return sal_True;
	}
	return sal_False;
}


//##################################################################################################
//##################################################################################################
//##################################################################################################


//--------------------------------------------------------------------------------------------------
template< class T >
void createInstance(
	Reference< T > & rxOut,
	const Reference< XComponentContext > & xContext,
	const OUString & rServiceName )
	throw (Exception)
{
    Reference< XMultiComponentFactory > xMgr( xContext->getServiceManager() );
	Reference< XInterface > x( xMgr->createInstanceWithContext( rServiceName, xContext ) );

	if (! x.is())
	{
		static sal_Bool s_bSet = sal_False;
		if (! s_bSet)
		{
			MutexGuard aGuard( Mutex::getGlobalMutex() );
			if (! s_bSet)
			{
				Reference< XSet > xSet( xMgr, UNO_QUERY );
				if (xSet.is())
				{
                    Reference< XMultiServiceFactory > xSF( xMgr, UNO_QUERY );
					// acceptor
					xSet->insert( makeAny( loadSharedLibComponentFactory(
						OUString( RTL_CONSTASCII_USTRINGPARAM(
                                      "acceptor.uno" SAL_DLLEXTENSION) ),
                        OUString(),
						OUString( RTL_CONSTASCII_USTRINGPARAM(
                                      "com.sun.star.comp.io.Acceptor") ),
						xSF, Reference< XRegistryKey >() ) ) );
					// connector
					xSet->insert( makeAny( loadSharedLibComponentFactory(
						OUString( RTL_CONSTASCII_USTRINGPARAM(
                                      "connector.uno" SAL_DLLEXTENSION) ),
                        OUString(),
						OUString( RTL_CONSTASCII_USTRINGPARAM(
                                      "com.sun.star.comp.io.Connector") ),
						xSF, Reference< XRegistryKey >() ) ) );
					// bridge factory
					xSet->insert( makeAny( loadSharedLibComponentFactory(
						OUString( RTL_CONSTASCII_USTRINGPARAM(
                                      "binaryurp.uno" SAL_DLLEXTENSION) ),
                        OUString(),
						OUString(
                            RTL_CONSTASCII_USTRINGPARAM(
                                "com.sun.star.comp.bridge.BridgeFactory") ),
						xSF, Reference< XRegistryKey >() ) ) );
				}
				s_bSet = sal_True;
			}
		}
		x = xMgr->createInstanceWithContext( rServiceName, xContext );
	}

	if (! x.is())
	{
		OUStringBuffer buf( 64 );
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("cannot get service instance \"") );
		buf.append( rServiceName );
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
		throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
	}

	rxOut = Reference< T >::query( x );
	if (! rxOut.is())
	{
		OUStringBuffer buf( 64 );
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("service instance \"") );
		buf.append( rServiceName );
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" does not support demanded interface \"") );
		const Type & rType = ::getCppuType( (const Reference< T > *)0 );
		buf.append( rType.getTypeName() );
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
		throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
	}
}
//--------------------------------------------------------------------------------------------------
static Reference< XSimpleRegistry > nestRegistries(
	const Reference< XSimpleRegistry > & xReadWrite,
	const Reference< XSimpleRegistry > & xReadOnly )
	throw (Exception)
{
	Reference< XSimpleRegistry > xReg( createNestedRegistry() );
    if (! xReg.is())
    {
		throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM("no nested registry service!" ) ),
            Reference< XInterface >() );
    }

	Reference< XInitialization > xInit( xReg, UNO_QUERY );
	if (! xInit.is())
		throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("nested registry does not export interface \"com.sun.star.lang.XInitialization\"!" ) ), Reference< XInterface >() );

	Sequence< Any > aArgs( 2 );
	aArgs[0] <<= xReadWrite;
	aArgs[1] <<= xReadOnly;
	xInit->initialize( aArgs );

	return xReg;
}
//--------------------------------------------------------------------------------------------------
static Reference< XSimpleRegistry > openRegistry(
	const OUString & rURL,
	sal_Bool bReadOnly, sal_Bool bCreate )
	throw (Exception)
{
	Reference< XSimpleRegistry > xNewReg( createSimpleRegistry() );
    if (! xNewReg.is())
    {
		throw RuntimeException(
            OUString( RTL_CONSTASCII_USTRINGPARAM("no simple registry service!" ) ),
            Reference< XInterface >() );
    }

	try
	{
		xNewReg->open( convertToFileUrl(rURL), bReadOnly, bCreate );
		if (xNewReg->isValid())
			return xNewReg;
		else
			xNewReg->close();
	}
	catch (Exception &)
	{
	}

	out( "\n> warning: cannot open registry \"" );
	out( rURL );
	if (bReadOnly)
		out( "\" for reading, ignoring!" );
	else
		out( "\" for reading and writing, ignoring!" );
	return Reference< XSimpleRegistry >();
}
//--------------------------------------------------------------------------------------------------
static Reference< XInterface > loadComponent(
	const Reference< XComponentContext > & xContext,
	const OUString & rImplName, const OUString & rLocation )
	throw (Exception)
{
	// determine loader to be used
	sal_Int32 nDot = rLocation.lastIndexOf( '.' );
	if (nDot > 0 && nDot < rLocation.getLength())
	{
		Reference< XImplementationLoader > xLoader;

		OUString aExt( rLocation.copy( nDot +1 ) );

		if (aExt.compareToAscii( "dll" ) == 0 ||
			aExt.compareToAscii( "exe" ) == 0 ||
			aExt.compareToAscii( "dylib" ) == 0 ||
			aExt.compareToAscii( "so" ) == 0)
		{
			createInstance(
				xLoader, xContext, OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.SharedLibrary") ) );
		}
		else if (aExt.compareToAscii( "jar" ) == 0 ||
				 aExt.compareToAscii( "class" ) == 0)
		{
			createInstance(
				xLoader, xContext, OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.loader.Java") ) );
		}
		else
		{
			OUStringBuffer buf( 64 );
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unknown extension of \"") );
			buf.append( rLocation );
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!  No loader available!") );
			throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
		}

		Reference< XInterface > xInstance;

		// activate
		Reference< XInterface > xFactory( xLoader->activate(
			rImplName, OUString(), rLocation, Reference< XRegistryKey >() ) );
		if (xFactory.is())
        {
            Reference< XSingleComponentFactory > xCFac( xFactory, UNO_QUERY );
            if (xCFac.is())
            {
                xInstance = xCFac->createInstanceWithContext( xContext );
            }
            else
            {
                Reference< XSingleServiceFactory > xSFac( xFactory, UNO_QUERY );
                if (xSFac.is())
                {
                    out( "\n> warning: ignoring context for implementation \"" );
                    out( rImplName );
                    out( "\"!" );
                    xInstance = xSFac->createInstance();
                }
            }
        }

		if (! xInstance.is())
		{
			OUStringBuffer buf( 64 );
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("activating component \"") );
			buf.append( rImplName );
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" from location \"") );
			buf.append( rLocation );
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" failed!") );
			throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
		}

		return xInstance;
	}
	else
	{
		OUStringBuffer buf( 64 );
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("location \"") );
		buf.append( rLocation );
		buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\" has no extension!  Cannot determine loader to be used!") );
		throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
	}
}


//##################################################################################################
//##################################################################################################
//##################################################################################################


//==================================================================================================
class OInstanceProvider
	: public WeakImplHelper1< XInstanceProvider >
{
	Reference< XComponentContext > _xContext;

	Mutex							  _aSingleInstanceMutex;
	Reference< XInterface >			  _xSingleInstance;
	sal_Bool						  _bSingleInstance;

	OUString						  _aImplName;
	OUString						  _aLocation;
	OUString						  _aServiceName;
	Sequence< Any >					  _aInitParams;

	OUString						  _aInstanceName;

	inline Reference< XInterface > createInstance() throw (Exception);

public:
	OInstanceProvider( const Reference< XComponentContext > & xContext,
					   const OUString & rImplName, const OUString & rLocation,
					   const OUString & rServiceName, const Sequence< Any > & rInitParams,
					   sal_Bool bSingleInstance, const OUString & rInstanceName )
		: _xContext( xContext )
		, _bSingleInstance( bSingleInstance )
		, _aImplName( rImplName )
		, _aLocation( rLocation )
		, _aServiceName( rServiceName )
		, _aInitParams( rInitParams )
		, _aInstanceName( rInstanceName )
		{}

	// XInstanceProvider
	virtual Reference< XInterface > SAL_CALL getInstance( const OUString & rName )
		throw (NoSuchElementException, RuntimeException);
};
//__________________________________________________________________________________________________
inline Reference< XInterface > OInstanceProvider::createInstance()
	throw (Exception)
{
	Reference< XInterface > xRet;
	if (_aImplName.getLength()) // manually via loader
		xRet = loadComponent( _xContext, _aImplName, _aLocation );
	else // via service manager
		unoexe::createInstance( xRet, _xContext, _aServiceName );

	// opt XInit
	Reference< XInitialization > xInit( xRet, UNO_QUERY );
	if (xInit.is())
		xInit->initialize( _aInitParams );

	return xRet;
}
//__________________________________________________________________________________________________
Reference< XInterface > OInstanceProvider::getInstance( const OUString & rName )
	throw (NoSuchElementException, RuntimeException)
{
	try
	{
		if (_aInstanceName == rName)
		{
			Reference< XInterface > xRet;

            if (_aImplName.getLength() == 0 && _aServiceName.getLength() == 0)
            {
                OSL_ASSERT(
                    rName.equalsAsciiL(
                        RTL_CONSTASCII_STRINGPARAM("uno.ComponentContext") ) );
                xRet = _xContext;
            }
			else if (_bSingleInstance)
			{
				if (! _xSingleInstance.is())
				{
					MutexGuard aGuard( _aSingleInstanceMutex );
					if (! _xSingleInstance.is())
					{
						_xSingleInstance = createInstance();
					}
				}
				xRet = _xSingleInstance;
			}
			else
			{
				xRet = createInstance();
			}

			return xRet;
		}
	}
	catch (Exception & rExc)
	{
		out( "\n> error: " );
		out( rExc.Message );
	}
	OUStringBuffer buf( 64 );
	buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("no such element \"") );
	buf.append( rName );
	buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
	throw NoSuchElementException( buf.makeStringAndClear(), Reference< XInterface >() );
}

//==================================================================================================
struct ODisposingListener : public WeakImplHelper1< XEventListener >
{
	Condition cDisposed;

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

	//----------------------------------------------------------------------------------------------
	static void waitFor( const Reference< XComponent > & xComp );
};
//__________________________________________________________________________________________________
void ODisposingListener::disposing( const EventObject & )
	throw (RuntimeException)
{
	cDisposed.set();
}
//--------------------------------------------------------------------------------------------------
void ODisposingListener::waitFor( const Reference< XComponent > & xComp )
{
	ODisposingListener * pListener = new ODisposingListener();
	Reference< XEventListener > xListener( pListener );

	xComp->addEventListener( xListener );
	pListener->cDisposed.wait();
}


//##################################################################################################
//##################################################################################################
//##################################################################################################


//##################################################################################################
} // namespace unoexe

using namespace unoexe;

SAL_IMPLEMENT_MAIN_WITH_ARGS(argc,)
{
	if (argc <= 1)
	{
		out( arUsingText );
		return 0;
	}

	sal_Int32 nRet = 0;
	Reference< XComponentContext > xContext;


	try
	{
		OUString aImplName, aLocation, aServiceName, aUnoUrl;
		vector< OUString > aReadOnlyRegistries;
		Sequence< OUString > aParams;
		sal_Bool bSingleAccept = sal_False;
		sal_Bool bSingleInstance = sal_False;

		//#### read command line arguments #########################################################

		bool bOldRegistryMimic = false;
		bool bNewRegistryMimic = false;
		OUString aReadWriteRegistry;

		sal_Int32 nPos = 0;
        sal_Int32 nCount = (sal_Int32)rtl_getAppCommandArgCount();
		// read up to arguments
		while (nPos < nCount)
		{
			OUString arg;

			rtl_getAppCommandArg(nPos, &arg.pData);

			const OUString dashdash = OUString(RTL_CONSTASCII_USTRINGPARAM("--"));
			if (dashdash == arg)
			{
				++nPos;
				break;
			}

			if (readOption( &aImplName, "c", &nPos, arg)				||
				readOption( &aLocation, "l", &nPos, arg)				||
				readOption( &aServiceName, "s", &nPos, arg)				||
				readOption( &aUnoUrl, "u", &nPos, arg)					||
				readOption( &s_quiet, "quiet", &nPos, arg)              ||
				readOption( &bSingleAccept, "singleaccept", &nPos, arg)	||
				readOption( &bSingleInstance, "singleinstance", &nPos, arg))
			{
				continue;
			}
			OUString aRegistry;
			if (readOption( &aRegistry, "ro", &nPos, arg))
			{
				aReadOnlyRegistries.push_back( aRegistry );
				bNewRegistryMimic = true;
				continue;
			}
			if (readOption( &aReadWriteRegistry, "rw", &nPos, arg))
			{
				bNewRegistryMimic = true;
				continue;
			}
			if (readOption( &aRegistry, "r", &nPos, arg))
			{
				aReadOnlyRegistries.push_back( aRegistry );
				aReadWriteRegistry = aRegistry;
				out( "\n> warning: DEPRECATED use of option -r, use -ro or -rw!" );
				bOldRegistryMimic = true;
				continue;
			}

			// else illegal argument
			OUStringBuffer buf( 64 );
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("unexpected parameter \"") );
			buf.append(arg);
			buf.appendAscii( RTL_CONSTASCII_STRINGPARAM("\"!") );
			throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface >() );
		}

		if (bOldRegistryMimic) // last one was set to be read-write
		{
			aReadOnlyRegistries.pop_back();
			if (bOldRegistryMimic && bNewRegistryMimic)
			{
				throw RuntimeException(
					OUString( RTL_CONSTASCII_USTRINGPARAM("mixing with DEPRECATED registry options!") ),
					Reference< XInterface >() );
			}
		}

		if ((aImplName.getLength() != 0) && (aServiceName.getLength() != 0))
			throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("give component exOR service name!" ) ), Reference< XInterface >() );
        if (aImplName.getLength() == 0 && aServiceName.getLength() == 0)
        {
            if (! aUnoUrl.endsWithIgnoreAsciiCaseAsciiL(
                    RTL_CONSTASCII_STRINGPARAM(";uno.ComponentContext") ))
                throw RuntimeException(
                    OUString( RTL_CONSTASCII_USTRINGPARAM(
                                  "expected UNO-URL with instance name "
                                  "uno.ComponentContext!") ),
                    Reference<XInterface>() );
            if (bSingleInstance)
                throw RuntimeException(
                    OUString( RTL_CONSTASCII_USTRINGPARAM(
                                  "unexpected option --singleinstance!") ),
                    Reference<XInterface>() );
        }
		if (aImplName.getLength() && !aLocation.getLength())
			throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("give component location!" ) ), Reference< XInterface >() );
		if (aServiceName.getLength() && aLocation.getLength())
			out( "\n> warning: service name given, will ignore location!" );

		// read component params
		aParams.realloc( nCount - nPos );
		OUString * pParams = aParams.getArray();

		sal_Int32 nOffset = nPos;
		for ( ; nPos < nCount; ++nPos )
		{
            if (rtl_getAppCommandArg( nPos, &pParams[nPos -nOffset].pData )
                != osl_Process_E_None)
            {
                OSL_ASSERT(false);
            }
		}

        if (aReadOnlyRegistries.size() > 0 ||
            aReadWriteRegistry.getLength() > 0)
        {
            //#### create registry #############################################

            Reference< XSimpleRegistry > xRegistry;

            // ReadOnly registries
            for ( size_t nReg = 0; nReg < aReadOnlyRegistries.size(); ++nReg )
            {
#if OSL_DEBUG_LEVEL > 1
                out( "\n> trying to open ro registry: " );
                out( OUStringToOString(
                         aReadOnlyRegistries[ nReg ],
                         RTL_TEXTENCODING_ASCII_US ).getStr() );
#endif
                Reference< XSimpleRegistry > xNewReg(
                    openRegistry(
                        aReadOnlyRegistries[ nReg ], sal_True, sal_False ) );
                if (xNewReg.is())
                    xRegistry = (xRegistry.is() ? nestRegistries(
                                     xNewReg, xRegistry ) : xNewReg);
            }
            if (aReadWriteRegistry.getLength())
            {
#if OSL_DEBUG_LEVEL > 1
                out( "\n> trying to open rw registry: " );
                out( OUStringToOString(
                         aReadWriteRegistry,
                         RTL_TEXTENCODING_ASCII_US ).getStr() );
#endif
                // ReadWrite registry
                Reference< XSimpleRegistry > xNewReg(
                    openRegistry( aReadWriteRegistry, sal_False, sal_True ) );
                if (xNewReg.is())
                    xRegistry = (xRegistry.is()
                                 ? nestRegistries( xNewReg, xRegistry )
                                 : xNewReg);
            }

            OSL_ASSERT( xRegistry.is() );
            xContext = bootstrap_InitialComponentContext( xRegistry );
        }
        else // defaulting
        {
            xContext = defaultBootstrap_InitialComponentContext();
        }

		//#### accept, instantiate, etc. ###########################################################

		if (aUnoUrl.getLength()) // accepting connections
		{
            sal_Int32 nIndex = 0, nTokens = 0;
            do { aUnoUrl.getToken( 0, ';', nIndex ); nTokens++; } while( nIndex != -1 );
			if (nTokens != 3 || aUnoUrl.getLength() < 10 ||
				!aUnoUrl.copy( 0, 4 ).equalsIgnoreAsciiCase( OUString( RTL_CONSTASCII_USTRINGPARAM("uno:") ) ))
			{
				throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("illegal uno url given!" ) ), Reference< XInterface >() );
			}
            nIndex = 0;
			OUString aConnectDescr( aUnoUrl.getToken( 0, ';', nIndex ).copy( 4 ) ); // uno:CONNECTDESCR;iiop;InstanceName
			OUString aInstanceName( aUnoUrl.getToken( 1, ';', nIndex ) );

			Reference< XAcceptor > xAcceptor;
			createInstance(
				xAcceptor, xContext,
				OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.connection.Acceptor") ) );

			// init params
			Sequence< Any > aInitParams( aParams.getLength() );
			const OUString * p = aParams.getConstArray();
			Any * pInitParams = aInitParams.getArray();
			for ( sal_Int32 i = aParams.getLength(); i--; )
			{
				pInitParams[i] = makeAny( p[i] );
			}

			// instance provider
			Reference< XInstanceProvider > xInstanceProvider( new OInstanceProvider(
				xContext, aImplName, aLocation, aServiceName, aInitParams,
				bSingleInstance, aInstanceName ) );

            nIndex = 0;
            OUString aUnoUrlToken( aUnoUrl.getToken( 1, ';', nIndex ) );
			for (;;)
			{
				// accepting
				out( "\n> accepting " );
				out( aConnectDescr );
				out( "..." );
				Reference< XConnection > xConnection( xAcceptor->accept( aConnectDescr ) );
				out( "connection established." );

				Reference< XBridgeFactory > xBridgeFactory;
				createInstance(
					xBridgeFactory, xContext,
					OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.bridge.BridgeFactory") ) );

				// bridge
				Reference< XBridge > xBridge( xBridgeFactory->createBridge(
					OUString(), aUnoUrlToken,
					xConnection, xInstanceProvider ) );

				if (bSingleAccept)
				{
					Reference< XComponent > xComp( xBridge, UNO_QUERY );
					if (! xComp.is())
						throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("bridge factory does not export interface \"com.sun.star.lang.XComponent\"!" ) ), Reference< XInterface >() );
					ODisposingListener::waitFor( xComp );
					break;
				}
			}
		}
		else // no uno url
		{
			Reference< XInterface > xInstance;
			if (aImplName.getLength()) // manually via loader
				xInstance = loadComponent( xContext, aImplName, aLocation );
			else // via service manager
				createInstance( xInstance, xContext, aServiceName );

			// execution
			Reference< XMain > xMain( xInstance, UNO_QUERY );
			if (xMain.is())
			{
				nRet = xMain->run( aParams );
			}
			else
			{
				Reference< XComponent > xComp( xInstance, UNO_QUERY );
				if (xComp.is())
					xComp->dispose();
				throw RuntimeException( OUString( RTL_CONSTASCII_USTRINGPARAM("component does not export interface interface \"com.sun.star.lang.XMain\"!" ) ), Reference< XInterface >() );
			}
		}
	}
	catch (Exception & rExc)
	{
		out( "\n> error: " );
		out( rExc.Message );
		out( "\n> dying..." );
		nRet = 1;
	}

	// cleanup
    Reference< XComponent > xComp( xContext, UNO_QUERY );
    if (xComp.is())
        xComp->dispose();

	out( "\n" );
	return nRet;
}
