--- /dev/null	2005-06-16 08:11:33.843000000 -0400
+++ SyncML/ResultsSender.php	2005-06-10 20:56:07.828125000 -0400
@@ -0,0 +1,118 @@
+<?php
+
+include_once 'Horde/SyncML/State.php';
+include_once 'Horde/SyncML/Command.php';
+
+/**
+ * $Horde: framework/SyncML/SyncML/Command/Results.php,v 1.14 2005/04/24 12:09:02 karsten Exp $
+ *
+ * Copyright 2003-2005 Anthony Mills <amills@pyramid6.com>
+ *
+ * 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  Anthony Mills <amills@pyramid6.com>
+ * @since   Horde 3.0
+ * @package Horde_SyncML
+ */
+class ResultsSender 
+{
+
+    var $_cmdRef;
+    var $_type;
+    var $_data;
+    var $_locSourceURI;
+
+    function output($currentCmdID, &$output)
+    {
+        $state = & $_SESSION['SyncML.state'];
+
+        $attrs = array();
+        $output->startElement($state->getURI(), 'Results', $attrs);
+
+        $output->startElement($state->getURI(), 'CmdID', $attrs);
+        $chars = $currentCmdID;
+        $output->characters($chars);
+        $output->endElement($state->getURI(), 'CmdID');
+
+        $output->startElement($state->getURI(), 'MsgRef', $attrs);
+        $chars = $state->getMsgID();
+        $output->characters($chars);
+        $output->endElement($state->getURI(), 'MsgRef');
+
+        $output->startElement($state->getURI(), 'CmdRef', $attrs);
+        $chars = $this->_cmdRef;
+        $output->characters($chars);
+        $output->endElement($state->getURI(), 'CmdRef');
+
+        $output->startElement($state->getURI(), 'Meta', $attrs);
+        $output->startElement($state->getURIMeta(), 'Type', $attrs);
+        $output->characters($this->_type);
+        $output->endElement($state->getURIMeta(), 'Type');
+        $output->endElement($state->getURI(), 'Meta');
+
+        $output->startElement($state->getURI(), 'Item', $attrs);
+        $output->startElement($state->getURI(), 'Source', $attrs);
+        $output->startElement($state->getURI(), 'LocURI', $attrs);
+        $chars = $this->_locSourceURI;
+        $output->characters($chars);
+        $output->endElement($state->getURI(), 'LocURI');
+        $output->endElement($state->getURI(), 'Source');
+
+        $output->startElement($state->getURI(), 'Data', $attrs);
+
+        // Need to send this information as opaque data so the WBXML
+        // will understand it.
+        $output->opaque($this->_data);
+
+        $output->endElement($state->getURI(), 'Data');
+        $output->endElement($state->getURI(), 'Item');
+
+        $output->endElement($state->getURI(), 'Results');
+
+        $currentCmdID++;
+
+        return $currentCmdID;
+    }
+
+    /**
+     * Setter for property cmdRef.
+     *
+     * @param string $cmdRef  New value of property cmdRef.
+     */
+    function setCmdRef($cmdRef)
+    {
+        $this->_cmdRef = $cmdRef;
+    }
+
+    /**
+     * Setter for property Type.
+     *
+     * @param string $type  New value of property type.
+     */
+    function setType($type)
+    {
+        $this->_type = $type;
+    }
+
+    /**
+     * Setter for property data.
+     *
+     * @param string $data  New value of property data.
+     */
+    function setData($data)
+    {
+        $this->_data = $data;
+    }
+
+    /**
+     * Setter for property locSourceURI.
+     *
+     * @param string $locSourceURI  New value of property locSourceURI.
+     */
+    function setlocSourceURI($locSourceURI)
+    {
+        $this->_locSourceURI = $locSourceURI;
+    }
+
+}
--- /dev/null	2005-06-16 08:11:52.968000000 -0400
+++ SyncML/Device/Synthesis.php	2005-06-16 07:38:08.468750000 -0400
@@ -0,0 +1,179 @@
+<?php
+
+/**
+ * The SyncML_Device:: class provides functionality that is potentially (client)
+ * device dependant.
+ * 
+ * So  if a sync client needs any kind of special data of the data sent to it or
+ * received from it, this is done here. There are two source of information to
+ * identify an device: The first (and better) one is the DevInf device info sent
+ * by the device upon a get request. If DevInf is not supported or sent by the
+ * client, the SourceURI of the device may be sufficent to identify it.
+ * 
+ * 
+ * Copyright 2005 Karsten Fourmont <karsten@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  Karsten Fourmont <karsten@horde.org>
+ * @package Horde_Framework
+ */
+
+ 
+ 
+class SyncML_Device_Synthesis extends SyncML_Device
+{
+    
+    /**
+     * When a client sends data during a sync but does not provide
+     * information about the contenttype with this individual item,
+     * this function returns the contenttype the item is supposed to be in.
+     * 
+     * As this is only used to parse to the horde's importdata api functions,
+     * some simple guesses for the contenttype are completly sufficient:
+     * horde does not care whether data is text/x-vcalendar or text/icalendar.
+     * So normally the default implementation in Device.php is perfectly
+     * sufficient. 
+     */
+
+//    function getPreferedContentType($type)
+//    {
+//        return parent::getPreferedContentType($type);
+//    }
+
+    /**
+     * Returns the preferred contenttype of the client for the given
+     * sync data type (contacts/tasks/notes/calendar).
+     *
+     * The result is passed as an option to the Horde API export functions.
+     * Please note that this is not the contentType ultimately passed to the 
+     * client but rather the contentType presented to the Horde API export 
+     * functions.
+     * After the data is retrieved from horde, convertServer2Client can do
+     * some post-processing and set the correct contentType acceptable for
+     * the client.
+     * 
+     *
+     * This is a likely candidate for modification in concrete subclasses:
+     * individual devices might prefer other charsets or other encodings
+     * (currently: QUOTED-PRINTABLE)
+     */
+    function getPreferedContentTypeClient($type)
+    {
+        if ($type == 'contacts') {
+                return parent::getPreferedContentTypeClient($type);
+        }
+        elseif ($type == 'notes') {
+                return parent::getPreferedContentTypeClient($type);
+        }
+        elseif ($type == 'tasks') {
+                return parent::getPreferedContentTypeClient($type);
+        }
+        elseif ($type == 'calendar') {
+                return parent::getPreferedContentTypeClient($type);
+        }
+        return parent::getPreferedContentTypeClient($type);
+    }
+
+    /**
+     * Convert the content.
+     *
+     * Currently strips uid (primary key) information as client and
+     * server might use different ones.
+     *
+     * Charset conversions might be added here too.
+     *
+     * @access public
+     * 
+     * @param string $content       The content to convert
+     * @param string $contentType   The contentType of the content 
+     * @return array                array($newcontent, $newcontentType):
+     *                              the converted content and the
+     *                              (possibly changed) new ContentType.
+     */
+    function convertClient2Server($content, $contentType)
+    {
+
+        list($content, $contentType) = 
+                parent::convertClient2Server($content, $contentType);
+
+        // do required conversions here                
+
+        if (DEBUGLOG_ICALENDARDATA == true) {
+            $fp=@fopen('/tmp/sync/log.txt', 'a');
+            if ($fp) {
+                @fwrite($fp, "\ninput converted for server s ($contentType):\n");
+                @fwrite ($fp,$content . "\n");
+                @fclose($fp);
+            }
+        }
+
+        return array($content, $contentType);
+    }
+
+    /**
+     * Converts the content from the backend to a format suitable for the
+     * client device.
+     *
+     * Strips the uid (primary key) information as client and server might use
+     * different ones.
+     *
+     * Charset conversions might be added here too.
+     *
+     * @access public
+     * 
+     * @param string $content       The content to convert
+     * @param string $contentType   The contentType of content as returned from
+     *                              the backend
+     * @return array                array($newcontent, $newcontentType):
+     *                              the converted content and the
+     *                              (possibly changed) new ContentType.
+     */
+
+    function convertServer2Client($content, $contentType)
+    {
+        global $backend;
+
+        list($content, $contentType) = 
+                parent::convertServer2Client($content, $contentType);
+
+        // do conversions here
+        //NPS: Not really technically correct, just swapping out the version number
+        //in the header so that the client doesn't immediately deny with a "Format
+        //not supported".  There is an open ticket at Horde to fix this properly.
+        $content = preg_replace('/(\r\n|\r|\n)VERSION:2.0/', '\1VERSION:1.0', $content, 1);
+
+        if (DEBUGLOG_ICALENDARDATA == true) {
+            $fp=@fopen('/tmp/sync/log.txt', 'a');
+            if ($fp) {
+                @fwrite($fp, "\noutput converted for client s ($contentType):\n");
+                @fwrite ($fp, $content . "\n");
+                @fclose($fp);
+            }
+        }
+
+        return array($content, $contentType);
+    }
+
+    /**
+     *
+     * Some devices like the Sony Ericsson P800/P900/P910 handle vtodos (tasks)
+     * and vevents in the same "calendar" sync.
+     * This requires special actions on our side as we store this in different
+     * databases (nag and kronolith).
+     * This functions determines whether the client does it like that.
+     * Currently this is done by checking the DevInf information. For
+     * different clients there may be different ways to find out how the
+     * client likes its tasks.
+     */
+    function handleTasksInCalendar()
+    {
+
+        // $di = $this->deviceInfo();
+
+        return parent::handleTasksInCalendar();
+
+    }
+
+}

