diff --git a/eventloopinteractor.cpp b/eventloopinteractor.cpp
index 923f7dc8..f34dcff4 100644
--- a/eventloopinteractor.cpp
+++ b/eventloopinteractor.cpp
@@ -1,187 +1,188 @@
 /*
   eventloopinteractor.cpp
   Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB
 
   This file is part of GPGME++.
 
   GPGME++ is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
 
   GPGME++ is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Library General Public License for more details.
 
   You should have received a copy of the GNU Library General Public License
   along with GPGME++; see the file COPYING.LIB.  If not, write to the
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
 */
 
 #include <gpgme++/config-gpgme++.h>
 
 #include <gpgme++/eventloopinteractor.h>
 
 #include <gpgme++/context.h>
 #include "context_p.h"
 #include <gpgme++/key.h>
 #include <gpgme++/trustitem.h>
 
 #include <gpgme.h>
 
 #include <vector>
 using std::vector;
 #ifndef NDEBUG
 # include <iostream>
 #endif
 #include <cassert>
 
 namespace GpgME {
 
   //
   // EventLoopInteractor::Private Declaration
   //
 
   class EventLoopInteractor::Private {
   public:
     struct OneFD {
       OneFD( int aFd, int aDir, gpgme_io_cb_t aFnc,
 	     void * aFncData, void * aExternalTag )
 	: fd( aFd ), dir( aDir ), fnc( aFnc ),
 	  fncData( aFncData ), externalTag( aExternalTag ) {}
       int fd;
       int dir;
       gpgme_io_cb_t fnc;
       void * fncData;
       void * externalTag;
     };
 
     vector<OneFD*> mCallbacks;
 
     static void removeIOCb( void * tag );
     static gpgme_error_t registerIOCb( void * data, int fd, int dir,
 				    gpgme_io_cb_t fnc, void * fnc_data,
 				    void ** r_tag );
     static void eventIOCb( void *, gpgme_event_io_t type, void * type_data );
 
     static gpgme_io_cbs iocbs;
   };
 
   gpgme_io_cbs EventLoopInteractor::Private::iocbs = {
     &EventLoopInteractor::Private::registerIOCb,
     0,
     &EventLoopInteractor::Private::removeIOCb,
     &EventLoopInteractor::Private::eventIOCb,
     0
   };
 
 
   //
   // EventLoopInteractor::Private IO Callback Implementations
   //
 
   gpgme_error_t EventLoopInteractor::Private::registerIOCb( void *, int fd, int dir,
 							 gpgme_io_cb_t fnc, void * fnc_data,
 							 void ** r_tag )
   {
     assert( instance() ); assert( instance()->d );
     bool ok = false;
     void * etag = instance()->registerWatcher( fd, dir ? Read : Write, ok );
     if ( !ok ) return GPG_ERR_GENERAL;
     instance()->d->mCallbacks.push_back( new OneFD( fd, dir, fnc, fnc_data, etag ) );
     if ( r_tag )
       *r_tag = instance()->d->mCallbacks.back();
     return GPG_ERR_NO_ERROR;
   }
 
   void EventLoopInteractor::Private::removeIOCb( void * tag ) {
     assert( instance() ); assert( instance()->d );
 
     for ( vector<OneFD*>::iterator it = instance()->d->mCallbacks.begin() ;
 	 it != instance()->d->mCallbacks.end() ; ++it ) {
       if ( *it == tag ) {
 	instance()->unregisterWatcher( (*it)->externalTag );
 	delete *it; *it = 0;
 	instance()->d->mCallbacks.erase( it );
 	return;
       }
     }
   }
 
   void EventLoopInteractor::Private::eventIOCb( void * data, gpgme_event_io_t type, void * type_data ) {
     assert( instance() );
     Context * ctx = static_cast<Context*>( data );
     switch( type ) {
     case GPGME_EVENT_START:
       {
-	// hmmm, what to do here?
+        instance()->operationStartEvent( ctx );
+	// TODO: what's in type_data?
       }
       break;
     case GPGME_EVENT_DONE:
       {
 	gpgme_error_t e = *static_cast<gpgme_error_t*>( type_data );
 	if ( ctx && ctx->impl() )
 	  ctx->impl()->lasterr = e;
 	instance()->operationDoneEvent( ctx, Error( e ) );
       }
       break;
     case GPGME_EVENT_NEXT_KEY:
       {
 	gpgme_key_t key = static_cast<gpgme_key_t>( type_data );
 	instance()->nextKeyEvent( ctx, Key( key, false ) );
       }
       break;
     case GPGME_EVENT_NEXT_TRUSTITEM:
       {
 	gpgme_trust_item_t item = static_cast<gpgme_trust_item_t>( type_data );
 	instance()->nextTrustItemEvent( ctx, TrustItem( item ) );
 	gpgme_trust_item_unref( item );
       }
       break;
     default: // warn
       ;
     }
   }
 
   //
   // EventLoopInteractor Implementation
   //
 
   EventLoopInteractor * EventLoopInteractor::mSelf = 0;
 
   EventLoopInteractor::EventLoopInteractor() {
     assert( !mSelf );
     d = new Private();
     mSelf = this;
   }
 
   EventLoopInteractor::~EventLoopInteractor() {
     // warn if there are still callbacks registered
     mSelf = 0;
     delete d; d = 0;
   }
 
   void EventLoopInteractor::manage( Context * context ) {
     if ( !context || context->managedByEventLoopInteractor() ) return;
     gpgme_io_cbs * iocbs = new gpgme_io_cbs( Private::iocbs );
     iocbs->event_priv = context;
     context->installIOCallbacks( iocbs );
   }
 
   void EventLoopInteractor::unmanage( Context * context ) {
     if ( context )
       context->uninstallIOCallbacks();
   }
 
   void EventLoopInteractor::actOn( int fd, Direction dir ) {
     for ( vector<Private::OneFD*>::const_iterator it = d->mCallbacks.begin() ;
 	  it != d->mCallbacks.end() ; ++it )
       if ( (*it)->fd == fd && ( (*it)->dir ? Read : Write ) == dir ) {
 	(*((*it)->fnc))( (*it)->fncData, fd );
 	break;
       }
   }
 
 } // namespace GpgME
diff --git a/eventloopinteractor.h b/eventloopinteractor.h
index 4b72b4df..0476638a 100644
--- a/eventloopinteractor.h
+++ b/eventloopinteractor.h
@@ -1,151 +1,152 @@
 /*
   eventloopinteractor.h
   Copyright (C) 2003,2004 Klarälvdalens Datakonsult AB
 
   This file is part of GPGME++.
 
   GPGME++ is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.
 
   GPGME++ is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU Library General Public License for more details.
 
   You should have received a copy of the GNU Library General Public License
   along with GPGME++; see the file COPYING.LIB.  If not, write to the
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.
 */
 
 // -*- c++ -*-
 #ifndef __GPGMEPP_EVENTLOOPINTERACTOR_H__
 #define __GPGMEPP_EVENTLOOPINTERACTOR_H__
 
 #include <gpgme++/gpgme++_export.h>
 
 namespace GpgME {
 
   class Context;
   class Error;
   class TrustItem;
   class Key;
 
   /*! \file eventloopinteractor.h
       \brief Abstract base class for gpgme's external event loop support
 
       This class does most of the work involved with hooking GpgME++
       up with external event loops, such as the GTK or Qt ones.
 
       It actually provides two interfaces: An interface to the gpgme
       IO Callback handling and one for gpgme events. The IO Callback
       interface consists of the three methods \c actOn(), \c
       registerWatcher() and \c unregisterWatcher(). The event
       interface consists of the three methods \c nextTrustItemEvent(),
       \c nextKeyEvent() and \c operationDoneEvent().
 
       \sect General Usage
 
       \c EventLoopInteractor is designed to be used as a
       singleton. However, in order to make any use of it, you have to
       subclass it and reimplement it's pure virtual methods (see
       below). We suggest you keep the constructor protected and
       provide a static \c instance() method that returns the single
       instance. Alternatively, you can create an instance on the
       stack, e.g. in \c main().
 
       If you want \c EventLoopInteractor to manage a particular \c
       Context, just call \c manage() on the \c Context. OTOH, if you
       want to disable IO callbacks for a \c Context, use \c unmanage().
 
       \sect IO Callback Interface
 
       One part of this interface is represented by \c
       registerWatcher() and \c unregisterWatcher(), both of which are
       pure virtual. \c registerWatcher() should do anything necessary
       to hook up watching of file descriptor \c fd for reading (\c dir
       = \c Read) or writing (\c dir = Write) to the event loop you use
       and return a tag identifying that particular watching process
       uniquely. This could be the index into an array of objects you
       use for that purpose or the address of such an object. E.g. in
       Qt, you'd essentially just create a new \c QSocketNotifier:
 
       \verbatim
       void * registerWatcher( int fd, Direction dir ) {
         return new QSocketNotifier( fd, dir == Read ? QSocketNotifier::Read : QSocketNotifier::Write );
 	// misses connecting to the activated() signal...
       }
       \endverbatim
 
       which uses the address of the created object as unique tag. The
       tag returned by \c registerWatcher is stored by \c
       EventLoopInteractor and passed as argument to \c
       unregisterWatcher(). So, in the picture above, you'd implement \c
       unregisterWatcher() like this:
 
       \verbatim
       void unregisterWatcher( void * tag ) {
         delete static_cast<QSocketNotifier*>( tag );
       }
       \endverbatim
 
       The other part of the IO callback interface is \c actOn(), which
       you should call if you receive notification from your event loop
       about activity on file descriptor \c fd in direction \c dir. In
       the picture above, you'd call this from the slot connected to
       the socket notifier's \c activated() signal.
 
       \note \c registerWatcher() as well as \c unregisterWatcher() may
       be called from within \c actOn(), so be careful with
       e.g. locking in threaded environments and keep in mind that the
       object you used to find the \c fd and \c dir fo the \c actOn()
       call might be deleted when \c actOn() returns!
 
       \sect Event Handler Interface
 
 
   */
   class GPGMEPP_EXPORT EventLoopInteractor {
   protected:
     EventLoopInteractor();
   public:
     virtual ~EventLoopInteractor();
 
     static EventLoopInteractor * instance() { return mSelf; }
 
     void manage( Context * context );
     void unmanage( Context * context );
 
     enum Direction { Read, Write };
   protected:
     //
     // IO Notification Interface
     //
 
     /** Call this if your event loop detected activity on file
 	descriptor fd, with direction dir */
     void actOn( int fd, Direction dir );
 
     virtual void * registerWatcher( int fd, Direction dir, bool & ok ) = 0;
     virtual void unregisterWatcher( void * tag ) = 0;
 
     //
     // Event Handler Interface
     //
 
+    virtual void operationStartEvent( Context * context ) = 0;
     virtual void nextTrustItemEvent( Context * context, const TrustItem & item ) = 0;
     virtual void nextKeyEvent( Context * context, const Key & key ) = 0;
     virtual void operationDoneEvent( Context * context, const Error & e ) = 0;
 
   private:
     class Private;
     friend class Private;
     Private * d;
     static EventLoopInteractor * mSelf;
   };
 
 }
 
 #endif // __GPGMEPP_EVENTLOOPINTERACTOR_H__