/**************************************************************
 *
 * 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 whether 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;
}

}
