/**************************************************************
 * 
 * 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_unotools.hxx"

#include <unotools/ucblockbytes.hxx>
#include <comphelper/processfactory.hxx>
#include <salhelper/condition.hxx>
#ifndef _OSL_THREAD_HXX_
#include <osl/thread.hxx>
#endif
#include <tools/urlobj.hxx>
#include <ucbhelper/interactionrequest.hxx>
#include <com/sun/star/task/XInteractionAbort.hpp>
#include <com/sun/star/ucb/InteractiveNetworkConnectException.hpp>
#include <com/sun/star/ucb/CommandFailedException.hpp>
#include <com/sun/star/ucb/UnsupportedDataSinkException.hpp>
#ifndef _COM_SUN_STAR_UCB_INTERACTIVEIODEXCEPTION_HPP_
#include <com/sun/star/ucb/InteractiveIOException.hpp>
#endif
#include <com/sun/star/io/XActiveDataStreamer.hpp>
#include <com/sun/star/ucb/DocumentHeaderField.hpp>
#include <com/sun/star/ucb/XCommandInfo.hpp>
#include <com/sun/star/ucb/XCommandProcessor.hpp>
#include <com/sun/star/task/XInteractionHandler.hpp>
#include <com/sun/star/ucb/OpenCommandArgument2.hpp>
#include <com/sun/star/ucb/PostCommandArgument2.hpp>
#include <com/sun/star/ucb/OpenMode.hpp>
#include <com/sun/star/beans/Property.hpp>
#include <com/sun/star/beans/PropertyValue.hpp>
#include <com/sun/star/beans/XPropertiesChangeNotifier.hpp>
#include <com/sun/star/beans/XPropertiesChangeListener.hpp>
#include <com/sun/star/sdbc/XRow.hpp>
#include <com/sun/star/io/XActiveDataSink.hpp>
#include <com/sun/star/io/XActiveDataControl.hpp>
#include <com/sun/star/io/XSeekable.hpp>
#include <cppuhelper/implbase1.hxx>
#include <cppuhelper/implbase2.hxx>
#include <tools/inetmsg.hxx>
#include <com/sun/star/io/XTruncate.hpp>
#include <com/sun/star/lang/IllegalArgumentException.hpp>

#include <comphelper/storagehelper.hxx>

#include <ucbhelper/contentbroker.hxx>
#include <ucbhelper/content.hxx>

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::io;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::ucb;
using namespace ::com::sun::star::task;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::beans;


namespace utl
{

/**
    Helper class for getting a XInputStream when opening a content
 */
class UcbDataSink_Impl : public ::cppu::WeakImplHelper2< XActiveDataControl, XActiveDataSink >
{
	UcbLockBytesRef         m_xLockBytes;

public:
							UcbDataSink_Impl( UcbLockBytes* pLockBytes )
								: m_xLockBytes( pLockBytes )
							{}

	SvLockBytes*            getLockBytes (void)
							{ return m_xLockBytes; }

	// XActiveDataControl.
    virtual void SAL_CALL   addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
    virtual void SAL_CALL   removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
    virtual void SAL_CALL   start (void) throw(RuntimeException) {}
    virtual void SAL_CALL   terminate (void) throw(RuntimeException)
                            { m_xLockBytes->terminate_Impl(); }

	// XActiveDataSink.
    virtual void SAL_CALL   setInputStream ( const Reference<XInputStream> &rxInputStream) throw(RuntimeException)
                            { m_xLockBytes->setInputStream_Impl (rxInputStream); }
    virtual Reference<XInputStream> SAL_CALL getInputStream (void) throw(RuntimeException)
                            { return m_xLockBytes->getInputStream_Impl(); }
};

/**
    Helper class for getting a XStream when opening a content
 */
class UcbStreamer_Impl : public ::cppu::WeakImplHelper2< XActiveDataStreamer, XActiveDataControl >
{
    Reference < XStream >   m_xStream;
    UcbLockBytesRef         m_xLockBytes;

public:

                            UcbStreamer_Impl( UcbLockBytes* pLockBytes )
                                : m_xLockBytes( pLockBytes )
                            {}

	// XActiveDataControl.
    virtual void SAL_CALL   addListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
    virtual void SAL_CALL   removeListener ( const Reference<XStreamListener> &/*rxListener*/) throw(RuntimeException) {}
    virtual void SAL_CALL   start (void) throw(RuntimeException) {}
    virtual void SAL_CALL   terminate (void) throw(RuntimeException)
                            { m_xLockBytes->terminate_Impl(); }

    // XActiveDataStreamer
    virtual void SAL_CALL   setStream( const Reference< XStream >& aStream ) throw(RuntimeException)
                            { m_xStream = aStream; m_xLockBytes->setStream_Impl( aStream ); }
    virtual Reference< XStream > SAL_CALL getStream() throw(RuntimeException)
                            { return m_xStream; }
};

/**
    Helper class for progress handling while executing UCB commands
 */
class ProgressHandler_Impl: public ::cppu::WeakImplHelper1< XProgressHandler >
{
    Link                    m_aProgress;

public:
                            ProgressHandler_Impl( const Link& rLink )
                                : m_aProgress( rLink )
                            {}
    // XProgressHandler
    virtual void SAL_CALL   push(const Any & /*rStatus*/) throw (RuntimeException) {}
    virtual void SAL_CALL   pop() throw (RuntimeException) {}
    virtual void SAL_CALL   update(const Any & /*rStatus*/) throw (RuntimeException)
                            { if ( m_aProgress.IsSet() ) m_aProgress.Call( 0 ); }
};

/**
    Helper class for managing interactions and progress when executing UCB commands
 */
class UcbTaskEnvironment : public ::cppu::WeakImplHelper1< XCommandEnvironment >
{
    Reference< XInteractionHandler >                m_xInteractionHandler;
    Reference< XProgressHandler >                   m_xProgressHandler;

public:
                            UcbTaskEnvironment( const Reference< XInteractionHandler>& rxInteractionHandler,
                                                const Reference< XProgressHandler>& rxProgressHandler )
                                : m_xInteractionHandler( rxInteractionHandler )
                                , m_xProgressHandler( rxProgressHandler )
                            {}


    virtual Reference<XInteractionHandler> SAL_CALL getInteractionHandler() throw (RuntimeException)
	{ return m_xInteractionHandler; }

    virtual Reference<XProgressHandler> SAL_CALL    getProgressHandler() throw (RuntimeException)
	{ return m_xProgressHandler; }
};


/**
    Helper class for property change notifies when executing UCB commands
*/
class UcbPropertiesChangeListener_Impl : public ::cppu::WeakImplHelper1< XPropertiesChangeListener >
{
public:
    UcbLockBytesRef         m_xLockBytes;

                            UcbPropertiesChangeListener_Impl( UcbLockBytesRef rRef )
                                : m_xLockBytes( rRef )
                            {}

    virtual void SAL_CALL   disposing ( const EventObject &/*rEvent*/) throw(RuntimeException) {}
    virtual void SAL_CALL   propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException);
};

void SAL_CALL UcbPropertiesChangeListener_Impl::propertiesChange ( const Sequence<PropertyChangeEvent> &rEvent) throw(RuntimeException)
{
	sal_Int32 i, n = rEvent.getLength();
	for (i = 0; i < n; i++)
	{
		PropertyChangeEvent evt (rEvent[i]);
        if (evt.PropertyName == ::rtl::OUString::createFromAscii ("DocumentHeader"))
		{
			Sequence<DocumentHeaderField> aHead;
			if (evt.NewValue >>= aHead)
			{
                sal_Int32 k, m = aHead.getLength();
                for (k = 0; k < m; k++)
                {
                    String aName( aHead[k].Name );
                    String aValue( aHead[k].Value );

                    if (aName.CompareIgnoreCaseToAscii("Expires") == COMPARE_EQUAL)
                    {
                        DateTime aExpires (0, 0);
                        if (INetRFC822Message::ParseDateField (aValue, aExpires))
                        {
                            aExpires.ConvertToLocalTime();
                            m_xLockBytes->SetExpireDate_Impl( aExpires );
                        }
                    }
                }
			}

            m_xLockBytes->SetStreamValid_Impl();
		}
        else if (evt.PropertyName == rtl::OUString::createFromAscii ("PresentationURL"))
		{
            ::rtl::OUString aUrl;
			if (evt.NewValue >>= aUrl)
			{
                ::rtl::OUString aBad (::rtl::OUString::createFromAscii ("private:"));
				if (!(aUrl.compareTo (aBad, aBad.getLength()) == 0))
				{
					// URL changed (Redirection).
                    m_xLockBytes->SetRealURL_Impl( aUrl );
				}
			}
		}
        else if (evt.PropertyName == ::rtl::OUString::createFromAscii ("MediaType"))
        {
            ::rtl::OUString aContentType;
            if (evt.NewValue >>= aContentType)
                m_xLockBytes->SetContentType_Impl( aContentType );
        }
	}
}



class Moderator
	: public osl::Thread
{
	// usage restriction:
	// It might be possible, that the call to the interactionhandler and/or
	// progresshandler is done asynchrounsly, while the 'execute' simply
	// returns. This would imply that these class must be refcounted !!!

public:

	Moderator(
		Reference < XContent >& xContent,
		Reference < XInteractionHandler >& xInteract,
		Reference < XProgressHandler >& xProgress,
		const Command& rArg
    )
        throw(
            ContentCreationException,
            RuntimeException
        );

	~Moderator();


	enum ResultType {
		NORESULT,

		INTERACTIONREQUEST,    // reply expected

		PROGRESSPUSH,
		PROGRESSUPDATE,
		PROGRESSPOP,

        INPUTSTREAM,
        STREAM,

		RESULT,
		TIMEDOUT,
		COMMANDABORTED,
		COMMANDFAILED,
		INTERACTIVEIO,
		UNSUPPORTED,
		GENERAL
	};


	class ConditionRes
		: public salhelper::Condition
	{
	public:

		ConditionRes(osl::Mutex& aMutex,Moderator& aModerator)
			: salhelper::Condition(aMutex),
              m_aModerator(aModerator)
		{
		}

	protected:

		bool applies() const {
			return m_aModerator.m_aResultType != NORESULT;
		}

	private:

		Moderator& m_aModerator;
	};


	struct Result {
		ResultType        type;
		Any               result;
		sal_Int32         ioErrorCode;
	};


	Result getResult(const sal_uInt32 milliSec);


	enum ReplyType {
		NOREPLY,
		EXIT,
		RETRY,
		REQUESTHANDLED
	};


	class ConditionRep
		: public salhelper::Condition
	{
	public:

		ConditionRep(osl::Mutex& aMutex,Moderator& aModerator)
			: salhelper::Condition(aMutex),
              m_aModerator(aModerator)
		{
		}

	protected:

		bool applies() const {
			return m_aModerator.m_aReplyType != NOREPLY;
		}

	private:

		Moderator& m_aModerator;
	};

	void setReply(ReplyType);


	void handle( const Reference<XInteractionRequest >& Request );

	void push( const Any& Status );

	void update( const Any& Status );

	void pop(  );

    void setStream(const Reference< XStream >& aStream);

    void setInputStream(const Reference<XInputStream> &rxInputStream);


protected:

	virtual void SAL_CALL run();

	virtual void SAL_CALL onTerminated();

private:

    osl::Mutex        m_aMutex;

    friend class ConditionRes;

	ConditionRes      m_aRes;
	ResultType        m_aResultType;
	sal_Int32         m_nIOErrorCode;
	Any               m_aResult;

    friend class ConditionRep;

	ConditionRep      m_aRep;
	ReplyType         m_aReplyType;

    Command                           m_aArg;
	::ucbhelper::Content              m_aContent;
};


class ModeratorsActiveDataStreamer
	: public ::cppu::WeakImplHelper1<XActiveDataStreamer>
{
public:

	ModeratorsActiveDataStreamer(Moderator &theModerator);

	~ModeratorsActiveDataStreamer();

    // XActiveDataStreamer
    virtual void SAL_CALL
    setStream(
        const Reference< XStream >& aStream
    )
        throw(
            RuntimeException
        );

    virtual Reference<XStream> SAL_CALL
    getStream (
        void
    ) throw(
        RuntimeException
    )
    {
        osl::MutexGuard aGuard(m_aMutex);
        return m_xStream;
    }


private:

    Moderator& m_aModerator;

    osl::Mutex m_aMutex;
    Reference<XStream> m_xStream;
};



class ModeratorsActiveDataSink
	: public ::cppu::WeakImplHelper1<XActiveDataSink>
{
public:

	ModeratorsActiveDataSink(Moderator &theModerator);

	~ModeratorsActiveDataSink();

	// XActiveDataSink.
    virtual void SAL_CALL
    setInputStream (
        const Reference<XInputStream> &rxInputStream
    )
        throw(
            RuntimeException
        );

    virtual Reference<XInputStream> SAL_CALL
    getInputStream (
        void
    ) throw(
        RuntimeException
    )
    {
        osl::MutexGuard aGuard(m_aMutex);
        return m_xStream;
    }


private:

	Moderator& m_aModerator;
    osl::Mutex m_aMutex;
    Reference<XInputStream> m_xStream;
};



ModeratorsActiveDataSink::ModeratorsActiveDataSink(Moderator &theModerator)
    : m_aModerator(theModerator)
{
}


ModeratorsActiveDataSink::~ModeratorsActiveDataSink()
{
}

// XActiveDataSink.
void SAL_CALL
ModeratorsActiveDataSink::setInputStream (
    const Reference<XInputStream> &rxInputStream
)
    throw(
        RuntimeException
    )
{
    m_aModerator.setInputStream(rxInputStream);
    osl::MutexGuard aGuard(m_aMutex);
    m_xStream = rxInputStream;
}


ModeratorsActiveDataStreamer::ModeratorsActiveDataStreamer(
    Moderator &theModerator
)
    : m_aModerator(theModerator)
{
}


ModeratorsActiveDataStreamer::~ModeratorsActiveDataStreamer()
{
}

// XActiveDataStreamer.
void SAL_CALL
ModeratorsActiveDataStreamer::setStream (
    const Reference<XStream> &rxStream
)
    throw(
        RuntimeException
    )
{
    m_aModerator.setStream(rxStream);
    osl::MutexGuard aGuard(m_aMutex);
    m_xStream = rxStream;
}



class ModeratorsInteractionHandler
	: public ::cppu::WeakImplHelper1<XInteractionHandler>
{
public:

	ModeratorsInteractionHandler(Moderator &theModerator);

	~ModeratorsInteractionHandler();

	virtual void SAL_CALL
	handle( const Reference<XInteractionRequest >& Request )
		throw (RuntimeException);

private:

	Moderator& m_aModerator;
};


class ModeratorsProgressHandler
	: public ::cppu::WeakImplHelper1<XProgressHandler>
{
public:

	ModeratorsProgressHandler(Moderator &theModerator);

	~ModeratorsProgressHandler();

	virtual void SAL_CALL push( const Any& Status )
		throw (
			RuntimeException);

    virtual void SAL_CALL update( const Any& Status )
		throw (RuntimeException);

    virtual void SAL_CALL pop(  )
		throw (RuntimeException);


private:

	Moderator& m_aModerator;
};


ModeratorsProgressHandler::ModeratorsProgressHandler(Moderator &theModerator)
	: m_aModerator(theModerator)
{
}

ModeratorsProgressHandler::~ModeratorsProgressHandler()
{
}


void SAL_CALL ModeratorsProgressHandler::push( const Any& Status )
	throw (
		RuntimeException)
{
	m_aModerator.push(Status);
}


void SAL_CALL ModeratorsProgressHandler::update( const Any& Status )
	throw (RuntimeException)
{
	m_aModerator.update(Status);
}


void SAL_CALL ModeratorsProgressHandler::pop(  )
	throw (RuntimeException)
{
	m_aModerator.pop();
}




ModeratorsInteractionHandler::ModeratorsInteractionHandler(
	Moderator &aModerator)
	: m_aModerator(aModerator)
{
}


ModeratorsInteractionHandler::~ModeratorsInteractionHandler()
{
}


void SAL_CALL
ModeratorsInteractionHandler::handle(
	const Reference<XInteractionRequest >& Request
)
	throw (
		RuntimeException
	)
{
	// wakes up the mainthread
	m_aModerator.handle(Request);
}




Moderator::Moderator(
	Reference < XContent >& xContent,
	Reference < XInteractionHandler >& xInteract,
	Reference < XProgressHandler >& xProgress,
	const Command& rArg
)
    throw(
        ::com::sun::star::ucb::ContentCreationException,
        ::com::sun::star::uno::RuntimeException
    )
	: m_aMutex(),

      m_aRes(m_aMutex,*this),
	  m_aResultType(NORESULT),
	  m_nIOErrorCode(0),
	  m_aResult(),

	  m_aRep(m_aMutex,*this),
	  m_aReplyType(NOREPLY),

	  m_aArg(rArg),
      m_aContent(
          xContent,
          new UcbTaskEnvironment(
              xInteract.is() ? new ModeratorsInteractionHandler(*this) : 0,
              xProgress.is() ? new ModeratorsProgressHandler(*this) : 0
          ))
{
    // now exchange the whole data sink stuff
    // with a thread safe version

    Reference<XInterface> *pxSink = NULL;

    PostCommandArgument2 aPostArg;
    OpenCommandArgument2 aOpenArg;

    int dec(2);
    if(m_aArg.Argument >>= aPostArg) {
        pxSink = &aPostArg.Sink;
        dec = 0;
    }
    else if(m_aArg.Argument >>= aOpenArg) {
        pxSink = &aOpenArg.Sink;
        dec = 1;
    }

    if(dec ==2)
        throw ContentCreationException();

    Reference < XActiveDataSink > xActiveSink(*pxSink,UNO_QUERY);
    if(xActiveSink.is())
        *pxSink = Reference<XInterface>(
            (cppu::OWeakObject*)new ModeratorsActiveDataSink(*this));

    Reference<XActiveDataStreamer> xStreamer( *pxSink, UNO_QUERY );
    if ( xStreamer.is() )
        *pxSink = Reference<XInterface>(
            (cppu::OWeakObject*)new ModeratorsActiveDataStreamer(*this));

    if(dec == 0)
        m_aArg.Argument <<= aPostArg;
    else if(dec == 1)
        m_aArg.Argument <<= aOpenArg;
}


Moderator::~Moderator()
{
}


Moderator::Result Moderator::getResult(const sal_uInt32 milliSec)
{
	Result ret;
	try {
        salhelper::ConditionWaiter aWaiter(m_aRes,milliSec);
        ret.type = m_aResultType;
        ret.result = m_aResult;
        ret.ioErrorCode = m_nIOErrorCode;

        // reset
        m_aResultType = NORESULT;
	}
	catch(const salhelper::ConditionWaiter::timedout&)
	{
		ret.type = TIMEDOUT;
	}

	return ret;
}


void Moderator::setReply(ReplyType aReplyType )
{
	salhelper::ConditionModifier aMod(m_aRep);
	m_aReplyType = aReplyType;
}


void Moderator::handle( const Reference<XInteractionRequest >& Request )
{
	ReplyType aReplyType;

	do {
		{
			salhelper::ConditionModifier aMod(m_aRes);
			m_aResultType = INTERACTIONREQUEST;
			m_aResult <<= Request;
		}

		{
			salhelper::ConditionWaiter aWait(m_aRep);
			aReplyType = m_aReplyType;

			// reset
			m_aReplyType = NOREPLY;
		}

		if(aReplyType == EXIT) {
			Sequence<Reference<XInteractionContinuation> > aSeq(
				Request->getContinuations());
			for(sal_Int32 i = 0; i < aSeq.getLength(); ++i) {
				Reference<XInteractionAbort> aRef(aSeq[i],UNO_QUERY);
				if(aRef.is()) {
					aRef->select();
				}
			}

			// resignal the exitcondition
			setReply(EXIT);
			break;
		}
	} while(aReplyType != REQUESTHANDLED);
}



void Moderator::push( const Any& Status )
{
    {
        salhelper::ConditionModifier aMod(m_aRes);
        m_aResultType = PROGRESSPUSH;
        m_aResult = Status;
    }
	ReplyType aReplyType;
    {
        salhelper::ConditionWaiter aWait(m_aRep);
		aReplyType = m_aReplyType;
		m_aReplyType = NOREPLY;
    }
	if(aReplyType == EXIT)
		setReply(EXIT);
}


void Moderator::update( const Any& Status )
{
	{
        salhelper::ConditionModifier aMod(m_aRes);
        m_aResultType = PROGRESSUPDATE;
        m_aResult = Status;
    }
	ReplyType aReplyType;
    {
        salhelper::ConditionWaiter aWait(m_aRep);
		aReplyType = m_aReplyType;
		m_aReplyType = NOREPLY;
    }
	if(aReplyType == EXIT)
		setReply(EXIT);
}


void Moderator::pop(  )
{
    {
        salhelper::ConditionModifier aMod(m_aRes);
        m_aResultType = PROGRESSPOP;
    }
	ReplyType aReplyType;
    {
        salhelper::ConditionWaiter aWait(m_aRep);
		aReplyType = m_aReplyType;
		m_aReplyType = NOREPLY;
	}
	if(aReplyType == EXIT)
		setReply(EXIT);
}


void Moderator::setStream(const Reference< XStream >& aStream)
{
    {
        salhelper::ConditionModifier aMod(m_aRes);
        m_aResultType = STREAM;
        m_aResult <<= aStream;
    }
	ReplyType aReplyType;
    {
        salhelper::ConditionWaiter aWait(m_aRep);
		aReplyType = m_aReplyType;
        m_aReplyType = NOREPLY;
    }
	if(aReplyType == EXIT)
		setReply(EXIT);
}


void Moderator::setInputStream(const Reference<XInputStream> &rxInputStream)
{
    {
        salhelper::ConditionModifier aMod(m_aRes);
        m_aResultType = INPUTSTREAM;
        m_aResult <<= rxInputStream;
    }
	ReplyType aReplyType;
    {
        salhelper::ConditionWaiter aWait(m_aRep);
		aReplyType = m_aReplyType;
        m_aReplyType = NOREPLY;
    }
	if(aReplyType == EXIT)
		setReply(EXIT);
}



void SAL_CALL Moderator::run()
{
	ResultType aResultType;
	Any        aResult;
	sal_Int32  nIOErrorCode = 0;

    try
    {
		aResult = m_aContent.executeCommand(m_aArg.Name,m_aArg.Argument);
		aResultType = RESULT;
    }
    catch ( CommandAbortedException )
    {
		aResultType = COMMANDABORTED;
    }
    catch ( CommandFailedException )
    {
		aResultType = COMMANDFAILED;
    }
    catch ( InteractiveIOException& r )
    {
		nIOErrorCode = r.Code;
		aResultType = INTERACTIVEIO;
    }
    catch ( UnsupportedDataSinkException& )
    {
		aResultType = UNSUPPORTED;
    }
    catch ( Exception )
    {
		aResultType = GENERAL;
    }

	{
		salhelper::ConditionModifier aMod(m_aRes);
		m_aResultType = aResultType;
		m_aResult = aResult;
		m_nIOErrorCode = nIOErrorCode;
	}
}



void SAL_CALL Moderator::onTerminated()
{
    {
        salhelper::ConditionWaiter aWaiter(m_aRep);
    }
 	delete this;
}


/**
   Function for opening UCB contents synchronously,
   but with handled timeout;
*/

static sal_Bool _UCBOpenContentSync(
	UcbLockBytesRef xLockBytes,
	Reference < XContent > xContent,
	const Command& rArg,
	Reference < XInterface > xSink,
	Reference < XInteractionHandler > xInteract,
	Reference < XProgressHandler > xProgress,
	UcbLockBytesHandlerRef xHandler );


static sal_Bool UCBOpenContentSync(
	UcbLockBytesRef xLockBytes,
	Reference < XContent > xContent,
	const Command& rArg,
	Reference < XInterface > xSink,
	Reference < XInteractionHandler > xInteract,
	Reference < XProgressHandler > xProgress,
	UcbLockBytesHandlerRef xHandler )
{
    // http protocol must be handled in a special way:
	//        during the opening process the input stream may change
    //        only the last inputstream after notifying the document
	//        headers is valid

	Reference<XContentIdentifier> xContId(
		xContent.is() ? xContent->getIdentifier() : 0 );

	rtl::OUString aScheme;
	if(xContId.is())
		aScheme = xContId->getContentProviderScheme();

    // now determine wether we use a timeout or not;
    if( ! aScheme.equalsIgnoreAsciiCaseAscii("http")                &&
		! aScheme.equalsIgnoreAsciiCaseAscii("https")                &&
        ! aScheme.equalsIgnoreAsciiCaseAscii("vnd.sun.star.webdav") &&
        ! aScheme.equalsIgnoreAsciiCaseAscii("ftp"))
		return _UCBOpenContentSync(
			xLockBytes,xContent,rArg,xSink,xInteract,xProgress,xHandler);

    if ( (aScheme.compareToAscii( "http" ) != COMPARE_EQUAL) ||
		 (aScheme.compareToAscii( "https" ) != COMPARE_EQUAL) )
        xLockBytes->SetStreamValid_Impl();

    Reference< XPropertiesChangeListener > xListener;
	Reference< XPropertiesChangeNotifier > xProps(xContent,UNO_QUERY);
    if(xProps.is()) {
		xListener =
			new UcbPropertiesChangeListener_Impl(xLockBytes);
        xProps->addPropertiesChangeListener(
			Sequence< ::rtl::OUString >(),
			xListener);
	}

    Any aResult;
    bool bException(false);
    bool bAborted(false);
    bool bResultAchieved(false);

    Moderator* pMod = 0;
    try {
        pMod = new Moderator(xContent,xInteract,xProgress,rArg);
        pMod->create();
    } catch(const ContentCreationException&) {
        bResultAchieved = bException = true;
        xLockBytes->SetError( ERRCODE_IO_GENERAL );
    }

    sal_uInt32 nTimeout(5000); // initially 5000 milliSec
	while(!bResultAchieved) {

        Moderator::Result res;
		// try to get the result for with timeout
		res = pMod->getResult(nTimeout);

		switch(res.type) {
        case Moderator::PROGRESSPUSH:
			{
				if(xProgress.is())
					xProgress->push(res.result);
				pMod->setReply(Moderator::REQUESTHANDLED);
				break;
			}
        case Moderator::PROGRESSUPDATE:
			{
				if(xProgress.is())
					xProgress->update(res.result);
				pMod->setReply(Moderator::REQUESTHANDLED);
				break;
			}
        case Moderator::PROGRESSPOP:
			{
				if(xProgress.is())
					xProgress->pop();
				pMod->setReply(Moderator::REQUESTHANDLED);
				break;
			}
        case Moderator::STREAM:
            {
                Reference<XStream> result;
                if(res.result >>= result) {
                    Reference < XActiveDataStreamer > xStreamer(
                        xSink, UNO_QUERY
                    );

                    if(xStreamer.is())
                        xStreamer->setStream(result);
                }
				pMod->setReply(Moderator::REQUESTHANDLED);
                break;
            }
        case Moderator::INPUTSTREAM:
            {
				Reference<XInputStream> result;
				res.result >>= result;
                Reference < XActiveDataSink > xActiveSink(
                    xSink, UNO_QUERY
                );

                if(xActiveSink.is())
                    xActiveSink->setInputStream(result);
				pMod->setReply(Moderator::REQUESTHANDLED);
                break;
            }
        case Moderator::TIMEDOUT:
			{
				Reference<XInteractionRetry> xRet;
				if(xInteract.is()) {
					InteractiveNetworkConnectException aExcep;
					INetURLObject aURL(
						xContId.is() ?
						xContId->getContentIdentifier() :
						rtl::OUString() );
					aExcep.Server = aURL.GetHost();
					aExcep.Classification = InteractionClassification_ERROR;
					aExcep.Message =
						rtl::OUString(
							RTL_CONSTASCII_USTRINGPARAM(
								"server not responding after five seconds"));
					Any request;
					request <<= aExcep;
					ucbhelper::InteractionRequest *ir =
						new ucbhelper::InteractionRequest(request);
					Reference<XInteractionRequest> xIR(ir);
					Sequence<Reference<XInteractionContinuation> > aSeq(2);
					ucbhelper::InteractionRetry *retryP =
						new ucbhelper::InteractionRetry(ir);
					aSeq[0] = retryP;
					ucbhelper::InteractionAbort *abortP =
						new ucbhelper::InteractionAbort(ir);
					aSeq[1] = abortP;

					ir->setContinuations(aSeq);
					xInteract->handle(xIR);
					rtl::Reference< ucbhelper::InteractionContinuation > ref
						= ir->getSelection();
					if(ref.is()) {
						Reference<XInterface> xInt(ref.get());
						xRet = Reference<XInteractionRetry>(xInt,UNO_QUERY);
					}
				}

				if(!xRet.is()) {
					bAborted = true;
					xLockBytes->SetError(ERRCODE_ABORT);
				}

				break;
			}
        case Moderator::INTERACTIONREQUEST:
			{
				Reference<XInteractionRequest> Request;
				res.result >>= Request;
				xInteract->handle(Request);
				pMod->setReply(Moderator::REQUESTHANDLED);
				break;
			}
        case Moderator::RESULT:
			{
				bResultAchieved = true;
				aResult = res.result;
				break;
			}
        case Moderator::COMMANDABORTED:
			{
				bAborted = true;
				xLockBytes->SetError( ERRCODE_ABORT );
				break;
			}
        case Moderator::COMMANDFAILED:
			{
				bAborted = true;
				xLockBytes->SetError( ERRCODE_ABORT );
				break;
			}
        case Moderator::INTERACTIVEIO:
			{
				bException = true;
				if ( res.ioErrorCode == IOErrorCode_ACCESS_DENIED ||
					 res.ioErrorCode == IOErrorCode_LOCKING_VIOLATION )
					xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
				else if ( res.ioErrorCode == IOErrorCode_NOT_EXISTING )
					xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
				else if ( res.ioErrorCode == IOErrorCode_CANT_READ )
					xLockBytes->SetError( ERRCODE_IO_CANTREAD );
				else
					xLockBytes->SetError( ERRCODE_IO_GENERAL );
				break;
			}
        case Moderator::UNSUPPORTED:
			{
				bException = true;
				xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
				break;
			}
        default:
			{
				bException = true;
				xLockBytes->SetError( ERRCODE_IO_GENERAL );
				break;
			}
		}

		bResultAchieved |= bException;
		bResultAchieved |= bAborted;
        if(nTimeout == 5000) nTimeout *= 2;
    }

    if(pMod) pMod->setReply(Moderator::EXIT);

    if ( bAborted || bException )
    {
        if( xHandler.Is() )
            xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes );

        Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
        if ( xActiveSink.is() )
            xActiveSink->setInputStream( Reference < XInputStream >() );

        Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
        if ( xStreamer.is() )
            xStreamer->setStream( Reference < XStream >() );
    }

    Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
    if ( xControl.is() )
        xControl->terminate();

    if ( xProps.is() )
        xProps->removePropertiesChangeListener(
			Sequence< ::rtl::OUString >(),
			xListener );

    return ( bAborted || bException );
}

/**
    Function for opening UCB contents synchronously
 */
static sal_Bool _UCBOpenContentSync(
	UcbLockBytesRef xLockBytes,
	Reference < XContent > xContent,
	const Command& rArg,
	Reference < XInterface > xSink,
	Reference < XInteractionHandler > xInteract,
	Reference < XProgressHandler > xProgress,
	UcbLockBytesHandlerRef xHandler )
{
    ::ucbhelper::Content aContent( xContent, new UcbTaskEnvironment( xInteract, xProgress ) );
    Reference < XContentIdentifier > xIdent = xContent->getIdentifier();
    ::rtl::OUString aScheme = xIdent->getContentProviderScheme();

    // http protocol must be handled in a special way: during the opening process the input stream may change
    // only the last inputstream after notifying the document headers is valid
    if ( aScheme.compareToAscii("http") != COMPARE_EQUAL )
        xLockBytes->SetStreamValid_Impl();

    Reference< XPropertiesChangeListener > xListener = new UcbPropertiesChangeListener_Impl( xLockBytes );
    Reference< XPropertiesChangeNotifier > xProps ( xContent, UNO_QUERY );
    if ( xProps.is() )
        xProps->addPropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener );

    Any aResult;
    bool bException = false;
    bool bAborted = false;

    try
    {
        aResult = aContent.executeCommand( rArg.Name, rArg.Argument );
    }
    catch ( CommandAbortedException )
    {
        bAborted = true;
		xLockBytes->SetError( ERRCODE_ABORT );
    }
    catch ( CommandFailedException )
    {
        bAborted = true;
		xLockBytes->SetError( ERRCODE_ABORT );
    }
    catch ( InteractiveIOException& r )
    {
		bException = true;
        if ( r.Code == IOErrorCode_ACCESS_DENIED || r.Code == IOErrorCode_LOCKING_VIOLATION )
			xLockBytes->SetError( ERRCODE_IO_ACCESSDENIED );
		else if ( r.Code == IOErrorCode_NOT_EXISTING )
			xLockBytes->SetError( ERRCODE_IO_NOTEXISTS );
		else if ( r.Code == IOErrorCode_CANT_READ )
			xLockBytes->SetError( ERRCODE_IO_CANTREAD );
		else
			xLockBytes->SetError( ERRCODE_IO_GENERAL );
    }
    catch ( UnsupportedDataSinkException& )
    {
		bException = true;
        xLockBytes->SetError( ERRCODE_IO_NOTSUPPORTED );
    }
    catch ( Exception )
    {
        bException = true;
		xLockBytes->SetError( ERRCODE_IO_GENERAL );
    }

    if ( bAborted || bException )
    {
        if( xHandler.Is() )
            xHandler->Handle( UcbLockBytesHandler::CANCEL, xLockBytes );

        Reference < XActiveDataSink > xActiveSink( xSink, UNO_QUERY );
        if ( xActiveSink.is() )
            xActiveSink->setInputStream( Reference < XInputStream >() );

        Reference < XActiveDataStreamer > xStreamer( xSink, UNO_QUERY );
        if ( xStreamer.is() )
            xStreamer->setStream( Reference < XStream >() );
    }

    Reference < XActiveDataControl > xControl( xSink, UNO_QUERY );
    if ( xControl.is() )
        xControl->terminate();


    if ( xProps.is() )
        xProps->removePropertiesChangeListener( Sequence< ::rtl::OUString >(), xListener );

    return ( bAborted || bException );
}


//----------------------------------------------------------------------------
UcbLockBytes::UcbLockBytes( UcbLockBytesHandler* pHandler )
    : m_xInputStream (NULL)
    , m_pCommandThread( NULL )
    , m_xHandler( pHandler )
    , m_nError( ERRCODE_NONE )
    , m_bTerminated  (sal_False)
    , m_bDontClose( sal_False )
    , m_bStreamValid  (sal_False)
{
    SetSynchronMode( sal_True );
}

//----------------------------------------------------------------------------
UcbLockBytes::~UcbLockBytes()
{
    if ( !m_bDontClose )
    {
        if ( m_xInputStream.is() )
        {
			try
			{
				m_xInputStream->closeInput();
			}
			catch ( RuntimeException const & )
			{}
			catch ( IOException const & )
			{}
        }
    }

    if ( !m_xInputStream.is() && m_xOutputStream.is() )
    {
        try
        {
            m_xOutputStream->closeOutput();
        }
        catch ( RuntimeException const & )
        {}
        catch ( IOException const & )
        {}
    }
}

Reference < XInputStream > UcbLockBytes::getInputStream()
{
	vos::OClearableGuard aGuard( m_aMutex );
    m_bDontClose = sal_True;
    return m_xInputStream;
}

Reference < XStream > UcbLockBytes::getStream()
{
	vos::OClearableGuard aGuard( m_aMutex );
	Reference < XStream > xStream( m_xSeekable, UNO_QUERY );
	if ( xStream.is() )
    	m_bDontClose = sal_True;
    return xStream;
}

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

sal_Bool UcbLockBytes::setStream_Impl( const Reference<XStream>& aStream )
{
	vos::OClearableGuard aGuard( m_aMutex );
    if ( aStream.is() )
    {
        m_xOutputStream = aStream->getOutputStream();
        setInputStream_Impl( aStream->getInputStream(), sal_False );
        m_xSeekable = Reference < XSeekable > ( aStream, UNO_QUERY );
    }
    else
    {
        m_xOutputStream = Reference < XOutputStream >();
        setInputStream_Impl( Reference < XInputStream >() );
    }

    return m_xInputStream.is();
}

sal_Bool UcbLockBytes::setInputStream_Impl( const Reference<XInputStream> &rxInputStream, sal_Bool bSetXSeekable )
{
	sal_Bool bRet = sal_False;

	try
	{
		vos::OClearableGuard aGuard( m_aMutex );

		if ( !m_bDontClose && m_xInputStream.is() )
			m_xInputStream->closeInput();

		m_xInputStream = rxInputStream;

		if( bSetXSeekable )
		{
    		m_xSeekable = Reference < XSeekable > ( rxInputStream, UNO_QUERY );
			if( !m_xSeekable.is() && rxInputStream.is() )
			{
            	Reference < XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
				Reference< XOutputStream > rxTempOut = Reference < XOutputStream > (
									xFactory->createInstance ( ::rtl::OUString::createFromAscii( "com.sun.star.io.TempFile" ) ),
									UNO_QUERY );

				if( rxTempOut.is() )
				{
					::comphelper::OStorageHelper::CopyInputToOutput( rxInputStream, rxTempOut );
					m_xInputStream = Reference< XInputStream >( rxTempOut, UNO_QUERY );
        			m_xSeekable = Reference < XSeekable > ( rxTempOut, UNO_QUERY );
				}
			}
		}

		bRet = m_xInputStream.is();
		// aGuard.clear();
	}
	catch( Exception& )
	{}

    if ( m_bStreamValid && m_xInputStream.is() )
        m_aInitialized.set();

	return bRet;
}

void UcbLockBytes::SetStreamValid_Impl()
{
    m_bStreamValid = sal_True;
    if ( m_xInputStream.is() )
        m_aInitialized.set();
}

//----------------------------------------------------------------------------
void UcbLockBytes::terminate_Impl()
{
	m_bTerminated = sal_True;
	m_aInitialized.set();
	m_aTerminated.set();

    if ( GetError() == ERRCODE_NONE && !m_xInputStream.is() )
	{
		DBG_ERROR("No InputStream, but no error set!" );
        SetError( ERRCODE_IO_NOTEXISTS );
	}

    if ( m_xHandler.Is() )
        m_xHandler->Handle( UcbLockBytesHandler::DONE, this );
}

//----------------------------------------------------------------------------
void UcbLockBytes::SetSynchronMode (sal_Bool bSynchron)
{
	SvLockBytes::SetSynchronMode (bSynchron);
}

//----------------------------------------------------------------------------
ErrCode UcbLockBytes::ReadAt ( sal_uLong nPos, void *pBuffer, sal_uLong nCount, sal_uLong *pRead) const
{
	if ( IsSynchronMode() )
    {
        UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
        pThis->m_aInitialized.wait();
    }

    Reference <XInputStream> xStream = getInputStream_Impl();
	if ( !xStream.is() )
	{
		if ( m_bTerminated )
			return ERRCODE_IO_CANTREAD;
		else
			return ERRCODE_IO_PENDING;
	}

	if ( pRead )
		*pRead = 0;

    Reference <XSeekable> xSeekable = getSeekable_Impl();
    if ( !xSeekable.is() )
		return ERRCODE_IO_CANTREAD;

	try
	{
        xSeekable->seek( nPos );
	}
	catch ( IOException )
	{
		return ERRCODE_IO_CANTSEEK;
	}
	catch (com::sun::star::lang::IllegalArgumentException)
	{
		return ERRCODE_IO_CANTSEEK;
	}

	Sequence<sal_Int8> aData;
	sal_Int32          nSize;

	nCount = VOS_MIN(nCount, 0x7FFFFFFF);
	try
	{
		if ( !m_bTerminated && !IsSynchronMode() )
		{
            sal_uInt64 nLen = xSeekable->getLength();
			if ( nPos + nCount > nLen )
				return ERRCODE_IO_PENDING;
		}

		nSize = xStream->readBytes( aData, sal_Int32(nCount) );
	}
	catch (IOException)
	{
		return ERRCODE_IO_CANTREAD;
	}

	rtl_copyMemory (pBuffer, aData.getConstArray(), nSize);
	if (pRead)
		*pRead = sal_uLong(nSize);

	return ERRCODE_NONE;
}

//----------------------------------------------------------------------------
ErrCode UcbLockBytes::WriteAt ( sal_uLong nPos, const void *pBuffer, sal_uLong nCount, sal_uLong *pWritten)
{
	if ( pWritten )
		*pWritten = 0;

    DBG_ASSERT( IsSynchronMode(), "Writing is only possible in SynchronMode!" );
    DBG_ASSERT( m_aInitialized.check(), "Writing bevor stream is ready!" );

    Reference <XSeekable> xSeekable = getSeekable_Impl();
    Reference <XOutputStream> xOutputStream = getOutputStream_Impl();
    if ( !xOutputStream.is() || !xSeekable.is() )
        return ERRCODE_IO_CANTWRITE;

	try
	{
        xSeekable->seek( nPos );
	}
	catch ( IOException )
	{
		return ERRCODE_IO_CANTSEEK;
	}

    sal_Int8* pData = (sal_Int8*) pBuffer;
    Sequence<sal_Int8> aData( pData, nCount );
	try
	{
        xOutputStream->writeBytes( aData );
        if ( pWritten )
            *pWritten = nCount;
	}
    catch ( Exception )
	{
        return ERRCODE_IO_CANTWRITE;
	}

	return ERRCODE_NONE;
}

//----------------------------------------------------------------------------
ErrCode UcbLockBytes::Flush() const
{
    Reference <XOutputStream > xOutputStream = getOutputStream_Impl();
    if ( !xOutputStream.is() )
        return ERRCODE_IO_CANTWRITE;

    try
    {
        xOutputStream->flush();
    }
    catch( Exception )
    {
        return ERRCODE_IO_CANTWRITE;
    }

    return ERRCODE_NONE;
}

//----------------------------------------------------------------------------
ErrCode UcbLockBytes::SetSize (sal_uLong nNewSize)
{
    SvLockBytesStat aStat;
    Stat( &aStat, (SvLockBytesStatFlag) 0 );
    sal_uLong nSize = aStat.nSize;

    if ( nSize > nNewSize )
    {
        Reference < XTruncate > xTrunc( getOutputStream_Impl(), UNO_QUERY );
        if ( xTrunc.is() )
        {
            xTrunc->truncate();
            nSize = 0;
        }
        else {
            DBG_WARNING("Not truncatable!");
        }
    }

    if ( nSize < nNewSize )
    {
        sal_uLong nDiff = nNewSize-nSize, nCount=0;
        sal_uInt8* pBuffer = new sal_uInt8[ nDiff ];
        memset(pBuffer, 0, nDiff); // initialize for enhanced security
        WriteAt( nSize, pBuffer, nDiff, &nCount );
        delete[] pBuffer;
        if ( nCount != nDiff )
            return ERRCODE_IO_CANTWRITE;
    }

    return ERRCODE_NONE;
}

//----------------------------------------------------------------------------
ErrCode UcbLockBytes::Stat( SvLockBytesStat *pStat, SvLockBytesStatFlag) const
{
	if ( IsSynchronMode() )
    {
        UcbLockBytes* pThis = const_cast < UcbLockBytes* >( this );
        pThis->m_aInitialized.wait();
    }

	if (!pStat)
		return ERRCODE_IO_INVALIDPARAMETER;

    Reference <XInputStream> xStream = getInputStream_Impl();
    Reference <XSeekable> xSeekable = getSeekable_Impl();

    if ( !xStream.is() )
    {
		if ( m_bTerminated )
            return ERRCODE_IO_INVALIDACCESS;
		else
			return ERRCODE_IO_PENDING;
    }
    else if( !xSeekable.is() )
		return ERRCODE_IO_CANTTELL;

	try
	{
        pStat->nSize = sal_uLong(xSeekable->getLength());
	}
	catch (IOException)
	{
		return ERRCODE_IO_CANTTELL;
	}

    return ERRCODE_NONE;
}

//----------------------------------------------------------------------------
void UcbLockBytes::Cancel()
{
	// is alive only for compatibility reasons
	OSL_ENSURE( m_bTerminated, "UcbLockBytes is not thread safe so it can be used only syncronously!\n" );
}

//----------------------------------------------------------------------------
IMPL_LINK( UcbLockBytes, DataAvailHdl, void*, EMPTYARG )
{
    if ( hasInputStream_Impl() && m_xHandler.Is() )
        m_xHandler->Handle( UcbLockBytesHandler::DATA_AVAILABLE, this );

	return 0;
}

UcbLockBytesRef UcbLockBytes::CreateInputLockBytes( const Reference< XInputStream >& xInputStream )
{
    if( !xInputStream.is() )
		return NULL;;

    UcbLockBytesRef xLockBytes = new UcbLockBytes();
    xLockBytes->setDontClose_Impl();
    xLockBytes->setInputStream_Impl( xInputStream );
    xLockBytes->terminate_Impl();
    return xLockBytes;
}

UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference< XStream >& xStream )
{
    if( !xStream.is() )
		return NULL;;

    UcbLockBytesRef xLockBytes = new UcbLockBytes();
    xLockBytes->setDontClose_Impl();
    xLockBytes->setStream_Impl( xStream );
    xLockBytes->terminate_Impl();
    return xLockBytes;
}

UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const ::rtl::OUString& rReferer, const ::rtl::OUString& rMediaType,
        const Reference < XInputStream >& xPostData, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler )
{
	if( !xContent.is() )
		return NULL;;

    UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler );
    xLockBytes->SetSynchronMode( !pHandler );
    Reference< XActiveDataControl > xSink = (XActiveDataControl*) new UcbDataSink_Impl( xLockBytes );

    PostCommandArgument2 aArgument;
	aArgument.Source = xPostData;
    aArgument.Sink = xSink;
    aArgument.MediaType = rMediaType;
    aArgument.Referer = rReferer;

    Command aCommand;
    aCommand.Name = ::rtl::OUString::createFromAscii ("post");
    aCommand.Argument <<= aArgument;

    Reference< XProgressHandler > xProgressHdl = new ProgressHandler_Impl( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) );

	sal_Bool bError = UCBOpenContentSync( xLockBytes,
										  xContent,
										  aCommand,
										  xSink,
										  xInteractionHandler,
										  xProgressHdl,
										  pHandler );

   	if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) )
	{
		DBG_ERROR("No InputStream, but no error set!" );
       	xLockBytes->SetError( ERRCODE_IO_GENERAL );
	}

    return xLockBytes;
}

UcbLockBytesRef UcbLockBytes::CreateLockBytes( const Reference < XContent >& xContent, const Sequence < PropertyValue >& rProps,
        StreamMode eOpenMode, const Reference < XInteractionHandler >& xInteractionHandler, UcbLockBytesHandler* pHandler )
{
	if( !xContent.is() )
		return NULL;;

    UcbLockBytesRef xLockBytes = new UcbLockBytes( pHandler );
    xLockBytes->SetSynchronMode( !pHandler );
    Reference< XActiveDataControl > xSink;
    if ( eOpenMode & STREAM_WRITE )
        xSink = (XActiveDataControl*) new UcbStreamer_Impl( xLockBytes );
    else
        xSink = (XActiveDataControl*) new UcbDataSink_Impl( xLockBytes );

    if ( rProps.getLength() )
    {
        Reference < XCommandProcessor > xProcessor( xContent, UNO_QUERY );
        Command aCommand;
        aCommand.Name     = ::rtl::OUString::createFromAscii("setPropertyValues");
        aCommand.Handle   = -1; /* unknown */
        aCommand.Argument <<= rProps;
        xProcessor->execute( aCommand, 0, Reference < XCommandEnvironment >() );
    }

	OpenCommandArgument2 aArgument;
    aArgument.Sink = xSink;
	aArgument.Mode = OpenMode::DOCUMENT;

    Command aCommand;
	aCommand.Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("open") );
	aCommand.Argument <<= aArgument;

    Reference< XProgressHandler > xProgressHdl = new ProgressHandler_Impl( LINK( &xLockBytes, UcbLockBytes, DataAvailHdl ) );

    sal_Bool bError = UCBOpenContentSync( xLockBytes,
										  xContent,
										  aCommand,
										  xSink,
										  xInteractionHandler,
										  xProgressHdl,
										  pHandler );

    if ( xLockBytes->GetError() == ERRCODE_NONE && ( bError || !xLockBytes->getInputStream().is() ) )
	{
		DBG_ERROR("No InputStream, but no error set!" );
       	xLockBytes->SetError( ERRCODE_IO_GENERAL );
	}

    return xLockBytes;
}

}
