<?xml version="1.0"?>
<!-- PLAN44.CH SYNCML CLIENT Library Version 3.4 Sample Configuration file -->
<!-- (works for V3.1.4.0 and later) -->

<sysync_config version="1.0">

	<!-- note: $(sandbox), $(logpath) must passed to the SyncML engine as a so called "config variable" before initializing
       the engine with the config file -->
  <configvar name="logpath" value="$(sandbox)/tmp/sysynclogs"/>
  <configvar name="binfilespath" value="$(sandbox)/Library/Preferences"/>
  <configvar name="textfilespath" value="$(sandbox)/Documents"/>
  

  <!-- this string is output to every session debug logfile to identify the config in use -->
  <configidstring>iOS sample SyncML client app</configidstring>

  <model>SySync Client iPhone SAMPLE</model>

  <debug>
    <!-- path where logfiles are stored -->
    <logpath>$(logpath)</logpath>
    <logflushmode>flush</logflushmode> <!-- buffered is fastest mode, but may loose data on process abort. Other options: "flush" (after every line) or "openclose" (safest, slowest, like in 2.x server) -->
    <!-- per session log -->
    <sessionlogs>yes</sessionlogs> <!-- by default, create a session log file for every sync session (might be disabled for special users/devices in scripts) -->
    <!-- debug format options -->
    <logformat>html</logformat> <!-- html is nicely colored and easily viewable with a web browser. Other options: "xml", "text" -->
    <timestamp>yes</timestamp> <!-- show timestamps for structure elements in log -->
    <timestampall>no</timestampall> <!-- don't show timestamp for every log line -->
    <timedsessionlognames>yes</timedsessionlognames> <!-- session logs also have the session start timestamp in the filename - makes them more easily sortable -->
    <!-- thread logging mode -->
    <subthreadmode>separate</subthreadmode> <!-- write log info from subthreads into separate log files. Other options: "suppress" -->
    <!-- basic debug level selection -->
    <enable option="extended"/> <!-- "extended" is a good choice for start testing. For production, use "normal" or "minimal" -->
    <!-- <enable option="normal"/> --> <!-- "normal" provides rich debug info, but still in reasonable size  -->
    <!-- <enable option="minimal"/> --> <!-- "minimal" just shows basic flow and error. Not suitable for debugging -->
    <!-- <enable option="maximal"/> --> <!-- "maximal" can create VERY LARGE logs and cause HEAVY SLOWDOWN. Only for detail debugging  -->
    <!-- <enable option="all"/> --> <!-- "all" shows EVERYTHING possible, and way too much for any normal situation. For hardcore debugging ONLY! -->
    <!-- additional debug info switches -->
    <enable option="userdata"/> <!-- Make this <disable ...> if you don't want user data in the logs -->
    <enable option="scripts"/> <!-- Make this <enable ...> to show script execution in logs  -->
    <enable option="exotic"/> <!-- Make this <enable ...> to include very in-detail info. CAN PRODUCE ENORMOUS LOGS and HEAVILY IMPACT PERFORMANCE for large slow syncs - use with care!  -->
    <!--<disable option="all"/>-->
    <!-- see manual for more debug info switches -->
    <!-- global log options -->
    <globallogs>no</globallogs> <!-- by default, do not log global session dispatching, creation etc. (not useful in multi-user operation) -->
    <singlegloballog>no</singlegloballog> <!-- a new global log will be started for every start of the server/application -->
    <!-- SyncML message dumping options -->
    <msgdump>yes</msgdump> <!-- do not dump syncml traffic 1:1 to files -->
    <xmltranslate>no</xmltranslate> <!-- do not try to translate syncml traffic into XML (DO NOT SET THIS OPTION IN PRODUCTIVE SERVERS!) -->
  </debug>

  <scripting>
    <looptimeout>5</looptimeout>


    <macro name="VCARD_INCOMING_SCRIPT"><![CDATA[
      // convert BDAY into a timestamp at noon in local time for iPhone address book
      BDAY_TS = BDAY;
      if (BDAY!=EMPTY) {
        BDAY_TS = BDAY_TS + TIMEUNITS(12*60*60); // make noon
        SETTIMEZONE(BDAY_TS,USERTIMEZONE());
      }
    ]]></macro>

    <macro name="VCARD_OUTGOING_SCRIPT"><![CDATA[
      // convert BDAY from local timestamp back to date-only
      BDAY = DATEONLY(CONVERTTOZONE(BDAY_TS,USERTIMEZONE(),TRUE));
    ]]></macro>



    <macro name="VCAL_INCOMING_SCRIPT"><![CDATA[
      STRING MATCHES[];
      STRING CAT,CN,EM;
      INTEGER i;
      TIMESTAMP ts;
      // make sure we have all trailing and leading spaces eliminated
      DESCRIPTION=NORMALIZED(DESCRIPTION);
      SUMMARY=NORMALIZED(SUMMARY);
      // eliminate description that is the same as summary
      if (DESCRIPTION==SUMMARY) DESCRIPTION=EMPTY;
      // calendar or todo
      if (ISEVENT) {
        // VEVENT
        // - handle duration cases
        if (ISDURATION(DURATION)) {
          if (DTEND==EMPTY) DTEND = DTSTART + DURATION;
          if (DTSTART==EMPTY) DTSTART = DTEND - DURATION;
        }
        // - detect alldays in vCalendar 1.0 (0:00-0:00 or 23:59 localtime)
        i = ALLDAYCOUNT(DTSTART,DTEND,TRUE);
        if (i>0) {
          // DTSTART and DTEND probably (could be real 24h timed as well in iCalendar 2.0!) represent allday event
          if (ITEMDATATYPE()=="vcalendar10") {
            // vCalendar 1.0 - this must be allday
            // - convert start to user zone (or floating) so it represents midnight
            DTSTART = CONVERTTOUSERZONE(DTSTART);
            // - make them real date-only values
            MAKEALLDAY(DTSTART,DTEND,i);
          }
          else {
            // iCalendar 2.0 - only if DTSTART is a date-only value this really is an allday
            if (ISDATEONLY(DTSTART)) {
            // reshape to make sure we don't have invalid zero-duration alldays (old OCS 9 servers)
            MAKEALLDAY(DTSTART,DTEND,i);
            }
          }
        }
        // - shape attendees (and make sure ATTENDEES[] is assigned even for empty email addresses)
        i=0;
        while(i<SIZE(ATTENDEES) || i<SIZE(ATTENDEE_CNS)) {
          PARSEEMAILSPEC(ATTENDEES[i], CN, EM);
          ATTENDEES[i] = EM; // pure email address
          // in case we have no specific common name, use the one extracted from the email
          // This catches the vCalendar 1.0 case and eventually ill-formed iCalendar 2.0 as well
          if (ATTENDEE_CNS[i]==EMPTY)
            ATTENDEE_CNS[i]=CN;
          // default participation status to needs-action
          if (ATTENDEE_PARTSTATS[i]==EMPTY)
            ATTENDEE_PARTSTATS[i]=1; // 1=needs action
          i=i+1;
        }
        // - shape organizer
        PARSEEMAILSPEC(ORGANIZER, CN, EM);
        ORGANIZER = EM; // pure email address
        if (ORGANIZER_CN==EMPTY)
          ORGANIZER_CN=CN;
      }
      // Common alarm handling
      // - handle relative alarm time (as possible with VALARM TRIGGER)
      if (ISDURATION(ALARM_TIME)) {
        if (ALARM_REL==2)
          ts = DTEND; // relative to end
        else {
          ts = DTSTART; // relative to start for events
        }
        // for now, make ALARM user(=system) zone in all cases
        ALARM_TIME = CONVERTTOUSERZONE(POINTINTIME(ts),TRUE) + ALARM_TIME;
      }
    ]]></macro>


    <macro name="VCAL_OUTGOING_SCRIPT"><![CDATA[
      // set UTC time of generation for iCalendar 2.0 DTSTAMP
      DGENERATED = NOW();
      // make sure we have all trailing and leading spaces eliminated
      DESCRIPTION=NORMALIZED(DESCRIPTION);
      SUMMARY=NORMALIZED(SUMMARY);
      if (ISEVENT) {
        // VEVENT
        // - combine attendee email address and common name into single string for vCalendar 1.0
        if (ITEMDATATYPE()=="vcalendar10") {
          i=0;
          while(i<SIZE(ATTENDEES)) {
            ATTENDEES[i] = MAKEEMAILSPEC(ATTENDEE_CNS[i], ATTENDEES[i]);
            i=i+1;
          }
          ORGANIZER = MAKEEMAILSPEC(ORGANIZER_CN, ORGANIZER);
        }
      }
      // make sure we have at least a summary
      if (SUMMARY==EMPTY) SUMMARY=SUBSTR(DESCRIPTION,0,32); // derive from description
      if (SUMMARY==EMPTY) SUMMARY="unnamed"; // in case description is empty as well
      // do NOT send duration (some servers crash when doing so)
      DURATION = UNASSIGNED;
      // shape alarm
      if (ALARM_TIME!=EMPTY) {
        if (ITEMDATATYPE()=="icalendar20") {
          if (ALARM_ACTION==EMPTY) ALARM_ACTION = "AUDIO";
          ALARM_TIME = CONVERTTOUSERZONE(ALARM_TIME,TRUE); // unfloat into user (system) zone, in case it is floating
          ALARM_TIME = CONVERTTOZONE(ALARM_TIME,"UTC"); // must always be UTC by iCalendar 2.0 specs
          // send as duration if we have non-empty non-date DTSTART
          if (DTSTART!=EMPTY && !ISDATEONLY(DTSTART)) {
            // make a duration (unfloat DTSTART into system zone in case it is floating first!)
            ALARM_TIME = ALARM_TIME-CONVERTTOZONE(CONVERTTOUSERZONE(DTSTART,TRUE),"UTC");
            ALARM_REL = 1; // relative to start
          }
        }
        else {
          if (ALARM_MSG==EMPTY) ALARM_MSG="alarm";
        }
      }
    ]]></macro>

  </scripting>


  <datatypes>

    <!-- list of internal fields representing vCard data -->
    <fieldlist name="contacts">
      <field name="REV" type="timestamp" compare="never" age="yes"/>

      <!-- Name elements -->
      <field name="N_LAST" type="string" compare="always"/>
      <field name="N_FIRST" type="string" compare="always"/>
      <field name="N_MIDDLE" type="string" compare="always"/>
      <field name="N_PREFIX" type="string" compare="conflict"/>
      <field name="N_SUFFIX" type="string" compare="conflict"/>
      <field name="NICKNAME" type="string" compare="conflict"/>
      <field name="TITLE" type="string" compare="conflict" merge="fillempty"/>

      <field name="FN" type="string" compare="conflict" merge="fillempty"/>

      <!-- categories -->
      <field name="CATEGORIES" array="yes" type="string" compare="conflict"/>

      <!-- organisation -->
      <field name="ORG_NAME" type="string" compare="slowsync" merge="fillempty"/>
      <field name="ORG_DIVISION" type="string" compare="conflict" merge="fillempty"/>

      <!-- birthday -->
      <field name="BDAY" type="date" compare="conflict" merge="fillempty"/>
      <field name="BDAY_TS" type="timestamp" compare="never"/>

      <!-- telephone numbers -->
      <field name="TEL"         array="yes" type="telephone" compare="conflict"/>
      <field name="TEL_FLAGS"   array="yes" type="integer"   compare="conflict"/> <!-- offset 0 -->
      <field name="TEL_LABEL"   array="yes" type="string"    compare="conflict"/> <!-- offset 1 -->
      <field name="TEL_ID"      array="yes" type="integer"   compare="conflict"/> <!-- offset 2 -->

      <!-- emails -->
      <field name="EMAIL"       array="yes" type="multiline" compare="conflict"/>
      <field name="EMAIL_FLAGS" array="yes" type="integer"   compare="conflict"/> <!-- offset 0 -->
      <field name="EMAIL_LABEL" array="yes" type="string"    compare="conflict"/> <!-- offset 1 -->
      <field name="EMAIL_ID"    array="yes" type="integer"   compare="conflict"/> <!-- offset 2 -->

      <!-- web addresses -->
      <field name="WEB"         array="yes" type="url" compare="conflict"/>
      <field name="WEB_FLAGS"   array="yes" type="integer"   compare="conflict"/> <!-- offset 0 -->
      <field name="WEB_LABEL"   array="yes" type="string"    compare="conflict"/> <!-- offset 1 -->
      <field name="WEB_ID"      array="yes" type="integer"   compare="conflict"/> <!-- offset 2 -->

      <!-- home address -->
      <field name="ADR_STREET"        array="yes" type="multiline" compare="conflict"/>
      <field name="ADR_ADDTL"         array="yes" type="multiline" compare="conflict"/> <!-- next after ADR_STREET for processing 2-line kABPersonAddressStreetKey -->
      <field name="ADR_STREET_FLAGS"  array="yes" type="integer"   compare="conflict"/> <!-- offset 0 (from ADR_STREET_FLAGS) -->
      <field name="ADR_STREET_LABEL"  array="yes" type="string"    compare="conflict"/> <!-- offset 1 -->
      <field name="ADR_STREET_ID"     array="yes" type="integer"   compare="conflict"/> <!-- offset 2 -->
      <field name="ADR_POBOX"         array="yes" type="multiline" compare="conflict"/>
      <field name="ADR_CITY"          array="yes" type="multiline" compare="conflict"/>
      <field name="ADR_REG"           array="yes" type="multiline" compare="conflict"/>
      <field name="ADR_ZIP"           array="yes" type="multiline" compare="conflict"/>
      <field name="ADR_COUNTRY"       array="yes" type="multiline" compare="conflict"/>

      <!-- Note -->
      <field name="NOTE" type="multiline" compare="conflict" merge="lines"/>

      <!-- Photo -->
      <field name="PHOTO" type="blob" compare="never" merge="fillempty"/>
      <field name="PHOTO_TYPE" type="integer" compare="never" merge="fillempty"/>

    </fieldlist>

    <!-- vCard profile -->
    <mimeprofile name="vcard" fieldlist="contacts">

      <profile name="VCARD" nummandatory="0"> <!-- we allow records without "N" as Address book can store them -->
        <property name="VERSION">
          <value conversion="version"/>
        </property>

        <property onlyformode="standard" name="PRODID" mandatory="no">
          <value conversion="prodid"/>
        </property>

        <property name="REV">
          <value field="REV"/>
        </property>

        <property name="N" values="5" mandatory="yes"> <!-- Note: makes N parse and generate even if not in remote's CTCap -->
          <value index="0" field="N_LAST"/>
          <value index="1" field="N_FIRST"/>
          <value index="2" field="N_MIDDLE"/>
          <value index="3" field="N_PREFIX"/>
          <value index="4" field="N_SUFFIX"/>
        </property>

        <property name="FN">
          <value field="FN"/>
        </property>

        <property name="NICKNAME" onlyformode="standard">
          <value field="NICKNAME"/>
        </property>

        <property name="TITLE">
          <value field="TITLE"/>
        </property>

        <property name="CATEGORIES" values="list" valueseparator="," altvalueseparator=";"> <!-- also accept vCalendar 1.0 style -->
          <value field="CATEGORIES"/>
          <position field="CATEGORIES" repeat="array" increment="1" minshow="0"/>
        </property>

        <property name="ORG" values="2">
          <value index="0" field="ORG_NAME"/>
          <value index="1" field="ORG_DIVISION"/>
        </property>

        <property name="TEL">
          <value field="TEL"/>
          <position field="TEL" repeat="array" increment="1" minshow="1"/>
          <parameter name="TYPE" default="yes" positional="no" show="yes">
            <value field="TEL_FLAGS" conversion="multimix" combine=",">
              <enum name="HOME"     value="B0"/>
              <enum name="WORK"     value="B1"/>
              <enum mode="ignore"   value="B2"/> <!-- OTHER -->
              <enum name="VOICE"    value="B3"/>
              <enum name="CELL"     value="B4"/>
              <enum name="FAX"      value="B5"/>
              <enum name="PAGER"    value="B6"/>
              <enum name="PREF"     value="B7"/>

              <enum mode="prefix" name="X-CustomLabel-" value="1.L"/>
              <enum mode="prefix" name="X-Synthesis-Ref" value="2.L"/>
            </value>
          </parameter>
        </property>

        <property name="EMAIL">
          <value field="EMAIL"/>
          <position field="EMAIL" repeat="array" increment="1" minshow="1"/>
          <parameter name="TYPE" default="yes" positional="no" show="yes">
            <value field="EMAIL_FLAGS" conversion="multimix" combine=",">
              <enum name="HOME"     value="B0"/>
              <enum name="WORK"     value="B1"/>
              <enum mode="ignore"   value="B2"/> <!-- OTHER -->
              <enum name="INTERNET" value="B3"/>

              <enum mode="prefix" name="X-CustomLabel-" value="1.L"/>
              <enum mode="prefix" name="X-Synthesis-Ref" value="2.L"/>
            </value>
          </parameter>
        </property>

        <property name="URL">
          <value field="WEB"/>
          <position field="WEB" repeat="array" increment="1" minshow="1"/>
          <parameter name="TYPE" default="yes" positional="no" show="yes">
            <value field="WEB_FLAGS" conversion="multimix" combine=",">
              <enum name="HOME"     value="B0"/>
              <enum name="WORK"     value="B1"/>
              <enum mode="ignore"   value="B2"/> <!-- OTHER -->
              <enum name="PREF"     value="B3"/>

              <enum mode="prefix" name="X-CustomLabel-" value="1.L"/>
              <enum mode="prefix" name="X-Synthesis-Ref" value="2.L"/>
            </value>
          </parameter>
        </property>

        <property name="ADR" values="7">
          <value index="0" field="ADR_POBOX"/>
          <value index="1" field="ADR_ADDTL"/>
          <value index="2" field="ADR_STREET"/>
          <value index="3" field="ADR_CITY"/>
          <value index="4" field="ADR_REG"/>
          <value index="5" field="ADR_ZIP"/>
          <value index="6" field="ADR_COUNTRY"/>
          <position field="ADR_POBOX" repeat="array" increment="1" minshow="1"/>
          <parameter name="TYPE" default="yes" positional="no" show="yes">
            <value field="ADR_STREET_FLAGS" conversion="multimix" combine=",">
              <enum name="HOME"     value="B0"/>
              <enum name="WORK"     value="B1"/>
              <enum mode="ignore"   value="B2"/> <!-- OTHER -->

              <enum mode="prefix" name="X-CustomLabel-" value="1.L"/>
              <enum mode="prefix" name="X-Synthesis-Ref" value="2.L"/>
            </value>
          </parameter>
        </property>

        <property name="BDAY">
          <value field="BDAY"/>
        </property>

        <property name="NOTE" filter="no">
          <value field="NOTE"/>
        </property>

        <property name="PHOTO" filter="no">
          <value field="PHOTO" conversion="BLOB_B64"/>
          <parameter name="TYPE" default="no" show="yes">
            <value field="PHOTO_TYPE">
              <enum name="JPEG" value="0"/>
            </value>
          </parameter>
        </property>

      </profile>
    </mimeprofile>

    <!-- vCard 2.1 datatype, using vCard profile defined above -->
    <datatype name="vcard21" basetype="vcard">
      <version>2.1</version>
      <use mimeprofile="vcard"/>

      <incomingscript><![CDATA[
        $VCARD_INCOMING_SCRIPT
      ]]></incomingscript>

      <outgoingscript><![CDATA[
        $VCARD_OUTGOING_SCRIPT
      ]]></outgoingscript>

    </datatype>

    <!-- vCard 3.0 datatype, using vCard profile defined above -->
    <datatype name="vcard30" basetype="vcard">
      <version>3.0</version>
      <use mimeprofile="vcard"/>

      <incomingscript><![CDATA[
        $VCARD_INCOMING_SCRIPT
      ]]></incomingscript>

      <outgoingscript><![CDATA[
        $VCARD_OUTGOING_SCRIPT
      ]]></outgoingscript>

    </datatype>


    <!-- calendar -->
    <fieldlist name="calendar">
      <field name="ISEVENT" type="integer" compare="always"/>

      <field name="DMODIFIED" type="timestamp" compare="never" age="yes"/>
      <field name="DCREATED" type="timestamp" compare="never"/>

      <field name="DGENERATED" type="timestamp" compare="never"/>

      <field name="UID" type="string" compare="never"/>

      <field name="CATEGORIES" array="yes" type="string" compare="conflict" merge="fillempty"/>
      <field name="CLASS" type="integer" compare="conflict" merge="fillempty"/>
      <field name="TRANSP" type="integer" compare="conflict" merge="fillempty"/>

      <field name="SUMMARY" type="multiline" compare="always"/>
      <field name="DESCRIPTION" type="multiline" compare="slowsync" merge="lines"/>
      <field name="LOCATION" type="multiline" compare="slowsync" merge="lines"/>

      <!-- recurrence rule block, fields must be in that order, including
           DTSTART as last field !! -->
      <field name="RR_FREQ" type="string" compare="conflict"/>
      <field name="RR_INTERVAL" type="integer" compare="conflict"/>
      <field name="RR_FMASK" type="integer" compare="conflict"/>
      <field name="RR_LMASK" type="integer" compare="conflict"/>
      <field name="RR_END" type="timestamp" compare="conflict"/>

      <!-- Note: DTSTART/DTEND are compared in the <comparescript>,
                 therefore compare is set no "never" here -->
      <field name="DTSTART" type="timestamp" compare="never"/>
      <field name="DTEND" type="timestamp" compare="never"/>
      <field name="DURATION" type="timestamp" compare="never"/>

      <field name="ALARM_TIME" type="timestamp" compare="conflict"/>
      <field name="ALARM_SNOOZE" type="string" compare="never"/>
      <field name="ALARM_REPEAT" type="string" compare="never"/>
      <field name="ALARM_MSG" type="string" compare="never"/>
      <field name="ALARM_SOUND" type="string" compare="never"/>
      <field name="ALARM_ACTION" type="string" compare="never"/>
      <field name="ALARM_REL" type="integer" compare="never"/>

      <!-- for events -->
      <field name="EXDATES" array="yes" type="timestamp" compare="never"/>

      <field name="ORIGSTART" array="no" type="timestamp" compare="never"/>
      <field name="SEQNO" array="no" type="integer" compare="never"/>

      <field name="ATTENDEES" array="yes" type="string" compare="never"/>
      <field name="ATTENDEE_CNS" array="yes" type="string" compare="never"/>
      <field name="ATTENDEE_PARTSTATS" array="yes" type="integer" compare="never"/>
      <field name="ORGANIZER" array="no" type="string" compare="never"/>
      <field name="ORGANIZER_CN" array="no" type="string" compare="never"/>

    </fieldlist>


    <!-- vCalendar with vTodo and vEvent for tasks and events -->
    <mimeprofile name="vcalendar" fieldlist="calendar">

      <unfloattimestamps>yes</unfloattimestamps>

      <vtimezonegenmode>current</vtimezonegenmode>
      <tzidgenmode>olson</tzidgenmode>

      <profile name="VCALENDAR" nummandatory="1">

        <property name="VERSION" mandatory="yes">
          <value conversion="version"/>
        </property>

        <property onlyformode="standard" name="PRODID" mandatory="no">
          <value conversion="prodid"/>
        </property>

        <property onlyformode="old" name="TZ" filter="false" suppressempty="yes">
          <value field="DTSTART" conversion="tz"/>
        </property>

        <property onlyformode="old" name="DAYLIGHT" mode="daylight" filter="false" suppressempty="yes">
          <value field="DTSTART" conversion="daylight"/>
        </property>

        <subprofile onlyformode="standard" name="VTIMEZONE" mode="vtimezones"/>


        <!-- sub-profile for event -->
        <subprofile name="VEVENT" nummandatory="1" showifselectedonly="yes" field="ISEVENT" value="1">

          <property name="LAST-MODIFIED">
            <value field="DMODIFIED"/>
          </property>

          <property name="DTSTAMP" suppressempty="yes" onlyformode="standard">
            <value field="DGENERATED"/>
          </property>

          <property name="DCREATED" suppressempty="yes" onlyformode="old">
            <value field="DCREATED"/>
          </property>
          <property name="CREATED" suppressempty="yes" onlyformode="standard">
            <value field="DCREATED"/>
          </property>

          <property name="UID" suppressempty="yes">
            <value field="UID"/>
          </property>

          <property name="SEQUENCE" suppressempty="yes">
            <value field="SEQNO"/>
          </property>

          <property ifndef="simple" onlyformode="standard" name="CATEGORIES" values="list" valueseparator="," suppressempty="yes">
            <value field="CATEGORIES" />
            <position field="CATEGORIES" repeat="array" minshow="0"/>
          </property>

          <property ifndef="simple" onlyformode="old" name="CATEGORIES" values="list" valueseparator=";" altvalueseparator="," suppressempty="yes">
            <value field="CATEGORIES" />
            <position field="CATEGORIES" repeat="array" minshow="0"/>
          </property>

          <property name="CLASS" suppressempty="yes">
            <value field="CLASS">
              <enum name="PUBLIC"       value="0"/>
              <enum name="PRIVATE"      value="1"/>
              <enum name="CONFIDENTIAL" value="2"/>
            </value>
          </property>


          <property name="TRANSP" suppressempty="yes" onlyformode="standard">
            <value field="TRANSP">
              <enum name="OPAQUE"       value="0"/>
              <enum name="TRANSPARENT"  value="1"/>
              <enum name="TENTATIVE"     value="2"/> <!-- according to Oracle de facto usage in vCalendar 1.0 -->
              <enum name="OUT_OF_OFFICE" value="3"/> <!-- according to Oracle de facto usage in vCalendar 1.0 -->
              <enum mode="defaultvalue" value="0"/>
            </value>
          </property>
          <property name="TRANSP" suppressempty="yes" onlyformode="old">
            <value field="TRANSP"/> <!-- directly numeric in vCalendar 1.0 -->
          </property>


          <property name="SUMMARY" mandatory="yes">
            <value field="SUMMARY"/>
          </property>

          <property name="DESCRIPTION" mandatory="yes">
            <value field="DESCRIPTION"/>
          </property>

          <property name="LOCATION" mandatory="no">
            <value field="LOCATION"/>
          </property>

          <property name="DTSTART" suppressempty="yes" delayedparsing="1">
            <value field="DTSTART" conversion="autodate"/>
            <parameter onlyformode="standard" name="TZID" default="no" show="yes">
              <value field="DTSTART" conversion="TZID"/>
            </parameter>
            <parameter onlyformode="standard" name="VALUE" default="no" show="yes">
              <value field="DTSTART" conversion="VALUETYPE"/>
            </parameter>
          </property>

          <!-- recurrence rule (with delayed parsing, as it is dependent on DTSTART) -->
          <property name="RRULE" suppressempty="yes" delayedparsing="2">
            <!-- Note: RR_FREQ is the beginning of a block of fields
                 suitable for the "rrule" conversion mode -->
            <value field="RR_FREQ" conversion="rrule"/>
          </property>

          <!-- Symbian uses this, so it might make the client work with symbian-prepared servers better -->
          <property name="X-RECURRENCE-ID" suppressempty="yes" onlyformode="old">
            <value field="ORIGSTART" conversion="autodate"/>
          </property>

          <property name="RECURRENCE-ID" suppressempty="yes" onlyformode="standard" delayedparsing="1">
            <value field="ORIGSTART" conversion="autodate"/>
            <parameter name="TZID" default="no" show="yes">
              <value field="ORIGSTART" conversion="TZID"/>
            </parameter>
            <parameter name="VALUE" default="no" show="yes">
              <value field="ORIGSTART" conversion="VALUETYPE"/>
            </parameter>
          </property>

          <property name="EXDATE" values="list" suppressempty="yes" onlyformode="standard" delayedparsing="1" valueseparator="," altvalueseparator=";">
            <value field="EXDATES"/>
            <position field="EXDATES" repeat="array" increment="1" minshow="0"/>
            <parameter name="TZID" default="no" show="yes">
              <value field="EXDATES" conversion="TZID"/>
            </parameter>
          </property>

          <property name="EXDATE" values="list" suppressempty="yes" onlyformode="old" foldbetween="yes" delayedparsing="1" valueseparator=";" altvalueseparator=",">
            <value field="EXDATES"/>
            <position field="EXDATES" repeat="array" increment="1" minshow="0"/>
          </property>


          <property name="DTEND" suppressempty="yes" delayedparsing="1">
            <value field="DTEND" conversion="autoenddate"/>
            <parameter onlyformode="standard" name="TZID" default="no" show="yes">
              <value field="DTEND" conversion="TZID"/>
            </parameter>
            <parameter onlyformode="standard" name="VALUE" default="no" show="yes">
              <value field="DTEND" conversion="VALUETYPE"/>
            </parameter>
          </property>

          <property name="DURATION" suppressempty="yes" delayedparsing="1" onlyformode="standard">
            <value field="DURATION"/>
            <parameter onlyformode="standard" name="VALUE" default="no" show="no">
              <value field="DURATION" conversion="VALUETYPE"/>
            </parameter>
          </property>

          <property name="ATTENDEE" suppressempty="yes" onlyformode="old">
            <value field="ATTENDEES"/>
            <parameter name="ROLE" default="no" positional="yes" show="yes">
              <value>
                <enum name="ORGANIZER"/>
              </value>
              <position has="ORGANIZER" field="ORGANIZER" overwriteempty="yes"/>
              <position hasnot="ORGANIZER" field="ATTENDEES" repeat="array" increment="1" overwriteempty="yes"/>
            </parameter>
            <parameter name="STATUS" default="no" show="yes">
              <value field="ATTENDEE_PARTSTATS">
                <enum name="NEEDS ACTION"   value="1"/>
                <enum mode="defaultvalue"   value="1"/>
                <enum name="ACCEPTED"       value="4"/>
                <enum name="DECLINED"       value="7"/>
                <enum name="TENTATIVE"      value="5"/>
                <enum name="DELEGATED"      value="6"/>
              </value>
            </parameter>
          </property>

          <property name="ATTENDEE" suppressempty="yes" onlyformode="standard">
            <value field="ATTENDEES" conversion="mailto"/>
            <position field="ATTENDEES" repeat="array" increment="1" minshow="0"/>
            <parameter name="CN" default="no" show="yes" shownonempty="yes">
              <value field="ATTENDEE_CNS"/>
            </parameter>
            <parameter name="PARTSTAT" default="no" show="yes">
              <value field="ATTENDEE_PARTSTATS">
                <enum name="NEEDS-ACTION"   value="1"/>
                <enum mode="defaultvalue"   value="1"/>
                <enum name="ACCEPTED"       value="4"/>
                <enum name="DECLINED"       value="7"/>
                <enum name="TENTATIVE"      value="5"/>
                <enum name="DELEGATED"      value="6"/>
              </value>
            </parameter>
          </property>

          <property name="ORGANIZER" suppressempty="yes" onlyformode="standard">
            <value field="ORGANIZER" conversion="mailto"/>
            <parameter name="CN" default="no" show="yes">
              <value field="ORGANIZER_CN"/>
            </parameter>
          </property>

          <!-- AALARM and DALARM both use mostly the same fields -->
          <property name="AALARM" onlyformode="old" values="4" suppressempty="yes">
            <value index="0" field="ALARM_TIME" conversion="emptyonly"/>
            <value index="1" field="ALARM_SNOOZE" conversion="emptyonly"/>
            <value index="2" field="ALARM_REPEAT" conversion="emptyonly"/>
            <value index="3" field="ALARM_SOUND" conversion="emptyonly"/>
          </property>
          <property name="DALARM" onlyformode="old" values="4" suppressempty="yes">
            <value index="0" field="ALARM_TIME" conversion="emptyonly"/>
            <value index="1" field="ALARM_SNOOZE" conversion="emptyonly"/>
            <value index="2" field="ALARM_REPEAT" conversion="emptyonly"/>
            <value index="3" field="ALARM_MSG" conversion="emptyonly"/>
          </property>

          <subprofile onlyformode="standard" name="VALARM" nummandatory="1" field="ALARM_TIME">
            <property name="TRIGGER" suppressempty="no" mandatory="yes">
              <value field="ALARM_TIME"/>
              <parameter name="VALUE" default="no" show="yes">
                <value field="ALARM_TIME" conversion="FULLVALUETYPE"/>
              </parameter>
              <parameter name="RELATED" default="no" show="yes">
                <value field="ALARM_REL">
                  <enum mode="ignore" value="0"/>
                  <enum name="START" value="1"/>
                  <enum name="END"   value="2"/>
                </value>
              </parameter>
            </property>
            <property name="ACTION" suppressempty="yes" mandatory="yes">
              <value field="ALARM_ACTION"/>
            </property>
            <property name="DESCRIPTION" suppressempty="yes">
              <value field="ALARM_MSG"/>
            </property>
            <property name="ATTACH" suppressempty="yes">
              <value field="ALARM_SOUND"/>
            </property>
            <property name="REPEAT" suppressempty="yes">
              <value field="ALARM_REPEAT"/>
            </property>
          </subprofile>


        </subprofile>

      </profile>
    </mimeprofile>


    <!-- vCalendar 1.0 datatype, using vCalendar profile defined
         above -->
    <datatype name="vcalendar10" basetype="vcalendar">
      <version>1.0</version>
      <use mimeprofile="vcalendar"/>

      <incomingscript><![CDATA[
        $VCAL_INCOMING_SCRIPT
      ]]></incomingscript>

      <outgoingscript><![CDATA[
        $VCAL_OUTGOING_SCRIPT
      ]]></outgoingscript>

    </datatype>


    <!-- iCalendar 2.0 datatype, using vCalendar profile defined
         above -->
    <datatype name="icalendar20" basetype="vcalendar">
      <version>2.0</version>
      <use mimeprofile="vcalendar"/>

      <incomingscript><![CDATA[
        $VCAL_INCOMING_SCRIPT
      ]]></incomingscript>

      <outgoingscript><![CDATA[
        $VCAL_OUTGOING_SCRIPT
      ]]></outgoingscript>

    </datatype>

  </datatypes>


  <client type="plugin">

    <binfilespath expand="yes">$(binfilespath)</binfilespath>

    <!-- IMPORTANT: Note that the following charset, lineend and quoting settings are relevant for session-level data access only.
         Most data access takes place in individual <datastores>, which each has the same three settings
         again locally (see below in the <datastore> sections). -->

    <!-- text db plugin is designed for UTF-8, make sure data is passed as UTF-8 (and not the ISO-8859-1 default) -->
    <datacharset>UTF-8</datacharset>
    <!-- text db plugin is designed for Unix linefeeds (\n, 0x0A), make data is passed with unix linefeeds (and not the DOS CRLF = 0x0D,0x0A default) -->
    <datalineends>unix</datalineends>

    <logenabled>no</logenabled> <!-- log disabled by default (session login scripts might disable it for special users/devices) -->

		<!-- If you want a binary log that can be queried using the /synclogs settings key, specify yes here -->
    <binfilelog>yes</binfilelog>


    <!-- If you want a text logfile (one line per sync/datastore), specify its full path here: -->
    <!--<logfile>$(logpath)/synclog.txt</logfile>-->

    <!-- the logfile format can be customized with <loglabels> and <logformat>
         but if these are not specified, a default format will be used
    -->
    <!-- This sample produces a simplified logfile:
    <loglabels>SyncEndTime\tUser\tStatus\tSynctype\tRemoteName\tDatabase\tLocAdded\tLocUpdated\tLocDeleted\n\n</loglabels>
    <logformat>%seT\t%U\t%sS\t%tS\t%nR\t%lD\t%laI\t%luI\t%ldI\n</logformat>
    -->


    <datastore name="text_contacts" type="plugin">

      <dbtypeid>2001</dbtypeid> <!-- This is the ID used to identify the datastore in progress events. Must be unique among all datastores -->
      <displayname>contacts textfile</displayname> <!-- this string can be queried using /profiles/<profileid>/targets/<dbtypeid>/dispName -->
      <dsavailflag>1</dsavailflag>  <!-- Used to remote provision availability and control settings: contacts = 1, events = 2, tasks = 4, memos = 8, emails = 16 -->

			<pseudochangedetection>yes</pseudochangedetection>

      <plugin_module>[SDK_textdb]</plugin_module> <!-- use TAB separated text files for storage -->
      <!-- plan44.ch client libary handles all admin data in it's own binary files, plugins don't need to care about admin data at all -->
      <plugin_datastoreadmin>no</plugin_datastoreadmin>

      <!-- Note: the plugin_params are specific to the plugin in use, and will not be accepted by all plugins.
           For example, the <datafilepath> parameter is specific to SDK_textdb. If you change this sample to
           use custom plugins, you might need to remove that parameter, otherwise the engine will report a
           config error -->
      <plugin_params>
        <datafilepath expand="yes">$(textfilespath)</datafilepath>
      </plugin_params>


      <alertprepscript><![CDATA[
        // pass on configured filter expressions
        setrecordfilter(targetsetting("remoteFilters"),false); // exclusive
      ]]></alertprepscript>

      <!-- use UTF8 with iOS/unix style linefeeds -->
      <datacharset>UTF-8</datacharset>
      <datalineends>unix</datalineends>

      <!-- Mapping of the fields to the fieldlist "contacts" -->
      <fieldmap fieldlist="contacts">
        <automap indexasname="false"/> <!-- use internal field list names -->
        <mapredefine name="NOTE" references="NOTE" type="string" mode="rw" size="24000"/>
      </fieldmap>

      <!-- datatypes supported by this datastore -->
      <typesupport>
        <use datatype="vcard30" mode="rw" preferred="yes"/>
        <use datatype="vcard21" mode="rw" preferred="legacy"/>
      </typesupport>

    </datastore>


    <datastore name="text_calendar" type="plugin">

      <dbtypeid>2002</dbtypeid> <!-- This is the ID used to identify the datastore in progress events. Must be unique among all datastores -->
      <displayname>calendar textfile</displayname>
      <dsavailflag>2</dsavailflag>  <!-- Used to remote provision availability and control settings: contacts = 1, events = 2, tasks = 4, memos = 8, emails = 16 -->

      <plugin_module>[SDK_textdb]</plugin_module>  <!-- use TAB separated text files for storage -->
      <!-- plan44.ch client libary handles all admin data in it's own binary files, plugins don't need to care about admin data at all -->
      <plugin_datastoreadmin>no</plugin_datastoreadmin>

      <plugin_params>
        <datafilepath expand="yes">$(textfilespath)</datafilepath>
      </plugin_params>


      <acceptfilter>F.ISEVENT:=1</acceptfilter>
      <silentdiscard>yes</silentdiscard>

      <alertprepscript><![CDATA[
        // pass on configured filter expressions
        setrecordfilter(targetsetting("remoteFilters"),false); // remote, exclusive
        // If a day range is selected and enabled in the settigs, apply it for the current sync
        if (targetsetting("extras") & 1 == 1) {
          setdaysrange(
            targetsetting("limit1"),
            targetsetting("limit2")
          );
        }
      ]]></alertprepscript>

      <!-- use UTF8 with iOS/unix style linefeeds -->
      <datacharset>UTF-8</datacharset>
      <datalineends>unix</datalineends>

      <!-- save times in UTC -->
      <datatimezone>UTC</datatimezone>

      <!-- if set to yes, all timestamps read from the DB are converted to user time zone (from DB time zone) before sending to remote -->
      <userzoneoutput>yes</userzoneoutput>

      <!-- Mapping of the fields to the fieldlist "contacts" -->
      <fieldmap fieldlist="calendar">

        <initscript><![CDATA[
          integer allday;
        ]]></initscript>

        <afterreadscript><![CDATA[
          // <userzoneoutput> makes it show in vCalendar as user time, only need to check allday
          if (allday) {
            // this is an allday event, make it dayonly
            MAKEALLDAY(DTSTART,DTEND);
          }
        ]]></afterreadscript>

        <beforewritescript><![CDATA[
          allday = FALSE;
          if (ISDATEONLY(DTSTART)) {
            allday = TRUE;
            DTSTART = CONVERTTOUSERZONE(DTSTART,TRUE); // unfloat
            DTEND = CONVERTTOUSERZONE(DTEND,TRUE); // unfloat
          }
        ]]></beforewritescript>


        <automap indexasname="false"/> <!-- use internal field list names -->
        <mapredefine name="DESCRIPTION" references="DESCRIPTION" type="string" mode="rw" size="24000"/>
        <map name="ALLDAY" references="allday" type="numeric" mode="rw"/>

      </fieldmap>

      <!-- datatypes supported by this datastore -->
      <typesupport>
        <use datatype="icalendar20" variant="VEVENT" mode="rw" preferred="yes"/>
        <use datatype="vcalendar10" variant="VEVENT" mode="rw" preferred="no"/>
      </typesupport>

    </datastore>

  </client>

</sysync_config>
