diff --git a/libs/ui/EventRecurrence.cpp b/libs/ui/EventRecurrence.cpp
new file mode 100644
index 0000000..b436b50
--- /dev/null
+++ b/libs/ui/EventRecurrence.cpp
@@ -0,0 +1,484 @@
+/*
+ *  Copyright 2006 The Android Open Source Project
+ */
+
+#include <pim/EventRecurrence.h>
+#include <utils/String8.h>
+#include <stdio.h>
+#include <limits.h>
+
+namespace android {
+
+#define FAIL_HERE() do { \
+            printf("Parsing failed at line %d\n", __LINE__); \
+            return UNKNOWN_ERROR; \
+        } while(0)
+
+EventRecurrence::EventRecurrence()
+    :freq((freq_t)0),
+     until(),
+     count(0),
+     interval(0),
+     bysecond(0),
+     bysecondCount(0),
+     byminute(0),
+     byminuteCount(0),
+     byhour(0),
+     byhourCount(0),
+     byday(0),
+     bydayNum(0),
+     bydayCount(0),
+     bymonthday(0),
+     bymonthdayCount(0),
+     byyearday(0),
+     byyeardayCount(0),
+     byweekno(0),
+     byweeknoCount(0),
+     bymonth(0),
+     bymonthCount(0),
+     bysetpos(0),
+     bysetposCount(0),
+     wkst(0)
+{
+}
+
+EventRecurrence::~EventRecurrence()
+{
+    delete[] bysecond;
+    delete[] byminute;
+    delete[] byhour;
+    delete[] byday;
+    delete[] bydayNum;
+    delete[] byyearday;
+    delete[] bymonthday;
+    delete[] byweekno;
+    delete[] bymonth;
+    delete[] bysetpos;
+}
+
+enum LHS {
+    NONE_LHS = 0,
+    FREQ,
+    UNTIL,
+    COUNT,
+    INTERVAL,
+    BYSECOND,
+    BYMINUTE,
+    BYHOUR,
+    BYDAY,
+    BYMONTHDAY,
+    BYYEARDAY,
+    BYWEEKNO,
+    BYMONTH,
+    BYSETPOS,
+    WKST
+};
+
+struct LHSProc
+{
+    const char16_t* text;
+    size_t textSize;
+    uint32_t value;
+};
+
+const char16_t FREQ_text[] = { 'F', 'R', 'E', 'Q' };
+const char16_t UNTIL_text[] = { 'U', 'N', 'T', 'I', 'L' };
+const char16_t COUNT_text[] = { 'C', 'O', 'U', 'N', 'T' };
+const char16_t INTERVAL_text[] = { 'I', 'N', 'T', 'E', 'R', 'V', 'A', 'L'};
+const char16_t BYSECOND_text[] = { 'B', 'Y', 'S', 'E', 'C', 'O', 'N', 'D' };
+const char16_t BYMINUTE_text[] = { 'B', 'Y', 'M', 'I', 'N', 'U', 'T', 'E' };
+const char16_t BYHOUR_text[] = { 'B', 'Y', 'H', 'O', 'U', 'R' };
+const char16_t BYDAY_text[] = { 'B', 'Y', 'D', 'A', 'Y' };
+const char16_t BYMONTHDAY_text[] = { 'B','Y','M','O','N','T','H','D','A','Y' };
+const char16_t BYYEARDAY_text[] = { 'B','Y','Y','E','A','R','D','A','Y' };
+const char16_t BYWEEKNO_text[] = { 'B', 'Y', 'W', 'E', 'E', 'K', 'N', 'O' };
+const char16_t BYMONTH_text[] = { 'B', 'Y', 'M', 'O', 'N', 'T', 'H' };
+const char16_t BYSETPOS_text[] = { 'B', 'Y', 'S', 'E', 'T', 'P', 'O', 'S' };
+const char16_t WKST_text[] = { 'W', 'K', 'S', 'T' };
+
+#define SIZ(x) (sizeof(x)/sizeof(x[0]))
+
+const LHSProc LHSPROC[] = {
+    { FREQ_text, SIZ(FREQ_text), FREQ },
+    { UNTIL_text, SIZ(UNTIL_text), UNTIL },
+    { COUNT_text, SIZ(COUNT_text), COUNT },
+    { INTERVAL_text, SIZ(INTERVAL_text), INTERVAL },
+    { BYSECOND_text, SIZ(BYSECOND_text), BYSECOND },
+    { BYMINUTE_text, SIZ(BYMINUTE_text), BYMINUTE },
+    { BYHOUR_text, SIZ(BYHOUR_text), BYHOUR },
+    { BYDAY_text, SIZ(BYDAY_text), BYDAY },
+    { BYMONTHDAY_text, SIZ(BYMONTHDAY_text), BYMONTHDAY },
+    { BYYEARDAY_text, SIZ(BYYEARDAY_text), BYYEARDAY },
+    { BYWEEKNO_text, SIZ(BYWEEKNO_text), BYWEEKNO },
+    { BYMONTH_text, SIZ(BYMONTH_text), BYMONTH },
+    { BYSETPOS_text, SIZ(BYSETPOS_text), BYSETPOS },
+    { WKST_text, SIZ(WKST_text), WKST },
+    { NULL, 0, NONE_LHS },
+};
+
+const char16_t SECONDLY_text[] = { 'S','E','C','O','N','D','L','Y' };
+const char16_t MINUTELY_text[] = { 'M','I','N','U','T','E','L','Y' };
+const char16_t HOURLY_text[] = { 'H','O','U','R','L','Y' };
+const char16_t DAILY_text[] = { 'D','A','I','L','Y' };
+const char16_t WEEKLY_text[] = { 'W','E','E','K','L','Y' };
+const char16_t MONTHLY_text[] = { 'M','O','N','T','H','L','Y' };
+const char16_t YEARLY_text[] = { 'Y','E','A','R','L','Y' };
+
+typedef LHSProc FreqProc;
+
+const FreqProc FREQPROC[] = {
+    { SECONDLY_text, SIZ(SECONDLY_text), EventRecurrence::SECONDLY },
+    { MINUTELY_text, SIZ(MINUTELY_text), EventRecurrence::MINUTELY },
+    { HOURLY_text, SIZ(HOURLY_text), EventRecurrence::HOURLY },
+    { DAILY_text, SIZ(DAILY_text), EventRecurrence::DAILY },
+    { WEEKLY_text, SIZ(WEEKLY_text), EventRecurrence::WEEKLY },
+    { MONTHLY_text, SIZ(MONTHLY_text), EventRecurrence::MONTHLY },
+    { YEARLY_text, SIZ(YEARLY_text), EventRecurrence::YEARLY },
+    { NULL, 0, NONE_LHS },
+};
+
+const char16_t SU_text[] = { 'S','U' };
+const char16_t MO_text[] = { 'M','O' };
+const char16_t TU_text[] = { 'T','U' };
+const char16_t WE_text[] = { 'W','E' };
+const char16_t TH_text[] = { 'T','H' };
+const char16_t FR_text[] = { 'F','R' };
+const char16_t SA_text[] = { 'S','A' };
+
+const FreqProc WEEKDAYPROC[] = {
+    { SU_text, SIZ(SU_text), EventRecurrence::SU },
+    { MO_text, SIZ(MO_text), EventRecurrence::MO },
+    { TU_text, SIZ(TU_text), EventRecurrence::TU },
+    { WE_text, SIZ(WE_text), EventRecurrence::WE },
+    { TH_text, SIZ(TH_text), EventRecurrence::TH },
+    { FR_text, SIZ(FR_text), EventRecurrence::FR },
+    { SA_text, SIZ(SA_text), EventRecurrence::SA },
+    { NULL, 0, NONE_LHS },
+};
+
+// returns the index into LHSPROC for the match or -1 if not found
+inline static int
+match_proc(const LHSProc* p, const char16_t* str, size_t len)
+{
+    int i = 0;
+    while (p->text != NULL) {
+        if (p->textSize == len) {
+            if (0 == memcmp(p->text, str, len*sizeof(char16_t))) {
+                return i;
+            }
+        }
+        p++;
+        i++;
+    }
+    return -1;
+}
+
+// rangeMin and rangeMax are inclusive
+static status_t
+parse_int(const char16_t* str, size_t len, int* out,
+            int rangeMin, int rangeMax, bool zeroOK)
+{
+    char16_t c;
+    size_t i=0;
+
+    if (len == 0) {
+        FAIL_HERE();
+    }
+    bool negative = false;
+    c = str[0];
+    if (c == '-' ) {
+        negative = true;
+        i++;
+    }
+    else if (c == '+') {
+        i++;
+    }
+    int n = 0;
+    for (; i<len; i++) {
+        c = str[i];
+        if (c < '0' || c > '9') {
+            FAIL_HERE();
+        }
+        int prev = n;
+        n *= 10;
+        // the spec doesn't address how big these numbers can be,
+        // so we're not going to worry about not being able to represent
+        // INT_MIN, and if we're going to wrap, we'll just clamp to
+        // INT_MAX instead
+        if (n < prev) {
+            n = INT_MAX;
+        } else {
+            n += c - '0';
+        }
+    }
+    if (negative) {
+        n = -n;
+    }
+    if (n < rangeMin || n > rangeMax) {
+        FAIL_HERE();
+    }
+    if (!zeroOK && n == 0) {
+        FAIL_HERE();
+    }
+    *out = n;
+    return NO_ERROR;
+}
+
+static status_t
+parse_int_list(const char16_t* str, size_t len, int* countOut, int** listOut,
+          int rangeMin, int rangeMax, bool zeroOK,
+          status_t (*func)(const char16_t*,size_t,int*,int,int,bool)=parse_int)
+{
+    status_t err;
+
+    if (len == 0) {
+        *countOut = 0;
+        *listOut = NULL;
+        return NO_ERROR;
+    }
+
+    // make one pass through looking for commas so we know how big to make our
+    // out array.
+    int count = 1;
+    for (size_t i=0; i<len; i++) {
+        if (str[i] == ',') {
+            count++;
+        }
+    }
+
+    int* list = new int[count];
+    const char16_t* p = str;
+    int commaIndex = 0;
+    size_t i;
+
+    for (i=0; i<len; i++) {
+        if (str[i] == ',') {
+            err = func(p, (str+i-p), list+commaIndex, rangeMin,
+                    rangeMax, zeroOK);
+            if (err != NO_ERROR) {
+                goto bail;
+            }
+            commaIndex++;
+            p = str+i+1;
+        }
+    }
+
+    err = func(p, (str+i-p), list+commaIndex, rangeMin, rangeMax, zeroOK);
+    if (err != NO_ERROR) {
+        goto bail;
+    }
+    commaIndex++;
+
+    *countOut = count;
+    *listOut = list;
+
+    return NO_ERROR;
+
+bail:
+    delete[] list;
+    FAIL_HERE();
+}
+
+// the numbers here are small, so we pack them both into one value, and then
+// split it out later.  it lets us reuse all the comma separated list code.
+static status_t
+parse_byday(const char16_t* s, size_t len, int* out,
+            int rangeMin, int rangeMax, bool zeroOK)
+{
+    status_t err;
+    int n = 0;
+    const char16_t* p = s;
+    size_t plen = len;
+
+    if (len > 0) {
+        char16_t c = s[0];
+        if (c == '-' || c == '+' || (c >= '0' && c <= '9')) {
+            if (len > 1) {
+                size_t nlen = 0;
+                c = s[nlen];
+                while (nlen < len
+                        && (c == '-' || c == '+' || (c >= '0' && c <= '9'))) {
+                    c = s[nlen];
+                    nlen++;
+                }
+                if (nlen > 0) {
+                    nlen--;
+                    err = parse_int(s, nlen, &n, rangeMin, rangeMax, zeroOK);
+                    if (err != NO_ERROR) {
+                        FAIL_HERE();
+                    }
+                    p += nlen;
+                    plen -= nlen;
+                }
+            }
+        }
+
+        int index = match_proc(WEEKDAYPROC, p, plen);
+        if (index >= 0) {
+            *out = (0xffff0000 & WEEKDAYPROC[index].value)
+                    | (0x0000ffff & n);
+            return NO_ERROR;
+        }
+    }
+    return UNKNOWN_ERROR;
+}
+
+static void
+postprocess_byday(int count, int* byday, int** bydayNum)
+{
+    int* bdn = new int[count];
+    *bydayNum = bdn;
+    for (int i=0; i<count; i++) {
+        uint32_t v = byday[i];
+        int16_t num = v & 0x0000ffff;
+        byday[i] = v & 0xffff0000;  
+        // will sign extend:
+        bdn[i] = num;
+    }
+}
+
+#define PARSE_INT_LIST_CHECKED(name, rangeMin, rangeMax, zeroOK) \
+    if (name##Count != 0 || NO_ERROR != parse_int_list(s, slen, \
+                         &name##Count, &name, rangeMin, rangeMax, zeroOK)) { \
+        FAIL_HERE(); \
+    }
+status_t
+EventRecurrence::parse(const String16& str)
+{
+    char16_t const* work = str.string();
+    size_t len = str.size();
+
+    int lhsIndex = NONE_LHS;
+    int index;
+    
+    size_t start = 0;
+    for (size_t i=0; i<len; i++) {
+        char16_t c = work[i];
+        if (c != ';' && i == len-1) {
+            c = ';';
+            i++;
+        }
+        if (c == ';' || c == '=') {
+            if (i != start) {
+                const char16_t* s = work+start;
+                const size_t slen = i-start;
+
+                String8 thestring(String16(s, slen));
+
+                switch (c)
+                {
+                    case '=':
+                        if (lhsIndex == NONE_LHS) {
+                            lhsIndex = match_proc(LHSPROC, s, slen);
+                            if (lhsIndex >= 0) {
+                                break;
+                            }
+                        }
+                        FAIL_HERE();
+                    case ';':
+                    {
+                        switch (LHSPROC[lhsIndex].value)
+                        {
+                            case FREQ:
+                                if (this->freq != 0) {
+                                    FAIL_HERE();
+                                }
+                                index = match_proc(FREQPROC, s, slen);
+                                if (index >= 0) {
+                                    this->freq = (freq_t)FREQPROC[index].value;
+                                }
+                                break;
+                            case UNTIL:
+                                // XXX should check that this is a valid time
+                                until.setTo(String16(s, slen));
+                                break;
+                            case COUNT:
+                                if (count != 0
+                                     || NO_ERROR != parse_int(s, slen,
+                                             &count, INT_MIN, INT_MAX, true)) {
+                                    FAIL_HERE();
+                                }
+                                break;
+                            case INTERVAL:
+                                if (interval != 0
+                                     || NO_ERROR != parse_int(s, slen,
+                                         &interval, INT_MIN, INT_MAX, false)) {
+                                    FAIL_HERE();
+                                }
+                                break;
+                            case BYSECOND:
+                                PARSE_INT_LIST_CHECKED(bysecond, 0, 59, true)
+                                break;
+                            case BYMINUTE:
+                                PARSE_INT_LIST_CHECKED(byminute, 0, 59, true)
+                                break;
+                            case BYHOUR:
+                                PARSE_INT_LIST_CHECKED(byhour, 0, 23, true)
+                                break;
+                            case BYDAY:
+                                if (bydayCount != 0 || NO_ERROR != 
+                                        parse_int_list(s, slen, &bydayCount,
+                                              &byday, -53, 53, false,
+                                              parse_byday)) {
+                                    FAIL_HERE();
+                                }
+                                postprocess_byday(bydayCount, byday, &bydayNum);
+                                break;
+                            case BYMONTHDAY:
+                                PARSE_INT_LIST_CHECKED(bymonthday, -31, 31,
+                                                        false)
+                                break;
+                            case BYYEARDAY:
+                                PARSE_INT_LIST_CHECKED(byyearday, -366, 366,
+                                                        false)
+                                break;
+                            case BYWEEKNO:
+                                PARSE_INT_LIST_CHECKED(byweekno, -53, 53,
+                                                        false)
+                                break;
+                            case BYMONTH:
+                                PARSE_INT_LIST_CHECKED(bymonth, 1, 12, false)
+                                break;
+                            case BYSETPOS:
+                                PARSE_INT_LIST_CHECKED(bysetpos,
+                                                        INT_MIN, INT_MAX, true)
+                                break;
+                            case WKST:
+                                if (this->wkst != 0) {
+                                    FAIL_HERE();
+                                }
+                                index = match_proc(WEEKDAYPROC, s, slen);
+                                if (index >= 0) {
+                                    this->wkst = (int)WEEKDAYPROC[index].value;
+                                }
+                                break;
+                            default:
+                                FAIL_HERE();
+                        }
+                        lhsIndex = NONE_LHS;
+                        break;
+                    }
+                }
+
+                start = i+1;
+            }
+        }
+    }
+
+    // enforce that there was a FREQ
+    if (freq == 0) {
+        FAIL_HERE();
+    }
+
+    // default wkst to MO if it wasn't specified
+    if (wkst == 0) {
+        wkst = MO;
+    }
+
+    return NO_ERROR;
+}
+
+
+}; // namespace android
+
+
