gunnar: server/kolab-webclient/patches/1.2.0/KOLAB series, NONE, 1.1 t_COPYRIGHT.diff, NONE, 1.1 t_COPYRIGHT2.diff, NONE, 1.1 t_COPYRIGHT3.diff, NONE, 1.1 t_GLOBAL_HK_GW_Config.diff, NONE, 1.1 t_GLOBAL_HK_GW_ConfigOpenPKG.diff, NONE, 1.1 t_Kolab__Format_HK_GW_HandleEmptyXmlParserReturn.diff, NONE, 1.1 t_Kolab__Server_HK_GW_DenyLogin.diff, NONE, 1.1 t_Kolab__Server_HK_GW_FixAddrForIdOrMail.diff, NONE, 1.1 t_Kolab__Server_HK_GW_FixBodyHeaderBreakInTestDriver.diff, NONE, 1.1 t_Kolab__Server_HK_GW_FixLowerCaseObjectClasses.diff, NONE, 1.1 t_Kolab__Server_HK_GW_FixNotics.diff, NONE, 1.1 t_Kolab__Server_HK_GW_UserMailAndFullname.diff, NONE, 1.1 t_Kolab__Storage_HK_GW_MultipleListCaches.diff, NONE, 1.1 t_Kolab__Storage_HK_GW_SuppressTriggering.diff, NONE, 1.1 t_Prefs_HK_GW_FixLDAPAuthForIngo.diff, NONE, 1.1 t_SyncML_HK_GW_CombinedFixes.diff, NONE, 1.1 t_Text_Filter_SC_CH_Xss.diff, NONE, 1.1 t_dimp_HK_GW_ItipHandling.diff, NONE, 1.1 t_dimp_H_MS_FixBrokenFolderImages.diff, NONE, 1.1 t_framework_HK_GW_Auth_InvalidCh eck.diff, NONE, 1.1 t_framework_HK_GW_Auth_ListUsers.diff, NONE, 1.1 t_framework_HK_GW_Auth_SafetyCheck.diff, NONE, 1.1 t_framework_HK_GW_Auth_UseKolabServer.diff, NONE, 1.1 t_framework_HK_GW_Auth_UseSession.diff, NONE, 1.1 t_framework_HK_GW_DB_SqliteErrorChecking.diff, NONE, 1.1 t_framework_HK_GW_Kolab_AttachmentSupport.diff, NONE, 1.1 t_framework_HK_GW_Kolab_MoveIMAP.diff, NONE, 1.1 t_framework_HK_GW_Kolab_XfbFixes.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Fbview_XfbConcept.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Format_ImprovedPreferencesHandling.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Server_AdditionalGetFeeBusyServerFixes.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Server_FixAddressObjectIdentification.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Server_FixGetGroups.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Server_ImprovedFreebusyServerFallback.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Server_ImprovedServerFallbacks.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Server_ListObjects.diff, NONE, 1.1 t_framework_HK_GW_Ko lab__Server_RequireIMAP.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Server_RewriteExtend.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Server_SafetyCheck.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Server_Session.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Server_getFreebusyServer.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Storage_CatchPossibleError.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Storage_FixTriggerOnFolderCreation.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Storage_FixTriggerOnFolderRename.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Storage_Foreign__owner.patch.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Storage_Restructuring__Fixes.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Storage_ShareIdFix.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Storage_Trigger.diff, NONE, 1.1 t_framework_HK_GW_Kolab__Storgae_FixedUpdateTriggering.diff, NONE, 1.1 t_framework_HK_GW_Prefs__KolabImapApplicationTag.diff, NONE, 1.1 t_framework_HK_GW_Vfs_KolabDriver.diff, NONE, 1.1 t_framework_HK_GW_framework_Kolab_DeprecatedGetServer.diff, NONE, 1.1 t_fram ework_HK_GW_framework_Kolab_MoveSessionHandler.diff, NONE, 1.1 t_framework_HK_GW_framework_Kolab__Format_WS.diff, NONE, 1.1 t_framework_HK_GW_horde_conf__xmlUpdates.diff, NONE, 1.1 t_framework_HK_GW_iCalendar_QuotedParameters.diff, NONE, 1.1 t_horde_SC_CH_SecIssues20090128.diff, NONE, 1.1 t_imp_HK_GW_AuthForInvitations.diff, NONE, 1.1 t_imp_H_GW_DefaultLoginView.diff, NONE, 1.1 t_imp_H_GW_LoginRetries.diff, NONE, 1.1 t_imp_H_JS_bug7739.diff, NONE, 1.1 t_imp_H_MS_bug7438.diff, NONE, 1.1 t_imp_HideGroupwareFolders.diff, NONE, 1.1 t_imp_SC_CH_SecIssues20090128.diff, NONE, 1.1 t_kronolith_HK_GW_AuthenticatedFreeBusy.diff, NONE, 1.1 t_kronolith_HK_GW_CalendarRenaming.diff, NONE, 1.1 t_kronolith_HK_GW_FbviewRelevance.diff, NONE, 1.1 t_kronolith_HK_GW_SyncMLrefresh.diff, NONE, 1.1 t_kronolith_HK_GW_XfbAccess.diff, NONE, 1.1 t_kronolith_HK_GW_getFreebusyServer.diff, NONE, 1.1 t_kronolith_HK_SB_ExtraParameters.diff, NONE, 1.1 t_kronolith_HK_SB_SaveEventAttendees.diff, NONE, 1.1 t_nag_H_MR_Bug__7400.diff, NONE, 1.1 t_pear_HK_ GW_AddNetIMAP.diff, NONE, 1.1 t_turba_HK_GW_AutomaticFreeBusyUrl.diff, NONE, 1.1 t_turba_HK_GW_FixAddressbookDeletion.diff, NONE, 1.1 t_turba_HK_GW_FixSyncMLAttributeDeletion.diff, NONE, 1.1 t_turba_HK_GW_PhotoSupport.diff, NONE, 1.1 t_turba_HK_GW_SyncMLrefresh.diff, NONE, 1.1

cvs at kolab.org cvs at kolab.org
Sat Apr 25 23:04:33 CEST 2009


Author: gunnar

Update of /kolabrepository/server/kolab-webclient/patches/1.2.0/KOLAB
In directory doto:/tmp/cvs-serv28792

Added Files:
	series t_COPYRIGHT.diff t_COPYRIGHT2.diff t_COPYRIGHT3.diff 
	t_GLOBAL_HK_GW_Config.diff t_GLOBAL_HK_GW_ConfigOpenPKG.diff 
	t_Kolab__Format_HK_GW_HandleEmptyXmlParserReturn.diff 
	t_Kolab__Server_HK_GW_DenyLogin.diff 
	t_Kolab__Server_HK_GW_FixAddrForIdOrMail.diff 
	t_Kolab__Server_HK_GW_FixBodyHeaderBreakInTestDriver.diff 
	t_Kolab__Server_HK_GW_FixLowerCaseObjectClasses.diff 
	t_Kolab__Server_HK_GW_FixNotics.diff 
	t_Kolab__Server_HK_GW_UserMailAndFullname.diff 
	t_Kolab__Storage_HK_GW_MultipleListCaches.diff 
	t_Kolab__Storage_HK_GW_SuppressTriggering.diff 
	t_Prefs_HK_GW_FixLDAPAuthForIngo.diff 
	t_SyncML_HK_GW_CombinedFixes.diff t_Text_Filter_SC_CH_Xss.diff 
	t_dimp_HK_GW_ItipHandling.diff 
	t_dimp_H_MS_FixBrokenFolderImages.diff 
	t_framework_HK_GW_Auth_InvalidCheck.diff 
	t_framework_HK_GW_Auth_ListUsers.diff 
	t_framework_HK_GW_Auth_SafetyCheck.diff 
	t_framework_HK_GW_Auth_UseKolabServer.diff 
	t_framework_HK_GW_Auth_UseSession.diff 
	t_framework_HK_GW_DB_SqliteErrorChecking.diff 
	t_framework_HK_GW_Kolab_AttachmentSupport.diff 
	t_framework_HK_GW_Kolab_MoveIMAP.diff 
	t_framework_HK_GW_Kolab_XfbFixes.diff 
	t_framework_HK_GW_Kolab__Fbview_XfbConcept.diff 
	t_framework_HK_GW_Kolab__Format_ImprovedPreferencesHandling.diff 
	t_framework_HK_GW_Kolab__Server_AdditionalGetFeeBusyServerFixes.diff 
	t_framework_HK_GW_Kolab__Server_FixAddressObjectIdentification.diff 
	t_framework_HK_GW_Kolab__Server_FixGetGroups.diff 
	t_framework_HK_GW_Kolab__Server_ImprovedFreebusyServerFallback.diff 
	t_framework_HK_GW_Kolab__Server_ImprovedServerFallbacks.diff 
	t_framework_HK_GW_Kolab__Server_ListObjects.diff 
	t_framework_HK_GW_Kolab__Server_RequireIMAP.diff 
	t_framework_HK_GW_Kolab__Server_RewriteExtend.diff 
	t_framework_HK_GW_Kolab__Server_SafetyCheck.diff 
	t_framework_HK_GW_Kolab__Server_Session.diff 
	t_framework_HK_GW_Kolab__Server_getFreebusyServer.diff 
	t_framework_HK_GW_Kolab__Storage_CatchPossibleError.diff 
	t_framework_HK_GW_Kolab__Storage_FixTriggerOnFolderCreation.diff 
	t_framework_HK_GW_Kolab__Storage_FixTriggerOnFolderRename.diff 
	t_framework_HK_GW_Kolab__Storage_Foreign__owner.patch.diff 
	t_framework_HK_GW_Kolab__Storage_Restructuring__Fixes.diff 
	t_framework_HK_GW_Kolab__Storage_ShareIdFix.diff 
	t_framework_HK_GW_Kolab__Storage_Trigger.diff 
	t_framework_HK_GW_Kolab__Storgae_FixedUpdateTriggering.diff 
	t_framework_HK_GW_Prefs__KolabImapApplicationTag.diff 
	t_framework_HK_GW_Vfs_KolabDriver.diff 
	t_framework_HK_GW_framework_Kolab_DeprecatedGetServer.diff 
	t_framework_HK_GW_framework_Kolab_MoveSessionHandler.diff 
	t_framework_HK_GW_framework_Kolab__Format_WS.diff 
	t_framework_HK_GW_horde_conf__xmlUpdates.diff 
	t_framework_HK_GW_iCalendar_QuotedParameters.diff 
	t_horde_SC_CH_SecIssues20090128.diff 
	t_imp_HK_GW_AuthForInvitations.diff 
	t_imp_H_GW_DefaultLoginView.diff t_imp_H_GW_LoginRetries.diff 
	t_imp_H_JS_bug7739.diff t_imp_H_MS_bug7438.diff 
	t_imp_HideGroupwareFolders.diff 
	t_imp_SC_CH_SecIssues20090128.diff 
	t_kronolith_HK_GW_AuthenticatedFreeBusy.diff 
	t_kronolith_HK_GW_CalendarRenaming.diff 
	t_kronolith_HK_GW_FbviewRelevance.diff 
	t_kronolith_HK_GW_SyncMLrefresh.diff 
	t_kronolith_HK_GW_XfbAccess.diff 
	t_kronolith_HK_GW_getFreebusyServer.diff 
	t_kronolith_HK_SB_ExtraParameters.diff 
	t_kronolith_HK_SB_SaveEventAttendees.diff 
	t_nag_H_MR_Bug__7400.diff t_pear_HK_GW_AddNetIMAP.diff 
	t_turba_HK_GW_AutomaticFreeBusyUrl.diff 
	t_turba_HK_GW_FixAddressbookDeletion.diff 
	t_turba_HK_GW_FixSyncMLAttributeDeletion.diff 
	t_turba_HK_GW_PhotoSupport.diff 
	t_turba_HK_GW_SyncMLrefresh.diff 
Log Message:
Moved the patches from patches/horde-webmail/1.2.0/tg into kolab-webclient/patches/1.2.0/KOLAB. This is an exact copy of the tg dir besides the series file. Here the unnecessary -p1 bits were removed from each line.

--- NEW FILE: series ---
t_SyncML_HK_GW_CombinedFixes.diff
t_Prefs_HK_GW_FixLDAPAuthForIngo.diff
t_Text_Filter_SC_CH_Xss.diff
t_framework_HK_GW_framework_Kolab__Format_WS.diff
t_framework_HK_GW_Kolab__Format_ImprovedPreferencesHandling.diff
t_framework_HK_GW_Prefs__KolabImapApplicationTag.diff
t_framework_HK_GW_horde_conf__xmlUpdates.diff
t_kronolith_HK_GW_AuthenticatedFreeBusy.diff
t_nag_H_MR_Bug__7400.diff
t_GLOBAL_HK_GW_Config.diff
t_GLOBAL_HK_GW_ConfigOpenPKG.diff
t_kronolith_HK_GW_SyncMLrefresh.diff
t_turba_HK_GW_FixAddressbookDeletion.diff
t_turba_HK_GW_FixSyncMLAttributeDeletion.diff
t_turba_HK_GW_SyncMLrefresh.diff
t_imp_HideGroupwareFolders.diff
t_imp_SC_CH_SecIssues20090128.diff
t_horde_SC_CH_SecIssues20090128.diff
t_dimp_H_MS_FixBrokenFolderImages.diff
t_dimp_HK_GW_ItipHandling.diff
t_framework_HK_GW_Kolab__Server_Session.diff
t_framework_HK_GW_Auth_UseSession.diff
t_framework_HK_GW_Kolab__Server_getFreebusyServer.diff
t_kronolith_HK_GW_getFreebusyServer.diff
t_framework_HK_GW_Kolab__Storage_Foreign__owner.patch.diff
t_framework_HK_GW_Kolab__Storage_Trigger.diff
t_framework_HK_GW_framework_Kolab_MoveSessionHandler.diff
t_framework_HK_GW_framework_Kolab_DeprecatedGetServer.diff
t_framework_HK_GW_Kolab__Storage_Restructuring__Fixes.diff
t_framework_HK_GW_Kolab__Server_ListObjects.diff
t_framework_HK_GW_Auth_ListUsers.diff
t_framework_HK_GW_Kolab__Server_RewriteExtend.diff
t_framework_HK_GW_Kolab__Storage_CatchPossibleError.diff
t_framework_HK_GW_Auth_UseKolabServer.diff
t_framework_HK_GW_Kolab__Server_SafetyCheck.diff
t_framework_HK_GW_Kolab_MoveIMAP.diff
t_framework_HK_GW_Auth_SafetyCheck.diff
t_framework_HK_GW_Kolab__Server_RequireIMAP.diff
t_framework_HK_GW_Auth_InvalidCheck.diff
t_framework_HK_GW_Kolab_AttachmentSupport.diff
t_framework_HK_GW_Vfs_KolabDriver.diff
t_turba_HK_GW_PhotoSupport.diff
t_framework_HK_GW_Kolab__Server_ImprovedFreebusyServerFallback.diff
t_framework_HK_GW_Kolab__Server_ImprovedServerFallbacks.diff
t_framework_HK_GW_Kolab__Storgae_FixedUpdateTriggering.diff
t_turba_HK_GW_AutomaticFreeBusyUrl.diff
t_framework_HK_GW_Kolab__Server_FixGetGroups.diff
t_kronolith_HK_GW_CalendarRenaming.diff
t_framework_HK_GW_Kolab__Storage_FixTriggerOnFolderRename.diff
t_framework_HK_GW_Kolab__Storage_FixTriggerOnFolderCreation.diff
t_framework_HK_GW_Kolab__Server_AdditionalGetFeeBusyServerFixes.diff
t_framework_HK_GW_Kolab__Server_FixAddressObjectIdentification.diff
t_framework_HK_GW_Kolab__Fbview_XfbConcept.diff
t_framework_HK_GW_Kolab_XfbFixes.diff
t_framework_HK_GW_DB_SqliteErrorChecking.diff
t_framework_HK_GW_Kolab__Storage_ShareIdFix.diff
t_framework_HK_GW_iCalendar_QuotedParameters.diff
t_Kolab__Server_HK_GW_DenyLogin.diff
t_Kolab__Server_HK_GW_UserMailAndFullname.diff
t_imp_HK_GW_AuthForInvitations.diff
t_Kolab__Storage_HK_GW_MultipleListCaches.diff
t_Kolab__Server_HK_GW_FixAddrForIdOrMail.diff
t_COPYRIGHT.diff
t_Kolab__Server_HK_GW_FixLowerCaseObjectClasses.diff
t_Kolab__Server_HK_GW_FixNotics.diff
t_COPYRIGHT2.diff
t_Kolab__Storage_HK_GW_SuppressTriggering.diff
t_COPYRIGHT3.diff
t_imp_H_MS_bug7438.diff
t_imp_H_JS_bug7739.diff
t_imp_H_GW_DefaultLoginView.diff
t_imp_H_GW_LoginRetries.diff
t_Kolab__Server_HK_GW_FixBodyHeaderBreakInTestDriver.diff
t_pear_HK_GW_AddNetIMAP.diff
t_kronolith_HK_SB_SaveEventAttendees.diff
t_kronolith_HK_SB_ExtraParameters.diff
t_kronolith_HK_GW_FbviewRelevance.diff
t_kronolith_HK_GW_XfbAccess.diff

--- NEW FILE: t_COPYRIGHT.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/COPYRIGHT

Fixes the copyright information.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Format.php           |    6 +++---
 horde-webmail/lib/Horde/Kolab/Format/Date.php      |    7 ++++---
 horde-webmail/lib/Horde/Kolab/Format/XML.php       |    6 +++---
 .../lib/Horde/Kolab/Format/XML/annotation.php      |    6 +++---
 .../lib/Horde/Kolab/Format/XML/contact.php         |    6 +++---
 .../Horde/Kolab/Format/XML/distributionlist.php    |    6 +++---
 horde-webmail/lib/Horde/Kolab/Format/XML/event.php |    6 +++---
 .../lib/Horde/Kolab/Format/XML/hprefs.php          |    6 +++---
 horde-webmail/lib/Horde/Kolab/Format/XML/note.php  |    6 +++---
 horde-webmail/lib/Horde/Kolab/Format/XML/task.php  |    6 +++---
 10 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Format.php b/horde-webmail/lib/Horde/Kolab/Format.php
index 372fa4f..cae1966 100644
--- a/horde-webmail/lib/Horde/Kolab/Format.php
+++ b/horde-webmail/lib/Horde/Kolab/Format.php
@@ -14,12 +14,12 @@ require_once 'PEAR.php';
  * The Horde_Kolab_Format:: class provides the means to read/write the
  * Kolab format.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format.php,v 1.4.2.3 2008/08/01 07:13:20 wrobel Exp $
+ * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format.php,v 1.4.2.4 2008/12/12 11:39:03 wrobel Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2008 Klarälvdalens Datakonsult AB
  *
  * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
  * @since   Horde 3.2
  * @author  Gunnar Wrobel <wrobel at pardus.de>
diff --git a/horde-webmail/lib/Horde/Kolab/Format/Date.php b/horde-webmail/lib/Horde/Kolab/Format/Date.php
index da1e9c2..58244b2 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/Date.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/Date.php
@@ -10,13 +10,14 @@
 /**
  * Kolab date handling functions. Based upon Kolab.php from Stuart Binge.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/Date.php,v 1.2.2.3 2008/08/01 07:13:20 wrobel Exp $
+ * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/Date.php,v 1.2.2.5 2009/01/06 15:23:13 jan Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
+ * @author  Stuart Binge <omicron at mighty.co.za>
  * @author  Thomas Jarosch <thomas.jarosch at intra2net.com>
  * @package Kolab_Format
  */
diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML.php b/horde-webmail/lib/Horde/Kolab/Format/XML.php
index fefa362..2472c83 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML.php
@@ -95,12 +95,12 @@ define('HORDE_KOLAB_XML_TYPE_MULTIPLE', 8);
  * For implementing a new format type you will have to inherit this
  * class and provide a _load/_save function.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML.php,v 1.5.2.6 2008/09/16 16:22:54 wrobel Exp $
+ * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML.php,v 1.5.2.10 2008/12/12 11:39:04 wrobel Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2008 Klarälvdalens Datakonsult AB
  *
  * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
  * @since   Horde 3.2
  * @author  Thomas Jarosch <thomas.jarosch at intra2net.com>
diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML/annotation.php b/horde-webmail/lib/Horde/Kolab/Format/XML/annotation.php
index cff091f..d3a8981 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML/annotation.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML/annotation.php
@@ -10,12 +10,12 @@
 /**
  * Kolab XML handler for IMAP folder annotations.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/annotation.php,v 1.1.2.3 2008/08/13 10:54:19 wrobel Exp $
+ * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/annotation.php,v 1.1.2.5 2009/01/06 15:23:14 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
  * @since   Horde 3.2
  * @author  Gunnar Wrobel <wrobel at pardus.de>
diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML/contact.php b/horde-webmail/lib/Horde/Kolab/Format/XML/contact.php
index 66fa525..ffdfbc7 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML/contact.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML/contact.php
@@ -10,12 +10,12 @@
 /**
  * Kolab XML handler for contact groupware objects
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/contact.php,v 1.2.2.5 2008/08/21 04:31:49 wrobel Exp $
+ * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/contact.php,v 1.2.2.6 2008/12/12 11:39:04 wrobel Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2008 Klarälvdalens Datakonsult AB
  *
  * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
  * @since   Horde 3.2
  * @author  Thomas Jarosch <thomas.jarosch at intra2net.com>
diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML/distributionlist.php b/horde-webmail/lib/Horde/Kolab/Format/XML/distributionlist.php
index 4c789f6..d628be7 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML/distributionlist.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML/distributionlist.php
@@ -10,12 +10,12 @@
 /**
  * Kolab XML handler for distributionlist groupware objects
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/distributionlist.php,v 1.2.2.4 2008/08/13 10:54:19 wrobel Exp $
+ * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/distributionlist.php,v 1.2.2.5 2008/12/12 11:39:04 wrobel Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2008 Klarälvdalens Datakonsult AB
  *
  * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
  * @since   Horde 3.2
  * @author  Thomas Jarosch <thomas.jarosch at intra2net.com>
diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML/event.php b/horde-webmail/lib/Horde/Kolab/Format/XML/event.php
index 38d8850..9f71239 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML/event.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML/event.php
@@ -13,12 +13,12 @@ require_once 'Horde/Kolab/Format/Date.php';
 /**
  * Kolab XML handler for event groupware objects.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/event.php,v 1.2.2.2 2008/08/01 07:13:21 wrobel Exp $
+ * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/event.php,v 1.2.2.3 2008/12/12 11:39:04 wrobel Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2008 Klarälvdalens Datakonsult AB
  *
  * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
  * @since   Horde 3.2
  * @author  Thomas Jarosch <thomas.jarosch at intra2net.com>
diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML/hprefs.php b/horde-webmail/lib/Horde/Kolab/Format/XML/hprefs.php
index 22a94bc..f45b26c 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML/hprefs.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML/hprefs.php
@@ -10,12 +10,12 @@
 /**
  * Kolab XML handler for client preferences.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/hprefs.php,v 1.2.2.3 2008/08/20 20:25:28 wrobel Exp $
+ * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/hprefs.php,v 1.2.2.7 2009/01/06 15:23:14 jan Exp $
  *
- * Copyright 2007 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
  * @since   Horde 3.2
  * @author  Gunnar Wrobel <wrobel at pardus.de>
diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML/note.php b/horde-webmail/lib/Horde/Kolab/Format/XML/note.php
index 84c6326..37b1d73 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML/note.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML/note.php
@@ -10,12 +10,12 @@
 /**
  * Kolab XML handler for note groupware objects.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/note.php,v 1.2.2.4 2008/08/13 10:54:19 wrobel Exp $
+ * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/note.php,v 1.2.2.5 2008/12/12 11:39:04 wrobel Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2008 Klarälvdalens Datakonsult AB
  *
  * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
  * @since   Horde 3.2
  * @author  Thomas Jarosch <thomas.jarosch at intra2net.com>
diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML/task.php b/horde-webmail/lib/Horde/Kolab/Format/XML/task.php
index d700b89..5c71267 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML/task.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML/task.php
@@ -10,12 +10,12 @@
 /**
  * Kolab XML handler for task groupware objects.
  *
- * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/task.php,v 1.2.2.5 2008/08/13 10:54:19 wrobel Exp $
+ * $Horde: framework/Kolab_Format/lib/Horde/Kolab/Format/XML/task.php,v 1.2.2.6 2008/12/12 11:39:04 wrobel Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2008 Klarälvdalens Datakonsult AB
  *
  * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ * did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
  *
  * @since   Horde 3.2
  * @author  Thomas Jarosch <thomas.jarosch at intra2net.com>
-- 
tg: (6e63b1b..) t/COPYRIGHT (depends on: t/Kolab_Server/HK/GW/FixAddrForIdOrMail)
-- 
TOPGIT patch commit log
=======================

commit a3542e35d21c42304c3809074411981bfc88d8b3
Author: Gunnar Wrobel <p at rdus.de>
Date:   Tue Feb 24 06:12:30 2009 +0000

    Synced the Kolab_Format package with horde-fw3.

--- NEW FILE: t_COPYRIGHT2.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/COPYRIGHT2

Syncs the Kolab_Server module in the kolab-webclient with horde-fw3.

STATUS: MERGED

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/IMAP.php             |    4 +-
 horde-webmail/lib/Horde/Kolab/IMAP/cclient.php     |    4 +-
 horde-webmail/lib/Horde/Kolab/IMAP/pear.php        |    4 +-
 horde-webmail/lib/Horde/Kolab/IMAP/test.php        |    4 +-
 horde-webmail/lib/Horde/Kolab/Server.php           |    4 +-
 horde-webmail/lib/Horde/Kolab/Server/Object.php    |    4 +-
 .../lib/Horde/Kolab/Server/Object/address.php      |    4 +-
 .../Horde/Kolab/Server/Object/administrator.php    |    4 +-
 .../lib/Horde/Kolab/Server/Object/adminrole.php    |    4 +-
 .../lib/Horde/Kolab/Server/Object/distlist.php     |    4 +-
 .../Horde/Kolab/Server/Object/domainmaintainer.php |    4 +-
 .../lib/Horde/Kolab/Server/Object/group.php        |    4 +-
 .../lib/Horde/Kolab/Server/Object/maintainer.php   |    4 +-
 .../lib/Horde/Kolab/Server/Object/server.php       |    4 +-
 .../lib/Horde/Kolab/Server/Object/sharedfolder.php |    4 +-
 .../lib/Horde/Kolab/Server/Object/user.php         |    4 +-
 horde-webmail/lib/Horde/Kolab/Server/ldap.php      |    4 +-
 horde-webmail/lib/Horde/Kolab/Server/test.php      |    4 +-
 horde-webmail/lib/Horde/Kolab/Session.php          |   23 +++++++++++++------
 19 files changed, 52 insertions(+), 43 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/IMAP.php b/horde-webmail/lib/Horde/Kolab/IMAP.php
index 20a31b2..a7cf592 100644
--- a/horde-webmail/lib/Horde/Kolab/IMAP.php
+++ b/horde-webmail/lib/Horde/Kolab/IMAP.php
@@ -9,9 +9,9 @@
  * The Horde_Kolab_IMAP class provides a wrapper around two different Kolab IMAP
  * connection types.
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/IMAP.php,v 1.2 2008/08/18 13:32:56 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/IMAP.php,v 1.1.2.2 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/IMAP/cclient.php b/horde-webmail/lib/Horde/Kolab/IMAP/cclient.php
index 78aa997..e31cd08 100644
--- a/horde-webmail/lib/Horde/Kolab/IMAP/cclient.php
+++ b/horde-webmail/lib/Horde/Kolab/IMAP/cclient.php
@@ -9,9 +9,9 @@
  * The Horde_Kolab_IMAP_Connection_cclient class connects to an IMAP server using
  * the IMAP functionality within PHP.
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/IMAP/cclient.php,v 1.3 2008/10/06 17:22:42 slusarz Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/IMAP/cclient.php,v 1.1.2.2 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/IMAP/pear.php b/horde-webmail/lib/Horde/Kolab/IMAP/pear.php
index d9c2c86..8afff30 100644
--- a/horde-webmail/lib/Horde/Kolab/IMAP/pear.php
+++ b/horde-webmail/lib/Horde/Kolab/IMAP/pear.php
@@ -17,9 +17,9 @@ require_once 'Net/IMAP.php';
  * The Horde_Kolab_IMAP_Connection_pear class connects to an IMAP server using the
  * Net_IMAP PEAR package.
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/IMAP/pear.php,v 1.2 2008/08/18 13:32:56 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/IMAP/pear.php,v 1.1.2.2 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/IMAP/test.php b/horde-webmail/lib/Horde/Kolab/IMAP/test.php
index b6f1e49..5a804af 100644
--- a/horde-webmail/lib/Horde/Kolab/IMAP/test.php
+++ b/horde-webmail/lib/Horde/Kolab/IMAP/test.php
@@ -14,9 +14,9 @@ define('KOLAB_IMAP_FLAG_DELETED', 1);
  * The Horde_Kolab_IMAP_Connection_test class simulates an IMAP server for
  * testing purposes.
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/IMAP/test.php,v 1.2 2008/08/18 13:32:56 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/IMAP/test.php,v 1.1.2.3 2009/02/23 23:02:30 wrobel Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server.php b/horde-webmail/lib/Horde/Kolab/Server.php
index fea438a..bf251f5 100644
--- a/horde-webmail/lib/Horde/Kolab/Server.php
+++ b/horde-webmail/lib/Horde/Kolab/Server.php
@@ -28,9 +28,9 @@ define('KOLAB_SERVER_RESULT_MANY',   3);
  * This class provides methods to deal with Kolab objects stored in
  * the Kolab object db.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server.php,v 1.2.2.3 2008/09/22 12:22:33 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server.php,v 1.2.2.8 2009/01/08 09:33:35 wrobel Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object.php b/horde-webmail/lib/Horde/Kolab/Server/Object.php
index e3b38e0..2e5ada2 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object.php
@@ -71,9 +71,9 @@ define('KOLAB_UT_RESOURCE',           3);
  * This class provides methods to deal with Kolab objects stored in
  * the Kolab db.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object.php,v 1.2.2.3 2008/09/22 16:20:59 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object.php,v 1.2.2.8 2009/01/08 21:07:32 wrobel Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/address.php b/horde-webmail/lib/Horde/Kolab/Server/Object/address.php
index 8f3aac2..98ed518 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/address.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/address.php
@@ -17,9 +17,9 @@
  * This class provides methods to deal with global address book
  * entries for Kolab.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/address.php,v 1.2.2.2 2008/08/01 07:56:20 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/address.php,v 1.2.2.5 2009/01/08 21:07:32 wrobel Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/administrator.php b/horde-webmail/lib/Horde/Kolab/Server/Object/administrator.php
index f03ac86..2566c51 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/administrator.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/administrator.php
@@ -19,9 +19,9 @@ require_once 'Horde/Kolab/Server/Object/adminrole.php';
  * This class provides methods to deal with administrator
  * entries for Kolab.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/administrator.php,v 1.2.2.2 2008/08/01 07:56:20 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/administrator.php,v 1.2.2.4 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/adminrole.php b/horde-webmail/lib/Horde/Kolab/Server/Object/adminrole.php
index ac1ae87..aea4410 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/adminrole.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/adminrole.php
@@ -16,9 +16,9 @@
 /**
  * This class provides methods to deal with administrator object types.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/maintainer.php,v 1.3 2008/08/01 07:49:26 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/adminrole.php,v 1.1.2.3 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/distlist.php b/horde-webmail/lib/Horde/Kolab/Server/Object/distlist.php
index 945c047..7965e0d 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/distlist.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/distlist.php
@@ -18,9 +18,9 @@ require_once 'Horde/Kolab/Server/Object/group.php';
 /**
  * This class provides methods to deal with distribution lists for Kolab.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/group.php,v 1.3 2008/08/01 07:49:26 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/distlist.php,v 1.1.2.2 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/domainmaintainer.php b/horde-webmail/lib/Horde/Kolab/Server/Object/domainmaintainer.php
index 7fdfd53..a76070c 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/domainmaintainer.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/domainmaintainer.php
@@ -18,9 +18,9 @@ require_once 'Horde/Kolab/Server/Object/adminrole.php';
 /**
  * This class provides methods associated to Kolab domain maintainers.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/domainmaintainer.php,v 1.2.2.2 2008/08/01 07:56:20 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/domainmaintainer.php,v 1.2.2.5 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/group.php b/horde-webmail/lib/Horde/Kolab/Server/Object/group.php
index 1b4163c..91c1bd2 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/group.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/group.php
@@ -16,9 +16,9 @@
 /**
  * This class provides methods to deal with groups for Kolab.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/group.php,v 1.2.2.2 2008/08/01 07:56:20 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/group.php,v 1.2.2.4 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/maintainer.php b/horde-webmail/lib/Horde/Kolab/Server/Object/maintainer.php
index 485ae2d..d93a64e 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/maintainer.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/maintainer.php
@@ -19,9 +19,9 @@ require_once 'Horde/Kolab/Server/Object/adminrole.php';
  * This class provides methods to deal with maintainer
  * entries for Kolab.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/maintainer.php,v 1.2.2.2 2008/08/01 07:56:20 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/maintainer.php,v 1.2.2.4 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/server.php b/horde-webmail/lib/Horde/Kolab/Server/Object/server.php
index 5db7261..965eb84 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/server.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/server.php
@@ -16,9 +16,9 @@
 /**
  * This class provides methods to deal with Kolab server configuration.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/server.php,v 1.2.2.2 2008/08/01 07:56:20 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/server.php,v 1.2.2.4 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/sharedfolder.php b/horde-webmail/lib/Horde/Kolab/Server/Object/sharedfolder.php
index c909c05..3b68862 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/sharedfolder.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/sharedfolder.php
@@ -17,9 +17,9 @@
  * This class provides methods to deal with shared folders
  * entries for Kolab.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/sharedfolder.php,v 1.2.2.2 2008/08/01 07:56:20 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/sharedfolder.php,v 1.2.2.4 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
index 99b5975..d4e57a0 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
@@ -17,9 +17,9 @@
  * This class provides methods to deal with Kolab users stored in
  * the Kolab db.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/user.php,v 1.2.2.3 2008/09/12 16:52:07 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/Object/user.php,v 1.2.2.10 2009/01/08 21:07:32 wrobel Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/ldap.php b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
index 87d6b1b..a50ba2c 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/ldap.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
@@ -20,9 +20,9 @@ require_once 'Horde/LDAP.php';
  * This class provides methods to deal with Kolab objects stored in
  * the standard Kolab LDAP db.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/ldap.php,v 1.2.2.2 2008/08/01 07:56:19 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/ldap.php,v 1.2.2.10 2009/02/24 07:39:47 wrobel Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/test.php b/horde-webmail/lib/Horde/Kolab/Server/test.php
index 2b07122..47f985a 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/test.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/test.php
@@ -19,9 +19,9 @@ require_once 'Horde/Kolab/Server/ldap.php';
 /**
  * This class provides a class for testing the Kolab Server DB.
  *
- * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/test.php,v 1.2.2.2 2008/08/01 07:56:19 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Server/test.php,v 1.2.2.7 2009/01/06 15:23:15 jan Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Session.php b/horde-webmail/lib/Horde/Kolab/Session.php
index bcbda7e..135bcb5 100644
--- a/horde-webmail/lib/Horde/Kolab/Session.php
+++ b/horde-webmail/lib/Horde/Kolab/Session.php
@@ -1,8 +1,17 @@
 <?php
 /**
- * @package Kolab_Server
+ * The Horde_Kolab_Session class holds additional user details for the current
+ * session.
+ *
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Session.php,v 1.1.2.11 2009/02/07 14:09:56 wrobel Exp $
+ *
+ * PHP version 4
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Session.php,v 1.4 2008/09/22 16:15:51 wrobel Exp $
+ * @category Kolab
+ * @package  Kolab_Server
+ * @author   Gunnar Wrobel <wrobel at pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
  */
 
 /** We need the Auth library */
@@ -18,9 +27,9 @@ require_once 'Horde/Auth.php';
  * relevant for the user session should be accessed via the Horde_Kolab_Session
  * class.
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Session.php,v 1.4 2008/09/22 16:15:51 wrobel Exp $
+ * $Horde: framework/Kolab_Server/lib/Horde/Kolab/Session.php,v 1.1.2.11 2009/02/07 14:09:56 wrobel Exp $
  *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2008-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
@@ -287,14 +296,14 @@ class Horde_Kolab_Session {
     {
         if (!isset($this->_imap)) {
 
-            /** We need the Kolab IMAP library now. */
-            require_once 'Horde/Kolab/IMAP.php';
-
             $params = $this->getImapParams();
             if (is_a($params, 'PEAR_Error')) {
                 return $params;
             }
 
+            /** We need the Kolab IMAP library now. */
+            require_once 'Horde/Kolab/IMAP.php';
+
             $imap = &Horde_Kolab_IMAP::singleton($params['hostspec'],
                                                  $params['port'], true, false);
             if (is_a($imap, 'PEAR_Error')) {
-- 
tg: (7a64fc0..) t/COPYRIGHT2 (depends on: t/Kolab_Server/HK/GW/FixNotics)
-- 
TOPGIT patch commit log
=======================

commit 31b74193f0fce276c94a91cdc9a2c34e7f450cce
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 22:36:28 2009 +0000

    Remove stray files.

commit 9e9b402b7dd46a893a57fe12b46834fdf46cdd74
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 05:14:36 2009 +0000

    Sync the kolab-webclient Kolab_Server module with fw3.

--- NEW FILE: t_COPYRIGHT3.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/COPYRIGHT3

Syncs the Kolab_Storage module with Horde fw3.

STATUS: MERGED

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Deprecated.php     |    4 ++--
 horde-webmail/lib/Horde/Kolab/Storage.php        |    4 ++--
 horde-webmail/lib/Horde/Kolab/Storage/Cache.php  |    4 ++--
 horde-webmail/lib/Horde/Kolab/Storage/Data.php   |    4 ++--
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |    4 ++--
 horde-webmail/lib/Horde/Kolab/Storage/List.php   |    4 ++--
 horde-webmail/lib/Horde/Kolab/Storage/Perms.php  |    4 ++--
 7 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Deprecated.php b/horde-webmail/lib/Horde/Kolab/Deprecated.php
index e2ade05..a627821 100644
--- a/horde-webmail/lib/Horde/Kolab/Deprecated.php
+++ b/horde-webmail/lib/Horde/Kolab/Deprecated.php
@@ -17,9 +17,9 @@ require_once 'Horde/Kolab/Storage.php';
  * backward compatibility. The intended way of using the Kolab storage
  * handling is to use the main Kolab_Storage class only.
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Deprecated.php,v 1.1.2.1 2008/08/18 13:48:57 wrobel Exp $
+ * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Deprecated.php,v 1.1.2.4 2009/01/06 15:23:17 jan Exp $
  *
- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Storage.php b/horde-webmail/lib/Horde/Kolab/Storage.php
index 0531243..96a905b 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage.php
@@ -34,9 +34,9 @@ require_once 'Horde/Kolab/Storage/List.php';
  *     $folder = Kolab_Storage::getShareData(Auth::getAuth(), 'event');
  *   </code>
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage.php,v 1.2.2.2 2008/09/12 16:09:51 wrobel Exp $
+ * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage.php,v 1.2.2.3 2009/01/06 15:23:17 jan Exp $
  *
- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Cache.php b/horde-webmail/lib/Horde/Kolab/Storage/Cache.php
index 908a5d8..d60ceeb 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Cache.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Cache.php
@@ -12,9 +12,9 @@ require_once 'Horde/Cache.php';
  * The Kolab_Cache class provides a cache for the Kolab
  * storage for groupware objects
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Cache.php,v 1.2.2.2 2008/09/06 09:19:31 jan Exp $
+ * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Cache.php,v 1.2.2.4 2009/01/06 15:23:18 jan Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Data.php b/horde-webmail/lib/Horde/Kolab/Storage/Data.php
index 472a131..213d1f2 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Data.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Data.php
@@ -12,9 +12,9 @@ require_once 'Horde/Kolab/Storage/Cache.php';
  * The Kolab_Data class represents a data type in an IMAP folder on the Kolab
  * server.
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Data.php,v 1.5.2.1 2008/08/18 13:48:57 wrobel Exp $
+ * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Data.php,v 1.5.2.4 2009/01/06 15:23:18 jan Exp $
  *
- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index 8c74322..4d3e0f3 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -59,9 +59,9 @@ define('HORDE_ANNOT_SHARE_ATTR', '/vendor/horde/share-');
  * The Kolab_Folder class represents an IMAP folder on the Kolab
  * server.
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder.php,v 1.7.2.3 2008/09/25 14:44:03 wrobel Exp $
+ * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder.php,v 1.7.2.19 2009/02/24 07:40:40 wrobel Exp $
  *
- * Copyright 2004-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/List.php b/horde-webmail/lib/Horde/Kolab/Storage/List.php
index d7af1b2..583f41f 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/List.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/List.php
@@ -12,9 +12,9 @@ require_once 'Horde/Kolab/Storage/Folder.php';
  * The Kolab_List class represents all IMAP folders on the Kolab
  * server visible to the current user.
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/List.php,v 1.3.2.2 2008/09/25 09:20:07 wrobel Exp $
+ * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/List.php,v 1.3.2.7 2009/02/23 21:33:19 wrobel Exp $
  *
- * Copyright 2007-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2007-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Perms.php b/horde-webmail/lib/Horde/Kolab/Storage/Perms.php
index 114fda9..8b3dd72 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Perms.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Perms.php
@@ -13,9 +13,9 @@ require_once 'Horde/Perms.php';
  * Permission handling and the IMAP permission system used on the
  * Kolab server.
  *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Perms.php,v 1.2.2.1 2008/08/18 13:48:57 wrobel Exp $
+ * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Perms.php,v 1.2.2.2 2009/01/06 15:23:18 jan Exp $
  *
- * Copyright 2006-2008 The Horde Project (http://www.horde.org/)
+ * Copyright 2006-2009 The Horde Project (http://www.horde.org/)
  *
  * See the enclosed file COPYING for license information (LGPL). If you
  * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
-- 
tg: (b79b990..) t/COPYRIGHT3 (depends on: t/Kolab_Storage/HK/GW/SuppressTriggering)
-- 
TOPGIT patch commit log
=======================

commit f6c131c0e081c7fec9baf44bb96080b3f8e99918
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 22:37:24 2009 +0000

    Remove stray files.

commit adc83aafb0abaaeadb86a06f210928f1ee7c1bdb
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 06:07:04 2009 +0000

    Sync Kolab_Storage within kolab-webclient with horde fw3.

--- NEW FILE: t_GLOBAL_HK_GW_Config.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/GLOBAL/HK/GW/Config

The Horde configuration for Kolab.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/config/conf.php            |  116 ++++++++++++++
 horde-webmail/config/hooks.php           |   52 +++----
 horde-webmail/config/kolab.php           |   40 +++++
 horde-webmail/config/prefs.php           |    4 +-
 horde-webmail/dimp/config/servers.php    |  255 ++++++++++++++++++++++++++++++
 horde-webmail/imp/config/conf.php        |   14 +-
 horde-webmail/imp/config/hooks.php       |    7 +
 horde-webmail/imp/config/servers.php     |   67 +++++++-
 horde-webmail/ingo/config/backends.php   |    4 +
 horde-webmail/ingo/config/conf.php       |    3 +-
 horde-webmail/kronolith/config/conf.php  |   15 +-
[...1125 lines suppressed...]

    Switch to authentication via imp to allow direct selection of DIMP.

commit 85d406d86c124d48ba5f58b014a59042984547bb
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 8 21:08:46 2009 +0000

    Allow local kolab.php configuration files.

commit 6f3d56d64443a9d456b03ba364506c61dc609b1c
Author: Gunnar Wrobel <p at rdus.de>
Date:   Mon Feb 2 00:03:06 2009 +0000

    Use only cookies for session management.

commit 58c0d2b40ea52c6c7a143efeaaaf87619d105b12
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 22:17:11 2009 +0000

    Added patch release/HK-GW-Config.patch  from the mercurial release queue.

--- NEW FILE: t_GLOBAL_HK_GW_ConfigOpenPKG.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/GLOBAL/HK/GW/ConfigOpenPKG

Specific OpenPKG configuration bits.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/config/conf.php |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/config/conf.php b/horde-webmail/config/conf.php
index f5c85a6..ae2acef 100644
--- a/horde-webmail/config/conf.php
+++ b/horde-webmail/config/conf.php
@@ -41,7 +41,8 @@ $conf['log']['params']['append'] = true;
 $conf['log']['type'] = 'file';
 $conf['log']['enabled'] = true;
 $conf['log_accesskeys'] = false;
-$conf['prefs']['driver'] = 'kolab_imap';
+$conf['prefs']['driver'] = 'file';
+$conf['prefs']['params']['directory'] = dirname(__FILE__) . '/../storage/';
 $conf['alarms']['params']['driverconfig'] = 'horde';
 $conf['alarms']['params']['ttl'] = 300;
 $conf['alarms']['driver'] = 'sql';
-- 
tg: (5c96f93..) t/GLOBAL/HK/GW/ConfigOpenPKG (depends on: t/GLOBAL/HK/GW/Config)
-- 
TOPGIT patch commit log
=======================

commit 0a7bb75c1aa1f659664a8e3ae5d18f0f1e680ebd
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 22:31:59 2009 +0000

    Added patch release/HK-GW-Config_OpenPKG.patch  from the mercurial release queue.

--- NEW FILE: t_Kolab__Format_HK_GW_HandleEmptyXmlParserReturn.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/Kolab_Format/HK/GW/HandleEmptyXmlParserReturn

Correct handling of empty return values from the XML parser. An empty
return might occur if the XML document is broken (e.g. broken encoding).

ISSUE: kolab/issue3520 (calendar with certain entries does not display in web client)
ISSUE: kolab/issue3525 (free/busy regeneration aborts for unparsable events)
ISSUE: kolab/issue3528 (Events with broken encoding should work)

LINK: https://www.intevation.de/roundup/kolab/issue3520
LINK: https://www.intevation.de/roundup/kolab/issue3525
LINK: https://www.intevation.de/roundup/kolab/issue3528

STATUS: MERGED

REF: http://cvs.horde.org/diff.php/framework/Kolab_Format/lib/Horde/Kolab/Format/XML.php?r1=1.5.2.10&r2=1.5.2.11
REF: http://cvs.horde.org/diff.php/framework/Kolab_Format/lib/Horde/Kolab/Format/XML.php?r1=1.15&r2=1.16

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Format/XML.php |   22 +++++++++++++++++++++-
 1 files changed, 21 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML.php b/horde-webmail/lib/Horde/Kolab/Format/XML.php
index d3d7def..3ed41b9 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML.php
@@ -364,6 +364,9 @@ class Horde_Kolab_Format_XML
     /**
      * Load an object based on the given XML string.
      *
+     * @todo Check encoding of the returned array. It seems to be ISO-8859-1 at
+     * the moment and UTF-8 would seem more appropriate.
+     *
      * @param string $xmltext  The XML of the message as string.
      *
      * @return array|PEAR_Error The data array representing the object.
@@ -371,7 +374,24 @@ class Horde_Kolab_Format_XML
     function load(&$xmltext)
     {
         $noderoot = $this->_parseXml($xmltext);
-        if ($noderoot === false) {
+        if (is_a($noderoot, 'PEAR_Error') || empty($noderoot)) {
+            /**
+             * If the first call does not return successfully this might mean we
+             * got an attachment with broken encoding. There are some Kolab
+             * client versions in the wild that might have done that. So the
+             * next section starts a second attempt by guessing the encoding and
+             * trying again.
+             */
+            if (strcasecmp(mb_detect_encoding($xmltext, 'UTF-8, ISO-8859-1'), 'UTF-8') !== 0) {
+                $xmltext = mb_convert_encoding($xmltext, 'UTF-8', 'ISO-8859-1');
+            }
+            $noderoot = $this->_parseXml($xmltext);
+        }
+
+        if (is_a($noderoot, 'PEAR_Error')) {
+            return $noderoot;
+        }
+        if (empty($noderoot)) {
             return false;
         }
 
-- 
tg: (2d1588f..) t/Kolab_Format/HK/GW/HandleEmptyXmlParserReturn (depends on: t/kronolith/HK/GW/XfbAccess)
-- 
TOPGIT patch commit log
=======================

commit adba3be1192f9ea9fb90c4418da8e4f5fc388c4e
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sat Apr 25 22:14:40 2009 +0200

    Merged the patch in slightly modified form upstream.

commit 1883efc257b2e50646e11da79cc47fb0f7f328ca
Author: Gunnar Wrobel <p at rdus.de>
Date:   Thu Apr 2 11:36:17 2009 +0200

    Correct handling of empty return values from the XML parser. An empty
    return might occur if the XML document is broken (e.g. broken encoding).
    
    ISSUE: kolab/issue3520 (calendar with certain entries does not display in web client)
    ISSUE: kolab/issue3525 (free/busy regeneration aborts for unparsable events)
    ISSUE: kolab/issue3528 (Events with broken encoding should work)
    
    LINK: https://www.intevation.de/roundup/kolab/issue3520
    LINK: https://www.intevation.de/roundup/kolab/issue3525
    LINK: https://www.intevation.de/roundup/kolab/issue3528

--- NEW FILE: t_Kolab__Server_HK_GW_DenyLogin.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/Kolab_Server/HK/GW/DenyLogin

Allow/Deny login to specific Kolab user groups.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Server.php      |   39 ++++++++++++++++++++++--
 horde-webmail/lib/Horde/Kolab/Server/ldap.php |   18 +++++++++++
 horde-webmail/lib/Horde/Kolab/Session.php     |   30 +++++++++++++++++++
 3 files changed, 83 insertions(+), 4 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Server.php b/horde-webmail/lib/Horde/Kolab/Server.php
index 7954b21..fea438a 100644
--- a/horde-webmail/lib/Horde/Kolab/Server.php
+++ b/horde-webmail/lib/Horde/Kolab/Server.php
@@ -414,7 +414,7 @@ class Horde_Kolab_Server {
     }
 
     /**
-     * Identify the UID for the first object found using a specified
+     * Identify the UID for the first user found using a specified
      * attribute value.
      *
      * @param string $attr     The name of the attribute used for searching.
@@ -431,6 +431,23 @@ class Horde_Kolab_Server {
     }
 
     /**
+     * Identify the GID for the first group found using a specified
+     * attribute value.
+     *
+     * @param string $attr     The name of the attribute used for searching.
+     * @param string $value    The desired value of the attribute.
+     * @param int    $restrict A KOLAB_SERVER_RESULT_* result restriction.
+     *
+     * @return mixed|PEAR_Error The GID or false if there was no result.
+     */
+    function gidForAttr($attr, $value,
+                        $restrict = KOLAB_SERVER_RESULT_SINGLE)
+    {
+        /* In the default class we just return false */
+        return false;
+    }
+
+    /**
      * Is the given UID member of the group with the given mail address?
      *
      * @param string $uid  UID of the user.
@@ -460,20 +477,34 @@ class Horde_Kolab_Server {
     }
 
     /**
-     * Identify the UID for the first object found with the given mail.
+     * Identify the UID for the first user found with the given mail.
      *
-     * @param string $mail     Search for objects with this mail address.
+     * @param string $mail     Search for users with this mail address.
      * @param int    $restrict A KOLAB_SERVER_RESULT_* result restriction.
      *
      * @return mixed|PEAR_Error The UID or false if there was no result.
      */
     function uidForMail($mail,
-                      $restrict = KOLAB_SERVER_RESULT_SINGLE)
+                        $restrict = KOLAB_SERVER_RESULT_SINGLE)
     {
         return $this->uidForAttr('mail', $mail);
     }
 
     /**
+     * Identify the GID for the first group found with the given mail.
+     *
+     * @param string $mail     Search for groups with this mail address.
+     * @param int    $restrict A KOLAB_SERVER_RESULT_* result restriction.
+     *
+     * @return mixed|PEAR_Error The GID or false if there was no result.
+     */
+    function gidForMail($mail,
+                        $restrict = KOLAB_SERVER_RESULT_SINGLE)
+    {
+        return $this->gidForAttr('mail', $mail);
+    }
+
+    /**
      * Identify the UID for the first object found with the given ID or mail.
      *
      * @param string $id Search for objects with this uid/mail.
diff --git a/horde-webmail/lib/Horde/Kolab/Server/ldap.php b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
index a09f74d..d4079b8 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/ldap.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
@@ -784,6 +784,24 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
     }
 
     /**
+     * Identify the GID for the first group found using a specified
+     * attribute value.
+     *
+     * @param string $attr     The name of the attribute used for searching.
+     * @param string $value    The desired value of the attribute.
+     * @param int    $restrict A KOLAB_SERVER_RESULT_* result restriction.
+     *
+     * @return mixed|PEAR_Error The GID or false if there was no result.
+     */
+    function gidForAttr($attr, $value,
+                       $restrict = KOLAB_SERVER_RESULT_SINGLE)
+    {
+        $filter = '(&(objectClass=kolabGroupOfNames)(' . $attr .
+            '=' . Horde_LDAP::quote($value) . '))';
+        return $this->_dnForFilter($filter, $restrict);
+    }
+
+    /**
      * Is the given UID member of the group with the given mail address?
      *
      * @param string $uid  UID of the user.
diff --git a/horde-webmail/lib/Horde/Kolab/Session.php b/horde-webmail/lib/Horde/Kolab/Session.php
index a0e3cf3..d47f8b0 100644
--- a/horde-webmail/lib/Horde/Kolab/Session.php
+++ b/horde-webmail/lib/Horde/Kolab/Session.php
@@ -123,6 +123,32 @@ class Horde_Kolab_Session {
                     if (empty($conf['kolab']['imap']['allow_special_users'])
                         && !is_a($user_object, 'Horde_Kolab_Server_Object_user')) {
                         $this->auth = PEAR::raiseError(_('Access to special Kolab users is denied.'));
+                    } else if (isset($conf['kolab']['server']['deny_group'])) {
+                        $dn = $server->gidForMail($conf['kolab']['server']['deny_group']);
+                        if (is_a($dn, 'PEAR_Error')) {
+                            $this->auth = $dn;
+                        } else if (empty($dn)) {
+                            Horde::logMessage('The Kolab configuratin setting $conf[\'kolab\'][\'server\'][\'deny_group\'] holds a non-existing group!',
+                                              __FILE__, __LINE__, PEAR_LOG_WARNING);
+                            $this->auth = true;
+                        } else if (in_array($dn, $user_object->getGroups())) {
+                            $this->auth = PEAR::raiseError(_('You are member of a group that may not login on this server.'));
+                        } else {
+                            $this->auth = true;
+                        }
+                    } else if (isset($conf['kolab']['server']['allow_group'])) {
+                        $dn = $server->gidForMail($conf['kolab']['server']['allow_group']);
+                        if (is_a($dn, 'PEAR_Error')) {
+                            $this->auth = $dn;
+                        } else if (empty($dn)) {
+                            Horde::logMessage('The Kolab configuratin setting $conf[\'kolab\'][\'server\'][\'allow_group\'] holds a non-existing group!',
+                                              __FILE__, __LINE__, PEAR_LOG_WARNING);
+                            $this->auth = true;
+                        } else if (!in_array($dn, $user_object->getGroups())) {
+                            $this->auth = PEAR::raiseError(_('You are no member of a group that may login on this server.'));
+                        } else {
+                            $this->auth = true;
+                        }
                     } else {
                         /**
                          * At this point we can be certain the user is an
@@ -131,6 +157,10 @@ class Horde_Kolab_Session {
                         $this->auth = true;
                     }
 
+                    if (empty($this->auth) || is_a($this->auth, 'PEAR_Error')) {
+                        return;
+                    }
+
                     $result = $user_object->get(KOLAB_ATTR_MAIL);
                     if (!empty($result) && !is_a($result, 'PEAR_Error')) {
                         $this->user_mail = $result;
-- 
tg: (f425aea..) t/Kolab_Server/HK/GW/DenyLogin (depends on: t/framework/HK/GW/iCalendar/QuotedParameters)
-- 
TOPGIT patch commit log
=======================

commit 553b6a6a3b5f42bcc314b3ccb8dc271c094739d4
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 23:39:21 2009 +0000

    Remove patch remains.

commit ec2569d9f53c41b19c033cc8cdeceb5169e18106
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 17:54:16 2009 +0000

    Added patch release/HK-GW-Kolab_Server-Deny_login.patch from the mercurial release queue.

--- NEW FILE: t_Kolab__Server_HK_GW_FixAddrForIdOrMail.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/Kolab_Server/HK/GW/FixAddrForIdOrMail

Downcase the array of returned mail addresses. Ensure we always return
an array.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/IMAP/test.php   |    2 +-
 horde-webmail/lib/Horde/Kolab/Server/ldap.php |    7 ++++++-
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/IMAP/test.php b/horde-webmail/lib/Horde/Kolab/IMAP/test.php
index ce5609a..b6f1e49 100644
--- a/horde-webmail/lib/Horde/Kolab/IMAP/test.php
+++ b/horde-webmail/lib/Horde/Kolab/IMAP/test.php
@@ -75,7 +75,7 @@ class Horde_Kolab_IMAP_test extends Horde_Kolab_IMAP {
         $tls = ($tls) ? 'tls' : 'notls';
         $this->_connected = $login . ':' . $password . ':' . $tls;
         $this->_user = $login;
-        $this->_mbox = null;
+        unset($this->_mbox);
         $this->_mboxname = null;
     }
 
diff --git a/horde-webmail/lib/Horde/Kolab/Server/ldap.php b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
index d4079b8..5ff4786 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/ldap.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
@@ -721,7 +721,10 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
             . Horde_LDAP::quote($id) . ')))';
         $result = $this->_attrsForFilter($filter, array('mail', 'alias'),
                                          KOLAB_SERVER_RESULT_STRICT);
-        if (empty($result) || is_a($result, 'PEAR_Error')) {
+        if (empty($result)) {
+            return array();
+        }
+        if (is_a($result, 'PEAR_Error')) {
             return $result;
         }
         $addrs = array_merge((array) $result['mail'], (array) $result['alias']);
@@ -746,6 +749,8 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
             }
         }
 
+        $addrs = array_map('strtolower', $addrs);
+
         return $addrs;
     }
 
-- 
tg: (0bd4e3e..) t/Kolab_Server/HK/GW/FixAddrForIdOrMail (depends on: t/Kolab_Storage/HK/GW/MultipleListCaches)
-- 
TOPGIT patch commit log
=======================

commit 799ad34f530b4f3936ffa7ac278a64443b3c3d5e
Author: Gunnar Wrobel <p at rdus.de>
Date:   Tue Feb 24 05:53:09 2009 +0000

    Fix recursive tg dependency.

commit 64ac03c4ba437b3ce0fa994f0030a6fca9643f23
Author: Gunnar Wrobel <p at rdus.de>
Date:   Tue Feb 24 05:52:00 2009 +0000

    New TopGit dependency: t/Kolab_Storage/HK/GW/MultipleListCaches

commit f3c256bfe91fcea559d5d8f08dabf1c280f33b11
Author: Gunnar Wrobel <p at rdus.de>
Date:   Tue Feb 24 00:05:22 2009 +0100

    Fix addrsForIdOrMail.

--- NEW FILE: t_Kolab__Server_HK_GW_FixBodyHeaderBreakInTestDriver.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/Kolab_Server/HK/GW/FixBodyHeaderBreakInTestDriver

Fixes handling the line break between mail header and body in the IMAP test driver.

STATUS: MERGED

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/IMAP/test.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/IMAP/test.php b/horde-webmail/lib/Horde/Kolab/IMAP/test.php
index 5a804af..6e1f0e4 100644
--- a/horde-webmail/lib/Horde/Kolab/IMAP/test.php
+++ b/horde-webmail/lib/Horde/Kolab/IMAP/test.php
@@ -550,7 +550,7 @@ class Horde_Kolab_IMAP_test extends Horde_Kolab_IMAP {
      */
     function appendMessage($msg)
     {
-        $split = strpos('\r\n\r\n', $msg);
+        $split = strpos($msg, "\r\n\r\n");
         $mail = array('header' => substr($msg, 0, $split + 2),
                       'body' => substr($msg, $split + 3));
         return $this->_appendMessage($mail);
-- 
tg: (9cfd718..) t/Kolab_Server/HK/GW/FixBodyHeaderBreakInTestDriver (depends on: t/imp/H/GW/LoginRetries)
-- 
TOPGIT patch commit log
=======================

commit a632bbd56954bed61abb308bd8d8d5551887ba84
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Mar 13 00:16:18 2009 +0100

    Four patches went missing when I reordered the patch queue. The reordering was an operation I shouldn't have done. This commit removes the attempt to readd the four patches at a later queue position.

commit 8a3ca1d315a184f38667fc10e7f34488301d5d47
Author: Gunnar Wrobel <p at rdus.de>
Date:   Mon Mar 9 06:00:41 2009 +0000

    Add missing to sync Kolab_Server with horde fw3.

--- NEW FILE: t_Kolab__Server_HK_GW_FixLowerCaseObjectClasses.diff ---
From: root <root at domU-12-31-38-01-B8-13.compute-1.amazonaws.com>
Subject: [PATCH] t/Kolab_Server/HK/GW/FixLowerCaseObjectClasses

Fixed objectClass evaluation to respect case-insensitivity (Bug: #7694)

http://bugs.horde.org/ticket/7694

STATUS: MERGED

http://cvs.horde.org/diff.php/framework/Kolab_Server/lib/Horde/Kolab/Server/ldap.php?sa=1&r1=1.2.2.5&r2=1.2.2.6

Signed-off-by: root <wrobel at pardus.de>

---
 horde-webmail/lib/Horde/Kolab/Server/ldap.php |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Server/ldap.php b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
index 5ff4786..055174c 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/ldap.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
@@ -570,13 +570,13 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
         }
 
         // Not a user type?
-        if (!in_array('kolabInetOrgPerson', $oc)) {
+        if (!in_array('kolabinetorgperson', $oc)) {
             // Is it a group?
-            if (in_array('kolabGroupOfNames', $oc)) {
+            if (in_array('kolabgroupofnames', $oc)) {
                 return KOLAB_OBJECT_GROUP;
             }
             // Is it a shared Folder?
-            if (in_array('kolabSharedFolder', $oc)) {
+            if (in_array('kolabsharedfolder', $oc)) {
                 return KOLAB_OBJECT_SHAREDFOLDER;
             }
             return PEAR::raiseError(sprintf(_("Unkown Kolab object type for DN %s."),
@@ -626,7 +626,8 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
         }
         unset($object['count']);
         unset($object['objectClass']['count']);
-        return $object['objectClass'];
+        $result = array_map('strtolower', $object['objectClass']);
+        return $result;
     }
 
     /**
-- 
tg: (a3542e3..) t/Kolab_Server/HK/GW/FixLowerCaseObjectClasses (depends on: t/COPYRIGHT)
-- 
TOPGIT patch commit log
=======================

commit d3af838ddf2055eddb27316024ffe98f6e6c8e1f
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 04:59:05 2009 +0000

    Merged fix for http://bugs.horde.org/ticket/7694 into the kolab-webclient.

--- NEW FILE: t_Kolab__Server_HK_GW_FixNotics.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/Kolab_Server/HK/GW/FixNotics

Merged upstream patch to fix Kolab_Server notices into the kolab-webclient.

STATUS: MERGED

http://cvs.horde.org/diff.php/framework/Kolab_Server/lib/Horde/Kolab/Server/diff.php?sa=1&f=framework%2FKolab_Server%2Flib%2FHorde%2FKolab%2FServer%2Fldap.php&r1=1.2.2.9&r2=1.2.2.10&t=unified

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Server/ldap.php |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Server/ldap.php b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
index 055174c..87d6b1b 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/ldap.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
@@ -519,7 +519,7 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
 
             $result = array();
             foreach ($attrs as $attr) {
-                if ($entry[$attr]['count'] > 0) {
+                if (isset($entry[$attr]) && $entry[$attr]['count'] > 0) {
                     unset($entry[$attr]['count']);
                     $result[$attr] = $entry[$attr];
                 }
@@ -728,7 +728,11 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
         if (is_a($result, 'PEAR_Error')) {
             return $result;
         }
-        $addrs = array_merge((array) $result['mail'], (array) $result['alias']);
+        if (isset($result['alias'])) {
+            $addrs = array_merge((array) $result['mail'], (array) $result['alias']);
+        } else {
+            $addrs = $result['mail'];
+        }
         $mail  = $result['mail'][0];
 
         $filter = '(&(objectClass=kolabInetOrgPerson)(kolabDelegate='
-- 
tg: (d3af838..) t/Kolab_Server/HK/GW/FixNotics (depends on: t/Kolab_Server/HK/GW/FixLowerCaseObjectClasses)
-- 
TOPGIT patch commit log
=======================

commit 7a64fc01eb5d94557ac5fa8e44ea135094b1e8b6
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 05:02:38 2009 +0000

    Merged missing upstream patch into Kolab-Filter.

--- NEW FILE: t_Kolab__Server_HK_GW_UserMailAndFullname.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/Kolab_Server/HK/GW/UserMailAndFullname

Identify the users full name and make it accessible via the Kolab session handler.

FIXME: This has been reported by Thomas to be only partially working (fullname not be correctly accessible).

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Server/Object.php    |    5 ++++
 .../lib/Horde/Kolab/Server/Object/address.php      |   10 +++++++++
 .../lib/Horde/Kolab/Server/Object/user.php         |    2 +
 horde-webmail/lib/Horde/Kolab/Session.php          |   21 ++++++++++++++++++-
 4 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object.php b/horde-webmail/lib/Horde/Kolab/Server/Object.php
index 663281e..e3b38e0 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object.php
@@ -33,6 +33,7 @@ define('KOLAB_ATTR_CN',           'cn');
 define('KOLAB_ATTR_GIVENNAME',    'givenName');
 define('KOLAB_ATTR_FN',           'fn');
 define('KOLAB_ATTR_LNFN',         'lnfn');
+define('KOLAB_ATTR_FNLN',         'fnln');
 define('KOLAB_ATTR_MAIL',         'mail');
 define('KOLAB_ATTR_SID',          'uid');
 define('KOLAB_ATTR_ACL',          'acl');
@@ -366,6 +367,10 @@ class Horde_Kolab_Server_Object {
             $gn = $this->_get(KOLAB_ATTR_GIVENNAME, true);
             $sn = $this->_get(KOLAB_ATTR_SN, true);
             return sprintf('%s, %s', $sn, $gn);
+        case KOLAB_ATTR_FNLN:
+            $gn = $this->_get(KOLAB_ATTR_GIVENNAME, true);
+            $sn = $this->_get(KOLAB_ATTR_SN, true);
+            return sprintf('%s %s', $gn, $sn);
         default:
             return false;
         }
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/address.php b/horde-webmail/lib/Horde/Kolab/Server/Object/address.php
index bcf905e..8f3aac2 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/address.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/address.php
@@ -55,6 +55,16 @@ class Horde_Kolab_Server_Object_address extends Horde_Kolab_Server_Object {
     );
 
     /**
+     * Attributes derived from the LDAP values.
+     *
+     * @var array
+     */
+    var $_derived_attributes = array(
+        KOLAB_ATTR_LNFN,
+        KOLAB_ATTR_FNLN,
+    );
+
+    /**
      * The attributes required when creating an object of this class.
      *
      * @var array
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
index 62b71e8..99b5975 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
@@ -69,6 +69,8 @@ class Horde_Kolab_Server_Object_user extends Horde_Kolab_Server_Object {
     var $_derived_attributes = array(
         KOLAB_ATTR_ID,
         KOLAB_ATTR_USERTYPE,
+        KOLAB_ATTR_LNFN,
+        KOLAB_ATTR_FNLN,
     );
 
     /**
diff --git a/horde-webmail/lib/Horde/Kolab/Session.php b/horde-webmail/lib/Horde/Kolab/Session.php
index d47f8b0..bcbda7e 100644
--- a/horde-webmail/lib/Horde/Kolab/Session.php
+++ b/horde-webmail/lib/Horde/Kolab/Session.php
@@ -55,6 +55,13 @@ class Horde_Kolab_Session {
     var $user_mail;
 
     /**
+     * Full name.
+     *
+     * @var string
+     */
+    var $user_name = '';
+
+    /**
      * True if the Kolab_Server login was successfull.
      *
      * @var boolean|PEAR_Error
@@ -171,6 +178,11 @@ class Horde_Kolab_Session {
                         $this->user_id = $result;
                     }
 
+                    $result = $user_object->get(KOLAB_ATTR_FNLN);
+                    if (!empty($result) && !is_a($result, 'PEAR_Error')) {
+                        $this->user_name = $result;
+                    }
+
                     $result = $user_object->getServer('imap');
                     if (!empty($result) && !is_a($result, 'PEAR_Error')) {
                         $server = explode(':', $result, 2);
@@ -249,6 +261,8 @@ class Horde_Kolab_Session {
             $params['user'] = $user;
             if (isset($credentials['password'])) {
                 $params['pass'] = $credentials['password'];
+            } else {
+                $params['pass'] = Auth::getCredential('password');
             }
         }
         return Horde_Kolab_Server::singleton($params);
@@ -332,9 +346,12 @@ class Horde_Kolab_Session {
             $session = $hs->query('kolab_session');
         }
 
+        if (empty($user)) {
+            $user = Auth::getAuth();
+        }
+
         if ($destruct || empty($session)
-            || (!empty($user) &&  $user != $session->user_mail
-                && $user != $session->user_id)) {
+            || ($user != $session->user_mail && $user != $session->user_id)) {
             $session = new Horde_Kolab_Session($user, $credentials);
         }
 
-- 
tg: (a5a1f3e..) t/Kolab_Server/HK/GW/UserMailAndFullname (depends on: t/Kolab_Server/HK/GW/DenyLogin)
-- 
TOPGIT patch commit log
=======================

commit 4c997afbb54e494cdcc52969b158d2817ce84d44
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sat Feb 7 10:02:15 2009 +0000

    If we are authenticated and create a session without any information, the user will be set but the getServer() method has no access to the password. So it should be fetched here.

commit 3a9e1f04cf73d8576104715c48a8a26c8cd9c190
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 18:07:49 2009 +0000

    Added fixme in the patch description.

commit c69914c9e65d971428760fc139da66fb962e0016
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 18:06:20 2009 +0000

    Added patch release/HK-GW-Kolab_Server-User_Id.patch from the mercurial release queue.

--- NEW FILE: t_Kolab__Storage_HK_GW_MultipleListCaches.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/Kolab_Storage/HK/GW/MultipleListCaches

Fix testing when authenticating twice. Using different caches
is required in that case.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Storage/List.php |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Storage/List.php b/horde-webmail/lib/Horde/Kolab/Storage/List.php
index 6e6a16e..d7af1b2 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/List.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/List.php
@@ -107,15 +107,15 @@ class Kolab_List {
             $list = $session->query('kolab_folderlist');
         }
 
-        if (empty($list)) {
-            $list = new Kolab_List();
+        if (empty($list[Auth::getAuth()])) {
+            $list[Auth::getAuth()] = new Kolab_List();
         }
 
         if (!empty($GLOBALS['conf']['kolab']['imap']['cache_folders'])) {
             register_shutdown_function(array(&$list, 'shutdown'));
         }
 
-        return $list;
+        return $list[Auth::getAuth()];
     }
 
     /**
-- 
tg: (017e19d..) t/Kolab_Storage/HK/GW/MultipleListCaches (depends on: t/imp/HK/GW/AuthForInvitations)
-- 
TOPGIT patch commit log
=======================

commit 1e071de95f289b72a7b03bbffba4e533406e2b2e
Author: Gunnar Wrobel <p at rdus.de>
Date:   Mon Feb 23 22:57:52 2009 +0000

    Use different List caches so that we avoid problems when authenticating twice during testing.

--- NEW FILE: t_Kolab__Storage_HK_GW_SuppressTriggering.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/Kolab_Storage/HK/GW/SuppressTriggering

Allow to supress triggering (relevant for testing).

STATUS: MERGED

http://cvs.horde.org/diff.php/framework/Kolab_Storage/lib/Horde/Kolab/Storage/diff.php?sa=1&f=framework%2FKolab_Storage%2Flib%2FHorde%2FKolab%2FStorage%2FFolder.php&r1=1.27&r2=1.28&t=unified

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index 6596559..8c74322 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -1208,8 +1208,6 @@ class Kolab_Folder {
      */
     function trigger($name = null)
     {
-        global $conf;
-
         $type =  $this->getType();
         if (is_a($type, 'PEAR_Error')) {
             return $type;
@@ -1252,6 +1250,12 @@ class Kolab_Folder {
      */
     function triggerUrl($url)
     {
+        global $conf;
+
+        if (!empty($conf['kolab']['no_triggering'])) {
+            return true;
+        }
+
         $options['method'] = 'GET';
         $options['timeout'] = 5;
         $options['allowRedirects'] = true;
-- 
tg: (31b7419..) t/Kolab_Storage/HK/GW/SuppressTriggering (depends on: t/COPYRIGHT2)
-- 
TOPGIT patch commit log
=======================

commit d7fd24cc6662987d4887e253e54c4b4e20ea88f1
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 05:38:16 2009 +0000

    Merged missing upstream commit into kolab-webclient.

--- NEW FILE: t_Prefs_HK_GW_FixLDAPAuthForIngo.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/Prefs/HK/GW/FixLDAPAuthForIngo

Fix the authentication with the Kolab/LDAP backend to always use the credentials of the current user. Without this it won't 
be possible to store the filters within Ingo in LDAP.

FIXME: This is only a hack. The right thing to do would be to store the filter settings within the Kolab format rather than 
the preferences.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Prefs/kolab.php |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Prefs/kolab.php b/horde-webmail/lib/Horde/Prefs/kolab.php
index 55075db..0ebd4fd 100644
--- a/horde-webmail/lib/Horde/Prefs/kolab.php
+++ b/horde-webmail/lib/Horde/Prefs/kolab.php
@@ -1,5 +1,6 @@
 <?php
 
+require_once 'Horde/Auth.php';
 require_once 'Horde/Prefs/ldap.php';
 require_once 'Horde/Kolab.php';
 
@@ -42,7 +43,8 @@ class Prefs_kolab extends Prefs_ldap {
                         'searchpw' => $GLOBALS['conf']['kolab']['ldap']['phppw'],
                         'uid' => 'mail');
 
-        parent::Prefs_ldap($user, $password, $scope, $params, $caching);
+        parent::Prefs_ldap(Auth::getAuth(), Auth::getCredential('password'),
+                           $scope, $params, $caching);
     }
 
 }
-- 
tg: (ba51448..) t/Prefs/HK/GW/FixLDAPAuthForIngo (depends on: t/SyncML/HK/GW/CombinedFixes)
-- 
TOPGIT patch commit log
=======================

commit 1f1947c6b2ead4f66d54f280b2b243f4fcb8ef1f
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 18:30:02 2009 +0000

    Added patch release/HK-GW-Fix_Prefs_for_Ingo.patch from the mercurial release queue.

--- NEW FILE: t_SyncML_HK_GW_CombinedFixes.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/SyncML/HK/GW/CombinedFixes

Combined set of Univention SyncML patches.

FIXME: At least one of these has been rejected upstream. Rework the patch and update this one. Actually this patch should be 
splitted into the single parts.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/iCalendar.php      |   35 ++++++++++++
 horde-webmail/lib/SyncML/Backend.php       |   18 ++++++
 horde-webmail/lib/SyncML/Backend/Horde.php |   80 ++++++++++++++++++++++++++++
 horde-webmail/lib/SyncML/Constants.php     |    2 +-
 horde-webmail/lib/SyncML/Device.php        |   69 ++++++++++++++++++++++++
 horde-webmail/lib/SyncML/Sync.php          |   27 +++++++++-
 6 files changed, 228 insertions(+), 3 deletions(-)

diff --git a/horde-webmail/lib/Horde/iCalendar.php b/horde-webmail/lib/Horde/iCalendar.php
index decf66a..4b7143e 100644
--- a/horde-webmail/lib/Horde/iCalendar.php
+++ b/horde-webmail/lib/Horde/iCalendar.php
@@ -155,6 +155,41 @@ class Horde_iCalendar {
     }
 
     /**
+     * Sets an attribute empty.
+     *
+     * @param string $name     The name of the attribute.
+     * @param array $params    Array containing any addition parameters for
+     *                         this attribute.
+     * @param boolean $append  True to append the attribute, False to replace
+     *                         the first matching attribute found.
+     */
+    function setAttributeEmpty($name, $params = array(), $append = false)
+    {
+        switch ($name) {
+        case 'EXDATE':
+        case 'RDATE':
+            $this->setAttribute($name, array(), $params, $append, true);
+            break;
+        case 'COMPLETED':
+        case 'CREATED':
+        case 'DCREATED':
+        case 'LAST-MODIFIED':
+        case 'DTEND':
+        case 'DTSTART':
+        case 'DTSTAMP':
+        case 'DUE':
+        case 'AALARM':
+        case 'RECURRENCE-ID':
+            /* These values expect a date and there is no sensible
+             default so we better leave them alone for now. */
+            break;
+        default:
+            $this->setAttribute($name, '', $params, $append);
+            break;
+        }
+    }
+
+    /**
      * Sets parameter(s) for an (already existing) attribute.  The
      * parameter set is merged into the existing set.
      *
diff --git a/horde-webmail/lib/SyncML/Backend.php b/horde-webmail/lib/SyncML/Backend.php
index b445b3a..a13174a 100644
--- a/horde-webmail/lib/SyncML/Backend.php
+++ b/horde-webmail/lib/SyncML/Backend.php
@@ -567,6 +567,24 @@ class SyncML_Backend {
     }
 
     /**
+     * Checks if the entry specified by $cuid has been modified on the server.
+     *
+     * @param string $databaseURI  URI of Database to sync. Like
+     *                             calendar, tasks, contacts or notes.
+     *                             May include optional parameters:
+     *                             tasks?options=ignorecompleted.
+     * @param string  $cuid        Client ID of this entry
+     * @param integer $from_ts     Start timestamp.
+     *
+     * @return boolean   True if the client entry has been modified on
+     *                   the server. False otherwise.
+     */
+    function unchanged($databaseURI, $cuid, $from_ts)
+    {
+        die ("Not implemented!");
+    }
+
+    /**
      * Authenticates the user at the backend.
      *
      * For some types of authentications (notably auth:basic) the username
diff --git a/horde-webmail/lib/SyncML/Backend/Horde.php b/horde-webmail/lib/SyncML/Backend/Horde.php
index a9be55d..a71b5f8 100644
--- a/horde-webmail/lib/SyncML/Backend/Horde.php
+++ b/horde-webmail/lib/SyncML/Backend/Horde.php
@@ -204,6 +204,11 @@ class SyncML_Backend_Horde extends SyncML_Backend {
                                   __FILE__, __LINE__, PEAR_LOG_DEBUG);
                 continue;
             }
+            if ($suid_ts > $to_ts) {
+                // Add delayed to the next sync operation
+                $this->logMessage("Add ignored, lies in sync future: $suid", __FILE__, __LINE__, PEAR_LOG_DEBUG);
+                continue;
+            }
             $this->logMessage(
                 "Adding to client from db $database, server id $suid",
                 __FILE__, __LINE__, PEAR_LOG_DEBUG);
@@ -251,6 +256,11 @@ class SyncML_Backend_Horde extends SyncML_Backend {
                                       __FILE__, __LINE__, PEAR_LOG_DEBUG);
                     continue;
                 }
+                if ($suid_ts > $to_ts) {
+                    // Change delayed to the next sync operation
+                    $this->logMessage("Change ignored, lies in sync future: $suid", __FILE__, __LINE__, PEAR_LOG_DEBUG);
+                    continue;
+                }
                 $cuid = $this->_getCuid($database, $suid);
                 if (!$cuid) {
                     $this->logMessage(
@@ -311,6 +321,11 @@ class SyncML_Backend_Horde extends SyncML_Backend {
                                       __FILE__, __LINE__, PEAR_LOG_DEBUG);
                     continue;
                 }
+                if ($suid_ts > $to_ts) {
+                    // Delete delayed to the next sync operation
+                    $this->logMessage("Delete ignored, lies in sync future: $suid", __FILE__, __LINE__, PEAR_LOG_DEBUG);
+                   continue;
+                }
                 $cuid = $this->_getCuid($database, $suid);
                 if (!$cuid) {
                     $this->logMessage(
@@ -512,6 +527,71 @@ class SyncML_Backend_Horde extends SyncML_Backend {
     }
 
     /**
+     * Checks if the entry specified by $cuid has been modified on the server.
+     *
+     * @param string $databaseURI  URI of Database to sync. Like
+     *                             calendar, tasks, contacts or notes.
+     *                             May include optional parameters:
+     *                             tasks?options=ignorecompleted.
+     * @param string $cuid         Client ID of this entry
+     * @param integer $from_ts     Last server sync time.
+     *
+     * @return boolean   True if the client entry has been modified on
+     *                   the server. False otherwise.
+     */
+    function getConflict($databaseURI, $cuid, $server_ts)
+    {
+        global $registry;
+
+        $database = $this->_normalize($databaseURI);
+
+        // Only server needs to do a cuid<->suid map
+        if ($this->_backendMode == SYNCML_BACKENDMODE_SERVER) {
+            $suid = $this->_getSuid($database, $cuid);
+        } else {
+            $suid = $cuid;
+        }
+        $this->logMessage("checking modification date of entry suid $suid in $database", __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+        if ($suid) {
+            $mod_ts = $registry->call($database . '/getActionTimestamp', array($suid, 'modify', SyncML_Backend::getParameter($databaseURI,'source')));
+            $client_ts = $this->_getChangeTS($database, $suid);
+            // Check that the last server anchor is smaller than the
+            // last modification stamp (this means that a change
+            // occurred after the last sync started). This might still
+            // be a client change so check that the last client update
+            // also happened before the last modification)
+            if ($server_ts < $mod_ts && $client_ts < $mod_ts) {
+                // Duplicate the server entry
+                $this->logMessage("Conflict detected. Returning conflicting server entry $suid.", __FILE__, __LINE__, PEAR_LOG_DEBUG);
+                $device = &$_SESSION['SyncML.state']->getDevice();
+                $contentType = $device->getPreferredContentType($databaseURI);
+                return $this->retrieveEntry($databaseURI, $suid, $contentType);
+            }
+        } 
+        return false;
+    }
+
+    function duplicateConflict($databaseURI, $content)
+    {
+        global $registry;
+
+        $database = $this->_normalize($databaseURI);
+        $device = &$_SESSION['SyncML.state']->getDevice();
+        $contentType = $device->getPreferredContentType($databaseURI);
+        $content = preg_replace('/(\r\n|\r|\n)UID:.*?(\r\n|\r|\n)/', '\1', $content, 1);
+        $duid = $registry->call($database. '/import',
+                                array($content, $contentType, 
+                                      SyncML_Backend::getParameter($databaseURI,'source')));
+        if (is_a($duid, 'PEAR_Error')) {
+            $this->logMessage("duplicating entry failed.", __FILE__, __LINE__, PEAR_LOG_DEBUG);
+            return false;
+        }
+        $this->logMessage("duplicated server entry to $duid.", __FILE__, __LINE__, PEAR_LOG_DEBUG);
+        return true;
+    }
+
+    /**
      * Authenticates the user at the backend.
      *
      * For some types of authentications (notably auth:basic) the username
diff --git a/horde-webmail/lib/SyncML/Constants.php b/horde-webmail/lib/SyncML/Constants.php
index e0d0f9b..7ca925a 100644
--- a/horde-webmail/lib/SyncML/Constants.php
+++ b/horde-webmail/lib/SyncML/Constants.php
@@ -66,7 +66,7 @@ define('RESPONSE_RESET_CONTENT', 205);
 define('RESPONSE_PARTIAL_CONTENT', 206);
 define('RESPONSE_CONFLICT_RESOLVED_WITH_MERGE', 207);
 define('RESPONSE_CONFLICT_RESOLVED_WITH_CLIENT_WINNING', 208);
-define('RESPONSE_CONFILCT_RESOLVED_WITH_DUPLICATE', 209);
+define('RESPONSE_CONFLICT_RESOLVED_WITH_DUPLICATE', 209);
 define('RESPONSE_DELETE_WITHOUT_ARCHIVE', 210);
 define('RESPONSE_ITEM_NO_DELETED', 211);
 define('RESPONSE_AUTHENTICATION_ACCEPTED', 212);
diff --git a/horde-webmail/lib/SyncML/Device.php b/horde-webmail/lib/SyncML/Device.php
index 196dfbb..dd793c7 100644
--- a/horde-webmail/lib/SyncML/Device.php
+++ b/horde-webmail/lib/SyncML/Device.php
@@ -159,6 +159,8 @@ class SyncML_Device {
             SYNCML_LOGFILE_DATA,
             "\nInput received from client ($contentType):\n$content\n");
 
+        $content = $this->_completeEmptyAttributes($content, $contentType);
+
         // Always remove client UID. UID will be seperately passed in XML.
         $content = preg_replace('/(\r\n|\r|\n)UID:.*?(\r\n|\r|\n)/',
                                 '\1', $content, 1);
@@ -167,6 +169,73 @@ class SyncML_Device {
     }
 
     /**
+     * Complete any attributes that the client supports but did not
+     * provide. In case the user did delete an attribute on the client
+     * this action is required to indicate to the server that the
+     * attribute needs to be deleted. A completely missing attribute
+     * would be considered as "no change" by the server.
+     *
+     * @param string $content       The content to convert
+     * @param string $contentType   The contentType of the content
+     *
+     * @return string               The converted content
+     */
+    function _completeEmptyAttributes($content, $contentType)
+    {
+        
+        $di = $_SESSION['SyncML.state']->deviceInfo;
+
+        if (empty($di) || !isset($di->_CTCap) || !isset($di->_CTCap[$contentType])) {
+            return $content;
+        }
+
+        require_once 'Horde/iCalendar.php';
+        $iCal = new Horde_iCalendar();
+        if (!$iCal->parsevCalendar($content)) {
+            // We cant parse the content, return it unchanged
+            return $content;
+        }
+        $components = $iCal->getComponents();
+        $attributes = $di->_CTCap[$contentType];
+
+        foreach ($components as $component) {
+            foreach ($attributes as $name => $properties) {
+                if ($name == 'BEGIN' || $name == 'END') {
+                    continue;
+                }
+                $values = $component->getAllAttributes($name);
+                if (!isset($properties->_params)) {
+                    if (empty($values)) {
+                        // Undefined attribute -> replace it with
+                        // the correct empty value
+                        $component->setAttributeEmpty($name);
+                    }
+                } else {
+                    foreach ($properties->_params as $key => $property) {
+                        if (!empty($values)) {
+                            $present = true;
+                        } else {
+                            $present = false;
+                            foreach ($values as $value) {
+                                if (in_array($key, array_keys($value['params']))) {
+                                    $present = true;
+                                    break;
+                                }
+                            }
+                        }
+                        if (!$present) {
+                            // Undefined attribute -> replace it with
+                            // the correct empty value
+                            $component->setAttributeEmpty($name, array($key => null), true);
+                        }
+                    }
+                }
+            }
+        }
+        return $iCal->exportvCalendar();
+     }
+
+    /**
      * Converts the content from the backend to a format suitable for the
      * client device.
      *
diff --git a/horde-webmail/lib/SyncML/Sync.php b/horde-webmail/lib/SyncML/Sync.php
index 2342389..57e233b 100644
--- a/horde-webmail/lib/SyncML/Sync.php
+++ b/horde-webmail/lib/SyncML/Sync.php
@@ -283,7 +283,13 @@ class SyncML_Sync {
             }
         } elseif ($item->elementType == 'Delete') {
             /* Handle client delete requests. */
+            $duplicate = $backend->getConflict($hordedatabase, $cuid, $this->_serverAnchorLast);
             $ok = $backend->deleteEntry($database, $cuid);
+            $duplicated = false;
+            if ($duplicate) {
+                $duplicated = $backend->duplicateConflict($hordedatabase, $duplicate);
+            }
+
             if (!$ok && $tasksincalendar) {
                 $backend->logMessage(
                     'Task ' . $cuid . ' deletion sent with calendar request',
@@ -293,8 +299,14 @@ class SyncML_Sync {
 
             if ($ok) {
                 $this->_client_delete_count++;
-                $item->responseCode = RESPONSE_OK;
                 $backend->logMessage('Deleted entry ' . $suid . ' due to client request', __FILE__, __LINE__, PEAR_LOG_DEBUG);
+                if (!$duplicated) {
+                    $item->responseCode = RESPONSE_OK;
+                } else {
+                    $this->_client_add_count++;
+                    $backend->logMessage('Duplicated entry ' . $suid . ' due to client/server conflict', __FILE__, __LINE__, PEAR_LOG_INFO);
+                    $item->responseCode = RESPONSE_CONFLICT_RESOLVED_WITH_DUPLICATE;
+                }
             } else {
                 $this->_errors++;
                 $item->responseCode = RESPONSE_ITEM_NO_DELETED;
@@ -303,13 +315,24 @@ class SyncML_Sync {
 
         } elseif ($item->elementType == 'Replace') {
             /* Handle client replace requests. */
+            $duplicate = $backend->getConflict($hordedatabase, $cuid, $this->_serverAnchorLast);
             $suid = $backend->replaceEntry($hordedatabase, $content,
                                            $contentType, $cuid);
+            $duplicated = false;
+            if ($duplicate) {
+                $duplicated = $backend->duplicateConflict($hordedatabase, $duplicate);
+            }
 
             if (!is_a($suid, 'PEAR_Error')) {
                 $this->_client_replace_count++;
-                $item->responseCode = RESPONSE_OK;
                 $backend->logMessage('Replaced entry ' . $suid . ' due to client request', __FILE__, __LINE__, PEAR_LOG_DEBUG);
+                if (!$duplicated) {
+                    $item->responseCode = RESPONSE_OK;
+                } else {
+                    $this->_client_add_count++;
+                    $backend->logMessage('Duplicated entry ' . $suid . ' due to client/server conflict', __FILE__, __LINE__, PEAR_LOG_INFO);
+                    $item->responseCode = RESPONSE_CONFLICT_RESOLVED_WITH_DUPLICATE;
+                }
             } else {
                 $backend->logMessage($suid->message, __FILE__, __LINE__, PEAR_LOG_DEBUG);
 
-- 
tg: (6938161..) t/SyncML/HK/GW/CombinedFixes (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 3c12e523cdbac5e2d0c1add78fcb25f500af2877
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 18:22:13 2009 +0000

    Added patch release/HK-GW-SyncML.patch from the mercurial release queue.

--- NEW FILE: t_Text_Filter_SC_CH_Xss.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/Text/Filter/SC/CH/Xss

Fixes a potential security issue with Internet Explorer.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Text/Filter/xss.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Text/Filter/xss.php b/horde-webmail/lib/Horde/Text/Filter/xss.php
index 26ba9db..fbd60e2 100644
--- a/horde-webmail/lib/Horde/Text/Filter/xss.php
+++ b/horde-webmail/lib/Horde/Text/Filter/xss.php
@@ -193,7 +193,7 @@ class Text_Filter_xss extends Text_Filter {
         /* Comment out style/link tags. */
         if ($this->_params['strip_styles']) {
             if ($this->_params['strip_style_attributes']) {
-                $patterns['/\s+style\s*=/i'] = ' ' . $this->_params['replace'] . '=';
+                $patterns['/(\s+|([\'"]))style\s*=/i'] = '$2 ' . $this->_params['replace'] . '=';
             }
             $patterns['|<style[^>]*>(?:\s*<\!--)*|i'] = '<!--';
             $patterns['|(?:-->\s*)*</style>|i'] = '-->';
-- 
tg: (6938161..) t/Text/Filter/SC/CH/Xss (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 0138238299582204ebb0e613985378ee36cf6fc7
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 17:50:47 2009 +0000

    Added patch release/H-CH-Xss_fix.patch from the mercurial release queue.

--- NEW FILE: t_dimp_HK_GW_ItipHandling.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/dimp/HK/GW/ItipHandling

Allow handling iTip messages in dimp.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/dimp/imp.php                 |   23 +++++++
 horde-webmail/dimp/js/DimpBase.js          |   14 ++++
 horde-webmail/imp/lib/MIME/Viewer/itip.php |   98 ++++++++++++++++++++--------
 3 files changed, 108 insertions(+), 27 deletions(-)

diff --git a/horde-webmail/dimp/imp.php b/horde-webmail/dimp/imp.php
index f8b9b5c..70264fe 100644
--- a/horde-webmail/dimp/imp.php
+++ b/horde-webmail/dimp/imp.php
@@ -710,6 +710,29 @@ case 'SendMDN':
     $imp_ui = new IMP_UI_Message();
     $imp_ui->MDNCheck($ob->header, true);
     break;
+
+case 'iTip':
+    $selection = Util::getPost('selection');
+    $component = Util::getPost('component');
+    $action = str_replace('_', '-', $selection);
+    $_POST['action'] = array($component => $action);
+
+    if (empty($indices)) {
+        break;
+    }
+    $idx_string = _getIdxString($indices);
+
+    /* Parse MIME info and create the body of the message. */
+    require_once IMP_BASE . '/lib/MIME/Contents.php';
+    $imp_contents = &IMP_Contents::singleton($idx_string);
+
+    $cr = !$imp_contents->buildMessage();
+
+    if (is_a($cr, 'PEAR_Error')) {
+        $notification->push($cr, 'horde.error');
+    }
+
+    break;
 }
 
 // Clear the output buffer that we started above, and log any unexpected
diff --git a/horde-webmail/dimp/js/DimpBase.js b/horde-webmail/dimp/js/DimpBase.js
index 96cd917..39a728b 100644
--- a/horde-webmail/dimp/js/DimpBase.js
+++ b/horde-webmail/dimp/js/DimpBase.js
@@ -1663,6 +1663,20 @@ var DimpBase = {
         nf.setStyle({ height: (document.viewport.getHeight() - nf.cumulativeOffset()[1] - 10) + 'px' });
     },
 
+    itip: function(action, index, folder, component)
+    {
+        var args, vs;
+
+	vs = this.viewport.getViewportSelection().search({ imapuid: { equal: [ index ] }, view: { equal: [ folder ] } });
+	if (!vs.size() && folder != this.folder) {
+	    vs = this.viewport.getViewportSelection(folder).search({ imapuid: { equal: [ index ] } });
+	}
+
+	args = this.viewport.addRequestParams({ selection: action, component: component });
+
+	DimpCore.doAction('iTip', args, DimpCore.toUIDArray(vs));
+    },
+
     /* Flag actions for message list. */
     flag: function(action, index, folder)
     {
diff --git a/horde-webmail/imp/lib/MIME/Viewer/itip.php b/horde-webmail/imp/lib/MIME/Viewer/itip.php
index 1f8fe1e..e030413 100644
--- a/horde-webmail/imp/lib/MIME/Viewer/itip.php
+++ b/horde-webmail/imp/lib/MIME/Viewer/itip.php
@@ -122,7 +122,7 @@ class IMP_MIME_Viewer_itip extends MIME_Viewer {
                 break;
 
             case 'import':
-            case 'accept-import':
+            case 'acceptimport':
                 // vFreebusy reply.
                 // vFreebusy publish.
                 // vEvent request.
@@ -202,12 +202,12 @@ class IMP_MIME_Viewer_itip extends MIME_Viewer {
                     $this->_msgs[$key][] = array('warning', _("This action is not yet implemented."));
                 }
 
-                if ($action != 'accept-import') {
+                if ($action != 'acceptimport') {
                     break;
                 }
 
             case 'accept':
-            case 'accept-import':
+            case 'acceptimport':
             case 'deny':
             case 'tentative':
                 // vEvent request.
@@ -279,7 +279,7 @@ class IMP_MIME_Viewer_itip extends MIME_Viewer {
 
                     switch ($action) {
                     case 'accept':
-                    case 'accept-import':
+                    case 'acceptimport':
                         $message = sprintf(_("%s has accepted."), $name);
                         $subject = _("Accepted: ") . $vEvent->getAttribute('SUMMARY');
                         $params['PARTSTAT'] = 'ACCEPTED';
@@ -622,7 +622,7 @@ class IMP_MIME_Viewer_itip extends MIME_Viewer {
         case 'PUBLISH':
             $desc = _("%s wishes to make you aware of \"%s\".");
             if ($registry->hasMethod('calendar/import')) {
-                $options[] = '<option value="import">' .   _("Add this to my calendar") . '</option>';
+                $options['import'] = _("Add this to my calendar");
             }
             break;
 
@@ -655,35 +655,35 @@ class IMP_MIME_Viewer_itip extends MIME_Viewer {
                     : _("%s wishes to make you aware of \"%s\".");
             }
             if ($is_update && $registry->hasMethod('calendar/replace')) {
-                $options[] = '<option value="accept-import">' . _("Accept and update in my calendar") . '</option>';
-                $options[] = '<option value="import">' . _("Update in my calendar") . '</option>';
+                $options['acceptimport'] = _("Accept and update in my calendar");
+                $options['import'] = _("Update in my calendar");
             } elseif ($registry->hasMethod('calendar/import')) {
-                $options[] = '<option value="accept-import">' . _("Accept and add to my calendar") . '</option>';
-                $options[] = '<option value="import">' . _("Add to my calendar") . '</option>';
+                $options['acceptimport'] = _("Accept and add to my calendar");
+                $options['import'] = _("Add to my calendar");
             }
-            $options[] = '<option value="accept">' . _("Accept request") . '</option>';
-            $options[] = '<option value="tentative">' . _("Tentatively Accept request") . '</option>';
-            $options[] = '<option value="deny">' . _("Deny request") . '</option>';
-            // $options[] = '<option value="delegate">' . _("Delegate position") . '</option>';
+            $options['accept'] = _("Accept request");
+            $options['tentative'] = _("Tentatively Accept request");
+            $options['deny'] = _("Deny request");
+            // $options['delegate'] = _("Delegate position");
             break;
 
         case 'ADD':
             $desc = _("%s wishes to ammend \"%s\".");
             if ($registry->hasMethod('calendar/import')) {
-                $options[] = '<option value="import">' .   _("Update this event on my calendar") . '</option>';
+                $options['import'] = _("Update this event on my calendar");
             }
             break;
 
         case 'REFRESH':
             $desc = _("%s wishes to receive the latest information about \"%s\".");
-            $options[] = '<option value="send">' . _("Send Latest Information") . '</option>';
+            $options['send'] = _("Send Latest Information");
             break;
 
         case 'REPLY':
             $desc = _("%s has replied to the invitation to \"%s\".");
             $sender = $this->_headers->getValue('From');
             if ($registry->hasMethod('calendar/updateAttendee')) {
-                $options[] = '<option value="update">' . _("Update respondent status") . '</option>';
+                $options['update'] = _("Update respondent status");
             }
             break;
 
@@ -691,12 +691,12 @@ class IMP_MIME_Viewer_itip extends MIME_Viewer {
             if (is_a($instance = $vevent->getAttribute('RECURRENCE-ID'), 'PEAR_Error')) {
                 $desc = _("%s has cancelled \"%s\".");
                 if ($registry->hasMethod('calendar/delete')) {
-                    $options[] = '<option value="delete">' . _("Delete from my calendar") . '</option>';
+                    $options['delete'] = _("Delete from my calendar");
                 }
             } else {
                 $desc = _("%s has cancelled an instance of the recurring \"%s\".");
                 if ($registry->hasMethod('calendar/replace')) {
-                    $options[] = '<option value="import">' . _("Update in my calendar") . '</option>';
+                    $options['import'] = _("Update in my calendar");
                 }
             }
             break;
@@ -709,6 +709,36 @@ class IMP_MIME_Viewer_itip extends MIME_Viewer {
             $desc = sprintf($desc, htmlspecialchars($sender), htmlspecialchars($summary));
         }
 
+        if ($_SESSION['imp']['viewmode'] == 'dimp') {
+            require_once DIMP_BASE . '/lib/DIMP.php';
+
+            function _createMEntry($text, $image, $id, $class = '', $show_text = true, $app = null)
+            {
+                $params = array('icon' => $image, 'id' => $id, 'class' => $class);
+                if ($show_text) {
+                    $params['title'] = $text;
+                } else {
+                    $params['tooltip'] = $text;
+                }
+                if (isset($app)) {
+                    $params['app'] = $app;
+                }
+                return DIMP::actionButton($params);
+            }
+
+            $script = 'if (DIMP.baseWindow) {var B = DIMP.baseWindow.DimpBase;} else {B = DimpBase;};DimpCore.addMouseEvents({ id: \'button_invitation_cont\', type: \'itippopdown\', offset: \'button_invitation_cont\', left: true});';
+	    $script .= '[ \'acceptimport\', \'import\', \'accept\', \'tentative\', \'deny\', \'update\', \'send\' ].each(function(a) {var d = $(\'ctx_itippopdown_\' + a); if (d) { DimpCore.clickObserveHandler({ d: d, f: function(a) { B.itip(a, DIMP.conf.msg_index, DIMP.conf.msg_folder, ' . $id . '); window.close(); }.curry(a) })}})';
+
+            $html .= '<div><span id="button_invitation_cont">' . _createMEntry(_("Invitation"), 'kronolith.png', 'button_invitation', 'hasmenu', true, 'kronolith') . Horde::img('popdown.png', '', array(), $GLOBALS['registry']->getImageDir('dimp')) . '</span></div><p/><script type="text/javascript">' . $script . '</script>';
+
+            if ($this->_msgs) {
+                global $notification;
+                foreach ($this->_msgs[$id] as $msg) {
+                    $notification->push($msg[1], 'horde.' . $msg[0]);
+                }
+            }
+        }
+
         $html .= '<h2 class="header">' . $desc . '</h2>';
 
         if ($this->_msgs) {
@@ -796,16 +826,30 @@ class IMP_MIME_Viewer_itip extends MIME_Viewer {
             $html .= '</tbody></table>';
         }
 
-        if ($_SESSION['imp']['viewmode'] != 'imp') {
-            return $html;
-        }
-
         if ($options) {
-            $html .= '<h2 class="smallheader">' . _("Actions") . '</h2>' .
-                '<label for="action_' . $id . '" class="hidden">' . _("Actions") . '</label>' .
-                '<select id="action_' . $id . '" name="action[' . $id . ']">' .
-                implode("\n", $options) .
-                '</select> <input type="submit" class="button" value="' . _("Go") . '" />';
+
+            if ($_SESSION['imp']['viewmode'] == 'imp') {
+
+                $html .= '<h2 class="smallheader">' . _("Actions") . '</h2>' .
+                    '<label for="action_' . $id . '" class="hidden">' . _("Actions") . '</label>' .
+                    '<select id="action_' . $id . '" name="action[' . $id . ']">';
+
+                foreach ($options as $key => $description) {
+                    $html .= '<option value="' . $key .'">' . $description . "</option>\n";
+                }
+
+                $html .= '</select> <input type="submit" class="button" value="' . _("Go") . '" />';
+
+            } else if ($_SESSION['imp']['viewmode'] == 'dimp') {
+
+                $html .= '<div class="context" id="ctx_itippopdown">';
+
+                foreach ($options as $key => $description) {
+                    $html .= '<div>' . _createMEntry($description, 'kronolith.png', 'ctx_itippopdown_' . $key, '', true, 'kronolith') . '</div>';
+                }
+
+                $html .= '</div>';
+            }
         }
 
         return $html;
-- 
tg: (667dce6..) t/dimp/HK/GW/ItipHandling (depends on: master t/dimp/H/MS/FixBrokenFolderImages)
-- 
TOPGIT patch commit log
=======================

commit 2650c064ee6792752d58f6b1b974c05383ea80e7
Author: root <root at domU-12-31-38-01-B8-13.compute-1.amazonaws.com>
Date:   Fri Feb 20 14:52:48 2009 +0000

    Fixed accept import and moved script initialization from onmouseover event.

commit ea8089c0665f52fb45c90993d85bef7c6ac40ee8
Author: root <root at ec2-174-129-182-10.compute-1.amazonaws.com>
Date:   Fri Feb 20 10:03:43 2009 +0000

    Handle all available options.

commit e964c911e211a203a85f020748679fcb0fc63703
Author: root <root at domU-12-31-38-01-B8-13.compute-1.amazonaws.com>
Date:   Fri Feb 20 04:26:45 2009 +0000

    Remove stray config file.

commit b283064e483d73c9be827a58eba57ec149a4731d
Author: Gunnar Wrobel <p at rdus.de>
Date:   Mon Feb 9 08:13:32 2009 +0000

    Complete the iTip handling in IMP (draft version).

commit a72190bb95b05e4a3dd78238a4c3d95ba0a968a7
Author: Gunnar Wrobel <p at rdus.de>
Date:   Mon Feb 9 08:12:05 2009 +0000

    New TopGit dependency: t/dimp/H/MS/FixBrokenFolderImages

commit debda05a3fc8546913ce79e9c1cf36e72bda6e97
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 8 22:46:26 2009 +0000

    Started patching dimp for iTip handling.

--- NEW FILE: t_dimp_H_MS_FixBrokenFolderImages.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/dimp/H/MS/FixBrokenFolderImages

Fixes broken custom folder images within DIMP.

http://bugs.horde.org/ticket/7831

https://www.intevation.de/roundup/kolab/issue3328

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/dimp/js/DimpBase.js     | 2149 ++++++++++++++++++++++++++++++++-
 horde-webmail/dimp/js/src/DimpBase.js |    2 +-
 horde-webmail/dimp/lib/DIMP.php       |    9 +-
 horde-webmail/dimp/themes/screen.css  |    2 +-
 4 files changed, 2157 insertions(+), 5 deletions(-)

diff --git a/horde-webmail/dimp/js/DimpBase.js b/horde-webmail/dimp/js/DimpBase.js
[...2197 lines suppressed...]
     display: inline;
     float: left;
     width: 20px;
-- 
tg: (6938161..) t/dimp/H/MS/FixBrokenFolderImages (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 12a42ba2183476ce329b567490ff5013727d8a39
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sat Feb 7 23:54:51 2009 +0000

    Fix the style name.

commit 8588d2b184f6244655c219104b4d8119f0ea4644
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sat Feb 7 18:43:00 2009 +0000

     kolab/issue3328 ([Webclient] DIMP groupware folder names display bug)

--- NEW FILE: t_framework_HK_GW_Auth_InvalidCheck.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Auth/InvalidCheck

Remove an obsolete check.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Auth/kolab.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Auth/kolab.php b/horde-webmail/lib/Horde/Auth/kolab.php
index ae846c8..7fbc55b 100644
--- a/horde-webmail/lib/Horde/Auth/kolab.php
+++ b/horde-webmail/lib/Horde/Auth/kolab.php
@@ -101,7 +101,7 @@ class Auth_kolab extends Auth {
 
             $max_count = $conf['auth']['params']['login_block_count'];
 
-            if ($count > $max_count || !$login_ok) {
+            if ($count > $max_count) {
                 // Add entry for current failed login.
                 $entry = array();
                 $entry[ 'timestamp' ] = time();
-- 
tg: (493930b..) t/framework/HK/GW/Auth/InvalidCheck (depends on: t/framework/HK/GW/Kolab_Server/RequireIMAP)
-- 
TOPGIT patch commit log
=======================

commit c01dce5512d9422c0a2aa907b6201f65ba2330db
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sat Jan 31 00:06:59 2009 +0000

    Added patch framework/HK-GW-Auth-Typo_fix.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Auth_ListUsers.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Auth/ListUsers

Implement listing users in the Kolab Auth driver.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Auth/kolab.php |   33 ++++++++++++++++++++++++++++++++
 1 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/horde-webmail/lib/Horde/Auth/kolab.php b/horde-webmail/lib/Horde/Auth/kolab.php
index 55dcb6e..235e72a 100644
--- a/horde-webmail/lib/Horde/Auth/kolab.php
+++ b/horde-webmail/lib/Horde/Auth/kolab.php
@@ -21,6 +21,18 @@ require_once 'Horde/Auth/imap.php';
 class Auth_kolab extends Auth_imap {
 
     /**
+     * An array of capabilities, so that the driver can report which
+     * operations it supports and which it doesn't.
+     *
+     * @var array
+     */
+    var $capabilities = array('add'           => false,
+                              'update'        => false,
+                              'resetpassword' => false,
+                              'remove'        => false,
+                              'list'          => true,
+                              'transparent'   => false);
+    /**
      * Find out if a set of login credentials are valid.
      *
      * @access private
@@ -148,4 +160,25 @@ class Auth_kolab extends Auth_imap {
         return parent::setAuth($userId, $credentials, $realm, $changeRequested);
     }
 
+    /**
+     * List Users
+     *
+     * @return array  List of Users
+     */
+    function listUsers()
+    {
+        @include_once 'Horde/Kolab/Server.php';
+
+        if (class_exists('Horde_Kolab_Server')) {
+            $server = Horde_Kolab_Server::singleton();
+            $users = $server->listObjects(KOLAB_OBJECT_USER);
+            $mails = array();
+            foreach ($users as $user) {
+                $mails[] = $user->get(KOLAB_ATTR_MAIL);
+            }
+            return $mails;
+        } else {
+            return PEAR::raiseError("The class \"Horde_Kolab_Server\" is not available.");
+        }
+    }
 }
-- 
tg: (d75006c..) t/framework/HK/GW/Auth/ListUsers (depends on: t/framework/HK/GW/Kolab_Server/ListObjects)
-- 
TOPGIT patch commit log
=======================

commit 4bb7043665e636375b842317dfd6f8685ba4c5ac
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 23:21:05 2009 +0000

    Removed patch remains.

commit d84a437b9d2acb9fdca37070a5c22ff5d7d69934
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 22:48:42 2009 +0000

    Added patch release/HK-GW-Auth-KolabUserList.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Auth_SafetyCheck.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Auth/SafetyCheck

A tiny safety check.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Auth/kolab.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Auth/kolab.php b/horde-webmail/lib/Horde/Auth/kolab.php
index b790c1e..ae846c8 100644
--- a/horde-webmail/lib/Horde/Auth/kolab.php
+++ b/horde-webmail/lib/Horde/Auth/kolab.php
@@ -60,7 +60,7 @@ class Auth_kolab extends Auth {
             return false;
         }
 
-        if ($conf['auth']['params']['login_block'] != 1) {
+        if (!isset($conf['auth']['params']) || $conf['auth']['params']['login_block'] != 1) {
             // Return if feature is disabled.
             return $session->auth;
         }
-- 
tg: (a71d158..) t/framework/HK/GW/Auth/SafetyCheck (depends on: t/framework/HK/GW/Kolab/MoveIMAP)
-- 
TOPGIT patch commit log
=======================

commit 1b1b2443155c09a313726728cc3eda6dc01b3bb6
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 23:33:46 2009 +0000

    Added patch /release/HK-GW-Kolab_Freebusy-Use_new_Kolab_Server.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Auth_UseKolabServer.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Auth/UseKolabServer

Support adding users and switch over to using Kolab_Server (and LDAP).

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Auth/kolab.php        |   71 +++++++++++++++++--------
 horde-webmail/lib/Horde/Kolab/Server/test.php |    7 ++-
 horde-webmail/lib/Horde/Kolab/Session.php     |    7 +--
 3 files changed, 57 insertions(+), 28 deletions(-)

diff --git a/horde-webmail/lib/Horde/Auth/kolab.php b/horde-webmail/lib/Horde/Auth/kolab.php
index 235e72a..b790c1e 100644
--- a/horde-webmail/lib/Horde/Auth/kolab.php
+++ b/horde-webmail/lib/Horde/Auth/kolab.php
@@ -1,7 +1,5 @@
 <?php
 
-require_once 'Horde/Auth/imap.php';
-
 /**
  * Kolab implementation of the Horde authentication system. Derives from the
  * Auth_imap IMAP authentication object, and simply provides parameters to it
@@ -18,7 +16,7 @@ require_once 'Horde/Auth/imap.php';
  * @since   Horde 1.3
  * @package Horde_Auth
  */
-class Auth_kolab extends Auth_imap {
+class Auth_kolab extends Auth {
 
     /**
      * An array of capabilities, so that the driver can report which
@@ -26,7 +24,7 @@ class Auth_kolab extends Auth_imap {
      *
      * @var array
      */
-    var $capabilities = array('add'           => false,
+    var $capabilities = array('add'           => true,
                               'update'        => false,
                               'resetpassword' => false,
                               'remove'        => false,
@@ -39,7 +37,7 @@ class Auth_kolab extends Auth_imap {
      *
      * @param string $userId      The userId to check.
      * @param array $credentials  An array of login credentials. For Kolab,
-     *                            this must contain a password entry.
+     *                            this must contain a "password" entry.
      *
      * @return boolean  Whether or not the credentials are valid.
      */
@@ -52,12 +50,9 @@ class Auth_kolab extends Auth_imap {
         @include_once 'Horde/Kolab/Session.php';
 
         if (class_exists('Horde_Kolab_Session')) {
-            $session = &Horde_Kolab_Session::singleton($userId);
-            $userId = $session->user_mail;
-            $params = $session->getImapParams();
-            if (is_a($params, 'PEAR_Error')) {
-                $this->_setAuthError(AUTH_REASON_MESSAGE, $params->getMessage());
-                return false;
+            $session = &Horde_Kolab_Session::singleton($userId, $credentials, true);
+            if (is_a($session->auth, 'PEAR_Error')) {
+                $this->_setAuthError(AUTH_REASON_MESSAGE, $session->auth->getMessage());
             }
         } else {
             $this->_setAuthError(AUTH_REASON_MESSAGE,
@@ -65,18 +60,14 @@ class Auth_kolab extends Auth_imap {
             return false;
         }
 
-        $this->_setParams($params);
-
-        $login_ok = parent::_authenticate($userId, $credentials);
-
         if ($conf['auth']['params']['login_block'] != 1) {
             // Return if feature is disabled.
-            return $login_ok;
+            return $session->auth;
         }
 
         @include_once 'Horde/History.php';
 
-        if (class_exists('Horde_History')) {
+        if ($session->auth !== true && class_exists('Horde_History')) {
             $history = &Horde_History::singleton();
 
             $history_identifier = "$userId at logins.kolab";
@@ -132,7 +123,7 @@ class Auth_kolab extends Auth_imap {
             }
         }
 
-        return $login_ok;
+        return $session->auth === true;
     }
 
     /**
@@ -167,10 +158,14 @@ class Auth_kolab extends Auth_imap {
      */
     function listUsers()
     {
-        @include_once 'Horde/Kolab/Server.php';
+        @include_once 'Horde/Kolab/Session.php';
 
-        if (class_exists('Horde_Kolab_Server')) {
-            $server = Horde_Kolab_Server::singleton();
+        if (class_exists('Horde_Kolab_Session')) {
+            $session = &Horde_Kolab_Session::singleton();
+            $server = $session->getServer();
+            if (is_a($server, 'PEAR_Error')) {
+                return $server;
+            }
             $users = $server->listObjects(KOLAB_OBJECT_USER);
             $mails = array();
             foreach ($users as $user) {
@@ -178,7 +173,39 @@ class Auth_kolab extends Auth_imap {
             }
             return $mails;
         } else {
-            return PEAR::raiseError("The class \"Horde_Kolab_Server\" is not available.");
+            return PEAR::raiseError("The class \"Horde_Kolab_Session\" is not available.");
+        }
+    }
+
+    /**
+     * Add a set of authentication credentials.
+     *
+     * @param string $userId      The userId to add.
+     * @param array $credentials  The credentials to be set.
+     *
+     * @return boolean|PEAR_Error  True on success.
+     */
+    function addUser($userId, $credentials)
+    {
+        @include_once 'Horde/Kolab/Session.php';
+
+        if (class_exists('Horde_Kolab_Session')) {
+            $session = &Horde_Kolab_Session::singleton();
+            $server = $session->getServer();
+            if (is_a($server, 'PEAR_Error')) {
+                return $server;
+            }
+            $result = $server->store(KOLAB_OBJECT_USER, $userId, $credentials);
+            if (is_a($result, KOLAB_OBJECT_USER)) {
+                return true;
+            } else if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            } else {
+                return PEAR::raiseError(sprintf('The new Kolab object is a %s rather than a ' . KOLAB_OBJECT_USER,
+                                                get_class($result)));
+            }
+        } else {
+            return PEAR::raiseError("The class \"Horde_Kolab_Session\" is not available.");
         }
     }
 }
diff --git a/horde-webmail/lib/Horde/Kolab/Server/test.php b/horde-webmail/lib/Horde/Kolab/Server/test.php
index 6f8a237..6565bbc 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/test.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/test.php
@@ -125,21 +125,24 @@ class Horde_Kolab_Server_test extends Horde_Kolab_Server_ldap {
 
             $data = $this->_read($dn, $attrs = array('userPassword'));
             if (is_a($data, 'PEAR_Error')) {
+                $this->_bound = false;
                 return $data;
             }
             if (!isset($data['userPassword'])) {
+                $this->_bound = false;
                 return PEAR::raiseError('User has no password entry!');
             }
-            $this->_bound = $data['userPassword'][0] = $pw;
+            $this->_bound = $data['userPassword'][0] == $pw;
             if (!$this->_bound) {
                 return PEAR::raiseError('Incorrect password!');
             }
         } else if ($this->_params['no_anonymous_bind']) {
+            $this->_bound = false;
             return PEAR::raiseError('Anonymous bind is not allowed!');
         } else {
             $this->_bound = true;
         }
-        return true;
+        return $this->_bound;
     }
 
     /**
diff --git a/horde-webmail/lib/Horde/Kolab/Session.php b/horde-webmail/lib/Horde/Kolab/Session.php
index 7c73496..616b285 100644
--- a/horde-webmail/lib/Horde/Kolab/Session.php
+++ b/horde-webmail/lib/Horde/Kolab/Session.php
@@ -129,7 +129,7 @@ class Horde_Kolab_Session {
                         $this->user_mail = $result;
                     }
 
-                    $result = $user_object->get(KOLAB_ATTR_UID);
+                    $result = $user_object->get(KOLAB_ATTR_SID);
                     if (!empty($result) && !is_a($result, 'PEAR_Error')) {
                         $this->user_id = $result;
                     }
@@ -209,7 +209,6 @@ class Horde_Kolab_Session {
                 $params['pass'] = $credentials['password'];
             }
         }
-
         return Horde_Kolab_Server::singleton($params);
     }
 
@@ -242,7 +241,7 @@ class Horde_Kolab_Session {
      *
      * @return Horde_Kolab_Session  The concrete Session reference.
      */
-    function &singleton($user = null, $credentials = null)
+    function &singleton($user = null, $credentials = null, $destruct = false)
     {
         static $session;
 
@@ -258,7 +257,7 @@ class Horde_Kolab_Session {
             $session = $hs->query('kolab_session');
         }
 
-        if (empty($session)
+        if ($destruct || empty($session)
             || (!empty($user) &&  $user != $session->user_mail
                 && $user != $session->user_id)) {
             $session = new Horde_Kolab_Session($user, $credentials);
-- 
tg: (a00ff66..) t/framework/HK/GW/Auth/UseKolabServer (depends on: t/framework/HK/GW/Kolab_Storage/CatchPossibleError)
-- 
TOPGIT patch commit log
=======================

commit a92d02c65183a8af5418101133be2c8df95e705a
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 23:20:41 2009 +0000

    Added patch release/HK-GW-Auth-Use_Kolab_Server.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Auth_UseSession.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Auth/UseSession

Switches Kolab authentication to use the Kolab_Session handler.
This effectively switches from IMAP based authentication to LDAP 
based authentication.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Auth/kolab.php |  130 +++++++-------------------------
 1 files changed, 28 insertions(+), 102 deletions(-)

diff --git a/horde-webmail/lib/Horde/Auth/kolab.php b/horde-webmail/lib/Horde/Auth/kolab.php
index fda2d9b..55dcb6e 100644
--- a/horde-webmail/lib/Horde/Auth/kolab.php
+++ b/horde-webmail/lib/Horde/Auth/kolab.php
@@ -21,18 +21,6 @@ require_once 'Horde/Auth/imap.php';
 class Auth_kolab extends Auth_imap {
 
     /**
-     * Constructs a new Kolab authentication object.
-     *
-     * @param array $params  A hash containing connection parameters.
-     */
-    function Auth_kolab($params = array())
-    {
-        $params['protocol'] = 'imap/notls/novalidate-cert';
-
-        parent::Auth_imap($params);
-    }
-
-    /**
      * Find out if a set of login credentials are valid.
      *
      * @access private
@@ -47,17 +35,26 @@ class Auth_kolab extends Auth_imap {
     {
         global $conf;
 
-        /**
-         * Determine the IMAP server for the user and update the
-         * connection parameters */
-        $result = $this->_getImapServer($userId);
-        if (is_a($result, 'PEAR_Error')) {
-            $this->_setAuthError(AUTH_REASON_MESSAGE, $result->getMessage());
-            return false;
+        $params = array();
+
+        @include_once 'Horde/Kolab/Session.php';
+
+        if (class_exists('Horde_Kolab_Session')) {
+            $session = &Horde_Kolab_Session::singleton($userId);
+            $userId = $session->user_mail;
+            $params = $session->getImapParams();
+            if (is_a($params, 'PEAR_Error')) {
+                $this->_setAuthError(AUTH_REASON_MESSAGE, $params->getMessage());
+                return false;
+            }
         } else {
-            $this->_setParams($result);
+            $this->_setAuthError(AUTH_REASON_MESSAGE,
+                                 'The class Horde_Kolab_Session is required for the Kolab auth driver but it is missing!');
+            return false;
         }
 
+        $this->_setParams($params);
+
         $login_ok = parent::_authenticate($userId, $credentials);
 
         if ($conf['auth']['params']['login_block'] != 1) {
@@ -108,11 +105,13 @@ class Auth_kolab extends Auth_imap {
                 $new_history_list[] = $entry;
 
                 // Write back history.
-                $history->log($history_identifier, array('action' => 'add', 'who' => $userId,
-                                                         'history_list' => $new_history_list), true);
+                $history->log($history_identifier,
+                              array('action' => 'add', 'who' => $userId,
+                                    'history_list' => $new_history_list), true);
 
                 if ($count > $max_count) {
-                    $this->_setAuthError(AUTH_REASON_MESSAGE, _("Too many invalid logins during the last minutes."));
+                    $this->_setAuthError(AUTH_REASON_MESSAGE,
+                                         _("Too many invalid logins during the last minutes."));
                 } else {
                     $this->_setAuthError(AUTH_REASON_BADLOGIN);
                 }
@@ -125,73 +124,11 @@ class Auth_kolab extends Auth_imap {
     }
 
     /**
-     * Identify the IMAP server we should authenticate against.
-     *
-     * @access private
-     *
-     * @param string $userId      The userId to check.
-     * @param array $credentials  An array of login credentials. For Kolab,
-     *                            this must contain a password entry.
-     *
-     * @return boolean  Whether or not the credentials are valid.
-     */
-    function _getImapServer($userId)
-    {
-        $params = array();
-
-        @include_once 'Horde/Kolab/Server.php';
-
-        if (class_exists('Horde_Kolab_Server')) {
-            $db = Horde_Kolab_Server::singleton();
-            if (is_a($db, 'PEAR_Error')) {
-                return $db;
-            }
-            $dn = $db->dnForUidOrMail($userId);
-            if (is_a($dn, 'PEAR_Error')) {
-                return $dn;
-            }
-            $user = $db->fetch($dn);
-            if (is_a($user, 'PEAR_Error')) {
-                return $user;
-            }
-
-            global $conf;
-
-            if (empty($conf['kolab']['misc']['allow_special'])
-                && !is_a($user, 'Horde_Kolab_Server_Object_user')) {
-                return PEAR::raiseError(_('User is not a standard Kolab user.'));
-            }
-            $result = $user->getServer('imap');
-            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
-                $server = explode(':', $result, 2);
-                if (!empty($server[0])) {
-                    $params['hostspec'] = $server[0];
-                }
-                if (!empty($server[1])) {
-                    $params['port'] = $server[1];
-                }
-            }
-        }
-
-        if (empty($params['hostspec'])
-            && isset($conf['kolab']['imap']['server'])) {
-            $params['hostspec'] = $conf['kolab']['imap']['server'];
-        }
-
-        if (!isset($params['port'])
-            && isset($conf['kolab']['imap']['port'])) {
-            $params['port'] = $conf['kolab']['imap']['port'];
-        }
-
-        return $params;
-    }
-    
-    /**
      * Sets a variable in the session saying that authorization has succeeded,
      * note which userId was authorized, and note when the login took place.
      *
      * The kolab driver rewrites UIDs into the correct mail addresses that
-     * need to be used to log into the system.
+     * need to be used to log into the IMAP server.
      *
      * @param string $userId            The userId who has been authorized.
      * @param array $credentials        The credentials of the user.
@@ -201,22 +138,11 @@ class Auth_kolab extends Auth_imap {
      */
     function setAuth($userId, $credentials, $realm = null, $changeRequested = false)
     {
-        @include_once 'Horde/Kolab/Server.php';
-
-        if (class_exists('Horde_Kolab_Server')) {
-            $db = Horde_Kolab_Server::singleton();
-            if (!is_a($db, 'PEAR_Error')) {
-                $userMail = $db->mailForUidOrMail($userId);
-                if (is_a($userMail, 'PEAR_Error')) {
-                    Horde::logMessage(sprintf("Error while fetching the Kolab ID: %s",
-                                              $userMail->getMessage()),
-                                      __FILE__, __LINE__, PEAR_LOG_ERR);
-                } else {
-                    if (!empty($userMail)) {
-                        $userId = $userMail;
-                    }
-                }
-            }
+        @include_once 'Horde/Kolab/Session.php';
+
+        if (class_exists('Horde_Kolab_Session')) {
+            $session = &Horde_Kolab_Session::singleton($userId);
+            $userId = $session->user_mail;
         }
 
         return parent::setAuth($userId, $credentials, $realm, $changeRequested);
-- 
tg: (ef1f7b1..) t/framework/HK/GW/Auth/UseSession (depends on: t/framework/HK/GW/Kolab_Server/Session)
-- 
TOPGIT patch commit log
=======================

commit 6b1cf18d426950b48f589787255085f2deed89a2
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 20:30:29 2009 +0000

    Added patch release/HK-GW-Auth-SessionMove.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_DB_SqliteErrorChecking.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/DB/SqliteErrorChecking

Fix error checking in the sqlite PEAR implementation.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/pear/DB/sqlite.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/pear/DB/sqlite.php b/horde-webmail/pear/DB/sqlite.php
index bf2acec..00e65f4 100644
--- a/horde-webmail/pear/DB/sqlite.php
+++ b/horde-webmail/pear/DB/sqlite.php
@@ -742,7 +742,7 @@ class DB_sqlite extends DB_common
         
         // PHP 5.2+ prepends the function name to $php_errormsg, so we need
         // this hack to work around it, per bug #9599.
-        $errormsg = preg_replace('/^sqlite[a-z_]+\(\): /', '', $errormsg);
+        $errormsg = preg_replace('/^sqlite[a-z_]+\(\) \[[^\]]*\]: /', '', $errormsg);
         
         if (!isset($error_regexps)) {
             $error_regexps = array(
-- 
tg: (018dab9..) t/framework/HK/GW/DB/SqliteErrorChecking (depends on: t/framework/HK/GW/Kolab/XfbFixes)
-- 
TOPGIT patch commit log
=======================

commit 1dd36cf01fd707c95af690339799bc5ce73a05c0
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:52:24 2009 +0000

    Added patch release/HK-GW-DB_sqlite-Incorrect_error_check.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab_AttachmentSupport.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab/AttachmentSupport

Attachment support as specified in the Kolab format.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Format/XML.php     |   51 +++++-
 horde-webmail/lib/Horde/Kolab/Storage/Cache.php  |   25 +++
 horde-webmail/lib/Horde/Kolab/Storage/Data.php   |   70 +++++--
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |  229 ++++++++++++++++------
 4 files changed, 294 insertions(+), 81 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML.php b/horde-webmail/lib/Horde/Kolab/Format/XML.php
index d3d7def..f225477 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML.php
@@ -117,11 +117,18 @@ class Horde_Kolab_Format_XML
     var $_version = 1;
 
     /**
+     * The name of the resulting document.
+     *
+     * @var string
+     */
+    var $_name = 'kolab.xml';
+
+    /**
      * The XML document this driver works with.
      *
      * @var Horde_DOM_Document
      */
-    var $_xmldoc = null;
+        var $_xmldoc = null;
 
     /**
      * The name of the root element.
@@ -319,12 +326,20 @@ class Horde_Kolab_Format_XML
                 'default' => 'public',
             ),
             'inline-attachment' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
+                'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
                 'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+                'array'   => array(
+                    'type'  => HORDE_KOLAB_XML_TYPE_STRING,
+                    'value' => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+                ),
             ),
             'link-attachment' => array(
-                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
+                'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
                 'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+                'array'   => array(
+                    'type'  => HORDE_KOLAB_XML_TYPE_STRING,
+                    'value' => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+                ),
             ),
             'product-id' => array(
                 'type'    => HORDE_KOLAB_XML_TYPE_STRING,
@@ -362,6 +377,36 @@ class Horde_Kolab_Format_XML
     }
 
     /**
+     * Return the name of the resulting document.
+     *
+     * @return string The name that may be used as filename.
+     */
+    function getName()
+    {
+        return $this->_name;
+    }
+
+    /**
+     * Return the mime type of the resulting document.
+     *
+     * @return string The mime type of the result.
+     */
+    function getMimeType()
+    {
+        return 'application/x-vnd.kolab.' . $this->_root_name;
+    }
+
+    /**
+     * Return the disposition of the resulting document.
+     *
+     * @return string The disportion of this document.
+     */
+    function getDisposition()
+    {
+        return 'attachment';
+    }
+
+    /**
      * Load an object based on the given XML string.
      *
      * @param string $xmltext  The XML of the message as string.
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Cache.php b/horde-webmail/lib/Horde/Kolab/Storage/Cache.php
index f2bed55..908a5d8 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Cache.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Cache.php
@@ -187,6 +187,31 @@ class Kolab_Cache {
     }
 
     /**
+     * Load a cached attachment.
+     *
+     * @param string $key          Access key to the cached data.
+     *
+     * @return mixed The data of the object.
+     */
+    function loadAttachment($key)
+    {
+        return $this->_horde_cache->get($key, 0);
+    }
+
+    /**
+     * Cache an attachment.
+     *
+     * @param string $key  Access key to the cached data.
+     * @param string $data The data to be cached.
+     *
+     * @return boolean True if successfull.
+     */
+    function storeAttachment($key, $data)
+    {
+        return $this->_horde_cache->set($key, $data);
+    }
+
+    /**
      * Initialize the cache structure.
      */
     function reset()
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Data.php b/horde-webmail/lib/Horde/Kolab/Storage/Data.php
index 4e3b39c..472a131 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Data.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Data.php
@@ -48,14 +48,6 @@ class Kolab_Data {
     var $_object_type;
 
     /**
-     * The full mime type string of the current Kolab object format we're
-     * dealing with.
-     *
-     * @var string
-     */
-    var $_mime_type;
-
-    /**
      * The version of the data.
      *
      * @var int
@@ -108,8 +100,6 @@ class Kolab_Data {
         }
         $this->_data_version = $data_version;
 
-        $this->_mime_type = 'application/x-vnd.kolab.' . $this->_object_type;
-
         if ($this->_object_type != $this->_type) {
             $this->_type_key = '@' . $this->_object_type;
         } else {
@@ -286,12 +276,6 @@ class Kolab_Data {
      */
     function save($object, $old_object_id = null)
     {
-        $handler = Horde_Kolab_Format::factory('XML', $this->_object_type,
-                                               $this->_data_version);
-        if (is_a($handler, 'PEAR_Error')) {
-            return $handler;
-        }
-
         // update existing kolab object
         if ($old_object_id != null) {
             // check if object really exists
@@ -306,12 +290,15 @@ class Kolab_Data {
                 return PEAR::raiseError(sprintf(_("Old object %s does not map to a uid."),
                                                 $old_object_id));
             }
+
+            $old_object = $this->getObject($old_object_id);
         } else {
             $id = null;
+            $old_object = null;
         }
 
-        $result = $this->_folder->saveObject($object, $handler, $this->_object_type,
-                                             $this->_mime_type, $id);
+        $result = $this->_folder->saveObject($object, $this->_data_version,
+                                             $this->_object_type, $id, $old_object);
         if (is_a($result, 'PEAR_Error')) {
             return $result;
         }
@@ -346,6 +333,8 @@ class Kolab_Data {
 
             $recent_uids = array_diff($ids, array_keys($this->_cache->uids));
 
+            $formats = $this->_folder->getFormats();
+
             $handler = Horde_Kolab_Format::factory('XML', $this->_object_type, $this->_data_version);
             if (is_a($handler, 'PEAR_Error')) {
                 return $handler;
@@ -358,7 +347,13 @@ class Kolab_Data {
                     continue;
                 }
 
-                $text = $this->_folder->fetch($id, $this->_mime_type);
+                $mime = $this->_folder->parseMessage($id, $handler->getMimeType(), false);
+                if (is_a($mime, 'PEAR_Error')) {
+                    Horde::logMessage($text, __FILE__, __LINE__, PEAR_LOG_WARNING);
+                    $text = false;
+                } else {
+                    $text = $mime[0];
+                }
 
                 if ($text) {
                     $object = $handler->load($text);
@@ -373,6 +368,31 @@ class Kolab_Data {
                 }
 
                 if ($object !== false) {
+                    $message = &$mime[2];
+                    $handler_type = $handler->getMimeType();
+                    foreach ($message->getParts() as $part) {
+                        $name = $part->getName();
+                        $type = $part->getType();
+                        $dp   = $part->getDispositionParameter('x-kolab-type');
+                        if (!empty($name) && $type != $handler_type
+                            || (!empty($dp) && in_array($dp, $formats))) {
+                            $object['_attachments'][$name]['type'] = $type;
+                            $object['_attachments'][$name]['key'] = $this->_cache_key . '/' . $object['uid'] . ':' . $name;
+                            $part->transferDecodeContents();
+                            $result = $this->_cache->storeAttachment($object['_attachments'][$name]['key'],
+                                                                     $part->getContents());
+                            if (is_a($result, 'PEAR_Error')) {
+                                Horde::logMessage(sprintf('Failed storing attachment of object %s: %s',
+                                                          $id, $result->getMessage()),
+                                                  __FILE__, __LINE__, PEAR_LOG_ERR);
+                                $object = false;
+                                break;
+                            }
+                        }
+                    }
+                }
+
+                if ($object !== false) {
                     $this->_cache->store($id, $object['uid'], $object);
                     $mod_ts = time();
                     if (is_array($changes) && in_array($object['uid'], $changes)
@@ -577,6 +597,18 @@ class Kolab_Data {
     }
 
     /**
+     * Return the specified attachment.
+     *
+     * @param string     $attachment_id       The attachment id.
+     *
+     * @return string|PEAR_Error  The attachment data as a string.
+     */
+    function getAttachment($attachment_id)
+    {
+        return $this->_cache->loadAttachment($attachment_id);
+    }
+
+    /**
      * Retrieve all object ids in the current folder.
      *
      * @return array  The object ids.
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index f1fd7e7..ddcfbe8 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -307,7 +307,7 @@ class Kolab_Folder {
 
             if (isset($attributes['type'])) {
                 if ($attributes['type'] != $type) {
-                    Horde::logMessage(sprintf("Cannot modify the type of a folder from %s to %s!",
+                    Horde::logMessage(sprintf('Cannot modify the type of a folder from %s to %s!',
                                               $type, $attributes['type']),
                                       __FILE__, __LINE__, PEAR_LOG_ERR);
                 }
@@ -352,7 +352,7 @@ class Kolab_Folder {
 
         if (isset($attributes['owner'])) {
             if ($attributes['owner'] != $this->getOwner()) {
-                Horde::logMessage(sprintf("Cannot modify the owner of a folder from %s to %s!",
+                Horde::logMessage(sprintf('Cannot modify the owner of a folder from %s to %s!',
                                           $this->getOwner(), $attributes['owner']),
                                   __FILE__, __LINE__, PEAR_LOG_ERR);
             }
@@ -763,19 +763,43 @@ class Kolab_Folder {
     }
 
     /**
+     * Retrieve the supported formats.
+     *
+     * @return array The names of the supported formats.
+     */
+    function getFormats()
+    {
+        global $conf;
+
+        if (empty($conf['kolab']['misc']['formats'])) {
+            $formats = array('XML');
+        } else {
+            $formats = $conf['kolab']['misc']['formats'];
+        }
+        if (!is_array($formats)) {
+            $formats = array($formats);
+        }
+        if (!in_array('XML', $formats)) {
+            $formats[] = 'XML';
+        }
+        return $formats;
+    }
+
+    /**
      * Save an object in this folder.
      *
-     * @param array              $object  The array that holds the data of
-     *                                    the object.
-     * @param Horde_Kolab_Format $handler The handler for the Kolab Format.
-     * @param string       $object_type   The type of the kolab object.
-     * @param string       $mime_type     The mime type for the kolab object.
-     * @param string       $id            The IMAP id of the old object if it
-     *                                    existed before
+     * @param array  $object        The array that holds the data of the object.
+     * @param int    $data_version  The format handler version.
+     * @param string $object_type   The type of the kolab object.
+     * @param string $id            The IMAP id of the old object if it
+     *                              existed before
+     * @param array  $old_object    The array that holds the current data of the
+     *                              object.
      *
      * @return boolean|PEAR_Error  True on success.
      */
-    function saveObject(&$object, &$handler, $object_type, $mime_type, $id = null)
+    function saveObject(&$object, $data_version, $object_type, $id = null,
+                        &$old_object = null)
     {
         $session = &Horde_Kolab_Session::singleton();
         $imap = &$session->getImap();
@@ -791,25 +815,77 @@ class Kolab_Folder {
 
         $new_headers = new MIME_Headers();
 
+        $formats = $this->getFormats();
+
+        $handlers = array();
+        foreach ($formats as $type) {
+            $handlers[$type] = &Horde_Kolab_Format::factory($type, $object_type,
+                                                            $data_version);
+            if (is_a($handlers[$type], 'PEAR_Error')) {
+                if ($type == 'XML') {
+                    return $handlers[$type];
+                }
+                Horde::logMessage(sprintf('Loading format handler "%s" failed: %s',
+                                          $type, $handlers[$type]->getMessage()),
+                                  __FILE__, __LINE__, PEAR_LOG_ERR);
+                continue;
+            }
+        }
+
         if ($id != null) {
             /** Update an existing kolab object */
+            $session = &Horde_Kolab_Session::singleton();
+            $imap = &$session->getImap();
+            if (is_a($imap, 'PEAR_Error')) {
+                return $imap;
+            }
+
+            if (!in_array($id, $imap->getUids())) {
+                return PEAR::raiseError(sprintf(_("The message with ID %s does not exist. This probably means that the Kolab object has been modified by somebody else while you were editing it. Your edits have been lost."),
+                                                $id));
+            }
 
             /** Parse email and load Kolab format structure */
-            $result = $this->_parseMessage($id, $mime_type);
+            $result = $this->parseMessage($id, $handlers['XML']->getMimeType(),
+                                          true, $formats);
             if (is_a($result, 'PEAR_Error')) {
                 return $result;
             }
-            list($old_message, $mime_part_id, $mime_message, $mime_headers) = $result;
+            list($old_message, $part_ids, $mime_message, $mime_headers) = $result;
             if (is_a($old_message, 'PEAR_Error')) {
                 return $old_message;
             }
 
-            $result = $handler->load($old_message);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
+            if (isset($object['_attachments']) && isset($old_object['_attachments'])) {
+                $attachments = array_keys($object['_attachments']);
+                foreach (array_keys($old_object['_attachments']) as $attachment) {
+                    if (!in_array($attachment, $attachments)) {
+                        foreach ($mime_message->getParts() as $part) {
+                            if ($part->getName() === $attachment) {
+                                foreach (array_keys($mime_message->_parts) as $key) {
+                                    if ($mime_message->_parts[$key]->getMIMEId() == $part->getMIMEId()) {
+                                        unset($mime_message->_parts[$key]);
+                                        break;
+                                    }
+                                }
+                                $mime_message->_generateIdMap($mime_message->_parts);
+                            }
+                        }                        
+                    }
+                }
+            }
+            $object = array_merge($old_object, $object);
+
+            if (isset($attachments)) {
+                foreach ($mime_message->getParts() as $part) {
+                    $name = $part->getName();
+                    foreach ($attachments as $attachment) {
+                        if ($name === $attachment) {
+                            $object['_attachments'][$attachment]['id'] = $part->getMIMEId();
+                        }
+                    }
+                }
             }
-
-            $object = array_merge($result, $object);
 
             /** Copy email header */
             if (!empty($mime_headers) && !$mime_headers === false) {
@@ -822,20 +898,53 @@ class Kolab_Folder {
             $mime_part_id = false;
         }
 
-        $new_content = $handler->save($object);
-        if (is_a($new_content, 'PEAR_Error')) {
-            return $new_content;
+        if (isset($object['_attachments'])) {
+            $attachments = array_keys($object['_attachments']);
+            foreach ($attachments as $attachment) {
+                $data = $object['_attachments'][$attachment];
+
+                if (!isset($data['content']) && !isset($data['path'])) {
+                    /**
+                     * There no new content and no new path. Do not rewrite the
+                     * attachment.
+                     */
+                    continue;
+                }
+
+                $part = new MIME_Part(isset($data['type']) ? $data['type'] : null,
+                                      isset($data['content']) ? $data['content'] : file_get_contents($data['path']),
+                                      NLS::getCharset());
+                $part->setTransferEncoding('quoted-printable');
+                $part->setDisposition('attachment');
+                $part->setName($attachment);
+
+                if (!isset($data['id'])) {
+                    $mime_message->addPart($part);
+                } else {
+                    $mime_message->alterPart($data['id'], $part);
+                }
+            }
         }
 
-        /** Update mime part */
-        $part = new MIME_Part($mime_type, $new_content, NLS::getCharset());
-        $part->setTransferEncoding("quoted-printable");
-        $part->setName($object_type . ".xml");
+        foreach ($formats as $type) {
+            $new_content = $handlers[$type]->save($object);
+            if (is_a($new_content, 'PEAR_Error')) {
+                return $new_content;
+            }
 
-        if ($mime_part_id === false) {
-            $mime_message->addPart($part);
-        } else {
-            $mime_message->alterPart($mime_part_id, $part);
+            /** Update mime part */
+            $part = new MIME_Part($handlers[$type]->getMimeType(),
+                                  $new_content, NLS::getCharset());
+            $part->setTransferEncoding('quoted-printable');
+            $part->setDisposition($handlers[$type]->getDisposition());
+            $part->setDispositionParameter('x-kolab-type', $type);
+            $part->setName($handlers[$type]->getName());
+
+            if (!isset($part_ids) || $part_ids[$type] === false) {
+                $mime_message->addPart($part);
+            } else {
+                $mime_message->alterPart($part_ids[$type], $part);
+            }
         }
 
         $session = &Horde_Kolab_Session::singleton();
@@ -844,9 +953,9 @@ class Kolab_Folder {
         $new_headers->addHeader('From', $session->user_mail);
         $new_headers->addHeader('To', $session->user_mail);
         $new_headers->addHeader('Date', date('r'));
-        $new_headers->addHeader('X-Kolab-Type', $mime_type);
-        $new_headers->addHeader('Subject', $object["uid"]);
-        $new_headers->addHeader('User-Agent', 'Horde::Kolab v1.1');
+        $new_headers->addHeader('X-Kolab-Type', $handlers['XML']->getMimeType());
+        $new_headers->addHeader('Subject', $object['uid']);
+        $new_headers->addHeader('User-Agent', 'Horde::Kolab::Storage v0.2');
         $new_headers->addMIMEHeaders($mime_message);
 
         $msg = preg_replace("/\r\n|\n|\r/s", "\r\n",
@@ -891,30 +1000,12 @@ class Kolab_Folder {
     }
 
     /**
-     * Fetch an IMAP message.
-     *
-     * @param int     $id             The message to retrieve
-     * @param string  $mime_type      The mime type of the part to retrieve
-     *
-     * @return mixed A string containing the Kolab XML object or false
-     *               if an error occured.
-     */
-    function fetch($id, $mime_type)
-    {
-        $result = $this->_parseMessage($id, $mime_type, false);
-        if (is_a($result, 'PEAR_Error')) {
-            Horde::logMessage($text, __FILE__, __LINE__, PEAR_LOG_WARNING);
-            return false;
-        }
-        return $result[0];
-    }
-
-    /**
      * Get an IMAP message and retrieve the Kolab Format object.
      *
      * @param int     $id             The message to retrieve.
      * @param string  $mime_type      The mime type of the part to retrieve.
      * @param boolean $parse_headers  Should the heades be MIME parsed?
+     * @param array   $formats        The list of possible format parts.
      *
      * @return array|PEAR_Error An array that list the Kolab XML
      *                          object text, the mime ID of the part
@@ -922,7 +1013,8 @@ class Kolab_Folder {
      *                          message and the MIME parsed headers if
      *                          requested.
      */
-    function _parseMessage($id, $mime_type, $parse_headers = true)
+    function parseMessage($id, $mime_type, $parse_headers = true,
+                          $formats = array('XML'))
     {
         $session = &Horde_Kolab_Session::singleton();
         $imap = &$session->getImap();
@@ -932,12 +1024,14 @@ class Kolab_Folder {
 
         $raw_headers = $imap->getMessageHeader($id);
         if (is_a($raw_headers, 'PEAR_Error')) {
-            return $raw_headers;
+            return PEAR::raiseError(sprintf(_("Failed retrieving the message with ID %s. Original error: %s."),
+                                            $id, $raw_headers->getMessage()));
         }
 
         $body = $imap->getMessageBody($id);
         if (is_a($body, 'PEAR_Error')) {
-            return $body;
+            return PEAR::raiseError(sprintf(_("Failed retrieving the message with ID %s. Original error: %s."),
+                                            $id, $body->getMessage()));
         }
 
         $mime_message = MIME_Structure::parseTextMIMEMessage($raw_headers . $body);
@@ -947,17 +1041,34 @@ class Kolab_Folder {
         $xml = false;
 
         // Read in a Kolab event object, if one exists
-        $mime_part_id = array_search($mime_type, $parts);
-        if ($mime_part_id !== false) {
+        $part_ids['XML'] = array_search($mime_type, $parts);
+        if ($part_ids['XML'] !== false) {
             if ($parse_headers) {
                 $mime_headers = MIME_Structure::parseMIMEHeaders($raw_headers);
             }
 
-            $part = $mime_message->getPart($mime_part_id);
+            $part = $mime_message->getPart($part_ids['XML']);
             $part->transferDecodeContents();
             $xml = $part->getContents();
         }
-        $result = array($xml, $mime_part_id, $mime_message, $mime_headers);
+
+        $alternate_formats = array_diff(array('XML'), $formats);
+        if (!empty($alternate_formats)) {
+            foreach ($alternate_formats as $type) {
+                $part_ids[$type] = false;
+            }
+            foreach ($mime_message->getParts() as $part) {
+                $params = $part->getDispositionParameters();
+                foreach ($alternate_formats as $type) {
+                    if (isset($params['x-kolab-format'])
+                        && $params['x-kolab-format'] == $type) {
+                        $part_ids[$type] = $part->getMIMEId();
+                    }
+                }
+            }
+        }
+
+        $result = array($xml, $part_ids, $mime_message, $mime_headers);
         return $result;
     }
 
@@ -1270,7 +1381,7 @@ class Kolab_Folder {
         }
         $data = $this->_annotation_data->getObject('KOLAB_FOLDER_CONFIGURATION');
         if (is_a($data, 'PEAR_Error')) {
-            Horde::logMessage(sprintf("Error retrieving annotation data on folder %s: %s",
+            Horde::logMessage(sprintf('Error retrieving annotation data on folder %s: %s',
                                       $this->name, $data->getMessage()),
                               __FILE__, __LINE__, PEAR_LOG_ERR);
             return '';
@@ -1308,7 +1419,7 @@ class Kolab_Folder {
         }
         $data = $this->_annotation_data->getObject('KOLAB_FOLDER_CONFIGURATION');
         if (is_a($data, 'PEAR_Error')) {
-            Horde::logMessage(sprintf("Error retrieving annotation data on folder %s: %s",
+            Horde::logMessage(sprintf('Error retrieving annotation data on folder %s: %s',
                                       $this->name, $data->getMessage()),
                               __FILE__, __LINE__, PEAR_LOG_ERR);
             $data = array();
-- 
tg: (cda64a2..) t/framework/HK/GW/Kolab/AttachmentSupport (depends on: t/framework/HK/GW/Auth/InvalidCheck)
-- 
TOPGIT patch commit log
=======================

commit 3f524003ae3a20c6ff04899b06ad780649676746
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sat Jan 31 00:10:37 2009 +0000

    Added patches framework/HK-GW-Kolab_Format-Support_Attachments.patch and framework/HK-GW-Kolab_Storage-Support_Attachments.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab_MoveIMAP.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab/MoveIMAP

Move the IMAP handlers from Kolab_Storage to Kolab_Server.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Deprecated.php       |    4 +-
 horde-webmail/lib/Horde/Kolab/IMAP.php             |  139 ++++
 horde-webmail/lib/Horde/Kolab/IMAP/cclient.php     |  778 ++++++++++++++++++++
 horde-webmail/lib/Horde/Kolab/IMAP/pear.php        |  520 +++++++++++++
 horde-webmail/lib/Horde/Kolab/IMAP/test.php        |  728 ++++++++++++++++++
 .../lib/Horde/Kolab/Server/Object/adminrole.php    |    2 +-
 .../Horde/Kolab/Server/Object/domainmaintainer.php |    2 +-
 horde-webmail/lib/Horde/Kolab/Server/test.php      |    2 +-
 horde-webmail/lib/Horde/Kolab/Session.php          |   40 +
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php   |  177 ++---
 horde-webmail/lib/Horde/Kolab/Storage/IMAP.php     |  139 ----
[...4231 lines suppressed...]
             if (is_a($result, 'PEAR_Error')) {
                 return $result;
             }
-- 
tg: (9a3fc7a..) t/framework/HK/GW/Kolab/MoveIMAP (depends on: t/framework/HK/GW/Kolab_Server/SafetyCheck)
-- 
TOPGIT patch commit log
=======================

commit 69e24b73af698051835806775a1ddacbd543a225
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sat Jan 31 00:01:58 2009 +0000

    Forgot to remove files

commit 6b9f9868700129d3f12471273613b27f3d7ae7ca
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 23:31:53 2009 +0000

    Added patch release/HK-GW-Kolab-IMAP_Move.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab_XfbFixes.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab/XfbFixes

Fixes to support the extended free/busy concept.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |   19 ++++++++++++++++++-
 horde-webmail/lib/Horde/Share/kolab.php          |    9 +++++----
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index 36844f9..1da391b 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -406,6 +406,22 @@ class Kolab_Folder {
                 $attributes = array($attributes);
             }
             foreach ($attributes as $key => $value) {
+                if ($key == 'params') {
+                    $params = unserialize($value);
+                    if (isset($params['xfbaccess'])) {
+                        $result = $this->setXfbAccess($params['xfbaccess']);
+                        if (is_a($result, 'PEAR_Error')) {
+                            return $result;
+                        }
+                    }
+                    if (isset($params['fbrelevance'])) {
+                        $result = $this->setFbrelevance(join(' ', $params['fbrelevance']));
+                        if (is_a($result, 'PEAR_Error')) {
+                            return $result;
+                        }
+                    }
+                }
+
                 // setAnnotation apparently does not suppoort UTF-8 nor any special characters
                 $store = base64_encode($value);
                 if ($key == 'desc') {
@@ -1614,7 +1630,8 @@ class Kolab_Folder {
      */
     function setXfbaccess($access)
     {
+        $value = join(' ', $access);
         return $this->_setAnnotation(KOLAB_ANNOT_ROOT . 'pxfb-readable-for',
-                                     $access);
+                                     $value);
     }
 }
diff --git a/horde-webmail/lib/Horde/Share/kolab.php b/horde-webmail/lib/Horde/Share/kolab.php
index 10ac08f..43ae960 100644
--- a/horde-webmail/lib/Horde/Share/kolab.php
+++ b/horde-webmail/lib/Horde/Share/kolab.php
@@ -526,10 +526,10 @@ class Horde_Share_Object_kolab extends Horde_Share_Object {
                              'default' => $this->get('default'),
                              'name' => $this->get('name'));
             $type = $this->get('type');
-            if (!is_a($type, 'PEAR_Error') && $type[0] == 'event') {
+            if (!is_a($type, 'PEAR_Error') && $type == 'event') {
                 $default = array_merge($default, array(
-                                           'fbrelevance' => $this->getFbrelevance(),
-                                           'xfbaccess'   => $this->getXfbaccess()
+                                           'fbrelevance' => $this->_folder->getFbrelevance(),
+                                           'xfbaccess'   => $this->_folder->getXfbaccess()
                                        ));
             }
             if (is_a($params, 'PEAR_Error') || $params == '') {
@@ -584,8 +584,9 @@ class Horde_Share_Object_kolab extends Horde_Share_Object {
             $value = unserialize($value);
             if (isset($value['default'])) {
                 $this->_data['default'] = $value['default'];
+                unset($value['default']);
             }
-            break;
+            $value = serialize($value);
 
         default:
             $this->_data[$attribute] = $value;
-- 
tg: (84604ae..) t/framework/HK/GW/Kolab/XfbFixes (depends on: t/framework/HK/GW/Kolab_Fbview/XfbConcept)
-- 
TOPGIT patch commit log
=======================

commit 07447788c136353d40cc6c5b4d9f1d1f0d13ef76
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:49:49 2009 +0000

    Added patch framework/HK-GW-Kolab-XFB_access_fixes.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Fbview_XfbConcept.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Fbview/XfbConcept

Implementation of the extended free/busy concept.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |   88 ++++++++++++++++++++++
 horde-webmail/lib/Horde/Share/kolab.php          |    7 ++
 2 files changed, 95 insertions(+), 0 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index b39f678..36844f9 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -44,6 +44,13 @@ define('KOLAB_ANNOT_ROOT', '/vendor/kolab/');
 define('KOLAB_ANNOT_FOLDER_TYPE', KOLAB_ANNOT_ROOT . 'folder-type');
 
 /**
+ * Kolab specific free/busy relevance
+ */
+define('KOLAB_FBRELEVANCE_ADMINS',  0);
+define('KOLAB_FBRELEVANCE_READERS', 1);
+define('KOLAB_FBRELEVANCE_NOBODY',  2);
+ 
+/**
  * Horde-specific annotations on the imap folder have this prefix.
  */
 define('HORDE_ANNOT_SHARE_ATTR', '/vendor/horde/share-');
@@ -1529,4 +1536,85 @@ class Kolab_Folder {
         $data['uid'] = 'KOLAB_FOLDER_CONFIGURATION';
         return $this->_annotation_data->save($data, $uid);
     }
+
+
+
+    /**
+     * Get the free/busy relevance for this folder
+     *
+     * @return int  Value containing the FB_RELEVANCE.
+     */
+    function getFbrelevance()
+    {
+        $result = $this->getKolabAttribute('incidences-for');
+        if (is_a($result, 'PEAR_Error') || empty($result)) {
+            return KOLAB_FBRELEVANCE_ADMINS;
+        }
+        switch ($result) {
+        case 'admins':
+            return KOLAB_FBRELEVANCE_ADMINS;
+        case 'readers':
+            return KOLAB_FBRELEVANCE_READERS;
+        case 'nobody':
+            return KOLAB_FBRELEVANCE_NOBODY;
+        default:
+            return KOLAB_FBRELEVANCE_ADMINS;
+        }
+    }
+
+    /**
+     * Set the free/busy relevance for this folder
+     *
+     * @param int $relevance Value containing the FB_RELEVANCE
+     *
+     * @return mixed  True on success or a PEAR_Error.
+     */
+    function setFbrelevance($relevance)
+    {
+        switch ($relevance) {
+        case KOLAB_FBRELEVANCE_ADMINS:
+            $value = 'admins';
+            break;
+        case KOLAB_FBRELEVANCE_READERS:
+            $value = 'readers';
+            break;
+        case KOLAB_FBRELEVANCE_NOBODY:
+            $value = 'nobody';
+            break;
+        default:
+            $value = 'admins';
+        }
+
+        return $this->_setAnnotation(KOLAB_ANNOT_ROOT . 'incidences-for',
+                                     $value);
+    }
+
+    /**
+     * Get the extended free/busy access settings for this folder
+     *
+     * @return array  Array containing the users with access to the
+     *                extended information.
+     */
+    function getXfbaccess()
+    {
+        $result = $this->getKolabAttribute('pxfb-readable-for');
+        if (is_a($result, 'PEAR_Error') || empty($result)) {
+            return array();
+        }
+        return explode(' ', $result);
+    }
+
+    /**
+     * Set the extended free/busy access settings for this folder
+     *
+     * @param array $access  Array containing the users with access to the
+     *                      extended information.
+     *
+     * @return mixed  True on success or a PEAR_Error.
+     */
+    function setXfbaccess($access)
+    {
+        return $this->_setAnnotation(KOLAB_ANNOT_ROOT . 'pxfb-readable-for',
+                                     $access);
+    }
 }
diff --git a/horde-webmail/lib/Horde/Share/kolab.php b/horde-webmail/lib/Horde/Share/kolab.php
index b4d6f16..10ac08f 100644
--- a/horde-webmail/lib/Horde/Share/kolab.php
+++ b/horde-webmail/lib/Horde/Share/kolab.php
@@ -525,6 +525,13 @@ class Horde_Share_Object_kolab extends Horde_Share_Object {
             $default = array('source' => 'kolab',
                              'default' => $this->get('default'),
                              'name' => $this->get('name'));
+            $type = $this->get('type');
+            if (!is_a($type, 'PEAR_Error') && $type[0] == 'event') {
+                $default = array_merge($default, array(
+                                           'fbrelevance' => $this->getFbrelevance(),
+                                           'xfbaccess'   => $this->getXfbaccess()
+                                       ));
+            }
             if (is_a($params, 'PEAR_Error') || $params == '') {
                 $params = $default;
             }
-- 
tg: (faa8655..) t/framework/HK/GW/Kolab_Fbview/XfbConcept (depends on: t/framework/HK/GW/Kolab_Server/FixAddressObjectIdentification)
-- 
TOPGIT patch commit log
=======================

commit 0cdca1ac8e05cffe0b14de2e572fc71b0a86df7c
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:47:08 2009 +0000

    Added patch framework/HK-GW-Fbview_xfb_concept.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Format_ImprovedPreferencesHandling.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Format/ImprovedPreferencesHandling

Ensure the preferences is known and only call it if it is really available.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Format/XML.php |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML.php b/horde-webmail/lib/Horde/Kolab/Format/XML.php
index e66d49e..3123bee 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML.php
@@ -968,6 +968,8 @@ class Horde_Kolab_Format_XML
      */
     function _loadMultipleCategories(&$object)
     {
+        global $prefs;
+
         if (empty($object['categories'])) {
             return;
         }
@@ -975,7 +977,8 @@ class Horde_Kolab_Format_XML
         // Create horde category if needed
         @include_once 'Horde/Prefs/CategoryManager.php';
         if ($this->_create_categories
-            && class_exists('Prefs_CategoryManager')) {
+            && class_exists('Prefs_CategoryManager')
+            && isset($prefs) && is_a($prefs, 'Prefs')) {
             $cManager = new Prefs_CategoryManager();
             $horde_categories = $cManager->get();
         } else {
-- 
tg: (7214163..) t/framework/HK/GW/Kolab_Format/ImprovedPreferencesHandling (depends on: t/framework/HK/GW/framework/Kolab_Format/WS)
-- 
TOPGIT patch commit log
=======================

commit 8320631427755105ed2ee15bec8859d423f88c91
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 22:43:10 2009 +0000

    Added patch release/HK-GW-Kolab_Format-PrefsHandling.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Server_AdditionalGetFeeBusyServerFixes.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Server/AdditionalGetFeeBusyServerFixes

Another fix to the getServer('freebusy') call.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 .../lib/Horde/Kolab/Server/Object/user.php         |    3 +++
 horde-webmail/lib/Horde/Kolab/Session.php          |    8 --------
 2 files changed, 3 insertions(+), 8 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
index 556933f..62b71e8 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
@@ -208,6 +208,9 @@ class Horde_Kolab_Server_Object_user extends Horde_Kolab_Server_Object {
             if (empty($server)) {
                 $server = $_SERVER['SERVER_NAME'];
             }
+            if (isset($conf['kolab']['freebusy']['server'])) {
+                return $conf['kolab']['freebusy']['server'];
+            }
             if (isset($conf['kolab']['server']['freebusy_url_format'])) {
                 return sprintf($conf['kolab']['server']['freebusy_url_format'],
                                $server);
diff --git a/horde-webmail/lib/Horde/Kolab/Session.php b/horde-webmail/lib/Horde/Kolab/Session.php
index 2ac507a..a0e3cf3 100644
--- a/horde-webmail/lib/Horde/Kolab/Session.php
+++ b/horde-webmail/lib/Horde/Kolab/Session.php
@@ -181,14 +181,6 @@ class Horde_Kolab_Session {
         }
 
         $this->_imap_params['protocol'] = 'imap/notls/novalidate-cert';
-
-        if (!isset($this->freebusy_server)) {
-            if (isset($conf['kolab']['freebusy']['server'])) {
-                $this->freebusy_server = $conf['kolab']['freebusy']['server'];
-            } else {
-                $this->freebusy_server = 'https://localhost/freebusy';
-            }
-        }
     }
 
     /**
-- 
tg: (3e0f3f4..) t/framework/HK/GW/Kolab_Server/AdditionalGetFeeBusyServerFixes (depends on: t/framework/HK/GW/Kolab_Storage/FixTriggerOnFolderCreation)
-- 
TOPGIT patch commit log
=======================

commit f2d30e95bea6393624c2f298e45be176e275aecc
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:38:40 2009 +0000

    Added patch framework/HK-GW-Kolab_Server-Another_get_freebusy_server.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Server_FixAddressObjectIdentification.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Server/FixAddressObjectIdentification

Fix the identification of address objects.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Server/ldap.php |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Server/ldap.php b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
index 7b52476..a09f74d 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/ldap.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
@@ -601,7 +601,7 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
             }
         }
 
-        if (strpos($dn, 'cn=internal') !== false) {
+        if (strpos($dn, 'cn=external') !== false) {
             return KOLAB_OBJECT_ADDRESS;
         }
 
@@ -930,7 +930,7 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
                 return sprintf('cn=%s,%s', $id, $this->_base_dn);
             }
         case KOLAB_OBJECT_ADDRESS:
-            return sprintf('cn=%s,cn=internal,%s', $id, $this->_base_dn);
+            return sprintf('cn=%s,cn=external,%s', $id, $this->_base_dn);
         case KOLAB_OBJECT_SHAREDFOLDER:
         case KOLAB_OBJECT_ADMINISTRATOR:
         case KOLAB_OBJECT_MAINTAINER:
-- 
tg: (72d0535..) t/framework/HK/GW/Kolab_Server/FixAddressObjectIdentification (depends on: t/framework/HK/GW/Kolab_Server/AdditionalGetFeeBusyServerFixes)
-- 
TOPGIT patch commit log
=======================

commit 7eddb3186e0bbb13420e3fd3ee55bbb940e83e2e
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:40:40 2009 +0000

    Added patch framework/HK-GW-Kolab_Server-Fix_address_identification.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Server_FixGetGroups.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Server/FixGetGroups

Fix the retrieval of user groups.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 .../lib/Horde/Kolab/Server/Object/user.php         |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
index 76b202b..556933f 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
@@ -179,7 +179,7 @@ class Horde_Kolab_Server_Object_user extends Horde_Kolab_Server_Object {
      */
     function getGroups()
     {
-        return $this->_db->getGroups($this->_dn);
+        return $this->_db->getGroups($this->_uid);
     }
 
     /**
-- 
tg: (59cb337..) t/framework/HK/GW/Kolab_Server/FixGetGroups (depends on: t/turba/HK/GW/AutomaticFreeBusyUrl)
-- 
TOPGIT patch commit log
=======================

commit 8c62525963066a04f92ca69d54429e5a6162b7f3
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:24:55 2009 +0000

    Added patch framework/HK-GW-Kolab_Server-Fix_getGroups.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Server_ImprovedFreebusyServerFallback.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Server/ImprovedFreebusyServerFallback

An improved fallback value for the Free/Busy server.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Session.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Session.php b/horde-webmail/lib/Horde/Kolab/Session.php
index d7c56d8..2ac507a 100644
--- a/horde-webmail/lib/Horde/Kolab/Session.php
+++ b/horde-webmail/lib/Horde/Kolab/Session.php
@@ -186,7 +186,7 @@ class Horde_Kolab_Session {
             if (isset($conf['kolab']['freebusy']['server'])) {
                 $this->freebusy_server = $conf['kolab']['freebusy']['server'];
             } else {
-                $this->freebusy_server = 'localhost';
+                $this->freebusy_server = 'https://localhost/freebusy';
             }
         }
     }
-- 
tg: (8ab103d..) t/framework/HK/GW/Kolab_Server/ImprovedFreebusyServerFallback (depends on: t/turba/HK/GW/PhotoSupport)
-- 
TOPGIT patch commit log
=======================

commit 6c4eda4dc0b4658fe17034bb540bc5829bfa4fcd
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sat Jan 31 00:21:26 2009 +0000

    Added patch /framework/HK-GW-Fix_freebusy_server_fallback.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Server_ImprovedServerFallbacks.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Server/ImprovedServerFallbacks

Improved fallbacks for getServer().

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 .../lib/Horde/Kolab/Server/Object/user.php         |   19 ++++++++++++++++---
 1 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
index 73e108d..76b202b 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
@@ -193,6 +193,8 @@ class Horde_Kolab_Server_Object_user extends Horde_Kolab_Server_Object {
      */
     function getServer($server_type)
     {
+        global $conf;
+
         switch ($server_type) {
         case 'freebusy':
             $server = $this->get(KOLAB_ATTR_FREEBUSYHOST);
@@ -203,7 +205,15 @@ class Horde_Kolab_Server_Object_user extends Horde_Kolab_Server_Object {
             if (is_a($server, 'PEAR_Error')) {
                 return $server;
             }
-            return 'https://' . $server . '/freebusy';
+            if (empty($server)) {
+                $server = $_SERVER['SERVER_NAME'];
+            }
+            if (isset($conf['kolab']['server']['freebusy_url_format'])) {
+                return sprintf($conf['kolab']['server']['freebusy_url_format'],
+                               $server);
+            } else {
+                return 'https://' . $server . '/freebusy';
+            }
         case 'imap':
             $server = $this->get(KOLAB_ATTR_IMAPHOST);
             if (!is_a($server, 'PEAR_Error') && !empty($server)) {
@@ -211,8 +221,11 @@ class Horde_Kolab_Server_Object_user extends Horde_Kolab_Server_Object {
             }
         case 'homeserver':
         default:
-            $home = $this->get(KOLAB_ATTR_HOMESERVER);
-            return $home;
+            $server = $this->get(KOLAB_ATTR_HOMESERVER);
+            if (empty($server)) {
+                $server = $_SERVER['SERVER_NAME'];
+            }
+            return $server;
         }
     }
 
-- 
tg: (2185342..) t/framework/HK/GW/Kolab_Server/ImprovedServerFallbacks (depends on: t/framework/HK/GW/Kolab_Server/ImprovedFreebusyServerFallback)
-- 
TOPGIT patch commit log
=======================

commit d0d1a70bc27ac4ae027e9bece298f957cf2f9102
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sat Jan 31 00:26:41 2009 +0000

    Added patch framework/HK-GW-Kolab_Server-Fix_getServor_on_empty_homeserver.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Server_ListObjects.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Server/ListObjects

Implement listing objects in the Kolab user database.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Server.php        |   31 +++
 horde-webmail/lib/Horde/Kolab/Server/Object.php |    1 +
 horde-webmail/lib/Horde/Kolab/Server/ldap.php   |  260 +++++++++++++++++++++--
 horde-webmail/lib/Horde/Kolab/Server/test.php   |  110 +++++++++-
 4 files changed, 371 insertions(+), 31 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Server.php b/horde-webmail/lib/Horde/Kolab/Server.php
index 33441d5..0d6fbd7 100644
--- a/horde-webmail/lib/Horde/Kolab/Server.php
+++ b/horde-webmail/lib/Horde/Kolab/Server.php
@@ -394,4 +394,35 @@ class Horde_Kolab_Server {
         }
         return $dn;
     }
+
+    /**
+     * List all objects of a specific type
+     *
+     * @param string $type   The type of the objects to be listed
+     * @param array  $params Additional parameters.
+     *
+     * @return array|PEAR_Error An array of Kolab objects.
+     */
+    function listObjects($type, $params = null)
+    {
+        if (!in_array($type, $this->valid_types)) {
+            return PEAR::raiseError(sprintf(_("Invalid Kolab object type \"%s\"."), 
+                                            $type));
+        }
+
+        return $this->_listObjects($type, $params);
+    }
+
+    /**
+     * List all objects of a specific type
+     *
+     * @param string $type   The type of the objects to be listed
+     * @param array  $params Additional parameters.
+     *
+     * @return array|PEAR_Error An array of Kolab objects.
+     */
+    function _listObjects($type, $params = null)
+    {
+        return array();
+    }
 };
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object.php b/horde-webmail/lib/Horde/Kolab/Server/Object.php
index b4ae799..1d49fa7 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object.php
@@ -32,6 +32,7 @@ define('KOLAB_ATTR_HOMESERVER',   'kolabHomeServer');
 define('KOLAB_ATTR_IPOLICY',      'kolabInvitationPolicy');
 define('KOLAB_ATTR_FBPAST',       'kolabFreeBusyPast');
 define('KOLAB_ATTR_FBFUTURE',     'kolabFreeBusyFuture');
+define('KOLAB_ATTR_FOLDERTYPE',   'kolabFolderType');
 
 /**
  * This class provides methods to deal with Kolab objects stored in
diff --git a/horde-webmail/lib/Horde/Kolab/Server/ldap.php b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
index 9ed679f..ed5bc84 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/ldap.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/ldap.php
@@ -133,11 +133,12 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
      * @param string  $filter     Filter criteria.
      * @param array   $attributes Restrict the search result to
      *                            these attributes.
+     * @param string  $base       The base location for searching.
      *
      * @return array|PEAR_Error A LDAP search result.
      */
-    function _search($filter,
-                     $attributes = null) {
+    function _search($filter, $attributes = null, $base = null)
+    {
         if (!$this->_bound) {
             $result = $this->_bind();
             if (is_a($result, 'PEAR_Error')) {
@@ -145,10 +146,14 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
             }
         }
 
+        if (empty($base)) {
+            $base = $this->_base_dn;
+        }
+
         if (isset($attributes)) {
-            $result = @ldap_search($this->_connection, $this->_base_dn, $filter, $attributes);
+            $result = @ldap_search($this->_connection, $base, $filter, $attributes);
         } else {
-            $result = @ldap_search($this->_connection, $this->_base_dn, $filter);
+            $result = @ldap_search($this->_connection, $base, $filter);
         }
         if (!$result && $this->_errno()) {
             return PEAR::raiseError(sprintf(_("LDAP Error: Failed to search using filter %s. Error was: %s"),
@@ -247,18 +252,65 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
     }
 
     /**
+     * Return the next entry of a result.
+     *
+     * @param resource $entry   The current LDAP entry.
+     *
+     * @return resource  The next entry of the result.
+     */
+    function _nextEntry($entry)
+    {
+        return @ldap_next_entry($this->_connection, $entry);
+    }
+
+    /**
      * Return the entries of a result.
      *
      * @param resource $result   The LDAP search result.
+     * @param int      $from     Only return results after this position.
+     * @param int      $to       Only return results until this position.
      *
      * @return array  The entries of the result.
      */
-    function _getEntries($result)
+    function _getEntries($result, $from = -1, $to = -1)
     {
+        if ($from >= 0 || $to >= 0) {
+            $result = array();
+            $i = 0;
+            for ($entry = $this->_firstEntry($result);
+                 $entry != false;
+                 $entry = $this->_nextEntry($entry)) {
+                if (!$entry  && $this->_errno()) {
+                    return false;
+                }
+                if ($i > $from && ($i <= $to || $to == -1)) {
+                    $attributes = $this->_getAttributes($entry);
+                    if (!$attributes  && $this->_errno()) {
+                        return false;
+                    }
+                    $result[] = $attributes;
+                }
+                $i++;
+            }
+            return $result;
+        }
         return @ldap_get_entries($this->_connection, $result);
     }
 
     /**
+     * Sort the entries of a result.
+     *
+     * @param resource $result    The LDAP search result.
+     * @param string   $attribute The attribute used for sorting.
+     *
+     * @return boolean  True if sorting succeeded.
+     */
+    function _sort($result, $attribute)
+    {
+        return @ldap_sort($this->_connection, $result, $attribute);
+    }
+
+    /**
      * Return the current LDAP error number.
      *
      * @return int  The current LDAP error number.
@@ -285,15 +337,46 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
      */
 
     /**
+     * Return the DNs of a result.
+     *
+     * @param resource $result   The LDAP search result.
+     * @param int      $from     Only return results after this position.
+     * @param int      $to       Only return results until this position.
+     *
+     * @return array  The DNs of the result.
+     */
+    function _getDns($result, $from = -1, $to = -1)
+    {
+        $dns = array();
+        $entry = $this->_firstEntry($result);
+        $i = 0;
+        for ($entry = $this->_firstEntry($result);
+             $entry != false;
+             $entry = $this->_nextEntry($entry)) {
+            if ($i > $from && ($i <= $to || $to == -1)) {
+                $dn = $this->_getDn($entry);
+                if (!$dn  && $this->_errno()) {
+                    return false;
+                }
+                $dns[] = $dn;
+            }
+            $i++;
+        }
+        if ($this->_errno()) {
+            return false;
+        }
+        return $dns;
+    }
+
+    /**
      * Identify the DN of the first result entry.
      *
-     * @param array $result The LDAP search result.
+     * @param array $result   The LDAP search result.
      * @param int   $restrict A KOLAB_SERVER_RESULT_* result restriction.
      *
      * @return string|PEAR_Error The DN.
      */
-    function _dnFromResult($result,
-                           $restrict = KOLAB_SERVER_RESULT_SINGLE)
+    function _dnFromResult($result, $restrict = KOLAB_SERVER_RESULT_SINGLE)
     {
         switch ($restrict) {
         case KOLAB_SERVER_RESULT_STRICT:
@@ -320,20 +403,15 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
             }
             return $dn;
         case KOLAB_SERVER_RESULT_MANY:
-            $entries = $this->_getEntries($result);
-            if (!$entries) {
-                return false;
-            }
+            $entries = $this->_getDns($result);
             if (!$entries  && $this->_errno()) {
                 return PEAR::raiseError(sprintf(_("Search failed. Error was: %s"),
                                                 $this->_error()));
             }
-            unset($entries['count']);
-            $result = array();
-            foreach ($entries as $entry) {
-                $result[] = $entry['dn'];
+            if (!$entries) {
+                return false;
             }
-            return $result;
+            return $entries;
         }
         return false;
     }
@@ -387,13 +465,13 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
             return $result;
         case KOLAB_SERVER_RESULT_MANY:
             $entries = $this->_getEntries($result);
-            if (!$entries) {
-                return false;
-            }
             if (!$entries  && $this->_errno()) {
                 return PEAR::raiseError(sprintf(_("Search failed. Error was: %s"),
                                                 $this->_error()));
             }
+            if (!$entries) {
+                return false;
+            }
             unset($entries['count']);
             $result = array();
             $i = 0;
@@ -677,4 +755,146 @@ class Horde_Kolab_Server_ldap extends Horde_Kolab_Server {
         }
         return $result;
     }
+
+    /**
+     * List all objects of a specific type
+     *
+     * @param string $type   The type of the objects to be listed
+     * @param array  $params Additional parameters.
+     *
+     * @return array|PEAR_Error An array of Kolab objects.
+     */
+    function _listObjects($type, $params = null)
+    {
+        if (empty($params['base_dn'])) {
+            $base = $this->_base_dn;
+        } else {
+            $base = $params['base_dn'];
+        }
+
+        switch ($type) {
+        case KOLAB_OBJECT_USER:
+            $filter = '(&(objectClass=kolabInetOrgPerson)(uid=*)(mail=*)(sn=*))';
+            $attributes = array(
+                KOLAB_ATTR_SN,
+                KOLAB_ATTR_CN,
+                KOLAB_ATTR_UID,
+                KOLAB_ATTR_MAIL,
+                KOLAB_ATTR_DELETED,
+            );
+            $sort = KOLAB_ATTR_SN;
+            break;
+        case KOLAB_OBJECT_ADDRESS:
+            $filter = '(&(objectClass=inetOrgPerson)(!(uid=*))(sn=*))';
+            $attributes = array(
+                KOLAB_ATTR_SN,
+                KOLAB_ATTR_CN,
+                KOLAB_ATTR_MAIL,
+                KOLAB_ATTR_DELETED,
+            );
+            $sort = KOLAB_ATTR_SN;
+            break;
+        case KOLAB_OBJECT_ADMINISTRATOR:
+            $filter = '(&(cn=*)(objectClass=inetOrgPerson)(uid=*)(sn=*))';
+            $attributes = array(
+                KOLAB_ATTR_SN,
+                KOLAB_ATTR_CN,
+                KOLAB_ATTR_UID,
+                KOLAB_ATTR_DELETED,
+            );
+            $sort = KOLAB_ATTR_SN;
+            break;
+        case KOLAB_OBJECT_DOMAINMAINTAINER:
+            $filter = '(&(cn=*)(objectClass=kolabInetOrgPerson)(!(uid=manager))(sn=*))';
+            $attributes = array(
+                KOLAB_ATTR_SN,
+                KOLAB_ATTR_CN,
+                KOLAB_ATTR_UID,
+                KOLAB_ATTR_DELETED,
+            );
+            $sort = KOLAB_ATTR_SN;
+            break;
+        case KOLAB_OBJECT_GROUP:
+            $filter = '(&(!(cn=domains))(objectClass=kolabGroupOfNames))';
+            $attributes = array(
+                KOLAB_ATTR_CN,
+                KOLAB_ATTR_MAIL,
+                KOLAB_ATTR_DELETED,
+            );
+            $sort = KOLAB_ATTR_CN;
+            break;
+        case KOLAB_OBJECT_MAINTAINER:
+            $filter = '(&(cn=*)(objectClass=inetOrgPerson)(!(uid=manager))(sn=*))';
+            $attributes = array(
+                KOLAB_ATTR_SN,
+                KOLAB_ATTR_CN,
+                KOLAB_ATTR_UID,
+                KOLAB_ATTR_DELETED,
+            );
+            $sort = KOLAB_ATTR_SN;
+            break;
+        case KOLAB_OBJECT_SHAREDFOLDER:
+            $filter = '(objectClass=kolabSharedFolder)';
+            $attributes = array(
+                KOLAB_ATTR_CN,
+                KOLAB_ATTR_DELETED,
+                KOLAB_ATTR_FOLDERTYPE,
+            );
+            $sort = KOLAB_ATTR_CN;
+            break;
+        case KOLAB_OBJECT_SERVER:
+            $filter = '(&((k=kolab))(objectClass=kolab))';
+            $attributes = false;
+            $sort = false;
+            break;
+        }
+
+        if (isset($params['attributes'])) {
+            $attributes = $params['attributes'];
+        }
+
+        if (isset($params['sort'])) {
+            $sort = $params['sort'];
+        }
+
+        $result = $this->_search($filter, $attributes, $base);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+
+        if ($sort) {
+            $this->_sort($result, $sort);
+        }
+
+        if (isset($params['from'])) {
+            $from = $params['from'];
+        } else {
+            $from = -1;
+        }
+
+        if (isset($params['to'])) {
+            $sort = $params['to'];
+        } else {
+            $to = -1;
+        }
+
+        $entries = $this->_getDns($result, $from, $to);
+        if (!$entries  && $this->_errno()) {
+            return PEAR::raiseError(sprintf(_("Search failed. Error was: %s"),
+                                            $this->_error()));
+        }
+        if (!$entries) {
+            return false;
+        }
+
+        $objects = array();
+        foreach ($entries as $dn) {
+            $result = $this->fetch($dn, $type);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+            $objects[] = $result;
+        }
+        return $objects;
+    }
 }
diff --git a/horde-webmail/lib/Horde/Kolab/Server/test.php b/horde-webmail/lib/Horde/Kolab/Server/test.php
index 94945e0..d4ece0d 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/test.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/test.php
@@ -47,6 +47,27 @@ class Horde_Kolab_Server_test extends Horde_Kolab_Server_ldap {
     var $_error = '';
 
     /**
+     * Attribute used for sorting.
+     *
+     * @var string
+     */
+    var $_sort_by;
+
+    /**
+     * A result cache for iterating over the result.
+     *
+     * @var array
+     */
+    var $_current_result;
+
+    /**
+     * An index into the current result for iterating.
+     *
+     * @var int
+     */
+    var $_current_index;
+
+    /**
      * Parse LDAP filter.
      * Partially derived from Net_LDAP_Filter.
      *
@@ -126,7 +147,7 @@ class Horde_Kolab_Server_test extends Horde_Kolab_Server_ldap {
      *
      * @return array|PEAR_Error A LDAP serach result.
      */
-    function _search($filter, $attributes = null) {
+    function _search($filter, $attributes = null, $base = null) {
         $filter = $this->_parse($filter);
         if (is_a($filter, 'PEAR_Error')) {
             return $filter;
@@ -135,6 +156,16 @@ class Horde_Kolab_Server_test extends Horde_Kolab_Server_ldap {
         if (empty($result)) {
             return null;
         }
+        if ($base) {
+            $subtree = array();
+            foreach ($result as $entry) {
+                if (strpos($entry['dn'], $base)) {
+                    $subtree[] = $entry;
+                }
+            }
+            $result = $subtree;
+        }
+
         return $result;
     }
 
@@ -156,7 +187,7 @@ class Horde_Kolab_Server_test extends Horde_Kolab_Server_ldap {
                     switch ($filter['log']) {
                     case '=':
                         $value = $element['data'][$filter['att']];
-                        if ($value == $filter['val']
+                        if ($filter['val'] == '*' || $value == $filter['val']
                             || (is_array($value)
                                 && in_array($filter['val'], $value))) {
                             if (empty($attributes)) {
@@ -290,32 +321,58 @@ class Horde_Kolab_Server_test extends Horde_Kolab_Server_ldap {
     }
 
     /**
-     * Return the first entry of a result.
-     *
-     * @param array $result   The LDAP search result.
+     * Return the current entry of a result.
      *
-     * @return mixe  The first entry of the result or false.
+     * @return mixe  The current entry of the result or false.
      */
-    function _firstEntry($result)
+    function _fetchEntry()
     {
-        if (is_array($result)) {
-            $data = array_keys($result[0]['data']);
+        if (is_array($this->_current_result)
+            && $this->_current_index < count($this->_current_result)) {
+            $data = array_keys($this->_current_result[$this->_current_index]['data']);
             $data['count'] = 1;
-            $data['dn'] = array($result[0]['dn']);
+            $data['dn'] = array($this->_current_result[$this->_current_index]['dn']);
             $data['dn']['count'] = 1;
-            foreach ($result[0]['data'] as $attr => $value) {
+            foreach ($this->_current_result[$this->_current_index]['data'] as $attr => $value) {
                 if (!is_array($value)) {
                     $value = array($value);
                 }
                 $data[$attr] = $value;
                 $data[$attr]['count'] = count($value);
             }
+            $this->_current_index++;
             return $data;
         }
         return false;
     }
 
     /**
+     * Return the first entry of a result.
+     *
+     * @param array $result   The LDAP search result.
+     *
+     * @return mixe  The first entry of the result or false.
+     */
+    function _firstEntry($result)
+    {
+        $this->_current_result = $result;
+        $this->_current_index = 0;
+        return $this->_fetchEntry();
+    }
+
+    /**
+     * Return the next entry of a result.
+     *
+     * @param resource $entry   The current LDAP entry.
+     *
+     * @return resource  The next entry of the result.
+     */
+    function _nextEntry($entry)
+    {
+        return $this->_fetchEntry();
+    }
+
+    /**
      * Return the entries of a result.
      *
      * @param array $result   The LDAP search result.
@@ -338,6 +395,37 @@ class Horde_Kolab_Server_test extends Horde_Kolab_Server_ldap {
     }
 
     /**
+     * Sort the entries of a result.
+     *
+     * @param resource $result    The LDAP search result.
+     * @param string   $attribute The attribute used for sorting.
+     *
+     * @return boolean  True if sorting succeeded.
+     */
+    function _sort(&$result, $attribute)
+    {
+        $this->_sort_by = $attribute;
+        usort($result, array($this, '_resultSort'));
+        return false;
+    }
+
+    /**
+     * Sort two entries.
+     *
+     * @param array $a First entry.
+     * @param array $b Second entry.
+     *
+     * @return int  Comparison result.
+     */
+    function _resultSort($a, $b)
+    {
+        $x = isset($a['data'][$this->_sort_by][0])?$a['data'][$this->_sort_by][0]:'';
+        $y = isset($b['data'][$this->_sort_by][0])?$b['data'][$this->_sort_by][0]:'';
+        return strcasecmp($x, $y);
+    }
+
+
+    /**
      * Return the current LDAP error number.
      *
      * @return int  The current LDAP error number.
-- 
tg: (53715c4..) t/framework/HK/GW/Kolab_Server/ListObjects (depends on: t/framework/HK/GW/Kolab_Storage/Restructuring_Fixes)
-- 
TOPGIT patch commit log
=======================

commit 25572367d02bd92e5e9c2e329695bd780851d67e
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 22:45:52 2009 +0000

    Added patch release/HK-GW-Kolab_Server-ListObjects.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Server_RequireIMAP.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Server/RequireIMAP

Add missing requires.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab.php         |    7 +++++++
 horde-webmail/lib/Horde/Kolab/Session.php |   19 ++++++++++++++++---
 2 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab.php b/horde-webmail/lib/Horde/Kolab.php
index 9ed8949..2ec113d 100644
--- a/horde-webmail/lib/Horde/Kolab.php
+++ b/horde-webmail/lib/Horde/Kolab.php
@@ -805,4 +805,11 @@ class Kolab {
             return '';
         }
     }
+
+    /**
+     * @deprecated
+     */
+    function triggerFreeBusyUpdate()
+    {
+    }
 }
diff --git a/horde-webmail/lib/Horde/Kolab/Session.php b/horde-webmail/lib/Horde/Kolab/Session.php
index fa58066..d7c56d8 100644
--- a/horde-webmail/lib/Horde/Kolab/Session.php
+++ b/horde-webmail/lib/Horde/Kolab/Session.php
@@ -192,6 +192,19 @@ class Horde_Kolab_Session {
     }
 
     /**
+     * Returns the properties that need to be serialized.
+     *
+     * @return array  List of serializable properties.
+     */
+    function __sleep()
+    {
+        $properties = get_object_vars($this);
+        unset($properties['_imap']);
+        $properties = array_keys($properties);
+        return $properties;
+    }
+
+    /**
      * Get the Kolab Server connection.
      *
      * @param string $user        The session will be setup for the user with
@@ -238,14 +251,14 @@ class Horde_Kolab_Session {
     {
         if (!isset($this->_imap)) {
 
+            /** We need the Kolab IMAP library now. */
+            require_once 'Horde/Kolab/IMAP.php';
+
             $params = $this->getImapParams();
             if (is_a($params, 'PEAR_Error')) {
                 return $params;
             }
 
-            /** We need the Kolab IMAP library now. */
-            require_once 'Horde/Kolab/IMAP.php';
-
             $imap = &Horde_Kolab_IMAP::singleton($params['hostspec'],
                                                  $params['port'], true, false);
             if (is_a($imap, 'PEAR_Error')) {
-- 
tg: (d4fffeb..) t/framework/HK/GW/Kolab_Server/RequireIMAP (depends on: t/framework/HK/GW/Auth/SafetyCheck)
-- 
TOPGIT patch commit log
=======================

commit d0f864a8b75a23948f9b85032773a95ba81fd96e
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 23:32:59 2009 +0000

    Removed patch remains.

commit c788193b98fbbceb373fa2c5f61306a53a5d2e05
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 23:58:08 2009 +0000

    Added patch release/HK-GW-Kolab_Storage-Require_IMAP.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Server_RewriteExtend.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Server/RewriteExtend

Rewritten/extended the first Kolab_Server version.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Server.php           |  404 +++++++++++++++-----
 horde-webmail/lib/Horde/Kolab/Server/Object.php    |  388 +++++++++++++++----
 .../lib/Horde/Kolab/Server/Object/address.php      |   58 +++-
 .../Horde/Kolab/Server/Object/administrator.php    |   37 +-
 .../lib/Horde/Kolab/Server/Object/adminrole.php    |  157 ++++++++
 .../lib/Horde/Kolab/Server/Object/distlist.php     |   52 +++
 .../Horde/Kolab/Server/Object/domainmaintainer.php |  106 +++++-
 .../lib/Horde/Kolab/Server/Object/group.php        |  206 ++++++++++-
 .../lib/Horde/Kolab/Server/Object/maintainer.php   |   38 +-
 .../lib/Horde/Kolab/Server/Object/server.php       |   17 +-
 .../lib/Horde/Kolab/Server/Object/sharedfolder.php |   74 ++++-
[...3797 lines suppressed...]
      */
     function shutdown()
     {
@@ -243,4 +280,5 @@ class Horde_Kolab_Session {
         $session = &Horde_SessionObjects::singleton();
         $session->overwrite('kolab_session', $this, false);
     }
+
 }
-- 
tg: (d10384d..) t/framework/HK/GW/Kolab_Server/RewriteExtend (depends on: t/framework/HK/GW/Auth/ListUsers)
-- 
TOPGIT patch commit log
=======================

commit d9464b0512a4d1ea3adf651ca48fe97ef035a1f0
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 22:51:46 2009 +0000

    Added patch release/HK-GW-Kolab_Server-Version2.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Server_SafetyCheck.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Server/SafetyCheck

A tiny safety check.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Server.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Server.php b/horde-webmail/lib/Horde/Kolab/Server.php
index 5be2505..7954b21 100644
--- a/horde-webmail/lib/Horde/Kolab/Server.php
+++ b/horde-webmail/lib/Horde/Kolab/Server.php
@@ -194,7 +194,7 @@ class Horde_Kolab_Server {
         }
 
         $sparam         = $server_params;
-        $sparam['pass'] = md5($sparam['pass']);
+        $sparam['pass'] = isset($sparam['pass']) ? md5($sparam['pass']) : '';
         $signature      = serialize(array($driver, $sparam));
         if (empty($instances[$signature])) {
             $instances[$signature] = &Horde_Kolab_Server::factory($driver,
-- 
tg: (022752c..) t/framework/HK/GW/Kolab_Server/SafetyCheck (depends on: t/framework/HK/GW/Auth/UseKolabServer)
-- 
TOPGIT patch commit log
=======================

commit 4618c36aa9740cfa90578aefceaba610d121d9c1
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 23:28:39 2009 +0000

    Added patch release/HK-GW-Share-Testing.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Server_Session.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Server/Session

Adds the Kolab Session handler.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Session.php |  246 +++++++++++++++++++++++++++++
 1 files changed, 246 insertions(+), 0 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Session.php b/horde-webmail/lib/Horde/Kolab/Session.php
new file mode 100644
index 0000000..83e4ec1
--- /dev/null
+++ b/horde-webmail/lib/Horde/Kolab/Session.php
@@ -0,0 +1,246 @@
+<?php
+/**
+ * @package Kolab_Server
+ *
+ * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Session.php,v 1.4 2008/09/22 16:15:51 wrobel Exp $
+ */
+
+/** We need the Auth library */
+require_once 'Horde/Auth.php';
+
+/**
+ * The Horde_Kolab_Session class holds additional user details for the current
+ * session.
+ *
+ * The core user credentials (login, pass) are kept within the Auth module and
+ * can be retrieved using <code>Auth::getAuth()</code> respectively
+ * <code>Auth::getCredential('password')</code>. Any additional Kolab user data
+ * relevant for the user session should be accessed via the Horde_Kolab_Session
+ * class.
+ *
+ * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Session.php,v 1.4 2008/09/22 16:15:51 wrobel Exp $
+ *
+ * Copyright 2008 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author  Gunnar Wrobel <wrobel at pardus.de>
+ * @package Kolab_Server
+ */
+class Horde_Kolab_Session {
+
+    /**
+     * User ID.
+     *
+     * @var string
+     */
+    var $user_id;
+
+    /**
+     * Primary user mail address.
+     *
+     * @var string
+     */
+    var $user_mail;
+
+    /**
+     * The connection parameters for the IMAP server.
+     *
+     * @var array|PEAR_Error
+     */
+    var $_imap_params;
+
+    /**
+     * The free/busy server for the current user.
+     *
+     * @var array|PEAR_Error
+     */
+    var $freebusy_server;
+
+    /**
+     * Constructor.
+     *
+     * @param string $user The session will be setup for the user with this ID.
+     */
+    function Horde_Kolab_Session($user = null)
+    {
+        global $conf;
+
+        if (empty($user)) {
+            $user = Auth::getAuth();
+            if (empty($user)) {
+                $user = 'anonymous';
+            } else if (!strpos($user, '@')) {
+                $user = $user . '@' . (!empty($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost');
+            }
+        }
+
+        $this->user_id = $user;
+        $this->_imap_params = array();
+
+        $user_object = $this->_fetchUser($user);
+        if (!is_a($user_object, 'PEAR_Error')) {
+            $result = $user_object->get(KOLAB_ATTR_MAIL);
+            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
+                $this->user_mail = $result;
+            }
+
+            $result = $user_object->get(KOLAB_ATTR_UID);
+            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
+                $this->user_id = $result;
+            }
+
+            $result = $user_object->getServer('imap');
+            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
+                $server = explode(':', $result, 2);
+                if (!empty($server[0])) {
+                    $this->_imap_params['hostspec'] = $server[0];
+                }
+                if (!empty($server[1])) {
+                    $this->_imap_params['port'] = $server[1];
+                }
+            }
+
+            $result = $user_object->getServer('freebusy');
+            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
+                $this->freebusy_server = $result;
+            }
+        }
+
+        if (empty($conf['kolab']['imap']['allow_special_users'])
+            && (is_a($user_object, 'PEAR_Error')
+                || !is_a($user_object, 'Horde_Kolab_Server_Object_user'))) {
+            $this->_imap_params = PEAR::raiseError(_('Access to special Kolab users is denied.'));
+            return;
+        }
+
+        if (empty($this->user_mail)) {
+            $this->user_mail = $user;
+        }
+
+        if (!isset($this->_imap_params['hostspec'])) {
+            if (isset($conf['kolab']['imap']['server'])) {
+                $this->_imap_params['hostspec'] = $conf['kolab']['imap']['server'];
+            } else {
+                $this->_imap_params['hostspec'] = 'localhost';
+            }
+        }
+
+        if (!isset($this->_imap_params['port'])) {
+            if (isset($conf['kolab']['imap']['port'])) {
+                $this->_imap_params['port'] = $conf['kolab']['imap']['port'];
+            } else {
+                $this->_imap_params['port'] = 143;
+            }
+        }
+
+        $this->_imap_params['protocol'] = 'imap/notls/novalidate-cert';
+
+        if (!isset($this->freebusy_server)) {
+            if (isset($conf['kolab']['freebusy']['server'])) {
+                $this->freebusy_server = $conf['kolab']['freebusy']['server'];
+            } else {
+                $this->freebusy_server = 'localhost';
+            }
+        }
+    }
+
+    /**
+     * Fetch the Kolab_Object representing the current user.
+     *
+     * @param string $user The id of the user to retrieve.
+     *
+     * @return Kolab_Object_user|PEAR_Error The object representing
+     *                                      the current user.
+     */
+    function _fetchUser($user = null)
+    {
+        if (empty($user)) {
+            $user = Auth::getAuth();
+            if (empty($user)) {
+                return PEAR::raiseError(_('Anonymous user.'));
+            }
+        }
+
+        /** We need the Kolab Server access. */
+        require_once 'Horde/Kolab/Server.php';
+        $server = Horde_Kolab_Server::singleton();
+        if (is_a($server, 'PEAR_Error')) {
+            return $server;
+        }
+
+        $dn = $server->dnForUidOrMail($user);
+        if (empty($dn)) {
+            return PEAR::raiseError(_('No such user.'));
+        }
+        if (is_a($dn, 'PEAR_Error')) {
+            return $dn;
+        }
+
+        return $server->fetch($dn);
+    }
+
+    /**
+     * Get the IMAP connection parameters.
+     *
+     * @return array|PEAR_Error The IMAP connection parameters.
+     */
+    function &getImapParams()
+    {
+        return $this->_imap_params;
+    }
+
+    /**
+     * Attempts to return a reference to a concrete Horde_Kolab_Session instance.
+     *
+     * It will only create a new instance if no Horde_Kolab_Session instance
+     * currently exists or if a user ID has been specified that does not match the
+     * user ID/user mail of the current session.
+     *
+     * This method must be invoked as:
+     *   <code>$var = &Horde_Kolab_Session::singleton();</code>
+     *
+     * @static
+     *
+     * @param string $user The session will be setup for the user with this ID.
+     *
+     * @return Horde_Kolab_Session  The concrete Session reference.
+     */
+    function &singleton($user = null)
+    {
+        static $session;
+
+        if (!isset($session)) {
+            /**
+             * Horde_Kolab_Server currently has no caching so we mainly
+             * cache some user information here as reading this data
+             * may be expensive when running in a multi-host
+             * environment.
+             */
+            require_once 'Horde/SessionObjects.php';
+            $hs = &Horde_SessionObjects::singleton();
+            $session = $hs->query('kolab_session');
+        }
+
+        if (empty($session)
+            || (!empty($user) &&  $user != $session->user_mail
+                && $user != $session->user_id)) {
+            $session = new Horde_Kolab_Session($user);
+        }
+
+        register_shutdown_function(array(&$session, 'shutdown'));
+
+        return $session;
+    }
+
+    /**
+     * Stores the object in the session cache.
+     */
+    function shutdown()
+    {
+        require_once 'Horde/SessionObjects.php';
+        $session = &Horde_SessionObjects::singleton();
+        $session->overwrite('kolab_session', $this, false);
+    }
+}
-- 
tg: (6938161..) t/framework/HK/GW/Kolab_Server/Session (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 1211d81d2f9da103a0a7387eb1e4956eec48004d
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 20:11:36 2009 +0000

    Added patch release/HK-GW-Kolab_Server-SessionMove.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Server_getFreebusyServer.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Server/getFreebusyServer

Allow to retrieve the free/busy server of a user.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Server/Object.php    |   26 ++++++++++---------
 .../lib/Horde/Kolab/Server/Object/user.php         |    8 ++++++
 2 files changed, 22 insertions(+), 12 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object.php b/horde-webmail/lib/Horde/Kolab/Server/Object.php
index 82170f5..b4ae799 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object.php
@@ -19,18 +19,19 @@ define('KOLAB_OBJECT_USER',             'Horde_Kolab_Server_Object_user');
 define('KOLAB_OBJECT_SERVER',           'Horde_Kolab_Server_Object_server');
 
 /** Define the possible Kolab object attributes */
-define('KOLAB_ATTR_DN',        'dn');
-define('KOLAB_ATTR_SN',        'sn');
-define('KOLAB_ATTR_CN',        'cn');
-define('KOLAB_ATTR_FN',        'fn');
-define('KOLAB_ATTR_MAIL',      'mail');
-define('KOLAB_ATTR_UID',       'uid');
-define('KOLAB_ATTR_DELETED',   'kolabDeleteFlag');
-define('KOLAB_ATTR_IMAPHOST',  'kolabImapServer');
-define('KOLAB_ATTR_HOMESERVER','kolabHomeServer');
-define('KOLAB_ATTR_IPOLICY',   'kolabInvitationPolicy');
-define('KOLAB_ATTR_FBPAST',    'kolabFreeBusyPast');
-define('KOLAB_ATTR_FBFUTURE',  'kolabFreeBusyFuture');
+define('KOLAB_ATTR_DN',           'dn');
+define('KOLAB_ATTR_SN',           'sn');
+define('KOLAB_ATTR_CN',           'cn');
+define('KOLAB_ATTR_FN',           'fn');
+define('KOLAB_ATTR_MAIL',         'mail');
+define('KOLAB_ATTR_UID',          'uid');
+define('KOLAB_ATTR_DELETED',      'kolabDeleteFlag');
+define('KOLAB_ATTR_FREEBUSYHOST', 'kolabFreeBusyServer');
+define('KOLAB_ATTR_IMAPHOST',     'kolabImapServer');
+define('KOLAB_ATTR_HOMESERVER',   'kolabHomeServer');
+define('KOLAB_ATTR_IPOLICY',      'kolabInvitationPolicy');
+define('KOLAB_ATTR_FBPAST',       'kolabFreeBusyPast');
+define('KOLAB_ATTR_FBFUTURE',     'kolabFreeBusyFuture');
 
 /**
  * This class provides methods to deal with Kolab objects stored in
@@ -200,6 +201,7 @@ class Horde_Kolab_Server_Object {
 		case KOLAB_ATTR_MAIL:
 		case KOLAB_ATTR_UID:
 		case KOLAB_ATTR_IMAPHOST:
+		case KOLAB_ATTR_FREEBUSYHOST:
 		case KOLAB_ATTR_HOMESERVER:
 			return $this->_get($attr, true);
 		default:
diff --git a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
index a4cd05f..d6b9e97 100644
--- a/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
+++ b/horde-webmail/lib/Horde/Kolab/Server/Object/user.php
@@ -43,6 +43,7 @@ class Horde_Kolab_Server_Object_user extends Horde_Kolab_Server_Object {
         KOLAB_ATTR_MAIL,
         KOLAB_ATTR_DELETED,
 		KOLAB_ATTR_IMAPHOST,
+		KOLAB_ATTR_FREEBUSYHOST,
 		KOLAB_ATTR_HOMESERVER,
 		KOLAB_ATTR_IPOLICY,
         KOLAB_ATTR_FBFUTURE,
@@ -69,11 +70,18 @@ class Horde_Kolab_Server_Object_user extends Horde_Kolab_Server_Object {
     function getServer($server_type)
     {
         switch ($server_type) {
+        case 'freebusy':
+            $server = $this->get(KOLAB_ATTR_FREEBUSYHOST);
+            if (!is_a($server, 'PEAR_Error') && !empty($server)) {
+                return $server;
+            }
+            return 'https://' . $this->getServer('homeserver') . '/freebusy';
         case 'imap':
             $server = $this->get(KOLAB_ATTR_IMAPHOST);
             if (!is_a($server, 'PEAR_Error') && !empty($server)) {
                 return $server;
             }
+        case 'homeserver':
         default:
             $home = $this->get(KOLAB_ATTR_HOMESERVER);
             return $home;
-- 
tg: (6938161..) t/framework/HK/GW/Kolab_Server/getFreebusyServer (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 7d8c722ee5e3307f7aa0c4b5f0580fb10beb7c8f
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 20:14:18 2009 +0000

    Added patch /release/HK-GW-Kolab_Server-getFreeBusyServer.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Storage_CatchPossibleError.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Storage/CatchPossibleError

Catch a possible error in Kolab_Storage.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index 2ee6983..2769446 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -667,12 +667,15 @@ class Kolab_Folder {
      *
      * @param Kolab_List $list  The handler for the list of folders.
      *
-     * @return Kolab_Data  The data handler.
+     * @return Kolab_Data|PEAR_Error  The data handler.
      */
     function &getData($object_type = null, $data_version = 1)
     {
         if (empty($object_type)) {
             $object_type = $this->getType();
+            if (is_a($object_type, 'PEAR_Error')) {
+                return $object_type;
+            }
         }
 
         if ($this->tainted) {
-- 
tg: (324e066..) t/framework/HK/GW/Kolab_Storage/CatchPossibleError (depends on: t/framework/HK/GW/Kolab_Server/RewriteExtend)
-- 
TOPGIT patch commit log
=======================

commit c5b10e7b77b6cc89480ed7c3ff90954fa286a41e
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 23:15:19 2009 +0000

    Added patch release/HK-GW-Kolab_Storage-Catch_Error.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Storage_FixTriggerOnFolderCreation.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Storage/FixTriggerOnFolderCreation

Fix triggering when creating a folder.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |   61 +++++++++++-----------
 1 files changed, 31 insertions(+), 30 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index df6e967..b39f678 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -348,7 +348,11 @@ class Kolab_Folder {
                                                   $result->getMessage()),
                                           __FILE__, __LINE__, PEAR_LOG_ERR);
                     }
-                    $result = $this->trigger();
+                    $imap->setAnnotation(KOLAB_ANNOT_FOLDER_TYPE, 
+                                         array('value.shared' => $this->_type),
+                                         $this->name);
+
+                    $result = $this->trigger($this->name);
                     if (is_a($result, 'PEAR_Error')) {
                         Horde::logMessage(sprintf('Failed triggering dummy folder: %s!',
                                                   $result->getMessage()),
@@ -378,19 +382,10 @@ class Kolab_Folder {
             unset($attributes['owner']);
         }
 
-        /** Now save the folder permissions */
-        if (isset($this->_perms)) {
-            $result = $this->_perms->save();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
         /** Handle the folder type */
         $folder_type = $this->_type . ($this->_default ? '.default' : '');
         if ($this->_type_annotation != $folder_type) {
-            $result = $this->_setAnnotation(KOLAB_ANNOT_FOLDER_TYPE,
-                                            $folder_type, $this->name);
+            $result = $this->_setAnnotation(KOLAB_ANNOT_FOLDER_TYPE, $folder_type);
             if (is_a($result, 'PEAR_Error')) {
                 $this->_type = null;
                 $this->_default = false;
@@ -411,8 +406,7 @@ class Kolab_Folder {
                 } else {
                     $entry = HORDE_ANNOT_SHARE_ATTR . $key;
                 }
-                $result = $this->_setAnnotation($entry,
-                                                $store, $this->name);
+                $result = $this->_setAnnotation($entry, $store);
                 if (is_a($result, 'PEAR_Error')) {
                     return $result;
                 }
@@ -420,6 +414,14 @@ class Kolab_Folder {
             $this->_attributes = $attributes;
         }
 
+        /** Now save the folder permissions */
+        if (isset($this->_perms)) {
+            $result = $this->_perms->save();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
         $result = $this->trigger();
         if (is_a($result, 'PEAR_Error')) {
             Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
@@ -442,13 +444,6 @@ class Kolab_Folder {
             return $result;
         }
 
-        $result = $this->trigger();
-        if (is_a($result, 'PEAR_Error')) {
-            Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
-                                      $this->name, $result->getMessage()),
-                              __FILE__, __LINE__, PEAR_LOG_ERR);
-        }
-
         return true;
     }
 
@@ -488,15 +483,19 @@ class Kolab_Folder {
     /**
      * Returns the subpath of the folder.
      *
+     * @param string $name Name of the folder that should be triggered.
+     *
      * @return string|PEAR_Error  The subpath of this folder.
      */
-    function getSubpath()
+    function getSubpath($name = null)
     {
-        if (!isset($this->_subpath)) {
-            if (!isset($this->name) && isset($this->new_name)) {
-                $name = $this->new_name;
-            } else {
-                $name = $this->name;
+        if (!isset($this->_subpath) || isset($name)) {
+            if (!isset($name)) {
+                if (!isset($this->name) && isset($this->new_name)) {
+                    $name = $this->new_name;
+                } else {
+                    $name = $this->name;
+                }
             }
 
             if (!preg_match(";(shared\.|INBOX[/]?|user/([^/]+)[/]?)([^@]*)(@.*)?;", $name, $matches)) {
@@ -1179,9 +1178,11 @@ class Kolab_Folder {
      * folder. This is currently only required for handling free/busy
      * information with Kolab.
      *
+     * @param string $name Name of the folder that should be triggered.
+     *
      * @return boolean|PEAR_Error True if successfull.
      */
-    function trigger()
+    function trigger($name = null)
     {
         global $conf;
 
@@ -1195,7 +1196,7 @@ class Kolab_Folder {
             return $owner;
         }
 
-        $subpath = $this->getSubpath();
+        $subpath = $this->getSubpath($name);
         if (is_a($subpath, 'PEAR_Error')) {
             return $subpath;
         }
@@ -1507,8 +1508,8 @@ class Kolab_Folder {
                 return $imap;
             }
             return $imap->setAnnotation($key,
-                                               array('value.shared' => $value),
-                                               $this->name);
+                                        array('value.shared' => $value),
+                                        $this->name);
         }
 
         if (!isset($this->_annotation_data)) {
-- 
tg: (4a6bd9f..) t/framework/HK/GW/Kolab_Storage/FixTriggerOnFolderCreation (depends on: t/framework/HK/GW/Kolab_Storage/FixTriggerOnFolderRename)
-- 
TOPGIT patch commit log
=======================

commit 534947cac14b588de735123d83f0b5061719013e
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:36:34 2009 +0000

    Added patch framework/HK-GW-Kolab_Storage-Fix_trigger_on_creation.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Storage_FixTriggerOnFolderRename.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Storage/FixTriggerOnFolderRename

Fix folder triggering on folder rename.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |   27 ++++++++++++++++++---
 1 files changed, 23 insertions(+), 4 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index a668a24..df6e967 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -337,11 +337,30 @@ class Kolab_Folder {
                 }
 
                 /**
-                 * Trigger the old folder name but ignore the error this will
-                 * elicit.  While we get an error because of the missing folder
-                 * the corresponding cache value will get purged.
+                 * Trigger the old folder on an empty IMAP folder.
                  */
-                $result = $this->trigger();
+                $session = &Horde_Kolab_Session::singleton();
+                $imap = &$session->getImap();
+                if (!is_a($imap, 'PEAR_Error')) {
+                    $result = $imap->create($this->name);
+                    if (is_a($result, 'PEAR_Error')) {
+                        Horde::logMessage(sprintf('Failed creating dummy folder: %s!',
+                                                  $result->getMessage()),
+                                          __FILE__, __LINE__, PEAR_LOG_ERR);
+                    }
+                    $result = $this->trigger();
+                    if (is_a($result, 'PEAR_Error')) {
+                        Horde::logMessage(sprintf('Failed triggering dummy folder: %s!',
+                                                  $result->getMessage()),
+                                          __FILE__, __LINE__, PEAR_LOG_ERR);
+                    }
+                    $result = $imap->delete($this->name);
+                    if (is_a($result, 'PEAR_Error')) {
+                        Horde::logMessage(sprintf('Failed deleting dummy folder: %s!',
+                                                  $result->getMessage()),
+                                          __FILE__, __LINE__, PEAR_LOG_ERR);
+                    }
+                }
 
                 $this->name     = $this->new_name;
                 $this->new_name = null;
-- 
tg: (ba404b5..) t/framework/HK/GW/Kolab_Storage/FixTriggerOnFolderRename (depends on: t/kronolith/HK/GW/CalendarRenaming)
-- 
TOPGIT patch commit log
=======================

commit 911c0394af77c700df40dc632e636b861c049a6c
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:33:08 2009 +0000

    Added patch framework/HK-GW-Kolab_Storage-Fix_rename_trigger.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Storage_Foreign__owner.patch.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Storage/Foreign_owner.patch

Correctly determine the foreign folder owners.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index 408ae54..ab9ecfd 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -420,7 +420,7 @@ class Kolab_Folder {
     function getOwner()
     {
         if (!isset($this->_owner)) {
-            if (!preg_match(";(shared\.|INBOX[/]?|user/([^/]+)/)([^@]+)(@.*)?;", $this->name, $matches)) {
+            if (!preg_match(";(shared\.|INBOX[/]?|user/([^/]+))([^@]+)(@.*)?;", $this->name, $matches)) {
                 return PEAR::raiseError(sprintf(_("Owner of folder %s cannot be determined."), $this->name));
             }
 
-- 
tg: (6938161..) t/framework/HK/GW/Kolab_Storage/Foreign_owner.patch (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 72fc4db48cc2448f1e5e476b1781c276aab28686
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 20:09:47 2009 +0000

    Added patch description.

commit 555c9aec2a85f9c0d2e2ef62a481590281ca75cb
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 19:56:26 2009 +0000

    Added patch release/HK-GW-Kolab_Storage-ForeignOwner.patch from the mercurial patch queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Storage_Restructuring__Fixes.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Storage/Restructuring_Fixes

Some fixes of issues caused by restructuring the Kolab modules.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |   15 +++++++++++----
 horde-webmail/lib/Horde/Kolab/Storage/List.php   |    8 ++++----
 2 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index 97a2603..2ee6983 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -238,8 +238,8 @@ class Kolab_Folder {
                 return $imap;
             }
 
-            $result = $this->_imap->connect(Auth::getAuth(),
-                                            Auth::getCredential('password'));
+            $result = $imap->connect(Auth::getAuth(),
+                                     Auth::getCredential('password'));
             if (is_a($result, 'PEAR_Error')) {
                 return $result;
             }
@@ -385,6 +385,7 @@ class Kolab_Folder {
 
                 $this->new_name = null;
                 $this->_title = null;
+                $this->_owner = null;
             }
         }
 
@@ -475,8 +476,14 @@ class Kolab_Folder {
     function getOwner()
     {
         if (!isset($this->_owner)) {
-            if (!preg_match(";(shared\.|INBOX[/]?|user/([^/]+))([^@]+)(@.*)?;", $this->name, $matches)) {
-                return PEAR::raiseError(sprintf(_("Owner of folder %s cannot be determined."), $this->name));
+            if (!isset($this->name) && isset($this->new_name)) {
+                $name = $this->new_name;
+            } else {
+                $name = $this->name;
+            }
+
+            if (!preg_match(";(shared\.|INBOX[/]?|user/([^/]+)[/]?)([^@]*)(@.*)?;", $name, $matches)) {
+                return PEAR::raiseError(sprintf(_("Owner of folder %s cannot be determined."), $name));
             }
 
             if (substr($matches[1], 0, 6) == 'INBOX/') {
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/List.php b/horde-webmail/lib/Horde/Kolab/Storage/List.php
index 6d31c19..8cfed66 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/List.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/List.php
@@ -475,19 +475,19 @@ class Kolab_List {
         $type = $folder->getType();
         if (is_a($type, 'PEAR_Error')) {
             Horde::logMessage(sprintf("Error while updating the Kolab folder list cache: %s.",
-                                      $type->getMessage()), __FILE__, __LINE__, PEAR_LOG_ERROR);
+                                      $type->getMessage()), __FILE__, __LINE__, PEAR_LOG_ERR);
             return;
         }
         $default = $folder->isDefault();
         if (is_a($default, 'PEAR_Error')) {
             Horde::logMessage(sprintf("Error while updating the Kolab folder list cache: %s.",
-                                      $default->getMessage()), __FILE__, __LINE__, PEAR_LOG_ERROR);
+                                      $default->getMessage()), __FILE__, __LINE__, PEAR_LOG_ERR);
             return;
         }
-        $owner = $folder->isDefault();
+        $owner = $folder->getOwner();
         if (is_a($owner, 'PEAR_Error')) {
             Horde::logMessage(sprintf("Error while updating the Kolab folder list cache: %s.",
-                                      $owner->getMessage()), __FILE__, __LINE__, PEAR_LOG_ERROR);
+                                      $owner->getMessage()), __FILE__, __LINE__, PEAR_LOG_ERR);
             return;
         }
 
-- 
tg: (4868827..) t/framework/HK/GW/Kolab_Storage/Restructuring_Fixes (depends on: t/framework/HK/GW/framework/Kolab/DeprecatedGetServer)
-- 
TOPGIT patch commit log
=======================

commit 47a6392250c3cc5112d25cf4b599cb9112cf8d32
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 21:51:53 2009 +0000

    Added patch release/HK-GW-Kolab_Format-MoreTesting.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Storage_ShareIdFix.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Storage/ShareIdFix

Fix deriving share id for default folders.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index 1da391b..6596559 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -265,8 +265,9 @@ class Kolab_Folder {
      */
     function getShareId()
     {
-        if ($this->isDefault()) {
-            return Auth::getAuth();
+        $current_user = Auth::getAuth();
+        if ($this->isDefault() && $this->getOwner() == $current_user) {
+            return $current_user;
         }
         return rawurlencode($this->name);
     }
-- 
tg: (1f4cc03..) t/framework/HK/GW/Kolab_Storage/ShareIdFix (depends on: t/framework/HK/GW/DB/SqliteErrorChecking)
-- 
TOPGIT patch commit log
=======================

commit 7b70f82b05f55cd3e8e450ade6848c33e6c6fc9c
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:54:22 2009 +0000

    Added patch framework/HK-GW-Kolab_Storage-Shared_default_folders.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Storage_Trigger.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Storage/Trigger

A better trigger implementation that gets called automatically
when storing stuff and is independant from the folder type.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab.php                |   50 +---------
 horde-webmail/lib/Horde/Kolab/Storage/Data.php   |   10 ++-
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |  125 ++++++++++++++++++++--
 3 files changed, 128 insertions(+), 57 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab.php b/horde-webmail/lib/Horde/Kolab.php
index 70e9fc1..4338b8e 100644
--- a/horde-webmail/lib/Horde/Kolab.php
+++ b/horde-webmail/lib/Horde/Kolab.php
@@ -711,7 +711,7 @@ class Kolab {
      * Returns an array of application-specific constants, that are used in
      * a generic manner throughout the library.
      *
-     * FIXME: Move to IMAP.php
+     * @deprecated
      *
      * @param string $app  The application whose constants to query.
      *
@@ -811,52 +811,4 @@ class Kolab {
             }
         }
     }
-
-    /**
-     * Triggers the freebusy update for the given share uid.
-     *
-     * @return boolean True if update was successfull, false otherwise.
-     */
-    function triggerFreeBusyUpdate($share_uid)
-    {
-        global $conf;
-
-        $folder_path = rawurldecode($share_uid);
-        if (!preg_match(";(shared\.|INBOX[/]?|user/([^/]+)/)([^@]+)(@.*)?;", $folder_path, $matches)) {
-            return PEAR::raiseError(sprintf(_("Owner of folder %s cannot be determined."), $folder_path));
-        }
-
-        if (substr($matches[1], 0, 6) == 'INBOX/') {
-            $owner =  Auth::getAuth();
-        } elseif (substr($matches[1], 0, 5) == 'user/') {
-            $domain = strstr(Auth::getAuth(), '@');
-            $user_domain = isset($matches[4]) ? $matches[4] : $domain;
-            $owner = $matches[2] . $user_domain;
-        } elseif ($matches[1] == 'shared.') {
-            return PEAR::raiseError(sprintf(_("Cannot trigger shared folder %s."), $folder_path));
-        }
-        $folder = isset($matches[3]) ? $matches[3] : '';
-
-        $url = 'https://' . Kolab::getServer("imap") .
-            '/freebusy/trigger/' . $owner . '/' . $folder . '.pfb';
-
-        // now start the request
-        $options['method'] = 'GET';
-        $options['timeout'] = 5;
-        $options['allowRedirects'] = true;
-
-        if (isset($conf['http']['proxy']) && !empty($conf['http']['proxy']['proxy_host'])) {
-            $options = array_merge($options, $conf['http']['proxy']);
-        }
-        require_once 'HTTP/Request.php';
-        $http = new HTTP_Request($url, $options);
-        $http->setBasicAuth(Auth::getAuth(), Auth::getCredential('password'));
-        @$http->sendRequest();
-        if ($http->getResponseCode() != 200) {
-            return PEAR::raiseError(sprintf(_("Unable to trigger free/busy update for folder %s on URL %s"),
-                                            $share_uid, $url));
-        }
-
-        return true;
-    }
 }
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Data.php b/horde-webmail/lib/Horde/Kolab/Storage/Data.php
index 2560e0a..4e3b39c 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Data.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Data.php
@@ -219,7 +219,7 @@ class Kolab_Data {
             return true;
         }
         foreach ($this->_cache->uids as $id => $object_uid) {
-            $result = $this->_folder->deleteMessage($id);
+            $result = $this->_folder->deleteMessage($id, false);
             if (is_a($result, 'PEAR_Error')) {
                 return $result;
             }
@@ -230,6 +230,14 @@ class Kolab_Data {
             unset($this->_cache->uids[$id]);
         }
         $this->_cache->save();
+
+        $result = $this->_folder->trigger();
+        if (is_a($result, 'PEAR_Error')) {
+            Horde::logMessage(sprintf('Failed triggering folder %s!',
+                                      $this->_folder->name),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+        }
+
         return true;
     }
 
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index ab9ecfd..827faa9 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -335,7 +335,22 @@ class Kolab_Folder {
                     return $result;
                 }
 
+                $result = $this->trigger();
+                if (is_a($result, 'PEAR_Error')) {
+                    Horde::logMessage(sprintf('Failed triggering folder %s!',
+                                              $this->name),
+                                      __FILE__, __LINE__, PEAR_LOG_ERR);
+                }
+
                 $this->name = $this->new_name;
+
+                $result = $this->trigger();
+                if (is_a($result, 'PEAR_Error')) {
+                    Horde::logMessage(sprintf('Failed triggering folder %s!',
+                                              $this->name),
+                                      __FILE__, __LINE__, PEAR_LOG_ERR);
+                }
+
                 $this->new_name = null;
                 $this->_title = null;
             }
@@ -409,6 +424,14 @@ class Kolab_Folder {
         if (is_a($result, 'PEAR_Error')) {
             return $result;
         }
+
+        $result = $this->trigger();
+        if (is_a($result, 'PEAR_Error')) {
+            Horde::logMessage(sprintf('Failed triggering folder %s!',
+                                      $this->name),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+        }
+
         return true;
     }
 
@@ -638,11 +661,12 @@ class Kolab_Folder {
     /**
      * Delete the specified message from this folder.
      *
-     * @param  string $id IMAP id of the message to be deleted.
+     * @param  string  $id      IMAP id of the message to be deleted.
+     * @param  boolean $trigger Should the folder be triggered?
      *
      * @return boolean|PEAR_Error True if successful.
      */
-    function deleteMessage($id)
+    function deleteMessage($id, $trigger = true)
     {
         if (is_a($this->_imap, 'PEAR_Error')) {
             return $this->_imap;
@@ -663,6 +687,16 @@ class Kolab_Folder {
         if (is_a($result, 'PEAR_Error')) {
             return $result;
         }
+
+        if ($trigger) {
+            $result = $this->trigger();
+            if (is_a($result, 'PEAR_Error')) {
+                Horde::logMessage(sprintf('Failed triggering folder %s!',
+                                          $this->name),
+                                  __FILE__, __LINE__, PEAR_LOG_ERR);
+            }
+        }
+
         return true;
     }
 
@@ -695,6 +729,14 @@ class Kolab_Folder {
         if (is_a($result, 'PEAR_Error')) {
             return $result;
         }
+
+        $result = $this->trigger();
+        if (is_a($result, 'PEAR_Error')) {
+            Horde::logMessage(sprintf('Failed triggering folder %s!',
+                                      $this->name),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+        }
+
         return true;
     }
 
@@ -713,7 +755,16 @@ class Kolab_Folder {
             return $folder;
         }
         $folder->tainted = true;
-        return $this->moveMessage($id, $folder->name);
+
+        $success = $this->moveMessage($id, $folder->name);
+
+        $result = $folder->trigger();
+        if (is_a($result, 'PEAR_Error')) {
+            Horde::logMessage(sprintf('Failed triggering folder %s!',
+                                      $this->name),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+        }
+        return $success;
     }
 
     /**
@@ -831,6 +882,14 @@ class Kolab_Folder {
                 return $result;
             }
         }
+
+        $result = $this->trigger();
+        if (is_a($result, 'PEAR_Error')) {
+            Horde::logMessage(sprintf('Failed triggering folder %s!',
+                                      $this->name),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+        }
+
         return true;
     }
 
@@ -951,6 +1010,58 @@ class Kolab_Folder {
     }
 
     /**
+     * Triggers any required updates after changes within the
+     * folder. This is currently only required for handling free/busy
+     * information with Kolab.
+     *
+     * @return boolean|PEAR_Error True if successfull.
+     */
+    function trigger()
+    {
+        global $conf;
+
+        $type =  $this->getType();
+        if (is_a($type, 'PEAR_Error')) {
+            return $type;
+        }
+
+        $owner = $this->getOwner();
+        if (is_a($owner, 'PEAR_Error')) {
+            return $owner;
+        }
+
+        switch($type) {
+        case 'event':
+            $session = &Horde_Kolab_Session::singleton();
+            $url = sprintf('%s/trigger/%s/%s.pfb',
+                           $session->freebusy_server, $owner, $this->name);
+            break;
+        default:
+            return true;
+        }
+
+        // now start the request
+        $options['method'] = 'GET';
+        $options['timeout'] = 5;
+        $options['allowRedirects'] = true;
+
+        if (isset($conf['http']['proxy']) && !empty($conf['http']['proxy']['proxy_host'])) {
+            $options = array_merge($options, $conf['http']['proxy']);
+        }
+
+        require_once 'HTTP/Request.php';
+        $http = new HTTP_Request($url, $options);
+        $http->setBasicAuth(Auth::getAuth(), Auth::getCredential('password'));
+        @$http->sendRequest();
+        if ($http->getResponseCode() != 200) {
+            return PEAR::raiseError(sprintf(_("Unable to trigger free/busy update for folder %s on URL %s"),
+                                            $this->name, $url));
+        }
+
+        return true;
+    }
+
+    /**
      * Checks to see if a user has a given permission.
      *
      * @param string $userid       The userid of the user.
@@ -1056,7 +1167,7 @@ class Kolab_Folder {
             if (!is_a($acl, 'PEAR_Error')) {
                 return $acl;
             }
-            
+
             $my_rights = $this->_imap->getMyrights($this->name);
             if (is_a($my_rights, 'PEAR_Error')) {
                 return $my_rights;
@@ -1124,7 +1235,7 @@ class Kolab_Folder {
     {
         $this->_annotation_data = $this->getData('annotation');
     }
-    
+
 
     /**
      * Get an annotation value of this folder.
@@ -1144,7 +1255,7 @@ class Kolab_Folder {
             return $this->_imap->getAnnotation($key, 'value.shared',
                                                $this->name);
         }
-        
+
         if (!isset($this->_annotation_data)) {
             $this->_getAnnotationData();
         }
@@ -1180,7 +1291,7 @@ class Kolab_Folder {
                                                array('value.shared' => $value),
                                                $this->name);
         }
-        
+
         if (!isset($this->_annotation_data)) {
             $this->_getAnnotationData();
         }
-- 
tg: (a47b2ab..) t/framework/HK/GW/Kolab_Storage/Trigger (depends on: t/framework/HK/GW/Kolab_Storage/Foreign_owner.patch)
-- 
TOPGIT patch commit log
=======================

commit f53c2ff7849165fa9cbf59d27a36276023d693c4
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 20:21:25 2009 +0000

    Added patch release/HK-GW-Kolab_Storage-Trigger.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Kolab__Storgae_FixedUpdateTriggering.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Kolab_Storgae/FixedUpdateTriggering

Complete/fix the triggering when updating folders.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php |  143 +++++++++++++++++-----
 1 files changed, 110 insertions(+), 33 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index ddcfbe8..64a438b 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -110,6 +110,13 @@ class Kolab_Folder {
     var $_owner;
 
     /**
+     * The pure folder.
+     *
+     * @var string
+     */
+    var $_subpath;
+
+    /**
      * Additional Horde folder attributes.
      *
      * @var array
@@ -330,23 +337,15 @@ class Kolab_Folder {
 
                 $result = $this->trigger();
                 if (is_a($result, 'PEAR_Error')) {
-                    Horde::logMessage(sprintf('Failed triggering folder %s!',
-                                              $this->name),
-                                      __FILE__, __LINE__, PEAR_LOG_ERR);
-                }
-
-                $this->name = $this->new_name;
-
-                $result = $this->trigger();
-                if (is_a($result, 'PEAR_Error')) {
-                    Horde::logMessage(sprintf('Failed triggering folder %s!',
-                                              $this->name),
+                    Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
+                                              $this->name, $result->getMessage()),
                                       __FILE__, __LINE__, PEAR_LOG_ERR);
                 }
 
+                $this->name     = $this->new_name;
                 $this->new_name = null;
-                $this->_title = null;
-                $this->_owner = null;
+                $this->_title   = null;
+                $this->_owner   = null;
             }
         }
 
@@ -400,6 +399,14 @@ class Kolab_Folder {
             }
             $this->_attributes = $attributes;
         }
+
+        $result = $this->trigger();
+        if (is_a($result, 'PEAR_Error')) {
+            Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
+                                      $this->name, $result->getMessage()),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+        }
+
         return true;
     }
 
@@ -417,8 +424,8 @@ class Kolab_Folder {
 
         $result = $this->trigger();
         if (is_a($result, 'PEAR_Error')) {
-            Horde::logMessage(sprintf('Failed triggering folder %s!',
-                                      $this->name),
+            Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
+                                      $this->name, $result->getMessage()),
                               __FILE__, __LINE__, PEAR_LOG_ERR);
         }
 
@@ -443,6 +450,8 @@ class Kolab_Folder {
                 return PEAR::raiseError(sprintf(_("Owner of folder %s cannot be determined."), $name));
             }
 
+            $this->_subpath = $matches[3];
+
             if (substr($matches[1], 0, 6) == 'INBOX/') {
                 $this->_owner = Auth::getAuth();
             } elseif (substr($matches[1], 0, 5) == 'user/') {
@@ -457,6 +466,30 @@ class Kolab_Folder {
     }
 
     /**
+     * Returns the subpath of the folder.
+     *
+     * @return string|PEAR_Error  The subpath of this folder.
+     */
+    function getSubpath()
+    {
+        if (!isset($this->_subpath)) {
+            if (!isset($this->name) && isset($this->new_name)) {
+                $name = $this->new_name;
+            } else {
+                $name = $this->name;
+            }
+
+            if (!preg_match(";(shared\.|INBOX[/]?|user/([^/]+)[/]?)([^@]*)(@.*)?;", $name, $matches)) {
+                return PEAR::raiseError(sprintf(_("Subpath of folder %s cannot be determined."), $name));
+            }
+
+            $this->_subpath = $matches[3];
+
+        }
+        return $this->_subpath;
+    }
+
+    /**
      * Returns a readable title for this folder.
      *
      * @return string  The folder title.
@@ -684,8 +717,8 @@ class Kolab_Folder {
         if ($trigger) {
             $result = $this->trigger();
             if (is_a($result, 'PEAR_Error')) {
-                Horde::logMessage(sprintf('Failed triggering folder %s!',
-                                          $this->name),
+                Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
+                                          $this->name, $result->getMessage()),
                                   __FILE__, __LINE__, PEAR_LOG_ERR);
             }
         }
@@ -727,8 +760,8 @@ class Kolab_Folder {
 
         $result = $this->trigger();
         if (is_a($result, 'PEAR_Error')) {
-            Horde::logMessage(sprintf('Failed triggering folder %s!',
-                                      $this->name),
+            Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
+                                      $this->name, $result->getMessage()),
                               __FILE__, __LINE__, PEAR_LOG_ERR);
         }
 
@@ -753,10 +786,10 @@ class Kolab_Folder {
 
         $success = $this->moveMessage($id, $folder->name);
 
-        $result = $folder->trigger();
+        $result = $this->trigger();
         if (is_a($result, 'PEAR_Error')) {
-            Horde::logMessage(sprintf('Failed triggering folder %s!',
-                                      $this->name),
+            Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
+                                      $this->name, $result->getMessage()),
                               __FILE__, __LINE__, PEAR_LOG_ERR);
         }
         return $success;
@@ -870,7 +903,7 @@ class Kolab_Folder {
                                 }
                                 $mime_message->_generateIdMap($mime_message->_parts);
                             }
-                        }                        
+                        }
                     }
                 }
             }
@@ -991,8 +1024,8 @@ class Kolab_Folder {
 
         $result = $this->trigger();
         if (is_a($result, 'PEAR_Error')) {
-            Horde::logMessage(sprintf('Failed triggering folder %s!',
-                                      $this->name),
+            Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
+                                      $this->name, $result->getMessage()),
                               __FILE__, __LINE__, PEAR_LOG_ERR);
         }
 
@@ -1142,17 +1175,38 @@ class Kolab_Folder {
             return $owner;
         }
 
+        $subpath = $this->getSubpath();
+        if (is_a($subpath, 'PEAR_Error')) {
+            return $subpath;
+        }
+
         switch($type) {
         case 'event':
             $session = &Horde_Kolab_Session::singleton();
             $url = sprintf('%s/trigger/%s/%s.pfb',
-                           $session->freebusy_server, $owner, $this->name);
+                           $session->freebusy_server, $owner, $subpath);
             break;
         default:
             return true;
         }
 
-        // now start the request
+        $result = $this->triggerUrl($url);
+        if (is_a($result, 'PEAR_Error')) {
+            return PEAR::raiseError(sprintf(_("Failed triggering folder %s. Error was: %s"),
+                                            $this->name, $result->getMessage()));
+        }
+        return $result;
+    }
+
+    /**
+     * Triggers a URL.
+     *
+     * @param string $url The URL to be triggered.
+     *
+     * @return boolean|PEAR_Error True if successfull.
+     */
+    function triggerUrl($url)
+    {
         $options['method'] = 'GET';
         $options['timeout'] = 5;
         $options['allowRedirects'] = true;
@@ -1166,10 +1220,9 @@ class Kolab_Folder {
         $http->setBasicAuth(Auth::getAuth(), Auth::getCredential('password'));
         @$http->sendRequest();
         if ($http->getResponseCode() != 200) {
-            return PEAR::raiseError(sprintf(_("Unable to trigger free/busy update for folder %s on URL %s"),
-                                            $this->name, $url));
+            return PEAR::raiseError(sprintf(_("Unable to trigger URL %s. Response: %s"),
+                                            $url, $http->getResponseCode()));
         }
-
         return true;
     }
 
@@ -1315,7 +1368,19 @@ class Kolab_Folder {
             return true;
         }
 
-        return $imap->setACL($this->name, $user, $acl);
+        $iresult = $imap->setACL($this->name, $user, $acl);
+        if (is_a($iresult, 'PEAR_Error')) {
+            return $iresult;
+        }
+
+        $result = $this->trigger();
+        if (is_a($result, 'PEAR_Error')) {
+            Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
+                                      $this->name, $result->getMessage()),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+        }
+
+        return $iresult;
     }
 
     /**
@@ -1339,7 +1404,19 @@ class Kolab_Folder {
             return true;
         }
 
-        return $imap->deleteACL($this->name, $user);
+        $iresult = $imap->deleteACL($this->name, $user);
+        if (is_a($iresult, 'PEAR_Error')) {
+            return $iresult;
+        }
+
+        $result = $this->trigger();
+        if (is_a($result, 'PEAR_Error')) {
+            Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
+                                      $this->name, $result->getMessage()),
+                              __FILE__, __LINE__, PEAR_LOG_ERR);
+        }
+
+        return $iresult;
     }
 
 
@@ -1349,7 +1426,7 @@ class Kolab_Folder {
      *
      * @return array|PEAR_Error  The anotations of this folder.
      */
-    function _getAnnotationData() 
+    function _getAnnotationData()
     {
         $this->_annotation_data = $this->getData('annotation');
     }
-- 
tg: (2cf9df2..) t/framework/HK/GW/Kolab_Storgae/FixedUpdateTriggering (depends on: t/framework/HK/GW/Kolab_Server/ImprovedServerFallbacks)
-- 
TOPGIT patch commit log
=======================

commit 18952be0440a4f12a6ea15bb4683f13d1cc9f061
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:18:48 2009 +0000

    Added patch framework/HK-GW-Kolab_Storage-Trigger_fix.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Prefs__KolabImapApplicationTag.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Prefs_KolabImapApplicationTag

Switches from the "categories" tag in the Kolab IMAP preferences
driver to the new "application" tag.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 .../lib/Horde/Kolab/Format/XML/hprefs.php          |   48 ++++++++++++++++++++
 horde-webmail/lib/Horde/Prefs/kolab_imap.php       |    4 +-
 2 files changed, 50 insertions(+), 2 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML/hprefs.php b/horde-webmail/lib/Horde/Kolab/Format/XML/hprefs.php
index e646ad6..22a94bc 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML/hprefs.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML/hprefs.php
@@ -46,6 +46,10 @@ class Horde_Kolab_Format_XML_hprefs extends Horde_Kolab_Format_XML {
         /** Specific preferences fields, in kolab format specification order
          */
         $this->_fields_specific = array(
+            'application' => array (
+                'type'    => HORDE_KOLAB_XML_TYPE_STRING,
+                'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
+            ),
             'pref' => array(
                 'type'    => HORDE_KOLAB_XML_TYPE_MULTIPLE,
                 'value'   => HORDE_KOLAB_XML_VALUE_MAYBE_MISSING,
@@ -58,4 +62,48 @@ class Horde_Kolab_Format_XML_hprefs extends Horde_Kolab_Format_XML {
 
         parent::Horde_Kolab_Format_XML();
     }
+
+    /**
+     * Load an object based on the given XML string.
+     *
+     * @param string $xmltext  The XML of the message as string.
+     *
+     * @return array|PEAR_Error The data array representing the object.
+     */
+    function load(&$xmltext)
+    {
+        $object = parent::load($xmltext);
+
+        if (empty($object['application'])) {
+            if (!empty($object['categories'])) {
+                $object['application'] = $object['categories'];
+                unset($object['categories']);
+            } else {
+                return PEAR::raiseError('Preferences XML object is missing an application setting.');
+            }
+        }
+
+        return $object;
+    }
+
+    /**
+     * Convert the data to a XML string.
+     *
+     * @param array $attributes  The data array representing the note.
+     *
+     * @return string|PEAR_Error The data as XML string.
+     */
+    function save($object)
+    {
+        if (empty($object['application'])) {
+            if (!empty($object['categories'])) {
+                $object['application'] = $object['categories'];
+                unset($object['categories']);
+            } else {
+                return PEAR::raiseError('Preferences XML object is missing an application setting.');
+            }
+        }
+
+        return parent::save($object);
+    }
 }
diff --git a/horde-webmail/lib/Horde/Prefs/kolab_imap.php b/horde-webmail/lib/Horde/Prefs/kolab_imap.php
index db332c6..4a24e6a 100644
--- a/horde-webmail/lib/Horde/Prefs/kolab_imap.php
+++ b/horde-webmail/lib/Horde/Prefs/kolab_imap.php
@@ -163,7 +163,7 @@ class Prefs_kolab_imap extends Prefs {
         }
 
         foreach ($prefs as $pref) {
-            if ($pref['categories'] == $scope) {
+            if ($pref['application'] == $scope) {
                 return $pref;
             }
         }
@@ -218,7 +218,7 @@ class Prefs_kolab_imap extends Prefs {
             }
 
             $object = array('uid' => $prefs_uid,
-                            'categories' => $scope,
+                            'application' => $scope,
                             'pref' => $new_values);
 
             $result = $this->_connection->_storage->save($object, $old_uid);
-- 
tg: (6938161..) t/framework/HK/GW/Prefs_KolabImapApplicationTag (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 68891b53f52ce54e318990731b1e6c7ecb5d3544
Author: Gunnar Wrobel <p at rdus.de>
Date:   Thu Jan 29 22:07:23 2009 +0000

    Added patch release/HK-GW-Prefs-KolabImapApplicationTag.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_Vfs_KolabDriver.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/Vfs/KolabDriver

Support the Horde virtual filesystem with Kolab.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/VFS/kolab.php |  631 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 631 insertions(+), 0 deletions(-)

diff --git a/horde-webmail/lib/VFS/kolab.php b/horde-webmail/lib/VFS/kolab.php
new file mode 100644
index 0000000..e8b75c5
--- /dev/null
+++ b/horde-webmail/lib/VFS/kolab.php
@@ -0,0 +1,631 @@
+<?php
+
+/** We need the Kolab Storage library for accessing the server. */
+require_once 'Horde/Kolab/Storage/List.php';
+
+/**
+ * VFS implementation for a Kolab IMAP server.
+ *
+ * $Horde:$
+ *
+ * Copyright 2002-2007 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author  Gunnar Wrobel <wrobel at pardus.de>
+ * @package VFS
+ */
+class VFS_kolab extends VFS {
+
+    /**
+     * Variable holding the connection to the Kolab storage system.
+     *
+     * @var Horde_Kolab_IMAP
+     */
+    var $_imap = false;
+
+    /**
+     * Cache for the list of folders.
+     *
+     * @var array
+     */
+    var $_folders;
+
+    /**
+     * Retrieves a file from the VFS.
+     *
+     * @param string $path  The pathname to the file.
+     * @param string $name  The filename to retrieve.
+     *
+     * @return string  The file data.
+     */
+    function read($path, $name)
+    {
+        list($app, $uid) = $this->_getAppUid($path);
+        if ($app && $uid) {
+            $handler = &$this->_getAppHandler($app, $uid);
+            if (is_a($handler, 'PEAR_Error')) {
+                return $handler;
+            }
+            $object = $handler->getObject($uid);
+
+            if (isset($object['_attachments'][$name])) {
+                return $handler->getAttachment($object['_attachments'][$name]['key']);
+            }
+        }
+
+        //FIXME
+        if ($this->isFolder(dirname($path), basename($path))) {
+            $session = &Horde_Kolab_Session::singleton();
+            $imap = &$session->getImap();
+
+            $result = $imap->select(substr($path,1));
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+
+            $file = explode('/', $name);
+
+            return $this->_getFile($imap, $file[0], $file[1]);
+        }
+        return '';
+    }
+
+    /**
+     * Stores a file in the VFS.
+     *
+     * @param string $path         The path to store the file in.
+     * @param string $name         The filename to use.
+     * @param string $tmpFile      The temporary file containing the data to
+     *                             be stored.
+     * @param boolean $autocreate  Automatically create directories?
+     *
+     * @return mixed  True on success or a PEAR_Error object on failure.
+     */
+    function write($path, $name, $tmpFile, $autocreate = false)
+    {
+        list($app, $uid) = $this->_getAppUid($path);
+        if ($app) {
+            $handler = &$this->_getAppHandler($app, $uid);
+            if (is_a($handler, 'PEAR_Error')) {
+                return $handler;
+            }
+            $object = $handler->getObject($uid);
+            $object['_attachments'][$name]['path'] = $tmpFile;
+            if (empty($object['link-attachment'])) {
+                $object['link-attachment'] = array($name);
+            } else {
+                $object['link-attachment'][] = $name;
+            }
+
+            return $handler->save($object, $uid);
+        }
+
+        if ($autocreate && !$this->isFolder(dirname($path), basename($path))) {
+            $result = $this->autocreatePath($path);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        //FIXME
+        return PEAR::raiseError(_("Not supported."));
+    }
+
+    /**
+     * Deletes a file from the VFS.
+     *
+     * @abstract
+     *
+     * @param string $path  The path to delete the file from.
+     * @param string $name  The filename to delete.
+     *
+     * @return mixed  True on success or a PEAR_Error object on failure.
+     */
+    function deleteFile($path, $name)
+    {
+        list($app, $uid) = $this->_getAppUid($path);
+        if ($app) {
+            $handler = &$this->_getAppHandler($app, $uid);
+            if (is_a($handler, 'PEAR_Error')) {
+                return $handler;
+            }
+            $object = $handler->getObject($uid);
+            if (!isset($object['_attachments'][$name])) {
+                return PEAR::raiseError(_("Unable to delete VFS file."));
+            }
+            unset($object['_attachments'][$name]);
+            $object['link-attachment'] = array_values(array_diff($object['link-attachment'], array($name)));
+
+            return $handler->save($object, $uid);
+        }
+
+        //FIXME
+        return PEAR::raiseError(_("Not supported."));
+    }
+
+    /**
+     * Creates a folder on the VFS.
+     *
+     * @param string $path  The parent folder.
+     * @param string $name  The name of the new folder.
+     *
+     * @return mixed  True on success or a PEAR_Error object on failure.
+     */
+    function createFolder($path, $name)
+    {
+        $list = Kolab_List::singleton();
+        $folder = $this->_getFolder($path, $name);
+
+        $object = $list->getNewFolder();
+        $object->setName($folder);
+
+        $result = $object->save(array('type' => 'h-file'));
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+
+        $this->_folders = null;
+    }
+
+     /**
+     * Deletes a folder from the VFS.
+     *
+     * @param string $path        The parent folder.
+     * @param string $name        The name of the folder to delete.
+     * @param boolean $recursive  Force a recursive delete?
+     *
+     * @return mixed  True on success or a PEAR_Error object on failure.
+     */
+    function deleteFolder($path, $name, $recursive = false)
+    {
+        if ($recursive) {
+            $result = $this->emptyFolder($path . '/' . $name);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        } else {
+            $list = $this->listFolder($path . '/' . $name, null, false);
+            if (is_a($list, 'PEAR_Error')) {
+                return $list;
+            }
+            if (count($list)) {
+                return PEAR::raiseError(sprintf(_("Unable to delete %s, the directory is not empty"),
+                                                $path . '/' . $name));
+            }
+        }
+
+        list($app, $uid) = $this->_getAppUid($path . '/' . $name);
+        if ($app) {
+            /**
+             * Objects provide no real folders and we don't delete them.
+             */
+            return true;
+        }
+
+        $folders = $this->_getFolders();
+        if (is_a($folders, 'PEAR_Error')) {
+            return $folders;
+        }
+        $folder = $this->_getFolder($path, $name);
+
+        if (!empty($folders['/' . $folder])) {
+            $result = $folders['/' . $folder]->delete();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+
+            $this->_folders = null;
+
+            return true;
+        }
+        return PEAR::raiseError(sprintf('No such folder %s!', '/' . $folder));
+    }
+
+    /**
+     * Recursively remove all files and subfolders from the given
+     * folder.
+     *
+     * @param string $path  The path of the folder to empty.
+     *
+     * @return mixed  True on success or a PEAR_Error object on failure.
+     */
+    function emptyFolder($path)
+    {
+        // Get and delete the subfolders.
+        $list = $this->listFolder($path, null, false, true);
+        if (is_a($list, 'PEAR_Error')) {
+            return $list;
+        }
+        foreach ($list as $folder) {
+            $result = $this->deleteFolder($path, $folder['name'], true);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        // Only files are left, get and delete them.
+        $list = $this->listFolder($path, null, false);
+        if (is_a($list, 'PEAR_Error')) {
+            return $list;
+        }
+        foreach ($list as $file) {
+            $result = $this->deleteFile($path, $file['name']);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Returns an an unsorted file list of the specified directory.
+     *
+     * @param string $path       The path of the directory.
+     * @param mixed $filter      String/hash to filter file/dirname on.
+     * @param boolean $dotfiles  Show dotfiles?
+     * @param boolean $dironly   Show only directories?
+     *
+     * @return array  File list on success or PEAR_Error on failure.
+     */
+    function _listFolder($path = '', $filter = null, $dotfiles = true,
+                         $dironly = false)
+    {
+        list($app, $uid) = $this->_getAppUid($path);
+        if ($app) {
+            if ($dironly) {
+                /** 
+                 * Objects dont support directories.
+                 */
+                return array();
+            }
+            if ($uid) {
+                $handler = &$this->_getAppHandler($app, $uid);
+                if (is_a($handler, 'PEAR_Error')) {
+                    return $handler;
+                }
+                $object = $handler->getObject($uid);
+
+                $filenames = isset($object['_attachments']) ? array_keys($object['_attachments']) : array();
+            } else {
+                $filenames = $this->_getAppUids($app);
+            }
+
+            $owner = Auth::getAuth();
+
+            $files = array();
+            $file = array();
+            foreach($filenames as $filename) {
+                
+                $name = explode('.', $filename);
+
+                if (count($name) == 1) {
+                    $file['type'] = '**none';
+                } else {
+                    $file['type'] = VFS::strtolower($name[count($name) - 1]);
+                }
+
+                $file['size'] = '-1';
+                $file['name'] = $filename;
+                $file['group'] = 'none';
+                $file['owner'] = $owner;
+                $file['date'] = 0;
+                $file['perms'] = 'rwxrwx---';
+
+                $files[$file['name']] = $file;
+            }
+            return $files;
+        }
+
+        $owner = Auth::getAuth();
+
+        $files = array();
+
+        $folders = $this->listFolders($path, $filter, $dotfiles);
+        if (is_a($folders, 'PEAR_Error')) {
+            return $folders;
+        }
+
+        $list = $this->_getFolders();
+
+        $file = array();
+        foreach ($folders as $folder) {
+            $file['type'] = '**dir';
+            $file['size'] = -1;
+            $file['name'] = $folder['abbrev'];
+            //FIXME
+            $file['group'] = 'none';
+            //FIXME
+            $file['owner'] = $owner;
+            //FIXME
+            $file['date'] = 0;
+            //FIXME
+            $file['perms'] = 'rwxrwx---';
+
+            $files[$file['name']] = $file;
+        }
+
+        if (!$dironly
+            && $this->isFolder(basename($path), basename($path))
+            && !empty($list[$path])) {
+
+            $session = &Horde_Kolab_Session::singleton();
+            $imap = &$session->getImap();
+
+            $result = $imap->select(substr($path, 1));
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+
+            $uids = $imap->getUids();
+            if (is_a($uids, 'PEAR_Error')) {
+                return $uids;
+            }
+
+            foreach ($uids as $uid) {
+                $mFiles = $this->_parseMessage($imap, $uid);
+                if (is_a($mFiles, 'PEAR_Error')) {
+                    return $mFiles;
+                }
+                $result = array_merge($files, $mFiles);
+                $files = $result;
+            }
+        }
+
+        return $files;
+    }
+
+    function _parseMessage($imap, $uid)
+    {
+        $result = $imap->getMessageHeader($uid);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+
+        $raw_headers = $result;
+
+        $body = $imap->getMessageBody($uid);
+        if (is_a($body, 'PEAR_Error')) {
+            return $body;
+        }
+
+        $raw_message = $raw_headers . $body;
+
+        $mime_message = &MIME_Structure::parseTextMIMEMessage($raw_message);
+        $parts = $mime_message->contentTypeMap();
+
+        $owner = Auth::getAuth();
+
+        $files = array();
+        $file = array();
+
+        foreach ($parts as $part_id => $disposition) {
+            $part = $mime_message->getPart($part_id);
+
+            $filename = $part->getDispositionParameter('filename');
+
+            if ($filename) {
+                $file['type'] = '**file';
+                $file['size'] = $part->getSize();
+                $file['name'] = $uid . '/' . $filename;
+                //FIXME
+                $file['group'] = 'none';
+                //FIXME
+                $file['owner'] = $owner;
+                //FIXME
+                $file['date'] = 0;
+                //FIXME
+                $file['perms'] = 'rwxrwx---';
+
+                $files[$file['name']] = $file;
+            }
+
+        }
+
+        return $files;
+    }
+
+
+    function _getFile($imap, $uid, $filename)
+    {
+        $result = $imap->getMessageHeader($uid);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+
+        $raw_headers = $result;
+
+        $body = $imap->getMessageBody($uid);
+        if (is_a($body, 'PEAR_Error')) {
+            return $body;
+        }
+
+        $raw_message = $raw_headers . $body;
+
+        $mime_message = &MIME_Structure::parseTextMIMEMessage($raw_message);
+        $parts = $mime_message->contentTypeMap();
+
+        $owner = Auth::getAuth();
+
+        $files = array();
+        $file = array();
+
+        foreach ($parts as $part_id => $disposition) {
+            $part = $mime_message->getPart($part_id);
+
+            $f= $part->getDispositionParameter('filename');
+
+            if ($f && $f == $filename ) {
+                return $part->transferDecode();
+            }
+        }
+        return '';
+    }
+
+
+    /**
+     * Returns a sorted list of folders in the specified directory.
+     *
+     * @param string $path         The path of the directory to get the
+     *                             directory list for.
+     * @param mixed $filter        Hash of items to filter based on folderlist.
+     * @param boolean $dotfolders  Include dotfolders?
+     *
+     * @return mixed  Folder list on success or a PEAR_Error object on failure.
+     */
+    function listFolders($path = '', $filter = null, $dotfolders = true)
+    {
+        if (substr($path, -1) != '/') {
+            $path .= '/';
+        }
+
+        $aFolders = array();
+        $aFolder = array();
+
+        if ($dotfolders && $path != '/') {
+            $aFolder['val'] = dirname($path);
+            $aFolder['abbrev'] = '..';
+            $aFolder['label'] = '..';
+
+            $aFolders[$aFolder['val']] = $aFolder;
+        }
+
+        $folders = $this->_getFolders();
+
+        $base_len = strlen($path);
+        foreach (array_keys($folders) as $folder) {
+            if (substr($folder, 0, $base_len) == $path) {
+                $name = substr($folder, $base_len);
+                if (!strpos($name, '/')) {
+                    $aFolder['val']	= $folder;
+                    $aFolder['abbrev'] = $name;
+                    $aFolder['label'] = $folder;
+                    $aFolders[$aFolder['val']] = $aFolder;
+                }
+            }
+        }
+
+        ksort($aFolders);
+        return $aFolders;
+    }
+
+    function _getFolder($path, $name)
+    {
+        $folder = $path . '/' . $name;
+
+        while (substr($folder, 0, 1) == '/') {
+            $folder = substr($folder, 1);
+        }
+
+        while (substr($folder, -1) == '/') {
+            $folder = substr($folder, 0, -1);
+        }
+
+        return $folder;
+    }
+
+
+    function _getFolders()
+    {
+        if (!isset($this->_folders)) {
+
+            $vfs_folders = array();
+
+            $list = Kolab_List::singleton();
+
+            if (!empty($this->_params['all_folders'])) {
+                $folders = $list->getFolders();
+            } else {
+                $folders = $list->getByType('h-file');
+            }
+
+            if (is_a($folders, 'PEAR_Error')) {
+                return $folders;
+            }
+
+            foreach ($folders as $folder) {
+                $vfs_folders['/' . $folder->name] = &$folder;
+            }
+
+            foreach (array_keys($vfs_folders) as $name) {
+                $dir = dirname($name);
+                while ($dir != '/') {
+                    if (!isset($vfs_folders[$dir])) {
+                        $vfs_folders[$dir] = null;
+                    }
+                    $dir = dirname($dir);
+                }
+            }
+            $this->_folders = $vfs_folders;
+        }
+        return $this->_folders;
+    }
+
+    function _getAppUid($path)
+    {
+        if (defined('TURBA_VFS_PATH')
+            && substr($path, 0, strlen(TURBA_VFS_PATH)) == TURBA_VFS_PATH) {
+            return array('turba', substr($path, strlen(TURBA_VFS_PATH) + 1));
+        }
+        return array(false, false);
+    }
+
+    function &_getAppHandler($app, $uid)
+    {
+        global $registry;
+
+        switch ($app) {
+        case 'turba':
+            $sources = $registry->call('contacts/sources',
+                                       array('writeable' => true));
+            $fields = array();
+            foreach (array_keys($sources) as $source) {
+                $fields[$source] = array('__uid');
+            }
+            $result = $registry->call('contacts/search',
+                                      array('names' => $uid,
+                                            'sources' => array_keys($sources),
+                                            'fields' => $fields));
+            $list = Kolab_List::singleton();
+            $share = &$list->getByShare($result[$uid][0]['source'], 'contact');
+            if (is_a($share, 'PEAR_Error')) {
+                return $share;
+            }
+            return $share->getData();
+        }
+    }
+
+    function _getAppUids($app)
+    {
+        global $registry;
+
+        switch ($app) {
+        case 'turba':
+            $sources = $registry->call('contacts/sources',
+                                       array('writeable' => true));
+            $result = $registry->call('contacts/search',
+                                      array('names' => '',
+                                            'sources' => array_keys($sources),
+                                            'fields' => array()));
+            $uids = array();
+            foreach ($result[''] as $contact) {
+                if (isset($contact['__uid'])) {
+                    $uids[] = $contact['__uid'];
+                }
+            }
+            return $uids;
+        }
+    }
+
+    /**
+     * Connecting is not required for this driver.
+     *
+     * @access private
+     *
+     * @return NULL
+     */
+    function _connect()
+    {
+    }
+}
-- 
tg: (864fbe8..) t/framework/HK/GW/Vfs/KolabDriver (depends on: t/framework/HK/GW/Kolab/AttachmentSupport)
-- 
TOPGIT patch commit log
=======================

commit e1219c6a3362b1979d889a3b88b4ea4ac79ff631
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sat Jan 31 00:12:50 2009 +0000

    Added patch framework/HK-GW-VFS-Kolab.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_framework_Kolab_DeprecatedGetServer.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/framework/Kolab/DeprecatedGetServer

Deprecates the old getServer routines in Horde/Kolab.php.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab.php |   24 +++++++++---------------
 1 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab.php b/horde-webmail/lib/Horde/Kolab.php
index 4338b8e..9ed8949 100644
--- a/horde-webmail/lib/Horde/Kolab.php
+++ b/horde-webmail/lib/Horde/Kolab.php
@@ -794,21 +794,15 @@ class Kolab {
     {
         global $conf;
 
-        if (!empty($conf['kolab']['misc']['multidomain']) &&
-            !empty($_SESSION['kolabHomeserver'])) {
-            // in multidomain mode we return the kolabHomeserver
-            return $_SESSION['kolabHomeserver'];
-        } else {
-            switch ($server_type) {
-            case 'imap':
-                return $conf['kolab']['imap']['server'];
-            case 'ldap':
-                return $conf['kolab']['ldap']['server'];
-            case 'smtp':
-                return $conf['kolab']['smtp']['server'];
-            default:
-                return '';
-            }
+        switch ($server_type) {
+        case 'imap':
+            return $conf['kolab']['imap']['server'];
+        case 'ldap':
+            return $conf['kolab']['ldap']['server'];
+        case 'smtp':
+            return $conf['kolab']['smtp']['server'];
+        default:
+            return '';
         }
     }
 }
-- 
tg: (ca94278..) t/framework/HK/GW/framework/Kolab/DeprecatedGetServer (depends on: t/framework/HK/GW/framework/Kolab/MoveSessionHandler)
-- 
TOPGIT patch commit log
=======================

commit afeb05387ac5e55f1a29dbe129c07c9acc31c42f
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 21:43:43 2009 +0000

    Added patch release/HK-GW-Kolab-DeprecateGetServer.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_framework_Kolab_MoveSessionHandler.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/framework/Kolab/MoveSessionHandler

Move several Kolab specific components to the new Kolab_Session handler.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Deprecated.php      |    4 +-
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php  |   38 +++-
 horde-webmail/lib/Horde/Kolab/Storage/List.php    |   10 +-
 horde-webmail/lib/Horde/Kolab/Storage/Session.php |  244 ---------------------
 4 files changed, 40 insertions(+), 256 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Deprecated.php b/horde-webmail/lib/Horde/Kolab/Deprecated.php
index af78ceb..6f45013 100644
--- a/horde-webmail/lib/Horde/Kolab/Deprecated.php
+++ b/horde-webmail/lib/Horde/Kolab/Deprecated.php
@@ -180,7 +180,7 @@ class Kolab_Storage_Deprecated extends Kolab_Storage {
             /** We need the DOM library for xml handling (PHP4/5). */
             require_once 'Horde/DOM.php';
 
-            $session = &Kolab_Session::singleton();
+            $session = &Horde_Kolab_Session::singleton();
             $this->_imap = &$session->getImap();
 
             $this->_object_type = $app_consts['mime_type_suffix'];
@@ -449,7 +449,7 @@ class Kolab_Storage_Deprecated extends Kolab_Storage {
      */
     function listObjectsInFolder($folder)
     {
-        $session = &Kolab_Session::singleton();
+        $session = &Horde_Kolab_Session::singleton();
         $imap = &$session->getImap();
 
         // Select mailbox to search in
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index 827faa9..97a2603 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -5,6 +5,9 @@
  * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Folder.php,v 1.7.2.3 2008/09/25 14:44:03 wrobel Exp $
  */
 
+/** We need the current user session. */
+require_once 'Horde/Kolab/Session.php';
+
 /** Data handling for Kolab **/
 require_once 'Horde/Kolab/Storage/Data.php';
 
@@ -186,8 +189,7 @@ class Kolab_Folder {
      */
     function __wakeup()
     {
-        $session = &Kolab_Session::singleton();
-        $this->_imap = &$session->getImap();
+        $this->_imap = &$this->getImap();
 
         if (!isset($this->_data)) {
             $this->_data = array();
@@ -216,6 +218,36 @@ class Kolab_Folder {
     }
 
     /**
+     * Create an IMAP connection.
+     *
+     * @return Kolab_IMAP|PEAR_Error The IMAP connection.
+     */
+    function &getImap()
+    {
+        $session = &Horde_Kolab_Session::singleton();
+        $params = &$session->getImapParams();
+        if (is_a($params, 'PEAR_Error')) {
+            return $params;
+        } else {
+            /** We need the Kolab IMAP library now. */
+            require_once 'Horde/Kolab/Storage/IMAP.php';
+
+            $imap = &Kolab_IMAP::singleton($params['hostspec'],
+                                           $params['port'], true, false);
+            if (is_a($imap, 'PEAR_Error')) {
+                return $imap;
+            }
+
+            $result = $this->_imap->connect(Auth::getAuth(),
+                                            Auth::getCredential('password'));
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+            return $imap;
+        }
+    }
+
+    /**
      * Set the list handler.
      *
      * @param Kolab_List $list  The handler for the list of folders.
@@ -841,7 +873,7 @@ class Kolab_Folder {
             $mime_message->alterPart($mime_part_id, $part);
         }
 
-        $session = &Kolab_Session::singleton();
+        $session = &Horde_Kolab_Session::singleton();
 
         // Update email headers
         $new_headers->addHeader('From', $session->user_mail);
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/List.php b/horde-webmail/lib/Horde/Kolab/Storage/List.php
index 3306df5..6d31c19 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/List.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/List.php
@@ -5,9 +5,6 @@
  * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/List.php,v 1.3.2.2 2008/09/25 09:20:07 wrobel Exp $
  */
 
-/** We need the IMAP connection. */
-require_once 'Horde/Kolab/Storage/Session.php';
-
 /** Kolab IMAP folder representation. **/
 require_once 'Horde/Kolab/Storage/Folder.php';
 
@@ -84,8 +81,7 @@ class Kolab_List {
      */
     function __wakeup()
     {
-        $session = &Kolab_Session::singleton();
-        $this->_imap = &$session->getImap();
+        $this->_imap = &Kolab_Folder::getImap();
 
         if (!isset($this->_folders)) {
             $this->_folders = array();
@@ -127,7 +123,7 @@ class Kolab_List {
         static $list;
 
         if (!isset($list) &&
-            !empty($GLOBALS['conf']['kolab']['cache_folders'])) {
+            !empty($GLOBALS['conf']['kolab']['imap']['cache_folders'])) {
             require_once 'Horde/SessionObjects.php';
             $session = &Horde_SessionObjects::singleton();
             $list = $session->query('kolab_folderlist');
@@ -137,7 +133,7 @@ class Kolab_List {
             $list = new Kolab_List();
         }
 
-        if (!empty($GLOBALS['conf']['kolab']['cache_folders'])) {
+        if (!empty($GLOBALS['conf']['kolab']['imap']['cache_folders'])) {
             register_shutdown_function(array(&$list, 'shutdown'));
         }
 
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Session.php b/horde-webmail/lib/Horde/Kolab/Storage/Session.php
deleted file mode 100644
index 840ad98..0000000
--- a/horde-webmail/lib/Horde/Kolab/Storage/Session.php
+++ /dev/null
@@ -1,244 +0,0 @@
-<?php
-/**
- * @package Kolab_Storage
- *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Session.php,v 1.3.2.2 2008/09/22 16:21:23 wrobel Exp $
- */
-
-/** We need the Auth library */
-require_once 'Horde/Auth.php';
-
-/**
- * The Kolab_Session class allows the Kolab classes to use a central
- * IMAP connection per session.
- *
- * $Horde: framework/Kolab_Storage/lib/Horde/Kolab/Storage/Session.php,v 1.3.2.2 2008/09/22 16:21:23 wrobel Exp $
- *
- * Copyright 2008 The Horde Project (http://www.horde.org/)
- *
- * See the enclosed file COPYING for license information (LGPL). If you
- * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
- *
- * @author  Gunnar Wrobel <wrobel at pardus.de>
- * @package Kolab_Storage
- */
-class Kolab_Session {
-
-    /**
-     * The name of the IMAP server.
-     *
-     * @var string
-     */
-    var $_imap_server;
-
-    /**
-     * The IMAP port of the server.
-     *
-     * @var int
-     */
-    var $_imap_port;
-
-    /**
-     * Primary user mail address.
-     *
-     * @var string
-     */
-    var $user_mail;
-
-    /**
-     * Our Kolab_IMAP object, used to communicate with the IMAP server.
-     *
-     * @var Kolab_IMAP
-     */
-    var $_imap;
-
-    /**
-     * Constructor.
-     */
-    function Kolab_Session()
-    {
-        global $conf;
-
-        $user = $this->_fetchUser();
-        if (!is_a($user, 'PEAR_Error')) {
-            $result = $user->get(KOLAB_ATTR_MAIL);
-            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
-                $this->user_mail = $result;
-            }
-
-            if (!empty($conf['kolab']['misc']['multidomain'])) {
-                $result = $user->getServer('imap');
-                if (!empty($result) && !is_a($result, 'PEAR_Error')) {
-                    $server = explode(':', $result, 2);
-                    if (!empty($server[0])) {
-                        $this->_imap_server = $server[0];
-                    }
-                    if (!empty($server[1])) {
-                        $this->_imap_port = $server[1];
-                    }
-                }
-            }
-        }
-
-        if (!isset($this->_imap_server)
-            && isset($conf['kolab']['imap']['server'])) {
-            $this->_imap_server = $conf['kolab']['imap']['server'];
-        }
-
-        if (!isset($this->_imap_port)
-            && isset($conf['kolab']['imap']['port'])) {
-            $this->_imap_port = $conf['kolab']['imap']['port'];
-        } else {
-            $this->_imap_port = 143;
-        }
-
-        if (!isset($this->user_mail)) {
-            $auth = Auth::getAuth();
-            if (empty($auth)) {
-                $auth = 'anonymous';
-            }
-            if (strpos($auth, '@')) {
-                $this->user_mail = $auth;
-            } else {
-                $this->user_mail = $auth . '@' . (!empty($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost');
-            }
-        }
-    }
-
-    /**
-     * Returns the properties that need to be serialized.
-     *
-     * @return array  List of serializable properties.
-     */
-    function __sleep()
-    {
-        $properties = get_object_vars($this);
-        unset($properties['_imap']);
-        $properties = array_keys($properties);
-        return $properties;
-    }
-
-    /**
-     * Fetch the Kolab_Object representing the current user.
-     *
-     * @return Kolab_Object_user|PEAR_Error The object representing
-     *                                      the current user.
-     */
-    function _fetchUser()
-    {
-        $user = Auth::getAuth();
-        if (empty($user)) {
-            return PEAR::raiseError(_('Anonymous user.'));
-        }
-
-        /** We need the Kolab Server access. */
-        require_once 'Horde/Kolab/Server.php';
-        $server = Horde_Kolab_Server::singleton();
-        if (is_a($server, 'PEAR_Error')) {
-            return $server;
-        }
-
-        $dn = $server->dnForUidOrMail($user);
-        if (empty($dn)) {
-            return PEAR::raiseError(_('No such user.'));
-        }
-        if (is_a($dn, 'PEAR_Error')) {
-            return $dn;
-        }
-
-        $user = $server->fetch($dn);
-        if (is_a($user, 'PEAR_Error')) {
-            return $user;
-        }
-
-        global $conf;
-
-        if (empty($conf['kolab']['misc']['allow_special'])
-            && !is_a($user, 'Horde_Kolab_Server_Object_user')) {
-            return PEAR::raiseError(_('Current user is not a standard Kolab user.'));
-        }
-        return $user;
-    }
-
-    /**
-     * Returns the current IMAP connection.
-     *
-     * @return Kolab_IMAP|PEAR_Error An open IMAP connection.
-     */
-    function &getImap()
-    {
-        if (isset($this->_imap)) {
-            return $this->_imap;
-        }
-
-        if (!isset($this->_imap_server)) {
-            $this->_imap = PEAR::raiseError(_("The URL for the Kolab IMAP Server is not available!"));
-            return $this->_imap;
-        }
-
-        /** We need the Kolab IMAP library now. */
-        require_once 'Horde/Kolab/Storage/IMAP.php';
-
-        $this->_imap = &Kolab_IMAP::singleton($this->_imap_server, $this->_imap_port,
-                                              true, false);
-        if (is_a($this->_imap, 'PEAR_Error')) {
-            return $this->_imap;
-        }
-        $result = $this->_imap->connect(Auth::getAuth(),
-                                        Auth::getCredential('password'));
-        if (is_a($result, 'PEAR_Error')) {
-            $this->_imap = &$result;
-            return $result;
-        }
-
-        return $this->_imap;
-    }
-
-    /**
-     * Attempts to return a reference to a concrete Kolab_Session instance.
-     *
-     * It will only create a new instance if no Kolab_Session instance
-     * currently exists.
-     *
-     * This method must be invoked as:
-     *   <code>$var = &Kolab_Session::singleton();</code>
-     *
-     * @static
-     *
-     * @return Kolab_Session  The concrete Session reference.
-     */
-    function &singleton()
-    {
-        static $session;
-
-        if (!isset($session)) {
-            /**
-             * Horde_Kolab_Server currently has no caching so we mainly
-             * cache some user information here as reading this data
-             * may be expensive when running in a multi-host
-             * environment.
-             */
-            require_once 'Horde/SessionObjects.php';
-            $hs = &Horde_SessionObjects::singleton();
-            $session = $hs->query('kolab_session');
-        }
-
-        if (empty($session)) {
-            $session = new Kolab_Session();
-        }
-
-        register_shutdown_function(array(&$session, 'shutdown'));
-
-        return $session;
-    }
-
-    /**
-     * Stores the object in the session cache.
-     */
-    function shutdown()
-    {
-        require_once 'Horde/SessionObjects.php';
-        $session = &Horde_SessionObjects::singleton();
-        $session->overwrite('kolab_session', $this, false);
-    }
-}
-- 
tg: (049b435..) t/framework/HK/GW/framework/Kolab/MoveSessionHandler (depends on: t/framework/HK/GW/Auth/UseSession t/kronolith/HK/GW/getFreebusyServer t/framework/HK/GW/Kolab_Storage/Trigger)
-- 
TOPGIT patch commit log
=======================

commit 9bc50d7cb446fd82cf2416781d10d4952acf83d5
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 21:39:39 2009 +0000

    Added dependency on t/framework/HK/GW/Kolab_Storage/Trigger.

commit c7d3f02e77aa7e3899b828acf8041e38309ddf7d
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 21:38:03 2009 +0000

    New TopGit dependency: t/framework/HK/GW/Kolab_Storage/Trigger

commit fd2f1ee045e95340f5880c1fc8bed3dc2743cb43
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 20:42:51 2009 +0000

    Added patch release/HK-GW-Kolab-Move_Session_handler.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_framework_Kolab__Format_WS.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/framework/Kolab_Format/WS

Whitespace.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Kolab/Format/XML.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Kolab/Format/XML.php b/horde-webmail/lib/Horde/Kolab/Format/XML.php
index d3d7def..e66d49e 100644
--- a/horde-webmail/lib/Horde/Kolab/Format/XML.php
+++ b/horde-webmail/lib/Horde/Kolab/Format/XML.php
@@ -982,7 +982,7 @@ class Horde_Kolab_Format_XML
             $cManager = null;
             $horde_categories = null;
         }
-        
+
         $kolab_categories = explode (',', $object['categories']);
 
         $primary_category = '';
-- 
tg: (6938161..) t/framework/HK/GW/framework/Kolab_Format/WS (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 83ea6082e87acd8fc235100a90f32937e94c152e
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 20:35:02 2009 +0000

    Added patch release/HK-GW-Kolab_Format-WS.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_horde_conf__xmlUpdates.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/horde/conf_xmlUpdates

Adapt the Kolab configuration to recent changes in the Kolab modules.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/config/conf.xml |   21 +++++++++++++++------
 1 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/horde-webmail/config/conf.xml b/horde-webmail/config/conf.xml
index 34a340c..f9f44cd 100644
--- a/horde-webmail/config/conf.xml
+++ b/horde-webmail/config/conf.xml
@@ -1803,8 +1803,8 @@
       <configinteger name="sieveport" desc="Sieve port:">2000</configinteger>
       <configstring name="maildomain" desc="Default
       maildomain:">example.com</configstring>
-      <configboolean name="virtdomains" desc="Virtual
-      domains:">true</configboolean>
+      <configboolean name="cache_folders" desc="Cache IMAP folders:"
+       required="true">true</configboolean>
      </configsection>
      <configheader>Kolab SMTP Server Settings</configheader>
      <configsection name="smtp">
@@ -1812,10 +1812,19 @@
       address:">localhost</configstring>
       <configinteger name="port" desc="Server port:">25</configinteger>
      </configsection>
-     <configheader>Kolab Misc</configheader>
-     <configsection name="misc">
-      <configboolean name="multidomain" desc="Enable multi domain
-      support:" required="false">false</configboolean>
+     <configheader>Kolab Free/Busy Application Settings</configheader>
+     <configsection name="freebusy">
+       <configdescription>
+	 Enter the leading part of the URL to the Kolab Free/Busy
+	 application here. This will usually be
+	 "https://localhost/freebusy" but if you installed it so that
+	 you reach the application at "https://freebusy.example.org"
+	 then you would enter "https://freebusy.example.org". The URL
+	 "https://freebusy.example.org/freebusy" would thus need the
+	 setting "https://freebusy.example.org/freebusy".
+       </configdescription>
+      <configstring name="server" desc="Application
+      address:">https://localhost/freebusy</configstring>
      </configsection>
     </case>
    </configswitch>
-- 
tg: (6938161..) t/framework/HK/GW/horde/conf_xmlUpdates (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 1feb7eb8d50a04ed097834f1d46fc4ba4f170e58
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 21:47:20 2009 +0000

    Added patch horde/HK-GW-conf_xml_kolab.patch from the mercurial release queue.

--- NEW FILE: t_framework_HK_GW_iCalendar_QuotedParameters.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/framework/HK/GW/iCalendar/QuotedParameters

Fix handling of quoting in the iCalendar library.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/iCalendar.php |   30 ++++++++++++++++++++++++++++--
 1 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/horde-webmail/lib/Horde/iCalendar.php b/horde-webmail/lib/Horde/iCalendar.php
index decf66a..2a2db6a 100644
--- a/horde-webmail/lib/Horde/iCalendar.php
+++ b/horde-webmail/lib/Horde/iCalendar.php
@@ -604,9 +604,12 @@ class Horde_iCalendar {
 
                 // Parse parameters.
                 if (!empty($parts[2])) {
-                    preg_match_all('/;(([^;=]*)(=([^;]*))?)/', $parts[2], $param_parts);
+                    preg_match_all('/;(([^;=]*)(=("[^"]*"|[^;]*))?)/', $parts[2], $param_parts);
                     foreach ($param_parts[2] as $key => $paramName) {
                         $paramValue = $param_parts[4][$key];
+                        if (preg_match('/"([^"]*)"/', $paramValue, $parts)) {
+                            $paramValue = $parts[1];
+                        }
                         $params[String::upper($paramName)] = $paramValue;
                     }
                 }
@@ -832,7 +835,30 @@ class Horde_iCalendar {
                     if ($param_value === null) {
                         $params_str .= ";$param_name";
                     } else {
-                        $params_str .= ";$param_name=$param_value";
+                        $len = strlen($param_value);
+                        $safe_value = '';
+                        $quote = false;
+                        for ($i = 0; $i < $len; ++$i) {
+                            $ord = ord($param_value[$i]);
+                            // Accept only valid characters.
+                            if ($ord == 9 || $ord == 32 || $ord == 33 ||
+                                ($ord >= 35 && $ord <= 126) ||
+                                $ord >= 128) {
+                                $safe_value .= $param_value[$i];
+                                /** 
+                                 * Characters above 128 do not need to be quoted
+                                 * as per RFC2445 but Outlook requires this.
+                                 */
+                                if ($ord == 44 || $ord == 58 || $ord == 59 ||
+                                    $ord >= 128) {
+                                    $quote = true;
+                                }
+                            }
+                        }
+                        if ($quote) {
+                            $safe_value = '"' . $safe_value . '"';
+                        }
+                        $params_str .= ";$param_name=$safe_value";
                     }
                 }
             }
-- 
tg: (af8ebe5..) t/framework/HK/GW/iCalendar/QuotedParameters (depends on: t/framework/HK/GW/Kolab_Storage/ShareIdFix)
-- 
TOPGIT patch commit log
=======================

commit 71f301253fbb754496093d6e6905a395a228c494
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 17:45:38 2009 +0000

    Added patch release/HK-GW-iCalendar-Quoted_parameters.patch from the mercurial release queue.

--- NEW FILE: t_horde_SC_CH_SecIssues20090128.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/horde/SC/CH/SecIssues20090128

Security issues that were patched on 20090128.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/lib/Horde/Image.php              |    1 +
 horde-webmail/services/portal/cloud_search.php |    2 +-
 2 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/lib/Horde/Image.php b/horde-webmail/lib/Horde/Image.php
index 2d48777..1288ef5 100644
--- a/horde-webmail/lib/Horde/Image.php
+++ b/horde-webmail/lib/Horde/Image.php
@@ -551,6 +551,7 @@ class Horde_Image {
             list($app, $driver) = $driver;
         }
 
+        $driver = basename($driver);
         $class = 'Horde_Image_' . $driver;
         if (!class_exists($class)) {
             if (!empty($app)) {
diff --git a/horde-webmail/services/portal/cloud_search.php b/horde-webmail/services/portal/cloud_search.php
index 0d0bc53..7e22aa6 100644
--- a/horde-webmail/services/portal/cloud_search.php
+++ b/horde-webmail/services/portal/cloud_search.php
@@ -28,7 +28,7 @@ $results = $registry->call('images/searchTags', array(array($tag)));
 $results = array_merge($results, $registry->call('news/searchTags',
                                                  array(array($tag))));
 echo '<div class="control"><strong>'
-    . sprintf(_("Results for %s"), '<span style="font-style:italic">' . $tag . '</span>')
+    . sprintf(_("Results for %s"), '<span style="font-style:italic">' . htmlspecialchars($tag) . '</span>')
     . '</strong>'
     . Horde::link('#', '', '', '', '$(\'cloudsearch\').hide();', '', '', array('style' => 'font-size:75%;'))
     . '(' . _("Hide Results") . ')</a></span></div><ul class="linedRow">';
-- 
tg: (6938161..) t/horde/SC/CH/SecIssues20090128 (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 360162337f2e7e5e65a6e19d46a0fbb7a0a091c0
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Feb 6 06:57:28 2009 +0000

    Security fixes from 20090128.

--- NEW FILE: t_imp_HK_GW_AuthForInvitations.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/imp/HK/GW/AuthForInvitations

Correctly authenticate to the SMTP server when responding to invitations.

FIXME: I believe this was solved with slight modifications upstream. Adapt this patch.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/imp/lib/MIME/Viewer/itip.php |   29 ++++++++++++++++++++++++++-
 1 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/horde-webmail/imp/lib/MIME/Viewer/itip.php b/horde-webmail/imp/lib/MIME/Viewer/itip.php
index 1f8fe1e..4f6beab 100644
--- a/horde-webmail/imp/lib/MIME/Viewer/itip.php
+++ b/horde-webmail/imp/lib/MIME/Viewer/itip.php
@@ -87,6 +87,29 @@ class IMP_MIME_Viewer_itip extends MIME_Viewer {
         // Get the iCalendar file components.
         $components = $vCal->getComponents();
 
+        $mailer_driver = $GLOBALS['conf']['mailer']['type'];
+        $mailer_params = $GLOBALS['conf']['mailer']['params'];
+
+        /* Force the SMTP host and port value to the current SMTP server if
+         * one has been selected for this connection. */
+        if (!empty($_SESSION['imp']['smtphost'])) {
+            $mailer_params['host'] = $_SESSION['imp']['smtphost'];
+        }
+        if (!empty($_SESSION['imp']['smtpport'])) {
+            $mailer_params['port'] = $_SESSION['imp']['smtpport'];
+        }
+
+        /* If SMTP authentication has been requested, use either the username
+         * and password provided in the configuration or populate the username
+         * and password fields based on the current values for the user. Note
+         * that we assume that the username and password values from the
+         * current IMAP / POP3 connection are valid for SMTP authentication as
+         * well. */
+        if (!empty($mailer_params['auth']) && empty($mailer_params['username'])) {
+            $mailer_params['username'] = $_SESSION['imp']['user'];
+            $mailer_params['password'] = Secret::read(Secret::getKey('imp'), $_SESSION['imp']['pass']);
+        }
+
         // Handle the action requests.
         $actions = Util::getFormData('action', array());
         foreach ($actions as $key => $action) {
@@ -332,7 +355,8 @@ class IMP_MIME_Viewer_itip extends MIME_Viewer {
                     $msg_headers->addMIMEHeaders($mime);
 
                     // Send the reply.
-                    $status = $mime->send($organizerEmail, $msg_headers);
+                    $status = $mime->send($organizerEmail, $msg_headers,
+                                          $mailer_driver, $mailer_params);
                     if (is_a($status, 'PEAR_Error')) {
                         $this->_msgs[$key][] = array('error', sprintf(_("Error sending reply: %s."), $status->getMessage()));
                     } else {
@@ -435,7 +459,8 @@ class IMP_MIME_Viewer_itip extends MIME_Viewer {
                     $msg_headers->addMIMEHeaders($mime);
 
                     // Send the reply.
-                    $status = $mime->send($organizerEmail, $msg_headers);
+                    $status = $mime->send($organizerEmail, $msg_headers,
+                                          $mailer_driver, $mailer_params);
                     if (is_a($status, 'PEAR_Error')) {
                         $this->_msgs[$key][] = array('error', sprintf(_("Error sending reply: %s."), $status->getMessage()));
                     } else {
-- 
tg: (066c7a2..) t/imp/HK/GW/AuthForInvitations (depends on: t/Kolab_Server/HK/GW/UserMailAndFullname)
-- 
TOPGIT patch commit log
=======================

commit 7bddd3610cfadd4c16b624018d6ccd77e3e908b5
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 18:09:57 2009 +0000

    Added patch release/HK-GW-Auth_for_invitations.patch from the mercurial release queue.

--- NEW FILE: t_imp_H_GW_DefaultLoginView.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/imp/H/GW/DefaultLoginView

Allow to configure the default imp view shown to the user.

STATUS: SUBMIT

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/imp/config/conf.php |    1 +
 horde-webmail/imp/config/conf.xml |    8 ++++++++
 horde-webmail/imp/login.php       |    3 ++-
 3 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/imp/config/conf.php b/horde-webmail/imp/config/conf.php
index 3a0f1d6..6cea64b 100644
--- a/horde-webmail/imp/config/conf.php
+++ b/horde-webmail/imp/config/conf.php
@@ -13,6 +13,7 @@ $conf['user']['allow_resume_all'] = false;
 $conf['user']['allow_view_source'] = true;
 $conf['user']['alternate_login'] = false;
 $conf['user']['redirect_on_logout'] = false;
+$conf['user']['default_view'] = 'imp';
 $conf['user']['select_view'] = true;
 $conf['server']['change_server'] = false;
 $conf['server']['change_port'] = false;
diff --git a/horde-webmail/imp/config/conf.xml b/horde-webmail/imp/config/conf.xml
index 517556e..92171b7 100644
--- a/horde-webmail/imp/config/conf.xml
+++ b/horde-webmail/imp/config/conf.xml
@@ -103,6 +103,14 @@
      </configenum>
     </case>
    </configswitch>
+   <configenum name="default_view" desc="Which application view should be the
+   suggested default on the login page?">imp
+    <values>
+     <value desc="IMP">imp</value>
+     <value desc="DIMP">dimp</value>
+     <value desc="MIMP">mimp</value>
+    </values>
+   </configenum>
   </configsection>
  </configtab>
 
diff --git a/horde-webmail/imp/login.php b/horde-webmail/imp/login.php
index e6cd3c9..4644e93 100644
--- a/horde-webmail/imp/login.php
+++ b/horde-webmail/imp/login.php
@@ -257,7 +257,8 @@ if (!empty($conf['user']['select_view'])) {
     $apps = $registry->listApps(null, true);
     $view_cookie = isset($_COOKIE['default_imp_view'])
         ? $_COOKIE['default_imp_view']
-        : ($browser->isMobile() && isset($apps['mimp']) ? 'mimp' : 'imp');
+        : ($browser->isMobile() && isset($apps['mimp']) ? 'mimp' 
+           : isset($conf['user']['default_view']) ? $conf['user']['default_view'] : 'imp');
     if (isset($apps['dimp']) || isset($apps['mimp'])) {
         $views[] = array('sel' => $view_cookie == 'imp',
                          'val' => 'imp', 'name' => _("Traditional"));
-- 
tg: (3a70f58..) t/imp/H/GW/DefaultLoginView (depends on: t/imp/H/JS/bug7739)
-- 
TOPGIT patch commit log
=======================

commit e2430d5bafced289bb0b8ac9d073fca9a4e9bb4a
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 20:09:33 2009 +0000

    Add the conf.xml part of the new configuration variable.

commit df4a014051b707ab4bf5ded96264c3b4f3b62ac4
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 08:14:20 2009 +0000

    Allow to configure the default view for imp.

--- NEW FILE: t_imp_H_GW_LoginRetries.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/imp/H/GW/LoginRetries

Fix the number of retries the c-client libraries uses when connecting to the IMAP server.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/imp/config/servers.php |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/imp/config/servers.php b/horde-webmail/imp/config/servers.php
index 1c6e537..d050122 100644
--- a/horde-webmail/imp/config/servers.php
+++ b/horde-webmail/imp/config/servers.php
@@ -264,7 +264,7 @@ if ($GLOBALS['conf']['kolab']['enabled']) {
         $imapParams = array(
 			'hostspec' => $server,
 			'port'     => $GLOBALS['conf']['kolab']['imap']['port'],
-            'protocol' => $GLOBALS['conf']['auth']['params']['protocol']
+            'protocol' => 'imap/novalidate-cert',
         );
     }
 
@@ -284,5 +284,6 @@ if ($GLOBALS['conf']['kolab']['enabled']) {
         'acl'        => array(
             'driver' => 'rfc2086',
         ),
+        'login_tries' => 1,
     );
 }
-- 
tg: (4f99941..) t/imp/H/GW/LoginRetries (depends on: t/imp/H/GW/DefaultLoginView)
-- 
TOPGIT patch commit log
=======================

commit 7540b6dc7fee180870333d1cbd8e2a173bdae751
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 20:27:01 2009 +0000

    Fix the number of login retries.

--- NEW FILE: t_imp_H_JS_bug7739.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/imp/H/JS/bug7739

[#7739] Folders tree not updated after an add (new) folder action

http://bugs.horde.org/ticket/7739

STATUS: MERGED

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/imp/lib/IMAP/Tree.php |    9 ++++++++-
 horde-webmail/imp/lib/Search.php    |   17 +++++++++++------
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/horde-webmail/imp/lib/IMAP/Tree.php b/horde-webmail/imp/lib/IMAP/Tree.php
index e249c1c..1fb857c 100644
--- a/horde-webmail/imp/lib/IMAP/Tree.php
+++ b/horde-webmail/imp/lib/IMAP/Tree.php
@@ -1584,7 +1584,14 @@ class IMP_Tree {
         }
 
         foreach (array_keys($id) as $key) {
-            $adds[] = IMPTREE_VFOLDER_KEY . $this->_delimiter . $key;
+            $id_key = IMPTREE_VFOLDER_KEY . $this->_delimiter . $key;
+            if (!isset($this->_tree[$id_key])) {
+                $adds[] = $id_key;
+            }
+        }
+
+        if (empty($adds)) {
+            return;
         }
 
         $this->insert($adds);
diff --git a/horde-webmail/imp/lib/Search.php b/horde-webmail/imp/lib/Search.php
index ddb86e5..f14a8e4 100644
--- a/horde-webmail/imp/lib/Search.php
+++ b/horde-webmail/imp/lib/Search.php
@@ -204,12 +204,15 @@ class IMP_Search {
     /**
      * Deletes an IMAP search query.
      *
-     * @param string $id  The search query id to use (by default, will use
-     *                    the current ID set in the object).
+     * @param string $id          The search query id to use (by default, will
+     *                            use the current ID set in the object).
+     * @param boolean $no_delete  Don't delete the entry in the tree object.
+     *
+     *
      *
      * @return string  Returns the search query id.
      */
-    function deleteSearchQuery($id = null)
+    function deleteSearchQuery($id = null, $no_delete = false)
     {
         $id = $this->_strip($id);
         $is_vfolder = !empty($_SESSION['imp']['search']['q'][$id]['vfolder']);
@@ -219,7 +222,9 @@ class IMP_Search {
             $vfolders = $this->_getVFolderList();
             unset($vfolders[$id]);
             $this->_saveVFolderList($vfolders);
-            $this->_updateIMPTree('delete', $id);
+            if (!$no_delete) {
+                $this->_updateIMPTree('delete', $id);
+            }
         }
     }
 
@@ -355,7 +360,7 @@ class IMP_Search {
         /* Delete the current Virtual Trash folder, if it exists. */
         $vtrash_id = $GLOBALS['prefs']->getValue('vtrash_id');
         if (!empty($vtrash_id)) {
-            $this->deleteSearchQuery($vtrash_id);
+            $this->deleteSearchQuery($vtrash_id, true);
         }
 
         if (!$GLOBALS['prefs']->getValue('use_vtrash')) {
@@ -418,7 +423,7 @@ class IMP_Search {
         /* Delete the current Virtual Inbox folder, if it exists. */
         $vinbox_id = $GLOBALS['prefs']->getValue('vinbox_id');
         if (!empty($vinbox_id)) {
-            $this->deleteSearchQuery($vinbox_id);
+            $this->deleteSearchQuery($vinbox_id, true);
         }
 
         if (!$GLOBALS['prefs']->getValue('use_vinbox')) {
-- 
tg: (38b4949..) t/imp/H/JS/bug7739 (depends on: t/imp/H/MS/bug7438)
-- 
TOPGIT patch commit log
=======================

commit 1a74763ee823d7cc74b9b2f8585bcd71963c805e
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 07:56:27 2009 +0000

    Merged [#7739] Folders tree not updated after an add (new) folder action.

--- NEW FILE: t_imp_H_MS_bug7438.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/imp/H/MS/bug7438

[#7438] Failed login not passed back to login screen

http://bugs.horde.org/ticket/7438

STATUS: MERGED

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/imp/lib/Auth/imp.php |    2 +-
 horde-webmail/imp/redirect.php     |    6 ++----
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/horde-webmail/imp/lib/Auth/imp.php b/horde-webmail/imp/lib/Auth/imp.php
index c94b0b1..6b55015 100644
--- a/horde-webmail/imp/lib/Auth/imp.php
+++ b/horde-webmail/imp/lib/Auth/imp.php
@@ -142,7 +142,7 @@ class Auth_imp extends Auth {
             if (isset($prefs)) {
                 $prefs->cleanup(true);
             }
-            $this->_setAuthError(AUTH_REASON_FAILED);
+            $this->_setAuthError(AUTH_REASON_BADLOGIN);
             return false;
         }
 
diff --git a/horde-webmail/imp/redirect.php b/horde-webmail/imp/redirect.php
index 7e5c045..e2f0daa 100644
--- a/horde-webmail/imp/redirect.php
+++ b/horde-webmail/imp/redirect.php
@@ -237,12 +237,10 @@ if (($imapuser !== null) && ($pass !== null)) {
 
         IMP_Session::loginTasks();
 
-        $url = _newSessionUrl($actionID, $isLogin, $view);
-    } else {
-        $url = Auth::addLogoutParameters(IMP::logoutUrl());
+        _redirect(_framesetUrl(_newSessionUrl($actionID, $isLogin, $view)));
     }
 
-    _redirect(_framesetUrl($url));
+    _redirect(Auth::addLogoutParameters(IMP::logoutUrl()));
 }
 
 /* No session, and no login attempt. Just go to the login page. */
-- 
tg: (461f8df..) t/imp/H/MS/bug7438 (depends on: t/COPYRIGHT3)
-- 
TOPGIT patch commit log
=======================

commit 38b4949c93b00cae793ace9ae861ade22e0bb3c1
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 22:57:16 2009 +0000

    Removed stray patch file.

commit 42660a8ab771c9f54731f24022409089aef6a09f
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 20:02:39 2009 +0000

    Fix base patch.

commit 0ae1d51e9802057c3aa2805a4088fe1eb6df8a53
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Mar 8 07:23:20 2009 +0000

    Fix [#7438] Failed login not passed back to login screen

--- NEW FILE: t_imp_HideGroupwareFolders.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/imp/HideGroupwareFolders

Hides special Kolab groupware folders.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/imp/config/conf.xml       |    4 +++
 horde-webmail/imp/config/hooks.php.dist |   11 +++++++-
 horde-webmail/imp/lib/IMAP/Tree.php     |   40 ++++++++++++++++++++++++++++--
 3 files changed, 50 insertions(+), 5 deletions(-)

diff --git a/horde-webmail/imp/config/conf.xml b/horde-webmail/imp/config/conf.xml
index 9be5108..517556e 100644
--- a/horde-webmail/imp/config/conf.xml
+++ b/horde-webmail/imp/config/conf.xml
@@ -445,6 +445,10 @@
    a custom function to provide additional information/custom formatting of
    messages in the mailbox message list? If so, make sure you define
    _imp_hook_msglist_format() in hooks.php.">false</configboolean>
+   <configboolean name="display_folder" required="false" desc="Should we use a 
+   custom function to dynamically determine if we show a specified folder?
+   If so, make sure you define _imp_hook_display_folder() in 
+   hooks.php.">false</configboolean>
   </configsection>
  </configtab>
 
diff --git a/horde-webmail/imp/config/hooks.php.dist b/horde-webmail/imp/config/hooks.php.dist
index 98e429e..f690ef5 100644
--- a/horde-webmail/imp/config/hooks.php.dist
+++ b/horde-webmail/imp/config/hooks.php.dist
@@ -426,7 +426,7 @@ if (!empty($GLOBALS['conf']['kolab']['enabled'])) {
             case 'contact':
                 return $GLOBALS['registry']->get('webroot', 'turba');
 
-            case 'prefs':
+            case 'h-prefs':
                 return $GLOBALS['registry']->get('webroot', 'horde') . '/services/prefs.php?app=horde';
 
             default:
@@ -480,7 +480,7 @@ if (!empty($GLOBALS['conf']['kolab']['enabled'])) {
                     );
                     break;
 
-                case 'prefs':
+                case 'h-prefs':
                     $icons[$name] = array(
                         'icon' => 'prefs.png',
                         'icondir' => $GLOBALS['registry']->getImageDir('horde'),
@@ -493,6 +493,13 @@ if (!empty($GLOBALS['conf']['kolab']['enabled'])) {
             return $icons;
         }
     }
+    if (!function_exists('_imp_hook_display_folder')) {
+        function _imp_hook_display_folder($mailbox)
+        {
+            $type = Kolab::getMailboxType($mailbox);
+            return empty($type) || $type == 'mail';
+        }
+    }
 }
 
 // Sample function for returning the quota. Uses the PECL ssh2
diff --git a/horde-webmail/imp/lib/IMAP/Tree.php b/horde-webmail/imp/lib/IMAP/Tree.php
index ce69fe8..e249c1c 100644
--- a/horde-webmail/imp/lib/IMAP/Tree.php
+++ b/horde-webmail/imp/lib/IMAP/Tree.php
@@ -32,6 +32,7 @@ define('IMPTREE_ELT_IS_POLLED', 32);
 define('IMPTREE_ELT_NEED_SORT', 64);
 define('IMPTREE_ELT_VFOLDER', 128);
 define('IMPTREE_ELT_NONIMAP', 256);
+define('IMPTREE_ELT_INVISIBLE', 512);
 
 /* The isOpen() expanded mode constants. */
 define('IMPTREE_OPEN_NONE', 0);
@@ -395,6 +396,13 @@ class IMP_Tree {
         /* Convert 'INBOX' to localized name. */
         $elt['l'] = ($elt['v'] == 'INBOX') ? _("Inbox") : String::convertCharset($tmp[$elt['c']], 'UTF7-IMAP');
 
+        if (!empty($GLOBALS['conf']['hooks']['display_folder'])) {
+            if (!Horde::callHook('_imp_hook_display_folder', array($elt['v']),
+                                 'imp')) {
+                $this->_setInvisible($elt, true);
+            }
+        }
+
         if ($_SESSION['imp']['base_protocol'] != 'pop3') {
             if ($elt['c'] != 0) {
                 $elt['p'] = implode(is_null($ns_info) ? $this->_delimiter : $ns_info['delimiter'], array_slice($tmp, 0, $elt['c']));
@@ -1274,6 +1282,31 @@ class IMP_Tree {
     }
 
     /**
+     * Set the invisible attribute for an element.
+     *
+     * @access private
+     *
+     * @param array &$elt    A tree element.
+     * @param boolean $bool  The setting.
+     */
+    function _setInvisible(&$elt, $bool)
+    {
+        $this->_setAttribute($elt, IMPTREE_ELT_INVISIBLE, $bool);
+    }
+
+    /**
+     * Is the element invisible?
+     *
+     * @param array $elt  A tree element.
+     *
+     * @return integer  True if the element is invisible.
+     */
+    function isInvisible($elt)
+    {
+        return $elt['a'] & IMPTREE_ELT_INVISIBLE;
+    }
+
+    /**
      * Flag the element as needing its children to be sorted.
      *
      * @access private
@@ -1441,9 +1474,10 @@ class IMP_Tree {
      */
     function _activeElt($elt)
     {
-        return ($this->_showunsub ||
-                ($this->isSubscribed($elt) && !$this->isContainer($elt)) ||
-                $this->hasChildren($elt));
+        return (!$this->isInvisible($elt) &&
+                ($this->_showunsub || 
+                 ($this->isSubscribed($elt) && !$this->isContainer($elt)) ||
+                 $this->hasChildren($elt)));
     }
 
     /**
-- 
tg: (6938161..) t/imp/HideGroupwareFolders (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 1614756bd145f6c129efc989a7b52e8a3e5e3e61
Author: Gunnar Wrobel <p at rdus.de>
Date:   Thu Feb 5 22:07:03 2009 +0000

    Added patch imp/HK-MP-Hide_groupware_folders.patch from the mercurial patch queue.

--- NEW FILE: t_imp_SC_CH_SecIssues20090128.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/imp/SC/CH/SecIssues20090128

Security issues patched on 20090128

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/imp/message.php |   10 +++++-----
 horde-webmail/imp/pgp.php     |    4 ++--
 horde-webmail/imp/smime.php   |    4 ++--
 3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/horde-webmail/imp/message.php b/horde-webmail/imp/message.php
index c822e0b..0488af7 100644
--- a/horde-webmail/imp/message.php
+++ b/horde-webmail/imp/message.php
@@ -444,7 +444,7 @@ if (!$printer_friendly && !empty($conf['maillog']['use_maillog'])) {
 
     /* Do MDN processing now. */
     if ($imp_ui->MDNCheck($ob->header, Util::getFormData('mdn_confirm'))) {
-        $confirm_link = Horde::link(Util::addParameter($selfURL, 'mdn_confirm', 1)) . _("HERE") . '</a>';
+        $confirm_link = Horde::link(htmlspecialchars(Util::addParameter($selfURL, 'mdn_confirm', 1))) . _("HERE") . '</a>';
         $notification->push(sprintf(_("The sender of this message is requesting a Message Disposition Notification from you when you have read this message. Please click %s to send the notification message."), $confirm_link), 'horde.message', array('content.raw'));
     }
 }
@@ -617,13 +617,13 @@ if (!$printer_friendly) {
 
     $a_template->set('headers', Horde::widget('#', _("Headers"), 'widget hasmenu', '', '', _("Headers"), true));
     if ($all_headers || $list_headers) {
-        $a_template->set('common_headers', Horde::widget($headersURL, _("Show Common Headers"), 'widget', '', '', _("Show Common Headers"), true));
+        $a_template->set('common_headers', Horde::widget(htmlspecialchars($headersURL), _("Show Common Headers"), 'widget', '', '', _("Show Common Headers"), true));
     }
     if (!$all_headers) {
-        $a_template->set('all_headers', Horde::widget(Util::addParameter($headersURL, 'show_all_headers', 1), _("Show All Headers"), 'widget', '', '', _("Show All Headers"), true));
+        $a_template->set('all_headers', Horde::widget(htmlspecialchars(Util::addParameter($headersURL, 'show_all_headers', 1)), _("Show All Headers"), 'widget', '', '', _("Show All Headers"), true));
     }
     if ($list_info['exists'] && !$list_headers) {
-        $a_template->set('list_headers', Horde::widget(Util::addParameter($headersURL, 'show_list_headers', 1), _("Show Mailing List Information"), 'widget', '', '', _("Show Mailing List Information"), true));
+        $a_template->set('list_headers', Horde::widget(htmlspecialchars(Util::addParameter($headersURL, 'show_list_headers', 1)), _("Show Mailing List Information"), 'widget', '', '', _("Show Mailing List Information"), true));
     }
 
     echo $a_template->fetch(IMP_TEMPLATES . '/message/navbar_actions.html');
@@ -681,7 +681,7 @@ if ($show_parts || ($downloadall_link && !$printer_friendly)) {
             $url = Horde::selfUrl(true);
             $url = Util::removeParameter($url, array('actionID'));
             $url = Util::addParameter($url, array('actionID' => 'strip_all', 'message_token' => $message_token));
-            $val .= '<br />' . Horde::link($url, _("Strip All Attachments"), null, null, "return window.confirm('" . addslashes(_("Are you sure you wish to PERMANENTLY delete all attachments?")) . "');") . _("Strip All Attachments") . ' ' . Horde::img('delete.png', _("Strip Attachments"), null, $registry->getImageDir('horde')) . '</a>';
+            $val .= '<br />' . Horde::link(htmlspecialchars($url), _("Strip All Attachments"), null, null, "return window.confirm('" . addslashes(_("Are you sure you wish to PERMANENTLY delete all attachments?")) . "');") . _("Strip All Attachments") . ' ' . Horde::img('delete.png', _("Strip Attachments"), null, $registry->getImageDir('horde')) . '</a>';
         }
     }
     $hdrs[] = array('name' => _("Part(s)"), 'val' => $val, 'i' => (++$i % 2));
diff --git a/horde-webmail/imp/pgp.php b/horde-webmail/imp/pgp.php
index 35c733c..e88e910 100644
--- a/horde-webmail/imp/pgp.php
+++ b/horde-webmail/imp/pgp.php
@@ -40,7 +40,7 @@ function _outputPassphraseDialog($secure_check, $symmetric = false)
     $t->set('symmetric', $symmetric);
     $t->set('submit_url', Util::addParameter(Horde::applicationUrl('pgp.php'), 'actionID', $symmetric ? 'process_symmetric_passphrase_dialog' : 'process_passphrase_dialog'));
     $t->set('reload', htmlspecialchars(Util::getFormData('reload')));
-    $t->set('action', Util::getFormData('passphrase_action'));
+    $t->set('action', htmlspecialchars(Util::getFormData('passphrase_action')));
     $t->set('locked_img', Horde::img('locked.png', _("PGP"), null, $GLOBALS['registry']->getImageDir('horde')));
     echo $t->fetch(IMP_TEMPLATES . '/pgp/passphrase.html');
 }
@@ -66,7 +66,7 @@ function _importKeyDialog($target)
 
 function _reloadWindow()
 {
-    Util::closeWindowJS('opener.focus();opener.location.href="' . Util::getFormData('reload') . '";');
+    Util::closeWindowJS('opener.focus();opener.location.href="' . htmlspecialchars(Util::getFormData('reload')) . '";');
 }
 
 function _getImportKey()
diff --git a/horde-webmail/imp/smime.php b/horde-webmail/imp/smime.php
index 6ba24c6..d05c454 100644
--- a/horde-webmail/imp/smime.php
+++ b/horde-webmail/imp/smime.php
@@ -63,7 +63,7 @@ function _outputPassphraseDialog($secure_check)
     $t->setOption('gettext', true);
     $t->set('submit_url', Util::addParameter(Horde::applicationUrl('smime.php'), 'actionID', 'process_passphrase_dialog'));
     $t->set('reload', htmlspecialchars(html_entity_decode(Util::getFormData('reload'))));
-    $t->set('action', Util::getFormData('passphrase_action'));
+    $t->set('action', htmlspecialchars(Util::getFormData('passphrase_action')));
     $t->set('locked_img', Horde::img('locked.png', _("S/MIME"), null, $GLOBALS['registry']->getImageDir('horde')));
     echo $t->fetch(IMP_TEMPLATES . '/smime/passphrase.html');
 }
@@ -79,7 +79,7 @@ function _actionWindow()
 
 function _reloadWindow()
 {
-    Util::closeWindowJS('opener.focus();opener.location.href="' . Util::getFormData('reload') . '";');
+    Util::closeWindowJS('opener.focus();opener.location.href="' . htmlspecialchars(Util::getFormData('reload')) . '";');
 }
 
 function _textWindowOutput($filename, $msg, $html = false)
-- 
tg: (6938161..) t/imp/SC/CH/SecIssues20090128 (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit a6149778434f9d0c94bd4bbf2b7b8cb15ed8135e
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Feb 6 06:39:50 2009 +0000

    Security fixes from 20090128.

--- NEW FILE: t_kronolith_HK_GW_AuthenticatedFreeBusy.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/kronolith/HK/GW/AuthenticatedFreeBusy

Allow the use of authenticated Free/Busy with Kolab.

FIXME: Check if that has been commited/submitted upstream.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/kronolith/config/conf.xml  |    6 ++++++
 horde-webmail/kronolith/lib/FreeBusy.php |    3 +++
 2 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/horde-webmail/kronolith/config/conf.xml b/horde-webmail/kronolith/config/conf.xml
index aa72858..0ed2387 100644
--- a/horde-webmail/kronolith/config/conf.xml
+++ b/horde-webmail/kronolith/config/conf.xml
@@ -49,6 +49,12 @@
   </configswitch>
  </configsection>
 
+ <configsection name="authenticated_freebusy">
+   <configheader>Use authenticated free/busy</configheader>
+   <configboolean name="enable" desc="Should we authenticate with the current user credentials agains the free/busy URL?"
+   required="false">true</configboolean>
+ </configsection>
+
  <configsection name="metadata">
   <configheader>Metadata Settings</configheader>
   <configboolean name="keywords" desc="Should keywords be loaded from
diff --git a/horde-webmail/kronolith/lib/FreeBusy.php b/horde-webmail/kronolith/lib/FreeBusy.php
index a0615dc..a8db0ee 100644
--- a/horde-webmail/kronolith/lib/FreeBusy.php
+++ b/horde-webmail/kronolith/lib/FreeBusy.php
@@ -187,6 +187,9 @@ class Kronolith_FreeBusy {
 
             require_once 'HTTP/Request.php';
             $http = new HTTP_Request($url, $options);
+            if (!empty($GLOBALS['conf']['authenticated_freebusy'])) {
+                $http->setBasicAuth(Auth::getAuth(), Auth::getCredential('password'));
+            }
             if (is_a($response = @$http->sendRequest(), 'PEAR_Error')) {
                 return PEAR::raiseError(sprintf(_("The free/busy url for %s cannot be retrieved."), $email));
             }
-- 
tg: (6938161..) t/kronolith/HK/GW/AuthenticatedFreeBusy (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit b7ae3fffce45d1ec54a9477a0bc006e995d0abf0
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 18:19:43 2009 +0000

    Remove stuff from broken patching.

commit ebb26e5d1fbfae64d93da8fc83c82589a82812f2
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 18:18:21 2009 +0000

    Added patch kronolith/HK-GW-Authenticated_FB.patch from the mercurial release queue.

--- NEW FILE: t_kronolith_HK_GW_CalendarRenaming.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/kronolith/HK/GW/CalendarRenaming

Fix the renaming of calendars.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/kronolith/lib/Forms/EditCalendar.php |    9 +++++----
 horde-webmail/lib/Horde/Kolab/Storage/Folder.php   |   11 ++++++-----
 2 files changed, 11 insertions(+), 9 deletions(-)

diff --git a/horde-webmail/kronolith/lib/Forms/EditCalendar.php b/horde-webmail/kronolith/lib/Forms/EditCalendar.php
index 0a76c57..bef123d 100644
--- a/horde-webmail/kronolith/lib/Forms/EditCalendar.php
+++ b/horde-webmail/kronolith/lib/Forms/EditCalendar.php
@@ -49,11 +49,12 @@ class Kronolith_EditCalendarForm extends Horde_Form {
     function execute()
     {
         $original_name = $this->_calendar->get('name');
-        $this->_calendar->set('name', $this->_vars->get('name'));
+        $new_name = $this->_vars->get('name');
+        $this->_calendar->set('name', $new_name);
         $this->_calendar->set('desc', $this->_vars->get('description'));
 
-        if ($original_name != $this->_vars->get('name')) {
-            $result = $GLOBALS['kronolith_driver']->rename($original_name, $this->_vars->get('name'));
+        if ($original_name != $new_name) {
+            $result = $GLOBALS['kronolith_driver']->rename($original_name, $new_name);
             if (is_a($result, 'PEAR_Error')) {
                 return PEAR::raiseError(sprintf(_("Unable to rename \"%s\": %s"), $original_name, $result->getMessage()));
             }
@@ -61,7 +62,7 @@ class Kronolith_EditCalendarForm extends Horde_Form {
 
         $result = $this->_calendar->save();
         if (is_a($result, 'PEAR_Error')) {
-            return PEAR::raiseError(sprintf(_("Unable to save calendar \"%s\": %s"), $id, $result->getMessage()));
+            return PEAR::raiseError(sprintf(_("Unable to save calendar \"%s\": %s"), $new_name, $result->getMessage()));
         }
         return true;
     }
diff --git a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
index 64a438b..a668a24 100644
--- a/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
+++ b/horde-webmail/lib/Horde/Kolab/Storage/Folder.php
@@ -323,6 +323,7 @@ class Kolab_Folder {
 
             if (isset($attributes['default'])) {
                 $this->_default = $attributes['default'];
+                unset($attributes['default']);
             } else {
                 $this->_default = $this->isDefault();
             }
@@ -335,12 +336,12 @@ class Kolab_Folder {
                     return $result;
                 }
 
+                /**
+                 * Trigger the old folder name but ignore the error this will
+                 * elicit.  While we get an error because of the missing folder
+                 * the corresponding cache value will get purged.
+                 */
                 $result = $this->trigger();
-                if (is_a($result, 'PEAR_Error')) {
-                    Horde::logMessage(sprintf('Failed triggering folder %s! Error was: %s',
-                                              $this->name, $result->getMessage()),
-                                      __FILE__, __LINE__, PEAR_LOG_ERR);
-                }
 
                 $this->name     = $this->new_name;
                 $this->new_name = null;
-- 
tg: (1b6a9e5..) t/kronolith/HK/GW/CalendarRenaming (depends on: t/framework/HK/GW/Kolab_Server/FixGetGroups)
-- 
TOPGIT patch commit log
=======================

commit 3179737578e80232c88ff68099839a9d720212ac
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:27:18 2009 +0000

    Added patch kronolith/HK-GW-Renaming_fix.patch from the mercurial release queue.

--- NEW FILE: t_kronolith_HK_GW_FbviewRelevance.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/kronolith/HK/GW/FbviewRelevance

Heed the Free/Busy relevance setting.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/kronolith/calendars/edit.php         |    4 ++++
 .../kronolith/lib/Forms/CreateCalendar.php         |    4 ++++
 horde-webmail/kronolith/lib/Forms/EditCalendar.php |    4 ++++
 3 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/horde-webmail/kronolith/calendars/edit.php b/horde-webmail/kronolith/calendars/edit.php
index 67137d2..6357a2c 100644
--- a/horde-webmail/kronolith/calendars/edit.php
+++ b/horde-webmail/kronolith/calendars/edit.php
@@ -53,6 +53,10 @@ if ($form->validate($vars)) {
 
 $vars->set('name', $calendar->get('name'));
 $vars->set('description', $calendar->get('desc'));
+$params = @unserialize($calendar->get('params'));
+if (isset($params['fbrelevance'])) {
+    $vars->set('fbrelevance', $params['fbrelevance']);
+}
 $title = $form->getTitle();
 require KRONOLITH_TEMPLATES . '/common-header.inc';
 require KRONOLITH_TEMPLATES . '/menu.inc';
diff --git a/horde-webmail/kronolith/lib/Forms/CreateCalendar.php b/horde-webmail/kronolith/lib/Forms/CreateCalendar.php
index f11ae06..8d1154e 100644
--- a/horde-webmail/kronolith/lib/Forms/CreateCalendar.php
+++ b/horde-webmail/kronolith/lib/Forms/CreateCalendar.php
@@ -35,6 +35,9 @@ class Kronolith_CreateCalendarForm extends Horde_Form {
 
         $this->addVariable(_("Name"), 'name', 'text', true);
         $this->addVariable(_("Description"), 'description', 'longtext', false, false, null, array(4, 60));
+        $this->addVariable(_("Relevance"), 'fbrelevance', 'radio', false, false, null, 
+                           array(array('owners/administrators', 'readers', 'no one'), 
+                                 'This calendar is only included into the free/busy data for ...'));
 
         $this->setButtons(array(_("Create")));
     }
@@ -48,6 +51,7 @@ class Kronolith_CreateCalendarForm extends Horde_Form {
         }
         $calendar->set('name', $this->_vars->get('name'));
         $calendar->set('desc', $this->_vars->get('description'));
+        $calendar->set('params', serialize(array('fbrelevance' => (int) $this->_vars->get('fbrelevance', 0))));
         return $GLOBALS['kronolith_shares']->addShare($calendar);
     }
 
diff --git a/horde-webmail/kronolith/lib/Forms/EditCalendar.php b/horde-webmail/kronolith/lib/Forms/EditCalendar.php
index 0a76c57..e0b4659 100644
--- a/horde-webmail/kronolith/lib/Forms/EditCalendar.php
+++ b/horde-webmail/kronolith/lib/Forms/EditCalendar.php
@@ -42,6 +42,9 @@ class Kronolith_EditCalendarForm extends Horde_Form {
         $this->addHidden('', 'c', 'text', true);
         $this->addVariable(_("Name"), 'name', 'text', true);
         $this->addVariable(_("Description"), 'description', 'longtext', false, false, null, array(4, 60));
+        $this->addVariable(_("Relevance"), 'fbrelevance', 'radio', false, false, null, 
+                           array(array('owners/administrators', 'readers', 'no one'), 
+                                 'This calendar is only included into the free/busy data for ...'));
 
         $this->setButtons(array(_("Save")));
     }
@@ -51,6 +54,7 @@ class Kronolith_EditCalendarForm extends Horde_Form {
         $original_name = $this->_calendar->get('name');
         $this->_calendar->set('name', $this->_vars->get('name'));
         $this->_calendar->set('desc', $this->_vars->get('description'));
+        $this->_calendar->set('params', serialize(array('fbrelevance' => (int) $this->_vars->get('fbrelevance', 0))));
 
         if ($original_name != $this->_vars->get('name')) {
             $result = $GLOBALS['kronolith_driver']->rename($original_name, $this->_vars->get('name'));
-- 
tg: (67b6582..) t/kronolith/HK/GW/FbviewRelevance (depends on: t/kronolith/HK/SB/ExtraParameters)
-- 
TOPGIT patch commit log
=======================

commit dae3753e368fefa0e825f97b03b146bb7f9fc44a
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Mar 13 01:25:36 2009 +0100

    Remove stray .orig file.

commit adae108bd20332a0383b10ecbc0123d6d5c00fed
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 22:27:55 2009 +0000

    Added patch kronolith/HK-GW-Fbview_relevance.patch from the mercurial release queue.

--- NEW FILE: t_kronolith_HK_GW_SyncMLrefresh.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/kronolith/HK/GW/SyncMLrefresh

Refresh calendars before running a SyncML synchronization.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/kronolith/lib/Driver/kolab.php |   10 ++++++++++
 horde-webmail/kronolith/lib/api.php          |    3 +++
 2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/horde-webmail/kronolith/lib/Driver/kolab.php b/horde-webmail/kronolith/lib/Driver/kolab.php
index 6133d74..de49c81 100644
--- a/horde-webmail/kronolith/lib/Driver/kolab.php
+++ b/horde-webmail/kronolith/lib/Driver/kolab.php
@@ -62,6 +62,7 @@ class Kronolith_Driver_kolab extends Kronolith_Driver {
             $this->_calendar = $calendar;
             $this->_wrapper->reset();
         }
+        $this->_wrapper->open($calendar);
 
         return true;
     }
@@ -215,6 +216,10 @@ class Kronolith_Driver_kolab_wrapper {
         $this->_driver = &$driver;
         $this->_kolab = &$driver->_kolab;
     }
+
+    function open($calendar)
+    {
+    }
 }
 
 
@@ -991,6 +996,11 @@ class Kronolith_Driver_kolab_wrapper_new extends Kronolith_Driver_kolab_wrapper
         $this->reset();
     }
 
+    function open($calendar)
+    {
+        $this->synchronize();
+    }
+
     /**
      * Reset internal variable on share change
      */
diff --git a/horde-webmail/kronolith/lib/api.php b/horde-webmail/kronolith/lib/api.php
index 68a52d0..202b85e 100644
--- a/horde-webmail/kronolith/lib/api.php
+++ b/horde-webmail/kronolith/lib/api.php
@@ -694,6 +694,7 @@ function _kronolith_list($calendar = null, $startstamp = 0, $endstamp = 0)
 function _kronolith_listBy($action, $timestamp, $calendar = null)
 {
     require_once dirname(__FILE__) . '/base.php';
+    global $kronolith_driver;
 
     if (empty($calendar)) {
         $calendar = Kronolith::getDefaultCalendar();
@@ -704,6 +705,8 @@ function _kronolith_listBy($action, $timestamp, $calendar = null)
         return PEAR::raiseError(_("Permission Denied"));
     }
 
+    $kronolith_driver->open($calendar);
+
     $history = &Horde_History::singleton();
     $histories = $history->getByTimestamp('>', $timestamp, array(array('op' => '=', 'field' => 'action', 'value' => $action)), 'kronolith:' . $calendar);
     if (is_a($histories, 'PEAR_Error')) {
-- 
tg: (6938161..) t/kronolith/HK/GW/SyncMLrefresh (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit d66c36f15b0ee0524d4cc2660ea8d092e82df1b2
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 23:54:50 2009 +0000

    Added patch kronolith/HK-GW-SyncML_refresh.patch   from the mercurial release queue.

--- NEW FILE: t_kronolith_HK_GW_XfbAccess.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/kronolith/HK/GW/XfbAccess

Allows to set the extended free/busy view access parameters via the calendar settings.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/kronolith/perms.php                 |   48 ++++++++++++++++++
 horde-webmail/kronolith/templates/perms/perms.inc |   55 +++++++++++++++++++++
 2 files changed, 103 insertions(+), 0 deletions(-)

diff --git a/horde-webmail/kronolith/perms.php b/horde-webmail/kronolith/perms.php
index f9bed71..4966bd4 100644
--- a/horde-webmail/kronolith/perms.php
+++ b/horde-webmail/kronolith/perms.php
@@ -15,6 +15,34 @@
 require_once KRONOLITH_BASE . '/lib/base.php';
 require_once 'Horde/Group.php';
 
+function &getFbperms($share) 
+{
+    $fbperms = array();
+    $params = $share->get('params');
+    if (!is_a($params, 'PEAR_Error')) {
+        $params = @unserialize($params);
+        if (isset($params['xfbaccess'])) {
+            $xfbusers = $params['xfbaccess'];
+            foreach ($xfbusers as $user) {
+                $fbperms[$user] = PERMS_READ;
+            }
+        }
+    }
+    return $fbperms;
+}
+
+function setFbperms($share, $xfbusers)
+{
+    $fbperms = array();
+    $params = $share->get('params');
+    if (!is_a($params, 'PEAR_Error')) {
+        $params = @unserialize($params);
+        $params['xfbaccess'] = $xfbusers;
+        $params = serialize($params);
+        $share->set('params', $params);
+    }
+}
+
 $shares = &Horde_Share::singleton('kronolith');
 $groups = &Group::singleton();
 $auth = &Auth::singleton($conf['auth']['driver']);
@@ -36,6 +64,8 @@ case 'edit':
         $notification->push($share, 'horde.error');
     } elseif (isset($share) && Auth::getAuth() != $share->get('owner')) {
         exit('permission denied');
+    } else {
+        $fbperms = getFbperms($share);
     }
     break;
 
@@ -226,6 +256,24 @@ case 'editform':
             }
         }
 
+        // Process free/busy permissions.
+        $fb_names = Util::getFormData('fb_names');
+        $fb_read = Util::getFormData('fb_read');
+
+        $fbperms = getFbperms($share);
+        foreach ($fb_names as $key => $user) {
+            if (empty($user)) {
+                continue;
+            }
+
+            if (!empty($fb_read[$key])) {
+                $fbperms[$user] = PERMS_READ;
+            } else {
+                unset($fbperms[$user]);
+            }
+        }
+        setFbperms($share, array_keys($fbperms));
+
         $result = $share->setPermission($perm, false);
         if (is_a($result, 'PEAR_Error')) {
             $notification->push($result, 'horde.error');
diff --git a/horde-webmail/kronolith/templates/perms/perms.inc b/horde-webmail/kronolith/templates/perms/perms.inc
index 4ca65a6..2174167 100644
--- a/horde-webmail/kronolith/templates/perms/perms.inc
+++ b/horde-webmail/kronolith/templates/perms/perms.inc
@@ -330,6 +330,61 @@ foreach ($userList as $user) {
   <td> </td>
 </tr>
 
+<!-- Extended free/busy Permissions -->
+<tr valign="middle">
+  <td class="header leftAlign">
+    <?php echo Horde::img('user.png', '', '', $registry->getImageDir('horde')) . ' ' . _("Extended free/busy access") ?>
+  </td>
+  <td class="header" align="center"> </td>
+  <td class="header" align="center"><?php echo _("Read") ?></td>
+  <td class="header" align="center"> </td>
+  <td class="header" align="center"> </td>
+  <td class="header" align="center"> </td>
+  <td class="header"> </td>
+</tr>
+<?php foreach ($fbperms as $user => $fbperm) { if ($user != $owner) { ?>
+<tr>
+  <td class="light"><?php echo htmlspecialchars(Auth::removeHook($user)) ?><input type="hidden" name="fb_names[<?php echo htmlspecialchars($user) ?>]" value="<?php echo htmlspecialchars($user) ?>" /></td>
+  <td align="center"> </td>
+  <td align="center">
+    <input type="checkbox" id="fb_read_<?php echo str_replace('@', '_', htmlspecialchars($user)) ?>" name="fb_read[<?php echo htmlspecialchars($user) ?>]"<?php echo ($fbperm & PERMS_READ) ? ' checked="checked"' : '' ?> />
+    <label for="fb_read_<?php echo str_replace('@', '_', htmlspecialchars($user)) ?>" class="hidden"><?php echo _("Read") ?></label>
+  </td>
+  <td align="center"> </td>
+  <td align="center"> </td>
+  <td align="center"> </td>
+  <td> </td>
+</tr>
+<?php } } ?>
+<!-- New extended free/busy row -->
+<tr>
+<?php if ($auth->hasCapability('list')): ?>
+  <td class="light">
+    <label for="fb_names_new" class="hidden"><?php echo _("Select a user to add:") ?></label>
+    <select id="fb_names_new" name="fb_names[||new]">
+      <option value=""><?php echo _("Select a user to add:") ?></option>
+    <?php foreach ($userList as $user) { if (!isset($fbperms[$user])) { ?>
+      <option value="<?php echo htmlspecialchars($user) ?>"><?php echo htmlspecialchars(Auth::removeHook($user)) ?></option>
+    <?php } } ?>
+    </select>
+  </td>
+<?php else: ?>
+  <td class="light">
+    <label for="fb_names_new" class="hidden"><?php echo _("User to add:") ?></label>
+    <input type="text" id="fb_names_new" name="fb_names[||new]" />
+  </td>
+<?php endif; ?>
+  <td align="center"> </td>
+  <td align="center">
+    <input type="checkbox" id="fb_read_new" name="fb_read[||new]" />
+    <label for="fb_read_new" class="hidden"><?php echo _("Read") ?></label>
+  </td>
+  <td align="center"> </td>
+  <td align="center"> </td>
+  <td align="center"> </td>
+  <td> </td>
+</tr>
+
 <tr>
  <td colspan="7"> </td>
 </tr>
-- 
tg: (d2b5eee..) t/kronolith/HK/GW/XfbAccess (depends on: t/kronolith/HK/GW/FbviewRelevance)
-- 
TOPGIT patch commit log
=======================

commit 56a0438a5135d9dc3cde040531ad8d7dbc654f8c
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Mar 13 01:27:45 2009 +0100

    Remove stray .orig file.

commit a6a8bb95cc237651c51fa16bd64dd30f122553bf
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 22:29:11 2009 +0000

    Added patch kronolith/HK-GW-Fbview_xfb_access.patch from the mercurial release queue.

--- NEW FILE: t_kronolith_HK_GW_getFreebusyServer.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/kronolith/HK/GW/getFreebusyServer

Use the capability to retrieve the Free/Busy server provided in Kolab_Server.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/kronolith/lib/Storage/kolab.php |   23 +++++++++++++++--------
 1 files changed, 15 insertions(+), 8 deletions(-)

diff --git a/horde-webmail/kronolith/lib/Storage/kolab.php b/horde-webmail/kronolith/lib/Storage/kolab.php
index a099702..5f4c8bb 100644
--- a/horde-webmail/kronolith/lib/Storage/kolab.php
+++ b/horde-webmail/kronolith/lib/Storage/kolab.php
@@ -29,17 +29,24 @@ class Kronolith_Storage_kolab extends Kronolith_Storage {
     {
         global $conf;
 
-        if (!is_callable('Kolab', 'getServer')) {
-            $server = $conf['kolab']['imap']['server'];
+        @include_once 'Horde/Kolab/Session.php';
+
+        if (class_exists('Horde_Kolab_Session')) {
+            $session = &Horde_Kolab_Session::singleton();
+            $server = $session->freebusy_server;
+        } else if (!is_callable('Kolab', 'getServer')) {
+            $server = sprintf('%s://%s:%d/freebusy/',
+                              $conf['storage']['freebusy']['protocol'],
+                              $conf['kolab']['imap']['server'],
+                              $conf['storage']['freebusy']['port']);
         } else {
-            $server = Kolab::getServer('imap');
+            $server = sprintf('%s://%s:%d/freebusy/',
+                              $conf['storage']['freebusy']['protocol'],
+                              Kolab::getServer('imap'),
+                              $conf['storage']['freebusy']['port']);
         }
 
-        $fb_url = sprintf('%s://%s:%d/freebusy/%s.xfb',
-                          $conf['storage']['freebusy']['protocol'],
-                          $server,
-                          $conf['storage']['freebusy']['port'],
-                          $email);
+        $fb_url = sprintf('%s/%s.xfb', $server, $email);
 
         $options['method'] = 'GET';
         $options['timeout'] = 5;
-- 
tg: (e52fa15..) t/kronolith/HK/GW/getFreebusyServer (depends on: t/framework/HK/GW/Kolab_Server/getFreebusyServer)
-- 
TOPGIT patch commit log
=======================

commit e5954131256e7fba29a3dd6827f872114b1ddcb7
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Jan 30 20:16:49 2009 +0000

    Added patch kronolith/HK-GW-Kolab_Server-getFreeBusyServer.patch from the mercurial release queue.

--- NEW FILE: t_kronolith_HK_SB_ExtraParameters.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/kronolith/HK/SB/ExtraParameters

Add additional event parameters to the Free/Busy view.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/kronolith/lib/FBView.php             |   27 +++++++++++++++++--
 .../kronolith/templates/fbview/busyblock.html      |    2 +-
 2 files changed, 25 insertions(+), 4 deletions(-)

diff --git a/horde-webmail/kronolith/lib/FBView.php b/horde-webmail/kronolith/lib/FBView.php
index f0bb03f..db402d3 100644
--- a/horde-webmail/kronolith/lib/FBView.php
+++ b/horde-webmail/kronolith/lib/FBView.php
@@ -87,7 +87,7 @@ class Kronolith_FreeBusy_View {
             $rows = '';
             foreach ($this->_requiredMembers as $member) {
                 $member->simplify();
-                $blocks = $this->_getBlocks($member, $member->getBusyPeriods(), 'busyblock.html', _("Busy"));
+                $blocks = $this->_getBlocks($member, $member->getBusyPeriods(), 'busyblock.html', _("Busy"), $member->getExtraParams());
                 $template = new Horde_Template();
                 $template->set('blocks', $blocks);
                 $template->set('name', $member->getName());
@@ -109,7 +109,7 @@ class Kronolith_FreeBusy_View {
             $rows = '';
             foreach ($this->_optionalMembers as $member) {
                 $member->simplify();
-                $blocks = $this->_getBlocks($member, $member->getBusyPeriods(), 'busyblock.html', _("Busy"));
+                $blocks = $this->_getBlocks($member, $member->getBusyPeriods(), 'busyblock.html', _("Busy"), $member->getExtraParams());
                 $template = new Horde_Template();
                 $template->set('blocks', $blocks);
                 $template->set('name', $member->getName());
@@ -125,6 +125,9 @@ class Kronolith_FreeBusy_View {
             $html .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/section.html');
         }
 
+	//**********
+	//This has been disabled in kolab-fbview. Make this optional?
+
         // Possible meeting times.
         $optimal->setAttribute('ORGANIZER', _("All Attendees"));
         $blocks = $this->_getBlocks($optimal,
@@ -147,6 +150,9 @@ class Kronolith_FreeBusy_View {
         $template->set('blocks', $blocks);
         $rows .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/row.html');
 
+	//This has been disabled in kolab-fbview. Make this optional?
+	//**********
+
         // Reset locale.
         setlocale(LC_NUMERIC, $lc);
 
@@ -215,7 +221,7 @@ class Kronolith_FreeBusy_View {
         return $instances[$view];
     }
 
-    function _getBlocks($member, $periods, $blockfile, $label)
+    function _getBlocks($member, $periods, $blockfile, $label, $extra = array())
     {
         $template = new Horde_Template();
         $template->set('label', $label);
@@ -248,6 +254,21 @@ class Kronolith_FreeBusy_View {
 
                 $template->set('left', $left . '%');
                 $template->set('width', $width . '%');
+                $template->set('evclick', '');
+
+                if (isset($extra[$periodStart])) {
+                    if (!empty($extra[$periodStart]['X-UID'])) {
+                        $link = "javascript:performAction('viewaction', '" 
+			  . addslashes($member->getName() . "#" 
+				       . String::convertCharset(base64_decode($extra[$periodStart]['X-UID']), 
+								'UTF-8',NLS::getCharset())) . "')";
+                        $template->set('evclick', $link);
+                    }
+                    if (!empty($extra[$periodStart]['X-SUMMARY'])) {
+                        $template->set('label', String::convertCharset(base64_decode($extra[$periodStart]['X-SUMMARY']),'UTF-8',
+				       NLS::getCharset()));
+                    }
+                }
 
                 $blocks .= $template->fetch(KRONOLITH_TEMPLATES . '/fbview/' . $blockfile);
             } else {
diff --git a/horde-webmail/kronolith/templates/fbview/busyblock.html b/horde-webmail/kronolith/templates/fbview/busyblock.html
index 223ee21..a442b54 100644
--- a/horde-webmail/kronolith/templates/fbview/busyblock.html
+++ b/horde-webmail/kronolith/templates/fbview/busyblock.html
@@ -1 +1 @@
-<td><div class="busy" style="left:<tag:left />;width:<tag:width />;"> </div></td>
+<td><div class="busy" onclick="<tag:evclick />" style="cursor:pointer;left:<tag:left />;width:<tag:width />;" title="<tag:label />"> </div></td>
-- 
tg: (917327f..) t/kronolith/HK/SB/ExtraParameters (depends on: t/kronolith/HK/SB/SaveEventAttendees)
-- 
TOPGIT patch commit log
=======================

commit 0c5a8f2db1f17bcc46f24ca0cc7c5395abb289dc
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Mar 13 01:19:17 2009 +0100

    Removed stray .orig file.

commit c9a3d3d22933a4b7c27288c49250ff7535bcbfbf
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 22:26:49 2009 +0000

    Added patch kronolith/HK-SB-Fbview_extra_params.patch from the mercurial release queue.

--- NEW FILE: t_kronolith_HK_SB_SaveEventAttendees.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/kronolith/HK/SB/SaveEventAttendees

Allow to save attendees when adding them to kronolith events.

FIXME: It would be better to save these as distribution lists now.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/kronolith/attendees.php              |   18 +++++
 horde-webmail/kronolith/config/prefs.php.dist      |    8 ++
 horde-webmail/kronolith/savedattlist.php           |   77 ++++++++++++++++++++
 .../kronolith/templates/attendees/attendees.inc    |    2 +
 .../templates/javascript/open_savedattlist_win.js  |   36 +++++++++
 .../templates/savedattlist/savedattlist.inc        |   68 +++++++++++++++++
 6 files changed, 209 insertions(+), 0 deletions(-)

diff --git a/horde-webmail/kronolith/attendees.php b/horde-webmail/kronolith/attendees.php
index a2d8b3e..e1b15c0 100644
--- a/horde-webmail/kronolith/attendees.php
+++ b/horde-webmail/kronolith/attendees.php
@@ -178,6 +178,16 @@ case 'clear':
     $attendees = array();
     $_SESSION['kronolith']['attendees'] = $attendees;
     break;
+
+case 'save':
+    if (empty($attendees)) {
+        break;
+    }
+    $savedattlist = unserialize($prefs->getValue('saved_attendee_list'));
+    $savedattlist[] = array_keys($attendees);
+    $prefs->setValue('saved_attendee_list', serialize($savedattlist));
+    $notification->push(_('Successfully saved attendee list'), 'horde.success');
+    break;
 }
 
 // Get the current Free/Busy view; default to the 'day' view if none specified.
@@ -264,6 +274,14 @@ Imple::factory('ContactAutoCompleter', array('triggerId' => 'newAttendees'));
 
 $title = _("Edit attendees");
 require KRONOLITH_TEMPLATES . '/common-header.inc';
+
+if ($browser->hasFeature('javascript')) {
+    Horde::addScriptFile('open_savedattlist_win.js');
+    $savedattlist_url = 'javascript:open_savedattlist_win();';
+} else {
+    $savedattlist_url = Horde::applicationUrl('savedattlist.php');
+}
+
 $notification->notify(array('status'));
 require KRONOLITH_TEMPLATES . '/attendees/attendees.inc';
 require $registry->get('templates', 'horde') . '/common-footer.inc';
diff --git a/horde-webmail/kronolith/config/prefs.php.dist b/horde-webmail/kronolith/config/prefs.php.dist
index 22c08c3..b1c49d8 100644
--- a/horde-webmail/kronolith/config/prefs.php.dist
+++ b/horde-webmail/kronolith/config/prefs.php.dist
@@ -497,3 +497,11 @@ $_prefs['last_kronolith_maintenance'] = array(
     'shared' => false,
     'type' => 'implicit'
 );
+
+$_prefs['saved_attendee_list'] = array(
+    'value' => 'a:0:{}',
+    'locked' => false,
+    'shared' => false,
+    'type' => 'implicit',
+    'desc' => _("A saved list of attendees")
+);
diff --git a/horde-webmail/kronolith/savedattlist.php b/horde-webmail/kronolith/savedattlist.php
new file mode 100644
index 0000000..631b994
--- /dev/null
+++ b/horde-webmail/kronolith/savedattlist.php
@@ -0,0 +1,77 @@
+<?php
+/**
+ * $Horde: kronolith/attendeeshandler.php,v 1.1 2004/05/25 08:34:21 stuart Exp $
+ *
+ * Copyright 2004 Code Fusion  <http://www.codefusion.co.za/>
+ *                Stuart Binge <s.binge at codefusion.co.za>
+ *
+ * See the enclosed file COPYING for license information (GPL).  If you
+ * did not receive this file, see http://www.fsf.org/copyleft/gpl.html.
+ */
+
+ at define('KRONOLITH_BASE', dirname(__FILE__));
+require_once KRONOLITH_BASE . '/lib/base.php';
+require_once KRONOLITH_BASE . '/lib/FBView.php';
+
+$title = _('Load Attendee List');
+
+Horde::addScriptFile('tooltip.js', 'horde');
+require KRONOLITH_TEMPLATES . '/common-header.inc';
+
+// Get our list of saved attendees
+$savedattlist = unserialize($prefs->getValue('saved_attendee_list'));
+
+// Preformat our image urls
+$delimg = Horde::img('delete.png', _("Remove List"), null, $GLOBALS['registry']->getImageDir('horde'));
+$loadimg = Horde::img('tree/folder.png', _("Load List"), null, $GLOBALS['registry']->getImageDir('horde'));
+
+// Get our Action ID & Value. This specifies what action the user initiated.
+$actionID = Util::getFormData('actionID', false);
+$actionValue = Util::getFormData('actionValue', false);
+if (!$actionID) {
+    $actionID = (Util::getFormData('addNew', false) ? 'add' : false);
+    $actionValue = Util::getFormData('newAttendees', '');
+}
+
+// Perform the specified action, if there is one.
+switch ($actionID) {
+case 'remove':
+    // Remove the specified attendee
+    if (array_key_exists($actionValue, $savedattlist)) {
+        unset($savedattlist[$actionValue]);
+	$prefs->setValue('saved_attendee_list', serialize($savedattlist));
+    }
+    
+    break;
+
+case 'dismiss':
+    // Make sure we're actually allowed to dismiss
+    if (!$allow_dismiss) break;
+
+    // Close the attendee window
+    global $browser;
+
+    if ($browser->hasFeature('javascript')) {
+        Util::closeWindowJS();
+    } else {
+        $url = Util::getFormData('url');
+
+        if (!empty($url)) {
+            $location = Horde::applicationUrl($url, true);
+        } else {
+            $url = Util::addParameter($prefs->getValue('defaultview') . '.php', 'month', Util::getFormData('month'));
+            $url = Util::addParameter($url, 'year', Util::getFormData('year'));
+            $location = Horde::applicationUrl($url, true);
+        }
+
+        // Make sure URL is unique.
+        $location = Util::addParameter($location, 'unique', md5(microtime()));
+
+        header('Location: ' . $location);
+    }
+    break;
+}
+
+$form_handler = Horde::applicationUrl('savedattlist.php');
+require KRONOLITH_TEMPLATES . '/savedattlist/savedattlist.inc';
+require $GLOBALS['registry']->get('templates', 'horde') . '/common-footer.inc';
diff --git a/horde-webmail/kronolith/templates/attendees/attendees.inc b/horde-webmail/kronolith/templates/attendees/attendees.inc
index b057ea0..88f77eb 100644
--- a/horde-webmail/kronolith/templates/attendees/attendees.inc
+++ b/horde-webmail/kronolith/templates/attendees/attendees.inc
@@ -92,6 +92,8 @@ function switchDateView(view, timestamp)
 <div>
  <input type="submit" class="button" name="addNew" value="<?php echo htmlspecialchars(_("Save Attendees")) ?>" />
  <input type="submit" class="button" name="addNewClose" value="<?php echo htmlspecialchars(_("Save and Finish")) ?>" />
+ <input type="button" class="button" name="loadAttList" value="<?php echo htmlspecialchars(_("Load Attendee List")) ?>" onclick="<?php echo $savedattlist_url ?>" />
+ <?php if (!empty($attendees)): ?><input type="button" class="button" name="saveAttList" value="<?php echo htmlspecialchars(_("Save Attendee List")) ?>" onclick="performAction('save', '');" /><?php endif; ?>
  <?php if (!empty($attendees)): ?><input type="submit" class="button" name="clearAll" value="<?php echo htmlspecialchars(_("Clear all attendees")) ?>" /><?php endif; ?>
 </div>
 
diff --git a/horde-webmail/kronolith/templates/javascript/open_savedattlist_win.js b/horde-webmail/kronolith/templates/javascript/open_savedattlist_win.js
new file mode 100644
index 0000000..388a4b7
--- /dev/null
+++ b/horde-webmail/kronolith/templates/javascript/open_savedattlist_win.js
@@ -0,0 +1,36 @@
+<?php if (!strstr($_SERVER['PHP_SELF'], 'javascript.php')): ?><script language="JavaScript" type="text/javascript">
+<!--
+<?php endif; ?>
+function open_savedattlist_win(args)
+{
+    var url = "<?php echo Horde::url($GLOBALS['registry']->applicationWebPath('%application%/savedattlist.php', 'kronolith')) ?>";
+    if (url.indexOf('?') == -1) glue = '?';
+    else glue = '<?php echo ini_get('arg_separator.output') ?>';
+    var now = new Date();
+    var name = "savedattlist_window_" + now.getTime();
+    if (args != "") {
+        url = url + glue + args + '<?php echo ini_get('arg_separator.output') ?>' + "uniq=" + now.getTime();
+    } else {
+        url = url + glue + "uniq=" + now.getTime();
+    }
+    var Width = screen.width;
+    if (Width > 775) {
+        Width = 700;
+    } else {
+        Width -= 75;
+    }
+    var Height = screen.height;
+    if (Height > 725) {
+        Height = 650;
+    } else {
+        Height -= 75;
+    }
+    param = "toolbar=no,location=no,status=yes,scrollbars=yes,resizable=yes,width=" + Width + ",height=" + Height + ",left=0,top=0";
+    name = window.open(url, name, param);
+    if (!eval("name.opener")) {
+        name.opener = self;
+    }
+}
+<?php if (!strstr($_SERVER['PHP_SELF'], 'javascript.php')): ?>// -->
+</script>
+<?php endif; ?>
diff --git a/horde-webmail/kronolith/templates/savedattlist/savedattlist.inc b/horde-webmail/kronolith/templates/savedattlist/savedattlist.inc
new file mode 100644
index 0000000..2489f25
--- /dev/null
+++ b/horde-webmail/kronolith/templates/savedattlist/savedattlist.inc
@@ -0,0 +1,68 @@
+<!-- javascript action handling -->
+<script language="JavaScript" type="text/javascript">
+<!--
+function performAction(id, value)
+{
+    document.savedattlistForm.actionID.value = id;
+    document.savedattlistForm.actionValue.value = value;
+    document.savedattlistForm.submit();
+    return false;
+}
+
+function updateMessage(list)
+{
+    if (parent.opener.closed) {
+        alert('<?php echo addslashes(_("The Edit Attendees screen is no longer present. Exiting.")) ?>');
+        this.close();
+        return;
+    }
+
+    if (!parent.opener.document.attendeesForm) {
+        alert('<?php echo addslashes(_("You can only use this form from the Edit Attendees screen.")) ?>');
+        this.close();
+        return;
+    }
+
+    parent.opener.document.attendeesForm.newAttendees.value = list;
+    this.close();
+}
+// -->
+</script>
+
+<form method="post" action="<?php echo $form_handler; ?>" name="savedattlistForm">
+<?php Util::pformInput(); ?>
+<input type="hidden" name="actionID" value="" />
+<input type="hidden" name="actionValue" value="" />
+
+<div align="center">
+
+<table border="0" width="500" cellspacing="0" cellpadding="2">
+
+<!-- header -->
+<tr><td colspan="4" class="header"><b><?php echo $title ?></b></td></tr>
+
+<!-- attendee list header -->
+<tr class="item">
+ <td nowrap="nowrap" width="2%" align="center"><?php echo $loadimg ?></td>
+ <td nowrap="nowrap" width="2%" align="center"><?php echo $delimg ?></td>
+ <td nowrap="nowrap" width="96%"><b><?php echo htmlspecialchars(_("Attendees")) ?></b></td>
+</tr>
+
+<!-- attendees -->
+<?php $i = 0 ?>
+<?php if (empty($savedattlist)): ?>
+ <tr class="item<?php echo ($i++ % 2) ?>"><td align="center" colspan="3"><i><?php echo htmlspecialchars('-- ' . _("No saved attendee lists are available") . ' --') ?></i></td></tr>
+<?php else: foreach ($savedattlist as $index => $list): ?>
+ <tr class="item<?php echo ($i++ % 2) ?>">
+ <?php
+  echo '<td align="center">', Horde::link("javascript:updateMessage('" . addslashes(implode(', ', $list)) . "')", _("Load this list")), $loadimg, "</a></td>";
+ ?>
+ <?php
+  echo '<td align="center">', Horde::link("javascript:performAction('remove', '" . $index . "')", _("Remove this list")), $delimg, "</a></td>";
+ ?>
+  <td><?php echo implode(', ', $list); ?></td>
+ </tr>
+<?php endforeach; endif; ?>
+</table>
+</div>
+</form>
-- 
tg: (6938161..) t/kronolith/HK/SB/SaveEventAttendees (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 917327fa2943eff049d5cb98cd33ffcb8cea880c
Author: Gunnar Wrobel <p at rdus.de>
Date:   Fri Mar 13 07:44:50 2009 +0100

    Remove stray .orig file.

commit 026a99dd501ffc926853a2d8af9a7cdd7e30c9a0
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 22:21:11 2009 +0000

    Added patch kronolith/HK-SB-Fbview_save_attendees.patch  from the mercurial release queue.

--- NEW FILE: t_nag_H_MR_Bug__7400.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/nag/H/MR/Bug_7400

Fixes Horde bug [#7400] Error when marking task "completed"

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/nag/lib/Driver.php |   55 +++++++++++++++++++++----------------
 1 files changed, 31 insertions(+), 24 deletions(-)

diff --git a/horde-webmail/nag/lib/Driver.php b/horde-webmail/nag/lib/Driver.php
index 2cd926a..c8fd4ee 100644
--- a/horde-webmail/nag/lib/Driver.php
+++ b/horde-webmail/nag/lib/Driver.php
@@ -319,33 +319,40 @@ class Nag_Driver {
 
         $new_task = $this->get($task->id);
         $log_tasklist = $this->_tasklist;
-        if ($task->tasklist != $tasklist) {
+        if (!is_null($tasklist) && $task->tasklist != $tasklist) {
             /* Moving the task to another tasklist. */
             $share = $GLOBALS['nag_shares']->getShare($task->tasklist);
-            if (!is_a($share, 'PEAR_Error') &&
-                $share->hasPermission(Auth::getAuth(), PERMS_DELETE)) {
-                $share = $GLOBALS['nag_shares']->getShare($tasklist);
-                if (!is_a($share, 'PEAR_Error') &&
-                    $share->hasPermission(Auth::getAuth(), PERMS_EDIT)) {
-                    $moved = $this->_move($task->id, $tasklist);
-                    if (is_a($moved, 'PEAR_Error')) {
-                        return $moved;
-                    }
-                    $new_storage = &Nag_Driver::singleton($tasklist);
-                    $new_task = $new_storage->get($task->id);
-
-                    /* Log the moving of this item in the history log. */
-                    if (!empty($task->uid)) {
-                        $history = &Horde_History::singleton();
-                        $history->log('nag:' . $task->tasklist . ':' . $task->uid, array('action' => 'delete'), true);
-                        $history->log('nag:' . $tasklist . ':' . $task->uid, array('action' => 'add'), true);
-                        $log_tasklist = $tasklist;
-                    }
-                } else {
-                    $GLOBALS['notification']->push(sprintf(_("Access denied moving the task to %s."), $share->get('name')), 'horde.error');
-                }
-            } else {
+            if (is_a($share, 'PEAR_Error')) {
+                return $share;
+            }
+
+            if (!$share->hasPermission(Auth::getAuth(), PERMS_DELETE)) {
                 $GLOBALS['notification']->push(sprintf(_("Access denied removing task from %s."), $share->get('name')), 'horde.error');
+                return false;
+            }
+
+            $share = $GLOBALS['nag_shares']->getShare($tasklist);
+            if (is_a($share, 'PEAR_Error')) {
+                return $share;
+            }
+
+            if (!$share->hasPermission(Auth::getAuth(), PERMS_EDIT)) {
+                $GLOBALS['notification']->push(sprintf(_("Access denied moving the task to %s."), $share->get('name')), 'horde.error');
+            }
+
+            $moved = $this->_move($task->id, $tasklist);
+            if (is_a($moved, 'PEAR_Error')) {
+                return $moved;
+            }
+            $new_storage = &Nag_Driver::singleton($tasklist);
+            $new_task = $new_storage->get($task->id);
+
+            /* Log the moving of this item in the history log. */
+            if (!empty($task->uid)) {
+                $history = &Horde_History::singleton();
+                $history->log('nag:' . $task->tasklist . ':' . $task->uid, array('action' => 'delete'), true);
+                $history->log('nag:' . $tasklist . ':' . $task->uid, array('action' => 'add'), true);
+                $log_tasklist = $tasklist;
             }
         }
 
-- 
tg: (6938161..) t/nag/H/MR/Bug_7400 (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit e1ffc45a709692e0d13252f21ce6af7a91a6f42c
Author: Gunnar Wrobel <p at rdus.de>
Date:   Thu Jan 29 22:46:42 2009 +0100

    Included patch nag/H-MR-bug_7400.patch from the mercurial patch queue.

--- NEW FILE: t_pear_HK_GW_AddNetIMAP.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/pear/HK/GW/AddNetIMAP

Adds the PEAR Net_IMAP library in case the user does not have a PHP patched for Kolab.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/pear/Net/IMAP.php         | 2981 ++++++++++++++++++++++++
 horde-webmail/pear/Net/IMAPProtocol.php | 3797 +++++++++++++++++++++++++++++++
 2 files changed, 6778 insertions(+), 0 deletions(-)

diff --git a/horde-webmail/pear/Net/IMAP.php b/horde-webmail/pear/Net/IMAP.php
new file mode 100644
index 0000000..491b63f
--- /dev/null
+++ b/horde-webmail/pear/Net/IMAP.php
@@ -0,0 +1,2981 @@
+<?php
[...6774 lines suppressed...]
+                return substr($string, $start, $length);
+            } else {
+                return substr($string, $start);
+            }
+        }
+    }
+
+}//Class
+?>
-- 
tg: (56f3df6..) t/pear/HK/GW/AddNetIMAP (depends on: t/Kolab_Server/HK/GW/FixBodyHeaderBreakInTestDriver)
-- 
TOPGIT patch commit log
=======================

commit 451b1fbef4b6acf4fb332cecd2d96bd67b34fa19
Author: Gunnar Wrobel <p at rdus.de>
Date:   Wed Mar 11 21:52:31 2009 +0000

    Adds the PEAR Net_IMAP library in case the user does not have a PHP patched for Kolab.

--- NEW FILE: t_turba_HK_GW_AutomaticFreeBusyUrl.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/turba/HK/GW/AutomaticFreeBusyUrl

Determine the free/busy URL of Kolab users automatically.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/turba/config/attributes.php      |    6 ++++++
 horde-webmail/turba/config/attributes.php.dist |    6 ++++++
 horde-webmail/turba/config/sources.php.dist    |    4 +++-
 3 files changed, 15 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/turba/config/attributes.php b/horde-webmail/turba/config/attributes.php
index ce124f0..5a127d8 100644
--- a/horde-webmail/turba/config/attributes.php
+++ b/horde-webmail/turba/config/attributes.php
@@ -356,6 +356,12 @@ $attributes['category'] = array(
 );
 
 /* Additional attributes supported by Kolab */
+$attributes['kolabHomeServer'] = array(
+    'label' => _("Kolab Home Server"),
+    'type' => 'text',
+    'required' => false,
+    'params' => array('regex' => '', 'size' => 40, 'maxlength' => 255)
+);
 $attributes['initials'] = array(
     'label' => _("Initials"),
     'type' => 'text',
diff --git a/horde-webmail/turba/config/attributes.php.dist b/horde-webmail/turba/config/attributes.php.dist
index 0332682..3afb76f 100644
--- a/horde-webmail/turba/config/attributes.php.dist
+++ b/horde-webmail/turba/config/attributes.php.dist
@@ -402,6 +402,12 @@ $attributes['category'] = array(
 // );
 
 /* Additional attributes supported by Kolab */
+$attributes['kolabHomeServer'] = array(
+    'label' => _("Kolab Home Server"),
+    'type' => 'text',
+    'required' => false,
+    'params' => array('regex' => '', 'size' => 40, 'maxlength' => 255)
+);
 $attributes['initials'] = array(
     'label' => _("Initials"),
     'type' => 'text',
diff --git a/horde-webmail/turba/config/sources.php.dist b/horde-webmail/turba/config/sources.php.dist
index 3d5adf4..fd6eb7a 100644
--- a/horde-webmail/turba/config/sources.php.dist
+++ b/horde-webmail/turba/config/sources.php.dist
@@ -825,7 +825,9 @@ if (!empty($GLOBALS['conf']['kolab']['enabled'])) {
                 'cellPhone'         => 'mobile',
                 'fax'               => 'fax',
                 'notes'             => 'description',
-                'freebusyUrl'       => 'kolabHomeServer',
+                'kolabHomeServer'   => 'kolabHomeServer',
+                'freebusyUrl'       => array('fields' => array('kolabHomeServer', 'email'),
+                                             'format' => 'https://%s/freebusy/%s.ifb'),
             ),
             'search' => array(
                 'name',
-- 
tg: (3e628f4..) t/turba/HK/GW/AutomaticFreeBusyUrl (depends on: t/framework/HK/GW/Kolab_Storgae/FixedUpdateTriggering)
-- 
TOPGIT patch commit log
=======================

commit 358bad0ddf162ff032066b1045fec1f76d427e56
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 16:21:52 2009 +0000

    Added patch turba/HK-GW-Fix_freebusyurl.patch from the mercurial release queue.

--- NEW FILE: t_turba_HK_GW_FixAddressbookDeletion.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/turba/HK/GW/FixAddressbookDeletion

Fixes a Kolab specific problem with addressbook deletion. The fix is considered a hack by upstream and needs to be fixed at some point.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/turba/lib/Driver/share.php |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/horde-webmail/turba/lib/Driver/share.php b/horde-webmail/turba/lib/Driver/share.php
index 57222a4..2776a8f 100644
--- a/horde-webmail/turba/lib/Driver/share.php
+++ b/horde-webmail/turba/lib/Driver/share.php
@@ -145,7 +145,7 @@ class Turba_Driver_share extends Turba_Driver {
     function _deleteAll($sourceName = null)
     {
         if (is_null($sourceName)) {
-            $sourceName = $this->getContactOwner();
+            $sourceName = $this->getName();
         }
         return $this->_driver->_deleteAll($sourceName);
     }
-- 
tg: (6938161..) t/turba/HK/GW/FixAddressbookDeletion (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit cd7fd7431e30f5d645276f3b7cafe12935bcb836
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 23:48:17 2009 +0000

    Added patch turba/HK-GW-Fix_address_book_deletion_2.patch from the mercurial release queue.

--- NEW FILE: t_turba_HK_GW_FixSyncMLAttributeDeletion.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/turba/HK/GW/FixSyncMLAttributeDeletion

Fix the deletion of contact attributes when using SyncML.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/turba/lib/Driver.php |    3 ---
 1 files changed, 0 insertions(+), 3 deletions(-)

diff --git a/horde-webmail/turba/lib/Driver.php b/horde-webmail/turba/lib/Driver.php
index 248e5d3..efc61f8 100644
--- a/horde-webmail/turba/lib/Driver.php
+++ b/horde-webmail/turba/lib/Driver.php
@@ -1466,9 +1466,6 @@ class Turba_Driver {
         $hash = array();
         $attr = $vcard->getAllAttributes();
         foreach ($attr as $item) {
-            if (empty($item['value'])) {
-                continue;
-            }
 
             switch ($item['name']) {
             case 'FN':
-- 
tg: (6938161..) t/turba/HK/GW/FixSyncMLAttributeDeletion (depends on: master)
-- 
TOPGIT patch commit log
=======================

commit 3e71b03529030111cea5a55dbe3b4e2cbd98a6b0
Author: Gunnar Wrobel <p at rdus.de>
Date:   Mon Feb 2 00:16:42 2009 +0000

    Remove patch remains.

commit a3ce2f6066fe85019312ff354f5bca6ba5e3d2ab
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 23:50:06 2009 +0000

    Added patch turba/HK-GW-SyncML_delete_attributes.patch from the mercurial release queue.

--- NEW FILE: t_turba_HK_GW_PhotoSupport.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/turba/HK/GW/PhotoSupport

Support photos in turba.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/turba/config/sources.php.dist |    4 +-
 horde-webmail/turba/lib/Driver/kolab.php    |   54 +++++++++++++++-----------
 horde-webmail/turba/lib/Object.php          |    5 ++-
 3 files changed, 38 insertions(+), 25 deletions(-)

diff --git a/horde-webmail/turba/config/sources.php.dist b/horde-webmail/turba/config/sources.php.dist
index eae2039..3d5adf4 100644
--- a/horde-webmail/turba/config/sources.php.dist
+++ b/horde-webmail/turba/config/sources.php.dist
@@ -893,6 +893,8 @@ if (!empty($GLOBALS['conf']['kolab']['enabled'])) {
             'nameSuffix'        => 'suffix',
             'initials'          => 'initials',
             'nickname'          => 'nick-name',
+            'photo'             => 'photo',
+            'phototype'         => 'phototype',
             'gender'            => 'gender',
             'birthday'          => 'birthday',
             'spouse'            => 'spouse-name',
@@ -939,7 +941,7 @@ if (!empty($GLOBALS['conf']['kolab']['enabled'])) {
         'tabs' => array(
             _("Personal") => array('name', 'firstname', 'lastname', 'middlenames',
                                    'namePrefix', 'nameSuffix', 'initials', 'nickname',
-                                   'gender', 'birthday', 'spouse', 'anniversary',
+                                   'photo', 'gender', 'birthday', 'spouse', 'anniversary',
                                    'children'),
             _("Location") => array('homeStreet', 'homeCity', 'homeProvince',
                                    'homePostalCode', 'homeCountry', 'workStreet',
diff --git a/horde-webmail/turba/lib/Driver/kolab.php b/horde-webmail/turba/lib/Driver/kolab.php
index f97f75a..a585950 100644
--- a/horde-webmail/turba/lib/Driver/kolab.php
+++ b/horde-webmail/turba/lib/Driver/kolab.php
@@ -751,6 +751,14 @@ class Turba_Driver_kolab_wrapper_new extends Turba_Driver_kolab_wrapper {
             if (isset($contact['email'])) {
                 unset($contact['email']);
             }
+            if (isset($contact['picture'])) {
+                $name = $contact['picture'];
+                if (isset($contact['_attachments'][$name])) {
+                    $contact['photo'] =  $this->_store->_data->getAttachment($contact['_attachments'][$name]['key']);
+                    $contact['phototype'] = $contact['_attachments'][$name]['type'];
+                }
+            }
+
             $contacts[$id] = $contact;
         }
 
@@ -1088,29 +1096,11 @@ class Turba_Driver_kolab_wrapper_new extends Turba_Driver_kolab_wrapper {
             $attributes['full-name'] = $attributes['given-name'] . ' ' . $attributes['full-name'];
         }
 
-        $group = false;
-        if (isset($attributes['__type']) && $attributes['__type'] == 'Group') {
-            $group = true;
-            $result = $this->_store->setObjectType('distribution-list');
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-            $this->_convertMembers($attributes);
-        }
-
-        $object_id = $this->_store->save($attributes, null);
-        if (is_a($object_id, 'PEAR_Error')) {
-            return $object_id;
-        }
-
-        if ($group) {
-            $result = $this->_store->setObjectType('contact');
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
+        $result = $this->_store($attributes);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
         }
-
-        return $object_id;
+        return true;
     }
 
     /**
@@ -1126,9 +1116,19 @@ class Turba_Driver_kolab_wrapper_new extends Turba_Driver_kolab_wrapper {
         }
 
         if ($object_key != 'uid') {
-            return PEAR::raiseError(sprintf(_("Key for saving must be a UID not %s!"), $object_key));
+            return PEAR::raiseError(sprintf(_("Key for saving must be \'uid\' not %s!"), $object_key));
         }
 
+        return $this->_store($attributes, $object_id);
+    }
+
+    /**
+     * Stores an object in the Kolab message store.
+     *
+     * @return string  The object id, possibly updated.
+     */
+    function _store($attributes, $object_id = null)
+    {
         $group = false;
         if (isset($attributes['__type']) && $attributes['__type'] == 'Group') {
             $group = true;
@@ -1139,6 +1139,14 @@ class Turba_Driver_kolab_wrapper_new extends Turba_Driver_kolab_wrapper {
             $this->_convertMembers($attributes);
         }
 
+        if (isset($attributes['photo']) && isset($attributes['phototype'])) {
+            $attributes['_attachments']['photo.attachment'] = array('type' => $attributes['phototype'],
+                                                                    'content' => $attributes['photo']);
+            $attributes['picture'] = 'photo.attachment';
+            unset($attributes['photo']);
+            unset($attributes['phototype']);
+        }
+
         $result = $this->_store->save($attributes, $object_id);
         if (is_a($result, 'PEAR_Error')) {
             return $result;
diff --git a/horde-webmail/turba/lib/Object.php b/horde-webmail/turba/lib/Object.php
index ed7f65f..57c9368 100644
--- a/horde-webmail/turba/lib/Object.php
+++ b/horde-webmail/turba/lib/Object.php
@@ -249,7 +249,10 @@ class Turba_Object {
      */
     function addFile($info)
     {
-        $this->_vfsInit();
+        $result = $this->_vfsInit();
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
 
         $dir = TURBA_VFS_PATH . '/' . $this->getValue('__uid');
         $file = $info['name'];
-- 
tg: (ea9082a..) t/turba/HK/GW/PhotoSupport (depends on: t/framework/HK/GW/Vfs/KolabDriver)
-- 
TOPGIT patch commit log
=======================

commit 051c43e74fd790df114eb5a9c6aefc6f86c82d96
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sat Jan 31 00:14:04 2009 +0000

    Added patch /turba/HK-GW-Photo_support.patch from the mercurial release queue.

--- NEW FILE: t_turba_HK_GW_SyncMLrefresh.diff ---
From: Gunnar Wrobel <p at rdus.de>
Subject: [PATCH] t/turba/HK/GW/SyncMLrefresh

Refresh addressbooks before running a synchronization.

Signed-off-by: Gunnar Wrobel <p at rdus.de>

---
 horde-webmail/turba/lib/Driver/kolab.php |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/horde-webmail/turba/lib/Driver/kolab.php b/horde-webmail/turba/lib/Driver/kolab.php
index f97f75a..786f2e2 100644
--- a/horde-webmail/turba/lib/Driver/kolab.php
+++ b/horde-webmail/turba/lib/Driver/kolab.php
@@ -56,6 +56,7 @@ class Turba_Driver_kolab extends Turba_Driver {
         }
 
         $this->_wrapper = &new $wrapper($this->name, $this->_kolab);
+        $this->_wrapper->connect();        
     }
 
     /**
-- 
tg: (015e842..) t/turba/HK/GW/SyncMLrefresh (depends on: t/turba/HK/GW/FixSyncMLAttributeDeletion)
-- 
TOPGIT patch commit log
=======================

commit d59cb82e5725f53d3f6fa2a84e17ad3e46078e99
Author: Gunnar Wrobel <p at rdus.de>
Date:   Sun Feb 1 23:53:10 2009 +0000

    Added patch turba/HK-GW-SyncML_refresh.patch  from the mercurial release queue.





More information about the commits mailing list