/**************************************************************
 * 
 * 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, pText );
}
//--------------------------------------------------------------------------------------------------
static inline void out( const OUString & rText )
{
    if (! s_quiet)
    {
        OString aText( OUStringToOString( rText, RTL_TEXTENCODING_ASCII_US ) );
        fprintf( stderr, 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: ignroing 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, instanciate, 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;
}



