- s:^X-MS-CARDPICTURE:PHOTO:p;
- s:^X-GENDER:GENDER:p;
- s:^X-ANNIVERSARY:ANNIVERSARY:p;
- s:^X-EVOLUTION-ANNIVERSARY:ANNIVERSARY:p;
- s:^X-KADDRESSBOOK-X-Anniversary:ANNIVERSARY:p;
- s:^X-AIM(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:aim\:\2:p;
- s:^X-ICQ(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:aim\:\2:p;
- s:^X-GOOGLE-TALK(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:xmpp\:\2:p;
- s:^X-JABBER(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:xmpp\:\2:p;
- s:^X-MSN(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:msn\:\2:p;
- s:^X-YAHOO(;[^"\:]+|;"[^"]+")*\:(.*)$:IMPP\1\:ymsgr\:\2:p;
- s:^X-SIP(;[^"\:]+|;"[^"]+")*\:(sip\:)?(.*)$:IMPP\1\:sip\:\3:p;
- s:^LABEL(;[^"\:]+|;"[^"]+")*\:(.*)$:ADR;LABEL="\2"\1\::p;
- s:^X-EVOLUTION-BLOG-URL:URL:p;
-
- s:^AGENT:RELATED\;TYPE=agent:p;
- s:^X-ASSISTANT:RELATED\;TYPE=assistant;VALUE=text:p;
- s:^X-EVOLUTION-ASSISTANT:RELATED\;TYPE=assistant;VALUE=text:p;
- s:^X-KADDRESSBOOK-X-AssistantsName:RELATED\;TYPE=assistant;VALUE=text:p;
- s:^X-MANAGER:RELATED\;TYPE=manager;VALUE=text:p;
- s:^X-EVOLUTION-MANAGER:RELATED\;TYPE=manager;VALUE=text:p;
- s:^X-KADDRESSBOOK-X-ManagersName:RELATED\;TYPE=manager;VALUE=text:p;
- s:^X-SPOUSE:RELATED\;TYPE=spouse;VALUE=text:p;
- s:^X-EVOLUTION-SPOUSE:RELATED\;TYPE=spouse;VALUE=text:p;
- s:^X-KADDRESSBOOK-X-SpouseName:RELATED\;TYPE=spouse;VALUE=text:p;
-
- s:^([A-Z].*)$:\1:p;
+ # === turn property names to upper case, strip group names ===
+ h; s;^([^;:]+);;;
+ x; s;^([^;:\.]+\.)?([^;:]+).*$;\2;;
+ y;abcdefghijklmnopqrstuvwxyz;ABCDEFGHIJKLMNOPQRSTUVWXYZ;
+ G; s;\n;;;
+
+ # === strip trailing CR (but keep CRs in property value) ===
+ s;\r$;;;
+
+ # === Normalise various known vendor properties ===
+ s;^X-MS-CARDPICTURE(\;|:);PHOTO\1;;
+ s;^X-GENDER(\;|:);GENDER\1;;
+ s;^X-ANNIVERSARY(\;|:);ANNIVERSARY\1;;
+ s;^X-EVOLUTION-ANNIVERSARY(\;|:);ANNIVERSARY\1;;
+ s;^X-KADDRESSBOOK-X-ANNIVERSARY(\;|:);ANNIVERSARY\1;;
+ s;^X-EVOLUTION-BLOG-URL(\;|:);URL\1;;
+ s;^AGENT(\;|:);RELATED\;VALUE=text\;TYPE=agent\1;;
+ s;^X-ASSISTANT(\;|:);RELATED\;VALUE=text\;TYPE=assistant\1;;
+ s;^X-EVOLUTION-ASSISTANT(\;|:);RELATED\;VALUE=text\;TYPE=assistant\1;;
+ s;^X-KADDRESSBOOK-X-ASSISTANTSNAME(\;|:);RELATED\;VALUE=text\;TYPE=assistant\1;;
+ s;^X-MANAGER(\;|:);RELATED\;VALUE=text\;TYPE=manager\1;;
+ s;^X-EVOLUTION-MANAGER(\;|:);RELATED\;VALUE=text\;TYPE=manager\1;;
+ s;^X-KADDRESSBOOK-X-MANAGERSNAME(\;|:);RELATED\;VALUE=text\;TYPE=manager\1;;
+ s;^X-SPOUSE(\;|:);RELATED\;VALUE=text\;TYPE=spouse\1;;
+ s;^X-EVOLUTION-SPOUSE(\;|:);RELATED\;VALUE=text\;TYPE=spouse\1;;
+ s;^X-KADDRESSBOOK-X-SPOUSENAME(\;|:);RELATED\;VALUE=text\;TYPE=spouse\1;;
+
+ # === Normalise obsolete vendor IM properties ===
+ s;^X-AIM((\;[A-z0-9-]+|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:aim:;;
+ s;^X-ICQ((\;[A-z0-9-]+|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:aim:;;
+ s;^X-GOOGLE-TALK((\;[A-z0-9-]+|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:xmpp:;;
+ s;^X-JABBER((\;[A-z0-9-]+|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:xmpp:;;
+ s;^X-MSN((\;[A-z0-9-]+|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:msn:;;
+ s;^X-YAHOO((\;[A-z0-9-]+|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):;IMPP\1:ymsgr:;;
+ s;^X-SIP((\;[A-z0-9-]+|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(sip:)?;IMPP\1:sip:;;
+
+ # === Update obsolete LABEL property ===
+ s;^LABEL((\;[A-z0-9-]+|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(.*)$;ADR\1\;LABEL="\5":;;
+
+ /^([A-Z0-9-]+)((\;[A-z0-9-]+=?|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(.*)$/{
+ h;
+ s;^([A-Z0-9-]+)((\;[A-z0-9-]+=?|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):(.*)$;key='\''\1'\'';;
+ H; g;
+
+ s;^([A-Z0-9-]+)((\;[A-z0-9-]+=?|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):([^\n]*)\n.*$;\2;;
+ s;'\'';'\'\\\\\'\'';g
+ s;\;([A-Z0-9-]+)(=|=(([^\;,:"]+|"[^"]+")(,[^\;,:"]+|,"[^"]+")*))?;\ntag[\1]='\''\3'\'';g
+ s;^\n+;;; s;\n+$;;;
+ /^.+$/H; g;
+
+ s;^([A-Z0-9-]+)((\;[A-z0-9-]+=?|\;[A-z0-9-]+=([^;,:"]+|"[^"]+")(,[^;,:"]+|,"[^"]+")*)*):([^\n]*)\n.*$;\6;;
+ # :X s;((^|[^\\])(\\\\)*)[;,];\1\n;g; s;((^|[^\\])(\\\\)*)\\([;,]);\4;g; tX;
+ s;'\'';'\'\\\\\'\'';g
+ s;^.*$;value='\''&'\'';
+ H; g;
+
+ s;^[^\n]*[\n ]+;;
+ s;\n+$;;;
+
+ p;
+ }