]> granicus.if.org Git - ejabberd/commitdiff
Re-generate XMPP codec, decrease tests verbosity
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>
Mon, 17 Jun 2013 18:04:32 +0000 (04:04 +1000)
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>
Mon, 17 Jun 2013 18:05:01 +0000 (04:05 +1000)
Makefile.in
tools/xmpp_codec.erl
tools/xmpp_codec.hrl
tools/xmpp_codec.spec

index df8c4071a463ed8902e5615b5b9538506149e5d4..d69580220b7cf2d8e63726074fa3d45247380e33 100644 (file)
@@ -251,7 +251,7 @@ dialyzer: plt
        --get_warnings -o dialyzer.log ebin
 
 test:
-       $(REBAR) -v skip_deps=true ct
+       $(REBAR) skip_deps=true ct
 
 .PHONY: src doc edoc dialyzer Makefile TAGS clean clean-rel distclean rel plt \
        install uninstall uninstall-binary uninstall-all translations deps test spec
index cb113643a1c76b3dd827bc381cdfc404f97e1ff4..0e239491d1ab7819d1fbca9ecfe9b5518f2bc76f 100644 (file)
@@ -123,8 +123,6 @@ decode({xmlel, _name, _attrs, _} = _el) ->
       {<<"required">>, <<"jabber:x:data">>} ->
          decode_xdata_field_required(_el);
       {<<"vCard">>, <<"vcard-temp">>} -> decode_vcard(_el);
-      {<<"AGENT">>, <<"vcard-temp">>} ->
-         decode_vcard_AGENT(_el);
       {<<"CLASS">>, <<"vcard-temp">>} ->
          decode_vcard_CLASS(_el);
       {<<"CATEGORIES">>, <<"vcard-temp">>} ->
@@ -762,12 +760,9 @@ encode({xdata_field, _, _, _, _, _, _, _} = Field) ->
     encode_xdata_field(Field,
                       [{<<"xmlns">>, <<"jabber:x:data">>}]);
 encode({vcard, _, _, _, _, _, _, _, _, _, _, _, _, _, _,
-       _, _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} =
+       _, _, _, _, _, _, _, _, _, _, _, _, _, _, _} =
           Vcard) ->
     encode_vcard(Vcard, [{<<"xmlns">>, <<"vcard-temp">>}]);
-encode({vcard_agent, _, _} = Agent) ->
-    encode_vcard_AGENT(Agent,
-                      [{<<"xmlns">>, <<"vcard-temp">>}]);
 encode({vcard_key, _, _} = Key) ->
     encode_vcard_KEY(Key,
                     [{<<"xmlns">>, <<"vcard-temp">>}]);
@@ -1076,12 +1071,11 @@ pp(vcard_photo, 3) -> [type, binval, extval];
 pp(vcard_org, 2) -> [name, units];
 pp(vcard_sound, 3) -> [phonetic, binval, extval];
 pp(vcard_key, 2) -> [type, cred];
-pp(vcard_agent, 2) -> [vcard, extval];
-pp(vcard, 30) ->
+pp(vcard, 29) ->
     [version, fn, n, nickname, photo, bday, adr, label, tel,
      email, jabberid, mailer, tz, geo, title, role, logo,
-     org, categories, note, prodid, agent, rev, sort_string,
-     sound, uid, url, class, key, desc];
+     org, categories, note, prodid, rev, sort_string, sound,
+     uid, url, class, key, desc];
 pp(xdata_field, 7) ->
     [label, type, var, required, desc, values, options];
 pp(xdata, 6) ->
@@ -1154,6412 +1148,5970 @@ dec_tzo(Val) ->
     M = erlang:binary_to_integer(M1),
     if H >= -12, H =< 12, M >= 0, M < 60 -> {H, M} end.
 
-decode_last({xmlel, <<"query">>, _attrs, _els}) ->
-    Text = decode_last_els(_els, <<>>),
-    Seconds = decode_last_attrs(_attrs, undefined),
-    {last, Seconds, Text}.
+decode_muc({xmlel, <<"x">>, _attrs, _els}) ->
+    History = decode_muc_els(_els, undefined),
+    Password = decode_muc_attrs(_attrs, undefined),
+    {muc, History, Password}.
 
-decode_last_els([], Text) -> decode_last_cdata(Text);
-decode_last_els([{xmlcdata, _data} | _els], Text) ->
-    decode_last_els(_els, <<Text/binary, _data/binary>>);
-decode_last_els([_ | _els], Text) ->
-    decode_last_els(_els, Text).
+decode_muc_els([], History) -> History;
+decode_muc_els([{xmlel, <<"history">>, _attrs, _} = _el
+               | _els],
+              History) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc">> ->
+          decode_muc_els(_els, decode_muc_history(_el));
+       true -> decode_muc_els(_els, History)
+    end;
+decode_muc_els([_ | _els], History) ->
+    decode_muc_els(_els, History).
 
-decode_last_attrs([{<<"seconds">>, _val} | _attrs],
-                 _Seconds) ->
-    decode_last_attrs(_attrs, _val);
-decode_last_attrs([_ | _attrs], Seconds) ->
-    decode_last_attrs(_attrs, Seconds);
-decode_last_attrs([], Seconds) ->
-    decode_last_attr_seconds(Seconds).
+decode_muc_attrs([{<<"password">>, _val} | _attrs],
+                _Password) ->
+    decode_muc_attrs(_attrs, _val);
+decode_muc_attrs([_ | _attrs], Password) ->
+    decode_muc_attrs(_attrs, Password);
+decode_muc_attrs([], Password) ->
+    decode_muc_attr_password(Password).
 
-encode_last({last, Seconds, Text}, _xmlns_attrs) ->
-    _els = encode_last_cdata(Text, []),
-    _attrs = encode_last_attr_seconds(Seconds,
+encode_muc({muc, History, Password}, _xmlns_attrs) ->
+    _els = 'encode_muc_$history'(History, []),
+    _attrs = encode_muc_attr_password(Password,
                                      _xmlns_attrs),
-    {xmlel, <<"query">>, _attrs, _els}.
-
-decode_last_attr_seconds(undefined) -> undefined;
-decode_last_attr_seconds(_val) ->
-    case catch xml_gen:dec_int(_val, 0, infinity) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"seconds">>,
-                       <<"query">>, <<"jabber:iq:last">>});
-      _res -> _res
-    end.
+    {xmlel, <<"x">>, _attrs, _els}.
 
-encode_last_attr_seconds(undefined, _acc) -> _acc;
-encode_last_attr_seconds(_val, _acc) ->
-    [{<<"seconds">>, xml_gen:enc_int(_val)} | _acc].
+'encode_muc_$history'(undefined, _acc) -> _acc;
+'encode_muc_$history'(History, _acc) ->
+    [encode_muc_history(History, []) | _acc].
 
-decode_last_cdata(<<>>) -> undefined;
-decode_last_cdata(_val) -> _val.
+decode_muc_attr_password(undefined) -> undefined;
+decode_muc_attr_password(_val) -> _val.
 
-encode_last_cdata(undefined, _acc) -> _acc;
-encode_last_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_muc_attr_password(undefined, _acc) -> _acc;
+encode_muc_attr_password(_val, _acc) ->
+    [{<<"password">>, _val} | _acc].
 
-decode_version_name({xmlel, <<"name">>, _attrs,
-                    _els}) ->
-    Cdata = decode_version_name_els(_els, <<>>), Cdata.
+decode_muc_owner({xmlel, <<"query">>, _attrs, _els}) ->
+    {Config, Destroy} = decode_muc_owner_els(_els,
+                                            undefined, undefined),
+    {muc_owner, Destroy, Config}.
 
-decode_version_name_els([], Cdata) ->
-    decode_version_name_cdata(Cdata);
-decode_version_name_els([{xmlcdata, _data} | _els],
-                       Cdata) ->
-    decode_version_name_els(_els,
-                           <<Cdata/binary, _data/binary>>);
-decode_version_name_els([_ | _els], Cdata) ->
-    decode_version_name_els(_els, Cdata).
+decode_muc_owner_els([], Config, Destroy) ->
+    {Config, Destroy};
+decode_muc_owner_els([{xmlel, <<"destroy">>, _attrs,
+                      _} =
+                         _el
+                     | _els],
+                    Config, Destroy) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#owner">> ->
+          decode_muc_owner_els(_els, Config,
+                               decode_muc_owner_destroy(_el));
+       true -> decode_muc_owner_els(_els, Config, Destroy)
+    end;
+decode_muc_owner_els([{xmlel, <<"x">>, _attrs, _} = _el
+                     | _els],
+                    Config, Destroy) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<"jabber:x:data">> ->
+          decode_muc_owner_els(_els, decode_xdata(_el), Destroy);
+       true -> decode_muc_owner_els(_els, Config, Destroy)
+    end;
+decode_muc_owner_els([_ | _els], Config, Destroy) ->
+    decode_muc_owner_els(_els, Config, Destroy).
 
-encode_version_name(Cdata, _xmlns_attrs) ->
-    _els = encode_version_name_cdata(Cdata, []),
+encode_muc_owner({muc_owner, Destroy, Config},
+                _xmlns_attrs) ->
+    _els = 'encode_muc_owner_$destroy'(Destroy,
+                                      'encode_muc_owner_$config'(Config, [])),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"name">>, _attrs, _els}.
-
-decode_version_name_cdata(<<>>) ->
-    erlang:error({missing_cdata, <<>>, <<"name">>,
-                 <<"jabber:iq:version">>});
-decode_version_name_cdata(_val) -> _val.
+    {xmlel, <<"query">>, _attrs, _els}.
 
-encode_version_name_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_muc_owner_$config'(undefined, _acc) -> _acc;
+'encode_muc_owner_$config'(Config, _acc) ->
+    [encode_xdata(Config,
+                 [{<<"xmlns">>, <<"jabber:x:data">>}])
+     | _acc].
 
-decode_version_ver({xmlel, <<"version">>, _attrs,
-                   _els}) ->
-    Cdata = decode_version_ver_els(_els, <<>>), Cdata.
+'encode_muc_owner_$destroy'(undefined, _acc) -> _acc;
+'encode_muc_owner_$destroy'(Destroy, _acc) ->
+    [encode_muc_owner_destroy(Destroy, []) | _acc].
 
-decode_version_ver_els([], Cdata) ->
-    decode_version_ver_cdata(Cdata);
-decode_version_ver_els([{xmlcdata, _data} | _els],
-                      Cdata) ->
-    decode_version_ver_els(_els,
-                          <<Cdata/binary, _data/binary>>);
-decode_version_ver_els([_ | _els], Cdata) ->
-    decode_version_ver_els(_els, Cdata).
+decode_muc_owner_destroy({xmlel, <<"destroy">>, _attrs,
+                         _els}) ->
+    {Password, Reason} = decode_muc_owner_destroy_els(_els,
+                                                     undefined, undefined),
+    Jid = decode_muc_owner_destroy_attrs(_attrs, undefined),
+    {muc_owner_destroy, Jid, Reason, Password}.
 
-encode_version_ver(Cdata, _xmlns_attrs) ->
-    _els = encode_version_ver_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"version">>, _attrs, _els}.
+decode_muc_owner_destroy_els([], Password, Reason) ->
+    {Password, Reason};
+decode_muc_owner_destroy_els([{xmlel, <<"password">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Password, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#owner">> ->
+          decode_muc_owner_destroy_els(_els,
+                                       decode_muc_owner_password(_el), Reason);
+       true ->
+          decode_muc_owner_destroy_els(_els, Password, Reason)
+    end;
+decode_muc_owner_destroy_els([{xmlel, <<"reason">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Password, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#owner">> ->
+          decode_muc_owner_destroy_els(_els, Password,
+                                       decode_muc_owner_reason(_el));
+       true ->
+          decode_muc_owner_destroy_els(_els, Password, Reason)
+    end;
+decode_muc_owner_destroy_els([_ | _els], Password,
+                            Reason) ->
+    decode_muc_owner_destroy_els(_els, Password, Reason).
 
-decode_version_ver_cdata(<<>>) ->
-    erlang:error({missing_cdata, <<>>, <<"version">>,
-                 <<"jabber:iq:version">>});
-decode_version_ver_cdata(_val) -> _val.
+decode_muc_owner_destroy_attrs([{<<"jid">>, _val}
+                               | _attrs],
+                              _Jid) ->
+    decode_muc_owner_destroy_attrs(_attrs, _val);
+decode_muc_owner_destroy_attrs([_ | _attrs], Jid) ->
+    decode_muc_owner_destroy_attrs(_attrs, Jid);
+decode_muc_owner_destroy_attrs([], Jid) ->
+    decode_muc_owner_destroy_attr_jid(Jid).
 
-encode_version_ver_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_muc_owner_destroy({muc_owner_destroy, Jid,
+                         Reason, Password},
+                        _xmlns_attrs) ->
+    _els = 'encode_muc_owner_destroy_$reason'(Reason,
+                                             'encode_muc_owner_destroy_$password'(Password,
+                                                                                  [])),
+    _attrs = encode_muc_owner_destroy_attr_jid(Jid,
+                                              _xmlns_attrs),
+    {xmlel, <<"destroy">>, _attrs, _els}.
 
-decode_version_os({xmlel, <<"os">>, _attrs, _els}) ->
-    Cdata = decode_version_os_els(_els, <<>>), Cdata.
+'encode_muc_owner_destroy_$password'(undefined, _acc) ->
+    _acc;
+'encode_muc_owner_destroy_$password'(Password, _acc) ->
+    [encode_muc_owner_password(Password, []) | _acc].
 
-decode_version_os_els([], Cdata) ->
-    decode_version_os_cdata(Cdata);
-decode_version_os_els([{xmlcdata, _data} | _els],
-                     Cdata) ->
-    decode_version_os_els(_els,
-                         <<Cdata/binary, _data/binary>>);
-decode_version_os_els([_ | _els], Cdata) ->
-    decode_version_os_els(_els, Cdata).
+'encode_muc_owner_destroy_$reason'(undefined, _acc) ->
+    _acc;
+'encode_muc_owner_destroy_$reason'(Reason, _acc) ->
+    [encode_muc_owner_reason(Reason, []) | _acc].
 
-encode_version_os(Cdata, _xmlns_attrs) ->
-    _els = encode_version_os_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"os">>, _attrs, _els}.
+decode_muc_owner_destroy_attr_jid(undefined) ->
+    undefined;
+decode_muc_owner_destroy_attr_jid(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"jid">>, <<"destroy">>,
+                       <<"http://jabber.org/protocol/muc#owner">>});
+      _res -> _res
+    end.
 
-decode_version_os_cdata(<<>>) ->
-    erlang:error({missing_cdata, <<>>, <<"os">>,
-                 <<"jabber:iq:version">>});
-decode_version_os_cdata(_val) -> _val.
+encode_muc_owner_destroy_attr_jid(undefined, _acc) ->
+    _acc;
+encode_muc_owner_destroy_attr_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
 
-encode_version_os_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_muc_owner_reason({xmlel, <<"reason">>, _attrs,
+                        _els}) ->
+    Cdata = decode_muc_owner_reason_els(_els, <<>>), Cdata.
 
-decode_version({xmlel, <<"query">>, _attrs, _els}) ->
-    {Version_ver, Version_os, Version_name} =
-       decode_version_els(_els, undefined, undefined,
-                          undefined),
-    {version, Version_name, Version_ver, Version_os}.
+decode_muc_owner_reason_els([], Cdata) ->
+    decode_muc_owner_reason_cdata(Cdata);
+decode_muc_owner_reason_els([{xmlcdata, _data} | _els],
+                           Cdata) ->
+    decode_muc_owner_reason_els(_els,
+                               <<Cdata/binary, _data/binary>>);
+decode_muc_owner_reason_els([_ | _els], Cdata) ->
+    decode_muc_owner_reason_els(_els, Cdata).
 
-decode_version_els([], Version_ver, Version_os,
-                  Version_name) ->
-    {Version_ver, Version_os, Version_name};
-decode_version_els([{xmlel, <<"name">>, _attrs, _} = _el
-                   | _els],
-                  Version_ver, Version_os, Version_name) ->
+encode_muc_owner_reason(Cdata, _xmlns_attrs) ->
+    _els = encode_muc_owner_reason_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"reason">>, _attrs, _els}.
+
+decode_muc_owner_reason_cdata(<<>>) -> undefined;
+decode_muc_owner_reason_cdata(_val) -> _val.
+
+encode_muc_owner_reason_cdata(undefined, _acc) -> _acc;
+encode_muc_owner_reason_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_muc_owner_password({xmlel, <<"password">>,
+                          _attrs, _els}) ->
+    Cdata = decode_muc_owner_password_els(_els, <<>>),
+    Cdata.
+
+decode_muc_owner_password_els([], Cdata) ->
+    decode_muc_owner_password_cdata(Cdata);
+decode_muc_owner_password_els([{xmlcdata, _data}
+                              | _els],
+                             Cdata) ->
+    decode_muc_owner_password_els(_els,
+                                 <<Cdata/binary, _data/binary>>);
+decode_muc_owner_password_els([_ | _els], Cdata) ->
+    decode_muc_owner_password_els(_els, Cdata).
+
+encode_muc_owner_password(Cdata, _xmlns_attrs) ->
+    _els = encode_muc_owner_password_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"password">>, _attrs, _els}.
+
+decode_muc_owner_password_cdata(<<>>) -> undefined;
+decode_muc_owner_password_cdata(_val) -> _val.
+
+encode_muc_owner_password_cdata(undefined, _acc) ->
+    _acc;
+encode_muc_owner_password_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_muc_user({xmlel, <<"x">>, _attrs, _els}) ->
+    {Status_codes, Items, Invites, Decline, Destroy} =
+       decode_muc_user_els(_els, [], [], [], undefined,
+                           undefined),
+    Password = decode_muc_user_attrs(_attrs, undefined),
+    {muc_user, Decline, Destroy, Invites, Items,
+     Status_codes, Password}.
+
+decode_muc_user_els([], Status_codes, Items, Invites,
+                   Decline, Destroy) ->
+    {lists:reverse(Status_codes), lists:reverse(Items),
+     lists:reverse(Invites), Decline, Destroy};
+decode_muc_user_els([{xmlel, <<"decline">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Status_codes, Items, Invites, Decline, Destroy) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:version">> ->
-          decode_version_els(_els, Version_ver, Version_os,
-                             decode_version_name(_el));
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
+          decode_muc_user_els(_els, Status_codes, Items, Invites,
+                              decode_muc_user_decline(_el), Destroy);
        true ->
-          decode_version_els(_els, Version_ver, Version_os,
-                             Version_name)
+          decode_muc_user_els(_els, Status_codes, Items, Invites,
+                              Decline, Destroy)
     end;
-decode_version_els([{xmlel, <<"version">>, _attrs, _} =
-                       _el
-                   | _els],
-                  Version_ver, Version_os, Version_name) ->
+decode_muc_user_els([{xmlel, <<"destroy">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Status_codes, Items, Invites, Decline, Destroy) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:version">> ->
-          decode_version_els(_els, decode_version_ver(_el),
-                             Version_os, Version_name);
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
+          decode_muc_user_els(_els, Status_codes, Items, Invites,
+                              Decline, decode_muc_user_destroy(_el));
        true ->
-          decode_version_els(_els, Version_ver, Version_os,
-                             Version_name)
+          decode_muc_user_els(_els, Status_codes, Items, Invites,
+                              Decline, Destroy)
     end;
-decode_version_els([{xmlel, <<"os">>, _attrs, _} = _el
-                   | _els],
-                  Version_ver, Version_os, Version_name) ->
+decode_muc_user_els([{xmlel, <<"invite">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Status_codes, Items, Invites, Decline, Destroy) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:version">> ->
-          decode_version_els(_els, Version_ver,
-                             decode_version_os(_el), Version_name);
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
+          decode_muc_user_els(_els, Status_codes, Items,
+                              case decode_muc_user_invite(_el) of
+                                undefined -> Invites;
+                                _new_el -> [_new_el | Invites]
+                              end,
+                              Decline, Destroy);
        true ->
-          decode_version_els(_els, Version_ver, Version_os,
-                             Version_name)
+          decode_muc_user_els(_els, Status_codes, Items, Invites,
+                              Decline, Destroy)
     end;
-decode_version_els([_ | _els], Version_ver, Version_os,
-                  Version_name) ->
-    decode_version_els(_els, Version_ver, Version_os,
-                      Version_name).
+decode_muc_user_els([{xmlel, <<"item">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Status_codes, Items, Invites, Decline, Destroy) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
+          decode_muc_user_els(_els, Status_codes,
+                              case decode_muc_user_item(_el) of
+                                undefined -> Items;
+                                _new_el -> [_new_el | Items]
+                              end,
+                              Invites, Decline, Destroy);
+       true ->
+          decode_muc_user_els(_els, Status_codes, Items, Invites,
+                              Decline, Destroy)
+    end;
+decode_muc_user_els([{xmlel, <<"status">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Status_codes, Items, Invites, Decline, Destroy) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
+          decode_muc_user_els(_els,
+                              case decode_muc_user_status(_el) of
+                                undefined -> Status_codes;
+                                _new_el -> [_new_el | Status_codes]
+                              end,
+                              Items, Invites, Decline, Destroy);
+       true ->
+          decode_muc_user_els(_els, Status_codes, Items, Invites,
+                              Decline, Destroy)
+    end;
+decode_muc_user_els([_ | _els], Status_codes, Items,
+                   Invites, Decline, Destroy) ->
+    decode_muc_user_els(_els, Status_codes, Items, Invites,
+                       Decline, Destroy).
 
-encode_version({version, Version_name, Version_ver,
-               Version_os},
-              _xmlns_attrs) ->
-    _els = 'encode_version_$version_name'(Version_name,
-                                         'encode_version_$version_os'(Version_os,
-                                                                      'encode_version_$version_ver'(Version_ver,
-                                                                                                    []))),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"query">>, _attrs, _els}.
+decode_muc_user_attrs([{<<"password">>, _val} | _attrs],
+                     _Password) ->
+    decode_muc_user_attrs(_attrs, _val);
+decode_muc_user_attrs([_ | _attrs], Password) ->
+    decode_muc_user_attrs(_attrs, Password);
+decode_muc_user_attrs([], Password) ->
+    decode_muc_user_attr_password(Password).
 
-'encode_version_$version_ver'(undefined, _acc) -> _acc;
-'encode_version_$version_ver'(Version_ver, _acc) ->
-    [encode_version_ver(Version_ver, []) | _acc].
+encode_muc_user({muc_user, Decline, Destroy, Invites,
+                Items, Status_codes, Password},
+               _xmlns_attrs) ->
+    _els = 'encode_muc_user_$destroy'(Destroy,
+                                     'encode_muc_user_$decline'(Decline,
+                                                                'encode_muc_user_$invites'(Invites,
+                                                                                           'encode_muc_user_$items'(Items,
+                                                                                                                    'encode_muc_user_$status_codes'(Status_codes,
+                                                                                                                                                    []))))),
+    _attrs = encode_muc_user_attr_password(Password,
+                                          _xmlns_attrs),
+    {xmlel, <<"x">>, _attrs, _els}.
 
-'encode_version_$version_os'(undefined, _acc) -> _acc;
-'encode_version_$version_os'(Version_os, _acc) ->
-    [encode_version_os(Version_os, []) | _acc].
+'encode_muc_user_$status_codes'([], _acc) -> _acc;
+'encode_muc_user_$status_codes'([Status_codes | _els],
+                               _acc) ->
+    'encode_muc_user_$status_codes'(_els,
+                                   [encode_muc_user_status(Status_codes, [])
+                                    | _acc]).
 
-'encode_version_$version_name'(undefined, _acc) -> _acc;
-'encode_version_$version_name'(Version_name, _acc) ->
-    [encode_version_name(Version_name, []) | _acc].
+'encode_muc_user_$items'([], _acc) -> _acc;
+'encode_muc_user_$items'([Items | _els], _acc) ->
+    'encode_muc_user_$items'(_els,
+                            [encode_muc_user_item(Items, []) | _acc]).
 
-decode_roster_group({xmlel, <<"group">>, _attrs,
-                    _els}) ->
-    Cdata = decode_roster_group_els(_els, <<>>), Cdata.
+'encode_muc_user_$invites'([], _acc) -> _acc;
+'encode_muc_user_$invites'([Invites | _els], _acc) ->
+    'encode_muc_user_$invites'(_els,
+                              [encode_muc_user_invite(Invites, []) | _acc]).
 
-decode_roster_group_els([], Cdata) ->
-    decode_roster_group_cdata(Cdata);
-decode_roster_group_els([{xmlcdata, _data} | _els],
-                       Cdata) ->
-    decode_roster_group_els(_els,
-                           <<Cdata/binary, _data/binary>>);
-decode_roster_group_els([_ | _els], Cdata) ->
-    decode_roster_group_els(_els, Cdata).
+'encode_muc_user_$decline'(undefined, _acc) -> _acc;
+'encode_muc_user_$decline'(Decline, _acc) ->
+    [encode_muc_user_decline(Decline, []) | _acc].
 
-encode_roster_group(Cdata, _xmlns_attrs) ->
-    _els = encode_roster_group_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"group">>, _attrs, _els}.
+'encode_muc_user_$destroy'(undefined, _acc) -> _acc;
+'encode_muc_user_$destroy'(Destroy, _acc) ->
+    [encode_muc_user_destroy(Destroy, []) | _acc].
 
-decode_roster_group_cdata(<<>>) ->
-    erlang:error({missing_cdata, <<>>, <<"group">>,
-                 <<"jabber:iq:roster">>});
-decode_roster_group_cdata(_val) -> _val.
+decode_muc_user_attr_password(undefined) -> undefined;
+decode_muc_user_attr_password(_val) -> _val.
 
-encode_roster_group_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_muc_user_attr_password(undefined, _acc) -> _acc;
+encode_muc_user_attr_password(_val, _acc) ->
+    [{<<"password">>, _val} | _acc].
 
-decode_roster_item({xmlel, <<"item">>, _attrs, _els}) ->
-    Groups = decode_roster_item_els(_els, []),
-    {Jid, Name, Subscription, Ask} =
-       decode_roster_item_attrs(_attrs, undefined, undefined,
-                                undefined, undefined),
-    {roster_item, Jid, Name, Groups, Subscription, Ask}.
+decode_muc_user_item({xmlel, <<"item">>, _attrs,
+                     _els}) ->
+    {Actor, Continue, Reason} =
+       decode_muc_user_item_els(_els, undefined, undefined,
+                                undefined),
+    {Affiliation, Role, Jid, Nick} =
+       decode_muc_user_item_attrs(_attrs, undefined, undefined,
+                                  undefined, undefined),
+    {muc_item, Actor, Continue, Reason, Affiliation, Role,
+     Jid, Nick}.
 
-decode_roster_item_els([], Groups) ->
-    lists:reverse(Groups);
-decode_roster_item_els([{xmlel, <<"group">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Groups) ->
+decode_muc_user_item_els([], Actor, Continue, Reason) ->
+    {Actor, Continue, Reason};
+decode_muc_user_item_els([{xmlel, <<"actor">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Actor, Continue, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:roster">> ->
-          decode_roster_item_els(_els,
-                                 case decode_roster_group(_el) of
-                                   undefined -> Groups;
-                                   _new_el -> [_new_el | Groups]
-                                 end);
-       true -> decode_roster_item_els(_els, Groups)
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
+          decode_muc_user_item_els(_els,
+                                   decode_muc_user_actor(_el), Continue,
+                                   Reason);
+       true ->
+          decode_muc_user_item_els(_els, Actor, Continue, Reason)
     end;
-decode_roster_item_els([_ | _els], Groups) ->
-    decode_roster_item_els(_els, Groups).
+decode_muc_user_item_els([{xmlel, <<"continue">>,
+                          _attrs, _} =
+                             _el
+                         | _els],
+                        Actor, Continue, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
+          decode_muc_user_item_els(_els, Actor,
+                                   decode_muc_user_continue(_el), Reason);
+       true ->
+          decode_muc_user_item_els(_els, Actor, Continue, Reason)
+    end;
+decode_muc_user_item_els([{xmlel, <<"reason">>, _attrs,
+                          _} =
+                             _el
+                         | _els],
+                        Actor, Continue, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
+          decode_muc_user_item_els(_els, Actor, Continue,
+                                   decode_muc_user_reason(_el));
+       true ->
+          decode_muc_user_item_els(_els, Actor, Continue, Reason)
+    end;
+decode_muc_user_item_els([_ | _els], Actor, Continue,
+                        Reason) ->
+    decode_muc_user_item_els(_els, Actor, Continue, Reason).
 
-decode_roster_item_attrs([{<<"jid">>, _val} | _attrs],
-                        _Jid, Name, Subscription, Ask) ->
-    decode_roster_item_attrs(_attrs, _val, Name,
-                            Subscription, Ask);
-decode_roster_item_attrs([{<<"name">>, _val} | _attrs],
-                        Jid, _Name, Subscription, Ask) ->
-    decode_roster_item_attrs(_attrs, Jid, _val,
-                            Subscription, Ask);
-decode_roster_item_attrs([{<<"subscription">>, _val}
-                         | _attrs],
-                        Jid, Name, _Subscription, Ask) ->
-    decode_roster_item_attrs(_attrs, Jid, Name, _val, Ask);
-decode_roster_item_attrs([{<<"ask">>, _val} | _attrs],
-                        Jid, Name, Subscription, _Ask) ->
-    decode_roster_item_attrs(_attrs, Jid, Name,
-                            Subscription, _val);
-decode_roster_item_attrs([_ | _attrs], Jid, Name,
-                        Subscription, Ask) ->
-    decode_roster_item_attrs(_attrs, Jid, Name,
-                            Subscription, Ask);
-decode_roster_item_attrs([], Jid, Name, Subscription,
-                        Ask) ->
-    {decode_roster_item_attr_jid(Jid),
-     decode_roster_item_attr_name(Name),
-     decode_roster_item_attr_subscription(Subscription),
-     decode_roster_item_attr_ask(Ask)}.
+decode_muc_user_item_attrs([{<<"affiliation">>, _val}
+                           | _attrs],
+                          _Affiliation, Role, Jid, Nick) ->
+    decode_muc_user_item_attrs(_attrs, _val, Role, Jid,
+                              Nick);
+decode_muc_user_item_attrs([{<<"role">>, _val}
+                           | _attrs],
+                          Affiliation, _Role, Jid, Nick) ->
+    decode_muc_user_item_attrs(_attrs, Affiliation, _val,
+                              Jid, Nick);
+decode_muc_user_item_attrs([{<<"jid">>, _val} | _attrs],
+                          Affiliation, Role, _Jid, Nick) ->
+    decode_muc_user_item_attrs(_attrs, Affiliation, Role,
+                              _val, Nick);
+decode_muc_user_item_attrs([{<<"nick">>, _val}
+                           | _attrs],
+                          Affiliation, Role, Jid, _Nick) ->
+    decode_muc_user_item_attrs(_attrs, Affiliation, Role,
+                              Jid, _val);
+decode_muc_user_item_attrs([_ | _attrs], Affiliation,
+                          Role, Jid, Nick) ->
+    decode_muc_user_item_attrs(_attrs, Affiliation, Role,
+                              Jid, Nick);
+decode_muc_user_item_attrs([], Affiliation, Role, Jid,
+                          Nick) ->
+    {decode_muc_user_item_attr_affiliation(Affiliation),
+     decode_muc_user_item_attr_role(Role),
+     decode_muc_user_item_attr_jid(Jid),
+     decode_muc_user_item_attr_nick(Nick)}.
 
-encode_roster_item({roster_item, Jid, Name, Groups,
-                   Subscription, Ask},
-                  _xmlns_attrs) ->
-    _els = 'encode_roster_item_$groups'(Groups, []),
-    _attrs = encode_roster_item_attr_ask(Ask,
-                                        encode_roster_item_attr_subscription(Subscription,
-                                                                             encode_roster_item_attr_name(Name,
-                                                                                                          encode_roster_item_attr_jid(Jid,
-                                                                                                                                      _xmlns_attrs)))),
+encode_muc_user_item({muc_item, Actor, Continue, Reason,
+                     Affiliation, Role, Jid, Nick},
+                    _xmlns_attrs) ->
+    _els = 'encode_muc_user_item_$reason'(Reason,
+                                         'encode_muc_user_item_$continue'(Continue,
+                                                                          'encode_muc_user_item_$actor'(Actor,
+                                                                                                        []))),
+    _attrs = encode_muc_user_item_attr_nick(Nick,
+                                           encode_muc_user_item_attr_jid(Jid,
+                                                                         encode_muc_user_item_attr_role(Role,
+                                                                                                        encode_muc_user_item_attr_affiliation(Affiliation,
+                                                                                                                                              _xmlns_attrs)))),
     {xmlel, <<"item">>, _attrs, _els}.
 
-'encode_roster_item_$groups'([], _acc) -> _acc;
-'encode_roster_item_$groups'([Groups | _els], _acc) ->
-    'encode_roster_item_$groups'(_els,
-                                [encode_roster_group(Groups, []) | _acc]).
+'encode_muc_user_item_$actor'(undefined, _acc) -> _acc;
+'encode_muc_user_item_$actor'(Actor, _acc) ->
+    [encode_muc_user_actor(Actor, []) | _acc].
 
-decode_roster_item_attr_jid(undefined) ->
-    erlang:error({missing_attr, <<"jid">>, <<"item">>,
-                 <<"jabber:iq:roster">>});
-decode_roster_item_attr_jid(_val) ->
-    case catch dec_jid(_val) of
+'encode_muc_user_item_$continue'(undefined, _acc) ->
+    _acc;
+'encode_muc_user_item_$continue'(Continue, _acc) ->
+    [encode_muc_user_continue(Continue, []) | _acc].
+
+'encode_muc_user_item_$reason'(undefined, _acc) -> _acc;
+'encode_muc_user_item_$reason'(Reason, _acc) ->
+    [encode_muc_user_reason(Reason, []) | _acc].
+
+decode_muc_user_item_attr_affiliation(undefined) ->
+    undefined;
+decode_muc_user_item_attr_affiliation(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [admin, member, none, outcast, owner])
+       of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"jid">>, <<"item">>,
-                       <<"jabber:iq:roster">>});
+         erlang:error({bad_attr_value, <<"affiliation">>,
+                       <<"item">>, <<"http://jabber.org/protocol/muc#user">>});
       _res -> _res
     end.
 
-encode_roster_item_attr_jid(_val, _acc) ->
-    [{<<"jid">>, enc_jid(_val)} | _acc].
-
-decode_roster_item_attr_name(undefined) -> undefined;
-decode_roster_item_attr_name(_val) -> _val.
-
-encode_roster_item_attr_name(undefined, _acc) -> _acc;
-encode_roster_item_attr_name(_val, _acc) ->
-    [{<<"name">>, _val} | _acc].
+encode_muc_user_item_attr_affiliation(undefined,
+                                     _acc) ->
+    _acc;
+encode_muc_user_item_attr_affiliation(_val, _acc) ->
+    [{<<"affiliation">>, xml_gen:enc_enum(_val)} | _acc].
 
-decode_roster_item_attr_subscription(undefined) -> none;
-decode_roster_item_attr_subscription(_val) ->
+decode_muc_user_item_attr_role(undefined) -> undefined;
+decode_muc_user_item_attr_role(_val) ->
     case catch xml_gen:dec_enum(_val,
-                               [none, to, from, both, remove])
+                               [moderator, none, participant, visitor])
        of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"subscription">>,
-                       <<"item">>, <<"jabber:iq:roster">>});
+         erlang:error({bad_attr_value, <<"role">>, <<"item">>,
+                       <<"http://jabber.org/protocol/muc#user">>});
       _res -> _res
     end.
 
-encode_roster_item_attr_subscription(none, _acc) ->
-    _acc;
-encode_roster_item_attr_subscription(_val, _acc) ->
-    [{<<"subscription">>, xml_gen:enc_enum(_val)} | _acc].
+encode_muc_user_item_attr_role(undefined, _acc) -> _acc;
+encode_muc_user_item_attr_role(_val, _acc) ->
+    [{<<"role">>, xml_gen:enc_enum(_val)} | _acc].
 
-decode_roster_item_attr_ask(undefined) -> undefined;
-decode_roster_item_attr_ask(_val) ->
-    case catch xml_gen:dec_enum(_val, [subscribe]) of
+decode_muc_user_item_attr_jid(undefined) -> undefined;
+decode_muc_user_item_attr_jid(_val) ->
+    case catch dec_jid(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"ask">>, <<"item">>,
-                       <<"jabber:iq:roster">>});
+         erlang:error({bad_attr_value, <<"jid">>, <<"item">>,
+                       <<"http://jabber.org/protocol/muc#user">>});
       _res -> _res
     end.
 
-encode_roster_item_attr_ask(undefined, _acc) -> _acc;
-encode_roster_item_attr_ask(_val, _acc) ->
-    [{<<"ask">>, xml_gen:enc_enum(_val)} | _acc].
-
-decode_roster({xmlel, <<"query">>, _attrs, _els}) ->
-    Items = decode_roster_els(_els, []),
-    Ver = decode_roster_attrs(_attrs, undefined),
-    {roster, Items, Ver}.
+encode_muc_user_item_attr_jid(undefined, _acc) -> _acc;
+encode_muc_user_item_attr_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
 
-decode_roster_els([], Items) -> lists:reverse(Items);
-decode_roster_els([{xmlel, <<"item">>, _attrs, _} = _el
-                  | _els],
-                 Items) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:roster">> ->
-          decode_roster_els(_els,
-                            case decode_roster_item(_el) of
-                              undefined -> Items;
-                              _new_el -> [_new_el | Items]
-                            end);
-       true -> decode_roster_els(_els, Items)
-    end;
-decode_roster_els([_ | _els], Items) ->
-    decode_roster_els(_els, Items).
+decode_muc_user_item_attr_nick(undefined) -> undefined;
+decode_muc_user_item_attr_nick(_val) -> _val.
 
-decode_roster_attrs([{<<"ver">>, _val} | _attrs],
-                   _Ver) ->
-    decode_roster_attrs(_attrs, _val);
-decode_roster_attrs([_ | _attrs], Ver) ->
-    decode_roster_attrs(_attrs, Ver);
-decode_roster_attrs([], Ver) ->
-    decode_roster_attr_ver(Ver).
+encode_muc_user_item_attr_nick(undefined, _acc) -> _acc;
+encode_muc_user_item_attr_nick(_val, _acc) ->
+    [{<<"nick">>, _val} | _acc].
 
-encode_roster({roster, Items, Ver}, _xmlns_attrs) ->
-    _els = 'encode_roster_$items'(Items, []),
-    _attrs = encode_roster_attr_ver(Ver, _xmlns_attrs),
-    {xmlel, <<"query">>, _attrs, _els}.
-
-'encode_roster_$items'([], _acc) -> _acc;
-'encode_roster_$items'([Items | _els], _acc) ->
-    'encode_roster_$items'(_els,
-                          [encode_roster_item(Items, []) | _acc]).
-
-decode_roster_attr_ver(undefined) -> undefined;
-decode_roster_attr_ver(_val) -> _val.
-
-encode_roster_attr_ver(undefined, _acc) -> _acc;
-encode_roster_attr_ver(_val, _acc) ->
-    [{<<"ver">>, _val} | _acc].
-
-decode_privacy_message({xmlel, <<"message">>, _attrs,
+decode_muc_user_status({xmlel, <<"status">>, _attrs,
                        _els}) ->
-    message.
-
-encode_privacy_message(message, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"message">>, _attrs, _els}.
+    Code = decode_muc_user_status_attrs(_attrs, undefined),
+    Code.
 
-decode_privacy_iq({xmlel, <<"iq">>, _attrs, _els}) ->
-    iq.
+decode_muc_user_status_attrs([{<<"code">>, _val}
+                             | _attrs],
+                            _Code) ->
+    decode_muc_user_status_attrs(_attrs, _val);
+decode_muc_user_status_attrs([_ | _attrs], Code) ->
+    decode_muc_user_status_attrs(_attrs, Code);
+decode_muc_user_status_attrs([], Code) ->
+    decode_muc_user_status_attr_code(Code).
 
-encode_privacy_iq(iq, _xmlns_attrs) ->
+encode_muc_user_status(Code, _xmlns_attrs) ->
     _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"iq">>, _attrs, _els}.
+    _attrs = encode_muc_user_status_attr_code(Code,
+                                             _xmlns_attrs),
+    {xmlel, <<"status">>, _attrs, _els}.
 
-decode_privacy_presence_in({xmlel, <<"presence-in">>,
-                           _attrs, _els}) ->
-    'presence-in'.
+decode_muc_user_status_attr_code(undefined) ->
+    undefined;
+decode_muc_user_status_attr_code(_val) ->
+    case catch xml_gen:dec_int(_val, 100, 999) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"code">>, <<"status">>,
+                       <<"http://jabber.org/protocol/muc#user">>});
+      _res -> _res
+    end.
 
-encode_privacy_presence_in('presence-in',
-                          _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"presence-in">>, _attrs, _els}.
+encode_muc_user_status_attr_code(undefined, _acc) ->
+    _acc;
+encode_muc_user_status_attr_code(_val, _acc) ->
+    [{<<"code">>, xml_gen:enc_int(_val)} | _acc].
 
-decode_privacy_presence_out({xmlel, <<"presence-out">>,
-                            _attrs, _els}) ->
-    'presence-out'.
+decode_muc_user_continue({xmlel, <<"continue">>, _attrs,
+                         _els}) ->
+    Thread = decode_muc_user_continue_attrs(_attrs,
+                                           undefined),
+    Thread.
 
-encode_privacy_presence_out('presence-out',
-                           _xmlns_attrs) ->
+decode_muc_user_continue_attrs([{<<"thread">>, _val}
+                               | _attrs],
+                              _Thread) ->
+    decode_muc_user_continue_attrs(_attrs, _val);
+decode_muc_user_continue_attrs([_ | _attrs], Thread) ->
+    decode_muc_user_continue_attrs(_attrs, Thread);
+decode_muc_user_continue_attrs([], Thread) ->
+    decode_muc_user_continue_attr_thread(Thread).
+
+encode_muc_user_continue(Thread, _xmlns_attrs) ->
     _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"presence-out">>, _attrs, _els}.
+    _attrs = encode_muc_user_continue_attr_thread(Thread,
+                                                 _xmlns_attrs),
+    {xmlel, <<"continue">>, _attrs, _els}.
 
-decode_privacy_item({xmlel, <<"item">>, _attrs,
-                    _els}) ->
-    Kinds = decode_privacy_item_els(_els, []),
-    {Action, Order, Type, Value} =
-       decode_privacy_item_attrs(_attrs, undefined, undefined,
-                                 undefined, undefined),
-    {privacy_item, Order, Action, Type, Value, Kinds}.
+decode_muc_user_continue_attr_thread(undefined) ->
+    undefined;
+decode_muc_user_continue_attr_thread(_val) -> _val.
 
-decode_privacy_item_els([], Kinds) ->
-    lists:reverse(Kinds);
-decode_privacy_item_els([{xmlel, <<"message">>, _attrs,
-                         _} =
-                            _el
-                        | _els],
-                       Kinds) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
-          decode_privacy_item_els(_els, Kinds);
-       true -> decode_privacy_item_els(_els, Kinds)
-    end;
-decode_privacy_item_els([{xmlel, <<"iq">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Kinds) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
-          decode_privacy_item_els(_els, Kinds);
-       true -> decode_privacy_item_els(_els, Kinds)
-    end;
-decode_privacy_item_els([{xmlel, <<"presence-in">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Kinds) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
-          decode_privacy_item_els(_els, Kinds);
-       true -> decode_privacy_item_els(_els, Kinds)
-    end;
-decode_privacy_item_els([{xmlel, <<"presence-out">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Kinds) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
-          decode_privacy_item_els(_els, Kinds);
-       true -> decode_privacy_item_els(_els, Kinds)
-    end;
-decode_privacy_item_els([_ | _els], Kinds) ->
-    decode_privacy_item_els(_els, Kinds).
+encode_muc_user_continue_attr_thread(undefined, _acc) ->
+    _acc;
+encode_muc_user_continue_attr_thread(_val, _acc) ->
+    [{<<"thread">>, _val} | _acc].
 
-decode_privacy_item_attrs([{<<"action">>, _val}
-                          | _attrs],
-                         _Action, Order, Type, Value) ->
-    decode_privacy_item_attrs(_attrs, _val, Order, Type,
-                             Value);
-decode_privacy_item_attrs([{<<"order">>, _val}
-                          | _attrs],
-                         Action, _Order, Type, Value) ->
-    decode_privacy_item_attrs(_attrs, Action, _val, Type,
-                             Value);
-decode_privacy_item_attrs([{<<"type">>, _val} | _attrs],
-                         Action, Order, _Type, Value) ->
-    decode_privacy_item_attrs(_attrs, Action, Order, _val,
-                             Value);
-decode_privacy_item_attrs([{<<"value">>, _val}
-                          | _attrs],
-                         Action, Order, Type, _Value) ->
-    decode_privacy_item_attrs(_attrs, Action, Order, Type,
-                             _val);
-decode_privacy_item_attrs([_ | _attrs], Action, Order,
-                         Type, Value) ->
-    decode_privacy_item_attrs(_attrs, Action, Order, Type,
-                             Value);
-decode_privacy_item_attrs([], Action, Order, Type,
-                         Value) ->
-    {decode_privacy_item_attr_action(Action),
-     decode_privacy_item_attr_order(Order),
-     decode_privacy_item_attr_type(Type),
-     decode_privacy_item_attr_value(Value)}.
+decode_muc_user_actor({xmlel, <<"actor">>, _attrs,
+                      _els}) ->
+    {Jid, Nick} = decode_muc_user_actor_attrs(_attrs,
+                                             undefined, undefined),
+    {muc_actor, Jid, Nick}.
 
-encode_privacy_item({privacy_item, Order, Action, Type,
-                    Value, Kinds},
-                   _xmlns_attrs) ->
-    _els = 'encode_privacy_item_$kinds'(Kinds, []),
-    _attrs = encode_privacy_item_attr_value(Value,
-                                           encode_privacy_item_attr_type(Type,
-                                                                         encode_privacy_item_attr_order(Order,
-                                                                                                        encode_privacy_item_attr_action(Action,
-                                                                                                                                        _xmlns_attrs)))),
-    {xmlel, <<"item">>, _attrs, _els}.
+decode_muc_user_actor_attrs([{<<"jid">>, _val}
+                            | _attrs],
+                           _Jid, Nick) ->
+    decode_muc_user_actor_attrs(_attrs, _val, Nick);
+decode_muc_user_actor_attrs([{<<"nick">>, _val}
+                            | _attrs],
+                           Jid, _Nick) ->
+    decode_muc_user_actor_attrs(_attrs, Jid, _val);
+decode_muc_user_actor_attrs([_ | _attrs], Jid, Nick) ->
+    decode_muc_user_actor_attrs(_attrs, Jid, Nick);
+decode_muc_user_actor_attrs([], Jid, Nick) ->
+    {decode_muc_user_actor_attr_jid(Jid),
+     decode_muc_user_actor_attr_nick(Nick)}.
 
-'encode_privacy_item_$kinds'([], _acc) -> _acc;
-'encode_privacy_item_$kinds'([message = Kinds | _els],
-                            _acc) ->
-    'encode_privacy_item_$kinds'(_els,
-                                [encode_privacy_message(Kinds, []) | _acc]);
-'encode_privacy_item_$kinds'([iq = Kinds | _els],
-                            _acc) ->
-    'encode_privacy_item_$kinds'(_els,
-                                [encode_privacy_iq(Kinds, []) | _acc]);
-'encode_privacy_item_$kinds'(['presence-in' = Kinds
-                             | _els],
-                            _acc) ->
-    'encode_privacy_item_$kinds'(_els,
-                                [encode_privacy_presence_in(Kinds, [])
-                                 | _acc]);
-'encode_privacy_item_$kinds'(['presence-out' = Kinds
-                             | _els],
-                            _acc) ->
-    'encode_privacy_item_$kinds'(_els,
-                                [encode_privacy_presence_out(Kinds, [])
-                                 | _acc]).
+encode_muc_user_actor({muc_actor, Jid, Nick},
+                     _xmlns_attrs) ->
+    _els = [],
+    _attrs = encode_muc_user_actor_attr_nick(Nick,
+                                            encode_muc_user_actor_attr_jid(Jid,
+                                                                           _xmlns_attrs)),
+    {xmlel, <<"actor">>, _attrs, _els}.
 
-decode_privacy_item_attr_action(undefined) ->
-    erlang:error({missing_attr, <<"action">>, <<"item">>,
-                 <<"jabber:iq:privacy">>});
-decode_privacy_item_attr_action(_val) ->
-    case catch xml_gen:dec_enum(_val, [allow, deny]) of
+decode_muc_user_actor_attr_jid(undefined) -> undefined;
+decode_muc_user_actor_attr_jid(_val) ->
+    case catch dec_jid(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"action">>, <<"item">>,
-                       <<"jabber:iq:privacy">>});
+         erlang:error({bad_attr_value, <<"jid">>, <<"actor">>,
+                       <<"http://jabber.org/protocol/muc#user">>});
       _res -> _res
     end.
 
-encode_privacy_item_attr_action(_val, _acc) ->
-    [{<<"action">>, xml_gen:enc_enum(_val)} | _acc].
+encode_muc_user_actor_attr_jid(undefined, _acc) -> _acc;
+encode_muc_user_actor_attr_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
 
-decode_privacy_item_attr_order(undefined) ->
-    erlang:error({missing_attr, <<"order">>, <<"item">>,
-                 <<"jabber:iq:privacy">>});
-decode_privacy_item_attr_order(_val) ->
-    case catch xml_gen:dec_int(_val, 0, infinity) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"order">>, <<"item">>,
-                       <<"jabber:iq:privacy">>});
-      _res -> _res
-    end.
+decode_muc_user_actor_attr_nick(undefined) -> undefined;
+decode_muc_user_actor_attr_nick(_val) -> _val.
 
-encode_privacy_item_attr_order(_val, _acc) ->
-    [{<<"order">>, xml_gen:enc_int(_val)} | _acc].
+encode_muc_user_actor_attr_nick(undefined, _acc) ->
+    _acc;
+encode_muc_user_actor_attr_nick(_val, _acc) ->
+    [{<<"nick">>, _val} | _acc].
 
-decode_privacy_item_attr_type(undefined) -> undefined;
-decode_privacy_item_attr_type(_val) ->
-    case catch xml_gen:dec_enum(_val,
-                               [group, jid, subscription])
-       of
+decode_muc_user_invite({xmlel, <<"invite">>, _attrs,
+                       _els}) ->
+    Reason = decode_muc_user_invite_els(_els, undefined),
+    {To, From} = decode_muc_user_invite_attrs(_attrs,
+                                             undefined, undefined),
+    {muc_invite, Reason, From, To}.
+
+decode_muc_user_invite_els([], Reason) -> Reason;
+decode_muc_user_invite_els([{xmlel, <<"reason">>,
+                            _attrs, _} =
+                               _el
+                           | _els],
+                          Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
+          decode_muc_user_invite_els(_els,
+                                     decode_muc_user_reason(_el));
+       true -> decode_muc_user_invite_els(_els, Reason)
+    end;
+decode_muc_user_invite_els([_ | _els], Reason) ->
+    decode_muc_user_invite_els(_els, Reason).
+
+decode_muc_user_invite_attrs([{<<"to">>, _val}
+                             | _attrs],
+                            _To, From) ->
+    decode_muc_user_invite_attrs(_attrs, _val, From);
+decode_muc_user_invite_attrs([{<<"from">>, _val}
+                             | _attrs],
+                            To, _From) ->
+    decode_muc_user_invite_attrs(_attrs, To, _val);
+decode_muc_user_invite_attrs([_ | _attrs], To, From) ->
+    decode_muc_user_invite_attrs(_attrs, To, From);
+decode_muc_user_invite_attrs([], To, From) ->
+    {decode_muc_user_invite_attr_to(To),
+     decode_muc_user_invite_attr_from(From)}.
+
+encode_muc_user_invite({muc_invite, Reason, From, To},
+                      _xmlns_attrs) ->
+    _els = 'encode_muc_user_invite_$reason'(Reason, []),
+    _attrs = encode_muc_user_invite_attr_from(From,
+                                             encode_muc_user_invite_attr_to(To,
+                                                                            _xmlns_attrs)),
+    {xmlel, <<"invite">>, _attrs, _els}.
+
+'encode_muc_user_invite_$reason'(undefined, _acc) ->
+    _acc;
+'encode_muc_user_invite_$reason'(Reason, _acc) ->
+    [encode_muc_user_reason(Reason, []) | _acc].
+
+decode_muc_user_invite_attr_to(undefined) -> undefined;
+decode_muc_user_invite_attr_to(_val) ->
+    case catch dec_jid(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"type">>, <<"item">>,
-                       <<"jabber:iq:privacy">>});
+         erlang:error({bad_attr_value, <<"to">>, <<"invite">>,
+                       <<"http://jabber.org/protocol/muc#user">>});
       _res -> _res
     end.
 
-encode_privacy_item_attr_type(undefined, _acc) -> _acc;
-encode_privacy_item_attr_type(_val, _acc) ->
-    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
+encode_muc_user_invite_attr_to(undefined, _acc) -> _acc;
+encode_muc_user_invite_attr_to(_val, _acc) ->
+    [{<<"to">>, enc_jid(_val)} | _acc].
 
-decode_privacy_item_attr_value(undefined) -> undefined;
-decode_privacy_item_attr_value(_val) -> _val.
+decode_muc_user_invite_attr_from(undefined) ->
+    undefined;
+decode_muc_user_invite_attr_from(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"from">>, <<"invite">>,
+                       <<"http://jabber.org/protocol/muc#user">>});
+      _res -> _res
+    end.
 
-encode_privacy_item_attr_value(undefined, _acc) -> _acc;
-encode_privacy_item_attr_value(_val, _acc) ->
-    [{<<"value">>, _val} | _acc].
+encode_muc_user_invite_attr_from(undefined, _acc) ->
+    _acc;
+encode_muc_user_invite_attr_from(_val, _acc) ->
+    [{<<"from">>, enc_jid(_val)} | _acc].
 
-decode_privacy_list({xmlel, <<"list">>, _attrs,
-                    _els}) ->
-    Items = decode_privacy_list_els(_els, []),
-    Name = decode_privacy_list_attrs(_attrs, undefined),
-    {privacy_list, Name, Items}.
+decode_muc_user_destroy({xmlel, <<"destroy">>, _attrs,
+                        _els}) ->
+    Reason = decode_muc_user_destroy_els(_els, undefined),
+    Jid = decode_muc_user_destroy_attrs(_attrs, undefined),
+    {muc_user_destroy, Reason, Jid}.
 
-decode_privacy_list_els([], Items) ->
-    lists:reverse(Items);
-decode_privacy_list_els([{xmlel, <<"item">>, _attrs,
-                         _} =
-                            _el
-                        | _els],
-                       Items) ->
+decode_muc_user_destroy_els([], Reason) -> Reason;
+decode_muc_user_destroy_els([{xmlel, <<"reason">>,
+                             _attrs, _} =
+                                _el
+                            | _els],
+                           Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
-          decode_privacy_list_els(_els,
-                                  case decode_privacy_item(_el) of
-                                    undefined -> Items;
-                                    _new_el -> [_new_el | Items]
-                                  end);
-       true -> decode_privacy_list_els(_els, Items)
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
+          decode_muc_user_destroy_els(_els,
+                                      decode_muc_user_reason(_el));
+       true -> decode_muc_user_destroy_els(_els, Reason)
     end;
-decode_privacy_list_els([_ | _els], Items) ->
-    decode_privacy_list_els(_els, Items).
+decode_muc_user_destroy_els([_ | _els], Reason) ->
+    decode_muc_user_destroy_els(_els, Reason).
 
-decode_privacy_list_attrs([{<<"name">>, _val} | _attrs],
-                         _Name) ->
-    decode_privacy_list_attrs(_attrs, _val);
-decode_privacy_list_attrs([_ | _attrs], Name) ->
-    decode_privacy_list_attrs(_attrs, Name);
-decode_privacy_list_attrs([], Name) ->
-    decode_privacy_list_attr_name(Name).
+decode_muc_user_destroy_attrs([{<<"jid">>, _val}
+                              | _attrs],
+                             _Jid) ->
+    decode_muc_user_destroy_attrs(_attrs, _val);
+decode_muc_user_destroy_attrs([_ | _attrs], Jid) ->
+    decode_muc_user_destroy_attrs(_attrs, Jid);
+decode_muc_user_destroy_attrs([], Jid) ->
+    decode_muc_user_destroy_attr_jid(Jid).
 
-encode_privacy_list({privacy_list, Name, Items},
-                   _xmlns_attrs) ->
-    _els = 'encode_privacy_list_$items'(Items, []),
-    _attrs = encode_privacy_list_attr_name(Name,
-                                          _xmlns_attrs),
-    {xmlel, <<"list">>, _attrs, _els}.
+encode_muc_user_destroy({muc_user_destroy, Reason, Jid},
+                       _xmlns_attrs) ->
+    _els = 'encode_muc_user_destroy_$reason'(Reason, []),
+    _attrs = encode_muc_user_destroy_attr_jid(Jid,
+                                             _xmlns_attrs),
+    {xmlel, <<"destroy">>, _attrs, _els}.
 
-'encode_privacy_list_$items'([], _acc) -> _acc;
-'encode_privacy_list_$items'([Items | _els], _acc) ->
-    'encode_privacy_list_$items'(_els,
-                                [encode_privacy_item(Items, []) | _acc]).
+'encode_muc_user_destroy_$reason'(undefined, _acc) ->
+    _acc;
+'encode_muc_user_destroy_$reason'(Reason, _acc) ->
+    [encode_muc_user_reason(Reason, []) | _acc].
 
-decode_privacy_list_attr_name(undefined) ->
-    erlang:error({missing_attr, <<"name">>, <<"list">>,
-                 <<"jabber:iq:privacy">>});
-decode_privacy_list_attr_name(_val) -> _val.
+decode_muc_user_destroy_attr_jid(undefined) ->
+    undefined;
+decode_muc_user_destroy_attr_jid(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"jid">>, <<"destroy">>,
+                       <<"http://jabber.org/protocol/muc#user">>});
+      _res -> _res
+    end.
 
-encode_privacy_list_attr_name(_val, _acc) ->
-    [{<<"name">>, _val} | _acc].
+encode_muc_user_destroy_attr_jid(undefined, _acc) ->
+    _acc;
+encode_muc_user_destroy_attr_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
 
-decode_privacy_default_list({xmlel, <<"default">>,
-                            _attrs, _els}) ->
-    Name = decode_privacy_default_list_attrs(_attrs,
-                                            undefined),
-    Name.
+decode_muc_user_decline({xmlel, <<"decline">>, _attrs,
+                        _els}) ->
+    Reason = decode_muc_user_decline_els(_els, undefined),
+    {To, From} = decode_muc_user_decline_attrs(_attrs,
+                                              undefined, undefined),
+    {muc_decline, Reason, From, To}.
 
-decode_privacy_default_list_attrs([{<<"name">>, _val}
-                                  | _attrs],
-                                 _Name) ->
-    decode_privacy_default_list_attrs(_attrs, _val);
-decode_privacy_default_list_attrs([_ | _attrs], Name) ->
-    decode_privacy_default_list_attrs(_attrs, Name);
-decode_privacy_default_list_attrs([], Name) ->
-    decode_privacy_default_list_attr_name(Name).
+decode_muc_user_decline_els([], Reason) -> Reason;
+decode_muc_user_decline_els([{xmlel, <<"reason">>,
+                             _attrs, _} =
+                                _el
+                            | _els],
+                           Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
+          decode_muc_user_decline_els(_els,
+                                      decode_muc_user_reason(_el));
+       true -> decode_muc_user_decline_els(_els, Reason)
+    end;
+decode_muc_user_decline_els([_ | _els], Reason) ->
+    decode_muc_user_decline_els(_els, Reason).
 
-encode_privacy_default_list(Name, _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_privacy_default_list_attr_name(Name,
-                                                  _xmlns_attrs),
-    {xmlel, <<"default">>, _attrs, _els}.
+decode_muc_user_decline_attrs([{<<"to">>, _val}
+                              | _attrs],
+                             _To, From) ->
+    decode_muc_user_decline_attrs(_attrs, _val, From);
+decode_muc_user_decline_attrs([{<<"from">>, _val}
+                              | _attrs],
+                             To, _From) ->
+    decode_muc_user_decline_attrs(_attrs, To, _val);
+decode_muc_user_decline_attrs([_ | _attrs], To, From) ->
+    decode_muc_user_decline_attrs(_attrs, To, From);
+decode_muc_user_decline_attrs([], To, From) ->
+    {decode_muc_user_decline_attr_to(To),
+     decode_muc_user_decline_attr_from(From)}.
 
-decode_privacy_default_list_attr_name(undefined) ->
-    none;
-decode_privacy_default_list_attr_name(_val) -> _val.
+encode_muc_user_decline({muc_decline, Reason, From, To},
+                       _xmlns_attrs) ->
+    _els = 'encode_muc_user_decline_$reason'(Reason, []),
+    _attrs = encode_muc_user_decline_attr_from(From,
+                                              encode_muc_user_decline_attr_to(To,
+                                                                              _xmlns_attrs)),
+    {xmlel, <<"decline">>, _attrs, _els}.
 
-encode_privacy_default_list_attr_name(none, _acc) ->
+'encode_muc_user_decline_$reason'(undefined, _acc) ->
     _acc;
-encode_privacy_default_list_attr_name(_val, _acc) ->
-    [{<<"name">>, _val} | _acc].
-
-decode_privacy_active_list({xmlel, <<"active">>, _attrs,
-                           _els}) ->
-    Name = decode_privacy_active_list_attrs(_attrs,
-                                           undefined),
-    Name.
+'encode_muc_user_decline_$reason'(Reason, _acc) ->
+    [encode_muc_user_reason(Reason, []) | _acc].
 
-decode_privacy_active_list_attrs([{<<"name">>, _val}
-                                 | _attrs],
-                                _Name) ->
-    decode_privacy_active_list_attrs(_attrs, _val);
-decode_privacy_active_list_attrs([_ | _attrs], Name) ->
-    decode_privacy_active_list_attrs(_attrs, Name);
-decode_privacy_active_list_attrs([], Name) ->
-    decode_privacy_active_list_attr_name(Name).
+decode_muc_user_decline_attr_to(undefined) -> undefined;
+decode_muc_user_decline_attr_to(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"to">>, <<"decline">>,
+                       <<"http://jabber.org/protocol/muc#user">>});
+      _res -> _res
+    end.
 
-encode_privacy_active_list(Name, _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_privacy_active_list_attr_name(Name,
-                                                 _xmlns_attrs),
-    {xmlel, <<"active">>, _attrs, _els}.
+encode_muc_user_decline_attr_to(undefined, _acc) ->
+    _acc;
+encode_muc_user_decline_attr_to(_val, _acc) ->
+    [{<<"to">>, enc_jid(_val)} | _acc].
 
-decode_privacy_active_list_attr_name(undefined) -> none;
-decode_privacy_active_list_attr_name(_val) -> _val.
+decode_muc_user_decline_attr_from(undefined) ->
+    undefined;
+decode_muc_user_decline_attr_from(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"from">>, <<"decline">>,
+                       <<"http://jabber.org/protocol/muc#user">>});
+      _res -> _res
+    end.
 
-encode_privacy_active_list_attr_name(none, _acc) ->
+encode_muc_user_decline_attr_from(undefined, _acc) ->
     _acc;
-encode_privacy_active_list_attr_name(_val, _acc) ->
-    [{<<"name">>, _val} | _acc].
+encode_muc_user_decline_attr_from(_val, _acc) ->
+    [{<<"from">>, enc_jid(_val)} | _acc].
 
-decode_privacy({xmlel, <<"query">>, _attrs, _els}) ->
-    {Lists, Default, Active} = decode_privacy_els(_els, [],
-                                                 undefined, undefined),
-    {privacy, Lists, Default, Active}.
+decode_muc_user_reason({xmlel, <<"reason">>, _attrs,
+                       _els}) ->
+    Cdata = decode_muc_user_reason_els(_els, <<>>), Cdata.
 
-decode_privacy_els([], Lists, Default, Active) ->
-    {lists:reverse(Lists), Default, Active};
-decode_privacy_els([{xmlel, <<"list">>, _attrs, _} = _el
-                   | _els],
-                  Lists, Default, Active) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
-          decode_privacy_els(_els,
-                             case decode_privacy_list(_el) of
-                               undefined -> Lists;
-                               _new_el -> [_new_el | Lists]
-                             end,
-                             Default, Active);
-       true -> decode_privacy_els(_els, Lists, Default, Active)
-    end;
-decode_privacy_els([{xmlel, <<"default">>, _attrs, _} =
-                       _el
-                   | _els],
-                  Lists, Default, Active) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
-          decode_privacy_els(_els, Lists,
-                             decode_privacy_default_list(_el), Active);
-       true -> decode_privacy_els(_els, Lists, Default, Active)
-    end;
-decode_privacy_els([{xmlel, <<"active">>, _attrs, _} =
-                       _el
-                   | _els],
-                  Lists, Default, Active) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
-          decode_privacy_els(_els, Lists, Default,
-                             decode_privacy_active_list(_el));
-       true -> decode_privacy_els(_els, Lists, Default, Active)
-    end;
-decode_privacy_els([_ | _els], Lists, Default,
-                  Active) ->
-    decode_privacy_els(_els, Lists, Default, Active).
+decode_muc_user_reason_els([], Cdata) ->
+    decode_muc_user_reason_cdata(Cdata);
+decode_muc_user_reason_els([{xmlcdata, _data} | _els],
+                          Cdata) ->
+    decode_muc_user_reason_els(_els,
+                              <<Cdata/binary, _data/binary>>);
+decode_muc_user_reason_els([_ | _els], Cdata) ->
+    decode_muc_user_reason_els(_els, Cdata).
 
-encode_privacy({privacy, Lists, Default, Active},
-              _xmlns_attrs) ->
-    _els = 'encode_privacy_$active'(Active,
-                                   'encode_privacy_$default'(Default,
-                                                             'encode_privacy_$lists'(Lists,
-                                                                                     []))),
+encode_muc_user_reason(Cdata, _xmlns_attrs) ->
+    _els = encode_muc_user_reason_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"query">>, _attrs, _els}.
-
-'encode_privacy_$lists'([], _acc) -> _acc;
-'encode_privacy_$lists'([Lists | _els], _acc) ->
-    'encode_privacy_$lists'(_els,
-                           [encode_privacy_list(Lists, []) | _acc]).
+    {xmlel, <<"reason">>, _attrs, _els}.
 
-'encode_privacy_$default'(undefined, _acc) -> _acc;
-'encode_privacy_$default'(Default, _acc) ->
-    [encode_privacy_default_list(Default, []) | _acc].
+decode_muc_user_reason_cdata(<<>>) -> undefined;
+decode_muc_user_reason_cdata(_val) -> _val.
 
-'encode_privacy_$active'(undefined, _acc) -> _acc;
-'encode_privacy_$active'(Active, _acc) ->
-    [encode_privacy_active_list(Active, []) | _acc].
+encode_muc_user_reason_cdata(undefined, _acc) -> _acc;
+encode_muc_user_reason_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_block_item({xmlel, <<"item">>, _attrs, _els}) ->
-    Jid = decode_block_item_attrs(_attrs, undefined), Jid.
+decode_muc_history({xmlel, <<"history">>, _attrs,
+                   _els}) ->
+    {Maxchars, Maxstanzas, Seconds, Since} =
+       decode_muc_history_attrs(_attrs, undefined, undefined,
+                                undefined, undefined),
+    {muc_history, Maxchars, Maxstanzas, Seconds, Since}.
 
-decode_block_item_attrs([{<<"jid">>, _val} | _attrs],
-                       _Jid) ->
-    decode_block_item_attrs(_attrs, _val);
-decode_block_item_attrs([_ | _attrs], Jid) ->
-    decode_block_item_attrs(_attrs, Jid);
-decode_block_item_attrs([], Jid) ->
-    decode_block_item_attr_jid(Jid).
+decode_muc_history_attrs([{<<"maxchars">>, _val}
+                         | _attrs],
+                        _Maxchars, Maxstanzas, Seconds, Since) ->
+    decode_muc_history_attrs(_attrs, _val, Maxstanzas,
+                            Seconds, Since);
+decode_muc_history_attrs([{<<"maxstanzas">>, _val}
+                         | _attrs],
+                        Maxchars, _Maxstanzas, Seconds, Since) ->
+    decode_muc_history_attrs(_attrs, Maxchars, _val,
+                            Seconds, Since);
+decode_muc_history_attrs([{<<"seconds">>, _val}
+                         | _attrs],
+                        Maxchars, Maxstanzas, _Seconds, Since) ->
+    decode_muc_history_attrs(_attrs, Maxchars, Maxstanzas,
+                            _val, Since);
+decode_muc_history_attrs([{<<"since">>, _val} | _attrs],
+                        Maxchars, Maxstanzas, Seconds, _Since) ->
+    decode_muc_history_attrs(_attrs, Maxchars, Maxstanzas,
+                            Seconds, _val);
+decode_muc_history_attrs([_ | _attrs], Maxchars,
+                        Maxstanzas, Seconds, Since) ->
+    decode_muc_history_attrs(_attrs, Maxchars, Maxstanzas,
+                            Seconds, Since);
+decode_muc_history_attrs([], Maxchars, Maxstanzas,
+                        Seconds, Since) ->
+    {decode_muc_history_attr_maxchars(Maxchars),
+     decode_muc_history_attr_maxstanzas(Maxstanzas),
+     decode_muc_history_attr_seconds(Seconds),
+     decode_muc_history_attr_since(Since)}.
 
-encode_block_item(Jid, _xmlns_attrs) ->
+encode_muc_history({muc_history, Maxchars, Maxstanzas,
+                   Seconds, Since},
+                  _xmlns_attrs) ->
     _els = [],
-    _attrs = encode_block_item_attr_jid(Jid, _xmlns_attrs),
-    {xmlel, <<"item">>, _attrs, _els}.
+    _attrs = encode_muc_history_attr_since(Since,
+                                          encode_muc_history_attr_seconds(Seconds,
+                                                                          encode_muc_history_attr_maxstanzas(Maxstanzas,
+                                                                                                             encode_muc_history_attr_maxchars(Maxchars,
+                                                                                                                                              _xmlns_attrs)))),
+    {xmlel, <<"history">>, _attrs, _els}.
 
-decode_block_item_attr_jid(undefined) ->
-    erlang:error({missing_attr, <<"jid">>, <<"item">>,
-                 <<"urn:xmpp:blocking">>});
-decode_block_item_attr_jid(_val) ->
-    case catch dec_jid(_val) of
+decode_muc_history_attr_maxchars(undefined) ->
+    undefined;
+decode_muc_history_attr_maxchars(_val) ->
+    case catch xml_gen:dec_int(_val, 0, infinity) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"jid">>, <<"item">>,
-                       <<"urn:xmpp:blocking">>});
+         erlang:error({bad_attr_value, <<"maxchars">>,
+                       <<"history">>, <<"http://jabber.org/protocol/muc">>});
       _res -> _res
     end.
 
-encode_block_item_attr_jid(_val, _acc) ->
-    [{<<"jid">>, enc_jid(_val)} | _acc].
-
-decode_block({xmlel, <<"block">>, _attrs, _els}) ->
-    Items = decode_block_els(_els, []), {block, Items}.
+encode_muc_history_attr_maxchars(undefined, _acc) ->
+    _acc;
+encode_muc_history_attr_maxchars(_val, _acc) ->
+    [{<<"maxchars">>, xml_gen:enc_int(_val)} | _acc].
 
-decode_block_els([], Items) -> lists:reverse(Items);
-decode_block_els([{xmlel, <<"item">>, _attrs, _} = _el
-                 | _els],
-                Items) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"urn:xmpp:blocking">> ->
-          decode_block_els(_els,
-                           case decode_block_item(_el) of
-                             undefined -> Items;
-                             _new_el -> [_new_el | Items]
-                           end);
-       true -> decode_block_els(_els, Items)
-    end;
-decode_block_els([_ | _els], Items) ->
-    decode_block_els(_els, Items).
+decode_muc_history_attr_maxstanzas(undefined) ->
+    undefined;
+decode_muc_history_attr_maxstanzas(_val) ->
+    case catch xml_gen:dec_int(_val, 0, infinity) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"maxstanzas">>,
+                       <<"history">>, <<"http://jabber.org/protocol/muc">>});
+      _res -> _res
+    end.
 
-encode_block({block, Items}, _xmlns_attrs) ->
-    _els = 'encode_block_$items'(Items, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"block">>, _attrs, _els}.
+encode_muc_history_attr_maxstanzas(undefined, _acc) ->
+    _acc;
+encode_muc_history_attr_maxstanzas(_val, _acc) ->
+    [{<<"maxstanzas">>, xml_gen:enc_int(_val)} | _acc].
 
-'encode_block_$items'([], _acc) -> _acc;
-'encode_block_$items'([Items | _els], _acc) ->
-    'encode_block_$items'(_els,
-                         [encode_block_item(Items, []) | _acc]).
+decode_muc_history_attr_seconds(undefined) -> undefined;
+decode_muc_history_attr_seconds(_val) ->
+    case catch xml_gen:dec_int(_val, 0, infinity) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"seconds">>,
+                       <<"history">>, <<"http://jabber.org/protocol/muc">>});
+      _res -> _res
+    end.
 
-decode_unblock({xmlel, <<"unblock">>, _attrs, _els}) ->
-    Items = decode_unblock_els(_els, []), {unblock, Items}.
+encode_muc_history_attr_seconds(undefined, _acc) ->
+    _acc;
+encode_muc_history_attr_seconds(_val, _acc) ->
+    [{<<"seconds">>, xml_gen:enc_int(_val)} | _acc].
 
-decode_unblock_els([], Items) -> lists:reverse(Items);
-decode_unblock_els([{xmlel, <<"item">>, _attrs, _} = _el
-                   | _els],
-                  Items) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"urn:xmpp:blocking">> ->
-          decode_unblock_els(_els,
-                             case decode_block_item(_el) of
-                               undefined -> Items;
-                               _new_el -> [_new_el | Items]
-                             end);
-       true -> decode_unblock_els(_els, Items)
-    end;
-decode_unblock_els([_ | _els], Items) ->
-    decode_unblock_els(_els, Items).
+decode_muc_history_attr_since(undefined) -> undefined;
+decode_muc_history_attr_since(_val) ->
+    case catch dec_utc(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"since">>,
+                       <<"history">>, <<"http://jabber.org/protocol/muc">>});
+      _res -> _res
+    end.
 
-encode_unblock({unblock, Items}, _xmlns_attrs) ->
-    _els = 'encode_unblock_$items'(Items, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"unblock">>, _attrs, _els}.
+encode_muc_history_attr_since(undefined, _acc) -> _acc;
+encode_muc_history_attr_since(_val, _acc) ->
+    [{<<"since">>, enc_utc(_val)} | _acc].
 
-'encode_unblock_$items'([], _acc) -> _acc;
-'encode_unblock_$items'([Items | _els], _acc) ->
-    'encode_unblock_$items'(_els,
-                           [encode_block_item(Items, []) | _acc]).
+decode_bytestreams({xmlel, <<"query">>, _attrs,
+                   _els}) ->
+    {Hosts, Used, Activate} = decode_bytestreams_els(_els,
+                                                    [], undefined, undefined),
+    {Dstaddr, Sid, Mode} = decode_bytestreams_attrs(_attrs,
+                                                   undefined, undefined,
+                                                   undefined),
+    {bytestreams, Hosts, Used, Activate, Dstaddr, Mode,
+     Sid}.
 
-decode_block_list({xmlel, <<"blocklist">>, _attrs,
-                  _els}) ->
-    {block_list}.
+decode_bytestreams_els([], Hosts, Used, Activate) ->
+    {lists:reverse(Hosts), Used, Activate};
+decode_bytestreams_els([{xmlel, <<"streamhost">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Hosts, Used, Activate) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns ==
+        <<"http://jabber.org/protocol/bytestreams">> ->
+          decode_bytestreams_els(_els,
+                                 case decode_bytestreams_streamhost(_el) of
+                                   undefined -> Hosts;
+                                   _new_el -> [_new_el | Hosts]
+                                 end,
+                                 Used, Activate);
+       true ->
+          decode_bytestreams_els(_els, Hosts, Used, Activate)
+    end;
+decode_bytestreams_els([{xmlel, <<"streamhost-used">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Hosts, Used, Activate) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns ==
+        <<"http://jabber.org/protocol/bytestreams">> ->
+          decode_bytestreams_els(_els, Hosts,
+                                 decode_bytestreams_streamhost_used(_el),
+                                 Activate);
+       true ->
+          decode_bytestreams_els(_els, Hosts, Used, Activate)
+    end;
+decode_bytestreams_els([{xmlel, <<"activate">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Hosts, Used, Activate) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns ==
+        <<"http://jabber.org/protocol/bytestreams">> ->
+          decode_bytestreams_els(_els, Hosts, Used,
+                                 decode_bytestreams_activate(_el));
+       true ->
+          decode_bytestreams_els(_els, Hosts, Used, Activate)
+    end;
+decode_bytestreams_els([_ | _els], Hosts, Used,
+                      Activate) ->
+    decode_bytestreams_els(_els, Hosts, Used, Activate).
 
-encode_block_list({block_list}, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"blocklist">>, _attrs, _els}.
+decode_bytestreams_attrs([{<<"dstaddr">>, _val}
+                         | _attrs],
+                        _Dstaddr, Sid, Mode) ->
+    decode_bytestreams_attrs(_attrs, _val, Sid, Mode);
+decode_bytestreams_attrs([{<<"sid">>, _val} | _attrs],
+                        Dstaddr, _Sid, Mode) ->
+    decode_bytestreams_attrs(_attrs, Dstaddr, _val, Mode);
+decode_bytestreams_attrs([{<<"mode">>, _val} | _attrs],
+                        Dstaddr, Sid, _Mode) ->
+    decode_bytestreams_attrs(_attrs, Dstaddr, Sid, _val);
+decode_bytestreams_attrs([_ | _attrs], Dstaddr, Sid,
+                        Mode) ->
+    decode_bytestreams_attrs(_attrs, Dstaddr, Sid, Mode);
+decode_bytestreams_attrs([], Dstaddr, Sid, Mode) ->
+    {decode_bytestreams_attr_dstaddr(Dstaddr),
+     decode_bytestreams_attr_sid(Sid),
+     decode_bytestreams_attr_mode(Mode)}.
 
-decode_disco_identity({xmlel, <<"identity">>, _attrs,
-                      _els}) ->
-    {Category, Type, Name} =
-       decode_disco_identity_attrs(_attrs, undefined,
-                                   undefined, undefined),
-    {identity, Category, Type, Name}.
+encode_bytestreams({bytestreams, Hosts, Used, Activate,
+                   Dstaddr, Mode, Sid},
+                  _xmlns_attrs) ->
+    _els = 'encode_bytestreams_$activate'(Activate,
+                                         'encode_bytestreams_$used'(Used,
+                                                                    'encode_bytestreams_$hosts'(Hosts,
+                                                                                                []))),
+    _attrs = encode_bytestreams_attr_mode(Mode,
+                                         encode_bytestreams_attr_sid(Sid,
+                                                                     encode_bytestreams_attr_dstaddr(Dstaddr,
+                                                                                                     _xmlns_attrs))),
+    {xmlel, <<"query">>, _attrs, _els}.
 
-decode_disco_identity_attrs([{<<"category">>, _val}
-                            | _attrs],
-                           _Category, Type, Name) ->
-    decode_disco_identity_attrs(_attrs, _val, Type, Name);
-decode_disco_identity_attrs([{<<"type">>, _val}
-                            | _attrs],
-                           Category, _Type, Name) ->
-    decode_disco_identity_attrs(_attrs, Category, _val,
-                               Name);
-decode_disco_identity_attrs([{<<"name">>, _val}
-                            | _attrs],
-                           Category, Type, _Name) ->
-    decode_disco_identity_attrs(_attrs, Category, Type,
-                               _val);
-decode_disco_identity_attrs([_ | _attrs], Category,
-                           Type, Name) ->
-    decode_disco_identity_attrs(_attrs, Category, Type,
-                               Name);
-decode_disco_identity_attrs([], Category, Type, Name) ->
-    {decode_disco_identity_attr_category(Category),
-     decode_disco_identity_attr_type(Type),
-     decode_disco_identity_attr_name(Name)}.
+'encode_bytestreams_$hosts'([], _acc) -> _acc;
+'encode_bytestreams_$hosts'([Hosts | _els], _acc) ->
+    'encode_bytestreams_$hosts'(_els,
+                               [encode_bytestreams_streamhost(Hosts, [])
+                                | _acc]).
 
-encode_disco_identity({identity, Category, Type, Name},
-                     _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_disco_identity_attr_name(Name,
-                                            encode_disco_identity_attr_type(Type,
-                                                                            encode_disco_identity_attr_category(Category,
-                                                                                                                _xmlns_attrs))),
-    {xmlel, <<"identity">>, _attrs, _els}.
+'encode_bytestreams_$used'(undefined, _acc) -> _acc;
+'encode_bytestreams_$used'(Used, _acc) ->
+    [encode_bytestreams_streamhost_used(Used, []) | _acc].
 
-decode_disco_identity_attr_category(undefined) ->
-    erlang:error({missing_attr, <<"category">>,
-                 <<"identity">>,
-                 <<"http://jabber.org/protocol/disco#info">>});
-decode_disco_identity_attr_category(_val) -> _val.
+'encode_bytestreams_$activate'(undefined, _acc) -> _acc;
+'encode_bytestreams_$activate'(Activate, _acc) ->
+    [encode_bytestreams_activate(Activate, []) | _acc].
 
-encode_disco_identity_attr_category(_val, _acc) ->
-    [{<<"category">>, _val} | _acc].
+decode_bytestreams_attr_dstaddr(undefined) -> undefined;
+decode_bytestreams_attr_dstaddr(_val) -> _val.
 
-decode_disco_identity_attr_type(undefined) ->
-    erlang:error({missing_attr, <<"type">>, <<"identity">>,
-                 <<"http://jabber.org/protocol/disco#info">>});
-decode_disco_identity_attr_type(_val) -> _val.
+encode_bytestreams_attr_dstaddr(undefined, _acc) ->
+    _acc;
+encode_bytestreams_attr_dstaddr(_val, _acc) ->
+    [{<<"dstaddr">>, _val} | _acc].
 
-encode_disco_identity_attr_type(_val, _acc) ->
-    [{<<"type">>, _val} | _acc].
+decode_bytestreams_attr_sid(undefined) -> undefined;
+decode_bytestreams_attr_sid(_val) -> _val.
 
-decode_disco_identity_attr_name(undefined) -> undefined;
-decode_disco_identity_attr_name(_val) -> _val.
+encode_bytestreams_attr_sid(undefined, _acc) -> _acc;
+encode_bytestreams_attr_sid(_val, _acc) ->
+    [{<<"sid">>, _val} | _acc].
 
-encode_disco_identity_attr_name(undefined, _acc) ->
-    _acc;
-encode_disco_identity_attr_name(_val, _acc) ->
-    [{<<"name">>, _val} | _acc].
+decode_bytestreams_attr_mode(undefined) -> tcp;
+decode_bytestreams_attr_mode(_val) ->
+    case catch xml_gen:dec_enum(_val, [tcp, udp]) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"mode">>, <<"query">>,
+                       <<"http://jabber.org/protocol/bytestreams">>});
+      _res -> _res
+    end.
 
-decode_disco_feature({xmlel, <<"feature">>, _attrs,
-                     _els}) ->
-    Var = decode_disco_feature_attrs(_attrs, undefined),
-    Var.
+encode_bytestreams_attr_mode(tcp, _acc) -> _acc;
+encode_bytestreams_attr_mode(_val, _acc) ->
+    [{<<"mode">>, xml_gen:enc_enum(_val)} | _acc].
 
-decode_disco_feature_attrs([{<<"var">>, _val} | _attrs],
-                          _Var) ->
-    decode_disco_feature_attrs(_attrs, _val);
-decode_disco_feature_attrs([_ | _attrs], Var) ->
-    decode_disco_feature_attrs(_attrs, Var);
-decode_disco_feature_attrs([], Var) ->
-    decode_disco_feature_attr_var(Var).
+decode_bytestreams_activate({xmlel, <<"activate">>,
+                            _attrs, _els}) ->
+    Cdata = decode_bytestreams_activate_els(_els, <<>>),
+    Cdata.
 
-encode_disco_feature(Var, _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_disco_feature_attr_var(Var,
-                                          _xmlns_attrs),
-    {xmlel, <<"feature">>, _attrs, _els}.
+decode_bytestreams_activate_els([], Cdata) ->
+    decode_bytestreams_activate_cdata(Cdata);
+decode_bytestreams_activate_els([{xmlcdata, _data}
+                                | _els],
+                               Cdata) ->
+    decode_bytestreams_activate_els(_els,
+                                   <<Cdata/binary, _data/binary>>);
+decode_bytestreams_activate_els([_ | _els], Cdata) ->
+    decode_bytestreams_activate_els(_els, Cdata).
 
-decode_disco_feature_attr_var(undefined) ->
-    erlang:error({missing_attr, <<"var">>, <<"feature">>,
-                 <<"http://jabber.org/protocol/disco#info">>});
-decode_disco_feature_attr_var(_val) -> _val.
+encode_bytestreams_activate(Cdata, _xmlns_attrs) ->
+    _els = encode_bytestreams_activate_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"activate">>, _attrs, _els}.
 
-encode_disco_feature_attr_var(_val, _acc) ->
-    [{<<"var">>, _val} | _acc].
-
-decode_disco_info({xmlel, <<"query">>, _attrs, _els}) ->
-    {Xdata, Feature, Identity} = decode_disco_info_els(_els,
-                                                      [], [], []),
-    Node = decode_disco_info_attrs(_attrs, undefined),
-    {disco_info, Node, Identity, Feature, Xdata}.
-
-decode_disco_info_els([], Xdata, Feature, Identity) ->
-    {lists:reverse(Xdata), lists:reverse(Feature),
-     lists:reverse(Identity)};
-decode_disco_info_els([{xmlel, <<"identity">>, _attrs,
-                       _} =
-                          _el
-                      | _els],
-                     Xdata, Feature, Identity) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/disco#info">> ->
-          decode_disco_info_els(_els, Xdata, Feature,
-                                case decode_disco_identity(_el) of
-                                  undefined -> Identity;
-                                  _new_el -> [_new_el | Identity]
-                                end);
-       true ->
-          decode_disco_info_els(_els, Xdata, Feature, Identity)
-    end;
-decode_disco_info_els([{xmlel, <<"feature">>, _attrs,
-                       _} =
-                          _el
-                      | _els],
-                     Xdata, Feature, Identity) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/disco#info">> ->
-          decode_disco_info_els(_els, Xdata,
-                                case decode_disco_feature(_el) of
-                                  undefined -> Feature;
-                                  _new_el -> [_new_el | Feature]
-                                end,
-                                Identity);
-       true ->
-          decode_disco_info_els(_els, Xdata, Feature, Identity)
-    end;
-decode_disco_info_els([{xmlel, <<"x">>, _attrs, _} = _el
-                      | _els],
-                     Xdata, Feature, Identity) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<"jabber:x:data">> ->
-          decode_disco_info_els(_els,
-                                case decode_xdata(_el) of
-                                  undefined -> Xdata;
-                                  _new_el -> [_new_el | Xdata]
-                                end,
-                                Feature, Identity);
-       true ->
-          decode_disco_info_els(_els, Xdata, Feature, Identity)
-    end;
-decode_disco_info_els([_ | _els], Xdata, Feature,
-                     Identity) ->
-    decode_disco_info_els(_els, Xdata, Feature, Identity).
-
-decode_disco_info_attrs([{<<"node">>, _val} | _attrs],
-                       _Node) ->
-    decode_disco_info_attrs(_attrs, _val);
-decode_disco_info_attrs([_ | _attrs], Node) ->
-    decode_disco_info_attrs(_attrs, Node);
-decode_disco_info_attrs([], Node) ->
-    decode_disco_info_attr_node(Node).
+decode_bytestreams_activate_cdata(<<>>) -> undefined;
+decode_bytestreams_activate_cdata(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"activate">>,
+                       <<"http://jabber.org/protocol/bytestreams">>});
+      _res -> _res
+    end.
 
-encode_disco_info({disco_info, Node, Identity, Feature,
-                  Xdata},
-                 _xmlns_attrs) ->
-    _els = 'encode_disco_info_$identity'(Identity,
-                                        'encode_disco_info_$feature'(Feature,
-                                                                     'encode_disco_info_$xdata'(Xdata,
-                                                                                                []))),
-    _attrs = encode_disco_info_attr_node(Node,
-                                        _xmlns_attrs),
-    {xmlel, <<"query">>, _attrs, _els}.
+encode_bytestreams_activate_cdata(undefined, _acc) ->
+    _acc;
+encode_bytestreams_activate_cdata(_val, _acc) ->
+    [{xmlcdata, enc_jid(_val)} | _acc].
 
-'encode_disco_info_$xdata'([], _acc) -> _acc;
-'encode_disco_info_$xdata'([Xdata | _els], _acc) ->
-    'encode_disco_info_$xdata'(_els,
-                              [encode_xdata(Xdata,
-                                            [{<<"xmlns">>,
-                                              <<"jabber:x:data">>}])
-                               | _acc]).
+decode_bytestreams_streamhost_used({xmlel,
+                                   <<"streamhost-used">>, _attrs, _els}) ->
+    Jid = decode_bytestreams_streamhost_used_attrs(_attrs,
+                                                  undefined),
+    Jid.
 
-'encode_disco_info_$feature'([], _acc) -> _acc;
-'encode_disco_info_$feature'([Feature | _els], _acc) ->
-    'encode_disco_info_$feature'(_els,
-                                [encode_disco_feature(Feature, []) | _acc]).
+decode_bytestreams_streamhost_used_attrs([{<<"jid">>,
+                                          _val}
+                                         | _attrs],
+                                        _Jid) ->
+    decode_bytestreams_streamhost_used_attrs(_attrs, _val);
+decode_bytestreams_streamhost_used_attrs([_ | _attrs],
+                                        Jid) ->
+    decode_bytestreams_streamhost_used_attrs(_attrs, Jid);
+decode_bytestreams_streamhost_used_attrs([], Jid) ->
+    decode_bytestreams_streamhost_used_attr_jid(Jid).
 
-'encode_disco_info_$identity'([], _acc) -> _acc;
-'encode_disco_info_$identity'([Identity | _els],
-                             _acc) ->
-    'encode_disco_info_$identity'(_els,
-                                 [encode_disco_identity(Identity, []) | _acc]).
+encode_bytestreams_streamhost_used(Jid, _xmlns_attrs) ->
+    _els = [],
+    _attrs =
+       encode_bytestreams_streamhost_used_attr_jid(Jid,
+                                                   _xmlns_attrs),
+    {xmlel, <<"streamhost-used">>, _attrs, _els}.
 
-decode_disco_info_attr_node(undefined) -> undefined;
-decode_disco_info_attr_node(_val) -> _val.
+decode_bytestreams_streamhost_used_attr_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>,
+                 <<"streamhost-used">>,
+                 <<"http://jabber.org/protocol/bytestreams">>});
+decode_bytestreams_streamhost_used_attr_jid(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"jid">>,
+                       <<"streamhost-used">>,
+                       <<"http://jabber.org/protocol/bytestreams">>});
+      _res -> _res
+    end.
 
-encode_disco_info_attr_node(undefined, _acc) -> _acc;
-encode_disco_info_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
+encode_bytestreams_streamhost_used_attr_jid(_val,
+                                           _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
 
-decode_disco_item({xmlel, <<"item">>, _attrs, _els}) ->
-    {Jid, Name, Node} = decode_disco_item_attrs(_attrs,
-                                               undefined, undefined,
-                                               undefined),
-    {disco_item, Jid, Name, Node}.
+decode_bytestreams_streamhost({xmlel, <<"streamhost">>,
+                              _attrs, _els}) ->
+    {Jid, Host, Port} =
+       decode_bytestreams_streamhost_attrs(_attrs, undefined,
+                                           undefined, undefined),
+    {streamhost, Jid, Host, Port}.
 
-decode_disco_item_attrs([{<<"jid">>, _val} | _attrs],
-                       _Jid, Name, Node) ->
-    decode_disco_item_attrs(_attrs, _val, Name, Node);
-decode_disco_item_attrs([{<<"name">>, _val} | _attrs],
-                       Jid, _Name, Node) ->
-    decode_disco_item_attrs(_attrs, Jid, _val, Node);
-decode_disco_item_attrs([{<<"node">>, _val} | _attrs],
-                       Jid, Name, _Node) ->
-    decode_disco_item_attrs(_attrs, Jid, Name, _val);
-decode_disco_item_attrs([_ | _attrs], Jid, Name,
-                       Node) ->
-    decode_disco_item_attrs(_attrs, Jid, Name, Node);
-decode_disco_item_attrs([], Jid, Name, Node) ->
-    {decode_disco_item_attr_jid(Jid),
-     decode_disco_item_attr_name(Name),
-     decode_disco_item_attr_node(Node)}.
+decode_bytestreams_streamhost_attrs([{<<"jid">>, _val}
+                                    | _attrs],
+                                   _Jid, Host, Port) ->
+    decode_bytestreams_streamhost_attrs(_attrs, _val, Host,
+                                       Port);
+decode_bytestreams_streamhost_attrs([{<<"host">>, _val}
+                                    | _attrs],
+                                   Jid, _Host, Port) ->
+    decode_bytestreams_streamhost_attrs(_attrs, Jid, _val,
+                                       Port);
+decode_bytestreams_streamhost_attrs([{<<"port">>, _val}
+                                    | _attrs],
+                                   Jid, Host, _Port) ->
+    decode_bytestreams_streamhost_attrs(_attrs, Jid, Host,
+                                       _val);
+decode_bytestreams_streamhost_attrs([_ | _attrs], Jid,
+                                   Host, Port) ->
+    decode_bytestreams_streamhost_attrs(_attrs, Jid, Host,
+                                       Port);
+decode_bytestreams_streamhost_attrs([], Jid, Host,
+                                   Port) ->
+    {decode_bytestreams_streamhost_attr_jid(Jid),
+     decode_bytestreams_streamhost_attr_host(Host),
+     decode_bytestreams_streamhost_attr_port(Port)}.
 
-encode_disco_item({disco_item, Jid, Name, Node},
-                 _xmlns_attrs) ->
+encode_bytestreams_streamhost({streamhost, Jid, Host,
+                              Port},
+                             _xmlns_attrs) ->
     _els = [],
-    _attrs = encode_disco_item_attr_node(Node,
-                                        encode_disco_item_attr_name(Name,
-                                                                    encode_disco_item_attr_jid(Jid,
-                                                                                               _xmlns_attrs))),
-    {xmlel, <<"item">>, _attrs, _els}.
+    _attrs = encode_bytestreams_streamhost_attr_port(Port,
+                                                    encode_bytestreams_streamhost_attr_host(Host,
+                                                                                            encode_bytestreams_streamhost_attr_jid(Jid,
+                                                                                                                                   _xmlns_attrs))),
+    {xmlel, <<"streamhost">>, _attrs, _els}.
 
-decode_disco_item_attr_jid(undefined) ->
-    erlang:error({missing_attr, <<"jid">>, <<"item">>,
-                 <<"http://jabber.org/protocol/disco#items">>});
-decode_disco_item_attr_jid(_val) ->
+decode_bytestreams_streamhost_attr_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>, <<"streamhost">>,
+                 <<"http://jabber.org/protocol/bytestreams">>});
+decode_bytestreams_streamhost_attr_jid(_val) ->
     case catch dec_jid(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"jid">>, <<"item">>,
-                       <<"http://jabber.org/protocol/disco#items">>});
+         erlang:error({bad_attr_value, <<"jid">>,
+                       <<"streamhost">>,
+                       <<"http://jabber.org/protocol/bytestreams">>});
       _res -> _res
     end.
 
-encode_disco_item_attr_jid(_val, _acc) ->
+encode_bytestreams_streamhost_attr_jid(_val, _acc) ->
     [{<<"jid">>, enc_jid(_val)} | _acc].
 
-decode_disco_item_attr_name(undefined) -> undefined;
-decode_disco_item_attr_name(_val) -> _val.
+decode_bytestreams_streamhost_attr_host(undefined) ->
+    erlang:error({missing_attr, <<"host">>,
+                 <<"streamhost">>,
+                 <<"http://jabber.org/protocol/bytestreams">>});
+decode_bytestreams_streamhost_attr_host(_val) -> _val.
 
-encode_disco_item_attr_name(undefined, _acc) -> _acc;
-encode_disco_item_attr_name(_val, _acc) ->
-    [{<<"name">>, _val} | _acc].
+encode_bytestreams_streamhost_attr_host(_val, _acc) ->
+    [{<<"host">>, _val} | _acc].
 
-decode_disco_item_attr_node(undefined) -> undefined;
-decode_disco_item_attr_node(_val) -> _val.
+decode_bytestreams_streamhost_attr_port(undefined) ->
+    1080;
+decode_bytestreams_streamhost_attr_port(_val) ->
+    case catch xml_gen:dec_int(_val, 0, 65535) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"port">>,
+                       <<"streamhost">>,
+                       <<"http://jabber.org/protocol/bytestreams">>});
+      _res -> _res
+    end.
 
-encode_disco_item_attr_node(undefined, _acc) -> _acc;
-encode_disco_item_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
-
-decode_disco_items({xmlel, <<"query">>, _attrs,
-                   _els}) ->
-    Items = decode_disco_items_els(_els, []),
-    Node = decode_disco_items_attrs(_attrs, undefined),
-    {disco_items, Node, Items}.
-
-decode_disco_items_els([], Items) ->
-    lists:reverse(Items);
-decode_disco_items_els([{xmlel, <<"item">>, _attrs, _} =
-                           _el
-                       | _els],
-                      Items) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns ==
-        <<"http://jabber.org/protocol/disco#items">> ->
-          decode_disco_items_els(_els,
-                                 case decode_disco_item(_el) of
-                                   undefined -> Items;
-                                   _new_el -> [_new_el | Items]
-                                 end);
-       true -> decode_disco_items_els(_els, Items)
-    end;
-decode_disco_items_els([_ | _els], Items) ->
-    decode_disco_items_els(_els, Items).
-
-decode_disco_items_attrs([{<<"node">>, _val} | _attrs],
-                        _Node) ->
-    decode_disco_items_attrs(_attrs, _val);
-decode_disco_items_attrs([_ | _attrs], Node) ->
-    decode_disco_items_attrs(_attrs, Node);
-decode_disco_items_attrs([], Node) ->
-    decode_disco_items_attr_node(Node).
-
-encode_disco_items({disco_items, Node, Items},
-                  _xmlns_attrs) ->
-    _els = 'encode_disco_items_$items'(Items, []),
-    _attrs = encode_disco_items_attr_node(Node,
-                                         _xmlns_attrs),
-    {xmlel, <<"query">>, _attrs, _els}.
-
-'encode_disco_items_$items'([], _acc) -> _acc;
-'encode_disco_items_$items'([Items | _els], _acc) ->
-    'encode_disco_items_$items'(_els,
-                               [encode_disco_item(Items, []) | _acc]).
-
-decode_disco_items_attr_node(undefined) -> undefined;
-decode_disco_items_attr_node(_val) -> _val.
+encode_bytestreams_streamhost_attr_port(1080, _acc) ->
+    _acc;
+encode_bytestreams_streamhost_attr_port(_val, _acc) ->
+    [{<<"port">>, xml_gen:enc_int(_val)} | _acc].
 
-encode_disco_items_attr_node(undefined, _acc) -> _acc;
-encode_disco_items_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
+decode_legacy_delay({xmlel, <<"x">>, _attrs, _els}) ->
+    {Stamp, From} = decode_legacy_delay_attrs(_attrs,
+                                             undefined, undefined),
+    {legacy_delay, Stamp, From}.
 
-decode_private({xmlel, <<"query">>, _attrs, _els}) ->
-    __Els = decode_private_els(_els, []), {private, __Els}.
+decode_legacy_delay_attrs([{<<"stamp">>, _val}
+                          | _attrs],
+                         _Stamp, From) ->
+    decode_legacy_delay_attrs(_attrs, _val, From);
+decode_legacy_delay_attrs([{<<"from">>, _val} | _attrs],
+                         Stamp, _From) ->
+    decode_legacy_delay_attrs(_attrs, Stamp, _val);
+decode_legacy_delay_attrs([_ | _attrs], Stamp, From) ->
+    decode_legacy_delay_attrs(_attrs, Stamp, From);
+decode_legacy_delay_attrs([], Stamp, From) ->
+    {decode_legacy_delay_attr_stamp(Stamp),
+     decode_legacy_delay_attr_from(From)}.
 
-decode_private_els([], __Els) -> lists:reverse(__Els);
-decode_private_els([{xmlel, _, _, _} = _el | _els],
-                  __Els) ->
-    decode_private_els(_els, [decode(_el) | __Els]);
-decode_private_els([_ | _els], __Els) ->
-    decode_private_els(_els, __Els).
+encode_legacy_delay({legacy_delay, Stamp, From},
+                   _xmlns_attrs) ->
+    _els = [],
+    _attrs = encode_legacy_delay_attr_from(From,
+                                          encode_legacy_delay_attr_stamp(Stamp,
+                                                                         _xmlns_attrs)),
+    {xmlel, <<"x">>, _attrs, _els}.
 
-encode_private({private, __Els}, _xmlns_attrs) ->
-    _els = [encode(_el) || _el <- __Els],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"query">>, _attrs, _els}.
+decode_legacy_delay_attr_stamp(undefined) ->
+    erlang:error({missing_attr, <<"stamp">>, <<"x">>,
+                 <<"jabber:x:delay">>});
+decode_legacy_delay_attr_stamp(_val) -> _val.
 
-decode_conference_nick({xmlel, <<"nick">>, _attrs,
-                       _els}) ->
-    Cdata = decode_conference_nick_els(_els, <<>>), Cdata.
+encode_legacy_delay_attr_stamp(_val, _acc) ->
+    [{<<"stamp">>, _val} | _acc].
 
-decode_conference_nick_els([], Cdata) ->
-    decode_conference_nick_cdata(Cdata);
-decode_conference_nick_els([{xmlcdata, _data} | _els],
-                          Cdata) ->
-    decode_conference_nick_els(_els,
-                              <<Cdata/binary, _data/binary>>);
-decode_conference_nick_els([_ | _els], Cdata) ->
-    decode_conference_nick_els(_els, Cdata).
+decode_legacy_delay_attr_from(undefined) -> undefined;
+decode_legacy_delay_attr_from(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"from">>, <<"x">>,
+                       <<"jabber:x:delay">>});
+      _res -> _res
+    end.
 
-encode_conference_nick(Cdata, _xmlns_attrs) ->
-    _els = encode_conference_nick_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"nick">>, _attrs, _els}.
+encode_legacy_delay_attr_from(undefined, _acc) -> _acc;
+encode_legacy_delay_attr_from(_val, _acc) ->
+    [{<<"from">>, enc_jid(_val)} | _acc].
 
-decode_conference_nick_cdata(<<>>) -> undefined;
-decode_conference_nick_cdata(_val) -> _val.
+decode_delay({xmlel, <<"delay">>, _attrs, _els}) ->
+    {Stamp, From} = decode_delay_attrs(_attrs, undefined,
+                                      undefined),
+    {delay, Stamp, From}.
 
-encode_conference_nick_cdata(undefined, _acc) -> _acc;
-encode_conference_nick_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_delay_attrs([{<<"stamp">>, _val} | _attrs],
+                  _Stamp, From) ->
+    decode_delay_attrs(_attrs, _val, From);
+decode_delay_attrs([{<<"from">>, _val} | _attrs], Stamp,
+                  _From) ->
+    decode_delay_attrs(_attrs, Stamp, _val);
+decode_delay_attrs([_ | _attrs], Stamp, From) ->
+    decode_delay_attrs(_attrs, Stamp, From);
+decode_delay_attrs([], Stamp, From) ->
+    {decode_delay_attr_stamp(Stamp),
+     decode_delay_attr_from(From)}.
 
-decode_conference_password({xmlel, <<"password">>,
-                           _attrs, _els}) ->
-    Cdata = decode_conference_password_els(_els, <<>>),
-    Cdata.
+encode_delay({delay, Stamp, From}, _xmlns_attrs) ->
+    _els = [],
+    _attrs = encode_delay_attr_from(From,
+                                   encode_delay_attr_stamp(Stamp,
+                                                           _xmlns_attrs)),
+    {xmlel, <<"delay">>, _attrs, _els}.
 
-decode_conference_password_els([], Cdata) ->
-    decode_conference_password_cdata(Cdata);
-decode_conference_password_els([{xmlcdata, _data}
-                               | _els],
-                              Cdata) ->
-    decode_conference_password_els(_els,
-                                  <<Cdata/binary, _data/binary>>);
-decode_conference_password_els([_ | _els], Cdata) ->
-    decode_conference_password_els(_els, Cdata).
+decode_delay_attr_stamp(undefined) ->
+    erlang:error({missing_attr, <<"stamp">>, <<"delay">>,
+                 <<"urn:xmpp:delay">>});
+decode_delay_attr_stamp(_val) ->
+    case catch dec_utc(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"stamp">>, <<"delay">>,
+                       <<"urn:xmpp:delay">>});
+      _res -> _res
+    end.
 
-encode_conference_password(Cdata, _xmlns_attrs) ->
-    _els = encode_conference_password_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"password">>, _attrs, _els}.
+encode_delay_attr_stamp(_val, _acc) ->
+    [{<<"stamp">>, enc_utc(_val)} | _acc].
 
-decode_conference_password_cdata(<<>>) -> undefined;
-decode_conference_password_cdata(_val) -> _val.
+decode_delay_attr_from(undefined) -> undefined;
+decode_delay_attr_from(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"from">>, <<"delay">>,
+                       <<"urn:xmpp:delay">>});
+      _res -> _res
+    end.
 
-encode_conference_password_cdata(undefined, _acc) ->
-    _acc;
-encode_conference_password_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_delay_attr_from(undefined, _acc) -> _acc;
+encode_delay_attr_from(_val, _acc) ->
+    [{<<"from">>, enc_jid(_val)} | _acc].
 
-decode_bookmark_conference({xmlel, <<"conference">>,
-                           _attrs, _els}) ->
-    {Password, Nick} = decode_bookmark_conference_els(_els,
-                                                     undefined, undefined),
-    {Name, Jid, Autojoin} =
-       decode_bookmark_conference_attrs(_attrs, undefined,
-                                        undefined, undefined),
-    {bookmark_conference, Name, Jid, Autojoin, Nick,
-     Password}.
+decode_pubsub({xmlel, <<"pubsub">>, _attrs, _els}) ->
+    {Affiliations, Subscriptions, Subscribe, Publish} =
+       decode_pubsub_els(_els, undefined, undefined, undefined,
+                         undefined),
+    {pubsub, Subscriptions, Affiliations, Publish,
+     Subscribe}.
 
-decode_bookmark_conference_els([], Password, Nick) ->
-    {Password, Nick};
-decode_bookmark_conference_els([{xmlel, <<"nick">>,
-                                _attrs, _} =
-                                   _el
-                               | _els],
-                              Password, Nick) ->
+decode_pubsub_els([], Affiliations, Subscriptions,
+                 Subscribe, Publish) ->
+    {Affiliations, Subscriptions, Subscribe, Publish};
+decode_pubsub_els([{xmlel, <<"subscriptions">>, _attrs,
+                   _} =
+                      _el
+                  | _els],
+                 Affiliations, Subscriptions, Subscribe, Publish) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"storage:bookmarks">> ->
-          decode_bookmark_conference_els(_els, Password,
-                                         decode_conference_nick(_el));
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
+          decode_pubsub_els(_els, Affiliations,
+                            decode_pubsub_subscriptions(_el), Subscribe,
+                            Publish);
        true ->
-          decode_bookmark_conference_els(_els, Password, Nick)
+          decode_pubsub_els(_els, Affiliations, Subscriptions,
+                            Subscribe, Publish)
     end;
-decode_bookmark_conference_els([{xmlel, <<"password">>,
-                                _attrs, _} =
-                                   _el
-                               | _els],
-                              Password, Nick) ->
+decode_pubsub_els([{xmlel, <<"affiliations">>, _attrs,
+                   _} =
+                      _el
+                  | _els],
+                 Affiliations, Subscriptions, Subscribe, Publish) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"storage:bookmarks">> ->
-          decode_bookmark_conference_els(_els,
-                                         decode_conference_password(_el),
-                                         Nick);
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
+          decode_pubsub_els(_els, decode_pubsub_affiliations(_el),
+                            Subscriptions, Subscribe, Publish);
        true ->
-          decode_bookmark_conference_els(_els, Password, Nick)
+          decode_pubsub_els(_els, Affiliations, Subscriptions,
+                            Subscribe, Publish)
     end;
-decode_bookmark_conference_els([_ | _els], Password,
-                              Nick) ->
-    decode_bookmark_conference_els(_els, Password, Nick).
-
-decode_bookmark_conference_attrs([{<<"name">>, _val}
-                                 | _attrs],
-                                _Name, Jid, Autojoin) ->
-    decode_bookmark_conference_attrs(_attrs, _val, Jid,
-                                    Autojoin);
-decode_bookmark_conference_attrs([{<<"jid">>, _val}
-                                 | _attrs],
-                                Name, _Jid, Autojoin) ->
-    decode_bookmark_conference_attrs(_attrs, Name, _val,
-                                    Autojoin);
-decode_bookmark_conference_attrs([{<<"autojoin">>, _val}
-                                 | _attrs],
-                                Name, Jid, _Autojoin) ->
-    decode_bookmark_conference_attrs(_attrs, Name, Jid,
-                                    _val);
-decode_bookmark_conference_attrs([_ | _attrs], Name,
-                                Jid, Autojoin) ->
-    decode_bookmark_conference_attrs(_attrs, Name, Jid,
-                                    Autojoin);
-decode_bookmark_conference_attrs([], Name, Jid,
-                                Autojoin) ->
-    {decode_bookmark_conference_attr_name(Name),
-     decode_bookmark_conference_attr_jid(Jid),
-     decode_bookmark_conference_attr_autojoin(Autojoin)}.
+decode_pubsub_els([{xmlel, <<"subscribe">>, _attrs, _} =
+                      _el
+                  | _els],
+                 Affiliations, Subscriptions, Subscribe, Publish) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
+          decode_pubsub_els(_els, Affiliations, Subscriptions,
+                            decode_pubsub_subscribe(_el), Publish);
+       true ->
+          decode_pubsub_els(_els, Affiliations, Subscriptions,
+                            Subscribe, Publish)
+    end;
+decode_pubsub_els([{xmlel, <<"publish">>, _attrs, _} =
+                      _el
+                  | _els],
+                 Affiliations, Subscriptions, Subscribe, Publish) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
+          decode_pubsub_els(_els, Affiliations, Subscriptions,
+                            Subscribe, decode_pubsub_publish(_el));
+       true ->
+          decode_pubsub_els(_els, Affiliations, Subscriptions,
+                            Subscribe, Publish)
+    end;
+decode_pubsub_els([_ | _els], Affiliations,
+                 Subscriptions, Subscribe, Publish) ->
+    decode_pubsub_els(_els, Affiliations, Subscriptions,
+                     Subscribe, Publish).
 
-encode_bookmark_conference({bookmark_conference, Name,
-                           Jid, Autojoin, Nick, Password},
-                          _xmlns_attrs) ->
-    _els = 'encode_bookmark_conference_$nick'(Nick,
-                                             'encode_bookmark_conference_$password'(Password,
-                                                                                    [])),
-    _attrs =
-       encode_bookmark_conference_attr_autojoin(Autojoin,
-                                                encode_bookmark_conference_attr_jid(Jid,
-                                                                                    encode_bookmark_conference_attr_name(Name,
-                                                                                                                         _xmlns_attrs))),
-    {xmlel, <<"conference">>, _attrs, _els}.
+encode_pubsub({pubsub, Subscriptions, Affiliations,
+              Publish, Subscribe},
+             _xmlns_attrs) ->
+    _els = 'encode_pubsub_$publish'(Publish,
+                                   'encode_pubsub_$subscribe'(Subscribe,
+                                                              'encode_pubsub_$subscriptions'(Subscriptions,
+                                                                                             'encode_pubsub_$affiliations'(Affiliations,
+                                                                                                                           [])))),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"pubsub">>, _attrs, _els}.
 
-'encode_bookmark_conference_$password'(undefined,
-                                      _acc) ->
-    _acc;
-'encode_bookmark_conference_$password'(Password,
-                                      _acc) ->
-    [encode_conference_password(Password, []) | _acc].
+'encode_pubsub_$affiliations'(undefined, _acc) -> _acc;
+'encode_pubsub_$affiliations'(Affiliations, _acc) ->
+    [encode_pubsub_affiliations(Affiliations, []) | _acc].
 
-'encode_bookmark_conference_$nick'(undefined, _acc) ->
-    _acc;
-'encode_bookmark_conference_$nick'(Nick, _acc) ->
-    [encode_conference_nick(Nick, []) | _acc].
+'encode_pubsub_$subscriptions'(undefined, _acc) -> _acc;
+'encode_pubsub_$subscriptions'(Subscriptions, _acc) ->
+    [encode_pubsub_subscriptions(Subscriptions, []) | _acc].
 
-decode_bookmark_conference_attr_name(undefined) ->
-    erlang:error({missing_attr, <<"name">>,
-                 <<"conference">>, <<"storage:bookmarks">>});
-decode_bookmark_conference_attr_name(_val) -> _val.
+'encode_pubsub_$subscribe'(undefined, _acc) -> _acc;
+'encode_pubsub_$subscribe'(Subscribe, _acc) ->
+    [encode_pubsub_subscribe(Subscribe, []) | _acc].
 
-encode_bookmark_conference_attr_name(_val, _acc) ->
-    [{<<"name">>, _val} | _acc].
+'encode_pubsub_$publish'(undefined, _acc) -> _acc;
+'encode_pubsub_$publish'(Publish, _acc) ->
+    [encode_pubsub_publish(Publish, []) | _acc].
 
-decode_bookmark_conference_attr_jid(undefined) ->
-    erlang:error({missing_attr, <<"jid">>, <<"conference">>,
-                 <<"storage:bookmarks">>});
-decode_bookmark_conference_attr_jid(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"jid">>,
-                       <<"conference">>, <<"storage:bookmarks">>});
-      _res -> _res
-    end.
+decode_pubsub_publish({xmlel, <<"publish">>, _attrs,
+                      _els}) ->
+    Items = decode_pubsub_publish_els(_els, []),
+    Node = decode_pubsub_publish_attrs(_attrs, undefined),
+    {Node, Items}.
 
-encode_bookmark_conference_attr_jid(_val, _acc) ->
-    [{<<"jid">>, enc_jid(_val)} | _acc].
+decode_pubsub_publish_els([], Items) ->
+    lists:reverse(Items);
+decode_pubsub_publish_els([{xmlel, <<"item">>, _attrs,
+                           _} =
+                              _el
+                          | _els],
+                         Items) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
+          decode_pubsub_publish_els(_els,
+                                    case decode_pubsub_item(_el) of
+                                      undefined -> Items;
+                                      _new_el -> [_new_el | Items]
+                                    end);
+       true -> decode_pubsub_publish_els(_els, Items)
+    end;
+decode_pubsub_publish_els([_ | _els], Items) ->
+    decode_pubsub_publish_els(_els, Items).
 
-decode_bookmark_conference_attr_autojoin(undefined) ->
-    false;
-decode_bookmark_conference_attr_autojoin(_val) ->
-    case catch dec_bool(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"autojoin">>,
-                       <<"conference">>, <<"storage:bookmarks">>});
-      _res -> _res
-    end.
+decode_pubsub_publish_attrs([{<<"node">>, _val}
+                            | _attrs],
+                           _Node) ->
+    decode_pubsub_publish_attrs(_attrs, _val);
+decode_pubsub_publish_attrs([_ | _attrs], Node) ->
+    decode_pubsub_publish_attrs(_attrs, Node);
+decode_pubsub_publish_attrs([], Node) ->
+    decode_pubsub_publish_attr_node(Node).
 
-encode_bookmark_conference_attr_autojoin(false, _acc) ->
-    _acc;
-encode_bookmark_conference_attr_autojoin(_val, _acc) ->
-    [{<<"autojoin">>, enc_bool(_val)} | _acc].
+encode_pubsub_publish({Node, Items}, _xmlns_attrs) ->
+    _els = 'encode_pubsub_publish_$items'(Items, []),
+    _attrs = encode_pubsub_publish_attr_node(Node,
+                                            _xmlns_attrs),
+    {xmlel, <<"publish">>, _attrs, _els}.
 
-decode_bookmark_url({xmlel, <<"url">>, _attrs, _els}) ->
-    {Name, Url} = decode_bookmark_url_attrs(_attrs,
-                                           undefined, undefined),
-    {bookmark_url, Name, Url}.
+'encode_pubsub_publish_$items'([], _acc) -> _acc;
+'encode_pubsub_publish_$items'([Items | _els], _acc) ->
+    'encode_pubsub_publish_$items'(_els,
+                                  [encode_pubsub_item(Items, []) | _acc]).
 
-decode_bookmark_url_attrs([{<<"name">>, _val} | _attrs],
-                         _Name, Url) ->
-    decode_bookmark_url_attrs(_attrs, _val, Url);
-decode_bookmark_url_attrs([{<<"url">>, _val} | _attrs],
-                         Name, _Url) ->
-    decode_bookmark_url_attrs(_attrs, Name, _val);
-decode_bookmark_url_attrs([_ | _attrs], Name, Url) ->
-    decode_bookmark_url_attrs(_attrs, Name, Url);
-decode_bookmark_url_attrs([], Name, Url) ->
-    {decode_bookmark_url_attr_name(Name),
-     decode_bookmark_url_attr_url(Url)}.
+decode_pubsub_publish_attr_node(undefined) ->
+    erlang:error({missing_attr, <<"node">>, <<"publish">>,
+                 <<"http://jabber.org/protocol/pubsub">>});
+decode_pubsub_publish_attr_node(_val) -> _val.
 
-encode_bookmark_url({bookmark_url, Name, Url},
-                   _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_bookmark_url_attr_url(Url,
-                                         encode_bookmark_url_attr_name(Name,
-                                                                       _xmlns_attrs)),
-    {xmlel, <<"url">>, _attrs, _els}.
+encode_pubsub_publish_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
-decode_bookmark_url_attr_name(undefined) ->
-    erlang:error({missing_attr, <<"name">>, <<"url">>,
-                 <<"storage:bookmarks">>});
-decode_bookmark_url_attr_name(_val) -> _val.
+decode_pubsub_subscribe({xmlel, <<"subscribe">>, _attrs,
+                        _els}) ->
+    {Node, Jid} = decode_pubsub_subscribe_attrs(_attrs,
+                                               undefined, undefined),
+    {Node, Jid}.
 
-encode_bookmark_url_attr_name(_val, _acc) ->
-    [{<<"name">>, _val} | _acc].
+decode_pubsub_subscribe_attrs([{<<"node">>, _val}
+                              | _attrs],
+                             _Node, Jid) ->
+    decode_pubsub_subscribe_attrs(_attrs, _val, Jid);
+decode_pubsub_subscribe_attrs([{<<"jid">>, _val}
+                              | _attrs],
+                             Node, _Jid) ->
+    decode_pubsub_subscribe_attrs(_attrs, Node, _val);
+decode_pubsub_subscribe_attrs([_ | _attrs], Node,
+                             Jid) ->
+    decode_pubsub_subscribe_attrs(_attrs, Node, Jid);
+decode_pubsub_subscribe_attrs([], Node, Jid) ->
+    {decode_pubsub_subscribe_attr_node(Node),
+     decode_pubsub_subscribe_attr_jid(Jid)}.
 
-decode_bookmark_url_attr_url(undefined) ->
-    erlang:error({missing_attr, <<"url">>, <<"url">>,
-                 <<"storage:bookmarks">>});
-decode_bookmark_url_attr_url(_val) -> _val.
+encode_pubsub_subscribe({Node, Jid}, _xmlns_attrs) ->
+    _els = [],
+    _attrs = encode_pubsub_subscribe_attr_jid(Jid,
+                                             encode_pubsub_subscribe_attr_node(Node,
+                                                                               _xmlns_attrs)),
+    {xmlel, <<"subscribe">>, _attrs, _els}.
 
-encode_bookmark_url_attr_url(_val, _acc) ->
-    [{<<"url">>, _val} | _acc].
+decode_pubsub_subscribe_attr_node(undefined) ->
+    undefined;
+decode_pubsub_subscribe_attr_node(_val) -> _val.
 
-decode_bookmarks_storage({xmlel, <<"storage">>, _attrs,
-                         _els}) ->
-    {Conference, Url} = decode_bookmarks_storage_els(_els,
-                                                    [], []),
-    {bookmark_storage, Conference, Url}.
+encode_pubsub_subscribe_attr_node(undefined, _acc) ->
+    _acc;
+encode_pubsub_subscribe_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
-decode_bookmarks_storage_els([], Conference, Url) ->
-    {lists:reverse(Conference), lists:reverse(Url)};
-decode_bookmarks_storage_els([{xmlel, <<"conference">>,
-                              _attrs, _} =
-                                 _el
-                             | _els],
-                            Conference, Url) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"storage:bookmarks">> ->
-          decode_bookmarks_storage_els(_els,
-                                       case decode_bookmark_conference(_el) of
-                                         undefined -> Conference;
-                                         _new_el -> [_new_el | Conference]
-                                       end,
-                                       Url);
-       true ->
-          decode_bookmarks_storage_els(_els, Conference, Url)
-    end;
-decode_bookmarks_storage_els([{xmlel, <<"url">>, _attrs,
-                              _} =
-                                 _el
-                             | _els],
-                            Conference, Url) ->
+decode_pubsub_subscribe_attr_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>, <<"subscribe">>,
+                 <<"http://jabber.org/protocol/pubsub">>});
+decode_pubsub_subscribe_attr_jid(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"jid">>,
+                       <<"subscribe">>,
+                       <<"http://jabber.org/protocol/pubsub">>});
+      _res -> _res
+    end.
+
+encode_pubsub_subscribe_attr_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
+
+decode_pubsub_affiliations({xmlel, <<"affiliations">>,
+                           _attrs, _els}) ->
+    Affiliations = decode_pubsub_affiliations_els(_els, []),
+    Affiliations.
+
+decode_pubsub_affiliations_els([], Affiliations) ->
+    lists:reverse(Affiliations);
+decode_pubsub_affiliations_els([{xmlel,
+                                <<"affiliation">>, _attrs, _} =
+                                   _el
+                               | _els],
+                              Affiliations) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"storage:bookmarks">> ->
-          decode_bookmarks_storage_els(_els, Conference,
-                                       case decode_bookmark_url(_el) of
-                                         undefined -> Url;
-                                         _new_el -> [_new_el | Url]
-                                       end);
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
+          decode_pubsub_affiliations_els(_els,
+                                         case decode_pubsub_affiliation(_el) of
+                                           undefined -> Affiliations;
+                                           _new_el -> [_new_el | Affiliations]
+                                         end);
        true ->
-          decode_bookmarks_storage_els(_els, Conference, Url)
+          decode_pubsub_affiliations_els(_els, Affiliations)
     end;
-decode_bookmarks_storage_els([_ | _els], Conference,
-                            Url) ->
-    decode_bookmarks_storage_els(_els, Conference, Url).
+decode_pubsub_affiliations_els([_ | _els],
+                              Affiliations) ->
+    decode_pubsub_affiliations_els(_els, Affiliations).
 
-encode_bookmarks_storage({bookmark_storage, Conference,
-                         Url},
-                        _xmlns_attrs) ->
-    _els = 'encode_bookmarks_storage_$url'(Url,
-                                          'encode_bookmarks_storage_$conference'(Conference,
-                                                                                 [])),
+encode_pubsub_affiliations(Affiliations,
+                          _xmlns_attrs) ->
+    _els =
+       'encode_pubsub_affiliations_$affiliations'(Affiliations,
+                                                  []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"storage">>, _attrs, _els}.
+    {xmlel, <<"affiliations">>, _attrs, _els}.
 
-'encode_bookmarks_storage_$conference'([], _acc) ->
+'encode_pubsub_affiliations_$affiliations'([], _acc) ->
     _acc;
-'encode_bookmarks_storage_$conference'([Conference
-                                       | _els],
-                                      _acc) ->
-    'encode_bookmarks_storage_$conference'(_els,
-                                          [encode_bookmark_conference(Conference,
-                                                                      [])
-                                           | _acc]).
-
-'encode_bookmarks_storage_$url'([], _acc) -> _acc;
-'encode_bookmarks_storage_$url'([Url | _els], _acc) ->
-    'encode_bookmarks_storage_$url'(_els,
-                                   [encode_bookmark_url(Url, []) | _acc]).
-
-decode_stat_error({xmlel, <<"error">>, _attrs, _els}) ->
-    Cdata = decode_stat_error_els(_els, <<>>),
-    Code = decode_stat_error_attrs(_attrs, undefined),
-    {Code, Cdata}.
+'encode_pubsub_affiliations_$affiliations'([Affiliations
+                                           | _els],
+                                          _acc) ->
+    'encode_pubsub_affiliations_$affiliations'(_els,
+                                              [encode_pubsub_affiliation(Affiliations,
+                                                                         [])
+                                               | _acc]).
 
-decode_stat_error_els([], Cdata) ->
-    decode_stat_error_cdata(Cdata);
-decode_stat_error_els([{xmlcdata, _data} | _els],
-                     Cdata) ->
-    decode_stat_error_els(_els,
-                         <<Cdata/binary, _data/binary>>);
-decode_stat_error_els([_ | _els], Cdata) ->
-    decode_stat_error_els(_els, Cdata).
+decode_pubsub_subscriptions({xmlel, <<"subscriptions">>,
+                            _attrs, _els}) ->
+    Subscriptions = decode_pubsub_subscriptions_els(_els,
+                                                   []),
+    Node = decode_pubsub_subscriptions_attrs(_attrs,
+                                            undefined),
+    {Node, Subscriptions}.
 
-decode_stat_error_attrs([{<<"code">>, _val} | _attrs],
-                       _Code) ->
-    decode_stat_error_attrs(_attrs, _val);
-decode_stat_error_attrs([_ | _attrs], Code) ->
-    decode_stat_error_attrs(_attrs, Code);
-decode_stat_error_attrs([], Code) ->
-    decode_stat_error_attr_code(Code).
+decode_pubsub_subscriptions_els([], Subscriptions) ->
+    lists:reverse(Subscriptions);
+decode_pubsub_subscriptions_els([{xmlel,
+                                 <<"subscription">>, _attrs, _} =
+                                    _el
+                                | _els],
+                               Subscriptions) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
+          decode_pubsub_subscriptions_els(_els,
+                                          case decode_pubsub_subscription(_el)
+                                              of
+                                            undefined -> Subscriptions;
+                                            _new_el ->
+                                                [_new_el | Subscriptions]
+                                          end);
+       true ->
+          decode_pubsub_subscriptions_els(_els, Subscriptions)
+    end;
+decode_pubsub_subscriptions_els([_ | _els],
+                               Subscriptions) ->
+    decode_pubsub_subscriptions_els(_els, Subscriptions).
 
-encode_stat_error({Code, Cdata}, _xmlns_attrs) ->
-    _els = encode_stat_error_cdata(Cdata, []),
-    _attrs = encode_stat_error_attr_code(Code,
-                                        _xmlns_attrs),
-    {xmlel, <<"error">>, _attrs, _els}.
+decode_pubsub_subscriptions_attrs([{<<"node">>, _val}
+                                  | _attrs],
+                                 _Node) ->
+    decode_pubsub_subscriptions_attrs(_attrs, _val);
+decode_pubsub_subscriptions_attrs([_ | _attrs], Node) ->
+    decode_pubsub_subscriptions_attrs(_attrs, Node);
+decode_pubsub_subscriptions_attrs([], Node) ->
+    decode_pubsub_subscriptions_attr_node(Node).
 
-decode_stat_error_attr_code(undefined) ->
-    erlang:error({missing_attr, <<"code">>, <<"error">>,
-                 <<"http://jabber.org/protocol/stats">>});
-decode_stat_error_attr_code(_val) ->
-    case catch xml_gen:dec_int(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"code">>, <<"error">>,
-                       <<"http://jabber.org/protocol/stats">>});
-      _res -> _res
-    end.
+encode_pubsub_subscriptions({Node, Subscriptions},
+                           _xmlns_attrs) ->
+    _els =
+       'encode_pubsub_subscriptions_$subscriptions'(Subscriptions,
+                                                    []),
+    _attrs = encode_pubsub_subscriptions_attr_node(Node,
+                                                  _xmlns_attrs),
+    {xmlel, <<"subscriptions">>, _attrs, _els}.
 
-encode_stat_error_attr_code(_val, _acc) ->
-    [{<<"code">>, xml_gen:enc_int(_val)} | _acc].
+'encode_pubsub_subscriptions_$subscriptions'([],
+                                            _acc) ->
+    _acc;
+'encode_pubsub_subscriptions_$subscriptions'([Subscriptions
+                                             | _els],
+                                            _acc) ->
+    'encode_pubsub_subscriptions_$subscriptions'(_els,
+                                                [encode_pubsub_subscription(Subscriptions,
+                                                                            [])
+                                                 | _acc]).
 
-decode_stat_error_cdata(<<>>) -> undefined;
-decode_stat_error_cdata(_val) -> _val.
+decode_pubsub_subscriptions_attr_node(undefined) ->
+    none;
+decode_pubsub_subscriptions_attr_node(_val) -> _val.
 
-encode_stat_error_cdata(undefined, _acc) -> _acc;
-encode_stat_error_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_pubsub_subscriptions_attr_node(none, _acc) ->
+    _acc;
+encode_pubsub_subscriptions_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
-decode_stat({xmlel, <<"stat">>, _attrs, _els}) ->
-    Error = decode_stat_els(_els, []),
-    {Name, Units, Value} = decode_stat_attrs(_attrs,
-                                            undefined, undefined, undefined),
-    {stat, Name, Units, Value, Error}.
+decode_pubsub_event({xmlel, <<"event">>, _attrs,
+                    _els}) ->
+    Items = decode_pubsub_event_els(_els, []),
+    {pubsub_event, Items}.
 
-decode_stat_els([], Error) -> lists:reverse(Error);
-decode_stat_els([{xmlel, <<"error">>, _attrs, _} = _el
-                | _els],
-               Error) ->
+decode_pubsub_event_els([], Items) ->
+    lists:reverse(Items);
+decode_pubsub_event_els([{xmlel, <<"items">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Items) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
     if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/stats">> ->
-          decode_stat_els(_els,
-                          case decode_stat_error(_el) of
-                            undefined -> Error;
-                            _new_el -> [_new_el | Error]
-                          end);
-       true -> decode_stat_els(_els, Error)
+       _xmlns ==
+        <<"http://jabber.org/protocol/pubsub#event">> ->
+          decode_pubsub_event_els(_els,
+                                  case decode_pubsub_event_items(_el) of
+                                    undefined -> Items;
+                                    _new_el -> [_new_el | Items]
+                                  end);
+       true -> decode_pubsub_event_els(_els, Items)
     end;
-decode_stat_els([_ | _els], Error) ->
-    decode_stat_els(_els, Error).
+decode_pubsub_event_els([_ | _els], Items) ->
+    decode_pubsub_event_els(_els, Items).
 
-decode_stat_attrs([{<<"name">>, _val} | _attrs], _Name,
-                 Units, Value) ->
-    decode_stat_attrs(_attrs, _val, Units, Value);
-decode_stat_attrs([{<<"units">>, _val} | _attrs], Name,
-                 _Units, Value) ->
-    decode_stat_attrs(_attrs, Name, _val, Value);
-decode_stat_attrs([{<<"value">>, _val} | _attrs], Name,
-                 Units, _Value) ->
-    decode_stat_attrs(_attrs, Name, Units, _val);
-decode_stat_attrs([_ | _attrs], Name, Units, Value) ->
-    decode_stat_attrs(_attrs, Name, Units, Value);
-decode_stat_attrs([], Name, Units, Value) ->
-    {decode_stat_attr_name(Name),
-     decode_stat_attr_units(Units),
-     decode_stat_attr_value(Value)}.
-
-encode_stat({stat, Name, Units, Value, Error},
-           _xmlns_attrs) ->
-    _els = 'encode_stat_$error'(Error, []),
-    _attrs = encode_stat_attr_value(Value,
-                                   encode_stat_attr_units(Units,
-                                                          encode_stat_attr_name(Name,
-                                                                                _xmlns_attrs))),
-    {xmlel, <<"stat">>, _attrs, _els}.
-
-'encode_stat_$error'([], _acc) -> _acc;
-'encode_stat_$error'([Error | _els], _acc) ->
-    'encode_stat_$error'(_els,
-                        [encode_stat_error(Error, []) | _acc]).
-
-decode_stat_attr_name(undefined) ->
-    erlang:error({missing_attr, <<"name">>, <<"stat">>,
-                 <<"http://jabber.org/protocol/stats">>});
-decode_stat_attr_name(_val) -> _val.
-
-encode_stat_attr_name(_val, _acc) ->
-    [{<<"name">>, _val} | _acc].
-
-decode_stat_attr_units(undefined) -> undefined;
-decode_stat_attr_units(_val) -> _val.
-
-encode_stat_attr_units(undefined, _acc) -> _acc;
-encode_stat_attr_units(_val, _acc) ->
-    [{<<"units">>, _val} | _acc].
-
-decode_stat_attr_value(undefined) -> undefined;
-decode_stat_attr_value(_val) -> _val.
+encode_pubsub_event({pubsub_event, Items},
+                   _xmlns_attrs) ->
+    _els = 'encode_pubsub_event_$items'(Items, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"event">>, _attrs, _els}.
 
-encode_stat_attr_value(undefined, _acc) -> _acc;
-encode_stat_attr_value(_val, _acc) ->
-    [{<<"value">>, _val} | _acc].
+'encode_pubsub_event_$items'([], _acc) -> _acc;
+'encode_pubsub_event_$items'([Items | _els], _acc) ->
+    'encode_pubsub_event_$items'(_els,
+                                [encode_pubsub_event_items(Items, []) | _acc]).
 
-decode_stats({xmlel, <<"query">>, _attrs, _els}) ->
-    Stat = decode_stats_els(_els, []), {stats, Stat}.
+decode_pubsub_event_items({xmlel, <<"items">>, _attrs,
+                          _els}) ->
+    {Items, Retract} = decode_pubsub_event_items_els(_els,
+                                                    [], []),
+    Node = decode_pubsub_event_items_attrs(_attrs,
+                                          undefined),
+    {pubsub_event_items, Node, Retract, Items}.
 
-decode_stats_els([], Stat) -> lists:reverse(Stat);
-decode_stats_els([{xmlel, <<"stat">>, _attrs, _} = _el
-                 | _els],
-                Stat) ->
+decode_pubsub_event_items_els([], Items, Retract) ->
+    {lists:reverse(Items), lists:reverse(Retract)};
+decode_pubsub_event_items_els([{xmlel, <<"retract">>,
+                               _attrs, _} =
+                                  _el
+                              | _els],
+                             Items, Retract) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
     if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/stats">> ->
-          decode_stats_els(_els,
-                           case decode_stat(_el) of
-                             undefined -> Stat;
-                             _new_el -> [_new_el | Stat]
-                           end);
-       true -> decode_stats_els(_els, Stat)
+       _xmlns ==
+        <<"http://jabber.org/protocol/pubsub#event">> ->
+          decode_pubsub_event_items_els(_els, Items,
+                                        case decode_pubsub_event_retract(_el)
+                                            of
+                                          undefined -> Retract;
+                                          _new_el -> [_new_el | Retract]
+                                        end);
+       true ->
+          decode_pubsub_event_items_els(_els, Items, Retract)
     end;
-decode_stats_els([_ | _els], Stat) ->
-    decode_stats_els(_els, Stat).
-
-encode_stats({stats, Stat}, _xmlns_attrs) ->
-    _els = 'encode_stats_$stat'(Stat, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"query">>, _attrs, _els}.
-
-'encode_stats_$stat'([], _acc) -> _acc;
-'encode_stats_$stat'([Stat | _els], _acc) ->
-    'encode_stats_$stat'(_els,
-                        [encode_stat(Stat, []) | _acc]).
-
-decode_iq({xmlel, <<"iq">>, _attrs, _els}) ->
-    {Error, __Els} = decode_iq_els(_els, undefined, []),
-    {Id, Type, From, To, Lang} = decode_iq_attrs(_attrs,
-                                                undefined, undefined,
-                                                undefined, undefined,
-                                                undefined),
-    {iq, Id, Type, Lang, From, To, Error, __Els}.
-
-decode_iq_els([], Error, __Els) ->
-    {Error, lists:reverse(__Els)};
-decode_iq_els([{xmlel, <<"error">>, _attrs, _} = _el
-              | _els],
-             Error, __Els) ->
+decode_pubsub_event_items_els([{xmlel, <<"item">>,
+                               _attrs, _} =
+                                  _el
+                              | _els],
+                             Items, Retract) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
-          decode_iq_els(_els, decode_error(_el), __Els);
-       true -> decode_iq_els(_els, Error, __Els)
+    if _xmlns == <<>>;
+       _xmlns ==
+        <<"http://jabber.org/protocol/pubsub#event">> ->
+          decode_pubsub_event_items_els(_els,
+                                        case decode_pubsub_event_item(_el) of
+                                          undefined -> Items;
+                                          _new_el -> [_new_el | Items]
+                                        end,
+                                        Retract);
+       true ->
+          decode_pubsub_event_items_els(_els, Items, Retract)
     end;
-decode_iq_els([{xmlel, _, _, _} = _el | _els], Error,
-             __Els) ->
-    decode_iq_els(_els, Error, [decode(_el) | __Els]);
-decode_iq_els([_ | _els], Error, __Els) ->
-    decode_iq_els(_els, Error, __Els).
-
-decode_iq_attrs([{<<"id">>, _val} | _attrs], _Id, Type,
-               From, To, Lang) ->
-    decode_iq_attrs(_attrs, _val, Type, From, To, Lang);
-decode_iq_attrs([{<<"type">>, _val} | _attrs], Id,
-               _Type, From, To, Lang) ->
-    decode_iq_attrs(_attrs, Id, _val, From, To, Lang);
-decode_iq_attrs([{<<"from">>, _val} | _attrs], Id, Type,
-               _From, To, Lang) ->
-    decode_iq_attrs(_attrs, Id, Type, _val, To, Lang);
-decode_iq_attrs([{<<"to">>, _val} | _attrs], Id, Type,
-               From, _To, Lang) ->
-    decode_iq_attrs(_attrs, Id, Type, From, _val, Lang);
-decode_iq_attrs([{<<"xml:lang">>, _val} | _attrs], Id,
-               Type, From, To, _Lang) ->
-    decode_iq_attrs(_attrs, Id, Type, From, To, _val);
-decode_iq_attrs([_ | _attrs], Id, Type, From, To,
-               Lang) ->
-    decode_iq_attrs(_attrs, Id, Type, From, To, Lang);
-decode_iq_attrs([], Id, Type, From, To, Lang) ->
-    {decode_iq_attr_id(Id), decode_iq_attr_type(Type),
-     decode_iq_attr_from(From), decode_iq_attr_to(To),
-     'decode_iq_attr_xml:lang'(Lang)}.
-
-encode_iq({iq, Id, Type, Lang, From, To, Error, __Els},
-         _xmlns_attrs) ->
-    _els = 'encode_iq_$error'(Error,
-                             [encode(_el) || _el <- __Els]),
-    _attrs = 'encode_iq_attr_xml:lang'(Lang,
-                                      encode_iq_attr_to(To,
-                                                        encode_iq_attr_from(From,
-                                                                            encode_iq_attr_type(Type,
-                                                                                                encode_iq_attr_id(Id,
-                                                                                                                  _xmlns_attrs))))),
-    {xmlel, <<"iq">>, _attrs, _els}.
+decode_pubsub_event_items_els([_ | _els], Items,
+                             Retract) ->
+    decode_pubsub_event_items_els(_els, Items, Retract).
 
-'encode_iq_$error'(undefined, _acc) -> _acc;
-'encode_iq_$error'(Error, _acc) ->
-    [encode_error(Error, []) | _acc].
+decode_pubsub_event_items_attrs([{<<"node">>, _val}
+                                | _attrs],
+                               _Node) ->
+    decode_pubsub_event_items_attrs(_attrs, _val);
+decode_pubsub_event_items_attrs([_ | _attrs], Node) ->
+    decode_pubsub_event_items_attrs(_attrs, Node);
+decode_pubsub_event_items_attrs([], Node) ->
+    decode_pubsub_event_items_attr_node(Node).
 
-decode_iq_attr_id(undefined) ->
-    erlang:error({missing_attr, <<"id">>, <<"iq">>,
-                 <<"jabber:client">>});
-decode_iq_attr_id(_val) -> _val.
+encode_pubsub_event_items({pubsub_event_items, Node,
+                          Retract, Items},
+                         _xmlns_attrs) ->
+    _els = 'encode_pubsub_event_items_$retract'(Retract,
+                                               'encode_pubsub_event_items_$items'(Items,
+                                                                                  [])),
+    _attrs = encode_pubsub_event_items_attr_node(Node,
+                                                _xmlns_attrs),
+    {xmlel, <<"items">>, _attrs, _els}.
 
-encode_iq_attr_id(_val, _acc) ->
-    [{<<"id">>, _val} | _acc].
+'encode_pubsub_event_items_$items'([], _acc) -> _acc;
+'encode_pubsub_event_items_$items'([Items | _els],
+                                  _acc) ->
+    'encode_pubsub_event_items_$items'(_els,
+                                      [encode_pubsub_event_item(Items, [])
+                                       | _acc]).
 
-decode_iq_attr_type(undefined) ->
-    erlang:error({missing_attr, <<"type">>, <<"iq">>,
-                 <<"jabber:client">>});
-decode_iq_attr_type(_val) ->
-    case catch xml_gen:dec_enum(_val,
-                               [get, set, result, error])
-       of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"type">>, <<"iq">>,
-                       <<"jabber:client">>});
-      _res -> _res
-    end.
+'encode_pubsub_event_items_$retract'([], _acc) -> _acc;
+'encode_pubsub_event_items_$retract'([Retract | _els],
+                                    _acc) ->
+    'encode_pubsub_event_items_$retract'(_els,
+                                        [encode_pubsub_event_retract(Retract,
+                                                                     [])
+                                         | _acc]).
 
-encode_iq_attr_type(_val, _acc) ->
-    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
+decode_pubsub_event_items_attr_node(undefined) ->
+    erlang:error({missing_attr, <<"node">>, <<"items">>,
+                 <<"http://jabber.org/protocol/pubsub#event">>});
+decode_pubsub_event_items_attr_node(_val) -> _val.
 
-decode_iq_attr_from(undefined) -> undefined;
-decode_iq_attr_from(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"from">>, <<"iq">>,
-                       <<"jabber:client">>});
-      _res -> _res
-    end.
+encode_pubsub_event_items_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
-encode_iq_attr_from(undefined, _acc) -> _acc;
-encode_iq_attr_from(_val, _acc) ->
-    [{<<"from">>, enc_jid(_val)} | _acc].
+decode_pubsub_event_item({xmlel, <<"item">>, _attrs,
+                         _els}) ->
+    {Id, Node, Publisher} =
+       decode_pubsub_event_item_attrs(_attrs, undefined,
+                                      undefined, undefined),
+    {pubsub_event_item, Id, Node, Publisher}.
 
-decode_iq_attr_to(undefined) -> undefined;
-decode_iq_attr_to(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"to">>, <<"iq">>,
-                       <<"jabber:client">>});
-      _res -> _res
-    end.
-
-encode_iq_attr_to(undefined, _acc) -> _acc;
-encode_iq_attr_to(_val, _acc) ->
-    [{<<"to">>, enc_jid(_val)} | _acc].
-
-'decode_iq_attr_xml:lang'(undefined) -> undefined;
-'decode_iq_attr_xml:lang'(_val) -> _val.
+decode_pubsub_event_item_attrs([{<<"id">>, _val}
+                               | _attrs],
+                              _Id, Node, Publisher) ->
+    decode_pubsub_event_item_attrs(_attrs, _val, Node,
+                                  Publisher);
+decode_pubsub_event_item_attrs([{<<"node">>, _val}
+                               | _attrs],
+                              Id, _Node, Publisher) ->
+    decode_pubsub_event_item_attrs(_attrs, Id, _val,
+                                  Publisher);
+decode_pubsub_event_item_attrs([{<<"publisher">>, _val}
+                               | _attrs],
+                              Id, Node, _Publisher) ->
+    decode_pubsub_event_item_attrs(_attrs, Id, Node, _val);
+decode_pubsub_event_item_attrs([_ | _attrs], Id, Node,
+                              Publisher) ->
+    decode_pubsub_event_item_attrs(_attrs, Id, Node,
+                                  Publisher);
+decode_pubsub_event_item_attrs([], Id, Node,
+                              Publisher) ->
+    {decode_pubsub_event_item_attr_id(Id),
+     decode_pubsub_event_item_attr_node(Node),
+     decode_pubsub_event_item_attr_publisher(Publisher)}.
 
-'encode_iq_attr_xml:lang'(undefined, _acc) -> _acc;
-'encode_iq_attr_xml:lang'(_val, _acc) ->
-    [{<<"xml:lang">>, _val} | _acc].
+encode_pubsub_event_item({pubsub_event_item, Id, Node,
+                         Publisher},
+                        _xmlns_attrs) ->
+    _els = [],
+    _attrs =
+       encode_pubsub_event_item_attr_publisher(Publisher,
+                                               encode_pubsub_event_item_attr_node(Node,
+                                                                                  encode_pubsub_event_item_attr_id(Id,
+                                                                                                                   _xmlns_attrs))),
+    {xmlel, <<"item">>, _attrs, _els}.
 
-decode_message_subject({xmlel, <<"subject">>, _attrs,
-                       _els}) ->
-    Data = decode_message_subject_els(_els, <<>>),
-    Lang = decode_message_subject_attrs(_attrs, undefined),
-    {text, Lang, Data}.
+decode_pubsub_event_item_attr_id(undefined) ->
+    undefined;
+decode_pubsub_event_item_attr_id(_val) -> _val.
 
-decode_message_subject_els([], Data) ->
-    decode_message_subject_cdata(Data);
-decode_message_subject_els([{xmlcdata, _data} | _els],
-                          Data) ->
-    decode_message_subject_els(_els,
-                              <<Data/binary, _data/binary>>);
-decode_message_subject_els([_ | _els], Data) ->
-    decode_message_subject_els(_els, Data).
+encode_pubsub_event_item_attr_id(undefined, _acc) ->
+    _acc;
+encode_pubsub_event_item_attr_id(_val, _acc) ->
+    [{<<"id">>, _val} | _acc].
 
-decode_message_subject_attrs([{<<"xml:lang">>, _val}
-                             | _attrs],
-                            _Lang) ->
-    decode_message_subject_attrs(_attrs, _val);
-decode_message_subject_attrs([_ | _attrs], Lang) ->
-    decode_message_subject_attrs(_attrs, Lang);
-decode_message_subject_attrs([], Lang) ->
-    'decode_message_subject_attr_xml:lang'(Lang).
+decode_pubsub_event_item_attr_node(undefined) ->
+    undefined;
+decode_pubsub_event_item_attr_node(_val) -> _val.
 
-encode_message_subject({text, Lang, Data},
-                      _xmlns_attrs) ->
-    _els = encode_message_subject_cdata(Data, []),
-    _attrs = 'encode_message_subject_attr_xml:lang'(Lang,
-                                                   _xmlns_attrs),
-    {xmlel, <<"subject">>, _attrs, _els}.
+encode_pubsub_event_item_attr_node(undefined, _acc) ->
+    _acc;
+encode_pubsub_event_item_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
-'decode_message_subject_attr_xml:lang'(undefined) ->
+decode_pubsub_event_item_attr_publisher(undefined) ->
     undefined;
-'decode_message_subject_attr_xml:lang'(_val) -> _val.
+decode_pubsub_event_item_attr_publisher(_val) -> _val.
 
-'encode_message_subject_attr_xml:lang'(undefined,
-                                      _acc) ->
+encode_pubsub_event_item_attr_publisher(undefined,
+                                       _acc) ->
     _acc;
-'encode_message_subject_attr_xml:lang'(_val, _acc) ->
-    [{<<"xml:lang">>, _val} | _acc].
+encode_pubsub_event_item_attr_publisher(_val, _acc) ->
+    [{<<"publisher">>, _val} | _acc].
 
-decode_message_subject_cdata(<<>>) -> undefined;
-decode_message_subject_cdata(_val) -> _val.
+decode_pubsub_event_retract({xmlel, <<"retract">>,
+                            _attrs, _els}) ->
+    Id = decode_pubsub_event_retract_attrs(_attrs,
+                                          undefined),
+    Id.
 
-encode_message_subject_cdata(undefined, _acc) -> _acc;
-encode_message_subject_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_pubsub_event_retract_attrs([{<<"id">>, _val}
+                                  | _attrs],
+                                 _Id) ->
+    decode_pubsub_event_retract_attrs(_attrs, _val);
+decode_pubsub_event_retract_attrs([_ | _attrs], Id) ->
+    decode_pubsub_event_retract_attrs(_attrs, Id);
+decode_pubsub_event_retract_attrs([], Id) ->
+    decode_pubsub_event_retract_attr_id(Id).
 
-decode_message_body({xmlel, <<"body">>, _attrs,
+encode_pubsub_event_retract(Id, _xmlns_attrs) ->
+    _els = [],
+    _attrs = encode_pubsub_event_retract_attr_id(Id,
+                                                _xmlns_attrs),
+    {xmlel, <<"retract">>, _attrs, _els}.
+
+decode_pubsub_event_retract_attr_id(undefined) ->
+    erlang:error({missing_attr, <<"id">>, <<"retract">>,
+                 <<"http://jabber.org/protocol/pubsub#event">>});
+decode_pubsub_event_retract_attr_id(_val) -> _val.
+
+encode_pubsub_event_retract_attr_id(_val, _acc) ->
+    [{<<"id">>, _val} | _acc].
+
+decode_pubsub_items({xmlel, <<"items">>, _attrs,
                     _els}) ->
-    Data = decode_message_body_els(_els, <<>>),
-    Lang = decode_message_body_attrs(_attrs, undefined),
-    {text, Lang, Data}.
+    Items = decode_pubsub_items_els(_els, []),
+    {Max_items, Node, Subid} =
+       decode_pubsub_items_attrs(_attrs, undefined, undefined,
+                                 undefined),
+    {pubsub_items, Node, Max_items, Subid, Items}.
 
-decode_message_body_els([], Data) ->
-    decode_message_body_cdata(Data);
-decode_message_body_els([{xmlcdata, _data} | _els],
-                       Data) ->
-    decode_message_body_els(_els,
-                           <<Data/binary, _data/binary>>);
-decode_message_body_els([_ | _els], Data) ->
-    decode_message_body_els(_els, Data).
+decode_pubsub_items_els([], Items) ->
+    lists:reverse(Items);
+decode_pubsub_items_els([{xmlel, <<"item">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Items) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
+          decode_pubsub_items_els(_els,
+                                  case decode_pubsub_item(_el) of
+                                    undefined -> Items;
+                                    _new_el -> [_new_el | Items]
+                                  end);
+       true -> decode_pubsub_items_els(_els, Items)
+    end;
+decode_pubsub_items_els([_ | _els], Items) ->
+    decode_pubsub_items_els(_els, Items).
 
-decode_message_body_attrs([{<<"xml:lang">>, _val}
+decode_pubsub_items_attrs([{<<"max_items">>, _val}
                           | _attrs],
-                         _Lang) ->
-    decode_message_body_attrs(_attrs, _val);
-decode_message_body_attrs([_ | _attrs], Lang) ->
-    decode_message_body_attrs(_attrs, Lang);
-decode_message_body_attrs([], Lang) ->
-    'decode_message_body_attr_xml:lang'(Lang).
+                         _Max_items, Node, Subid) ->
+    decode_pubsub_items_attrs(_attrs, _val, Node, Subid);
+decode_pubsub_items_attrs([{<<"node">>, _val} | _attrs],
+                         Max_items, _Node, Subid) ->
+    decode_pubsub_items_attrs(_attrs, Max_items, _val,
+                             Subid);
+decode_pubsub_items_attrs([{<<"subid">>, _val}
+                          | _attrs],
+                         Max_items, Node, _Subid) ->
+    decode_pubsub_items_attrs(_attrs, Max_items, Node,
+                             _val);
+decode_pubsub_items_attrs([_ | _attrs], Max_items, Node,
+                         Subid) ->
+    decode_pubsub_items_attrs(_attrs, Max_items, Node,
+                             Subid);
+decode_pubsub_items_attrs([], Max_items, Node, Subid) ->
+    {decode_pubsub_items_attr_max_items(Max_items),
+     decode_pubsub_items_attr_node(Node),
+     decode_pubsub_items_attr_subid(Subid)}.
 
-encode_message_body({text, Lang, Data}, _xmlns_attrs) ->
-    _els = encode_message_body_cdata(Data, []),
-    _attrs = 'encode_message_body_attr_xml:lang'(Lang,
-                                                _xmlns_attrs),
-    {xmlel, <<"body">>, _attrs, _els}.
+encode_pubsub_items({pubsub_items, Node, Max_items,
+                    Subid, Items},
+                   _xmlns_attrs) ->
+    _els = 'encode_pubsub_items_$items'(Items, []),
+    _attrs = encode_pubsub_items_attr_subid(Subid,
+                                           encode_pubsub_items_attr_node(Node,
+                                                                         encode_pubsub_items_attr_max_items(Max_items,
+                                                                                                            _xmlns_attrs))),
+    {xmlel, <<"items">>, _attrs, _els}.
 
-'decode_message_body_attr_xml:lang'(undefined) ->
+'encode_pubsub_items_$items'([], _acc) -> _acc;
+'encode_pubsub_items_$items'([Items | _els], _acc) ->
+    'encode_pubsub_items_$items'(_els,
+                                [encode_pubsub_item(Items, []) | _acc]).
+
+decode_pubsub_items_attr_max_items(undefined) ->
     undefined;
-'decode_message_body_attr_xml:lang'(_val) -> _val.
+decode_pubsub_items_attr_max_items(_val) ->
+    case catch xml_gen:dec_int(_val, 0, infinity) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"max_items">>,
+                       <<"items">>, <<"http://jabber.org/protocol/pubsub">>});
+      _res -> _res
+    end.
 
-'encode_message_body_attr_xml:lang'(undefined, _acc) ->
+encode_pubsub_items_attr_max_items(undefined, _acc) ->
     _acc;
-'encode_message_body_attr_xml:lang'(_val, _acc) ->
-    [{<<"xml:lang">>, _val} | _acc].
+encode_pubsub_items_attr_max_items(_val, _acc) ->
+    [{<<"max_items">>, xml_gen:enc_int(_val)} | _acc].
 
-decode_message_body_cdata(<<>>) -> undefined;
-decode_message_body_cdata(_val) -> _val.
+decode_pubsub_items_attr_node(undefined) ->
+    erlang:error({missing_attr, <<"node">>, <<"items">>,
+                 <<"http://jabber.org/protocol/pubsub">>});
+decode_pubsub_items_attr_node(_val) -> _val.
 
-encode_message_body_cdata(undefined, _acc) -> _acc;
-encode_message_body_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_pubsub_items_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
-decode_message_thread({xmlel, <<"thread">>, _attrs,
-                      _els}) ->
-    Cdata = decode_message_thread_els(_els, <<>>), Cdata.
+decode_pubsub_items_attr_subid(undefined) -> undefined;
+decode_pubsub_items_attr_subid(_val) -> _val.
 
-decode_message_thread_els([], Cdata) ->
-    decode_message_thread_cdata(Cdata);
-decode_message_thread_els([{xmlcdata, _data} | _els],
-                         Cdata) ->
-    decode_message_thread_els(_els,
-                             <<Cdata/binary, _data/binary>>);
-decode_message_thread_els([_ | _els], Cdata) ->
-    decode_message_thread_els(_els, Cdata).
+encode_pubsub_items_attr_subid(undefined, _acc) -> _acc;
+encode_pubsub_items_attr_subid(_val, _acc) ->
+    [{<<"subid">>, _val} | _acc].
 
-encode_message_thread(Cdata, _xmlns_attrs) ->
-    _els = encode_message_thread_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"thread">>, _attrs, _els}.
-
-decode_message_thread_cdata(<<>>) -> undefined;
-decode_message_thread_cdata(_val) -> _val.
-
-encode_message_thread_cdata(undefined, _acc) -> _acc;
-encode_message_thread_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_pubsub_item({xmlel, <<"item">>, _attrs, _els}) ->
+    __Els = decode_pubsub_item_els(_els, []),
+    Id = decode_pubsub_item_attrs(_attrs, undefined),
+    {pubsub_item, Id, __Els}.
 
-decode_message({xmlel, <<"message">>, _attrs, _els}) ->
-    {Error, Thread, Subject, Body, __Els} =
-       decode_message_els(_els, undefined, undefined, [], [],
-                          []),
-    {Id, Type, From, To, Lang} =
-       decode_message_attrs(_attrs, undefined, undefined,
-                            undefined, undefined, undefined),
-    {message, Id, Type, Lang, From, To, Subject, Body,
-     Thread, Error, __Els}.
+decode_pubsub_item_els([], __Els) ->
+    lists:reverse(__Els);
+decode_pubsub_item_els([{xmlel, _, _, _} = _el | _els],
+                      __Els) ->
+    decode_pubsub_item_els(_els, [decode(_el) | __Els]);
+decode_pubsub_item_els([_ | _els], __Els) ->
+    decode_pubsub_item_els(_els, __Els).
 
-decode_message_els([], Error, Thread, Subject, Body,
-                  __Els) ->
-    {Error, Thread, lists:reverse(Subject),
-     lists:reverse(Body), lists:reverse(__Els)};
-decode_message_els([{xmlel, <<"error">>, _attrs, _} =
-                       _el
-                   | _els],
-                  Error, Thread, Subject, Body, __Els) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
-          decode_message_els(_els, decode_error(_el), Thread,
-                             Subject, Body, __Els);
-       true ->
-          decode_message_els(_els, Error, Thread, Subject, Body,
-                             __Els)
-    end;
-decode_message_els([{xmlel, <<"subject">>, _attrs, _} =
-                       _el
-                   | _els],
-                  Error, Thread, Subject, Body, __Els) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
-          decode_message_els(_els, Error, Thread,
-                             case decode_message_subject(_el) of
-                               undefined -> Subject;
-                               _new_el -> [_new_el | Subject]
-                             end,
-                             Body, __Els);
-       true ->
-          decode_message_els(_els, Error, Thread, Subject, Body,
-                             __Els)
-    end;
-decode_message_els([{xmlel, <<"thread">>, _attrs, _} =
-                       _el
-                   | _els],
-                  Error, Thread, Subject, Body, __Els) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
-          decode_message_els(_els, Error,
-                             decode_message_thread(_el), Subject, Body, __Els);
-       true ->
-          decode_message_els(_els, Error, Thread, Subject, Body,
-                             __Els)
-    end;
-decode_message_els([{xmlel, <<"body">>, _attrs, _} = _el
-                   | _els],
-                  Error, Thread, Subject, Body, __Els) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
-          decode_message_els(_els, Error, Thread, Subject,
-                             case decode_message_body(_el) of
-                               undefined -> Body;
-                               _new_el -> [_new_el | Body]
-                             end,
-                             __Els);
-       true ->
-          decode_message_els(_els, Error, Thread, Subject, Body,
-                             __Els)
-    end;
-decode_message_els([{xmlel, _, _, _} = _el | _els],
-                  Error, Thread, Subject, Body, __Els) ->
-    decode_message_els(_els, Error, Thread, Subject, Body,
-                      [decode(_el) | __Els]);
-decode_message_els([_ | _els], Error, Thread, Subject,
-                  Body, __Els) ->
-    decode_message_els(_els, Error, Thread, Subject, Body,
-                      __Els).
+decode_pubsub_item_attrs([{<<"id">>, _val} | _attrs],
+                        _Id) ->
+    decode_pubsub_item_attrs(_attrs, _val);
+decode_pubsub_item_attrs([_ | _attrs], Id) ->
+    decode_pubsub_item_attrs(_attrs, Id);
+decode_pubsub_item_attrs([], Id) ->
+    decode_pubsub_item_attr_id(Id).
 
-decode_message_attrs([{<<"id">>, _val} | _attrs], _Id,
-                    Type, From, To, Lang) ->
-    decode_message_attrs(_attrs, _val, Type, From, To,
-                        Lang);
-decode_message_attrs([{<<"type">>, _val} | _attrs], Id,
-                    _Type, From, To, Lang) ->
-    decode_message_attrs(_attrs, Id, _val, From, To, Lang);
-decode_message_attrs([{<<"from">>, _val} | _attrs], Id,
-                    Type, _From, To, Lang) ->
-    decode_message_attrs(_attrs, Id, Type, _val, To, Lang);
-decode_message_attrs([{<<"to">>, _val} | _attrs], Id,
-                    Type, From, _To, Lang) ->
-    decode_message_attrs(_attrs, Id, Type, From, _val,
-                        Lang);
-decode_message_attrs([{<<"xml:lang">>, _val} | _attrs],
-                    Id, Type, From, To, _Lang) ->
-    decode_message_attrs(_attrs, Id, Type, From, To, _val);
-decode_message_attrs([_ | _attrs], Id, Type, From, To,
-                    Lang) ->
-    decode_message_attrs(_attrs, Id, Type, From, To, Lang);
-decode_message_attrs([], Id, Type, From, To, Lang) ->
-    {decode_message_attr_id(Id),
-     decode_message_attr_type(Type),
-     decode_message_attr_from(From),
-     decode_message_attr_to(To),
-     'decode_message_attr_xml:lang'(Lang)}.
+encode_pubsub_item({pubsub_item, Id, __Els},
+                  _xmlns_attrs) ->
+    _els = [encode(_el) || _el <- __Els],
+    _attrs = encode_pubsub_item_attr_id(Id, _xmlns_attrs),
+    {xmlel, <<"item">>, _attrs, _els}.
 
-encode_message({message, Id, Type, Lang, From, To,
-               Subject, Body, Thread, Error, __Els},
-              _xmlns_attrs) ->
-    _els = 'encode_message_$body'(Body,
-                                 'encode_message_$subject'(Subject,
-                                                           'encode_message_$thread'(Thread,
-                                                                                    'encode_message_$error'(Error,
-                                                                                                            [encode(_el)
-                                                                                                             || _el
-                                                                                                                    <- __Els])))),
-    _attrs = 'encode_message_attr_xml:lang'(Lang,
-                                           encode_message_attr_to(To,
-                                                                  encode_message_attr_from(From,
-                                                                                           encode_message_attr_type(Type,
-                                                                                                                    encode_message_attr_id(Id,
-                                                                                                                                           _xmlns_attrs))))),
-    {xmlel, <<"message">>, _attrs, _els}.
+decode_pubsub_item_attr_id(undefined) -> undefined;
+decode_pubsub_item_attr_id(_val) -> _val.
 
-'encode_message_$error'(undefined, _acc) -> _acc;
-'encode_message_$error'(Error, _acc) ->
-    [encode_error(Error, []) | _acc].
+encode_pubsub_item_attr_id(undefined, _acc) -> _acc;
+encode_pubsub_item_attr_id(_val, _acc) ->
+    [{<<"id">>, _val} | _acc].
 
-'encode_message_$thread'(undefined, _acc) -> _acc;
-'encode_message_$thread'(Thread, _acc) ->
-    [encode_message_thread(Thread, []) | _acc].
+decode_pubsub_affiliation({xmlel, <<"affiliation">>,
+                          _attrs, _els}) ->
+    {Node, Type} = decode_pubsub_affiliation_attrs(_attrs,
+                                                  undefined, undefined),
+    {pubsub_affiliation, Node, Type}.
 
-'encode_message_$subject'([], _acc) -> _acc;
-'encode_message_$subject'([Subject | _els], _acc) ->
-    'encode_message_$subject'(_els,
-                             [encode_message_subject(Subject, []) | _acc]).
+decode_pubsub_affiliation_attrs([{<<"node">>, _val}
+                                | _attrs],
+                               _Node, Type) ->
+    decode_pubsub_affiliation_attrs(_attrs, _val, Type);
+decode_pubsub_affiliation_attrs([{<<"affiliation">>,
+                                 _val}
+                                | _attrs],
+                               Node, _Type) ->
+    decode_pubsub_affiliation_attrs(_attrs, Node, _val);
+decode_pubsub_affiliation_attrs([_ | _attrs], Node,
+                               Type) ->
+    decode_pubsub_affiliation_attrs(_attrs, Node, Type);
+decode_pubsub_affiliation_attrs([], Node, Type) ->
+    {decode_pubsub_affiliation_attr_node(Node),
+     decode_pubsub_affiliation_attr_affiliation(Type)}.
 
-'encode_message_$body'([], _acc) -> _acc;
-'encode_message_$body'([Body | _els], _acc) ->
-    'encode_message_$body'(_els,
-                          [encode_message_body(Body, []) | _acc]).
+encode_pubsub_affiliation({pubsub_affiliation, Node,
+                          Type},
+                         _xmlns_attrs) ->
+    _els = [],
+    _attrs =
+       encode_pubsub_affiliation_attr_affiliation(Type,
+                                                  encode_pubsub_affiliation_attr_node(Node,
+                                                                                      _xmlns_attrs)),
+    {xmlel, <<"affiliation">>, _attrs, _els}.
 
-decode_message_attr_id(undefined) -> undefined;
-decode_message_attr_id(_val) -> _val.
+decode_pubsub_affiliation_attr_node(undefined) ->
+    erlang:error({missing_attr, <<"node">>,
+                 <<"affiliation">>,
+                 <<"http://jabber.org/protocol/pubsub">>});
+decode_pubsub_affiliation_attr_node(_val) -> _val.
 
-encode_message_attr_id(undefined, _acc) -> _acc;
-encode_message_attr_id(_val, _acc) ->
-    [{<<"id">>, _val} | _acc].
+encode_pubsub_affiliation_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
-decode_message_attr_type(undefined) -> normal;
-decode_message_attr_type(_val) ->
+decode_pubsub_affiliation_attr_affiliation(undefined) ->
+    erlang:error({missing_attr, <<"affiliation">>,
+                 <<"affiliation">>,
+                 <<"http://jabber.org/protocol/pubsub">>});
+decode_pubsub_affiliation_attr_affiliation(_val) ->
     case catch xml_gen:dec_enum(_val,
-                               [chat, normal, groupchat, headline, error])
+                               [member, none, outcast, owner, publisher,
+                                'publish-only'])
        of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"type">>, <<"message">>,
-                       <<"jabber:client">>});
+         erlang:error({bad_attr_value, <<"affiliation">>,
+                       <<"affiliation">>,
+                       <<"http://jabber.org/protocol/pubsub">>});
       _res -> _res
     end.
 
-encode_message_attr_type(normal, _acc) -> _acc;
-encode_message_attr_type(_val, _acc) ->
-    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
-
-decode_message_attr_from(undefined) -> undefined;
-decode_message_attr_from(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"from">>, <<"message">>,
-                       <<"jabber:client">>});
-      _res -> _res
-    end.
+encode_pubsub_affiliation_attr_affiliation(_val,
+                                          _acc) ->
+    [{<<"affiliation">>, xml_gen:enc_enum(_val)} | _acc].
 
-encode_message_attr_from(undefined, _acc) -> _acc;
-encode_message_attr_from(_val, _acc) ->
-    [{<<"from">>, enc_jid(_val)} | _acc].
+decode_pubsub_subscription({xmlel, <<"subscription">>,
+                           _attrs, _els}) ->
+    {Jid, Node, Subid, Type} =
+       decode_pubsub_subscription_attrs(_attrs, undefined,
+                                        undefined, undefined, undefined),
+    {pubsub_subscription, Jid, Node, Subid, Type}.
 
-decode_message_attr_to(undefined) -> undefined;
-decode_message_attr_to(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"to">>, <<"message">>,
-                       <<"jabber:client">>});
-      _res -> _res
-    end.
-
-encode_message_attr_to(undefined, _acc) -> _acc;
-encode_message_attr_to(_val, _acc) ->
-    [{<<"to">>, enc_jid(_val)} | _acc].
-
-'decode_message_attr_xml:lang'(undefined) -> undefined;
-'decode_message_attr_xml:lang'(_val) -> _val.
-
-'encode_message_attr_xml:lang'(undefined, _acc) -> _acc;
-'encode_message_attr_xml:lang'(_val, _acc) ->
-    [{<<"xml:lang">>, _val} | _acc].
-
-decode_presence_show({xmlel, <<"show">>, _attrs,
-                     _els}) ->
-    Cdata = decode_presence_show_els(_els, <<>>), Cdata.
-
-decode_presence_show_els([], Cdata) ->
-    decode_presence_show_cdata(Cdata);
-decode_presence_show_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_presence_show_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_presence_show_els([_ | _els], Cdata) ->
-    decode_presence_show_els(_els, Cdata).
+decode_pubsub_subscription_attrs([{<<"jid">>, _val}
+                                 | _attrs],
+                                _Jid, Node, Subid, Type) ->
+    decode_pubsub_subscription_attrs(_attrs, _val, Node,
+                                    Subid, Type);
+decode_pubsub_subscription_attrs([{<<"node">>, _val}
+                                 | _attrs],
+                                Jid, _Node, Subid, Type) ->
+    decode_pubsub_subscription_attrs(_attrs, Jid, _val,
+                                    Subid, Type);
+decode_pubsub_subscription_attrs([{<<"subid">>, _val}
+                                 | _attrs],
+                                Jid, Node, _Subid, Type) ->
+    decode_pubsub_subscription_attrs(_attrs, Jid, Node,
+                                    _val, Type);
+decode_pubsub_subscription_attrs([{<<"subscription">>,
+                                  _val}
+                                 | _attrs],
+                                Jid, Node, Subid, _Type) ->
+    decode_pubsub_subscription_attrs(_attrs, Jid, Node,
+                                    Subid, _val);
+decode_pubsub_subscription_attrs([_ | _attrs], Jid,
+                                Node, Subid, Type) ->
+    decode_pubsub_subscription_attrs(_attrs, Jid, Node,
+                                    Subid, Type);
+decode_pubsub_subscription_attrs([], Jid, Node, Subid,
+                                Type) ->
+    {decode_pubsub_subscription_attr_jid(Jid),
+     decode_pubsub_subscription_attr_node(Node),
+     decode_pubsub_subscription_attr_subid(Subid),
+     decode_pubsub_subscription_attr_subscription(Type)}.
 
-encode_presence_show(Cdata, _xmlns_attrs) ->
-    _els = encode_presence_show_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"show">>, _attrs, _els}.
+encode_pubsub_subscription({pubsub_subscription, Jid,
+                           Node, Subid, Type},
+                          _xmlns_attrs) ->
+    _els = [],
+    _attrs =
+       encode_pubsub_subscription_attr_subscription(Type,
+                                                    encode_pubsub_subscription_attr_subid(Subid,
+                                                                                          encode_pubsub_subscription_attr_node(Node,
+                                                                                                                               encode_pubsub_subscription_attr_jid(Jid,
+                                                                                                                                                                   _xmlns_attrs)))),
+    {xmlel, <<"subscription">>, _attrs, _els}.
 
-decode_presence_show_cdata(<<>>) -> undefined;
-decode_presence_show_cdata(_val) ->
-    case catch xml_gen:dec_enum(_val, [away, chat, dnd, xa])
-       of
+decode_pubsub_subscription_attr_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>,
+                 <<"subscription">>,
+                 <<"http://jabber.org/protocol/pubsub">>});
+decode_pubsub_subscription_attr_jid(_val) ->
+    case catch dec_jid(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"show">>,
-                       <<"jabber:client">>});
+         erlang:error({bad_attr_value, <<"jid">>,
+                       <<"subscription">>,
+                       <<"http://jabber.org/protocol/pubsub">>});
       _res -> _res
     end.
 
-encode_presence_show_cdata(undefined, _acc) -> _acc;
-encode_presence_show_cdata(_val, _acc) ->
-    [{xmlcdata, xml_gen:enc_enum(_val)} | _acc].
-
-decode_presence_status({xmlel, <<"status">>, _attrs,
-                       _els}) ->
-    Data = decode_presence_status_els(_els, <<>>),
-    Lang = decode_presence_status_attrs(_attrs, undefined),
-    {text, Lang, Data}.
-
-decode_presence_status_els([], Data) ->
-    decode_presence_status_cdata(Data);
-decode_presence_status_els([{xmlcdata, _data} | _els],
-                          Data) ->
-    decode_presence_status_els(_els,
-                              <<Data/binary, _data/binary>>);
-decode_presence_status_els([_ | _els], Data) ->
-    decode_presence_status_els(_els, Data).
-
-decode_presence_status_attrs([{<<"xml:lang">>, _val}
-                             | _attrs],
-                            _Lang) ->
-    decode_presence_status_attrs(_attrs, _val);
-decode_presence_status_attrs([_ | _attrs], Lang) ->
-    decode_presence_status_attrs(_attrs, Lang);
-decode_presence_status_attrs([], Lang) ->
-    'decode_presence_status_attr_xml:lang'(Lang).
-
-encode_presence_status({text, Lang, Data},
-                      _xmlns_attrs) ->
-    _els = encode_presence_status_cdata(Data, []),
-    _attrs = 'encode_presence_status_attr_xml:lang'(Lang,
-                                                   _xmlns_attrs),
-    {xmlel, <<"status">>, _attrs, _els}.
+encode_pubsub_subscription_attr_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
 
-'decode_presence_status_attr_xml:lang'(undefined) ->
+decode_pubsub_subscription_attr_node(undefined) ->
     undefined;
-'decode_presence_status_attr_xml:lang'(_val) -> _val.
+decode_pubsub_subscription_attr_node(_val) -> _val.
 
-'encode_presence_status_attr_xml:lang'(undefined,
-                                      _acc) ->
+encode_pubsub_subscription_attr_node(undefined, _acc) ->
     _acc;
-'encode_presence_status_attr_xml:lang'(_val, _acc) ->
-    [{<<"xml:lang">>, _val} | _acc].
-
-decode_presence_status_cdata(<<>>) -> undefined;
-decode_presence_status_cdata(_val) -> _val.
-
-encode_presence_status_cdata(undefined, _acc) -> _acc;
-encode_presence_status_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
-
-decode_presence_priority({xmlel, <<"priority">>, _attrs,
-                         _els}) ->
-    Cdata = decode_presence_priority_els(_els, <<>>), Cdata.
+encode_pubsub_subscription_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
-decode_presence_priority_els([], Cdata) ->
-    decode_presence_priority_cdata(Cdata);
-decode_presence_priority_els([{xmlcdata, _data} | _els],
-                            Cdata) ->
-    decode_presence_priority_els(_els,
-                                <<Cdata/binary, _data/binary>>);
-decode_presence_priority_els([_ | _els], Cdata) ->
-    decode_presence_priority_els(_els, Cdata).
+decode_pubsub_subscription_attr_subid(undefined) ->
+    undefined;
+decode_pubsub_subscription_attr_subid(_val) -> _val.
 
-encode_presence_priority(Cdata, _xmlns_attrs) ->
-    _els = encode_presence_priority_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"priority">>, _attrs, _els}.
+encode_pubsub_subscription_attr_subid(undefined,
+                                     _acc) ->
+    _acc;
+encode_pubsub_subscription_attr_subid(_val, _acc) ->
+    [{<<"subid">>, _val} | _acc].
 
-decode_presence_priority_cdata(<<>>) -> undefined;
-decode_presence_priority_cdata(_val) ->
-    case catch xml_gen:dec_int(_val) of
+decode_pubsub_subscription_attr_subscription(undefined) ->
+    undefined;
+decode_pubsub_subscription_attr_subscription(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [none, pending, subscribed, unconfigured])
+       of
       {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"priority">>,
-                       <<"jabber:client">>});
+         erlang:error({bad_attr_value, <<"subscription">>,
+                       <<"subscription">>,
+                       <<"http://jabber.org/protocol/pubsub">>});
       _res -> _res
     end.
 
-encode_presence_priority_cdata(undefined, _acc) -> _acc;
-encode_presence_priority_cdata(_val, _acc) ->
-    [{xmlcdata, xml_gen:enc_int(_val)} | _acc].
+encode_pubsub_subscription_attr_subscription(undefined,
+                                            _acc) ->
+    _acc;
+encode_pubsub_subscription_attr_subscription(_val,
+                                            _acc) ->
+    [{<<"subscription">>, xml_gen:enc_enum(_val)} | _acc].
 
-decode_presence({xmlel, <<"presence">>, _attrs,
-                _els}) ->
-    {Error, Status, Show, Priority, __Els} =
-       decode_presence_els(_els, undefined, [], undefined,
-                           undefined, []),
-    {Id, Type, From, To, Lang} =
-       decode_presence_attrs(_attrs, undefined, undefined,
-                             undefined, undefined, undefined),
-    {presence, Id, Type, Lang, From, To, Show, Status,
-     Priority, Error, __Els}.
+decode_xdata({xmlel, <<"x">>, _attrs, _els}) ->
+    {Fields, Items, Instructions, Reported, Title} =
+       decode_xdata_els(_els, [], [], [], undefined,
+                        undefined),
+    Type = decode_xdata_attrs(_attrs, undefined),
+    {xdata, Type, Instructions, Title, Reported, Items,
+     Fields}.
 
-decode_presence_els([], Error, Status, Show, Priority,
-                   __Els) ->
-    {Error, lists:reverse(Status), Show, Priority,
-     lists:reverse(__Els)};
-decode_presence_els([{xmlel, <<"error">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Error, Status, Show, Priority, __Els) ->
+decode_xdata_els([], Fields, Items, Instructions,
+                Reported, Title) ->
+    {lists:reverse(Fields), lists:reverse(Items),
+     lists:reverse(Instructions), Reported, Title};
+decode_xdata_els([{xmlel, <<"instructions">>, _attrs,
+                  _} =
+                     _el
+                 | _els],
+                Fields, Items, Instructions, Reported, Title) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
-          decode_presence_els(_els, decode_error(_el), Status,
-                              Show, Priority, __Els);
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_els(_els, Fields, Items,
+                           case decode_xdata_instructions(_el) of
+                             undefined -> Instructions;
+                             _new_el -> [_new_el | Instructions]
+                           end,
+                           Reported, Title);
        true ->
-          decode_presence_els(_els, Error, Status, Show, Priority,
-                              __Els)
+          decode_xdata_els(_els, Fields, Items, Instructions,
+                           Reported, Title)
     end;
-decode_presence_els([{xmlel, <<"show">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Error, Status, Show, Priority, __Els) ->
+decode_xdata_els([{xmlel, <<"title">>, _attrs, _} = _el
+                 | _els],
+                Fields, Items, Instructions, Reported, Title) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
-          decode_presence_els(_els, Error, Status,
-                              decode_presence_show(_el), Priority, __Els);
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_els(_els, Fields, Items, Instructions,
+                           Reported, decode_xdata_title(_el));
        true ->
-          decode_presence_els(_els, Error, Status, Show, Priority,
-                              __Els)
+          decode_xdata_els(_els, Fields, Items, Instructions,
+                           Reported, Title)
     end;
-decode_presence_els([{xmlel, <<"status">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Error, Status, Show, Priority, __Els) ->
+decode_xdata_els([{xmlel, <<"reported">>, _attrs, _} =
+                     _el
+                 | _els],
+                Fields, Items, Instructions, Reported, Title) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
-          decode_presence_els(_els, Error,
-                              case decode_presence_status(_el) of
-                                undefined -> Status;
-                                _new_el -> [_new_el | Status]
-                              end,
-                              Show, Priority, __Els);
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_els(_els, Fields, Items, Instructions,
+                           decode_xdata_reported(_el), Title);
        true ->
-          decode_presence_els(_els, Error, Status, Show, Priority,
-                              __Els)
+          decode_xdata_els(_els, Fields, Items, Instructions,
+                           Reported, Title)
     end;
-decode_presence_els([{xmlel, <<"priority">>, _attrs,
-                     _} =
-                        _el
-                    | _els],
-                   Error, Status, Show, Priority, __Els) ->
+decode_xdata_els([{xmlel, <<"item">>, _attrs, _} = _el
+                 | _els],
+                Fields, Items, Instructions, Reported, Title) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
-          decode_presence_els(_els, Error, Status, Show,
-                              decode_presence_priority(_el), __Els);
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_els(_els, Fields,
+                           case decode_xdata_item(_el) of
+                             undefined -> Items;
+                             _new_el -> [_new_el | Items]
+                           end,
+                           Instructions, Reported, Title);
        true ->
-          decode_presence_els(_els, Error, Status, Show, Priority,
-                              __Els)
+          decode_xdata_els(_els, Fields, Items, Instructions,
+                           Reported, Title)
     end;
-decode_presence_els([{xmlel, _, _, _} = _el | _els],
-                   Error, Status, Show, Priority, __Els) ->
-    decode_presence_els(_els, Error, Status, Show, Priority,
-                       [decode(_el) | __Els]);
-decode_presence_els([_ | _els], Error, Status, Show,
-                   Priority, __Els) ->
-    decode_presence_els(_els, Error, Status, Show, Priority,
-                       __Els).
-
-decode_presence_attrs([{<<"id">>, _val} | _attrs], _Id,
-                     Type, From, To, Lang) ->
-    decode_presence_attrs(_attrs, _val, Type, From, To,
-                         Lang);
-decode_presence_attrs([{<<"type">>, _val} | _attrs], Id,
-                     _Type, From, To, Lang) ->
-    decode_presence_attrs(_attrs, Id, _val, From, To, Lang);
-decode_presence_attrs([{<<"from">>, _val} | _attrs], Id,
-                     Type, _From, To, Lang) ->
-    decode_presence_attrs(_attrs, Id, Type, _val, To, Lang);
-decode_presence_attrs([{<<"to">>, _val} | _attrs], Id,
-                     Type, From, _To, Lang) ->
-    decode_presence_attrs(_attrs, Id, Type, From, _val,
-                         Lang);
-decode_presence_attrs([{<<"xml:lang">>, _val} | _attrs],
-                     Id, Type, From, To, _Lang) ->
-    decode_presence_attrs(_attrs, Id, Type, From, To, _val);
-decode_presence_attrs([_ | _attrs], Id, Type, From, To,
-                     Lang) ->
-    decode_presence_attrs(_attrs, Id, Type, From, To, Lang);
-decode_presence_attrs([], Id, Type, From, To, Lang) ->
-    {decode_presence_attr_id(Id),
-     decode_presence_attr_type(Type),
-     decode_presence_attr_from(From),
-     decode_presence_attr_to(To),
-     'decode_presence_attr_xml:lang'(Lang)}.
+decode_xdata_els([{xmlel, <<"field">>, _attrs, _} = _el
+                 | _els],
+                Fields, Items, Instructions, Reported, Title) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_els(_els,
+                           case decode_xdata_field(_el) of
+                             undefined -> Fields;
+                             _new_el -> [_new_el | Fields]
+                           end,
+                           Items, Instructions, Reported, Title);
+       true ->
+          decode_xdata_els(_els, Fields, Items, Instructions,
+                           Reported, Title)
+    end;
+decode_xdata_els([_ | _els], Fields, Items,
+                Instructions, Reported, Title) ->
+    decode_xdata_els(_els, Fields, Items, Instructions,
+                    Reported, Title).
 
-encode_presence({presence, Id, Type, Lang, From, To,
-                Show, Status, Priority, Error, __Els},
-               _xmlns_attrs) ->
-    _els = 'encode_presence_$priority'(Priority,
-                                      'encode_presence_$show'(Show,
-                                                              'encode_presence_$status'(Status,
-                                                                                        'encode_presence_$error'(Error,
-                                                                                                                 [encode(_el)
-                                                                                                                  || _el
-                                                                                                                         <- __Els])))),
-    _attrs = 'encode_presence_attr_xml:lang'(Lang,
-                                            encode_presence_attr_to(To,
-                                                                    encode_presence_attr_from(From,
-                                                                                              encode_presence_attr_type(Type,
-                                                                                                                        encode_presence_attr_id(Id,
-                                                                                                                                                _xmlns_attrs))))),
-    {xmlel, <<"presence">>, _attrs, _els}.
+decode_xdata_attrs([{<<"type">>, _val} | _attrs],
+                  _Type) ->
+    decode_xdata_attrs(_attrs, _val);
+decode_xdata_attrs([_ | _attrs], Type) ->
+    decode_xdata_attrs(_attrs, Type);
+decode_xdata_attrs([], Type) ->
+    decode_xdata_attr_type(Type).
 
-'encode_presence_$error'(undefined, _acc) -> _acc;
-'encode_presence_$error'(Error, _acc) ->
-    [encode_error(Error, []) | _acc].
+encode_xdata({xdata, Type, Instructions, Title,
+             Reported, Items, Fields},
+            _xmlns_attrs) ->
+    _els = 'encode_xdata_$title'(Title,
+                                'encode_xdata_$reported'(Reported,
+                                                         'encode_xdata_$instructions'(Instructions,
+                                                                                      'encode_xdata_$items'(Items,
+                                                                                                            'encode_xdata_$fields'(Fields,
+                                                                                                                                   []))))),
+    _attrs = encode_xdata_attr_type(Type, _xmlns_attrs),
+    {xmlel, <<"x">>, _attrs, _els}.
 
-'encode_presence_$status'([], _acc) -> _acc;
-'encode_presence_$status'([Status | _els], _acc) ->
-    'encode_presence_$status'(_els,
-                             [encode_presence_status(Status, []) | _acc]).
+'encode_xdata_$fields'([], _acc) -> _acc;
+'encode_xdata_$fields'([Fields | _els], _acc) ->
+    'encode_xdata_$fields'(_els,
+                          [encode_xdata_field(Fields, []) | _acc]).
 
-'encode_presence_$show'(undefined, _acc) -> _acc;
-'encode_presence_$show'(Show, _acc) ->
-    [encode_presence_show(Show, []) | _acc].
+'encode_xdata_$items'([], _acc) -> _acc;
+'encode_xdata_$items'([Items | _els], _acc) ->
+    'encode_xdata_$items'(_els,
+                         [encode_xdata_item(Items, []) | _acc]).
 
-'encode_presence_$priority'(undefined, _acc) -> _acc;
-'encode_presence_$priority'(Priority, _acc) ->
-    [encode_presence_priority(Priority, []) | _acc].
+'encode_xdata_$instructions'([], _acc) -> _acc;
+'encode_xdata_$instructions'([Instructions | _els],
+                            _acc) ->
+    'encode_xdata_$instructions'(_els,
+                                [encode_xdata_instructions(Instructions, [])
+                                 | _acc]).
 
-decode_presence_attr_id(undefined) -> undefined;
-decode_presence_attr_id(_val) -> _val.
+'encode_xdata_$reported'(undefined, _acc) -> _acc;
+'encode_xdata_$reported'(Reported, _acc) ->
+    [encode_xdata_reported(Reported, []) | _acc].
 
-encode_presence_attr_id(undefined, _acc) -> _acc;
-encode_presence_attr_id(_val, _acc) ->
-    [{<<"id">>, _val} | _acc].
+'encode_xdata_$title'(undefined, _acc) -> _acc;
+'encode_xdata_$title'(Title, _acc) ->
+    [encode_xdata_title(Title, []) | _acc].
 
-decode_presence_attr_type(undefined) -> undefined;
-decode_presence_attr_type(_val) ->
+decode_xdata_attr_type(undefined) ->
+    erlang:error({missing_attr, <<"type">>, <<"x">>,
+                 <<"jabber:x:data">>});
+decode_xdata_attr_type(_val) ->
     case catch xml_gen:dec_enum(_val,
-                               [unavailable, subscribe, subscribed,
-                                unsubscribe, unsubscribed, probe, error])
+                               [cancel, form, result, submit])
        of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"type">>,
-                       <<"presence">>, <<"jabber:client">>});
+         erlang:error({bad_attr_value, <<"type">>, <<"x">>,
+                       <<"jabber:x:data">>});
       _res -> _res
     end.
 
-encode_presence_attr_type(undefined, _acc) -> _acc;
-encode_presence_attr_type(_val, _acc) ->
+encode_xdata_attr_type(_val, _acc) ->
     [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
 
-decode_presence_attr_from(undefined) -> undefined;
-decode_presence_attr_from(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"from">>,
-                       <<"presence">>, <<"jabber:client">>});
-      _res -> _res
-    end.
-
-encode_presence_attr_from(undefined, _acc) -> _acc;
-encode_presence_attr_from(_val, _acc) ->
-    [{<<"from">>, enc_jid(_val)} | _acc].
-
-decode_presence_attr_to(undefined) -> undefined;
-decode_presence_attr_to(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"to">>, <<"presence">>,
-                       <<"jabber:client">>});
-      _res -> _res
-    end.
-
-encode_presence_attr_to(undefined, _acc) -> _acc;
-encode_presence_attr_to(_val, _acc) ->
-    [{<<"to">>, enc_jid(_val)} | _acc].
-
-'decode_presence_attr_xml:lang'(undefined) -> undefined;
-'decode_presence_attr_xml:lang'(_val) -> _val.
-
-'encode_presence_attr_xml:lang'(undefined, _acc) ->
-    _acc;
-'encode_presence_attr_xml:lang'(_val, _acc) ->
-    [{<<"xml:lang">>, _val} | _acc].
+decode_xdata_item({xmlel, <<"item">>, _attrs, _els}) ->
+    Fields = decode_xdata_item_els(_els, []), Fields.
 
-decode_error_bad_request({xmlel, <<"bad-request">>,
-                         _attrs, _els}) ->
-    'bad-request'.
+decode_xdata_item_els([], Fields) ->
+    lists:reverse(Fields);
+decode_xdata_item_els([{xmlel, <<"field">>, _attrs, _} =
+                          _el
+                      | _els],
+                     Fields) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_item_els(_els,
+                                case decode_xdata_field(_el) of
+                                  undefined -> Fields;
+                                  _new_el -> [_new_el | Fields]
+                                end);
+       true -> decode_xdata_item_els(_els, Fields)
+    end;
+decode_xdata_item_els([_ | _els], Fields) ->
+    decode_xdata_item_els(_els, Fields).
 
-encode_error_bad_request('bad-request', _xmlns_attrs) ->
-    _els = [],
+encode_xdata_item(Fields, _xmlns_attrs) ->
+    _els = 'encode_xdata_item_$fields'(Fields, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"bad-request">>, _attrs, _els}.
+    {xmlel, <<"item">>, _attrs, _els}.
 
-decode_error_conflict({xmlel, <<"conflict">>, _attrs,
+'encode_xdata_item_$fields'([], _acc) -> _acc;
+'encode_xdata_item_$fields'([Fields | _els], _acc) ->
+    'encode_xdata_item_$fields'(_els,
+                               [encode_xdata_field(Fields, []) | _acc]).
+
+decode_xdata_reported({xmlel, <<"reported">>, _attrs,
                       _els}) ->
-    conflict.
+    Fields = decode_xdata_reported_els(_els, []), Fields.
 
-encode_error_conflict(conflict, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"conflict">>, _attrs, _els}.
-
-decode_error_feature_not_implemented({xmlel,
-                                     <<"feature-not-implemented">>, _attrs,
-                                     _els}) ->
-    'feature-not-implemented'.
+decode_xdata_reported_els([], Fields) ->
+    lists:reverse(Fields);
+decode_xdata_reported_els([{xmlel, <<"field">>, _attrs,
+                           _} =
+                              _el
+                          | _els],
+                         Fields) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_reported_els(_els,
+                                    case decode_xdata_field(_el) of
+                                      undefined -> Fields;
+                                      _new_el -> [_new_el | Fields]
+                                    end);
+       true -> decode_xdata_reported_els(_els, Fields)
+    end;
+decode_xdata_reported_els([_ | _els], Fields) ->
+    decode_xdata_reported_els(_els, Fields).
 
-encode_error_feature_not_implemented('feature-not-implemented',
-                                    _xmlns_attrs) ->
-    _els = [],
+encode_xdata_reported(Fields, _xmlns_attrs) ->
+    _els = 'encode_xdata_reported_$fields'(Fields, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"feature-not-implemented">>, _attrs, _els}.
-
-decode_error_forbidden({xmlel, <<"forbidden">>, _attrs,
-                       _els}) ->
-    forbidden.
+    {xmlel, <<"reported">>, _attrs, _els}.
 
-encode_error_forbidden(forbidden, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"forbidden">>, _attrs, _els}.
+'encode_xdata_reported_$fields'([], _acc) -> _acc;
+'encode_xdata_reported_$fields'([Fields | _els],
+                               _acc) ->
+    'encode_xdata_reported_$fields'(_els,
+                                   [encode_xdata_field(Fields, []) | _acc]).
 
-decode_error_gone({xmlel, <<"gone">>, _attrs, _els}) ->
-    Uri = decode_error_gone_els(_els, <<>>), {gone, Uri}.
+decode_xdata_title({xmlel, <<"title">>, _attrs,
+                   _els}) ->
+    Cdata = decode_xdata_title_els(_els, <<>>), Cdata.
 
-decode_error_gone_els([], Uri) ->
-    decode_error_gone_cdata(Uri);
-decode_error_gone_els([{xmlcdata, _data} | _els],
-                     Uri) ->
-    decode_error_gone_els(_els,
-                         <<Uri/binary, _data/binary>>);
-decode_error_gone_els([_ | _els], Uri) ->
-    decode_error_gone_els(_els, Uri).
+decode_xdata_title_els([], Cdata) ->
+    decode_xdata_title_cdata(Cdata);
+decode_xdata_title_els([{xmlcdata, _data} | _els],
+                      Cdata) ->
+    decode_xdata_title_els(_els,
+                          <<Cdata/binary, _data/binary>>);
+decode_xdata_title_els([_ | _els], Cdata) ->
+    decode_xdata_title_els(_els, Cdata).
 
-encode_error_gone({gone, Uri}, _xmlns_attrs) ->
-    _els = encode_error_gone_cdata(Uri, []),
+encode_xdata_title(Cdata, _xmlns_attrs) ->
+    _els = encode_xdata_title_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"gone">>, _attrs, _els}.
+    {xmlel, <<"title">>, _attrs, _els}.
 
-decode_error_gone_cdata(<<>>) -> undefined;
-decode_error_gone_cdata(_val) -> _val.
+decode_xdata_title_cdata(<<>>) -> undefined;
+decode_xdata_title_cdata(_val) -> _val.
 
-encode_error_gone_cdata(undefined, _acc) -> _acc;
-encode_error_gone_cdata(_val, _acc) ->
+encode_xdata_title_cdata(undefined, _acc) -> _acc;
+encode_xdata_title_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_error_internal_server_error({xmlel,
-                                   <<"internal-server-error">>, _attrs,
-                                   _els}) ->
-    'internal-server-error'.
-
-encode_error_internal_server_error('internal-server-error',
-                                  _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"internal-server-error">>, _attrs, _els}.
+decode_xdata_instructions({xmlel, <<"instructions">>,
+                          _attrs, _els}) ->
+    Cdata = decode_xdata_instructions_els(_els, <<>>),
+    Cdata.
 
-decode_error_item_not_found({xmlel,
-                            <<"item-not-found">>, _attrs, _els}) ->
-    'item-not-found'.
+decode_xdata_instructions_els([], Cdata) ->
+    decode_xdata_instructions_cdata(Cdata);
+decode_xdata_instructions_els([{xmlcdata, _data}
+                              | _els],
+                             Cdata) ->
+    decode_xdata_instructions_els(_els,
+                                 <<Cdata/binary, _data/binary>>);
+decode_xdata_instructions_els([_ | _els], Cdata) ->
+    decode_xdata_instructions_els(_els, Cdata).
 
-encode_error_item_not_found('item-not-found',
-                           _xmlns_attrs) ->
-    _els = [],
+encode_xdata_instructions(Cdata, _xmlns_attrs) ->
+    _els = encode_xdata_instructions_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"item-not-found">>, _attrs, _els}.
-
-decode_error_jid_malformed({xmlel, <<"jid-malformed">>,
-                           _attrs, _els}) ->
-    'jid-malformed'.
+    {xmlel, <<"instructions">>, _attrs, _els}.
 
-encode_error_jid_malformed('jid-malformed',
-                          _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"jid-malformed">>, _attrs, _els}.
+decode_xdata_instructions_cdata(<<>>) -> undefined;
+decode_xdata_instructions_cdata(_val) -> _val.
 
-decode_error_not_acceptable({xmlel,
-                            <<"not-acceptable">>, _attrs, _els}) ->
-    'not-acceptable'.
+encode_xdata_instructions_cdata(undefined, _acc) ->
+    _acc;
+encode_xdata_instructions_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-encode_error_not_acceptable('not-acceptable',
-                           _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"not-acceptable">>, _attrs, _els}.
+decode_xdata_field({xmlel, <<"field">>, _attrs,
+                   _els}) ->
+    {Options, Values, Desc, Required} =
+       decode_xdata_field_els(_els, [], [], undefined, false),
+    {Label, Type, Var} = decode_xdata_field_attrs(_attrs,
+                                                 undefined, undefined,
+                                                 undefined),
+    {xdata_field, Label, Type, Var, Required, Desc, Values,
+     Options}.
 
-decode_error_not_allowed({xmlel, <<"not-allowed">>,
-                         _attrs, _els}) ->
-    'not-allowed'.
+decode_xdata_field_els([], Options, Values, Desc,
+                      Required) ->
+    {lists:reverse(Options), lists:reverse(Values), Desc,
+     Required};
+decode_xdata_field_els([{xmlel, <<"required">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Options, Values, Desc, Required) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_field_els(_els, Options, Values, Desc,
+                                 decode_xdata_field_required(_el));
+       true ->
+          decode_xdata_field_els(_els, Options, Values, Desc,
+                                 Required)
+    end;
+decode_xdata_field_els([{xmlel, <<"desc">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Options, Values, Desc, Required) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_field_els(_els, Options, Values,
+                                 decode_xdata_field_desc(_el), Required);
+       true ->
+          decode_xdata_field_els(_els, Options, Values, Desc,
+                                 Required)
+    end;
+decode_xdata_field_els([{xmlel, <<"value">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Options, Values, Desc, Required) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_field_els(_els, Options,
+                                 case decode_xdata_field_value(_el) of
+                                   undefined -> Values;
+                                   _new_el -> [_new_el | Values]
+                                 end,
+                                 Desc, Required);
+       true ->
+          decode_xdata_field_els(_els, Options, Values, Desc,
+                                 Required)
+    end;
+decode_xdata_field_els([{xmlel, <<"option">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Options, Values, Desc, Required) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_field_els(_els,
+                                 case decode_xdata_field_option(_el) of
+                                   undefined -> Options;
+                                   _new_el -> [_new_el | Options]
+                                 end,
+                                 Values, Desc, Required);
+       true ->
+          decode_xdata_field_els(_els, Options, Values, Desc,
+                                 Required)
+    end;
+decode_xdata_field_els([_ | _els], Options, Values,
+                      Desc, Required) ->
+    decode_xdata_field_els(_els, Options, Values, Desc,
+                          Required).
 
-encode_error_not_allowed('not-allowed', _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"not-allowed">>, _attrs, _els}.
+decode_xdata_field_attrs([{<<"label">>, _val} | _attrs],
+                        _Label, Type, Var) ->
+    decode_xdata_field_attrs(_attrs, _val, Type, Var);
+decode_xdata_field_attrs([{<<"type">>, _val} | _attrs],
+                        Label, _Type, Var) ->
+    decode_xdata_field_attrs(_attrs, Label, _val, Var);
+decode_xdata_field_attrs([{<<"var">>, _val} | _attrs],
+                        Label, Type, _Var) ->
+    decode_xdata_field_attrs(_attrs, Label, Type, _val);
+decode_xdata_field_attrs([_ | _attrs], Label, Type,
+                        Var) ->
+    decode_xdata_field_attrs(_attrs, Label, Type, Var);
+decode_xdata_field_attrs([], Label, Type, Var) ->
+    {decode_xdata_field_attr_label(Label),
+     decode_xdata_field_attr_type(Type),
+     decode_xdata_field_attr_var(Var)}.
 
-decode_error_not_authorized({xmlel,
-                            <<"not-authorized">>, _attrs, _els}) ->
-    'not-authorized'.
+encode_xdata_field({xdata_field, Label, Type, Var,
+                   Required, Desc, Values, Options},
+                  _xmlns_attrs) ->
+    _els = 'encode_xdata_field_$required'(Required,
+                                         'encode_xdata_field_$desc'(Desc,
+                                                                    'encode_xdata_field_$values'(Values,
+                                                                                                 'encode_xdata_field_$options'(Options,
+                                                                                                                               [])))),
+    _attrs = encode_xdata_field_attr_var(Var,
+                                        encode_xdata_field_attr_type(Type,
+                                                                     encode_xdata_field_attr_label(Label,
+                                                                                                   _xmlns_attrs))),
+    {xmlel, <<"field">>, _attrs, _els}.
 
-encode_error_not_authorized('not-authorized',
-                           _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"not-authorized">>, _attrs, _els}.
-
-decode_error_policy_violation({xmlel,
-                              <<"policy-violation">>, _attrs, _els}) ->
-    'policy-violation'.
+'encode_xdata_field_$options'([], _acc) -> _acc;
+'encode_xdata_field_$options'([Options | _els], _acc) ->
+    'encode_xdata_field_$options'(_els,
+                                 [encode_xdata_field_option(Options, [])
+                                  | _acc]).
 
-encode_error_policy_violation('policy-violation',
-                             _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"policy-violation">>, _attrs, _els}.
+'encode_xdata_field_$values'([], _acc) -> _acc;
+'encode_xdata_field_$values'([Values | _els], _acc) ->
+    'encode_xdata_field_$values'(_els,
+                                [encode_xdata_field_value(Values, []) | _acc]).
 
-decode_error_recipient_unavailable({xmlel,
-                                   <<"recipient-unavailable">>, _attrs,
-                                   _els}) ->
-    'recipient-unavailable'.
+'encode_xdata_field_$desc'(undefined, _acc) -> _acc;
+'encode_xdata_field_$desc'(Desc, _acc) ->
+    [encode_xdata_field_desc(Desc, []) | _acc].
 
-encode_error_recipient_unavailable('recipient-unavailable',
-                                  _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"recipient-unavailable">>, _attrs, _els}.
+'encode_xdata_field_$required'(false, _acc) -> _acc;
+'encode_xdata_field_$required'(Required, _acc) ->
+    [encode_xdata_field_required(Required, []) | _acc].
 
-decode_error_redirect({xmlel, <<"redirect">>, _attrs,
-                      _els}) ->
-    Uri = decode_error_redirect_els(_els, <<>>),
-    {redirect, Uri}.
+decode_xdata_field_attr_label(undefined) -> undefined;
+decode_xdata_field_attr_label(_val) -> _val.
 
-decode_error_redirect_els([], Uri) ->
-    decode_error_redirect_cdata(Uri);
-decode_error_redirect_els([{xmlcdata, _data} | _els],
-                         Uri) ->
-    decode_error_redirect_els(_els,
-                             <<Uri/binary, _data/binary>>);
-decode_error_redirect_els([_ | _els], Uri) ->
-    decode_error_redirect_els(_els, Uri).
+encode_xdata_field_attr_label(undefined, _acc) -> _acc;
+encode_xdata_field_attr_label(_val, _acc) ->
+    [{<<"label">>, _val} | _acc].
 
-encode_error_redirect({redirect, Uri}, _xmlns_attrs) ->
-    _els = encode_error_redirect_cdata(Uri, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"redirect">>, _attrs, _els}.
+decode_xdata_field_attr_type(undefined) -> undefined;
+decode_xdata_field_attr_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [boolean, fixed, hidden, 'jid-multi',
+                                'jid-single', 'list-multi', 'list-single',
+                                'text-multi', 'text-private', 'text-single'])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"type">>, <<"field">>,
+                       <<"jabber:x:data">>});
+      _res -> _res
+    end.
 
-decode_error_redirect_cdata(<<>>) -> undefined;
-decode_error_redirect_cdata(_val) -> _val.
+encode_xdata_field_attr_type(undefined, _acc) -> _acc;
+encode_xdata_field_attr_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
 
-encode_error_redirect_cdata(undefined, _acc) -> _acc;
-encode_error_redirect_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_xdata_field_attr_var(undefined) -> undefined;
+decode_xdata_field_attr_var(_val) -> _val.
 
-decode_error_registration_required({xmlel,
-                                   <<"registration-required">>, _attrs,
-                                   _els}) ->
-    'registration-required'.
+encode_xdata_field_attr_var(undefined, _acc) -> _acc;
+encode_xdata_field_attr_var(_val, _acc) ->
+    [{<<"var">>, _val} | _acc].
 
-encode_error_registration_required('registration-required',
-                                  _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"registration-required">>, _attrs, _els}.
+decode_xdata_field_option({xmlel, <<"option">>, _attrs,
+                          _els}) ->
+    Value = decode_xdata_field_option_els(_els, []), Value.
 
-decode_error_remote_server_not_found({xmlel,
-                                     <<"remote-server-not-found">>, _attrs,
-                                     _els}) ->
-    'remote-server-not-found'.
+decode_xdata_field_option_els([], [Value]) -> Value;
+decode_xdata_field_option_els([{xmlel, <<"value">>,
+                               _attrs, _} =
+                                  _el
+                              | _els],
+                             Value) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
+          decode_xdata_field_option_els(_els,
+                                        case decode_xdata_field_value(_el) of
+                                          undefined -> Value;
+                                          _new_el -> [_new_el | Value]
+                                        end);
+       true -> decode_xdata_field_option_els(_els, Value)
+    end;
+decode_xdata_field_option_els([_ | _els], Value) ->
+    decode_xdata_field_option_els(_els, Value).
 
-encode_error_remote_server_not_found('remote-server-not-found',
-                                    _xmlns_attrs) ->
-    _els = [],
+encode_xdata_field_option(Value, _xmlns_attrs) ->
+    _els = 'encode_xdata_field_option_$value'(Value, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"remote-server-not-found">>, _attrs, _els}.
+    {xmlel, <<"option">>, _attrs, _els}.
 
-decode_error_remote_server_timeout({xmlel,
-                                   <<"remote-server-timeout">>, _attrs,
-                                   _els}) ->
-    'remote-server-timeout'.
+'encode_xdata_field_option_$value'(Value, _acc) ->
+    [encode_xdata_field_value(Value, []) | _acc].
 
-encode_error_remote_server_timeout('remote-server-timeout',
-                                  _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"remote-server-timeout">>, _attrs, _els}.
+decode_xdata_field_value({xmlel, <<"value">>, _attrs,
+                         _els}) ->
+    Cdata = decode_xdata_field_value_els(_els, <<>>), Cdata.
 
-decode_error_resource_constraint({xmlel,
-                                 <<"resource-constraint">>, _attrs, _els}) ->
-    'resource-constraint'.
+decode_xdata_field_value_els([], Cdata) ->
+    decode_xdata_field_value_cdata(Cdata);
+decode_xdata_field_value_els([{xmlcdata, _data} | _els],
+                            Cdata) ->
+    decode_xdata_field_value_els(_els,
+                                <<Cdata/binary, _data/binary>>);
+decode_xdata_field_value_els([_ | _els], Cdata) ->
+    decode_xdata_field_value_els(_els, Cdata).
 
-encode_error_resource_constraint('resource-constraint',
-                                _xmlns_attrs) ->
-    _els = [],
+encode_xdata_field_value(Cdata, _xmlns_attrs) ->
+    _els = encode_xdata_field_value_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"resource-constraint">>, _attrs, _els}.
+    {xmlel, <<"value">>, _attrs, _els}.
 
-decode_error_service_unavailable({xmlel,
-                                 <<"service-unavailable">>, _attrs, _els}) ->
-    'service-unavailable'.
+decode_xdata_field_value_cdata(<<>>) -> undefined;
+decode_xdata_field_value_cdata(_val) -> _val.
 
-encode_error_service_unavailable('service-unavailable',
-                                _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"service-unavailable">>, _attrs, _els}.
+encode_xdata_field_value_cdata(undefined, _acc) -> _acc;
+encode_xdata_field_value_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_error_subscription_required({xmlel,
-                                   <<"subscription-required">>, _attrs,
-                                   _els}) ->
-    'subscription-required'.
+decode_xdata_field_desc({xmlel, <<"desc">>, _attrs,
+                        _els}) ->
+    Cdata = decode_xdata_field_desc_els(_els, <<>>), Cdata.
 
-encode_error_subscription_required('subscription-required',
-                                  _xmlns_attrs) ->
-    _els = [],
+decode_xdata_field_desc_els([], Cdata) ->
+    decode_xdata_field_desc_cdata(Cdata);
+decode_xdata_field_desc_els([{xmlcdata, _data} | _els],
+                           Cdata) ->
+    decode_xdata_field_desc_els(_els,
+                               <<Cdata/binary, _data/binary>>);
+decode_xdata_field_desc_els([_ | _els], Cdata) ->
+    decode_xdata_field_desc_els(_els, Cdata).
+
+encode_xdata_field_desc(Cdata, _xmlns_attrs) ->
+    _els = encode_xdata_field_desc_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"subscription-required">>, _attrs, _els}.
+    {xmlel, <<"desc">>, _attrs, _els}.
 
-decode_error_undefined_condition({xmlel,
-                                 <<"undefined-condition">>, _attrs, _els}) ->
-    'undefined-condition'.
+decode_xdata_field_desc_cdata(<<>>) -> undefined;
+decode_xdata_field_desc_cdata(_val) -> _val.
 
-encode_error_undefined_condition('undefined-condition',
-                                _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"undefined-condition">>, _attrs, _els}.
+encode_xdata_field_desc_cdata(undefined, _acc) -> _acc;
+encode_xdata_field_desc_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_error_unexpected_request({xmlel,
-                                <<"unexpected-request">>, _attrs, _els}) ->
-    'unexpected-request'.
+decode_xdata_field_required({xmlel, <<"required">>,
+                            _attrs, _els}) ->
+    true.
 
-encode_error_unexpected_request('unexpected-request',
-                               _xmlns_attrs) ->
+encode_xdata_field_required(true, _xmlns_attrs) ->
     _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"unexpected-request">>, _attrs, _els}.
-
-decode_error_text({xmlel, <<"text">>, _attrs, _els}) ->
-    Data = decode_error_text_els(_els, <<>>),
-    Lang = decode_error_text_attrs(_attrs, undefined),
-    {text, Lang, Data}.
-
-decode_error_text_els([], Data) ->
-    decode_error_text_cdata(Data);
-decode_error_text_els([{xmlcdata, _data} | _els],
-                     Data) ->
-    decode_error_text_els(_els,
-                         <<Data/binary, _data/binary>>);
-decode_error_text_els([_ | _els], Data) ->
-    decode_error_text_els(_els, Data).
-
-decode_error_text_attrs([{<<"xml:lang">>, _val}
-                        | _attrs],
-                       _Lang) ->
-    decode_error_text_attrs(_attrs, _val);
-decode_error_text_attrs([_ | _attrs], Lang) ->
-    decode_error_text_attrs(_attrs, Lang);
-decode_error_text_attrs([], Lang) ->
-    'decode_error_text_attr_xml:lang'(Lang).
-
-encode_error_text({text, Lang, Data}, _xmlns_attrs) ->
-    _els = encode_error_text_cdata(Data, []),
-    _attrs = 'encode_error_text_attr_xml:lang'(Lang,
-                                              _xmlns_attrs),
-    {xmlel, <<"text">>, _attrs, _els}.
+    {xmlel, <<"required">>, _attrs, _els}.
 
-'decode_error_text_attr_xml:lang'(undefined) ->
-    undefined;
-'decode_error_text_attr_xml:lang'(_val) -> _val.
+decode_vcard({xmlel, <<"vCard">>, _attrs, _els}) ->
+    {Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+     Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+     Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+     Fn, Version, N, Photo, Logo, Geo} =
+       decode_vcard_els(_els, undefined, [], undefined, [],
+                        undefined, undefined, undefined, undefined, undefined,
+                        undefined, undefined, undefined, undefined, undefined,
+                        undefined, undefined, undefined, undefined, undefined,
+                        undefined, [], [], [], undefined, undefined, undefined,
+                        undefined, undefined, undefined),
+    {vcard, Version, Fn, N, Nickname, Photo, Bday, Adr,
+     Label, Tel, Email, Jabberid, Mailer, Tz, Geo, Title,
+     Role, Logo, Org, Categories, Note, Prodid, Rev,
+     Sort_string, Sound, Uid, Url, Class, Key, Desc}.
 
-'encode_error_text_attr_xml:lang'(undefined, _acc) ->
-    _acc;
-'encode_error_text_attr_xml:lang'(_val, _acc) ->
-    [{<<"xml:lang">>, _val} | _acc].
-
-decode_error_text_cdata(<<>>) -> undefined;
-decode_error_text_cdata(_val) -> _val.
-
-encode_error_text_cdata(undefined, _acc) -> _acc;
-encode_error_text_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
-
-decode_error({xmlel, <<"error">>, _attrs, _els}) ->
-    {Text, Reason} = decode_error_els(_els, undefined,
-                                     undefined),
-    {Type, By} = decode_error_attrs(_attrs, undefined,
-                                   undefined),
-    {error, Type, By, Reason, Text}.
-
-decode_error_els([], Text, Reason) -> {Text, Reason};
-decode_error_els([{xmlel, <<"text">>, _attrs, _} = _el
+decode_vcard_els([], Mailer, Adr, Class, Categories,
+                Desc, Uid, Prodid, Jabberid, Sound, Note, Role, Title,
+                Nickname, Rev, Sort_string, Org, Bday, Key, Tz, Url,
+                Email, Tel, Label, Fn, Version, N, Photo, Logo, Geo) ->
+    {Mailer, lists:reverse(Adr), Class, Categories, Desc,
+     Uid, Prodid, Jabberid, Sound, Note, Role, Title,
+     Nickname, Rev, Sort_string, Org, Bday, Key, Tz, Url,
+     lists:reverse(Email), lists:reverse(Tel),
+     lists:reverse(Label), Fn, Version, N, Photo, Logo, Geo};
+decode_vcard_els([{xmlel, <<"N">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, decode_error_text(_el), Reason);
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version,
+                           decode_vcard_N(_el), Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"bad-request">>, _attrs,
-                  _} =
-                     _el
+decode_vcard_els([{xmlel, <<"ADR">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_bad_request(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer,
+                           case decode_vcard_ADR(_el) of
+                             undefined -> Adr;
+                             _new_el -> [_new_el | Adr]
+                           end,
+                           Class, Categories, Desc, Uid, Prodid, Jabberid,
+                           Sound, Note, Role, Title, Nickname, Rev,
+                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
+                           Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"conflict">>, _attrs, _} =
-                     _el
+decode_vcard_els([{xmlel, <<"LABEL">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_conflict(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel,
+                           case decode_vcard_LABEL(_el) of
+                             undefined -> Label;
+                             _new_el -> [_new_el | Label]
+                           end,
+                           Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"feature-not-implemented">>,
-                  _attrs, _} =
-                     _el
+decode_vcard_els([{xmlel, <<"TEL">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_feature_not_implemented(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email,
+                           case decode_vcard_TEL(_el) of
+                             undefined -> Tel;
+                             _new_el -> [_new_el | Tel]
+                           end,
+                           Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"forbidden">>, _attrs, _} =
-                     _el
+decode_vcard_els([{xmlel, <<"EMAIL">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_forbidden(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url,
+                           case decode_vcard_EMAIL(_el) of
+                             undefined -> Email;
+                             _new_el -> [_new_el | Email]
+                           end,
+                           Tel, Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"gone">>, _attrs, _} = _el
+decode_vcard_els([{xmlel, <<"GEO">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text, decode_error_gone(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, decode_vcard_GEO(_el));
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"internal-server-error">>,
-                  _attrs, _} =
-                     _el
+decode_vcard_els([{xmlel, <<"LOGO">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_internal_server_error(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           decode_vcard_LOGO(_el), Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"item-not-found">>, _attrs,
-                  _} =
-                     _el
+decode_vcard_els([{xmlel, <<"PHOTO">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_item_not_found(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N,
+                           decode_vcard_PHOTO(_el), Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"jid-malformed">>, _attrs,
-                  _} =
-                     _el
+decode_vcard_els([{xmlel, <<"ORG">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_jid_malformed(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string,
+                           decode_vcard_ORG(_el), Bday, Key, Tz, Url, Email,
+                           Tel, Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"not-acceptable">>, _attrs,
-                  _} =
-                     _el
+decode_vcard_els([{xmlel, <<"SOUND">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_not_acceptable(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid,
+                           decode_vcard_SOUND(_el), Note, Role, Title,
+                           Nickname, Rev, Sort_string, Org, Bday, Key, Tz, Url,
+                           Email, Tel, Label, Fn, Version, N, Photo, Logo,
+                           Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"not-allowed">>, _attrs,
-                  _} =
-                     _el
+decode_vcard_els([{xmlel, <<"KEY">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_not_allowed(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday,
+                           decode_vcard_KEY(_el), Tz, Url, Email, Tel, Label,
+                           Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"not-authorized">>, _attrs,
-                  _} =
+decode_vcard_els([{xmlel, <<"VERSION">>, _attrs, _} =
                      _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_not_authorized(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn,
+                           decode_vcard_VERSION(_el), N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"policy-violation">>,
-                  _attrs, _} =
-                     _el
+decode_vcard_els([{xmlel, <<"FN">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_policy_violation(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, decode_vcard_FN(_el),
+                           Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"recipient-unavailable">>,
-                  _attrs, _} =
+decode_vcard_els([{xmlel, <<"NICKNAME">>, _attrs, _} =
                      _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_recipient_unavailable(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, decode_vcard_NICKNAME(_el), Rev, Sort_string,
+                           Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn,
+                           Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"redirect">>, _attrs, _} =
-                     _el
+decode_vcard_els([{xmlel, <<"BDAY">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_redirect(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org,
+                           decode_vcard_BDAY(_el), Key, Tz, Url, Email, Tel,
+                           Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"registration-required">>,
-                  _attrs, _} =
+decode_vcard_els([{xmlel, <<"JABBERID">>, _attrs, _} =
                      _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_registration_required(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, decode_vcard_JABBERID(_el),
+                           Sound, Note, Role, Title, Nickname, Rev,
+                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
+                           Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"remote-server-not-found">>,
-                  _attrs, _} =
-                     _el
+decode_vcard_els([{xmlel, <<"MAILER">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_remote_server_not_found(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, decode_vcard_MAILER(_el), Adr,
+                           Class, Categories, Desc, Uid, Prodid, Jabberid,
+                           Sound, Note, Role, Title, Nickname, Rev,
+                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
+                           Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"remote-server-timeout">>,
-                  _attrs, _} =
-                     _el
+decode_vcard_els([{xmlel, <<"TZ">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_remote_server_timeout(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           decode_vcard_TZ(_el), Url, Email, Tel, Label, Fn,
+                           Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"resource-constraint">>,
-                  _attrs, _} =
-                     _el
+decode_vcard_els([{xmlel, <<"TITLE">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_resource_constraint(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           decode_vcard_TITLE(_el), Nickname, Rev, Sort_string,
+                           Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn,
+                           Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"service-unavailable">>,
-                  _attrs, _} =
-                     _el
+decode_vcard_els([{xmlel, <<"ROLE">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_service_unavailable(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note,
+                           decode_vcard_ROLE(_el), Title, Nickname, Rev,
+                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
+                           Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"subscription-required">>,
-                  _attrs, _} =
-                     _el
+decode_vcard_els([{xmlel, <<"NOTE">>, _attrs, _} = _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_subscription_required(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound,
+                           decode_vcard_NOTE(_el), Role, Title, Nickname, Rev,
+                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
+                           Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"undefined-condition">>,
-                  _attrs, _} =
+decode_vcard_els([{xmlel, <<"PRODID">>, _attrs, _} = _el
+                 | _els],
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, decode_vcard_PRODID(_el), Jabberid,
+                           Sound, Note, Role, Title, Nickname, Rev,
+                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
+                           Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
+    end;
+decode_vcard_els([{xmlel, <<"REV">>, _attrs, _} = _el
+                 | _els],
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, decode_vcard_REV(_el), Sort_string,
+                           Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn,
+                           Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
+    end;
+decode_vcard_els([{xmlel, <<"SORT-STRING">>, _attrs,
+                  _} =
                      _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_undefined_condition(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, decode_vcard_SORT_STRING(_el),
+                           Org, Bday, Key, Tz, Url, Email, Tel, Label, Fn,
+                           Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([{xmlel, <<"unexpected-request">>,
-                  _attrs, _} =
+decode_vcard_els([{xmlel, <<"UID">>, _attrs, _} = _el
+                 | _els],
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, decode_vcard_UID(_el), Prodid, Jabberid,
+                           Sound, Note, Role, Title, Nickname, Rev,
+                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
+                           Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
+    end;
+decode_vcard_els([{xmlel, <<"URL">>, _attrs, _} = _el
+                 | _els],
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, decode_vcard_URL(_el), Email, Tel, Label, Fn,
+                           Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
+    end;
+decode_vcard_els([{xmlel, <<"DESC">>, _attrs, _} = _el
+                 | _els],
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           decode_vcard_DESC(_el), Uid, Prodid, Jabberid,
+                           Sound, Note, Role, Title, Nickname, Rev,
+                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
+                           Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
+    end;
+decode_vcard_els([{xmlel, <<"CATEGORIES">>, _attrs, _} =
                      _el
                  | _els],
-                Text, Reason) ->
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
-          decode_error_els(_els, Text,
-                           decode_error_unexpected_request(_el));
-       true -> decode_error_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr, Class,
+                           decode_vcard_CATEGORIES(_el), Desc, Uid, Prodid,
+                           Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
+                           Label, Fn, Version, N, Photo, Logo, Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
     end;
-decode_error_els([_ | _els], Text, Reason) ->
-    decode_error_els(_els, Text, Reason).
-
-decode_error_attrs([{<<"type">>, _val} | _attrs], _Type,
-                  By) ->
-    decode_error_attrs(_attrs, _val, By);
-decode_error_attrs([{<<"by">>, _val} | _attrs], Type,
-                  _By) ->
-    decode_error_attrs(_attrs, Type, _val);
-decode_error_attrs([_ | _attrs], Type, By) ->
-    decode_error_attrs(_attrs, Type, By);
-decode_error_attrs([], Type, By) ->
-    {decode_error_attr_type(Type),
-     decode_error_attr_by(By)}.
-
-encode_error({error, Type, By, Reason, Text},
-            _xmlns_attrs) ->
-    _els = 'encode_error_$reason'(Reason,
-                                 'encode_error_$text'(Text, [])),
-    _attrs = encode_error_attr_by(By,
-                                 encode_error_attr_type(Type, _xmlns_attrs)),
-    {xmlel, <<"error">>, _attrs, _els}.
+decode_vcard_els([{xmlel, <<"CLASS">>, _attrs, _} = _el
+                 | _els],
+                Mailer, Adr, Class, Categories, Desc, Uid, Prodid,
+                Jabberid, Sound, Note, Role, Title, Nickname, Rev,
+                Sort_string, Org, Bday, Key, Tz, Url, Email, Tel, Label,
+                Fn, Version, N, Photo, Logo, Geo) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_els(_els, Mailer, Adr,
+                           decode_vcard_CLASS(_el), Categories, Desc, Uid,
+                           Prodid, Jabberid, Sound, Note, Role, Title,
+                           Nickname, Rev, Sort_string, Org, Bday, Key, Tz, Url,
+                           Email, Tel, Label, Fn, Version, N, Photo, Logo,
+                           Geo);
+       true ->
+          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                           Desc, Uid, Prodid, Jabberid, Sound, Note, Role,
+                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
+                           Logo, Geo)
+    end;
+decode_vcard_els([_ | _els], Mailer, Adr, Class,
+                Categories, Desc, Uid, Prodid, Jabberid, Sound, Note,
+                Role, Title, Nickname, Rev, Sort_string, Org, Bday, Key,
+                Tz, Url, Email, Tel, Label, Fn, Version, N, Photo, Logo,
+                Geo) ->
+    decode_vcard_els(_els, Mailer, Adr, Class, Categories,
+                    Desc, Uid, Prodid, Jabberid, Sound, Note, Role, Title,
+                    Nickname, Rev, Sort_string, Org, Bday, Key, Tz, Url,
+                    Email, Tel, Label, Fn, Version, N, Photo, Logo, Geo).
 
-'encode_error_$text'(undefined, _acc) -> _acc;
-'encode_error_$text'(Text, _acc) ->
-    [encode_error_text(Text,
-                      [{<<"xmlns">>,
-                        <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc].
+encode_vcard({vcard, Version, Fn, N, Nickname, Photo,
+             Bday, Adr, Label, Tel, Email, Jabberid, Mailer, Tz, Geo,
+             Title, Role, Logo, Org, Categories, Note, Prodid, Rev,
+             Sort_string, Sound, Uid, Url, Class, Key, Desc},
+            _xmlns_attrs) ->
+    _els = 'encode_vcard_$geo'(Geo,
+                              'encode_vcard_$logo'(Logo,
+                                                   'encode_vcard_$photo'(Photo,
+                                                                         'encode_vcard_$n'(N,
+                                                                                           'encode_vcard_$version'(Version,
+                                                                                                                   'encode_vcard_$fn'(Fn,
+                                                                                                                                      'encode_vcard_$label'(Label,
+                                                                                                                                                            'encode_vcard_$tel'(Tel,
+                                                                                                                                                                                'encode_vcard_$email'(Email,
+                                                                                                                                                                                                      'encode_vcard_$url'(Url,
+                                                                                                                                                                                                                          'encode_vcard_$tz'(Tz,
+                                                                                                                                                                                                                                             'encode_vcard_$key'(Key,
+                                                                                                                                                                                                                                                                 'encode_vcard_$bday'(Bday,
+                                                                                                                                                                                                                                                                                      'encode_vcard_$org'(Org,
+                                                                                                                                                                                                                                                                                                          'encode_vcard_$sort_string'(Sort_string,
+                                                                                                                                                                                                                                                                                                                                      'encode_vcard_$rev'(Rev,
+                                                                                                                                                                                                                                                                                                                                                          'encode_vcard_$nickname'(Nickname,
+                                                                                                                                                                                                                                                                                                                                                                                   'encode_vcard_$title'(Title,
+                                                                                                                                                                                                                                                                                                                                                                                                         'encode_vcard_$role'(Role,
+                                                                                                                                                                                                                                                                                                                                                                                                                              'encode_vcard_$note'(Note,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                   'encode_vcard_$sound'(Sound,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                         'encode_vcard_$jabberid'(Jabberid,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  'encode_vcard_$prodid'(Prodid,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         'encode_vcard_$uid'(Uid,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             'encode_vcard_$desc'(Desc,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  'encode_vcard_$categories'(Categories,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             'encode_vcard_$class'(Class,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   'encode_vcard_$adr'(Adr,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       'encode_vcard_$mailer'(Mailer,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              []))))))))))))))))))))))))))))),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"vCard">>, _attrs, _els}.
 
-'encode_error_$reason'(undefined, _acc) -> _acc;
-'encode_error_$reason'('bad-request' = Reason, _acc) ->
-    [encode_error_bad_request(Reason,
-                             [{<<"xmlns">>,
-                               <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'(conflict = Reason, _acc) ->
-    [encode_error_conflict(Reason,
-                          [{<<"xmlns">>,
-                            <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('feature-not-implemented' =
-                          Reason,
-                      _acc) ->
-    [encode_error_feature_not_implemented(Reason,
-                                         [{<<"xmlns">>,
-                                           <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'(forbidden = Reason, _acc) ->
-    [encode_error_forbidden(Reason,
-                           [{<<"xmlns">>,
-                             <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'({gone, _} = Reason, _acc) ->
-    [encode_error_gone(Reason,
-                      [{<<"xmlns">>,
-                        <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('internal-server-error' = Reason,
-                      _acc) ->
-    [encode_error_internal_server_error(Reason,
-                                       [{<<"xmlns">>,
-                                         <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('item-not-found' = Reason,
-                      _acc) ->
-    [encode_error_item_not_found(Reason,
-                                [{<<"xmlns">>,
-                                  <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('jid-malformed' = Reason,
-                      _acc) ->
-    [encode_error_jid_malformed(Reason,
-                               [{<<"xmlns">>,
-                                 <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('not-acceptable' = Reason,
-                      _acc) ->
-    [encode_error_not_acceptable(Reason,
-                                [{<<"xmlns">>,
-                                  <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('not-allowed' = Reason, _acc) ->
-    [encode_error_not_allowed(Reason,
-                             [{<<"xmlns">>,
-                               <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('not-authorized' = Reason,
-                      _acc) ->
-    [encode_error_not_authorized(Reason,
-                                [{<<"xmlns">>,
-                                  <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('policy-violation' = Reason,
-                      _acc) ->
-    [encode_error_policy_violation(Reason,
-                                  [{<<"xmlns">>,
-                                    <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('recipient-unavailable' = Reason,
-                      _acc) ->
-    [encode_error_recipient_unavailable(Reason,
-                                       [{<<"xmlns">>,
-                                         <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'({redirect, _} = Reason, _acc) ->
-    [encode_error_redirect(Reason,
-                          [{<<"xmlns">>,
-                            <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('registration-required' = Reason,
-                      _acc) ->
-    [encode_error_registration_required(Reason,
-                                       [{<<"xmlns">>,
-                                         <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('remote-server-not-found' =
-                          Reason,
-                      _acc) ->
-    [encode_error_remote_server_not_found(Reason,
-                                         [{<<"xmlns">>,
-                                           <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('remote-server-timeout' = Reason,
-                      _acc) ->
-    [encode_error_remote_server_timeout(Reason,
-                                       [{<<"xmlns">>,
-                                         <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('resource-constraint' = Reason,
-                      _acc) ->
-    [encode_error_resource_constraint(Reason,
-                                     [{<<"xmlns">>,
-                                       <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('service-unavailable' = Reason,
-                      _acc) ->
-    [encode_error_service_unavailable(Reason,
-                                     [{<<"xmlns">>,
-                                       <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('subscription-required' = Reason,
-                      _acc) ->
-    [encode_error_subscription_required(Reason,
-                                       [{<<"xmlns">>,
-                                         <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('undefined-condition' = Reason,
-                      _acc) ->
-    [encode_error_undefined_condition(Reason,
-                                     [{<<"xmlns">>,
-                                       <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc];
-'encode_error_$reason'('unexpected-request' = Reason,
-                      _acc) ->
-    [encode_error_unexpected_request(Reason,
-                                    [{<<"xmlns">>,
-                                      <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
-     | _acc].
+'encode_vcard_$mailer'(undefined, _acc) -> _acc;
+'encode_vcard_$mailer'(Mailer, _acc) ->
+    [encode_vcard_MAILER(Mailer, []) | _acc].
 
-decode_error_attr_type(undefined) ->
-    erlang:error({missing_attr, <<"type">>, <<"error">>,
-                 <<"jabber:client">>});
-decode_error_attr_type(_val) ->
-    case catch xml_gen:dec_enum(_val,
-                               [auth, cancel, continue, modify, wait])
-       of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"type">>, <<"error">>,
-                       <<"jabber:client">>});
-      _res -> _res
-    end.
+'encode_vcard_$adr'([], _acc) -> _acc;
+'encode_vcard_$adr'([Adr | _els], _acc) ->
+    'encode_vcard_$adr'(_els,
+                       [encode_vcard_ADR(Adr, []) | _acc]).
 
-encode_error_attr_type(_val, _acc) ->
-    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
+'encode_vcard_$class'(undefined, _acc) -> _acc;
+'encode_vcard_$class'(Class, _acc) ->
+    [encode_vcard_CLASS(Class, []) | _acc].
 
-decode_error_attr_by(undefined) -> undefined;
-decode_error_attr_by(_val) -> _val.
+'encode_vcard_$categories'([], _acc) -> _acc;
+'encode_vcard_$categories'(Categories, _acc) ->
+    [encode_vcard_CATEGORIES(Categories, []) | _acc].
 
-encode_error_attr_by(undefined, _acc) -> _acc;
-encode_error_attr_by(_val, _acc) ->
-    [{<<"by">>, _val} | _acc].
+'encode_vcard_$desc'(undefined, _acc) -> _acc;
+'encode_vcard_$desc'(Desc, _acc) ->
+    [encode_vcard_DESC(Desc, []) | _acc].
 
-decode_bind_jid({xmlel, <<"jid">>, _attrs, _els}) ->
-    Cdata = decode_bind_jid_els(_els, <<>>), Cdata.
+'encode_vcard_$uid'(undefined, _acc) -> _acc;
+'encode_vcard_$uid'(Uid, _acc) ->
+    [encode_vcard_UID(Uid, []) | _acc].
 
-decode_bind_jid_els([], Cdata) ->
-    decode_bind_jid_cdata(Cdata);
-decode_bind_jid_els([{xmlcdata, _data} | _els],
-                   Cdata) ->
-    decode_bind_jid_els(_els,
-                       <<Cdata/binary, _data/binary>>);
-decode_bind_jid_els([_ | _els], Cdata) ->
-    decode_bind_jid_els(_els, Cdata).
+'encode_vcard_$prodid'(undefined, _acc) -> _acc;
+'encode_vcard_$prodid'(Prodid, _acc) ->
+    [encode_vcard_PRODID(Prodid, []) | _acc].
 
-encode_bind_jid(Cdata, _xmlns_attrs) ->
-    _els = encode_bind_jid_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"jid">>, _attrs, _els}.
+'encode_vcard_$jabberid'(undefined, _acc) -> _acc;
+'encode_vcard_$jabberid'(Jabberid, _acc) ->
+    [encode_vcard_JABBERID(Jabberid, []) | _acc].
 
-decode_bind_jid_cdata(<<>>) -> undefined;
-decode_bind_jid_cdata(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"jid">>,
-                       <<"urn:ietf:params:xml:ns:xmpp-bind">>});
-      _res -> _res
-    end.
+'encode_vcard_$sound'(undefined, _acc) -> _acc;
+'encode_vcard_$sound'(Sound, _acc) ->
+    [encode_vcard_SOUND(Sound, []) | _acc].
 
-encode_bind_jid_cdata(undefined, _acc) -> _acc;
-encode_bind_jid_cdata(_val, _acc) ->
-    [{xmlcdata, enc_jid(_val)} | _acc].
-
-decode_bind_resource({xmlel, <<"resource">>, _attrs,
-                     _els}) ->
-    Cdata = decode_bind_resource_els(_els, <<>>), Cdata.
+'encode_vcard_$note'(undefined, _acc) -> _acc;
+'encode_vcard_$note'(Note, _acc) ->
+    [encode_vcard_NOTE(Note, []) | _acc].
 
-decode_bind_resource_els([], Cdata) ->
-    decode_bind_resource_cdata(Cdata);
-decode_bind_resource_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_bind_resource_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_bind_resource_els([_ | _els], Cdata) ->
-    decode_bind_resource_els(_els, Cdata).
+'encode_vcard_$role'(undefined, _acc) -> _acc;
+'encode_vcard_$role'(Role, _acc) ->
+    [encode_vcard_ROLE(Role, []) | _acc].
 
-encode_bind_resource(Cdata, _xmlns_attrs) ->
-    _els = encode_bind_resource_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"resource">>, _attrs, _els}.
+'encode_vcard_$title'(undefined, _acc) -> _acc;
+'encode_vcard_$title'(Title, _acc) ->
+    [encode_vcard_TITLE(Title, []) | _acc].
 
-decode_bind_resource_cdata(<<>>) -> undefined;
-decode_bind_resource_cdata(_val) ->
-    case catch resourceprep(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"resource">>,
-                       <<"urn:ietf:params:xml:ns:xmpp-bind">>});
-      _res -> _res
-    end.
+'encode_vcard_$nickname'(undefined, _acc) -> _acc;
+'encode_vcard_$nickname'(Nickname, _acc) ->
+    [encode_vcard_NICKNAME(Nickname, []) | _acc].
 
-encode_bind_resource_cdata(undefined, _acc) -> _acc;
-encode_bind_resource_cdata(_val, _acc) ->
-    [{xmlcdata, resourceprep(_val)} | _acc].
+'encode_vcard_$rev'(undefined, _acc) -> _acc;
+'encode_vcard_$rev'(Rev, _acc) ->
+    [encode_vcard_REV(Rev, []) | _acc].
 
-decode_bind({xmlel, <<"bind">>, _attrs, _els}) ->
-    {Jid, Resource} = decode_bind_els(_els, undefined,
-                                     undefined),
-    {bind, Jid, Resource}.
+'encode_vcard_$sort_string'(undefined, _acc) -> _acc;
+'encode_vcard_$sort_string'(Sort_string, _acc) ->
+    [encode_vcard_SORT_STRING(Sort_string, []) | _acc].
 
-decode_bind_els([], Jid, Resource) -> {Jid, Resource};
-decode_bind_els([{xmlel, <<"jid">>, _attrs, _} = _el
-                | _els],
-               Jid, Resource) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-bind">> ->
-          decode_bind_els(_els, decode_bind_jid(_el), Resource);
-       true -> decode_bind_els(_els, Jid, Resource)
-    end;
-decode_bind_els([{xmlel, <<"resource">>, _attrs, _} =
-                    _el
-                | _els],
-               Jid, Resource) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-bind">> ->
-          decode_bind_els(_els, Jid, decode_bind_resource(_el));
-       true -> decode_bind_els(_els, Jid, Resource)
-    end;
-decode_bind_els([_ | _els], Jid, Resource) ->
-    decode_bind_els(_els, Jid, Resource).
+'encode_vcard_$org'(undefined, _acc) -> _acc;
+'encode_vcard_$org'(Org, _acc) ->
+    [encode_vcard_ORG(Org, []) | _acc].
 
-encode_bind({bind, Jid, Resource}, _xmlns_attrs) ->
-    _els = 'encode_bind_$resource'(Resource,
-                                  'encode_bind_$jid'(Jid, [])),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"bind">>, _attrs, _els}.
+'encode_vcard_$bday'(undefined, _acc) -> _acc;
+'encode_vcard_$bday'(Bday, _acc) ->
+    [encode_vcard_BDAY(Bday, []) | _acc].
 
-'encode_bind_$jid'(undefined, _acc) -> _acc;
-'encode_bind_$jid'(Jid, _acc) ->
-    [encode_bind_jid(Jid, []) | _acc].
+'encode_vcard_$key'(undefined, _acc) -> _acc;
+'encode_vcard_$key'(Key, _acc) ->
+    [encode_vcard_KEY(Key, []) | _acc].
 
-'encode_bind_$resource'(undefined, _acc) -> _acc;
-'encode_bind_$resource'(Resource, _acc) ->
-    [encode_bind_resource(Resource, []) | _acc].
+'encode_vcard_$tz'(undefined, _acc) -> _acc;
+'encode_vcard_$tz'(Tz, _acc) ->
+    [encode_vcard_TZ(Tz, []) | _acc].
 
-decode_sasl_auth({xmlel, <<"auth">>, _attrs, _els}) ->
-    Text = decode_sasl_auth_els(_els, <<>>),
-    Mechanism = decode_sasl_auth_attrs(_attrs, undefined),
-    {sasl_auth, Mechanism, Text}.
+'encode_vcard_$url'(undefined, _acc) -> _acc;
+'encode_vcard_$url'(Url, _acc) ->
+    [encode_vcard_URL(Url, []) | _acc].
 
-decode_sasl_auth_els([], Text) ->
-    decode_sasl_auth_cdata(Text);
-decode_sasl_auth_els([{xmlcdata, _data} | _els],
-                    Text) ->
-    decode_sasl_auth_els(_els,
-                        <<Text/binary, _data/binary>>);
-decode_sasl_auth_els([_ | _els], Text) ->
-    decode_sasl_auth_els(_els, Text).
+'encode_vcard_$email'([], _acc) -> _acc;
+'encode_vcard_$email'([Email | _els], _acc) ->
+    'encode_vcard_$email'(_els,
+                         [encode_vcard_EMAIL(Email, []) | _acc]).
 
-decode_sasl_auth_attrs([{<<"mechanism">>, _val}
-                       | _attrs],
-                      _Mechanism) ->
-    decode_sasl_auth_attrs(_attrs, _val);
-decode_sasl_auth_attrs([_ | _attrs], Mechanism) ->
-    decode_sasl_auth_attrs(_attrs, Mechanism);
-decode_sasl_auth_attrs([], Mechanism) ->
-    decode_sasl_auth_attr_mechanism(Mechanism).
+'encode_vcard_$tel'([], _acc) -> _acc;
+'encode_vcard_$tel'([Tel | _els], _acc) ->
+    'encode_vcard_$tel'(_els,
+                       [encode_vcard_TEL(Tel, []) | _acc]).
 
-encode_sasl_auth({sasl_auth, Mechanism, Text},
-                _xmlns_attrs) ->
-    _els = encode_sasl_auth_cdata(Text, []),
-    _attrs = encode_sasl_auth_attr_mechanism(Mechanism,
-                                            _xmlns_attrs),
-    {xmlel, <<"auth">>, _attrs, _els}.
+'encode_vcard_$label'([], _acc) -> _acc;
+'encode_vcard_$label'([Label | _els], _acc) ->
+    'encode_vcard_$label'(_els,
+                         [encode_vcard_LABEL(Label, []) | _acc]).
 
-decode_sasl_auth_attr_mechanism(undefined) ->
-    erlang:error({missing_attr, <<"mechanism">>, <<"auth">>,
-                 <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
-decode_sasl_auth_attr_mechanism(_val) -> _val.
+'encode_vcard_$fn'(undefined, _acc) -> _acc;
+'encode_vcard_$fn'(Fn, _acc) ->
+    [encode_vcard_FN(Fn, []) | _acc].
 
-encode_sasl_auth_attr_mechanism(_val, _acc) ->
-    [{<<"mechanism">>, _val} | _acc].
+'encode_vcard_$version'(undefined, _acc) -> _acc;
+'encode_vcard_$version'(Version, _acc) ->
+    [encode_vcard_VERSION(Version, []) | _acc].
 
-decode_sasl_auth_cdata(<<>>) -> undefined;
-decode_sasl_auth_cdata(_val) ->
-    case catch base64:decode(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"auth">>,
-                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
-      _res -> _res
-    end.
+'encode_vcard_$n'(undefined, _acc) -> _acc;
+'encode_vcard_$n'(N, _acc) ->
+    [encode_vcard_N(N, []) | _acc].
 
-encode_sasl_auth_cdata(undefined, _acc) -> _acc;
-encode_sasl_auth_cdata(_val, _acc) ->
-    [{xmlcdata, base64:encode(_val)} | _acc].
+'encode_vcard_$photo'(undefined, _acc) -> _acc;
+'encode_vcard_$photo'(Photo, _acc) ->
+    [encode_vcard_PHOTO(Photo, []) | _acc].
 
-decode_sasl_abort({xmlel, <<"abort">>, _attrs, _els}) ->
-    {sasl_abort}.
+'encode_vcard_$logo'(undefined, _acc) -> _acc;
+'encode_vcard_$logo'(Logo, _acc) ->
+    [encode_vcard_LOGO(Logo, []) | _acc].
 
-encode_sasl_abort({sasl_abort}, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"abort">>, _attrs, _els}.
+'encode_vcard_$geo'(undefined, _acc) -> _acc;
+'encode_vcard_$geo'(Geo, _acc) ->
+    [encode_vcard_GEO(Geo, []) | _acc].
 
-decode_sasl_challenge({xmlel, <<"challenge">>, _attrs,
-                      _els}) ->
-    Text = decode_sasl_challenge_els(_els, <<>>),
-    {sasl_challenge, Text}.
+decode_vcard_CLASS({xmlel, <<"CLASS">>, _attrs,
+                   _els}) ->
+    Class = decode_vcard_CLASS_els(_els, undefined), Class.
 
-decode_sasl_challenge_els([], Text) ->
-    decode_sasl_challenge_cdata(Text);
-decode_sasl_challenge_els([{xmlcdata, _data} | _els],
-                         Text) ->
-    decode_sasl_challenge_els(_els,
-                             <<Text/binary, _data/binary>>);
-decode_sasl_challenge_els([_ | _els], Text) ->
-    decode_sasl_challenge_els(_els, Text).
+decode_vcard_CLASS_els([], Class) -> Class;
+decode_vcard_CLASS_els([{xmlel, <<"PUBLIC">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Class) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_CLASS_els(_els, decode_vcard_PUBLIC(_el));
+       true -> decode_vcard_CLASS_els(_els, Class)
+    end;
+decode_vcard_CLASS_els([{xmlel, <<"PRIVATE">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Class) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_CLASS_els(_els, decode_vcard_PRIVATE(_el));
+       true -> decode_vcard_CLASS_els(_els, Class)
+    end;
+decode_vcard_CLASS_els([{xmlel, <<"CONFIDENTIAL">>,
+                        _attrs, _} =
+                           _el
+                       | _els],
+                      Class) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_CLASS_els(_els,
+                                 decode_vcard_CONFIDENTIAL(_el));
+       true -> decode_vcard_CLASS_els(_els, Class)
+    end;
+decode_vcard_CLASS_els([_ | _els], Class) ->
+    decode_vcard_CLASS_els(_els, Class).
 
-encode_sasl_challenge({sasl_challenge, Text},
-                     _xmlns_attrs) ->
-    _els = encode_sasl_challenge_cdata(Text, []),
+encode_vcard_CLASS(Class, _xmlns_attrs) ->
+    _els = 'encode_vcard_CLASS_$class'(Class, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"challenge">>, _attrs, _els}.
+    {xmlel, <<"CLASS">>, _attrs, _els}.
 
-decode_sasl_challenge_cdata(<<>>) -> undefined;
-decode_sasl_challenge_cdata(_val) ->
-    case catch base64:decode(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"challenge">>,
-                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
-      _res -> _res
-    end.
+'encode_vcard_CLASS_$class'(undefined, _acc) -> _acc;
+'encode_vcard_CLASS_$class'(public = Class, _acc) ->
+    [encode_vcard_PUBLIC(Class, []) | _acc];
+'encode_vcard_CLASS_$class'(private = Class, _acc) ->
+    [encode_vcard_PRIVATE(Class, []) | _acc];
+'encode_vcard_CLASS_$class'(confidential = Class,
+                           _acc) ->
+    [encode_vcard_CONFIDENTIAL(Class, []) | _acc].
 
-encode_sasl_challenge_cdata(undefined, _acc) -> _acc;
-encode_sasl_challenge_cdata(_val, _acc) ->
-    [{xmlcdata, base64:encode(_val)} | _acc].
+decode_vcard_CATEGORIES({xmlel, <<"CATEGORIES">>,
+                        _attrs, _els}) ->
+    Keywords = decode_vcard_CATEGORIES_els(_els, []),
+    Keywords.
 
-decode_sasl_response({xmlel, <<"response">>, _attrs,
-                     _els}) ->
-    Text = decode_sasl_response_els(_els, <<>>),
-    {sasl_response, Text}.
-
-decode_sasl_response_els([], Text) ->
-    decode_sasl_response_cdata(Text);
-decode_sasl_response_els([{xmlcdata, _data} | _els],
-                        Text) ->
-    decode_sasl_response_els(_els,
-                            <<Text/binary, _data/binary>>);
-decode_sasl_response_els([_ | _els], Text) ->
-    decode_sasl_response_els(_els, Text).
+decode_vcard_CATEGORIES_els([], Keywords) ->
+    lists:reverse(Keywords);
+decode_vcard_CATEGORIES_els([{xmlel, <<"KEYWORD">>,
+                             _attrs, _} =
+                                _el
+                            | _els],
+                           Keywords) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_CATEGORIES_els(_els,
+                                      case decode_vcard_KEYWORD(_el) of
+                                        undefined -> Keywords;
+                                        _new_el -> [_new_el | Keywords]
+                                      end);
+       true -> decode_vcard_CATEGORIES_els(_els, Keywords)
+    end;
+decode_vcard_CATEGORIES_els([_ | _els], Keywords) ->
+    decode_vcard_CATEGORIES_els(_els, Keywords).
 
-encode_sasl_response({sasl_response, Text},
-                    _xmlns_attrs) ->
-    _els = encode_sasl_response_cdata(Text, []),
+encode_vcard_CATEGORIES(Keywords, _xmlns_attrs) ->
+    _els = 'encode_vcard_CATEGORIES_$keywords'(Keywords,
+                                              []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"response">>, _attrs, _els}.
-
-decode_sasl_response_cdata(<<>>) -> undefined;
-decode_sasl_response_cdata(_val) ->
-    case catch base64:decode(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"response">>,
-                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
-      _res -> _res
-    end.
+    {xmlel, <<"CATEGORIES">>, _attrs, _els}.
 
-encode_sasl_response_cdata(undefined, _acc) -> _acc;
-encode_sasl_response_cdata(_val, _acc) ->
-    [{xmlcdata, base64:encode(_val)} | _acc].
+'encode_vcard_CATEGORIES_$keywords'([], _acc) -> _acc;
+'encode_vcard_CATEGORIES_$keywords'([Keywords | _els],
+                                   _acc) ->
+    'encode_vcard_CATEGORIES_$keywords'(_els,
+                                       [encode_vcard_KEYWORD(Keywords, [])
+                                        | _acc]).
 
-decode_sasl_success({xmlel, <<"success">>, _attrs,
-                    _els}) ->
-    Text = decode_sasl_success_els(_els, <<>>),
-    {sasl_success, Text}.
+decode_vcard_KEY({xmlel, <<"KEY">>, _attrs, _els}) ->
+    {Cred, Type} = decode_vcard_KEY_els(_els, [],
+                                       undefined),
+    {vcard_key, Type, Cred}.
 
-decode_sasl_success_els([], Text) ->
-    decode_sasl_success_cdata(Text);
-decode_sasl_success_els([{xmlcdata, _data} | _els],
-                       Text) ->
-    decode_sasl_success_els(_els,
-                           <<Text/binary, _data/binary>>);
-decode_sasl_success_els([_ | _els], Text) ->
-    decode_sasl_success_els(_els, Text).
+decode_vcard_KEY_els([], [Cred], Type) -> {Cred, Type};
+decode_vcard_KEY_els([{xmlel, <<"TYPE">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Cred, Type) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_KEY_els(_els, Cred,
+                               decode_vcard_TYPE(_el));
+       true -> decode_vcard_KEY_els(_els, Cred, Type)
+    end;
+decode_vcard_KEY_els([{xmlel, <<"CRED">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Cred, Type) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_KEY_els(_els,
+                               case decode_vcard_CRED(_el) of
+                                 undefined -> Cred;
+                                 _new_el -> [_new_el | Cred]
+                               end,
+                               Type);
+       true -> decode_vcard_KEY_els(_els, Cred, Type)
+    end;
+decode_vcard_KEY_els([_ | _els], Cred, Type) ->
+    decode_vcard_KEY_els(_els, Cred, Type).
 
-encode_sasl_success({sasl_success, Text},
-                   _xmlns_attrs) ->
-    _els = encode_sasl_success_cdata(Text, []),
+encode_vcard_KEY({vcard_key, Type, Cred},
+                _xmlns_attrs) ->
+    _els = 'encode_vcard_KEY_$type'(Type,
+                                   'encode_vcard_KEY_$cred'(Cred, [])),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"success">>, _attrs, _els}.
-
-decode_sasl_success_cdata(<<>>) -> undefined;
-decode_sasl_success_cdata(_val) ->
-    case catch base64:decode(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"success">>,
-                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
-      _res -> _res
-    end.
-
-encode_sasl_success_cdata(undefined, _acc) -> _acc;
-encode_sasl_success_cdata(_val, _acc) ->
-    [{xmlcdata, base64:encode(_val)} | _acc].
-
-decode_sasl_failure_text({xmlel, <<"text">>, _attrs,
-                         _els}) ->
-    Data = decode_sasl_failure_text_els(_els, <<>>),
-    Lang = decode_sasl_failure_text_attrs(_attrs,
-                                         undefined),
-    {text, Lang, Data}.
-
-decode_sasl_failure_text_els([], Data) ->
-    decode_sasl_failure_text_cdata(Data);
-decode_sasl_failure_text_els([{xmlcdata, _data} | _els],
-                            Data) ->
-    decode_sasl_failure_text_els(_els,
-                                <<Data/binary, _data/binary>>);
-decode_sasl_failure_text_els([_ | _els], Data) ->
-    decode_sasl_failure_text_els(_els, Data).
-
-decode_sasl_failure_text_attrs([{<<"xml:lang">>, _val}
-                               | _attrs],
-                              _Lang) ->
-    decode_sasl_failure_text_attrs(_attrs, _val);
-decode_sasl_failure_text_attrs([_ | _attrs], Lang) ->
-    decode_sasl_failure_text_attrs(_attrs, Lang);
-decode_sasl_failure_text_attrs([], Lang) ->
-    'decode_sasl_failure_text_attr_xml:lang'(Lang).
-
-encode_sasl_failure_text({text, Lang, Data},
-                        _xmlns_attrs) ->
-    _els = encode_sasl_failure_text_cdata(Data, []),
-    _attrs = 'encode_sasl_failure_text_attr_xml:lang'(Lang,
-                                                     _xmlns_attrs),
-    {xmlel, <<"text">>, _attrs, _els}.
-
-'decode_sasl_failure_text_attr_xml:lang'(undefined) ->
-    undefined;
-'decode_sasl_failure_text_attr_xml:lang'(_val) -> _val.
+    {xmlel, <<"KEY">>, _attrs, _els}.
 
-'encode_sasl_failure_text_attr_xml:lang'(undefined,
-                                        _acc) ->
-    _acc;
-'encode_sasl_failure_text_attr_xml:lang'(_val, _acc) ->
-    [{<<"xml:lang">>, _val} | _acc].
+'encode_vcard_KEY_$cred'(Cred, _acc) ->
+    [encode_vcard_CRED(Cred, []) | _acc].
 
-decode_sasl_failure_text_cdata(<<>>) -> undefined;
-decode_sasl_failure_text_cdata(_val) -> _val.
+'encode_vcard_KEY_$type'(undefined, _acc) -> _acc;
+'encode_vcard_KEY_$type'(Type, _acc) ->
+    [encode_vcard_TYPE(Type, []) | _acc].
 
-encode_sasl_failure_text_cdata(undefined, _acc) -> _acc;
-encode_sasl_failure_text_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_vcard_SOUND({xmlel, <<"SOUND">>, _attrs,
+                   _els}) ->
+    {Phonetic, Extval, Binval} =
+       decode_vcard_SOUND_els(_els, undefined, undefined,
+                              undefined),
+    {vcard_sound, Phonetic, Binval, Extval}.
 
-decode_sasl_failure_aborted({xmlel, <<"aborted">>,
-                            _attrs, _els}) ->
-    aborted.
+decode_vcard_SOUND_els([], Phonetic, Extval, Binval) ->
+    {Phonetic, Extval, Binval};
+decode_vcard_SOUND_els([{xmlel, <<"BINVAL">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Phonetic, Extval, Binval) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_SOUND_els(_els, Phonetic, Extval,
+                                 decode_vcard_BINVAL(_el));
+       true ->
+          decode_vcard_SOUND_els(_els, Phonetic, Extval, Binval)
+    end;
+decode_vcard_SOUND_els([{xmlel, <<"EXTVAL">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Phonetic, Extval, Binval) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_SOUND_els(_els, Phonetic,
+                                 decode_vcard_EXTVAL(_el), Binval);
+       true ->
+          decode_vcard_SOUND_els(_els, Phonetic, Extval, Binval)
+    end;
+decode_vcard_SOUND_els([{xmlel, <<"PHONETIC">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Phonetic, Extval, Binval) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_SOUND_els(_els, decode_vcard_PHONETIC(_el),
+                                 Extval, Binval);
+       true ->
+          decode_vcard_SOUND_els(_els, Phonetic, Extval, Binval)
+    end;
+decode_vcard_SOUND_els([_ | _els], Phonetic, Extval,
+                      Binval) ->
+    decode_vcard_SOUND_els(_els, Phonetic, Extval, Binval).
 
-encode_sasl_failure_aborted(aborted, _xmlns_attrs) ->
-    _els = [],
+encode_vcard_SOUND({vcard_sound, Phonetic, Binval,
+                   Extval},
+                  _xmlns_attrs) ->
+    _els = 'encode_vcard_SOUND_$binval'(Binval,
+                                       'encode_vcard_SOUND_$extval'(Extval,
+                                                                    'encode_vcard_SOUND_$phonetic'(Phonetic,
+                                                                                                   []))),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"aborted">>, _attrs, _els}.
+    {xmlel, <<"SOUND">>, _attrs, _els}.
 
-decode_sasl_failure_account_disabled({xmlel,
-                                     <<"account-disabled">>, _attrs, _els}) ->
-    'account-disabled'.
+'encode_vcard_SOUND_$phonetic'(undefined, _acc) -> _acc;
+'encode_vcard_SOUND_$phonetic'(Phonetic, _acc) ->
+    [encode_vcard_PHONETIC(Phonetic, []) | _acc].
 
-encode_sasl_failure_account_disabled('account-disabled',
-                                    _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"account-disabled">>, _attrs, _els}.
+'encode_vcard_SOUND_$extval'(undefined, _acc) -> _acc;
+'encode_vcard_SOUND_$extval'(Extval, _acc) ->
+    [encode_vcard_EXTVAL(Extval, []) | _acc].
 
-decode_sasl_failure_credentials_expired({xmlel,
-                                        <<"credentials-expired">>, _attrs,
-                                        _els}) ->
-    'credentials-expired'.
+'encode_vcard_SOUND_$binval'(undefined, _acc) -> _acc;
+'encode_vcard_SOUND_$binval'(Binval, _acc) ->
+    [encode_vcard_BINVAL(Binval, []) | _acc].
 
-encode_sasl_failure_credentials_expired('credentials-expired',
-                                       _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"credentials-expired">>, _attrs, _els}.
+decode_vcard_ORG({xmlel, <<"ORG">>, _attrs, _els}) ->
+    {Units, Name} = decode_vcard_ORG_els(_els, [], []),
+    {vcard_org, Name, Units}.
 
-decode_sasl_failure_encryption_required({xmlel,
-                                        <<"encryption-required">>, _attrs,
-                                        _els}) ->
-    'encryption-required'.
+decode_vcard_ORG_els([], Units, [Name]) ->
+    {lists:reverse(Units), Name};
+decode_vcard_ORG_els([{xmlel, <<"ORGNAME">>, _attrs,
+                      _} =
+                         _el
+                     | _els],
+                    Units, Name) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ORG_els(_els, Units,
+                               case decode_vcard_ORGNAME(_el) of
+                                 undefined -> Name;
+                                 _new_el -> [_new_el | Name]
+                               end);
+       true -> decode_vcard_ORG_els(_els, Units, Name)
+    end;
+decode_vcard_ORG_els([{xmlel, <<"ORGUNIT">>, _attrs,
+                      _} =
+                         _el
+                     | _els],
+                    Units, Name) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ORG_els(_els,
+                               case decode_vcard_ORGUNIT(_el) of
+                                 undefined -> Units;
+                                 _new_el -> [_new_el | Units]
+                               end,
+                               Name);
+       true -> decode_vcard_ORG_els(_els, Units, Name)
+    end;
+decode_vcard_ORG_els([_ | _els], Units, Name) ->
+    decode_vcard_ORG_els(_els, Units, Name).
 
-encode_sasl_failure_encryption_required('encryption-required',
-                                       _xmlns_attrs) ->
-    _els = [],
+encode_vcard_ORG({vcard_org, Name, Units},
+                _xmlns_attrs) ->
+    _els = 'encode_vcard_ORG_$name'(Name,
+                                   'encode_vcard_ORG_$units'(Units, [])),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"encryption-required">>, _attrs, _els}.
-
-decode_sasl_failure_incorrect_encoding({xmlel,
-                                       <<"incorrect-encoding">>, _attrs,
-                                       _els}) ->
-    'incorrect-encoding'.
+    {xmlel, <<"ORG">>, _attrs, _els}.
 
-encode_sasl_failure_incorrect_encoding('incorrect-encoding',
-                                      _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"incorrect-encoding">>, _attrs, _els}.
+'encode_vcard_ORG_$units'([], _acc) -> _acc;
+'encode_vcard_ORG_$units'([Units | _els], _acc) ->
+    'encode_vcard_ORG_$units'(_els,
+                             [encode_vcard_ORGUNIT(Units, []) | _acc]).
 
-decode_sasl_failure_invalid_authzid({xmlel,
-                                    <<"invalid-authzid">>, _attrs, _els}) ->
-    'invalid-authzid'.
+'encode_vcard_ORG_$name'(Name, _acc) ->
+    [encode_vcard_ORGNAME(Name, []) | _acc].
 
-encode_sasl_failure_invalid_authzid('invalid-authzid',
-                                   _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"invalid-authzid">>, _attrs, _els}.
+decode_vcard_PHOTO({xmlel, <<"PHOTO">>, _attrs,
+                   _els}) ->
+    {Type, Extval, Binval} = decode_vcard_PHOTO_els(_els,
+                                                   undefined, undefined,
+                                                   undefined),
+    {vcard_photo, Type, Binval, Extval}.
 
-decode_sasl_failure_invalid_mechanism({xmlel,
-                                      <<"invalid-mechanism">>, _attrs,
-                                      _els}) ->
-    'invalid-mechanism'.
+decode_vcard_PHOTO_els([], Type, Extval, Binval) ->
+    {Type, Extval, Binval};
+decode_vcard_PHOTO_els([{xmlel, <<"TYPE">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Type, Extval, Binval) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_PHOTO_els(_els, decode_vcard_TYPE(_el),
+                                 Extval, Binval);
+       true ->
+          decode_vcard_PHOTO_els(_els, Type, Extval, Binval)
+    end;
+decode_vcard_PHOTO_els([{xmlel, <<"BINVAL">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Type, Extval, Binval) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_PHOTO_els(_els, Type, Extval,
+                                 decode_vcard_BINVAL(_el));
+       true ->
+          decode_vcard_PHOTO_els(_els, Type, Extval, Binval)
+    end;
+decode_vcard_PHOTO_els([{xmlel, <<"EXTVAL">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Type, Extval, Binval) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_PHOTO_els(_els, Type,
+                                 decode_vcard_EXTVAL(_el), Binval);
+       true ->
+          decode_vcard_PHOTO_els(_els, Type, Extval, Binval)
+    end;
+decode_vcard_PHOTO_els([_ | _els], Type, Extval,
+                      Binval) ->
+    decode_vcard_PHOTO_els(_els, Type, Extval, Binval).
 
-encode_sasl_failure_invalid_mechanism('invalid-mechanism',
-                                     _xmlns_attrs) ->
-    _els = [],
+encode_vcard_PHOTO({vcard_photo, Type, Binval, Extval},
+                  _xmlns_attrs) ->
+    _els = 'encode_vcard_PHOTO_$binval'(Binval,
+                                       'encode_vcard_PHOTO_$extval'(Extval,
+                                                                    'encode_vcard_PHOTO_$type'(Type,
+                                                                                               []))),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"invalid-mechanism">>, _attrs, _els}.
+    {xmlel, <<"PHOTO">>, _attrs, _els}.
 
-decode_sasl_failure_malformed_request({xmlel,
-                                      <<"malformed-request">>, _attrs,
-                                      _els}) ->
-    'malformed-request'.
+'encode_vcard_PHOTO_$type'(undefined, _acc) -> _acc;
+'encode_vcard_PHOTO_$type'(Type, _acc) ->
+    [encode_vcard_TYPE(Type, []) | _acc].
 
-encode_sasl_failure_malformed_request('malformed-request',
-                                     _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"malformed-request">>, _attrs, _els}.
+'encode_vcard_PHOTO_$extval'(undefined, _acc) -> _acc;
+'encode_vcard_PHOTO_$extval'(Extval, _acc) ->
+    [encode_vcard_EXTVAL(Extval, []) | _acc].
 
-decode_sasl_failure_mechanism_too_weak({xmlel,
-                                       <<"mechanism-too-weak">>, _attrs,
-                                       _els}) ->
-    'mechanism-too-weak'.
+'encode_vcard_PHOTO_$binval'(undefined, _acc) -> _acc;
+'encode_vcard_PHOTO_$binval'(Binval, _acc) ->
+    [encode_vcard_BINVAL(Binval, []) | _acc].
 
-encode_sasl_failure_mechanism_too_weak('mechanism-too-weak',
-                                      _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"mechanism-too-weak">>, _attrs, _els}.
+decode_vcard_LOGO({xmlel, <<"LOGO">>, _attrs, _els}) ->
+    {Type, Extval, Binval} = decode_vcard_LOGO_els(_els,
+                                                  undefined, undefined,
+                                                  undefined),
+    {vcard_logo, Type, Binval, Extval}.
 
-decode_sasl_failure_not_authorized({xmlel,
-                                   <<"not-authorized">>, _attrs, _els}) ->
-    'not-authorized'.
+decode_vcard_LOGO_els([], Type, Extval, Binval) ->
+    {Type, Extval, Binval};
+decode_vcard_LOGO_els([{xmlel, <<"TYPE">>, _attrs, _} =
+                          _el
+                      | _els],
+                     Type, Extval, Binval) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_LOGO_els(_els, decode_vcard_TYPE(_el),
+                                Extval, Binval);
+       true ->
+          decode_vcard_LOGO_els(_els, Type, Extval, Binval)
+    end;
+decode_vcard_LOGO_els([{xmlel, <<"BINVAL">>, _attrs,
+                       _} =
+                          _el
+                      | _els],
+                     Type, Extval, Binval) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_LOGO_els(_els, Type, Extval,
+                                decode_vcard_BINVAL(_el));
+       true ->
+          decode_vcard_LOGO_els(_els, Type, Extval, Binval)
+    end;
+decode_vcard_LOGO_els([{xmlel, <<"EXTVAL">>, _attrs,
+                       _} =
+                          _el
+                      | _els],
+                     Type, Extval, Binval) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_LOGO_els(_els, Type,
+                                decode_vcard_EXTVAL(_el), Binval);
+       true ->
+          decode_vcard_LOGO_els(_els, Type, Extval, Binval)
+    end;
+decode_vcard_LOGO_els([_ | _els], Type, Extval,
+                     Binval) ->
+    decode_vcard_LOGO_els(_els, Type, Extval, Binval).
 
-encode_sasl_failure_not_authorized('not-authorized',
-                                  _xmlns_attrs) ->
-    _els = [],
+encode_vcard_LOGO({vcard_logo, Type, Binval, Extval},
+                 _xmlns_attrs) ->
+    _els = 'encode_vcard_LOGO_$binval'(Binval,
+                                      'encode_vcard_LOGO_$extval'(Extval,
+                                                                  'encode_vcard_LOGO_$type'(Type,
+                                                                                            []))),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"not-authorized">>, _attrs, _els}.
+    {xmlel, <<"LOGO">>, _attrs, _els}.
 
-decode_sasl_failure_temporary_auth_failure({xmlel,
-                                           <<"temporary-auth-failure">>,
-                                           _attrs, _els}) ->
-    'temporary-auth-failure'.
+'encode_vcard_LOGO_$type'(undefined, _acc) -> _acc;
+'encode_vcard_LOGO_$type'(Type, _acc) ->
+    [encode_vcard_TYPE(Type, []) | _acc].
 
-encode_sasl_failure_temporary_auth_failure('temporary-auth-failure',
-                                          _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"temporary-auth-failure">>, _attrs, _els}.
+'encode_vcard_LOGO_$extval'(undefined, _acc) -> _acc;
+'encode_vcard_LOGO_$extval'(Extval, _acc) ->
+    [encode_vcard_EXTVAL(Extval, []) | _acc].
 
-decode_sasl_failure({xmlel, <<"failure">>, _attrs,
+'encode_vcard_LOGO_$binval'(undefined, _acc) -> _acc;
+'encode_vcard_LOGO_$binval'(Binval, _acc) ->
+    [encode_vcard_BINVAL(Binval, []) | _acc].
+
+decode_vcard_BINVAL({xmlel, <<"BINVAL">>, _attrs,
                     _els}) ->
-    {Text, Reason} = decode_sasl_failure_els(_els, [],
-                                            undefined),
-    {sasl_failure, Reason, Text}.
+    Cdata = decode_vcard_BINVAL_els(_els, <<>>), Cdata.
 
-decode_sasl_failure_els([], Text, Reason) ->
-    {lists:reverse(Text), Reason};
-decode_sasl_failure_els([{xmlel, <<"text">>, _attrs,
-                         _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els,
-                                  case decode_sasl_failure_text(_el) of
-                                    undefined -> Text;
-                                    _new_el -> [_new_el | Text]
-                                  end,
-                                  Reason);
-       true -> decode_sasl_failure_els(_els, Text, Reason)
-    end;
-decode_sasl_failure_els([{xmlel, <<"aborted">>, _attrs,
-                         _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els, Text,
-                                  decode_sasl_failure_aborted(_el));
-       true -> decode_sasl_failure_els(_els, Text, Reason)
-    end;
-decode_sasl_failure_els([{xmlel, <<"account-disabled">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
+decode_vcard_BINVAL_els([], Cdata) ->
+    decode_vcard_BINVAL_cdata(Cdata);
+decode_vcard_BINVAL_els([{xmlcdata, _data} | _els],
+                       Cdata) ->
+    decode_vcard_BINVAL_els(_els,
+                           <<Cdata/binary, _data/binary>>);
+decode_vcard_BINVAL_els([_ | _els], Cdata) ->
+    decode_vcard_BINVAL_els(_els, Cdata).
+
+encode_vcard_BINVAL(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_BINVAL_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"BINVAL">>, _attrs, _els}.
+
+decode_vcard_BINVAL_cdata(<<>>) -> undefined;
+decode_vcard_BINVAL_cdata(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"BINVAL">>,
+                       <<"vcard-temp">>});
+      _res -> _res
+    end.
+
+encode_vcard_BINVAL_cdata(undefined, _acc) -> _acc;
+encode_vcard_BINVAL_cdata(_val, _acc) ->
+    [{xmlcdata, base64:encode(_val)} | _acc].
+
+decode_vcard_GEO({xmlel, <<"GEO">>, _attrs, _els}) ->
+    {Lat, Lon} = decode_vcard_GEO_els(_els, [], []),
+    {vcard_geo, Lat, Lon}.
+
+decode_vcard_GEO_els([], [Lat], [Lon]) -> {Lat, Lon};
+decode_vcard_GEO_els([{xmlel, <<"LAT">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Lat, Lon) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els, Text,
-                                  decode_sasl_failure_account_disabled(_el));
-       true -> decode_sasl_failure_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_GEO_els(_els,
+                               case decode_vcard_LAT(_el) of
+                                 undefined -> Lat;
+                                 _new_el -> [_new_el | Lat]
+                               end,
+                               Lon);
+       true -> decode_vcard_GEO_els(_els, Lat, Lon)
     end;
-decode_sasl_failure_els([{xmlel,
-                         <<"credentials-expired">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
+decode_vcard_GEO_els([{xmlel, <<"LON">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Lat, Lon) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els, Text,
-                                  decode_sasl_failure_credentials_expired(_el));
-       true -> decode_sasl_failure_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_GEO_els(_els, Lat,
+                               case decode_vcard_LON(_el) of
+                                 undefined -> Lon;
+                                 _new_el -> [_new_el | Lon]
+                               end);
+       true -> decode_vcard_GEO_els(_els, Lat, Lon)
     end;
-decode_sasl_failure_els([{xmlel,
-                         <<"encryption-required">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
+decode_vcard_GEO_els([_ | _els], Lat, Lon) ->
+    decode_vcard_GEO_els(_els, Lat, Lon).
+
+encode_vcard_GEO({vcard_geo, Lat, Lon}, _xmlns_attrs) ->
+    _els = 'encode_vcard_GEO_$lon'(Lon,
+                                  'encode_vcard_GEO_$lat'(Lat, [])),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"GEO">>, _attrs, _els}.
+
+'encode_vcard_GEO_$lat'(Lat, _acc) ->
+    [encode_vcard_LAT(Lat, []) | _acc].
+
+'encode_vcard_GEO_$lon'(Lon, _acc) ->
+    [encode_vcard_LON(Lon, []) | _acc].
+
+decode_vcard_EMAIL({xmlel, <<"EMAIL">>, _attrs,
+                   _els}) ->
+    {X400, Userid, Internet, Home, Pref, Work} =
+       decode_vcard_EMAIL_els(_els, false, [], false, false,
+                              false, false),
+    {vcard_email, Home, Work, Internet, Pref, X400, Userid}.
+
+decode_vcard_EMAIL_els([], X400, [Userid], Internet,
+                      Home, Pref, Work) ->
+    {X400, Userid, Internet, Home, Pref, Work};
+decode_vcard_EMAIL_els([{xmlel, <<"HOME">>, _attrs, _} =
+                           _el
+                       | _els],
+                      X400, Userid, Internet, Home, Pref, Work) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els, Text,
-                                  decode_sasl_failure_encryption_required(_el));
-       true -> decode_sasl_failure_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
+                                 decode_vcard_HOME(_el), Pref, Work);
+       true ->
+          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
+                                 Home, Pref, Work)
     end;
-decode_sasl_failure_els([{xmlel,
-                         <<"incorrect-encoding">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
+decode_vcard_EMAIL_els([{xmlel, <<"WORK">>, _attrs, _} =
+                           _el
+                       | _els],
+                      X400, Userid, Internet, Home, Pref, Work) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els, Text,
-                                  decode_sasl_failure_incorrect_encoding(_el));
-       true -> decode_sasl_failure_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
+                                 Home, Pref, decode_vcard_WORK(_el));
+       true ->
+          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
+                                 Home, Pref, Work)
     end;
-decode_sasl_failure_els([{xmlel, <<"invalid-authzid">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
+decode_vcard_EMAIL_els([{xmlel, <<"INTERNET">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      X400, Userid, Internet, Home, Pref, Work) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els, Text,
-                                  decode_sasl_failure_invalid_authzid(_el));
-       true -> decode_sasl_failure_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_EMAIL_els(_els, X400, Userid,
+                                 decode_vcard_INTERNET(_el), Home, Pref, Work);
+       true ->
+          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
+                                 Home, Pref, Work)
     end;
-decode_sasl_failure_els([{xmlel,
-                         <<"invalid-mechanism">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
+decode_vcard_EMAIL_els([{xmlel, <<"PREF">>, _attrs, _} =
+                           _el
+                       | _els],
+                      X400, Userid, Internet, Home, Pref, Work) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els, Text,
-                                  decode_sasl_failure_invalid_mechanism(_el));
-       true -> decode_sasl_failure_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
+                                 Home, decode_vcard_PREF(_el), Work);
+       true ->
+          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
+                                 Home, Pref, Work)
     end;
-decode_sasl_failure_els([{xmlel,
-                         <<"malformed-request">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
+decode_vcard_EMAIL_els([{xmlel, <<"X400">>, _attrs, _} =
+                           _el
+                       | _els],
+                      X400, Userid, Internet, Home, Pref, Work) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els, Text,
-                                  decode_sasl_failure_malformed_request(_el));
-       true -> decode_sasl_failure_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_EMAIL_els(_els, decode_vcard_X400(_el),
+                                 Userid, Internet, Home, Pref, Work);
+       true ->
+          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
+                                 Home, Pref, Work)
     end;
-decode_sasl_failure_els([{xmlel,
-                         <<"mechanism-too-weak">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
+decode_vcard_EMAIL_els([{xmlel, <<"USERID">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      X400, Userid, Internet, Home, Pref, Work) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els, Text,
-                                  decode_sasl_failure_mechanism_too_weak(_el));
-       true -> decode_sasl_failure_els(_els, Text, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_EMAIL_els(_els, X400,
+                                 case decode_vcard_USERID(_el) of
+                                   undefined -> Userid;
+                                   _new_el -> [_new_el | Userid]
+                                 end,
+                                 Internet, Home, Pref, Work);
+       true ->
+          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
+                                 Home, Pref, Work)
     end;
-decode_sasl_failure_els([{xmlel, <<"not-authorized">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els, Text,
-                                  decode_sasl_failure_not_authorized(_el));
-       true -> decode_sasl_failure_els(_els, Text, Reason)
-    end;
-decode_sasl_failure_els([{xmlel,
-                         <<"temporary-auth-failure">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_failure_els(_els, Text,
-                                  decode_sasl_failure_temporary_auth_failure(_el));
-       true -> decode_sasl_failure_els(_els, Text, Reason)
-    end;
-decode_sasl_failure_els([_ | _els], Text, Reason) ->
-    decode_sasl_failure_els(_els, Text, Reason).
+decode_vcard_EMAIL_els([_ | _els], X400, Userid,
+                      Internet, Home, Pref, Work) ->
+    decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
+                          Home, Pref, Work).
 
-encode_sasl_failure({sasl_failure, Reason, Text},
-                   _xmlns_attrs) ->
-    _els = 'encode_sasl_failure_$reason'(Reason,
-                                        'encode_sasl_failure_$text'(Text, [])),
+encode_vcard_EMAIL({vcard_email, Home, Work, Internet,
+                   Pref, X400, Userid},
+                  _xmlns_attrs) ->
+    _els = 'encode_vcard_EMAIL_$work'(Work,
+                                     'encode_vcard_EMAIL_$pref'(Pref,
+                                                                'encode_vcard_EMAIL_$home'(Home,
+                                                                                           'encode_vcard_EMAIL_$internet'(Internet,
+                                                                                                                          'encode_vcard_EMAIL_$userid'(Userid,
+                                                                                                                                                       'encode_vcard_EMAIL_$x400'(X400,
+                                                                                                                                                                                  [])))))),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"failure">>, _attrs, _els}.
-
-'encode_sasl_failure_$text'([], _acc) -> _acc;
-'encode_sasl_failure_$text'([Text | _els], _acc) ->
-    'encode_sasl_failure_$text'(_els,
-                               [encode_sasl_failure_text(Text, []) | _acc]).
+    {xmlel, <<"EMAIL">>, _attrs, _els}.
 
-'encode_sasl_failure_$reason'(undefined, _acc) -> _acc;
-'encode_sasl_failure_$reason'(aborted = Reason, _acc) ->
-    [encode_sasl_failure_aborted(Reason, []) | _acc];
-'encode_sasl_failure_$reason'('account-disabled' =
-                                 Reason,
-                             _acc) ->
-    [encode_sasl_failure_account_disabled(Reason, [])
-     | _acc];
-'encode_sasl_failure_$reason'('credentials-expired' =
-                                 Reason,
-                             _acc) ->
-    [encode_sasl_failure_credentials_expired(Reason, [])
-     | _acc];
-'encode_sasl_failure_$reason'('encryption-required' =
-                                 Reason,
-                             _acc) ->
-    [encode_sasl_failure_encryption_required(Reason, [])
-     | _acc];
-'encode_sasl_failure_$reason'('incorrect-encoding' =
-                                 Reason,
-                             _acc) ->
-    [encode_sasl_failure_incorrect_encoding(Reason, [])
-     | _acc];
-'encode_sasl_failure_$reason'('invalid-authzid' =
-                                 Reason,
-                             _acc) ->
-    [encode_sasl_failure_invalid_authzid(Reason, [])
-     | _acc];
-'encode_sasl_failure_$reason'('invalid-mechanism' =
-                                 Reason,
-                             _acc) ->
-    [encode_sasl_failure_invalid_mechanism(Reason, [])
-     | _acc];
-'encode_sasl_failure_$reason'('malformed-request' =
-                                 Reason,
-                             _acc) ->
-    [encode_sasl_failure_malformed_request(Reason, [])
-     | _acc];
-'encode_sasl_failure_$reason'('mechanism-too-weak' =
-                                 Reason,
-                             _acc) ->
-    [encode_sasl_failure_mechanism_too_weak(Reason, [])
-     | _acc];
-'encode_sasl_failure_$reason'('not-authorized' = Reason,
-                             _acc) ->
-    [encode_sasl_failure_not_authorized(Reason, []) | _acc];
-'encode_sasl_failure_$reason'('temporary-auth-failure' =
-                                 Reason,
-                             _acc) ->
-    [encode_sasl_failure_temporary_auth_failure(Reason, [])
-     | _acc].
+'encode_vcard_EMAIL_$x400'(false, _acc) -> _acc;
+'encode_vcard_EMAIL_$x400'(X400, _acc) ->
+    [encode_vcard_X400(X400, []) | _acc].
 
-decode_sasl_mechanism({xmlel, <<"mechanism">>, _attrs,
-                      _els}) ->
-    Cdata = decode_sasl_mechanism_els(_els, <<>>), Cdata.
+'encode_vcard_EMAIL_$userid'(Userid, _acc) ->
+    [encode_vcard_USERID(Userid, []) | _acc].
 
-decode_sasl_mechanism_els([], Cdata) ->
-    decode_sasl_mechanism_cdata(Cdata);
-decode_sasl_mechanism_els([{xmlcdata, _data} | _els],
-                         Cdata) ->
-    decode_sasl_mechanism_els(_els,
-                             <<Cdata/binary, _data/binary>>);
-decode_sasl_mechanism_els([_ | _els], Cdata) ->
-    decode_sasl_mechanism_els(_els, Cdata).
+'encode_vcard_EMAIL_$internet'(false, _acc) -> _acc;
+'encode_vcard_EMAIL_$internet'(Internet, _acc) ->
+    [encode_vcard_INTERNET(Internet, []) | _acc].
 
-encode_sasl_mechanism(Cdata, _xmlns_attrs) ->
-    _els = encode_sasl_mechanism_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"mechanism">>, _attrs, _els}.
+'encode_vcard_EMAIL_$home'(false, _acc) -> _acc;
+'encode_vcard_EMAIL_$home'(Home, _acc) ->
+    [encode_vcard_HOME(Home, []) | _acc].
 
-decode_sasl_mechanism_cdata(<<>>) -> undefined;
-decode_sasl_mechanism_cdata(_val) -> _val.
+'encode_vcard_EMAIL_$pref'(false, _acc) -> _acc;
+'encode_vcard_EMAIL_$pref'(Pref, _acc) ->
+    [encode_vcard_PREF(Pref, []) | _acc].
 
-encode_sasl_mechanism_cdata(undefined, _acc) -> _acc;
-encode_sasl_mechanism_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_vcard_EMAIL_$work'(false, _acc) -> _acc;
+'encode_vcard_EMAIL_$work'(Work, _acc) ->
+    [encode_vcard_WORK(Work, []) | _acc].
 
-decode_sasl_mechanisms({xmlel, <<"mechanisms">>, _attrs,
-                       _els}) ->
-    List = decode_sasl_mechanisms_els(_els, []),
-    {sasl_mechanisms, List}.
+decode_vcard_TEL({xmlel, <<"TEL">>, _attrs, _els}) ->
+    {Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+     Work, Cell, Modem, Isdn, Video} =
+       decode_vcard_TEL_els(_els, [], false, false, false,
+                            false, false, false, false, false, false, false,
+                            false, false, false),
+    {vcard_tel, Home, Work, Voice, Fax, Pager, Msg, Cell,
+     Video, Bbs, Modem, Isdn, Pcs, Pref, Number}.
 
-decode_sasl_mechanisms_els([], List) ->
-    lists:reverse(List);
-decode_sasl_mechanisms_els([{xmlel, <<"mechanism">>,
-                            _attrs, _} =
-                               _el
-                           | _els],
-                          List) ->
+decode_vcard_TEL_els([], [Number], Pager, Pcs, Bbs,
+                    Voice, Home, Pref, Msg, Fax, Work, Cell, Modem, Isdn,
+                    Video) ->
+    {Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+     Work, Cell, Modem, Isdn, Video};
+decode_vcard_TEL_els([{xmlel, <<"HOME">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
-          decode_sasl_mechanisms_els(_els,
-                                     case decode_sasl_mechanism(_el) of
-                                       undefined -> List;
-                                       _new_el -> [_new_el | List]
-                                     end);
-       true -> decode_sasl_mechanisms_els(_els, List)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, decode_vcard_HOME(_el), Pref, Msg, Fax,
+                               Work, Cell, Modem, Isdn, Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
     end;
-decode_sasl_mechanisms_els([_ | _els], List) ->
-    decode_sasl_mechanisms_els(_els, List).
-
-encode_sasl_mechanisms({sasl_mechanisms, List},
-                      _xmlns_attrs) ->
-    _els = 'encode_sasl_mechanisms_$list'(List, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"mechanisms">>, _attrs, _els}.
-
-'encode_sasl_mechanisms_$list'([], _acc) -> _acc;
-'encode_sasl_mechanisms_$list'([List | _els], _acc) ->
-    'encode_sasl_mechanisms_$list'(_els,
-                                  [encode_sasl_mechanism(List, []) | _acc]).
-
-decode_starttls_required({xmlel, <<"required">>, _attrs,
-                         _els}) ->
-    true.
-
-encode_starttls_required(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"required">>, _attrs, _els}.
-
-decode_starttls({xmlel, <<"starttls">>, _attrs,
-                _els}) ->
-    Required = decode_starttls_els(_els, false),
-    {starttls, Required}.
-
-decode_starttls_els([], Required) -> Required;
-decode_starttls_els([{xmlel, <<"required">>, _attrs,
-                     _} =
-                        _el
-                    | _els],
-                   Required) ->
+decode_vcard_TEL_els([{xmlel, <<"WORK">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-tls">> ->
-          decode_starttls_els(_els,
-                              decode_starttls_required(_el));
-       true -> decode_starttls_els(_els, Required)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax,
+                               decode_vcard_WORK(_el), Cell, Modem, Isdn,
+                               Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
     end;
-decode_starttls_els([_ | _els], Required) ->
-    decode_starttls_els(_els, Required).
-
-encode_starttls({starttls, Required}, _xmlns_attrs) ->
-    _els = 'encode_starttls_$required'(Required, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"starttls">>, _attrs, _els}.
-
-'encode_starttls_$required'(false, _acc) -> _acc;
-'encode_starttls_$required'(Required, _acc) ->
-    [encode_starttls_required(Required, []) | _acc].
-
-decode_starttls_proceed({xmlel, <<"proceed">>, _attrs,
-                        _els}) ->
-    {starttls_proceed}.
-
-encode_starttls_proceed({starttls_proceed},
-                       _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"proceed">>, _attrs, _els}.
-
-decode_starttls_failure({xmlel, <<"failure">>, _attrs,
-                        _els}) ->
-    {starttls_failure}.
-
-encode_starttls_failure({starttls_failure},
-                       _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"failure">>, _attrs, _els}.
-
-decode_compress_failure_setup_failed({xmlel,
-                                     <<"setup-failed">>, _attrs, _els}) ->
-    'setup-failed'.
-
-encode_compress_failure_setup_failed('setup-failed',
-                                    _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"setup-failed">>, _attrs, _els}.
-
-decode_compress_failure_processing_failed({xmlel,
-                                          <<"processing-failed">>, _attrs,
-                                          _els}) ->
-    'processing-failed'.
-
-encode_compress_failure_processing_failed('processing-failed',
-                                         _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"processing-failed">>, _attrs, _els}.
-
-decode_compress_failure_unsupported_method({xmlel,
-                                           <<"unsupported-method">>, _attrs,
-                                           _els}) ->
-    'unsupported-method'.
-
-encode_compress_failure_unsupported_method('unsupported-method',
-                                          _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"unsupported-method">>, _attrs, _els}.
-
-decode_compress_failure({xmlel, <<"failure">>, _attrs,
-                        _els}) ->
-    Reason = decode_compress_failure_els(_els, undefined),
-    {compress_failure, Reason}.
-
-decode_compress_failure_els([], Reason) -> Reason;
-decode_compress_failure_els([{xmlel, <<"setup-failed">>,
-                             _attrs, _} =
-                                _el
-                            | _els],
-                           Reason) ->
+decode_vcard_TEL_els([{xmlel, <<"VOICE">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/compress">> ->
-          decode_compress_failure_els(_els,
-                                      decode_compress_failure_setup_failed(_el));
-       true -> decode_compress_failure_els(_els, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               decode_vcard_VOICE(_el), Home, Pref, Msg, Fax,
+                               Work, Cell, Modem, Isdn, Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
     end;
-decode_compress_failure_els([{xmlel,
-                             <<"processing-failed">>, _attrs, _} =
-                                _el
-                            | _els],
-                           Reason) ->
+decode_vcard_TEL_els([{xmlel, <<"FAX">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/compress">> ->
-          decode_compress_failure_els(_els,
-                                      decode_compress_failure_processing_failed(_el));
-       true -> decode_compress_failure_els(_els, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, decode_vcard_FAX(_el),
+                               Work, Cell, Modem, Isdn, Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
     end;
-decode_compress_failure_els([{xmlel,
-                             <<"unsupported-method">>, _attrs, _} =
-                                _el
-                            | _els],
-                           Reason) ->
+decode_vcard_TEL_els([{xmlel, <<"PAGER">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/compress">> ->
-          decode_compress_failure_els(_els,
-                                      decode_compress_failure_unsupported_method(_el));
-       true -> decode_compress_failure_els(_els, Reason)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number,
+                               decode_vcard_PAGER(_el), Pcs, Bbs, Voice, Home,
+                               Pref, Msg, Fax, Work, Cell, Modem, Isdn, Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
     end;
-decode_compress_failure_els([_ | _els], Reason) ->
-    decode_compress_failure_els(_els, Reason).
-
-encode_compress_failure({compress_failure, Reason},
-                       _xmlns_attrs) ->
-    _els = 'encode_compress_failure_$reason'(Reason, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"failure">>, _attrs, _els}.
-
-'encode_compress_failure_$reason'(undefined, _acc) ->
-    _acc;
-'encode_compress_failure_$reason'('setup-failed' =
-                                     Reason,
-                                 _acc) ->
-    [encode_compress_failure_setup_failed(Reason, [])
-     | _acc];
-'encode_compress_failure_$reason'('processing-failed' =
-                                     Reason,
-                                 _acc) ->
-    [encode_compress_failure_processing_failed(Reason, [])
-     | _acc];
-'encode_compress_failure_$reason'('unsupported-method' =
-                                     Reason,
-                                 _acc) ->
-    [encode_compress_failure_unsupported_method(Reason, [])
-     | _acc].
-
-decode_compress_method({xmlel, <<"method">>, _attrs,
-                       _els}) ->
-    Cdata = decode_compress_method_els(_els, <<>>), Cdata.
-
-decode_compress_method_els([], Cdata) ->
-    decode_compress_method_cdata(Cdata);
-decode_compress_method_els([{xmlcdata, _data} | _els],
-                          Cdata) ->
-    decode_compress_method_els(_els,
-                              <<Cdata/binary, _data/binary>>);
-decode_compress_method_els([_ | _els], Cdata) ->
-    decode_compress_method_els(_els, Cdata).
-
-encode_compress_method(Cdata, _xmlns_attrs) ->
-    _els = encode_compress_method_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"method">>, _attrs, _els}.
-
-decode_compress_method_cdata(<<>>) -> undefined;
-decode_compress_method_cdata(_val) -> _val.
-
-encode_compress_method_cdata(undefined, _acc) -> _acc;
-encode_compress_method_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
-
-decode_compress({xmlel, <<"compress">>, _attrs,
-                _els}) ->
-    Methods = decode_compress_els(_els, []),
-    {compress, Methods}.
-
-decode_compress_els([], Methods) ->
-    lists:reverse(Methods);
-decode_compress_els([{xmlel, <<"method">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Methods) ->
+decode_vcard_TEL_els([{xmlel, <<"MSG">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/compress">> ->
-          decode_compress_els(_els,
-                              case decode_compress_method(_el) of
-                                undefined -> Methods;
-                                _new_el -> [_new_el | Methods]
-                              end);
-       true -> decode_compress_els(_els, Methods)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, decode_vcard_MSG(_el), Fax,
+                               Work, Cell, Modem, Isdn, Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
     end;
-decode_compress_els([_ | _els], Methods) ->
-    decode_compress_els(_els, Methods).
-
-encode_compress({compress, Methods}, _xmlns_attrs) ->
-    _els = 'encode_compress_$methods'(Methods, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"compress">>, _attrs, _els}.
-
-'encode_compress_$methods'([], _acc) -> _acc;
-'encode_compress_$methods'([Methods | _els], _acc) ->
-    'encode_compress_$methods'(_els,
-                              [encode_compress_method(Methods, []) | _acc]).
-
-decode_compressed({xmlel, <<"compressed">>, _attrs,
-                  _els}) ->
-    {compressed}.
-
-encode_compressed({compressed}, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"compressed">>, _attrs, _els}.
-
-decode_compression_method({xmlel, <<"method">>, _attrs,
-                          _els}) ->
-    Cdata = decode_compression_method_els(_els, <<>>),
-    Cdata.
-
-decode_compression_method_els([], Cdata) ->
-    decode_compression_method_cdata(Cdata);
-decode_compression_method_els([{xmlcdata, _data}
-                              | _els],
-                             Cdata) ->
-    decode_compression_method_els(_els,
-                                 <<Cdata/binary, _data/binary>>);
-decode_compression_method_els([_ | _els], Cdata) ->
-    decode_compression_method_els(_els, Cdata).
-
-encode_compression_method(Cdata, _xmlns_attrs) ->
-    _els = encode_compression_method_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"method">>, _attrs, _els}.
-
-decode_compression_method_cdata(<<>>) -> undefined;
-decode_compression_method_cdata(_val) -> _val.
-
-encode_compression_method_cdata(undefined, _acc) ->
-    _acc;
-encode_compression_method_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
-
-decode_compression({xmlel, <<"compression">>, _attrs,
-                   _els}) ->
-    Methods = decode_compression_els(_els, []),
-    {compression, Methods}.
-
-decode_compression_els([], Methods) ->
-    lists:reverse(Methods);
-decode_compression_els([{xmlel, <<"method">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Methods) ->
+decode_vcard_TEL_els([{xmlel, <<"CELL">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/features/compress">> ->
-          decode_compression_els(_els,
-                                 case decode_compression_method(_el) of
-                                   undefined -> Methods;
-                                   _new_el -> [_new_el | Methods]
-                                 end);
-       true -> decode_compression_els(_els, Methods)
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work,
+                               decode_vcard_CELL(_el), Modem, Isdn, Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
     end;
-decode_compression_els([_ | _els], Methods) ->
-    decode_compression_els(_els, Methods).
+decode_vcard_TEL_els([{xmlel, <<"VIDEO">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, decode_vcard_VIDEO(_el));
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
+    end;
+decode_vcard_TEL_els([{xmlel, <<"BBS">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs,
+                               decode_vcard_BBS(_el), Voice, Home, Pref, Msg,
+                               Fax, Work, Cell, Modem, Isdn, Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
+    end;
+decode_vcard_TEL_els([{xmlel, <<"MODEM">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell,
+                               decode_vcard_MODEM(_el), Isdn, Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
+    end;
+decode_vcard_TEL_els([{xmlel, <<"ISDN">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               decode_vcard_ISDN(_el), Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
+    end;
+decode_vcard_TEL_els([{xmlel, <<"PCS">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager,
+                               decode_vcard_PCS(_el), Bbs, Voice, Home, Pref,
+                               Msg, Fax, Work, Cell, Modem, Isdn, Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
+    end;
+decode_vcard_TEL_els([{xmlel, <<"PREF">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, decode_vcard_PREF(_el), Msg, Fax,
+                               Work, Cell, Modem, Isdn, Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
+    end;
+decode_vcard_TEL_els([{xmlel, <<"NUMBER">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                    Work, Cell, Modem, Isdn, Video) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_TEL_els(_els,
+                               case decode_vcard_NUMBER(_el) of
+                                 undefined -> Number;
+                                 _new_el -> [_new_el | Number]
+                               end,
+                               Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
+                               Work, Cell, Modem, Isdn, Video);
+       true ->
+          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                               Isdn, Video)
+    end;
+decode_vcard_TEL_els([_ | _els], Number, Pager, Pcs,
+                    Bbs, Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
+                    Isdn, Video) ->
+    decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
+                        Voice, Home, Pref, Msg, Fax, Work, Cell, Modem, Isdn,
+                        Video).
 
-encode_compression({compression, Methods},
-                  _xmlns_attrs) ->
-    _els = 'encode_compression_$methods'(Methods, []),
+encode_vcard_TEL({vcard_tel, Home, Work, Voice, Fax,
+                 Pager, Msg, Cell, Video, Bbs, Modem, Isdn, Pcs, Pref,
+                 Number},
+                _xmlns_attrs) ->
+    _els = 'encode_vcard_TEL_$video'(Video,
+                                    'encode_vcard_TEL_$isdn'(Isdn,
+                                                             'encode_vcard_TEL_$modem'(Modem,
+                                                                                       'encode_vcard_TEL_$cell'(Cell,
+                                                                                                                'encode_vcard_TEL_$work'(Work,
+                                                                                                                                         'encode_vcard_TEL_$fax'(Fax,
+                                                                                                                                                                 'encode_vcard_TEL_$msg'(Msg,
+                                                                                                                                                                                         'encode_vcard_TEL_$pref'(Pref,
+                                                                                                                                                                                                                  'encode_vcard_TEL_$home'(Home,
+                                                                                                                                                                                                                                           'encode_vcard_TEL_$voice'(Voice,
+                                                                                                                                                                                                                                                                     'encode_vcard_TEL_$bbs'(Bbs,
+                                                                                                                                                                                                                                                                                             'encode_vcard_TEL_$pcs'(Pcs,
+                                                                                                                                                                                                                                                                                                                     'encode_vcard_TEL_$pager'(Pager,
+                                                                                                                                                                                                                                                                                                                                               'encode_vcard_TEL_$number'(Number,
+                                                                                                                                                                                                                                                                                                                                                                          [])))))))))))))),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"compression">>, _attrs, _els}.
-
-'encode_compression_$methods'([], _acc) -> _acc;
-'encode_compression_$methods'([Methods | _els], _acc) ->
-    'encode_compression_$methods'(_els,
-                                 [encode_compression_method(Methods, [])
-                                  | _acc]).
+    {xmlel, <<"TEL">>, _attrs, _els}.
 
-decode_stream_features({xmlel, <<"stream:features">>,
-                       _attrs, _els}) ->
-    __Els = decode_stream_features_els(_els, []),
-    {stream_features, __Els}.
+'encode_vcard_TEL_$number'(Number, _acc) ->
+    [encode_vcard_NUMBER(Number, []) | _acc].
 
-decode_stream_features_els([], __Els) ->
-    lists:reverse(__Els);
-decode_stream_features_els([{xmlel, _, _, _} = _el
-                           | _els],
-                          __Els) ->
-    decode_stream_features_els(_els, [decode(_el) | __Els]);
-decode_stream_features_els([_ | _els], __Els) ->
-    decode_stream_features_els(_els, __Els).
+'encode_vcard_TEL_$pager'(false, _acc) -> _acc;
+'encode_vcard_TEL_$pager'(Pager, _acc) ->
+    [encode_vcard_PAGER(Pager, []) | _acc].
 
-encode_stream_features({stream_features, __Els},
-                      _xmlns_attrs) ->
-    _els = [encode(_el) || _el <- __Els],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"stream:features">>, _attrs, _els}.
+'encode_vcard_TEL_$pcs'(false, _acc) -> _acc;
+'encode_vcard_TEL_$pcs'(Pcs, _acc) ->
+    [encode_vcard_PCS(Pcs, []) | _acc].
 
-decode_p1_push({xmlel, <<"push">>, _attrs, _els}) ->
-    {p1_push}.
+'encode_vcard_TEL_$bbs'(false, _acc) -> _acc;
+'encode_vcard_TEL_$bbs'(Bbs, _acc) ->
+    [encode_vcard_BBS(Bbs, []) | _acc].
 
-encode_p1_push({p1_push}, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"push">>, _attrs, _els}.
+'encode_vcard_TEL_$voice'(false, _acc) -> _acc;
+'encode_vcard_TEL_$voice'(Voice, _acc) ->
+    [encode_vcard_VOICE(Voice, []) | _acc].
 
-decode_p1_rebind({xmlel, <<"rebind">>, _attrs, _els}) ->
-    {p1_rebind}.
+'encode_vcard_TEL_$home'(false, _acc) -> _acc;
+'encode_vcard_TEL_$home'(Home, _acc) ->
+    [encode_vcard_HOME(Home, []) | _acc].
 
-encode_p1_rebind({p1_rebind}, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"rebind">>, _attrs, _els}.
+'encode_vcard_TEL_$pref'(false, _acc) -> _acc;
+'encode_vcard_TEL_$pref'(Pref, _acc) ->
+    [encode_vcard_PREF(Pref, []) | _acc].
 
-decode_p1_ack({xmlel, <<"ack">>, _attrs, _els}) ->
-    {p1_ack}.
+'encode_vcard_TEL_$msg'(false, _acc) -> _acc;
+'encode_vcard_TEL_$msg'(Msg, _acc) ->
+    [encode_vcard_MSG(Msg, []) | _acc].
 
-encode_p1_ack({p1_ack}, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"ack">>, _attrs, _els}.
+'encode_vcard_TEL_$fax'(false, _acc) -> _acc;
+'encode_vcard_TEL_$fax'(Fax, _acc) ->
+    [encode_vcard_FAX(Fax, []) | _acc].
 
-decode_caps({xmlel, <<"c">>, _attrs, _els}) ->
-    {Hash, Node, Ver} = decode_caps_attrs(_attrs, undefined,
-                                         undefined, undefined),
-    {caps, Hash, Node, Ver}.
+'encode_vcard_TEL_$work'(false, _acc) -> _acc;
+'encode_vcard_TEL_$work'(Work, _acc) ->
+    [encode_vcard_WORK(Work, []) | _acc].
 
-decode_caps_attrs([{<<"hash">>, _val} | _attrs], _Hash,
-                 Node, Ver) ->
-    decode_caps_attrs(_attrs, _val, Node, Ver);
-decode_caps_attrs([{<<"node">>, _val} | _attrs], Hash,
-                 _Node, Ver) ->
-    decode_caps_attrs(_attrs, Hash, _val, Ver);
-decode_caps_attrs([{<<"ver">>, _val} | _attrs], Hash,
-                 Node, _Ver) ->
-    decode_caps_attrs(_attrs, Hash, Node, _val);
-decode_caps_attrs([_ | _attrs], Hash, Node, Ver) ->
-    decode_caps_attrs(_attrs, Hash, Node, Ver);
-decode_caps_attrs([], Hash, Node, Ver) ->
-    {decode_caps_attr_hash(Hash),
-     decode_caps_attr_node(Node), decode_caps_attr_ver(Ver)}.
+'encode_vcard_TEL_$cell'(false, _acc) -> _acc;
+'encode_vcard_TEL_$cell'(Cell, _acc) ->
+    [encode_vcard_CELL(Cell, []) | _acc].
 
-encode_caps({caps, Hash, Node, Ver}, _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_caps_attr_ver(Ver,
-                                 encode_caps_attr_node(Node,
-                                                       encode_caps_attr_hash(Hash,
-                                                                             _xmlns_attrs))),
-    {xmlel, <<"c">>, _attrs, _els}.
-
-decode_caps_attr_hash(undefined) -> undefined;
-decode_caps_attr_hash(_val) -> _val.
-
-encode_caps_attr_hash(undefined, _acc) -> _acc;
-encode_caps_attr_hash(_val, _acc) ->
-    [{<<"hash">>, _val} | _acc].
-
-decode_caps_attr_node(undefined) -> undefined;
-decode_caps_attr_node(_val) -> _val.
+'encode_vcard_TEL_$modem'(false, _acc) -> _acc;
+'encode_vcard_TEL_$modem'(Modem, _acc) ->
+    [encode_vcard_MODEM(Modem, []) | _acc].
 
-encode_caps_attr_node(undefined, _acc) -> _acc;
-encode_caps_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
+'encode_vcard_TEL_$isdn'(false, _acc) -> _acc;
+'encode_vcard_TEL_$isdn'(Isdn, _acc) ->
+    [encode_vcard_ISDN(Isdn, []) | _acc].
 
-decode_caps_attr_ver(undefined) -> undefined;
-decode_caps_attr_ver(_val) ->
-    case catch base64:decode(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"ver">>, <<"c">>,
-                       <<"http://jabber.org/protocol/caps">>});
-      _res -> _res
-    end.
+'encode_vcard_TEL_$video'(false, _acc) -> _acc;
+'encode_vcard_TEL_$video'(Video, _acc) ->
+    [encode_vcard_VIDEO(Video, []) | _acc].
 
-encode_caps_attr_ver(undefined, _acc) -> _acc;
-encode_caps_attr_ver(_val, _acc) ->
-    [{<<"ver">>, base64:encode(_val)} | _acc].
+decode_vcard_LABEL({xmlel, <<"LABEL">>, _attrs,
+                   _els}) ->
+    {Line, Home, Pref, Work, Intl, Parcel, Postal, Dom} =
+       decode_vcard_LABEL_els(_els, [], false, false, false,
+                              false, false, false, false),
+    {vcard_label, Home, Work, Postal, Parcel, Dom, Intl,
+     Pref, Line}.
 
-decode_feature_register({xmlel, <<"register">>, _attrs,
-                        _els}) ->
-    {feature_register}.
+decode_vcard_LABEL_els([], Line, Home, Pref, Work, Intl,
+                      Parcel, Postal, Dom) ->
+    {lists:reverse(Line), Home, Pref, Work, Intl, Parcel,
+     Postal, Dom};
+decode_vcard_LABEL_els([{xmlel, <<"HOME">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_LABEL_els(_els, Line,
+                                 decode_vcard_HOME(_el), Pref, Work, Intl,
+                                 Parcel, Postal, Dom);
+       true ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 Intl, Parcel, Postal, Dom)
+    end;
+decode_vcard_LABEL_els([{xmlel, <<"WORK">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref,
+                                 decode_vcard_WORK(_el), Intl, Parcel, Postal,
+                                 Dom);
+       true ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 Intl, Parcel, Postal, Dom)
+    end;
+decode_vcard_LABEL_els([{xmlel, <<"POSTAL">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 Intl, Parcel, decode_vcard_POSTAL(_el), Dom);
+       true ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 Intl, Parcel, Postal, Dom)
+    end;
+decode_vcard_LABEL_els([{xmlel, <<"PARCEL">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 Intl, decode_vcard_PARCEL(_el), Postal, Dom);
+       true ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 Intl, Parcel, Postal, Dom)
+    end;
+decode_vcard_LABEL_els([{xmlel, <<"DOM">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 Intl, Parcel, Postal, decode_vcard_DOM(_el));
+       true ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 Intl, Parcel, Postal, Dom)
+    end;
+decode_vcard_LABEL_els([{xmlel, <<"INTL">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 decode_vcard_INTL(_el), Parcel, Postal, Dom);
+       true ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 Intl, Parcel, Postal, Dom)
+    end;
+decode_vcard_LABEL_els([{xmlel, <<"PREF">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_LABEL_els(_els, Line, Home,
+                                 decode_vcard_PREF(_el), Work, Intl, Parcel,
+                                 Postal, Dom);
+       true ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 Intl, Parcel, Postal, Dom)
+    end;
+decode_vcard_LABEL_els([{xmlel, <<"LINE">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_LABEL_els(_els,
+                                 case decode_vcard_LINE(_el) of
+                                   undefined -> Line;
+                                   _new_el -> [_new_el | Line]
+                                 end,
+                                 Home, Pref, Work, Intl, Parcel, Postal, Dom);
+       true ->
+          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                                 Intl, Parcel, Postal, Dom)
+    end;
+decode_vcard_LABEL_els([_ | _els], Line, Home, Pref,
+                      Work, Intl, Parcel, Postal, Dom) ->
+    decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
+                          Intl, Parcel, Postal, Dom).
 
-encode_feature_register({feature_register},
-                       _xmlns_attrs) ->
-    _els = [],
+encode_vcard_LABEL({vcard_label, Home, Work, Postal,
+                   Parcel, Dom, Intl, Pref, Line},
+                  _xmlns_attrs) ->
+    _els = 'encode_vcard_LABEL_$dom'(Dom,
+                                    'encode_vcard_LABEL_$postal'(Postal,
+                                                                 'encode_vcard_LABEL_$parcel'(Parcel,
+                                                                                              'encode_vcard_LABEL_$intl'(Intl,
+                                                                                                                         'encode_vcard_LABEL_$work'(Work,
+                                                                                                                                                    'encode_vcard_LABEL_$pref'(Pref,
+                                                                                                                                                                               'encode_vcard_LABEL_$home'(Home,
+                                                                                                                                                                                                          'encode_vcard_LABEL_$line'(Line,
+                                                                                                                                                                                                                                     [])))))))),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"register">>, _attrs, _els}.
-
-decode_register_registered({xmlel, <<"registered">>,
-                           _attrs, _els}) ->
-    true.
+    {xmlel, <<"LABEL">>, _attrs, _els}.
 
-encode_register_registered(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"registered">>, _attrs, _els}.
+'encode_vcard_LABEL_$line'([], _acc) -> _acc;
+'encode_vcard_LABEL_$line'([Line | _els], _acc) ->
+    'encode_vcard_LABEL_$line'(_els,
+                              [encode_vcard_LINE(Line, []) | _acc]).
 
-decode_register_remove({xmlel, <<"remove">>, _attrs,
-                       _els}) ->
-    true.
+'encode_vcard_LABEL_$home'(false, _acc) -> _acc;
+'encode_vcard_LABEL_$home'(Home, _acc) ->
+    [encode_vcard_HOME(Home, []) | _acc].
 
-encode_register_remove(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"remove">>, _attrs, _els}.
+'encode_vcard_LABEL_$pref'(false, _acc) -> _acc;
+'encode_vcard_LABEL_$pref'(Pref, _acc) ->
+    [encode_vcard_PREF(Pref, []) | _acc].
 
-decode_register_instructions({xmlel, <<"instructions">>,
-                             _attrs, _els}) ->
-    Cdata = decode_register_instructions_els(_els, <<>>),
-    Cdata.
+'encode_vcard_LABEL_$work'(false, _acc) -> _acc;
+'encode_vcard_LABEL_$work'(Work, _acc) ->
+    [encode_vcard_WORK(Work, []) | _acc].
 
-decode_register_instructions_els([], Cdata) ->
-    decode_register_instructions_cdata(Cdata);
-decode_register_instructions_els([{xmlcdata, _data}
-                                 | _els],
-                                Cdata) ->
-    decode_register_instructions_els(_els,
-                                    <<Cdata/binary, _data/binary>>);
-decode_register_instructions_els([_ | _els], Cdata) ->
-    decode_register_instructions_els(_els, Cdata).
+'encode_vcard_LABEL_$intl'(false, _acc) -> _acc;
+'encode_vcard_LABEL_$intl'(Intl, _acc) ->
+    [encode_vcard_INTL(Intl, []) | _acc].
 
-encode_register_instructions(Cdata, _xmlns_attrs) ->
-    _els = encode_register_instructions_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"instructions">>, _attrs, _els}.
+'encode_vcard_LABEL_$parcel'(false, _acc) -> _acc;
+'encode_vcard_LABEL_$parcel'(Parcel, _acc) ->
+    [encode_vcard_PARCEL(Parcel, []) | _acc].
 
-decode_register_instructions_cdata(<<>>) -> undefined;
-decode_register_instructions_cdata(_val) -> _val.
+'encode_vcard_LABEL_$postal'(false, _acc) -> _acc;
+'encode_vcard_LABEL_$postal'(Postal, _acc) ->
+    [encode_vcard_POSTAL(Postal, []) | _acc].
 
-encode_register_instructions_cdata(undefined, _acc) ->
-    _acc;
-encode_register_instructions_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_vcard_LABEL_$dom'(false, _acc) -> _acc;
+'encode_vcard_LABEL_$dom'(Dom, _acc) ->
+    [encode_vcard_DOM(Dom, []) | _acc].
 
-decode_register_username({xmlel, <<"username">>, _attrs,
-                         _els}) ->
-    Cdata = decode_register_username_els(_els, <<>>), Cdata.
+decode_vcard_ADR({xmlel, <<"ADR">>, _attrs, _els}) ->
+    {Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+     Locality, Work, Intl, Parcel, Postal, Dom, Region} =
+       decode_vcard_ADR_els(_els, undefined, undefined,
+                            undefined, false, false, undefined, undefined,
+                            undefined, false, false, false, false, false,
+                            undefined),
+    {vcard_adr, Home, Work, Postal, Parcel, Dom, Intl, Pref,
+     Pobox, Extadd, Street, Locality, Region, Pcode, Ctry}.
 
-decode_register_username_els([], Cdata) ->
-    decode_register_username_cdata(Cdata);
-decode_register_username_els([{xmlcdata, _data} | _els],
-                            Cdata) ->
-    decode_register_username_els(_els,
-                                <<Cdata/binary, _data/binary>>);
-decode_register_username_els([_ | _els], Cdata) ->
-    decode_register_username_els(_els, Cdata).
+decode_vcard_ADR_els([], Street, Extadd, Pcode, Home,
+                    Pref, Pobox, Ctry, Locality, Work, Intl, Parcel, Postal,
+                    Dom, Region) ->
+    {Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+     Locality, Work, Intl, Parcel, Postal, Dom, Region};
+decode_vcard_ADR_els([{xmlel, <<"HOME">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode,
+                               decode_vcard_HOME(_el), Pref, Pobox, Ctry,
+                               Locality, Work, Intl, Parcel, Postal, Dom,
+                               Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"WORK">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality,
+                               decode_vcard_WORK(_el), Intl, Parcel, Postal,
+                               Dom, Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"POSTAL">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               decode_vcard_POSTAL(_el), Dom, Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"PARCEL">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl,
+                               decode_vcard_PARCEL(_el), Postal, Dom, Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"DOM">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, decode_vcard_DOM(_el), Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"INTL">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work,
+                               decode_vcard_INTL(_el), Parcel, Postal, Dom,
+                               Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"PREF">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               decode_vcard_PREF(_el), Pobox, Ctry, Locality,
+                               Work, Intl, Parcel, Postal, Dom, Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"POBOX">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, decode_vcard_POBOX(_el), Ctry, Locality,
+                               Work, Intl, Parcel, Postal, Dom, Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"EXTADD">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street,
+                               decode_vcard_EXTADD(_el), Pcode, Home, Pref,
+                               Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"STREET">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, decode_vcard_STREET(_el),
+                               Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                               Locality, Work, Intl, Parcel, Postal, Dom,
+                               Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"LOCALITY">>, _attrs,
+                      _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, decode_vcard_LOCALITY(_el),
+                               Work, Intl, Parcel, Postal, Dom, Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"REGION">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, decode_vcard_REGION(_el));
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"PCODE">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd,
+                               decode_vcard_PCODE(_el), Home, Pref, Pobox,
+                               Ctry, Locality, Work, Intl, Parcel, Postal, Dom,
+                               Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([{xmlel, <<"CTRY">>, _attrs, _} =
+                         _el
+                     | _els],
+                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
+                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, decode_vcard_CTRY(_el), Locality,
+                               Work, Intl, Parcel, Postal, Dom, Region);
+       true ->
+          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                               Postal, Dom, Region)
+    end;
+decode_vcard_ADR_els([_ | _els], Street, Extadd, Pcode,
+                    Home, Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                    Postal, Dom, Region) ->
+    decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
+                        Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
+                        Postal, Dom, Region).
 
-encode_register_username(Cdata, _xmlns_attrs) ->
-    _els = encode_register_username_cdata(Cdata, []),
+encode_vcard_ADR({vcard_adr, Home, Work, Postal, Parcel,
+                 Dom, Intl, Pref, Pobox, Extadd, Street, Locality,
+                 Region, Pcode, Ctry},
+                _xmlns_attrs) ->
+    _els = 'encode_vcard_ADR_$region'(Region,
+                                     'encode_vcard_ADR_$dom'(Dom,
+                                                             'encode_vcard_ADR_$postal'(Postal,
+                                                                                        'encode_vcard_ADR_$parcel'(Parcel,
+                                                                                                                   'encode_vcard_ADR_$intl'(Intl,
+                                                                                                                                            'encode_vcard_ADR_$work'(Work,
+                                                                                                                                                                     'encode_vcard_ADR_$locality'(Locality,
+                                                                                                                                                                                                  'encode_vcard_ADR_$ctry'(Ctry,
+                                                                                                                                                                                                                           'encode_vcard_ADR_$pobox'(Pobox,
+                                                                                                                                                                                                                                                     'encode_vcard_ADR_$pref'(Pref,
+                                                                                                                                                                                                                                                                              'encode_vcard_ADR_$home'(Home,
+                                                                                                                                                                                                                                                                                                       'encode_vcard_ADR_$pcode'(Pcode,
+                                                                                                                                                                                                                                                                                                                                 'encode_vcard_ADR_$extadd'(Extadd,
+                                                                                                                                                                                                                                                                                                                                                            'encode_vcard_ADR_$street'(Street,
+                                                                                                                                                                                                                                                                                                                                                                                       [])))))))))))))),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"username">>, _attrs, _els}.
+    {xmlel, <<"ADR">>, _attrs, _els}.
 
-decode_register_username_cdata(<<>>) -> none;
-decode_register_username_cdata(_val) -> _val.
+'encode_vcard_ADR_$street'(undefined, _acc) -> _acc;
+'encode_vcard_ADR_$street'(Street, _acc) ->
+    [encode_vcard_STREET(Street, []) | _acc].
 
-encode_register_username_cdata(none, _acc) -> _acc;
-encode_register_username_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_vcard_ADR_$extadd'(undefined, _acc) -> _acc;
+'encode_vcard_ADR_$extadd'(Extadd, _acc) ->
+    [encode_vcard_EXTADD(Extadd, []) | _acc].
 
-decode_register_nick({xmlel, <<"nick">>, _attrs,
-                     _els}) ->
-    Cdata = decode_register_nick_els(_els, <<>>), Cdata.
+'encode_vcard_ADR_$pcode'(undefined, _acc) -> _acc;
+'encode_vcard_ADR_$pcode'(Pcode, _acc) ->
+    [encode_vcard_PCODE(Pcode, []) | _acc].
 
-decode_register_nick_els([], Cdata) ->
-    decode_register_nick_cdata(Cdata);
-decode_register_nick_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_register_nick_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_register_nick_els([_ | _els], Cdata) ->
-    decode_register_nick_els(_els, Cdata).
+'encode_vcard_ADR_$home'(false, _acc) -> _acc;
+'encode_vcard_ADR_$home'(Home, _acc) ->
+    [encode_vcard_HOME(Home, []) | _acc].
 
-encode_register_nick(Cdata, _xmlns_attrs) ->
-    _els = encode_register_nick_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"nick">>, _attrs, _els}.
+'encode_vcard_ADR_$pref'(false, _acc) -> _acc;
+'encode_vcard_ADR_$pref'(Pref, _acc) ->
+    [encode_vcard_PREF(Pref, []) | _acc].
 
-decode_register_nick_cdata(<<>>) -> none;
-decode_register_nick_cdata(_val) -> _val.
+'encode_vcard_ADR_$pobox'(undefined, _acc) -> _acc;
+'encode_vcard_ADR_$pobox'(Pobox, _acc) ->
+    [encode_vcard_POBOX(Pobox, []) | _acc].
 
-encode_register_nick_cdata(none, _acc) -> _acc;
-encode_register_nick_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_vcard_ADR_$ctry'(undefined, _acc) -> _acc;
+'encode_vcard_ADR_$ctry'(Ctry, _acc) ->
+    [encode_vcard_CTRY(Ctry, []) | _acc].
 
-decode_register_password({xmlel, <<"password">>, _attrs,
-                         _els}) ->
-    Cdata = decode_register_password_els(_els, <<>>), Cdata.
+'encode_vcard_ADR_$locality'(undefined, _acc) -> _acc;
+'encode_vcard_ADR_$locality'(Locality, _acc) ->
+    [encode_vcard_LOCALITY(Locality, []) | _acc].
 
-decode_register_password_els([], Cdata) ->
-    decode_register_password_cdata(Cdata);
-decode_register_password_els([{xmlcdata, _data} | _els],
-                            Cdata) ->
-    decode_register_password_els(_els,
-                                <<Cdata/binary, _data/binary>>);
-decode_register_password_els([_ | _els], Cdata) ->
-    decode_register_password_els(_els, Cdata).
+'encode_vcard_ADR_$work'(false, _acc) -> _acc;
+'encode_vcard_ADR_$work'(Work, _acc) ->
+    [encode_vcard_WORK(Work, []) | _acc].
 
-encode_register_password(Cdata, _xmlns_attrs) ->
-    _els = encode_register_password_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"password">>, _attrs, _els}.
+'encode_vcard_ADR_$intl'(false, _acc) -> _acc;
+'encode_vcard_ADR_$intl'(Intl, _acc) ->
+    [encode_vcard_INTL(Intl, []) | _acc].
 
-decode_register_password_cdata(<<>>) -> none;
-decode_register_password_cdata(_val) -> _val.
+'encode_vcard_ADR_$parcel'(false, _acc) -> _acc;
+'encode_vcard_ADR_$parcel'(Parcel, _acc) ->
+    [encode_vcard_PARCEL(Parcel, []) | _acc].
 
-encode_register_password_cdata(none, _acc) -> _acc;
-encode_register_password_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_vcard_ADR_$postal'(false, _acc) -> _acc;
+'encode_vcard_ADR_$postal'(Postal, _acc) ->
+    [encode_vcard_POSTAL(Postal, []) | _acc].
 
-decode_register_name({xmlel, <<"name">>, _attrs,
-                     _els}) ->
-    Cdata = decode_register_name_els(_els, <<>>), Cdata.
+'encode_vcard_ADR_$dom'(false, _acc) -> _acc;
+'encode_vcard_ADR_$dom'(Dom, _acc) ->
+    [encode_vcard_DOM(Dom, []) | _acc].
 
-decode_register_name_els([], Cdata) ->
-    decode_register_name_cdata(Cdata);
-decode_register_name_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_register_name_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_register_name_els([_ | _els], Cdata) ->
-    decode_register_name_els(_els, Cdata).
+'encode_vcard_ADR_$region'(undefined, _acc) -> _acc;
+'encode_vcard_ADR_$region'(Region, _acc) ->
+    [encode_vcard_REGION(Region, []) | _acc].
 
-encode_register_name(Cdata, _xmlns_attrs) ->
-    _els = encode_register_name_cdata(Cdata, []),
+decode_vcard_N({xmlel, <<"N">>, _attrs, _els}) ->
+    {Middle, Suffix, Prefix, Family, Given} =
+       decode_vcard_N_els(_els, undefined, undefined,
+                          undefined, undefined, undefined),
+    {vcard_name, Family, Given, Middle, Prefix, Suffix}.
+
+decode_vcard_N_els([], Middle, Suffix, Prefix, Family,
+                  Given) ->
+    {Middle, Suffix, Prefix, Family, Given};
+decode_vcard_N_els([{xmlel, <<"FAMILY">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Middle, Suffix, Prefix, Family, Given) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_N_els(_els, Middle, Suffix, Prefix,
+                             decode_vcard_FAMILY(_el), Given);
+       true ->
+          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
+                             Given)
+    end;
+decode_vcard_N_els([{xmlel, <<"GIVEN">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Middle, Suffix, Prefix, Family, Given) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
+                             decode_vcard_GIVEN(_el));
+       true ->
+          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
+                             Given)
+    end;
+decode_vcard_N_els([{xmlel, <<"MIDDLE">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Middle, Suffix, Prefix, Family, Given) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_N_els(_els, decode_vcard_MIDDLE(_el),
+                             Suffix, Prefix, Family, Given);
+       true ->
+          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
+                             Given)
+    end;
+decode_vcard_N_els([{xmlel, <<"PREFIX">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Middle, Suffix, Prefix, Family, Given) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_N_els(_els, Middle, Suffix,
+                             decode_vcard_PREFIX(_el), Family, Given);
+       true ->
+          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
+                             Given)
+    end;
+decode_vcard_N_els([{xmlel, <<"SUFFIX">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Middle, Suffix, Prefix, Family, Given) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
+          decode_vcard_N_els(_els, Middle,
+                             decode_vcard_SUFFIX(_el), Prefix, Family, Given);
+       true ->
+          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
+                             Given)
+    end;
+decode_vcard_N_els([_ | _els], Middle, Suffix, Prefix,
+                  Family, Given) ->
+    decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
+                      Given).
+
+encode_vcard_N({vcard_name, Family, Given, Middle,
+               Prefix, Suffix},
+              _xmlns_attrs) ->
+    _els = 'encode_vcard_N_$given'(Given,
+                                  'encode_vcard_N_$family'(Family,
+                                                           'encode_vcard_N_$prefix'(Prefix,
+                                                                                    'encode_vcard_N_$suffix'(Suffix,
+                                                                                                             'encode_vcard_N_$middle'(Middle,
+                                                                                                                                      []))))),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"name">>, _attrs, _els}.
+    {xmlel, <<"N">>, _attrs, _els}.
 
-decode_register_name_cdata(<<>>) -> none;
-decode_register_name_cdata(_val) -> _val.
+'encode_vcard_N_$middle'(undefined, _acc) -> _acc;
+'encode_vcard_N_$middle'(Middle, _acc) ->
+    [encode_vcard_MIDDLE(Middle, []) | _acc].
 
-encode_register_name_cdata(none, _acc) -> _acc;
-encode_register_name_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_vcard_N_$suffix'(undefined, _acc) -> _acc;
+'encode_vcard_N_$suffix'(Suffix, _acc) ->
+    [encode_vcard_SUFFIX(Suffix, []) | _acc].
 
-decode_register_first({xmlel, <<"first">>, _attrs,
-                      _els}) ->
-    Cdata = decode_register_first_els(_els, <<>>), Cdata.
+'encode_vcard_N_$prefix'(undefined, _acc) -> _acc;
+'encode_vcard_N_$prefix'(Prefix, _acc) ->
+    [encode_vcard_PREFIX(Prefix, []) | _acc].
 
-decode_register_first_els([], Cdata) ->
-    decode_register_first_cdata(Cdata);
-decode_register_first_els([{xmlcdata, _data} | _els],
-                         Cdata) ->
-    decode_register_first_els(_els,
-                             <<Cdata/binary, _data/binary>>);
-decode_register_first_els([_ | _els], Cdata) ->
-    decode_register_first_els(_els, Cdata).
+'encode_vcard_N_$family'(undefined, _acc) -> _acc;
+'encode_vcard_N_$family'(Family, _acc) ->
+    [encode_vcard_FAMILY(Family, []) | _acc].
 
-encode_register_first(Cdata, _xmlns_attrs) ->
-    _els = encode_register_first_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"first">>, _attrs, _els}.
+'encode_vcard_N_$given'(undefined, _acc) -> _acc;
+'encode_vcard_N_$given'(Given, _acc) ->
+    [encode_vcard_GIVEN(Given, []) | _acc].
 
-decode_register_first_cdata(<<>>) -> none;
-decode_register_first_cdata(_val) -> _val.
+decode_vcard_CONFIDENTIAL({xmlel, <<"CONFIDENTIAL">>,
+                          _attrs, _els}) ->
+    confidential.
 
-encode_register_first_cdata(none, _acc) -> _acc;
-encode_register_first_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_vcard_CONFIDENTIAL(confidential, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"CONFIDENTIAL">>, _attrs, _els}.
 
-decode_register_last({xmlel, <<"last">>, _attrs,
+decode_vcard_PRIVATE({xmlel, <<"PRIVATE">>, _attrs,
                      _els}) ->
-    Cdata = decode_register_last_els(_els, <<>>), Cdata.
-
-decode_register_last_els([], Cdata) ->
-    decode_register_last_cdata(Cdata);
-decode_register_last_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_register_last_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_register_last_els([_ | _els], Cdata) ->
-    decode_register_last_els(_els, Cdata).
+    private.
 
-encode_register_last(Cdata, _xmlns_attrs) ->
-    _els = encode_register_last_cdata(Cdata, []),
+encode_vcard_PRIVATE(private, _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"last">>, _attrs, _els}.
-
-decode_register_last_cdata(<<>>) -> none;
-decode_register_last_cdata(_val) -> _val.
+    {xmlel, <<"PRIVATE">>, _attrs, _els}.
 
-encode_register_last_cdata(none, _acc) -> _acc;
-encode_register_last_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_vcard_PUBLIC({xmlel, <<"PUBLIC">>, _attrs,
+                    _els}) ->
+    public.
 
-decode_register_email({xmlel, <<"email">>, _attrs,
-                      _els}) ->
-    Cdata = decode_register_email_els(_els, <<>>), Cdata.
+encode_vcard_PUBLIC(public, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"PUBLIC">>, _attrs, _els}.
 
-decode_register_email_els([], Cdata) ->
-    decode_register_email_cdata(Cdata);
-decode_register_email_els([{xmlcdata, _data} | _els],
-                         Cdata) ->
-    decode_register_email_els(_els,
-                             <<Cdata/binary, _data/binary>>);
-decode_register_email_els([_ | _els], Cdata) ->
-    decode_register_email_els(_els, Cdata).
+decode_vcard_EXTVAL({xmlel, <<"EXTVAL">>, _attrs,
+                    _els}) ->
+    Cdata = decode_vcard_EXTVAL_els(_els, <<>>), Cdata.
 
-encode_register_email(Cdata, _xmlns_attrs) ->
-    _els = encode_register_email_cdata(Cdata, []),
+decode_vcard_EXTVAL_els([], Cdata) ->
+    decode_vcard_EXTVAL_cdata(Cdata);
+decode_vcard_EXTVAL_els([{xmlcdata, _data} | _els],
+                       Cdata) ->
+    decode_vcard_EXTVAL_els(_els,
+                           <<Cdata/binary, _data/binary>>);
+decode_vcard_EXTVAL_els([_ | _els], Cdata) ->
+    decode_vcard_EXTVAL_els(_els, Cdata).
+
+encode_vcard_EXTVAL(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_EXTVAL_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"email">>, _attrs, _els}.
+    {xmlel, <<"EXTVAL">>, _attrs, _els}.
 
-decode_register_email_cdata(<<>>) -> none;
-decode_register_email_cdata(_val) -> _val.
+decode_vcard_EXTVAL_cdata(<<>>) -> undefined;
+decode_vcard_EXTVAL_cdata(_val) -> _val.
 
-encode_register_email_cdata(none, _acc) -> _acc;
-encode_register_email_cdata(_val, _acc) ->
+encode_vcard_EXTVAL_cdata(undefined, _acc) -> _acc;
+encode_vcard_EXTVAL_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_register_address({xmlel, <<"address">>, _attrs,
-                        _els}) ->
-    Cdata = decode_register_address_els(_els, <<>>), Cdata.
+decode_vcard_TYPE({xmlel, <<"TYPE">>, _attrs, _els}) ->
+    Cdata = decode_vcard_TYPE_els(_els, <<>>), Cdata.
 
-decode_register_address_els([], Cdata) ->
-    decode_register_address_cdata(Cdata);
-decode_register_address_els([{xmlcdata, _data} | _els],
-                           Cdata) ->
-    decode_register_address_els(_els,
-                               <<Cdata/binary, _data/binary>>);
-decode_register_address_els([_ | _els], Cdata) ->
-    decode_register_address_els(_els, Cdata).
+decode_vcard_TYPE_els([], Cdata) ->
+    decode_vcard_TYPE_cdata(Cdata);
+decode_vcard_TYPE_els([{xmlcdata, _data} | _els],
+                     Cdata) ->
+    decode_vcard_TYPE_els(_els,
+                         <<Cdata/binary, _data/binary>>);
+decode_vcard_TYPE_els([_ | _els], Cdata) ->
+    decode_vcard_TYPE_els(_els, Cdata).
 
-encode_register_address(Cdata, _xmlns_attrs) ->
-    _els = encode_register_address_cdata(Cdata, []),
+encode_vcard_TYPE(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_TYPE_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"address">>, _attrs, _els}.
+    {xmlel, <<"TYPE">>, _attrs, _els}.
 
-decode_register_address_cdata(<<>>) -> none;
-decode_register_address_cdata(_val) -> _val.
+decode_vcard_TYPE_cdata(<<>>) -> undefined;
+decode_vcard_TYPE_cdata(_val) -> _val.
 
-encode_register_address_cdata(none, _acc) -> _acc;
-encode_register_address_cdata(_val, _acc) ->
+encode_vcard_TYPE_cdata(undefined, _acc) -> _acc;
+encode_vcard_TYPE_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_register_city({xmlel, <<"city">>, _attrs,
-                     _els}) ->
-    Cdata = decode_register_city_els(_els, <<>>), Cdata.
+decode_vcard_DESC({xmlel, <<"DESC">>, _attrs, _els}) ->
+    Cdata = decode_vcard_DESC_els(_els, <<>>), Cdata.
 
-decode_register_city_els([], Cdata) ->
-    decode_register_city_cdata(Cdata);
-decode_register_city_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_register_city_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_register_city_els([_ | _els], Cdata) ->
-    decode_register_city_els(_els, Cdata).
+decode_vcard_DESC_els([], Cdata) ->
+    decode_vcard_DESC_cdata(Cdata);
+decode_vcard_DESC_els([{xmlcdata, _data} | _els],
+                     Cdata) ->
+    decode_vcard_DESC_els(_els,
+                         <<Cdata/binary, _data/binary>>);
+decode_vcard_DESC_els([_ | _els], Cdata) ->
+    decode_vcard_DESC_els(_els, Cdata).
 
-encode_register_city(Cdata, _xmlns_attrs) ->
-    _els = encode_register_city_cdata(Cdata, []),
+encode_vcard_DESC(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_DESC_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"city">>, _attrs, _els}.
+    {xmlel, <<"DESC">>, _attrs, _els}.
 
-decode_register_city_cdata(<<>>) -> none;
-decode_register_city_cdata(_val) -> _val.
+decode_vcard_DESC_cdata(<<>>) -> undefined;
+decode_vcard_DESC_cdata(_val) -> _val.
 
-encode_register_city_cdata(none, _acc) -> _acc;
-encode_register_city_cdata(_val, _acc) ->
+encode_vcard_DESC_cdata(undefined, _acc) -> _acc;
+encode_vcard_DESC_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_register_state({xmlel, <<"state">>, _attrs,
-                      _els}) ->
-    Cdata = decode_register_state_els(_els, <<>>), Cdata.
+decode_vcard_URL({xmlel, <<"URL">>, _attrs, _els}) ->
+    Cdata = decode_vcard_URL_els(_els, <<>>), Cdata.
 
-decode_register_state_els([], Cdata) ->
-    decode_register_state_cdata(Cdata);
-decode_register_state_els([{xmlcdata, _data} | _els],
-                         Cdata) ->
-    decode_register_state_els(_els,
-                             <<Cdata/binary, _data/binary>>);
-decode_register_state_els([_ | _els], Cdata) ->
-    decode_register_state_els(_els, Cdata).
+decode_vcard_URL_els([], Cdata) ->
+    decode_vcard_URL_cdata(Cdata);
+decode_vcard_URL_els([{xmlcdata, _data} | _els],
+                    Cdata) ->
+    decode_vcard_URL_els(_els,
+                        <<Cdata/binary, _data/binary>>);
+decode_vcard_URL_els([_ | _els], Cdata) ->
+    decode_vcard_URL_els(_els, Cdata).
 
-encode_register_state(Cdata, _xmlns_attrs) ->
-    _els = encode_register_state_cdata(Cdata, []),
+encode_vcard_URL(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_URL_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"state">>, _attrs, _els}.
+    {xmlel, <<"URL">>, _attrs, _els}.
 
-decode_register_state_cdata(<<>>) -> none;
-decode_register_state_cdata(_val) -> _val.
+decode_vcard_URL_cdata(<<>>) -> undefined;
+decode_vcard_URL_cdata(_val) -> _val.
 
-encode_register_state_cdata(none, _acc) -> _acc;
-encode_register_state_cdata(_val, _acc) ->
+encode_vcard_URL_cdata(undefined, _acc) -> _acc;
+encode_vcard_URL_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_register_zip({xmlel, <<"zip">>, _attrs, _els}) ->
-    Cdata = decode_register_zip_els(_els, <<>>), Cdata.
+decode_vcard_UID({xmlel, <<"UID">>, _attrs, _els}) ->
+    Cdata = decode_vcard_UID_els(_els, <<>>), Cdata.
 
-decode_register_zip_els([], Cdata) ->
-    decode_register_zip_cdata(Cdata);
-decode_register_zip_els([{xmlcdata, _data} | _els],
-                       Cdata) ->
-    decode_register_zip_els(_els,
-                           <<Cdata/binary, _data/binary>>);
-decode_register_zip_els([_ | _els], Cdata) ->
-    decode_register_zip_els(_els, Cdata).
+decode_vcard_UID_els([], Cdata) ->
+    decode_vcard_UID_cdata(Cdata);
+decode_vcard_UID_els([{xmlcdata, _data} | _els],
+                    Cdata) ->
+    decode_vcard_UID_els(_els,
+                        <<Cdata/binary, _data/binary>>);
+decode_vcard_UID_els([_ | _els], Cdata) ->
+    decode_vcard_UID_els(_els, Cdata).
 
-encode_register_zip(Cdata, _xmlns_attrs) ->
-    _els = encode_register_zip_cdata(Cdata, []),
+encode_vcard_UID(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_UID_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"zip">>, _attrs, _els}.
+    {xmlel, <<"UID">>, _attrs, _els}.
 
-decode_register_zip_cdata(<<>>) -> none;
-decode_register_zip_cdata(_val) -> _val.
+decode_vcard_UID_cdata(<<>>) -> undefined;
+decode_vcard_UID_cdata(_val) -> _val.
 
-encode_register_zip_cdata(none, _acc) -> _acc;
-encode_register_zip_cdata(_val, _acc) ->
+encode_vcard_UID_cdata(undefined, _acc) -> _acc;
+encode_vcard_UID_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_register_phone({xmlel, <<"phone">>, _attrs,
-                      _els}) ->
-    Cdata = decode_register_phone_els(_els, <<>>), Cdata.
+decode_vcard_SORT_STRING({xmlel, <<"SORT-STRING">>,
+                         _attrs, _els}) ->
+    Cdata = decode_vcard_SORT_STRING_els(_els, <<>>), Cdata.
 
-decode_register_phone_els([], Cdata) ->
-    decode_register_phone_cdata(Cdata);
-decode_register_phone_els([{xmlcdata, _data} | _els],
-                         Cdata) ->
-    decode_register_phone_els(_els,
-                             <<Cdata/binary, _data/binary>>);
-decode_register_phone_els([_ | _els], Cdata) ->
-    decode_register_phone_els(_els, Cdata).
+decode_vcard_SORT_STRING_els([], Cdata) ->
+    decode_vcard_SORT_STRING_cdata(Cdata);
+decode_vcard_SORT_STRING_els([{xmlcdata, _data} | _els],
+                            Cdata) ->
+    decode_vcard_SORT_STRING_els(_els,
+                                <<Cdata/binary, _data/binary>>);
+decode_vcard_SORT_STRING_els([_ | _els], Cdata) ->
+    decode_vcard_SORT_STRING_els(_els, Cdata).
 
-encode_register_phone(Cdata, _xmlns_attrs) ->
-    _els = encode_register_phone_cdata(Cdata, []),
+encode_vcard_SORT_STRING(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_SORT_STRING_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"phone">>, _attrs, _els}.
+    {xmlel, <<"SORT-STRING">>, _attrs, _els}.
 
-decode_register_phone_cdata(<<>>) -> none;
-decode_register_phone_cdata(_val) -> _val.
+decode_vcard_SORT_STRING_cdata(<<>>) -> undefined;
+decode_vcard_SORT_STRING_cdata(_val) -> _val.
 
-encode_register_phone_cdata(none, _acc) -> _acc;
-encode_register_phone_cdata(_val, _acc) ->
+encode_vcard_SORT_STRING_cdata(undefined, _acc) -> _acc;
+encode_vcard_SORT_STRING_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_register_url({xmlel, <<"url">>, _attrs, _els}) ->
-    Cdata = decode_register_url_els(_els, <<>>), Cdata.
+decode_vcard_REV({xmlel, <<"REV">>, _attrs, _els}) ->
+    Cdata = decode_vcard_REV_els(_els, <<>>), Cdata.
 
-decode_register_url_els([], Cdata) ->
-    decode_register_url_cdata(Cdata);
-decode_register_url_els([{xmlcdata, _data} | _els],
-                       Cdata) ->
-    decode_register_url_els(_els,
-                           <<Cdata/binary, _data/binary>>);
-decode_register_url_els([_ | _els], Cdata) ->
-    decode_register_url_els(_els, Cdata).
+decode_vcard_REV_els([], Cdata) ->
+    decode_vcard_REV_cdata(Cdata);
+decode_vcard_REV_els([{xmlcdata, _data} | _els],
+                    Cdata) ->
+    decode_vcard_REV_els(_els,
+                        <<Cdata/binary, _data/binary>>);
+decode_vcard_REV_els([_ | _els], Cdata) ->
+    decode_vcard_REV_els(_els, Cdata).
 
-encode_register_url(Cdata, _xmlns_attrs) ->
-    _els = encode_register_url_cdata(Cdata, []),
+encode_vcard_REV(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_REV_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"url">>, _attrs, _els}.
+    {xmlel, <<"REV">>, _attrs, _els}.
 
-decode_register_url_cdata(<<>>) -> none;
-decode_register_url_cdata(_val) -> _val.
+decode_vcard_REV_cdata(<<>>) -> undefined;
+decode_vcard_REV_cdata(_val) -> _val.
 
-encode_register_url_cdata(none, _acc) -> _acc;
-encode_register_url_cdata(_val, _acc) ->
+encode_vcard_REV_cdata(undefined, _acc) -> _acc;
+encode_vcard_REV_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_register_date({xmlel, <<"date">>, _attrs,
-                     _els}) ->
-    Cdata = decode_register_date_els(_els, <<>>), Cdata.
+decode_vcard_PRODID({xmlel, <<"PRODID">>, _attrs,
+                    _els}) ->
+    Cdata = decode_vcard_PRODID_els(_els, <<>>), Cdata.
 
-decode_register_date_els([], Cdata) ->
-    decode_register_date_cdata(Cdata);
-decode_register_date_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_register_date_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_register_date_els([_ | _els], Cdata) ->
-    decode_register_date_els(_els, Cdata).
+decode_vcard_PRODID_els([], Cdata) ->
+    decode_vcard_PRODID_cdata(Cdata);
+decode_vcard_PRODID_els([{xmlcdata, _data} | _els],
+                       Cdata) ->
+    decode_vcard_PRODID_els(_els,
+                           <<Cdata/binary, _data/binary>>);
+decode_vcard_PRODID_els([_ | _els], Cdata) ->
+    decode_vcard_PRODID_els(_els, Cdata).
 
-encode_register_date(Cdata, _xmlns_attrs) ->
-    _els = encode_register_date_cdata(Cdata, []),
+encode_vcard_PRODID(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_PRODID_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"date">>, _attrs, _els}.
+    {xmlel, <<"PRODID">>, _attrs, _els}.
 
-decode_register_date_cdata(<<>>) -> none;
-decode_register_date_cdata(_val) -> _val.
+decode_vcard_PRODID_cdata(<<>>) -> undefined;
+decode_vcard_PRODID_cdata(_val) -> _val.
 
-encode_register_date_cdata(none, _acc) -> _acc;
-encode_register_date_cdata(_val, _acc) ->
+encode_vcard_PRODID_cdata(undefined, _acc) -> _acc;
+encode_vcard_PRODID_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_register_misc({xmlel, <<"misc">>, _attrs,
-                     _els}) ->
-    Cdata = decode_register_misc_els(_els, <<>>), Cdata.
+decode_vcard_NOTE({xmlel, <<"NOTE">>, _attrs, _els}) ->
+    Cdata = decode_vcard_NOTE_els(_els, <<>>), Cdata.
 
-decode_register_misc_els([], Cdata) ->
-    decode_register_misc_cdata(Cdata);
-decode_register_misc_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_register_misc_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_register_misc_els([_ | _els], Cdata) ->
-    decode_register_misc_els(_els, Cdata).
+decode_vcard_NOTE_els([], Cdata) ->
+    decode_vcard_NOTE_cdata(Cdata);
+decode_vcard_NOTE_els([{xmlcdata, _data} | _els],
+                     Cdata) ->
+    decode_vcard_NOTE_els(_els,
+                         <<Cdata/binary, _data/binary>>);
+decode_vcard_NOTE_els([_ | _els], Cdata) ->
+    decode_vcard_NOTE_els(_els, Cdata).
 
-encode_register_misc(Cdata, _xmlns_attrs) ->
-    _els = encode_register_misc_cdata(Cdata, []),
+encode_vcard_NOTE(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_NOTE_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"misc">>, _attrs, _els}.
+    {xmlel, <<"NOTE">>, _attrs, _els}.
 
-decode_register_misc_cdata(<<>>) -> none;
-decode_register_misc_cdata(_val) -> _val.
+decode_vcard_NOTE_cdata(<<>>) -> undefined;
+decode_vcard_NOTE_cdata(_val) -> _val.
 
-encode_register_misc_cdata(none, _acc) -> _acc;
-encode_register_misc_cdata(_val, _acc) ->
+encode_vcard_NOTE_cdata(undefined, _acc) -> _acc;
+encode_vcard_NOTE_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_register_text({xmlel, <<"text">>, _attrs,
+decode_vcard_KEYWORD({xmlel, <<"KEYWORD">>, _attrs,
                      _els}) ->
-    Cdata = decode_register_text_els(_els, <<>>), Cdata.
+    Cdata = decode_vcard_KEYWORD_els(_els, <<>>), Cdata.
 
-decode_register_text_els([], Cdata) ->
-    decode_register_text_cdata(Cdata);
-decode_register_text_els([{xmlcdata, _data} | _els],
+decode_vcard_KEYWORD_els([], Cdata) ->
+    decode_vcard_KEYWORD_cdata(Cdata);
+decode_vcard_KEYWORD_els([{xmlcdata, _data} | _els],
                         Cdata) ->
-    decode_register_text_els(_els,
+    decode_vcard_KEYWORD_els(_els,
                             <<Cdata/binary, _data/binary>>);
-decode_register_text_els([_ | _els], Cdata) ->
-    decode_register_text_els(_els, Cdata).
+decode_vcard_KEYWORD_els([_ | _els], Cdata) ->
+    decode_vcard_KEYWORD_els(_els, Cdata).
 
-encode_register_text(Cdata, _xmlns_attrs) ->
-    _els = encode_register_text_cdata(Cdata, []),
+encode_vcard_KEYWORD(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_KEYWORD_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"text">>, _attrs, _els}.
+    {xmlel, <<"KEYWORD">>, _attrs, _els}.
 
-decode_register_text_cdata(<<>>) -> none;
-decode_register_text_cdata(_val) -> _val.
+decode_vcard_KEYWORD_cdata(<<>>) -> undefined;
+decode_vcard_KEYWORD_cdata(_val) -> _val.
 
-encode_register_text_cdata(none, _acc) -> _acc;
-encode_register_text_cdata(_val, _acc) ->
+encode_vcard_KEYWORD_cdata(undefined, _acc) -> _acc;
+encode_vcard_KEYWORD_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_register_key({xmlel, <<"key">>, _attrs, _els}) ->
-    Cdata = decode_register_key_els(_els, <<>>), Cdata.
+decode_vcard_ROLE({xmlel, <<"ROLE">>, _attrs, _els}) ->
+    Cdata = decode_vcard_ROLE_els(_els, <<>>), Cdata.
 
-decode_register_key_els([], Cdata) ->
-    decode_register_key_cdata(Cdata);
-decode_register_key_els([{xmlcdata, _data} | _els],
+decode_vcard_ROLE_els([], Cdata) ->
+    decode_vcard_ROLE_cdata(Cdata);
+decode_vcard_ROLE_els([{xmlcdata, _data} | _els],
+                     Cdata) ->
+    decode_vcard_ROLE_els(_els,
+                         <<Cdata/binary, _data/binary>>);
+decode_vcard_ROLE_els([_ | _els], Cdata) ->
+    decode_vcard_ROLE_els(_els, Cdata).
+
+encode_vcard_ROLE(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_ROLE_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"ROLE">>, _attrs, _els}.
+
+decode_vcard_ROLE_cdata(<<>>) -> undefined;
+decode_vcard_ROLE_cdata(_val) -> _val.
+
+encode_vcard_ROLE_cdata(undefined, _acc) -> _acc;
+encode_vcard_ROLE_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_TITLE({xmlel, <<"TITLE">>, _attrs,
+                   _els}) ->
+    Cdata = decode_vcard_TITLE_els(_els, <<>>), Cdata.
+
+decode_vcard_TITLE_els([], Cdata) ->
+    decode_vcard_TITLE_cdata(Cdata);
+decode_vcard_TITLE_els([{xmlcdata, _data} | _els],
+                      Cdata) ->
+    decode_vcard_TITLE_els(_els,
+                          <<Cdata/binary, _data/binary>>);
+decode_vcard_TITLE_els([_ | _els], Cdata) ->
+    decode_vcard_TITLE_els(_els, Cdata).
+
+encode_vcard_TITLE(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_TITLE_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"TITLE">>, _attrs, _els}.
+
+decode_vcard_TITLE_cdata(<<>>) -> undefined;
+decode_vcard_TITLE_cdata(_val) -> _val.
+
+encode_vcard_TITLE_cdata(undefined, _acc) -> _acc;
+encode_vcard_TITLE_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_TZ({xmlel, <<"TZ">>, _attrs, _els}) ->
+    Cdata = decode_vcard_TZ_els(_els, <<>>), Cdata.
+
+decode_vcard_TZ_els([], Cdata) ->
+    decode_vcard_TZ_cdata(Cdata);
+decode_vcard_TZ_els([{xmlcdata, _data} | _els],
+                   Cdata) ->
+    decode_vcard_TZ_els(_els,
+                       <<Cdata/binary, _data/binary>>);
+decode_vcard_TZ_els([_ | _els], Cdata) ->
+    decode_vcard_TZ_els(_els, Cdata).
+
+encode_vcard_TZ(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_TZ_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"TZ">>, _attrs, _els}.
+
+decode_vcard_TZ_cdata(<<>>) -> undefined;
+decode_vcard_TZ_cdata(_val) -> _val.
+
+encode_vcard_TZ_cdata(undefined, _acc) -> _acc;
+encode_vcard_TZ_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_MAILER({xmlel, <<"MAILER">>, _attrs,
+                    _els}) ->
+    Cdata = decode_vcard_MAILER_els(_els, <<>>), Cdata.
+
+decode_vcard_MAILER_els([], Cdata) ->
+    decode_vcard_MAILER_cdata(Cdata);
+decode_vcard_MAILER_els([{xmlcdata, _data} | _els],
                        Cdata) ->
-    decode_register_key_els(_els,
+    decode_vcard_MAILER_els(_els,
                            <<Cdata/binary, _data/binary>>);
-decode_register_key_els([_ | _els], Cdata) ->
-    decode_register_key_els(_els, Cdata).
+decode_vcard_MAILER_els([_ | _els], Cdata) ->
+    decode_vcard_MAILER_els(_els, Cdata).
 
-encode_register_key(Cdata, _xmlns_attrs) ->
-    _els = encode_register_key_cdata(Cdata, []),
+encode_vcard_MAILER(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_MAILER_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"key">>, _attrs, _els}.
+    {xmlel, <<"MAILER">>, _attrs, _els}.
 
-decode_register_key_cdata(<<>>) -> none;
-decode_register_key_cdata(_val) -> _val.
+decode_vcard_MAILER_cdata(<<>>) -> undefined;
+decode_vcard_MAILER_cdata(_val) -> _val.
 
-encode_register_key_cdata(none, _acc) -> _acc;
-encode_register_key_cdata(_val, _acc) ->
+encode_vcard_MAILER_cdata(undefined, _acc) -> _acc;
+encode_vcard_MAILER_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_register({xmlel, <<"query">>, _attrs, _els}) ->
-    {Zip, Misc, Address, Instructions, Text, Last, First,
-     Password, Registered, Date, Phone, State, Name,
-     Username, Remove, Key, City, Nick, Url, Email} =
-       decode_register_els(_els, undefined, undefined,
-                           undefined, undefined, undefined, undefined,
-                           undefined, undefined, false, undefined, undefined,
-                           undefined, undefined, undefined, false, undefined,
-                           undefined, undefined, undefined, undefined),
-    {register, Registered, Remove, Instructions, Username,
-     Nick, Password, Name, First, Last, Email, Address, City,
-     State, Zip, Phone, Url, Date, Misc, Text, Key}.
+decode_vcard_JABBERID({xmlel, <<"JABBERID">>, _attrs,
+                      _els}) ->
+    Cdata = decode_vcard_JABBERID_els(_els, <<>>), Cdata.
 
-decode_register_els([], Zip, Misc, Address,
-                   Instructions, Text, Last, First, Password, Registered,
-                   Date, Phone, State, Name, Username, Remove, Key, City,
-                   Nick, Url, Email) ->
-    {Zip, Misc, Address, Instructions, Text, Last, First,
-     Password, Registered, Date, Phone, State, Name,
-     Username, Remove, Key, City, Nick, Url, Email};
-decode_register_els([{xmlel, <<"registered">>, _attrs,
-                     _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              decode_register_registered(_el), Date, Phone,
-                              State, Name, Username, Remove, Key, City, Nick,
-                              Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"remove">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              decode_register_remove(_el), Key, City, Nick,
-                              Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"instructions">>, _attrs,
-                     _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              decode_register_instructions(_el), Text, Last,
-                              First, Password, Registered, Date, Phone, State,
-                              Name, Username, Remove, Key, City, Nick, Url,
-                              Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"username">>, _attrs,
-                     _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name,
-                              decode_register_username(_el), Remove, Key, City,
-                              Nick, Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"nick">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, decode_register_nick(_el),
-                              Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"password">>, _attrs,
-                     _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First,
-                              decode_register_password(_el), Registered, Date,
-                              Phone, State, Name, Username, Remove, Key, City,
-                              Nick, Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"name">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State,
-                              decode_register_name(_el), Username, Remove, Key,
-                              City, Nick, Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"first">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last,
-                              decode_register_first(_el), Password, Registered,
-                              Date, Phone, State, Name, Username, Remove, Key,
-                              City, Nick, Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"last">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, decode_register_last(_el),
-                              First, Password, Registered, Date, Phone, State,
-                              Name, Username, Remove, Key, City, Nick, Url,
-                              Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"email">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url,
-                              decode_register_email(_el));
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"address">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc,
-                              decode_register_address(_el), Instructions, Text,
-                              Last, First, Password, Registered, Date, Phone,
-                              State, Name, Username, Remove, Key, City, Nick,
-                              Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"city">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, decode_register_city(_el), Nick,
-                              Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"state">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone,
-                              decode_register_state(_el), Name, Username,
-                              Remove, Key, City, Nick, Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"zip">>, _attrs, _} = _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, decode_register_zip(_el),
-                              Misc, Address, Instructions, Text, Last, First,
-                              Password, Registered, Date, Phone, State, Name,
-                              Username, Remove, Key, City, Nick, Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"phone">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, decode_register_phone(_el),
-                              State, Name, Username, Remove, Key, City, Nick,
-                              Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"url">>, _attrs, _} = _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick,
-                              decode_register_url(_el), Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"date">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, decode_register_date(_el), Phone,
-                              State, Name, Username, Remove, Key, City, Nick,
-                              Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"misc">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip,
-                              decode_register_misc(_el), Address, Instructions,
-                              Text, Last, First, Password, Registered, Date,
-                              Phone, State, Name, Username, Remove, Key, City,
-                              Nick, Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"text">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, decode_register_text(_el), Last,
-                              First, Password, Registered, Date, Phone, State,
-                              Name, Username, Remove, Key, City, Nick, Url,
-                              Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([{xmlel, <<"key">>, _attrs, _} = _el
-                    | _els],
-                   Zip, Misc, Address, Instructions, Text, Last, First,
-                   Password, Registered, Date, Phone, State, Name,
-                   Username, Remove, Key, City, Nick, Url, Email) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, decode_register_key(_el), City, Nick,
-                              Url, Email);
-       true ->
-          decode_register_els(_els, Zip, Misc, Address,
-                              Instructions, Text, Last, First, Password,
-                              Registered, Date, Phone, State, Name, Username,
-                              Remove, Key, City, Nick, Url, Email)
-    end;
-decode_register_els([_ | _els], Zip, Misc, Address,
-                   Instructions, Text, Last, First, Password, Registered,
-                   Date, Phone, State, Name, Username, Remove, Key, City,
-                   Nick, Url, Email) ->
-    decode_register_els(_els, Zip, Misc, Address,
-                       Instructions, Text, Last, First, Password, Registered,
-                       Date, Phone, State, Name, Username, Remove, Key, City,
-                       Nick, Url, Email).
-
-encode_register({register, Registered, Remove,
-                Instructions, Username, Nick, Password, Name, First,
-                Last, Email, Address, City, State, Zip, Phone, Url,
-                Date, Misc, Text, Key},
-               _xmlns_attrs) ->
-    _els = 'encode_register_$email'(Email,
-                                   'encode_register_$url'(Url,
-                                                          'encode_register_$nick'(Nick,
-                                                                                  'encode_register_$city'(City,
-                                                                                                          'encode_register_$key'(Key,
-                                                                                                                                 'encode_register_$remove'(Remove,
-                                                                                                                                                           'encode_register_$username'(Username,
-                                                                                                                                                                                       'encode_register_$name'(Name,
-                                                                                                                                                                                                               'encode_register_$state'(State,
-                                                                                                                                                                                                                                        'encode_register_$phone'(Phone,
-                                                                                                                                                                                                                                                                 'encode_register_$date'(Date,
-                                                                                                                                                                                                                                                                                         'encode_register_$registered'(Registered,
-                                                                                                                                                                                                                                                                                                                       'encode_register_$password'(Password,
-                                                                                                                                                                                                                                                                                                                                                   'encode_register_$first'(First,
-                                                                                                                                                                                                                                                                                                                                                                            'encode_register_$last'(Last,
-                                                                                                                                                                                                                                                                                                                                                                                                    'encode_register_$text'(Text,
-                                                                                                                                                                                                                                                                                                                                                                                                                            'encode_register_$instructions'(Instructions,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                            'encode_register_$address'(Address,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       'encode_register_$misc'(Misc,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               'encode_register_$zip'(Zip,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [])))))))))))))))))))),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"query">>, _attrs, _els}.
-
-'encode_register_$zip'(undefined, _acc) -> _acc;
-'encode_register_$zip'(Zip, _acc) ->
-    [encode_register_zip(Zip, []) | _acc].
-
-'encode_register_$misc'(undefined, _acc) -> _acc;
-'encode_register_$misc'(Misc, _acc) ->
-    [encode_register_misc(Misc, []) | _acc].
-
-'encode_register_$address'(undefined, _acc) -> _acc;
-'encode_register_$address'(Address, _acc) ->
-    [encode_register_address(Address, []) | _acc].
-
-'encode_register_$instructions'(undefined, _acc) ->
-    _acc;
-'encode_register_$instructions'(Instructions, _acc) ->
-    [encode_register_instructions(Instructions, []) | _acc].
-
-'encode_register_$text'(undefined, _acc) -> _acc;
-'encode_register_$text'(Text, _acc) ->
-    [encode_register_text(Text, []) | _acc].
-
-'encode_register_$last'(undefined, _acc) -> _acc;
-'encode_register_$last'(Last, _acc) ->
-    [encode_register_last(Last, []) | _acc].
-
-'encode_register_$first'(undefined, _acc) -> _acc;
-'encode_register_$first'(First, _acc) ->
-    [encode_register_first(First, []) | _acc].
-
-'encode_register_$password'(undefined, _acc) -> _acc;
-'encode_register_$password'(Password, _acc) ->
-    [encode_register_password(Password, []) | _acc].
-
-'encode_register_$registered'(false, _acc) -> _acc;
-'encode_register_$registered'(Registered, _acc) ->
-    [encode_register_registered(Registered, []) | _acc].
-
-'encode_register_$date'(undefined, _acc) -> _acc;
-'encode_register_$date'(Date, _acc) ->
-    [encode_register_date(Date, []) | _acc].
-
-'encode_register_$phone'(undefined, _acc) -> _acc;
-'encode_register_$phone'(Phone, _acc) ->
-    [encode_register_phone(Phone, []) | _acc].
-
-'encode_register_$state'(undefined, _acc) -> _acc;
-'encode_register_$state'(State, _acc) ->
-    [encode_register_state(State, []) | _acc].
-
-'encode_register_$name'(undefined, _acc) -> _acc;
-'encode_register_$name'(Name, _acc) ->
-    [encode_register_name(Name, []) | _acc].
-
-'encode_register_$username'(undefined, _acc) -> _acc;
-'encode_register_$username'(Username, _acc) ->
-    [encode_register_username(Username, []) | _acc].
-
-'encode_register_$remove'(false, _acc) -> _acc;
-'encode_register_$remove'(Remove, _acc) ->
-    [encode_register_remove(Remove, []) | _acc].
-
-'encode_register_$key'(undefined, _acc) -> _acc;
-'encode_register_$key'(Key, _acc) ->
-    [encode_register_key(Key, []) | _acc].
-
-'encode_register_$city'(undefined, _acc) -> _acc;
-'encode_register_$city'(City, _acc) ->
-    [encode_register_city(City, []) | _acc].
-
-'encode_register_$nick'(undefined, _acc) -> _acc;
-'encode_register_$nick'(Nick, _acc) ->
-    [encode_register_nick(Nick, []) | _acc].
-
-'encode_register_$url'(undefined, _acc) -> _acc;
-'encode_register_$url'(Url, _acc) ->
-    [encode_register_url(Url, []) | _acc].
-
-'encode_register_$email'(undefined, _acc) -> _acc;
-'encode_register_$email'(Email, _acc) ->
-    [encode_register_email(Email, []) | _acc].
-
-decode_session({xmlel, <<"session">>, _attrs, _els}) ->
-    {session}.
-
-encode_session({session}, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"session">>, _attrs, _els}.
-
-decode_ping({xmlel, <<"ping">>, _attrs, _els}) ->
-    {ping}.
-
-encode_ping({ping}, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"ping">>, _attrs, _els}.
-
-decode_time_utc({xmlel, <<"utc">>, _attrs, _els}) ->
-    Cdata = decode_time_utc_els(_els, <<>>), Cdata.
-
-decode_time_utc_els([], Cdata) ->
-    decode_time_utc_cdata(Cdata);
-decode_time_utc_els([{xmlcdata, _data} | _els],
-                   Cdata) ->
-    decode_time_utc_els(_els,
-                       <<Cdata/binary, _data/binary>>);
-decode_time_utc_els([_ | _els], Cdata) ->
-    decode_time_utc_els(_els, Cdata).
-
-encode_time_utc(Cdata, _xmlns_attrs) ->
-    _els = encode_time_utc_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"utc">>, _attrs, _els}.
-
-decode_time_utc_cdata(<<>>) -> undefined;
-decode_time_utc_cdata(_val) ->
-    case catch dec_utc(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"utc">>,
-                       <<"urn:xmpp:time">>});
-      _res -> _res
-    end.
-
-encode_time_utc_cdata(undefined, _acc) -> _acc;
-encode_time_utc_cdata(_val, _acc) ->
-    [{xmlcdata, enc_utc(_val)} | _acc].
-
-decode_time_tzo({xmlel, <<"tzo">>, _attrs, _els}) ->
-    Cdata = decode_time_tzo_els(_els, <<>>), Cdata.
-
-decode_time_tzo_els([], Cdata) ->
-    decode_time_tzo_cdata(Cdata);
-decode_time_tzo_els([{xmlcdata, _data} | _els],
-                   Cdata) ->
-    decode_time_tzo_els(_els,
-                       <<Cdata/binary, _data/binary>>);
-decode_time_tzo_els([_ | _els], Cdata) ->
-    decode_time_tzo_els(_els, Cdata).
-
-encode_time_tzo(Cdata, _xmlns_attrs) ->
-    _els = encode_time_tzo_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"tzo">>, _attrs, _els}.
-
-decode_time_tzo_cdata(<<>>) -> undefined;
-decode_time_tzo_cdata(_val) ->
-    case catch dec_tzo(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"tzo">>,
-                       <<"urn:xmpp:time">>});
-      _res -> _res
-    end.
-
-encode_time_tzo_cdata(undefined, _acc) -> _acc;
-encode_time_tzo_cdata(_val, _acc) ->
-    [{xmlcdata, enc_tzo(_val)} | _acc].
-
-decode_time({xmlel, <<"time">>, _attrs, _els}) ->
-    {Utc, Tzo} = decode_time_els(_els, undefined,
-                                undefined),
-    {time, Tzo, Utc}.
-
-decode_time_els([], Utc, Tzo) -> {Utc, Tzo};
-decode_time_els([{xmlel, <<"tzo">>, _attrs, _} = _el
-                | _els],
-               Utc, Tzo) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"urn:xmpp:time">> ->
-          decode_time_els(_els, Utc, decode_time_tzo(_el));
-       true -> decode_time_els(_els, Utc, Tzo)
-    end;
-decode_time_els([{xmlel, <<"utc">>, _attrs, _} = _el
-                | _els],
-               Utc, Tzo) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"urn:xmpp:time">> ->
-          decode_time_els(_els, decode_time_utc(_el), Tzo);
-       true -> decode_time_els(_els, Utc, Tzo)
-    end;
-decode_time_els([_ | _els], Utc, Tzo) ->
-    decode_time_els(_els, Utc, Tzo).
-
-encode_time({time, Tzo, Utc}, _xmlns_attrs) ->
-    _els = 'encode_time_$tzo'(Tzo,
-                             'encode_time_$utc'(Utc, [])),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"time">>, _attrs, _els}.
-
-'encode_time_$utc'(undefined, _acc) -> _acc;
-'encode_time_$utc'(Utc, _acc) ->
-    [encode_time_utc(Utc, []) | _acc].
-
-'encode_time_$tzo'(undefined, _acc) -> _acc;
-'encode_time_$tzo'(Tzo, _acc) ->
-    [encode_time_tzo(Tzo, []) | _acc].
-
-decode_stream_error_text({xmlel, <<"text">>, _attrs,
-                         _els}) ->
-    Data = decode_stream_error_text_els(_els, <<>>),
-    Lang = decode_stream_error_text_attrs(_attrs,
-                                         undefined),
-    {text, Lang, Data}.
-
-decode_stream_error_text_els([], Data) ->
-    decode_stream_error_text_cdata(Data);
-decode_stream_error_text_els([{xmlcdata, _data} | _els],
-                            Data) ->
-    decode_stream_error_text_els(_els,
-                                <<Data/binary, _data/binary>>);
-decode_stream_error_text_els([_ | _els], Data) ->
-    decode_stream_error_text_els(_els, Data).
-
-decode_stream_error_text_attrs([{<<"xml:lang">>, _val}
-                               | _attrs],
-                              _Lang) ->
-    decode_stream_error_text_attrs(_attrs, _val);
-decode_stream_error_text_attrs([_ | _attrs], Lang) ->
-    decode_stream_error_text_attrs(_attrs, Lang);
-decode_stream_error_text_attrs([], Lang) ->
-    'decode_stream_error_text_attr_xml:lang'(Lang).
-
-encode_stream_error_text({text, Lang, Data},
-                        _xmlns_attrs) ->
-    _els = encode_stream_error_text_cdata(Data, []),
-    _attrs = 'encode_stream_error_text_attr_xml:lang'(Lang,
-                                                     _xmlns_attrs),
-    {xmlel, <<"text">>, _attrs, _els}.
-
-'decode_stream_error_text_attr_xml:lang'(undefined) ->
-    undefined;
-'decode_stream_error_text_attr_xml:lang'(_val) -> _val.
-
-'encode_stream_error_text_attr_xml:lang'(undefined,
-                                        _acc) ->
-    _acc;
-'encode_stream_error_text_attr_xml:lang'(_val, _acc) ->
-    [{<<"xml:lang">>, _val} | _acc].
-
-decode_stream_error_text_cdata(<<>>) -> undefined;
-decode_stream_error_text_cdata(_val) -> _val.
-
-encode_stream_error_text_cdata(undefined, _acc) -> _acc;
-encode_stream_error_text_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
-
-decode_stream_error_bad_format({xmlel, <<"bad-format">>,
-                               _attrs, _els}) ->
-    'bad-format'.
-
-encode_stream_error_bad_format('bad-format',
-                              _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"bad-format">>, _attrs, _els}.
-
-decode_stream_error_bad_namespace_prefix({xmlel,
-                                         <<"bad-namespace-prefix">>, _attrs,
-                                         _els}) ->
-    'bad-namespace-prefix'.
-
-encode_stream_error_bad_namespace_prefix('bad-namespace-prefix',
-                                        _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"bad-namespace-prefix">>, _attrs, _els}.
-
-decode_stream_error_conflict({xmlel, <<"conflict">>,
-                             _attrs, _els}) ->
-    conflict.
-
-encode_stream_error_conflict(conflict, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"conflict">>, _attrs, _els}.
-
-decode_stream_error_connection_timeout({xmlel,
-                                       <<"connection-timeout">>, _attrs,
-                                       _els}) ->
-    'connection-timeout'.
-
-encode_stream_error_connection_timeout('connection-timeout',
-                                      _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"connection-timeout">>, _attrs, _els}.
-
-decode_stream_error_host_gone({xmlel, <<"host-gone">>,
-                              _attrs, _els}) ->
-    'host-gone'.
-
-encode_stream_error_host_gone('host-gone',
-                             _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"host-gone">>, _attrs, _els}.
-
-decode_stream_error_host_unknown({xmlel,
-                                 <<"host-unknown">>, _attrs, _els}) ->
-    'host-unknown'.
-
-encode_stream_error_host_unknown('host-unknown',
-                                _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"host-unknown">>, _attrs, _els}.
-
-decode_stream_error_improper_addressing({xmlel,
-                                        <<"improper-addressing">>, _attrs,
-                                        _els}) ->
-    'improper-addressing'.
-
-encode_stream_error_improper_addressing('improper-addressing',
-                                       _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"improper-addressing">>, _attrs, _els}.
-
-decode_stream_error_internal_server_error({xmlel,
-                                          <<"internal-server-error">>, _attrs,
-                                          _els}) ->
-    'internal-server-error'.
-
-encode_stream_error_internal_server_error('internal-server-error',
-                                         _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"internal-server-error">>, _attrs, _els}.
-
-decode_stream_error_invalid_from({xmlel,
-                                 <<"invalid-from">>, _attrs, _els}) ->
-    'invalid-from'.
-
-encode_stream_error_invalid_from('invalid-from',
-                                _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"invalid-from">>, _attrs, _els}.
-
-decode_stream_error_invalid_id({xmlel, <<"invalid-id">>,
-                               _attrs, _els}) ->
-    'invalid-id'.
-
-encode_stream_error_invalid_id('invalid-id',
-                              _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"invalid-id">>, _attrs, _els}.
-
-decode_stream_error_invalid_namespace({xmlel,
-                                      <<"invalid-namespace">>, _attrs,
-                                      _els}) ->
-    'invalid-namespace'.
-
-encode_stream_error_invalid_namespace('invalid-namespace',
-                                     _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"invalid-namespace">>, _attrs, _els}.
-
-decode_stream_error_invalid_xml({xmlel,
-                                <<"invalid-xml">>, _attrs, _els}) ->
-    'invalid-xml'.
-
-encode_stream_error_invalid_xml('invalid-xml',
-                               _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"invalid-xml">>, _attrs, _els}.
-
-decode_stream_error_not_authorized({xmlel,
-                                   <<"not-authorized">>, _attrs, _els}) ->
-    'not-authorized'.
-
-encode_stream_error_not_authorized('not-authorized',
-                                  _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"not-authorized">>, _attrs, _els}.
-
-decode_stream_error_not_well_formed({xmlel,
-                                    <<"not-well-formed">>, _attrs, _els}) ->
-    'not-well-formed'.
-
-encode_stream_error_not_well_formed('not-well-formed',
-                                   _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"not-well-formed">>, _attrs, _els}.
-
-decode_stream_error_policy_violation({xmlel,
-                                     <<"policy-violation">>, _attrs, _els}) ->
-    'policy-violation'.
-
-encode_stream_error_policy_violation('policy-violation',
-                                    _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"policy-violation">>, _attrs, _els}.
-
-decode_stream_error_remote_connection_failed({xmlel,
-                                             <<"remote-connection-failed">>,
-                                             _attrs, _els}) ->
-    'remote-connection-failed'.
-
-encode_stream_error_remote_connection_failed('remote-connection-failed',
-                                            _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"remote-connection-failed">>, _attrs, _els}.
-
-decode_stream_error_reset({xmlel, <<"reset">>, _attrs,
-                          _els}) ->
-    reset.
-
-encode_stream_error_reset(reset, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"reset">>, _attrs, _els}.
-
-decode_stream_error_resource_constraint({xmlel,
-                                        <<"resource-constraint">>, _attrs,
-                                        _els}) ->
-    'resource-constraint'.
-
-encode_stream_error_resource_constraint('resource-constraint',
-                                       _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"resource-constraint">>, _attrs, _els}.
-
-decode_stream_error_restricted_xml({xmlel,
-                                   <<"restricted-xml">>, _attrs, _els}) ->
-    'restricted-xml'.
-
-encode_stream_error_restricted_xml('restricted-xml',
-                                  _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"restricted-xml">>, _attrs, _els}.
-
-decode_stream_error_see_other_host({xmlel,
-                                   <<"see-other-host">>, _attrs, _els}) ->
-    Host = decode_stream_error_see_other_host_els(_els,
-                                                 <<>>),
-    {'see-other-host', Host}.
-
-decode_stream_error_see_other_host_els([], Host) ->
-    decode_stream_error_see_other_host_cdata(Host);
-decode_stream_error_see_other_host_els([{xmlcdata,
-                                        _data}
-                                       | _els],
-                                      Host) ->
-    decode_stream_error_see_other_host_els(_els,
-                                          <<Host/binary, _data/binary>>);
-decode_stream_error_see_other_host_els([_ | _els],
-                                      Host) ->
-    decode_stream_error_see_other_host_els(_els, Host).
-
-encode_stream_error_see_other_host({'see-other-host',
-                                   Host},
-                                  _xmlns_attrs) ->
-    _els = encode_stream_error_see_other_host_cdata(Host,
-                                                   []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"see-other-host">>, _attrs, _els}.
-
-decode_stream_error_see_other_host_cdata(<<>>) ->
-    erlang:error({missing_cdata, <<>>, <<"see-other-host">>,
-                 <<"urn:ietf:params:xml:ns:xmpp-streams">>});
-decode_stream_error_see_other_host_cdata(_val) -> _val.
-
-encode_stream_error_see_other_host_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
-
-decode_stream_error_system_shutdown({xmlel,
-                                    <<"system-shutdown">>, _attrs, _els}) ->
-    'system-shutdown'.
-
-encode_stream_error_system_shutdown('system-shutdown',
-                                   _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"system-shutdown">>, _attrs, _els}.
-
-decode_stream_error_undefined_condition({xmlel,
-                                        <<"undefined-condition">>, _attrs,
-                                        _els}) ->
-    'undefined-condition'.
-
-encode_stream_error_undefined_condition('undefined-condition',
-                                       _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"undefined-condition">>, _attrs, _els}.
-
-decode_stream_error_unsupported_encoding({xmlel,
-                                         <<"unsupported-encoding">>, _attrs,
-                                         _els}) ->
-    'unsupported-encoding'.
-
-encode_stream_error_unsupported_encoding('unsupported-encoding',
-                                        _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"unsupported-encoding">>, _attrs, _els}.
-
-decode_stream_error_unsupported_stanza_type({xmlel,
-                                            <<"unsupported-stanza-type">>,
-                                            _attrs, _els}) ->
-    'unsupported-stanza-type'.
-
-encode_stream_error_unsupported_stanza_type('unsupported-stanza-type',
-                                           _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"unsupported-stanza-type">>, _attrs, _els}.
-
-decode_stream_error_unsupported_version({xmlel,
-                                        <<"unsupported-version">>, _attrs,
-                                        _els}) ->
-    'unsupported-version'.
-
-encode_stream_error_unsupported_version('unsupported-version',
-                                       _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"unsupported-version">>, _attrs, _els}.
-
-decode_stream_error({xmlel, <<"stream:error">>, _attrs,
-                    _els}) ->
-    {Text, Reason} = decode_stream_error_els(_els,
-                                            undefined, undefined),
-    {stream_error, Reason, Text}.
-
-decode_stream_error_els([], Text, Reason) ->
-    {Text, Reason};
-decode_stream_error_els([{xmlel, <<"text">>, _attrs,
-                         _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els,
-                                  decode_stream_error_text(_el), Reason);
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"bad-format">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_bad_format(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel,
-                         <<"bad-namespace-prefix">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_bad_namespace_prefix(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"conflict">>, _attrs,
-                         _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_conflict(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel,
-                         <<"connection-timeout">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_connection_timeout(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"host-gone">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_host_gone(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"host-unknown">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_host_unknown(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel,
-                         <<"improper-addressing">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_improper_addressing(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel,
-                         <<"internal-server-error">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_internal_server_error(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"invalid-from">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_invalid_from(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"invalid-id">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_invalid_id(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel,
-                         <<"invalid-namespace">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_invalid_namespace(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"invalid-xml">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_invalid_xml(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"not-authorized">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_not_authorized(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"not-well-formed">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_not_well_formed(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"policy-violation">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_policy_violation(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel,
-                         <<"remote-connection-failed">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_remote_connection_failed(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"reset">>, _attrs,
-                         _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_reset(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel,
-                         <<"resource-constraint">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_resource_constraint(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"restricted-xml">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_restricted_xml(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"see-other-host">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_see_other_host(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel, <<"system-shutdown">>,
-                         _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_system_shutdown(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel,
-                         <<"undefined-condition">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_undefined_condition(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel,
-                         <<"unsupported-encoding">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_unsupported_encoding(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel,
-                         <<"unsupported-stanza-type">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_unsupported_stanza_type(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([{xmlel,
-                         <<"unsupported-version">>, _attrs, _} =
-                            _el
-                        | _els],
-                       Text, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns ==
-        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
-          decode_stream_error_els(_els, Text,
-                                  decode_stream_error_unsupported_version(_el));
-       true -> decode_stream_error_els(_els, Text, Reason)
-    end;
-decode_stream_error_els([_ | _els], Text, Reason) ->
-    decode_stream_error_els(_els, Text, Reason).
+decode_vcard_JABBERID_els([], Cdata) ->
+    decode_vcard_JABBERID_cdata(Cdata);
+decode_vcard_JABBERID_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_vcard_JABBERID_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_vcard_JABBERID_els([_ | _els], Cdata) ->
+    decode_vcard_JABBERID_els(_els, Cdata).
+
+encode_vcard_JABBERID(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_JABBERID_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"JABBERID">>, _attrs, _els}.
+
+decode_vcard_JABBERID_cdata(<<>>) -> undefined;
+decode_vcard_JABBERID_cdata(_val) -> _val.
+
+encode_vcard_JABBERID_cdata(undefined, _acc) -> _acc;
+encode_vcard_JABBERID_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_BDAY({xmlel, <<"BDAY">>, _attrs, _els}) ->
+    Cdata = decode_vcard_BDAY_els(_els, <<>>), Cdata.
+
+decode_vcard_BDAY_els([], Cdata) ->
+    decode_vcard_BDAY_cdata(Cdata);
+decode_vcard_BDAY_els([{xmlcdata, _data} | _els],
+                     Cdata) ->
+    decode_vcard_BDAY_els(_els,
+                         <<Cdata/binary, _data/binary>>);
+decode_vcard_BDAY_els([_ | _els], Cdata) ->
+    decode_vcard_BDAY_els(_els, Cdata).
+
+encode_vcard_BDAY(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_BDAY_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"BDAY">>, _attrs, _els}.
+
+decode_vcard_BDAY_cdata(<<>>) -> undefined;
+decode_vcard_BDAY_cdata(_val) -> _val.
+
+encode_vcard_BDAY_cdata(undefined, _acc) -> _acc;
+encode_vcard_BDAY_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_NICKNAME({xmlel, <<"NICKNAME">>, _attrs,
+                      _els}) ->
+    Cdata = decode_vcard_NICKNAME_els(_els, <<>>), Cdata.
+
+decode_vcard_NICKNAME_els([], Cdata) ->
+    decode_vcard_NICKNAME_cdata(Cdata);
+decode_vcard_NICKNAME_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_vcard_NICKNAME_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_vcard_NICKNAME_els([_ | _els], Cdata) ->
+    decode_vcard_NICKNAME_els(_els, Cdata).
+
+encode_vcard_NICKNAME(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_NICKNAME_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"NICKNAME">>, _attrs, _els}.
+
+decode_vcard_NICKNAME_cdata(<<>>) -> undefined;
+decode_vcard_NICKNAME_cdata(_val) -> _val.
+
+encode_vcard_NICKNAME_cdata(undefined, _acc) -> _acc;
+encode_vcard_NICKNAME_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_FN({xmlel, <<"FN">>, _attrs, _els}) ->
+    Cdata = decode_vcard_FN_els(_els, <<>>), Cdata.
+
+decode_vcard_FN_els([], Cdata) ->
+    decode_vcard_FN_cdata(Cdata);
+decode_vcard_FN_els([{xmlcdata, _data} | _els],
+                   Cdata) ->
+    decode_vcard_FN_els(_els,
+                       <<Cdata/binary, _data/binary>>);
+decode_vcard_FN_els([_ | _els], Cdata) ->
+    decode_vcard_FN_els(_els, Cdata).
+
+encode_vcard_FN(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_FN_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"FN">>, _attrs, _els}.
+
+decode_vcard_FN_cdata(<<>>) -> undefined;
+decode_vcard_FN_cdata(_val) -> _val.
+
+encode_vcard_FN_cdata(undefined, _acc) -> _acc;
+encode_vcard_FN_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_VERSION({xmlel, <<"VERSION">>, _attrs,
+                     _els}) ->
+    Cdata = decode_vcard_VERSION_els(_els, <<>>), Cdata.
+
+decode_vcard_VERSION_els([], Cdata) ->
+    decode_vcard_VERSION_cdata(Cdata);
+decode_vcard_VERSION_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_vcard_VERSION_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_vcard_VERSION_els([_ | _els], Cdata) ->
+    decode_vcard_VERSION_els(_els, Cdata).
+
+encode_vcard_VERSION(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_VERSION_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"VERSION">>, _attrs, _els}.
+
+decode_vcard_VERSION_cdata(<<>>) -> undefined;
+decode_vcard_VERSION_cdata(_val) -> _val.
+
+encode_vcard_VERSION_cdata(undefined, _acc) -> _acc;
+encode_vcard_VERSION_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_CRED({xmlel, <<"CRED">>, _attrs, _els}) ->
+    Cdata = decode_vcard_CRED_els(_els, <<>>), Cdata.
+
+decode_vcard_CRED_els([], Cdata) ->
+    decode_vcard_CRED_cdata(Cdata);
+decode_vcard_CRED_els([{xmlcdata, _data} | _els],
+                     Cdata) ->
+    decode_vcard_CRED_els(_els,
+                         <<Cdata/binary, _data/binary>>);
+decode_vcard_CRED_els([_ | _els], Cdata) ->
+    decode_vcard_CRED_els(_els, Cdata).
+
+encode_vcard_CRED(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_CRED_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"CRED">>, _attrs, _els}.
+
+decode_vcard_CRED_cdata(<<>>) -> undefined;
+decode_vcard_CRED_cdata(_val) -> _val.
+
+encode_vcard_CRED_cdata(undefined, _acc) -> _acc;
+encode_vcard_CRED_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_PHONETIC({xmlel, <<"PHONETIC">>, _attrs,
+                      _els}) ->
+    Cdata = decode_vcard_PHONETIC_els(_els, <<>>), Cdata.
 
-encode_stream_error({stream_error, Reason, Text},
-                   _xmlns_attrs) ->
-    _els = 'encode_stream_error_$reason'(Reason,
-                                        'encode_stream_error_$text'(Text, [])),
+decode_vcard_PHONETIC_els([], Cdata) ->
+    decode_vcard_PHONETIC_cdata(Cdata);
+decode_vcard_PHONETIC_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_vcard_PHONETIC_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_vcard_PHONETIC_els([_ | _els], Cdata) ->
+    decode_vcard_PHONETIC_els(_els, Cdata).
+
+encode_vcard_PHONETIC(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_PHONETIC_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"stream:error">>, _attrs, _els}.
+    {xmlel, <<"PHONETIC">>, _attrs, _els}.
 
-'encode_stream_error_$text'(undefined, _acc) -> _acc;
-'encode_stream_error_$text'(Text, _acc) ->
-    [encode_stream_error_text(Text,
-                             [{<<"xmlns">>,
-                               <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc].
+decode_vcard_PHONETIC_cdata(<<>>) -> undefined;
+decode_vcard_PHONETIC_cdata(_val) -> _val.
 
-'encode_stream_error_$reason'(undefined, _acc) -> _acc;
-'encode_stream_error_$reason'('bad-format' = Reason,
-                             _acc) ->
-    [encode_stream_error_bad_format(Reason,
-                                   [{<<"xmlns">>,
-                                     <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('bad-namespace-prefix' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_bad_namespace_prefix(Reason,
-                                             [{<<"xmlns">>,
-                                               <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'(conflict = Reason,
-                             _acc) ->
-    [encode_stream_error_conflict(Reason,
-                                 [{<<"xmlns">>,
-                                   <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('connection-timeout' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_connection_timeout(Reason,
-                                           [{<<"xmlns">>,
-                                             <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('host-gone' = Reason,
-                             _acc) ->
-    [encode_stream_error_host_gone(Reason,
-                                  [{<<"xmlns">>,
-                                    <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('host-unknown' = Reason,
-                             _acc) ->
-    [encode_stream_error_host_unknown(Reason,
-                                     [{<<"xmlns">>,
-                                       <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('improper-addressing' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_improper_addressing(Reason,
-                                            [{<<"xmlns">>,
-                                              <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('internal-server-error' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_internal_server_error(Reason,
-                                              [{<<"xmlns">>,
-                                                <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('invalid-from' = Reason,
-                             _acc) ->
-    [encode_stream_error_invalid_from(Reason,
-                                     [{<<"xmlns">>,
-                                       <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('invalid-id' = Reason,
-                             _acc) ->
-    [encode_stream_error_invalid_id(Reason,
-                                   [{<<"xmlns">>,
-                                     <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('invalid-namespace' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_invalid_namespace(Reason,
-                                          [{<<"xmlns">>,
-                                            <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('invalid-xml' = Reason,
-                             _acc) ->
-    [encode_stream_error_invalid_xml(Reason,
-                                    [{<<"xmlns">>,
-                                      <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('not-authorized' = Reason,
-                             _acc) ->
-    [encode_stream_error_not_authorized(Reason,
-                                       [{<<"xmlns">>,
-                                         <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('not-well-formed' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_not_well_formed(Reason,
-                                        [{<<"xmlns">>,
-                                          <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('policy-violation' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_policy_violation(Reason,
-                                         [{<<"xmlns">>,
-                                           <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('remote-connection-failed' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_remote_connection_failed(Reason,
-                                                 [{<<"xmlns">>,
-                                                   <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'(reset = Reason, _acc) ->
-    [encode_stream_error_reset(Reason,
-                              [{<<"xmlns">>,
-                                <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('resource-constraint' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_resource_constraint(Reason,
-                                            [{<<"xmlns">>,
-                                              <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('restricted-xml' = Reason,
-                             _acc) ->
-    [encode_stream_error_restricted_xml(Reason,
-                                       [{<<"xmlns">>,
-                                         <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'({'see-other-host', _} =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_see_other_host(Reason,
-                                       [{<<"xmlns">>,
-                                         <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('system-shutdown' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_system_shutdown(Reason,
-                                        [{<<"xmlns">>,
-                                          <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('undefined-condition' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_undefined_condition(Reason,
-                                            [{<<"xmlns">>,
-                                              <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('unsupported-encoding' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_unsupported_encoding(Reason,
-                                             [{<<"xmlns">>,
-                                               <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('unsupported-stanza-type' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_unsupported_stanza_type(Reason,
-                                                [{<<"xmlns">>,
-                                                  <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc];
-'encode_stream_error_$reason'('unsupported-version' =
-                                 Reason,
-                             _acc) ->
-    [encode_stream_error_unsupported_version(Reason,
-                                            [{<<"xmlns">>,
-                                              <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
-     | _acc].
+encode_vcard_PHONETIC_cdata(undefined, _acc) -> _acc;
+encode_vcard_PHONETIC_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_HOME({xmlel, <<"HOME">>, _attrs, _els}) ->
-    true.
+decode_vcard_ORGUNIT({xmlel, <<"ORGUNIT">>, _attrs,
+                     _els}) ->
+    Cdata = decode_vcard_ORGUNIT_els(_els, <<>>), Cdata.
+
+decode_vcard_ORGUNIT_els([], Cdata) ->
+    decode_vcard_ORGUNIT_cdata(Cdata);
+decode_vcard_ORGUNIT_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_vcard_ORGUNIT_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_vcard_ORGUNIT_els([_ | _els], Cdata) ->
+    decode_vcard_ORGUNIT_els(_els, Cdata).
+
+encode_vcard_ORGUNIT(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_ORGUNIT_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"ORGUNIT">>, _attrs, _els}.
+
+decode_vcard_ORGUNIT_cdata(<<>>) -> undefined;
+decode_vcard_ORGUNIT_cdata(_val) -> _val.
+
+encode_vcard_ORGUNIT_cdata(undefined, _acc) -> _acc;
+encode_vcard_ORGUNIT_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_ORGNAME({xmlel, <<"ORGNAME">>, _attrs,
+                     _els}) ->
+    Cdata = decode_vcard_ORGNAME_els(_els, <<>>), Cdata.
+
+decode_vcard_ORGNAME_els([], Cdata) ->
+    decode_vcard_ORGNAME_cdata(Cdata);
+decode_vcard_ORGNAME_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_vcard_ORGNAME_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_vcard_ORGNAME_els([_ | _els], Cdata) ->
+    decode_vcard_ORGNAME_els(_els, Cdata).
+
+encode_vcard_ORGNAME(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_ORGNAME_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"ORGNAME">>, _attrs, _els}.
+
+decode_vcard_ORGNAME_cdata(<<>>) -> undefined;
+decode_vcard_ORGNAME_cdata(_val) -> _val.
+
+encode_vcard_ORGNAME_cdata(undefined, _acc) -> _acc;
+encode_vcard_ORGNAME_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_LON({xmlel, <<"LON">>, _attrs, _els}) ->
+    Cdata = decode_vcard_LON_els(_els, <<>>), Cdata.
+
+decode_vcard_LON_els([], Cdata) ->
+    decode_vcard_LON_cdata(Cdata);
+decode_vcard_LON_els([{xmlcdata, _data} | _els],
+                    Cdata) ->
+    decode_vcard_LON_els(_els,
+                        <<Cdata/binary, _data/binary>>);
+decode_vcard_LON_els([_ | _els], Cdata) ->
+    decode_vcard_LON_els(_els, Cdata).
 
-encode_vcard_HOME(true, _xmlns_attrs) ->
-    _els = [],
+encode_vcard_LON(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_LON_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"HOME">>, _attrs, _els}.
+    {xmlel, <<"LON">>, _attrs, _els}.
 
-decode_vcard_WORK({xmlel, <<"WORK">>, _attrs, _els}) ->
-    true.
+decode_vcard_LON_cdata(<<>>) -> undefined;
+decode_vcard_LON_cdata(_val) -> _val.
 
-encode_vcard_WORK(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"WORK">>, _attrs, _els}.
+encode_vcard_LON_cdata(undefined, _acc) -> _acc;
+encode_vcard_LON_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_VOICE({xmlel, <<"VOICE">>, _attrs,
-                   _els}) ->
-    true.
+decode_vcard_LAT({xmlel, <<"LAT">>, _attrs, _els}) ->
+    Cdata = decode_vcard_LAT_els(_els, <<>>), Cdata.
 
-encode_vcard_VOICE(true, _xmlns_attrs) ->
-    _els = [],
+decode_vcard_LAT_els([], Cdata) ->
+    decode_vcard_LAT_cdata(Cdata);
+decode_vcard_LAT_els([{xmlcdata, _data} | _els],
+                    Cdata) ->
+    decode_vcard_LAT_els(_els,
+                        <<Cdata/binary, _data/binary>>);
+decode_vcard_LAT_els([_ | _els], Cdata) ->
+    decode_vcard_LAT_els(_els, Cdata).
+
+encode_vcard_LAT(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_LAT_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"VOICE">>, _attrs, _els}.
+    {xmlel, <<"LAT">>, _attrs, _els}.
 
-decode_vcard_FAX({xmlel, <<"FAX">>, _attrs, _els}) ->
-    true.
+decode_vcard_LAT_cdata(<<>>) -> undefined;
+decode_vcard_LAT_cdata(_val) -> _val.
 
-encode_vcard_FAX(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"FAX">>, _attrs, _els}.
+encode_vcard_LAT_cdata(undefined, _acc) -> _acc;
+encode_vcard_LAT_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_PAGER({xmlel, <<"PAGER">>, _attrs,
-                   _els}) ->
-    true.
+decode_vcard_USERID({xmlel, <<"USERID">>, _attrs,
+                    _els}) ->
+    Cdata = decode_vcard_USERID_els(_els, <<>>), Cdata.
 
-encode_vcard_PAGER(true, _xmlns_attrs) ->
-    _els = [],
+decode_vcard_USERID_els([], Cdata) ->
+    decode_vcard_USERID_cdata(Cdata);
+decode_vcard_USERID_els([{xmlcdata, _data} | _els],
+                       Cdata) ->
+    decode_vcard_USERID_els(_els,
+                           <<Cdata/binary, _data/binary>>);
+decode_vcard_USERID_els([_ | _els], Cdata) ->
+    decode_vcard_USERID_els(_els, Cdata).
+
+encode_vcard_USERID(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_USERID_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"PAGER">>, _attrs, _els}.
+    {xmlel, <<"USERID">>, _attrs, _els}.
 
-decode_vcard_MSG({xmlel, <<"MSG">>, _attrs, _els}) ->
-    true.
+decode_vcard_USERID_cdata(<<>>) -> undefined;
+decode_vcard_USERID_cdata(_val) -> _val.
 
-encode_vcard_MSG(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"MSG">>, _attrs, _els}.
+encode_vcard_USERID_cdata(undefined, _acc) -> _acc;
+encode_vcard_USERID_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_CELL({xmlel, <<"CELL">>, _attrs, _els}) ->
-    true.
+decode_vcard_NUMBER({xmlel, <<"NUMBER">>, _attrs,
+                    _els}) ->
+    Cdata = decode_vcard_NUMBER_els(_els, <<>>), Cdata.
 
-encode_vcard_CELL(true, _xmlns_attrs) ->
-    _els = [],
+decode_vcard_NUMBER_els([], Cdata) ->
+    decode_vcard_NUMBER_cdata(Cdata);
+decode_vcard_NUMBER_els([{xmlcdata, _data} | _els],
+                       Cdata) ->
+    decode_vcard_NUMBER_els(_els,
+                           <<Cdata/binary, _data/binary>>);
+decode_vcard_NUMBER_els([_ | _els], Cdata) ->
+    decode_vcard_NUMBER_els(_els, Cdata).
+
+encode_vcard_NUMBER(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_NUMBER_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"CELL">>, _attrs, _els}.
+    {xmlel, <<"NUMBER">>, _attrs, _els}.
 
-decode_vcard_VIDEO({xmlel, <<"VIDEO">>, _attrs,
-                   _els}) ->
-    true.
+decode_vcard_NUMBER_cdata(<<>>) -> undefined;
+decode_vcard_NUMBER_cdata(_val) -> _val.
 
-encode_vcard_VIDEO(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"VIDEO">>, _attrs, _els}.
+encode_vcard_NUMBER_cdata(undefined, _acc) -> _acc;
+encode_vcard_NUMBER_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_BBS({xmlel, <<"BBS">>, _attrs, _els}) ->
-    true.
+decode_vcard_LINE({xmlel, <<"LINE">>, _attrs, _els}) ->
+    Cdata = decode_vcard_LINE_els(_els, <<>>), Cdata.
 
-encode_vcard_BBS(true, _xmlns_attrs) ->
-    _els = [],
+decode_vcard_LINE_els([], Cdata) ->
+    decode_vcard_LINE_cdata(Cdata);
+decode_vcard_LINE_els([{xmlcdata, _data} | _els],
+                     Cdata) ->
+    decode_vcard_LINE_els(_els,
+                         <<Cdata/binary, _data/binary>>);
+decode_vcard_LINE_els([_ | _els], Cdata) ->
+    decode_vcard_LINE_els(_els, Cdata).
+
+encode_vcard_LINE(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_LINE_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"BBS">>, _attrs, _els}.
+    {xmlel, <<"LINE">>, _attrs, _els}.
 
-decode_vcard_MODEM({xmlel, <<"MODEM">>, _attrs,
-                   _els}) ->
-    true.
+decode_vcard_LINE_cdata(<<>>) -> undefined;
+decode_vcard_LINE_cdata(_val) -> _val.
 
-encode_vcard_MODEM(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"MODEM">>, _attrs, _els}.
+encode_vcard_LINE_cdata(undefined, _acc) -> _acc;
+encode_vcard_LINE_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_ISDN({xmlel, <<"ISDN">>, _attrs, _els}) ->
-    true.
+decode_vcard_CTRY({xmlel, <<"CTRY">>, _attrs, _els}) ->
+    Cdata = decode_vcard_CTRY_els(_els, <<>>), Cdata.
 
-encode_vcard_ISDN(true, _xmlns_attrs) ->
-    _els = [],
+decode_vcard_CTRY_els([], Cdata) ->
+    decode_vcard_CTRY_cdata(Cdata);
+decode_vcard_CTRY_els([{xmlcdata, _data} | _els],
+                     Cdata) ->
+    decode_vcard_CTRY_els(_els,
+                         <<Cdata/binary, _data/binary>>);
+decode_vcard_CTRY_els([_ | _els], Cdata) ->
+    decode_vcard_CTRY_els(_els, Cdata).
+
+encode_vcard_CTRY(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_CTRY_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"ISDN">>, _attrs, _els}.
+    {xmlel, <<"CTRY">>, _attrs, _els}.
 
-decode_vcard_PCS({xmlel, <<"PCS">>, _attrs, _els}) ->
-    true.
+decode_vcard_CTRY_cdata(<<>>) -> undefined;
+decode_vcard_CTRY_cdata(_val) -> _val.
 
-encode_vcard_PCS(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"PCS">>, _attrs, _els}.
+encode_vcard_CTRY_cdata(undefined, _acc) -> _acc;
+encode_vcard_CTRY_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_POSTAL({xmlel, <<"POSTAL">>, _attrs,
-                    _els}) ->
-    true.
+decode_vcard_PCODE({xmlel, <<"PCODE">>, _attrs,
+                   _els}) ->
+    Cdata = decode_vcard_PCODE_els(_els, <<>>), Cdata.
 
-encode_vcard_POSTAL(true, _xmlns_attrs) ->
-    _els = [],
+decode_vcard_PCODE_els([], Cdata) ->
+    decode_vcard_PCODE_cdata(Cdata);
+decode_vcard_PCODE_els([{xmlcdata, _data} | _els],
+                      Cdata) ->
+    decode_vcard_PCODE_els(_els,
+                          <<Cdata/binary, _data/binary>>);
+decode_vcard_PCODE_els([_ | _els], Cdata) ->
+    decode_vcard_PCODE_els(_els, Cdata).
+
+encode_vcard_PCODE(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_PCODE_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"POSTAL">>, _attrs, _els}.
+    {xmlel, <<"PCODE">>, _attrs, _els}.
 
-decode_vcard_PARCEL({xmlel, <<"PARCEL">>, _attrs,
+decode_vcard_PCODE_cdata(<<>>) -> undefined;
+decode_vcard_PCODE_cdata(_val) -> _val.
+
+encode_vcard_PCODE_cdata(undefined, _acc) -> _acc;
+encode_vcard_PCODE_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_vcard_REGION({xmlel, <<"REGION">>, _attrs,
                     _els}) ->
-    true.
+    Cdata = decode_vcard_REGION_els(_els, <<>>), Cdata.
 
-encode_vcard_PARCEL(true, _xmlns_attrs) ->
-    _els = [],
+decode_vcard_REGION_els([], Cdata) ->
+    decode_vcard_REGION_cdata(Cdata);
+decode_vcard_REGION_els([{xmlcdata, _data} | _els],
+                       Cdata) ->
+    decode_vcard_REGION_els(_els,
+                           <<Cdata/binary, _data/binary>>);
+decode_vcard_REGION_els([_ | _els], Cdata) ->
+    decode_vcard_REGION_els(_els, Cdata).
+
+encode_vcard_REGION(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_REGION_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"PARCEL">>, _attrs, _els}.
+    {xmlel, <<"REGION">>, _attrs, _els}.
 
-decode_vcard_DOM({xmlel, <<"DOM">>, _attrs, _els}) ->
-    true.
+decode_vcard_REGION_cdata(<<>>) -> undefined;
+decode_vcard_REGION_cdata(_val) -> _val.
 
-encode_vcard_DOM(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"DOM">>, _attrs, _els}.
+encode_vcard_REGION_cdata(undefined, _acc) -> _acc;
+encode_vcard_REGION_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_INTL({xmlel, <<"INTL">>, _attrs, _els}) ->
-    true.
+decode_vcard_LOCALITY({xmlel, <<"LOCALITY">>, _attrs,
+                      _els}) ->
+    Cdata = decode_vcard_LOCALITY_els(_els, <<>>), Cdata.
 
-encode_vcard_INTL(true, _xmlns_attrs) ->
-    _els = [],
+decode_vcard_LOCALITY_els([], Cdata) ->
+    decode_vcard_LOCALITY_cdata(Cdata);
+decode_vcard_LOCALITY_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_vcard_LOCALITY_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_vcard_LOCALITY_els([_ | _els], Cdata) ->
+    decode_vcard_LOCALITY_els(_els, Cdata).
+
+encode_vcard_LOCALITY(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_LOCALITY_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"INTL">>, _attrs, _els}.
+    {xmlel, <<"LOCALITY">>, _attrs, _els}.
 
-decode_vcard_PREF({xmlel, <<"PREF">>, _attrs, _els}) ->
-    true.
+decode_vcard_LOCALITY_cdata(<<>>) -> undefined;
+decode_vcard_LOCALITY_cdata(_val) -> _val.
 
-encode_vcard_PREF(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"PREF">>, _attrs, _els}.
+encode_vcard_LOCALITY_cdata(undefined, _acc) -> _acc;
+encode_vcard_LOCALITY_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_INTERNET({xmlel, <<"INTERNET">>, _attrs,
-                      _els}) ->
-    true.
+decode_vcard_STREET({xmlel, <<"STREET">>, _attrs,
+                    _els}) ->
+    Cdata = decode_vcard_STREET_els(_els, <<>>), Cdata.
 
-encode_vcard_INTERNET(true, _xmlns_attrs) ->
-    _els = [],
+decode_vcard_STREET_els([], Cdata) ->
+    decode_vcard_STREET_cdata(Cdata);
+decode_vcard_STREET_els([{xmlcdata, _data} | _els],
+                       Cdata) ->
+    decode_vcard_STREET_els(_els,
+                           <<Cdata/binary, _data/binary>>);
+decode_vcard_STREET_els([_ | _els], Cdata) ->
+    decode_vcard_STREET_els(_els, Cdata).
+
+encode_vcard_STREET(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_STREET_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"INTERNET">>, _attrs, _els}.
+    {xmlel, <<"STREET">>, _attrs, _els}.
 
-decode_vcard_X400({xmlel, <<"X400">>, _attrs, _els}) ->
-    true.
+decode_vcard_STREET_cdata(<<>>) -> undefined;
+decode_vcard_STREET_cdata(_val) -> _val.
 
-encode_vcard_X400(true, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"X400">>, _attrs, _els}.
+encode_vcard_STREET_cdata(undefined, _acc) -> _acc;
+encode_vcard_STREET_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_FAMILY({xmlel, <<"FAMILY">>, _attrs,
+decode_vcard_EXTADD({xmlel, <<"EXTADD">>, _attrs,
                     _els}) ->
-    Cdata = decode_vcard_FAMILY_els(_els, <<>>), Cdata.
+    Cdata = decode_vcard_EXTADD_els(_els, <<>>), Cdata.
 
-decode_vcard_FAMILY_els([], Cdata) ->
-    decode_vcard_FAMILY_cdata(Cdata);
-decode_vcard_FAMILY_els([{xmlcdata, _data} | _els],
+decode_vcard_EXTADD_els([], Cdata) ->
+    decode_vcard_EXTADD_cdata(Cdata);
+decode_vcard_EXTADD_els([{xmlcdata, _data} | _els],
                        Cdata) ->
-    decode_vcard_FAMILY_els(_els,
+    decode_vcard_EXTADD_els(_els,
                            <<Cdata/binary, _data/binary>>);
-decode_vcard_FAMILY_els([_ | _els], Cdata) ->
-    decode_vcard_FAMILY_els(_els, Cdata).
+decode_vcard_EXTADD_els([_ | _els], Cdata) ->
+    decode_vcard_EXTADD_els(_els, Cdata).
 
-encode_vcard_FAMILY(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_FAMILY_cdata(Cdata, []),
+encode_vcard_EXTADD(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_EXTADD_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"FAMILY">>, _attrs, _els}.
+    {xmlel, <<"EXTADD">>, _attrs, _els}.
 
-decode_vcard_FAMILY_cdata(<<>>) -> undefined;
-decode_vcard_FAMILY_cdata(_val) -> _val.
+decode_vcard_EXTADD_cdata(<<>>) -> undefined;
+decode_vcard_EXTADD_cdata(_val) -> _val.
 
-encode_vcard_FAMILY_cdata(undefined, _acc) -> _acc;
-encode_vcard_FAMILY_cdata(_val, _acc) ->
+encode_vcard_EXTADD_cdata(undefined, _acc) -> _acc;
+encode_vcard_EXTADD_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_GIVEN({xmlel, <<"GIVEN">>, _attrs,
+decode_vcard_POBOX({xmlel, <<"POBOX">>, _attrs,
                    _els}) ->
-    Cdata = decode_vcard_GIVEN_els(_els, <<>>), Cdata.
+    Cdata = decode_vcard_POBOX_els(_els, <<>>), Cdata.
 
-decode_vcard_GIVEN_els([], Cdata) ->
-    decode_vcard_GIVEN_cdata(Cdata);
-decode_vcard_GIVEN_els([{xmlcdata, _data} | _els],
+decode_vcard_POBOX_els([], Cdata) ->
+    decode_vcard_POBOX_cdata(Cdata);
+decode_vcard_POBOX_els([{xmlcdata, _data} | _els],
                       Cdata) ->
-    decode_vcard_GIVEN_els(_els,
+    decode_vcard_POBOX_els(_els,
                           <<Cdata/binary, _data/binary>>);
-decode_vcard_GIVEN_els([_ | _els], Cdata) ->
-    decode_vcard_GIVEN_els(_els, Cdata).
+decode_vcard_POBOX_els([_ | _els], Cdata) ->
+    decode_vcard_POBOX_els(_els, Cdata).
 
-encode_vcard_GIVEN(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_GIVEN_cdata(Cdata, []),
+encode_vcard_POBOX(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_POBOX_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"GIVEN">>, _attrs, _els}.
+    {xmlel, <<"POBOX">>, _attrs, _els}.
 
-decode_vcard_GIVEN_cdata(<<>>) -> undefined;
-decode_vcard_GIVEN_cdata(_val) -> _val.
+decode_vcard_POBOX_cdata(<<>>) -> undefined;
+decode_vcard_POBOX_cdata(_val) -> _val.
 
-encode_vcard_GIVEN_cdata(undefined, _acc) -> _acc;
-encode_vcard_GIVEN_cdata(_val, _acc) ->
+encode_vcard_POBOX_cdata(undefined, _acc) -> _acc;
+encode_vcard_POBOX_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_MIDDLE({xmlel, <<"MIDDLE">>, _attrs,
+decode_vcard_SUFFIX({xmlel, <<"SUFFIX">>, _attrs,
                     _els}) ->
-    Cdata = decode_vcard_MIDDLE_els(_els, <<>>), Cdata.
+    Cdata = decode_vcard_SUFFIX_els(_els, <<>>), Cdata.
 
-decode_vcard_MIDDLE_els([], Cdata) ->
-    decode_vcard_MIDDLE_cdata(Cdata);
-decode_vcard_MIDDLE_els([{xmlcdata, _data} | _els],
+decode_vcard_SUFFIX_els([], Cdata) ->
+    decode_vcard_SUFFIX_cdata(Cdata);
+decode_vcard_SUFFIX_els([{xmlcdata, _data} | _els],
                        Cdata) ->
-    decode_vcard_MIDDLE_els(_els,
+    decode_vcard_SUFFIX_els(_els,
                            <<Cdata/binary, _data/binary>>);
-decode_vcard_MIDDLE_els([_ | _els], Cdata) ->
-    decode_vcard_MIDDLE_els(_els, Cdata).
+decode_vcard_SUFFIX_els([_ | _els], Cdata) ->
+    decode_vcard_SUFFIX_els(_els, Cdata).
 
-encode_vcard_MIDDLE(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_MIDDLE_cdata(Cdata, []),
+encode_vcard_SUFFIX(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_SUFFIX_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"MIDDLE">>, _attrs, _els}.
+    {xmlel, <<"SUFFIX">>, _attrs, _els}.
 
-decode_vcard_MIDDLE_cdata(<<>>) -> undefined;
-decode_vcard_MIDDLE_cdata(_val) -> _val.
+decode_vcard_SUFFIX_cdata(<<>>) -> undefined;
+decode_vcard_SUFFIX_cdata(_val) -> _val.
 
-encode_vcard_MIDDLE_cdata(undefined, _acc) -> _acc;
-encode_vcard_MIDDLE_cdata(_val, _acc) ->
+encode_vcard_SUFFIX_cdata(undefined, _acc) -> _acc;
+encode_vcard_SUFFIX_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
 decode_vcard_PREFIX({xmlel, <<"PREFIX">>, _attrs,
@@ -7587,6045 +7139,6410 @@ encode_vcard_PREFIX_cdata(undefined, _acc) -> _acc;
 encode_vcard_PREFIX_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_SUFFIX({xmlel, <<"SUFFIX">>, _attrs,
+decode_vcard_MIDDLE({xmlel, <<"MIDDLE">>, _attrs,
                     _els}) ->
-    Cdata = decode_vcard_SUFFIX_els(_els, <<>>), Cdata.
+    Cdata = decode_vcard_MIDDLE_els(_els, <<>>), Cdata.
 
-decode_vcard_SUFFIX_els([], Cdata) ->
-    decode_vcard_SUFFIX_cdata(Cdata);
-decode_vcard_SUFFIX_els([{xmlcdata, _data} | _els],
+decode_vcard_MIDDLE_els([], Cdata) ->
+    decode_vcard_MIDDLE_cdata(Cdata);
+decode_vcard_MIDDLE_els([{xmlcdata, _data} | _els],
                        Cdata) ->
-    decode_vcard_SUFFIX_els(_els,
+    decode_vcard_MIDDLE_els(_els,
                            <<Cdata/binary, _data/binary>>);
-decode_vcard_SUFFIX_els([_ | _els], Cdata) ->
-    decode_vcard_SUFFIX_els(_els, Cdata).
+decode_vcard_MIDDLE_els([_ | _els], Cdata) ->
+    decode_vcard_MIDDLE_els(_els, Cdata).
 
-encode_vcard_SUFFIX(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_SUFFIX_cdata(Cdata, []),
+encode_vcard_MIDDLE(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_MIDDLE_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"SUFFIX">>, _attrs, _els}.
+    {xmlel, <<"MIDDLE">>, _attrs, _els}.
 
-decode_vcard_SUFFIX_cdata(<<>>) -> undefined;
-decode_vcard_SUFFIX_cdata(_val) -> _val.
+decode_vcard_MIDDLE_cdata(<<>>) -> undefined;
+decode_vcard_MIDDLE_cdata(_val) -> _val.
 
-encode_vcard_SUFFIX_cdata(undefined, _acc) -> _acc;
-encode_vcard_SUFFIX_cdata(_val, _acc) ->
+encode_vcard_MIDDLE_cdata(undefined, _acc) -> _acc;
+encode_vcard_MIDDLE_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_POBOX({xmlel, <<"POBOX">>, _attrs,
+decode_vcard_GIVEN({xmlel, <<"GIVEN">>, _attrs,
                    _els}) ->
-    Cdata = decode_vcard_POBOX_els(_els, <<>>), Cdata.
+    Cdata = decode_vcard_GIVEN_els(_els, <<>>), Cdata.
 
-decode_vcard_POBOX_els([], Cdata) ->
-    decode_vcard_POBOX_cdata(Cdata);
-decode_vcard_POBOX_els([{xmlcdata, _data} | _els],
+decode_vcard_GIVEN_els([], Cdata) ->
+    decode_vcard_GIVEN_cdata(Cdata);
+decode_vcard_GIVEN_els([{xmlcdata, _data} | _els],
                       Cdata) ->
-    decode_vcard_POBOX_els(_els,
+    decode_vcard_GIVEN_els(_els,
                           <<Cdata/binary, _data/binary>>);
-decode_vcard_POBOX_els([_ | _els], Cdata) ->
-    decode_vcard_POBOX_els(_els, Cdata).
+decode_vcard_GIVEN_els([_ | _els], Cdata) ->
+    decode_vcard_GIVEN_els(_els, Cdata).
 
-encode_vcard_POBOX(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_POBOX_cdata(Cdata, []),
+encode_vcard_GIVEN(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_GIVEN_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"POBOX">>, _attrs, _els}.
+    {xmlel, <<"GIVEN">>, _attrs, _els}.
 
-decode_vcard_POBOX_cdata(<<>>) -> undefined;
-decode_vcard_POBOX_cdata(_val) -> _val.
+decode_vcard_GIVEN_cdata(<<>>) -> undefined;
+decode_vcard_GIVEN_cdata(_val) -> _val.
 
-encode_vcard_POBOX_cdata(undefined, _acc) -> _acc;
-encode_vcard_POBOX_cdata(_val, _acc) ->
+encode_vcard_GIVEN_cdata(undefined, _acc) -> _acc;
+encode_vcard_GIVEN_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_EXTADD({xmlel, <<"EXTADD">>, _attrs,
+decode_vcard_FAMILY({xmlel, <<"FAMILY">>, _attrs,
                     _els}) ->
-    Cdata = decode_vcard_EXTADD_els(_els, <<>>), Cdata.
+    Cdata = decode_vcard_FAMILY_els(_els, <<>>), Cdata.
 
-decode_vcard_EXTADD_els([], Cdata) ->
-    decode_vcard_EXTADD_cdata(Cdata);
-decode_vcard_EXTADD_els([{xmlcdata, _data} | _els],
+decode_vcard_FAMILY_els([], Cdata) ->
+    decode_vcard_FAMILY_cdata(Cdata);
+decode_vcard_FAMILY_els([{xmlcdata, _data} | _els],
                        Cdata) ->
-    decode_vcard_EXTADD_els(_els,
+    decode_vcard_FAMILY_els(_els,
                            <<Cdata/binary, _data/binary>>);
-decode_vcard_EXTADD_els([_ | _els], Cdata) ->
-    decode_vcard_EXTADD_els(_els, Cdata).
+decode_vcard_FAMILY_els([_ | _els], Cdata) ->
+    decode_vcard_FAMILY_els(_els, Cdata).
 
-encode_vcard_EXTADD(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_EXTADD_cdata(Cdata, []),
+encode_vcard_FAMILY(Cdata, _xmlns_attrs) ->
+    _els = encode_vcard_FAMILY_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"EXTADD">>, _attrs, _els}.
+    {xmlel, <<"FAMILY">>, _attrs, _els}.
 
-decode_vcard_EXTADD_cdata(<<>>) -> undefined;
-decode_vcard_EXTADD_cdata(_val) -> _val.
+decode_vcard_FAMILY_cdata(<<>>) -> undefined;
+decode_vcard_FAMILY_cdata(_val) -> _val.
 
-encode_vcard_EXTADD_cdata(undefined, _acc) -> _acc;
-encode_vcard_EXTADD_cdata(_val, _acc) ->
+encode_vcard_FAMILY_cdata(undefined, _acc) -> _acc;
+encode_vcard_FAMILY_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_STREET({xmlel, <<"STREET">>, _attrs,
+decode_vcard_X400({xmlel, <<"X400">>, _attrs, _els}) ->
+    true.
+
+encode_vcard_X400(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"X400">>, _attrs, _els}.
+
+decode_vcard_INTERNET({xmlel, <<"INTERNET">>, _attrs,
+                      _els}) ->
+    true.
+
+encode_vcard_INTERNET(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"INTERNET">>, _attrs, _els}.
+
+decode_vcard_PREF({xmlel, <<"PREF">>, _attrs, _els}) ->
+    true.
+
+encode_vcard_PREF(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"PREF">>, _attrs, _els}.
+
+decode_vcard_INTL({xmlel, <<"INTL">>, _attrs, _els}) ->
+    true.
+
+encode_vcard_INTL(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"INTL">>, _attrs, _els}.
+
+decode_vcard_DOM({xmlel, <<"DOM">>, _attrs, _els}) ->
+    true.
+
+encode_vcard_DOM(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"DOM">>, _attrs, _els}.
+
+decode_vcard_PARCEL({xmlel, <<"PARCEL">>, _attrs,
                     _els}) ->
-    Cdata = decode_vcard_STREET_els(_els, <<>>), Cdata.
+    true.
 
-decode_vcard_STREET_els([], Cdata) ->
-    decode_vcard_STREET_cdata(Cdata);
-decode_vcard_STREET_els([{xmlcdata, _data} | _els],
-                       Cdata) ->
-    decode_vcard_STREET_els(_els,
-                           <<Cdata/binary, _data/binary>>);
-decode_vcard_STREET_els([_ | _els], Cdata) ->
-    decode_vcard_STREET_els(_els, Cdata).
+encode_vcard_PARCEL(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"PARCEL">>, _attrs, _els}.
 
-encode_vcard_STREET(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_STREET_cdata(Cdata, []),
+decode_vcard_POSTAL({xmlel, <<"POSTAL">>, _attrs,
+                    _els}) ->
+    true.
+
+encode_vcard_POSTAL(true, _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"STREET">>, _attrs, _els}.
+    {xmlel, <<"POSTAL">>, _attrs, _els}.
 
-decode_vcard_STREET_cdata(<<>>) -> undefined;
-decode_vcard_STREET_cdata(_val) -> _val.
+decode_vcard_PCS({xmlel, <<"PCS">>, _attrs, _els}) ->
+    true.
 
-encode_vcard_STREET_cdata(undefined, _acc) -> _acc;
-encode_vcard_STREET_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_vcard_PCS(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"PCS">>, _attrs, _els}.
 
-decode_vcard_LOCALITY({xmlel, <<"LOCALITY">>, _attrs,
-                      _els}) ->
-    Cdata = decode_vcard_LOCALITY_els(_els, <<>>), Cdata.
+decode_vcard_ISDN({xmlel, <<"ISDN">>, _attrs, _els}) ->
+    true.
 
-decode_vcard_LOCALITY_els([], Cdata) ->
-    decode_vcard_LOCALITY_cdata(Cdata);
-decode_vcard_LOCALITY_els([{xmlcdata, _data} | _els],
-                         Cdata) ->
-    decode_vcard_LOCALITY_els(_els,
-                             <<Cdata/binary, _data/binary>>);
-decode_vcard_LOCALITY_els([_ | _els], Cdata) ->
-    decode_vcard_LOCALITY_els(_els, Cdata).
+encode_vcard_ISDN(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"ISDN">>, _attrs, _els}.
 
-encode_vcard_LOCALITY(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_LOCALITY_cdata(Cdata, []),
+decode_vcard_MODEM({xmlel, <<"MODEM">>, _attrs,
+                   _els}) ->
+    true.
+
+encode_vcard_MODEM(true, _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"LOCALITY">>, _attrs, _els}.
+    {xmlel, <<"MODEM">>, _attrs, _els}.
 
-decode_vcard_LOCALITY_cdata(<<>>) -> undefined;
-decode_vcard_LOCALITY_cdata(_val) -> _val.
+decode_vcard_BBS({xmlel, <<"BBS">>, _attrs, _els}) ->
+    true.
 
-encode_vcard_LOCALITY_cdata(undefined, _acc) -> _acc;
-encode_vcard_LOCALITY_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_vcard_BBS(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"BBS">>, _attrs, _els}.
 
-decode_vcard_REGION({xmlel, <<"REGION">>, _attrs,
-                    _els}) ->
-    Cdata = decode_vcard_REGION_els(_els, <<>>), Cdata.
+decode_vcard_VIDEO({xmlel, <<"VIDEO">>, _attrs,
+                   _els}) ->
+    true.
 
-decode_vcard_REGION_els([], Cdata) ->
-    decode_vcard_REGION_cdata(Cdata);
-decode_vcard_REGION_els([{xmlcdata, _data} | _els],
-                       Cdata) ->
-    decode_vcard_REGION_els(_els,
-                           <<Cdata/binary, _data/binary>>);
-decode_vcard_REGION_els([_ | _els], Cdata) ->
-    decode_vcard_REGION_els(_els, Cdata).
+encode_vcard_VIDEO(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"VIDEO">>, _attrs, _els}.
 
-encode_vcard_REGION(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_REGION_cdata(Cdata, []),
+decode_vcard_CELL({xmlel, <<"CELL">>, _attrs, _els}) ->
+    true.
+
+encode_vcard_CELL(true, _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"REGION">>, _attrs, _els}.
+    {xmlel, <<"CELL">>, _attrs, _els}.
 
-decode_vcard_REGION_cdata(<<>>) -> undefined;
-decode_vcard_REGION_cdata(_val) -> _val.
+decode_vcard_MSG({xmlel, <<"MSG">>, _attrs, _els}) ->
+    true.
 
-encode_vcard_REGION_cdata(undefined, _acc) -> _acc;
-encode_vcard_REGION_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_vcard_MSG(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"MSG">>, _attrs, _els}.
 
-decode_vcard_PCODE({xmlel, <<"PCODE">>, _attrs,
+decode_vcard_PAGER({xmlel, <<"PAGER">>, _attrs,
                    _els}) ->
-    Cdata = decode_vcard_PCODE_els(_els, <<>>), Cdata.
-
-decode_vcard_PCODE_els([], Cdata) ->
-    decode_vcard_PCODE_cdata(Cdata);
-decode_vcard_PCODE_els([{xmlcdata, _data} | _els],
-                      Cdata) ->
-    decode_vcard_PCODE_els(_els,
-                          <<Cdata/binary, _data/binary>>);
-decode_vcard_PCODE_els([_ | _els], Cdata) ->
-    decode_vcard_PCODE_els(_els, Cdata).
+    true.
 
-encode_vcard_PCODE(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_PCODE_cdata(Cdata, []),
+encode_vcard_PAGER(true, _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"PCODE">>, _attrs, _els}.
+    {xmlel, <<"PAGER">>, _attrs, _els}.
 
-decode_vcard_PCODE_cdata(<<>>) -> undefined;
-decode_vcard_PCODE_cdata(_val) -> _val.
+decode_vcard_FAX({xmlel, <<"FAX">>, _attrs, _els}) ->
+    true.
 
-encode_vcard_PCODE_cdata(undefined, _acc) -> _acc;
-encode_vcard_PCODE_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_vcard_FAX(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"FAX">>, _attrs, _els}.
 
-decode_vcard_CTRY({xmlel, <<"CTRY">>, _attrs, _els}) ->
-    Cdata = decode_vcard_CTRY_els(_els, <<>>), Cdata.
+decode_vcard_VOICE({xmlel, <<"VOICE">>, _attrs,
+                   _els}) ->
+    true.
 
-decode_vcard_CTRY_els([], Cdata) ->
-    decode_vcard_CTRY_cdata(Cdata);
-decode_vcard_CTRY_els([{xmlcdata, _data} | _els],
-                     Cdata) ->
-    decode_vcard_CTRY_els(_els,
-                         <<Cdata/binary, _data/binary>>);
-decode_vcard_CTRY_els([_ | _els], Cdata) ->
-    decode_vcard_CTRY_els(_els, Cdata).
+encode_vcard_VOICE(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"VOICE">>, _attrs, _els}.
 
-encode_vcard_CTRY(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_CTRY_cdata(Cdata, []),
+decode_vcard_WORK({xmlel, <<"WORK">>, _attrs, _els}) ->
+    true.
+
+encode_vcard_WORK(true, _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"CTRY">>, _attrs, _els}.
+    {xmlel, <<"WORK">>, _attrs, _els}.
 
-decode_vcard_CTRY_cdata(<<>>) -> undefined;
-decode_vcard_CTRY_cdata(_val) -> _val.
+decode_vcard_HOME({xmlel, <<"HOME">>, _attrs, _els}) ->
+    true.
 
-encode_vcard_CTRY_cdata(undefined, _acc) -> _acc;
-encode_vcard_CTRY_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_vcard_HOME(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"HOME">>, _attrs, _els}.
 
-decode_vcard_LINE({xmlel, <<"LINE">>, _attrs, _els}) ->
-    Cdata = decode_vcard_LINE_els(_els, <<>>), Cdata.
+decode_stream_error({xmlel, <<"stream:error">>, _attrs,
+                    _els}) ->
+    {Text, Reason} = decode_stream_error_els(_els,
+                                            undefined, undefined),
+    {stream_error, Reason, Text}.
 
-decode_vcard_LINE_els([], Cdata) ->
-    decode_vcard_LINE_cdata(Cdata);
-decode_vcard_LINE_els([{xmlcdata, _data} | _els],
-                     Cdata) ->
-    decode_vcard_LINE_els(_els,
-                         <<Cdata/binary, _data/binary>>);
-decode_vcard_LINE_els([_ | _els], Cdata) ->
-    decode_vcard_LINE_els(_els, Cdata).
+decode_stream_error_els([], Text, Reason) ->
+    {Text, Reason};
+decode_stream_error_els([{xmlel, <<"text">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els,
+                                  decode_stream_error_text(_el), Reason);
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"bad-format">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_bad_format(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel,
+                         <<"bad-namespace-prefix">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_bad_namespace_prefix(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"conflict">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_conflict(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel,
+                         <<"connection-timeout">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_connection_timeout(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"host-gone">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_host_gone(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"host-unknown">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_host_unknown(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel,
+                         <<"improper-addressing">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_improper_addressing(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel,
+                         <<"internal-server-error">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_internal_server_error(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"invalid-from">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_invalid_from(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"invalid-id">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_invalid_id(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel,
+                         <<"invalid-namespace">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_invalid_namespace(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"invalid-xml">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_invalid_xml(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"not-authorized">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_not_authorized(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"not-well-formed">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_not_well_formed(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"policy-violation">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_policy_violation(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel,
+                         <<"remote-connection-failed">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_remote_connection_failed(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"reset">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_reset(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel,
+                         <<"resource-constraint">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_resource_constraint(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"restricted-xml">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_restricted_xml(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"see-other-host">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_see_other_host(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel, <<"system-shutdown">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_system_shutdown(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel,
+                         <<"undefined-condition">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_undefined_condition(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel,
+                         <<"unsupported-encoding">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_unsupported_encoding(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel,
+                         <<"unsupported-stanza-type">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_unsupported_stanza_type(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([{xmlel,
+                         <<"unsupported-version">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-streams">> ->
+          decode_stream_error_els(_els, Text,
+                                  decode_stream_error_unsupported_version(_el));
+       true -> decode_stream_error_els(_els, Text, Reason)
+    end;
+decode_stream_error_els([_ | _els], Text, Reason) ->
+    decode_stream_error_els(_els, Text, Reason).
 
-encode_vcard_LINE(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_LINE_cdata(Cdata, []),
+encode_stream_error({stream_error, Reason, Text},
+                   _xmlns_attrs) ->
+    _els = 'encode_stream_error_$reason'(Reason,
+                                        'encode_stream_error_$text'(Text, [])),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"LINE">>, _attrs, _els}.
-
-decode_vcard_LINE_cdata(<<>>) -> undefined;
-decode_vcard_LINE_cdata(_val) -> _val.
+    {xmlel, <<"stream:error">>, _attrs, _els}.
 
-encode_vcard_LINE_cdata(undefined, _acc) -> _acc;
-encode_vcard_LINE_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_stream_error_$text'(undefined, _acc) -> _acc;
+'encode_stream_error_$text'(Text, _acc) ->
+    [encode_stream_error_text(Text,
+                             [{<<"xmlns">>,
+                               <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc].
 
-decode_vcard_NUMBER({xmlel, <<"NUMBER">>, _attrs,
-                    _els}) ->
-    Cdata = decode_vcard_NUMBER_els(_els, <<>>), Cdata.
+'encode_stream_error_$reason'(undefined, _acc) -> _acc;
+'encode_stream_error_$reason'('bad-format' = Reason,
+                             _acc) ->
+    [encode_stream_error_bad_format(Reason,
+                                   [{<<"xmlns">>,
+                                     <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('bad-namespace-prefix' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_bad_namespace_prefix(Reason,
+                                             [{<<"xmlns">>,
+                                               <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'(conflict = Reason,
+                             _acc) ->
+    [encode_stream_error_conflict(Reason,
+                                 [{<<"xmlns">>,
+                                   <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('connection-timeout' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_connection_timeout(Reason,
+                                           [{<<"xmlns">>,
+                                             <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('host-gone' = Reason,
+                             _acc) ->
+    [encode_stream_error_host_gone(Reason,
+                                  [{<<"xmlns">>,
+                                    <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('host-unknown' = Reason,
+                             _acc) ->
+    [encode_stream_error_host_unknown(Reason,
+                                     [{<<"xmlns">>,
+                                       <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('improper-addressing' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_improper_addressing(Reason,
+                                            [{<<"xmlns">>,
+                                              <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('internal-server-error' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_internal_server_error(Reason,
+                                              [{<<"xmlns">>,
+                                                <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('invalid-from' = Reason,
+                             _acc) ->
+    [encode_stream_error_invalid_from(Reason,
+                                     [{<<"xmlns">>,
+                                       <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('invalid-id' = Reason,
+                             _acc) ->
+    [encode_stream_error_invalid_id(Reason,
+                                   [{<<"xmlns">>,
+                                     <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('invalid-namespace' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_invalid_namespace(Reason,
+                                          [{<<"xmlns">>,
+                                            <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('invalid-xml' = Reason,
+                             _acc) ->
+    [encode_stream_error_invalid_xml(Reason,
+                                    [{<<"xmlns">>,
+                                      <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('not-authorized' = Reason,
+                             _acc) ->
+    [encode_stream_error_not_authorized(Reason,
+                                       [{<<"xmlns">>,
+                                         <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('not-well-formed' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_not_well_formed(Reason,
+                                        [{<<"xmlns">>,
+                                          <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('policy-violation' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_policy_violation(Reason,
+                                         [{<<"xmlns">>,
+                                           <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('remote-connection-failed' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_remote_connection_failed(Reason,
+                                                 [{<<"xmlns">>,
+                                                   <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'(reset = Reason, _acc) ->
+    [encode_stream_error_reset(Reason,
+                              [{<<"xmlns">>,
+                                <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('resource-constraint' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_resource_constraint(Reason,
+                                            [{<<"xmlns">>,
+                                              <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('restricted-xml' = Reason,
+                             _acc) ->
+    [encode_stream_error_restricted_xml(Reason,
+                                       [{<<"xmlns">>,
+                                         <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'({'see-other-host', _} =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_see_other_host(Reason,
+                                       [{<<"xmlns">>,
+                                         <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('system-shutdown' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_system_shutdown(Reason,
+                                        [{<<"xmlns">>,
+                                          <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('undefined-condition' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_undefined_condition(Reason,
+                                            [{<<"xmlns">>,
+                                              <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('unsupported-encoding' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_unsupported_encoding(Reason,
+                                             [{<<"xmlns">>,
+                                               <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('unsupported-stanza-type' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_unsupported_stanza_type(Reason,
+                                                [{<<"xmlns">>,
+                                                  <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc];
+'encode_stream_error_$reason'('unsupported-version' =
+                                 Reason,
+                             _acc) ->
+    [encode_stream_error_unsupported_version(Reason,
+                                            [{<<"xmlns">>,
+                                              <<"urn:ietf:params:xml:ns:xmpp-streams">>}])
+     | _acc].
 
-decode_vcard_NUMBER_els([], Cdata) ->
-    decode_vcard_NUMBER_cdata(Cdata);
-decode_vcard_NUMBER_els([{xmlcdata, _data} | _els],
-                       Cdata) ->
-    decode_vcard_NUMBER_els(_els,
-                           <<Cdata/binary, _data/binary>>);
-decode_vcard_NUMBER_els([_ | _els], Cdata) ->
-    decode_vcard_NUMBER_els(_els, Cdata).
+decode_stream_error_unsupported_version({xmlel,
+                                        <<"unsupported-version">>, _attrs,
+                                        _els}) ->
+    'unsupported-version'.
 
-encode_vcard_NUMBER(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_NUMBER_cdata(Cdata, []),
+encode_stream_error_unsupported_version('unsupported-version',
+                                       _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"NUMBER">>, _attrs, _els}.
+    {xmlel, <<"unsupported-version">>, _attrs, _els}.
 
-decode_vcard_NUMBER_cdata(<<>>) -> undefined;
-decode_vcard_NUMBER_cdata(_val) -> _val.
+decode_stream_error_unsupported_stanza_type({xmlel,
+                                            <<"unsupported-stanza-type">>,
+                                            _attrs, _els}) ->
+    'unsupported-stanza-type'.
 
-encode_vcard_NUMBER_cdata(undefined, _acc) -> _acc;
-encode_vcard_NUMBER_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_stream_error_unsupported_stanza_type('unsupported-stanza-type',
+                                           _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"unsupported-stanza-type">>, _attrs, _els}.
 
-decode_vcard_USERID({xmlel, <<"USERID">>, _attrs,
-                    _els}) ->
-    Cdata = decode_vcard_USERID_els(_els, <<>>), Cdata.
+decode_stream_error_unsupported_encoding({xmlel,
+                                         <<"unsupported-encoding">>, _attrs,
+                                         _els}) ->
+    'unsupported-encoding'.
 
-decode_vcard_USERID_els([], Cdata) ->
-    decode_vcard_USERID_cdata(Cdata);
-decode_vcard_USERID_els([{xmlcdata, _data} | _els],
-                       Cdata) ->
-    decode_vcard_USERID_els(_els,
-                           <<Cdata/binary, _data/binary>>);
-decode_vcard_USERID_els([_ | _els], Cdata) ->
-    decode_vcard_USERID_els(_els, Cdata).
+encode_stream_error_unsupported_encoding('unsupported-encoding',
+                                        _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"unsupported-encoding">>, _attrs, _els}.
 
-encode_vcard_USERID(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_USERID_cdata(Cdata, []),
+decode_stream_error_undefined_condition({xmlel,
+                                        <<"undefined-condition">>, _attrs,
+                                        _els}) ->
+    'undefined-condition'.
+
+encode_stream_error_undefined_condition('undefined-condition',
+                                       _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"USERID">>, _attrs, _els}.
+    {xmlel, <<"undefined-condition">>, _attrs, _els}.
 
-decode_vcard_USERID_cdata(<<>>) -> undefined;
-decode_vcard_USERID_cdata(_val) -> _val.
+decode_stream_error_system_shutdown({xmlel,
+                                    <<"system-shutdown">>, _attrs, _els}) ->
+    'system-shutdown'.
 
-encode_vcard_USERID_cdata(undefined, _acc) -> _acc;
-encode_vcard_USERID_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_stream_error_system_shutdown('system-shutdown',
+                                   _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"system-shutdown">>, _attrs, _els}.
 
-decode_vcard_LAT({xmlel, <<"LAT">>, _attrs, _els}) ->
-    Cdata = decode_vcard_LAT_els(_els, <<>>), Cdata.
+decode_stream_error_see_other_host({xmlel,
+                                   <<"see-other-host">>, _attrs, _els}) ->
+    Host = decode_stream_error_see_other_host_els(_els,
+                                                 <<>>),
+    {'see-other-host', Host}.
 
-decode_vcard_LAT_els([], Cdata) ->
-    decode_vcard_LAT_cdata(Cdata);
-decode_vcard_LAT_els([{xmlcdata, _data} | _els],
-                    Cdata) ->
-    decode_vcard_LAT_els(_els,
-                        <<Cdata/binary, _data/binary>>);
-decode_vcard_LAT_els([_ | _els], Cdata) ->
-    decode_vcard_LAT_els(_els, Cdata).
+decode_stream_error_see_other_host_els([], Host) ->
+    decode_stream_error_see_other_host_cdata(Host);
+decode_stream_error_see_other_host_els([{xmlcdata,
+                                        _data}
+                                       | _els],
+                                      Host) ->
+    decode_stream_error_see_other_host_els(_els,
+                                          <<Host/binary, _data/binary>>);
+decode_stream_error_see_other_host_els([_ | _els],
+                                      Host) ->
+    decode_stream_error_see_other_host_els(_els, Host).
 
-encode_vcard_LAT(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_LAT_cdata(Cdata, []),
+encode_stream_error_see_other_host({'see-other-host',
+                                   Host},
+                                  _xmlns_attrs) ->
+    _els = encode_stream_error_see_other_host_cdata(Host,
+                                                   []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"LAT">>, _attrs, _els}.
+    {xmlel, <<"see-other-host">>, _attrs, _els}.
 
-decode_vcard_LAT_cdata(<<>>) -> undefined;
-decode_vcard_LAT_cdata(_val) -> _val.
+decode_stream_error_see_other_host_cdata(<<>>) ->
+    erlang:error({missing_cdata, <<>>, <<"see-other-host">>,
+                 <<"urn:ietf:params:xml:ns:xmpp-streams">>});
+decode_stream_error_see_other_host_cdata(_val) -> _val.
 
-encode_vcard_LAT_cdata(undefined, _acc) -> _acc;
-encode_vcard_LAT_cdata(_val, _acc) ->
+encode_stream_error_see_other_host_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_LON({xmlel, <<"LON">>, _attrs, _els}) ->
-    Cdata = decode_vcard_LON_els(_els, <<>>), Cdata.
-
-decode_vcard_LON_els([], Cdata) ->
-    decode_vcard_LON_cdata(Cdata);
-decode_vcard_LON_els([{xmlcdata, _data} | _els],
-                    Cdata) ->
-    decode_vcard_LON_els(_els,
-                        <<Cdata/binary, _data/binary>>);
-decode_vcard_LON_els([_ | _els], Cdata) ->
-    decode_vcard_LON_els(_els, Cdata).
+decode_stream_error_restricted_xml({xmlel,
+                                   <<"restricted-xml">>, _attrs, _els}) ->
+    'restricted-xml'.
 
-encode_vcard_LON(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_LON_cdata(Cdata, []),
+encode_stream_error_restricted_xml('restricted-xml',
+                                  _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"LON">>, _attrs, _els}.
-
-decode_vcard_LON_cdata(<<>>) -> undefined;
-decode_vcard_LON_cdata(_val) -> _val.
+    {xmlel, <<"restricted-xml">>, _attrs, _els}.
 
-encode_vcard_LON_cdata(undefined, _acc) -> _acc;
-encode_vcard_LON_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_stream_error_resource_constraint({xmlel,
+                                        <<"resource-constraint">>, _attrs,
+                                        _els}) ->
+    'resource-constraint'.
 
-decode_vcard_ORGNAME({xmlel, <<"ORGNAME">>, _attrs,
-                     _els}) ->
-    Cdata = decode_vcard_ORGNAME_els(_els, <<>>), Cdata.
+encode_stream_error_resource_constraint('resource-constraint',
+                                       _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"resource-constraint">>, _attrs, _els}.
 
-decode_vcard_ORGNAME_els([], Cdata) ->
-    decode_vcard_ORGNAME_cdata(Cdata);
-decode_vcard_ORGNAME_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_vcard_ORGNAME_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_vcard_ORGNAME_els([_ | _els], Cdata) ->
-    decode_vcard_ORGNAME_els(_els, Cdata).
+decode_stream_error_reset({xmlel, <<"reset">>, _attrs,
+                          _els}) ->
+    reset.
 
-encode_vcard_ORGNAME(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_ORGNAME_cdata(Cdata, []),
+encode_stream_error_reset(reset, _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"ORGNAME">>, _attrs, _els}.
-
-decode_vcard_ORGNAME_cdata(<<>>) -> undefined;
-decode_vcard_ORGNAME_cdata(_val) -> _val.
+    {xmlel, <<"reset">>, _attrs, _els}.
 
-encode_vcard_ORGNAME_cdata(undefined, _acc) -> _acc;
-encode_vcard_ORGNAME_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_stream_error_remote_connection_failed({xmlel,
+                                             <<"remote-connection-failed">>,
+                                             _attrs, _els}) ->
+    'remote-connection-failed'.
 
-decode_vcard_ORGUNIT({xmlel, <<"ORGUNIT">>, _attrs,
-                     _els}) ->
-    Cdata = decode_vcard_ORGUNIT_els(_els, <<>>), Cdata.
+encode_stream_error_remote_connection_failed('remote-connection-failed',
+                                            _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"remote-connection-failed">>, _attrs, _els}.
 
-decode_vcard_ORGUNIT_els([], Cdata) ->
-    decode_vcard_ORGUNIT_cdata(Cdata);
-decode_vcard_ORGUNIT_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_vcard_ORGUNIT_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_vcard_ORGUNIT_els([_ | _els], Cdata) ->
-    decode_vcard_ORGUNIT_els(_els, Cdata).
+decode_stream_error_policy_violation({xmlel,
+                                     <<"policy-violation">>, _attrs, _els}) ->
+    'policy-violation'.
 
-encode_vcard_ORGUNIT(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_ORGUNIT_cdata(Cdata, []),
+encode_stream_error_policy_violation('policy-violation',
+                                    _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"ORGUNIT">>, _attrs, _els}.
-
-decode_vcard_ORGUNIT_cdata(<<>>) -> undefined;
-decode_vcard_ORGUNIT_cdata(_val) -> _val.
+    {xmlel, <<"policy-violation">>, _attrs, _els}.
 
-encode_vcard_ORGUNIT_cdata(undefined, _acc) -> _acc;
-encode_vcard_ORGUNIT_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_stream_error_not_well_formed({xmlel,
+                                    <<"not-well-formed">>, _attrs, _els}) ->
+    'not-well-formed'.
 
-decode_vcard_PHONETIC({xmlel, <<"PHONETIC">>, _attrs,
-                      _els}) ->
-    Cdata = decode_vcard_PHONETIC_els(_els, <<>>), Cdata.
+encode_stream_error_not_well_formed('not-well-formed',
+                                   _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"not-well-formed">>, _attrs, _els}.
 
-decode_vcard_PHONETIC_els([], Cdata) ->
-    decode_vcard_PHONETIC_cdata(Cdata);
-decode_vcard_PHONETIC_els([{xmlcdata, _data} | _els],
-                         Cdata) ->
-    decode_vcard_PHONETIC_els(_els,
-                             <<Cdata/binary, _data/binary>>);
-decode_vcard_PHONETIC_els([_ | _els], Cdata) ->
-    decode_vcard_PHONETIC_els(_els, Cdata).
+decode_stream_error_not_authorized({xmlel,
+                                   <<"not-authorized">>, _attrs, _els}) ->
+    'not-authorized'.
 
-encode_vcard_PHONETIC(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_PHONETIC_cdata(Cdata, []),
+encode_stream_error_not_authorized('not-authorized',
+                                  _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"PHONETIC">>, _attrs, _els}.
-
-decode_vcard_PHONETIC_cdata(<<>>) -> undefined;
-decode_vcard_PHONETIC_cdata(_val) -> _val.
+    {xmlel, <<"not-authorized">>, _attrs, _els}.
 
-encode_vcard_PHONETIC_cdata(undefined, _acc) -> _acc;
-encode_vcard_PHONETIC_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_stream_error_invalid_xml({xmlel,
+                                <<"invalid-xml">>, _attrs, _els}) ->
+    'invalid-xml'.
 
-decode_vcard_CRED({xmlel, <<"CRED">>, _attrs, _els}) ->
-    Cdata = decode_vcard_CRED_els(_els, <<>>), Cdata.
+encode_stream_error_invalid_xml('invalid-xml',
+                               _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"invalid-xml">>, _attrs, _els}.
 
-decode_vcard_CRED_els([], Cdata) ->
-    decode_vcard_CRED_cdata(Cdata);
-decode_vcard_CRED_els([{xmlcdata, _data} | _els],
-                     Cdata) ->
-    decode_vcard_CRED_els(_els,
-                         <<Cdata/binary, _data/binary>>);
-decode_vcard_CRED_els([_ | _els], Cdata) ->
-    decode_vcard_CRED_els(_els, Cdata).
+decode_stream_error_invalid_namespace({xmlel,
+                                      <<"invalid-namespace">>, _attrs,
+                                      _els}) ->
+    'invalid-namespace'.
 
-encode_vcard_CRED(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_CRED_cdata(Cdata, []),
+encode_stream_error_invalid_namespace('invalid-namespace',
+                                     _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"CRED">>, _attrs, _els}.
+    {xmlel, <<"invalid-namespace">>, _attrs, _els}.
 
-decode_vcard_CRED_cdata(<<>>) -> undefined;
-decode_vcard_CRED_cdata(_val) -> _val.
+decode_stream_error_invalid_id({xmlel, <<"invalid-id">>,
+                               _attrs, _els}) ->
+    'invalid-id'.
 
-encode_vcard_CRED_cdata(undefined, _acc) -> _acc;
-encode_vcard_CRED_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_stream_error_invalid_id('invalid-id',
+                              _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"invalid-id">>, _attrs, _els}.
 
-decode_vcard_VERSION({xmlel, <<"VERSION">>, _attrs,
-                     _els}) ->
-    Cdata = decode_vcard_VERSION_els(_els, <<>>), Cdata.
+decode_stream_error_invalid_from({xmlel,
+                                 <<"invalid-from">>, _attrs, _els}) ->
+    'invalid-from'.
 
-decode_vcard_VERSION_els([], Cdata) ->
-    decode_vcard_VERSION_cdata(Cdata);
-decode_vcard_VERSION_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_vcard_VERSION_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_vcard_VERSION_els([_ | _els], Cdata) ->
-    decode_vcard_VERSION_els(_els, Cdata).
+encode_stream_error_invalid_from('invalid-from',
+                                _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"invalid-from">>, _attrs, _els}.
+
+decode_stream_error_internal_server_error({xmlel,
+                                          <<"internal-server-error">>, _attrs,
+                                          _els}) ->
+    'internal-server-error'.
 
-encode_vcard_VERSION(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_VERSION_cdata(Cdata, []),
+encode_stream_error_internal_server_error('internal-server-error',
+                                         _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"VERSION">>, _attrs, _els}.
-
-decode_vcard_VERSION_cdata(<<>>) -> undefined;
-decode_vcard_VERSION_cdata(_val) -> _val.
+    {xmlel, <<"internal-server-error">>, _attrs, _els}.
 
-encode_vcard_VERSION_cdata(undefined, _acc) -> _acc;
-encode_vcard_VERSION_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_stream_error_improper_addressing({xmlel,
+                                        <<"improper-addressing">>, _attrs,
+                                        _els}) ->
+    'improper-addressing'.
 
-decode_vcard_FN({xmlel, <<"FN">>, _attrs, _els}) ->
-    Cdata = decode_vcard_FN_els(_els, <<>>), Cdata.
+encode_stream_error_improper_addressing('improper-addressing',
+                                       _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"improper-addressing">>, _attrs, _els}.
 
-decode_vcard_FN_els([], Cdata) ->
-    decode_vcard_FN_cdata(Cdata);
-decode_vcard_FN_els([{xmlcdata, _data} | _els],
-                   Cdata) ->
-    decode_vcard_FN_els(_els,
-                       <<Cdata/binary, _data/binary>>);
-decode_vcard_FN_els([_ | _els], Cdata) ->
-    decode_vcard_FN_els(_els, Cdata).
+decode_stream_error_host_unknown({xmlel,
+                                 <<"host-unknown">>, _attrs, _els}) ->
+    'host-unknown'.
 
-encode_vcard_FN(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_FN_cdata(Cdata, []),
+encode_stream_error_host_unknown('host-unknown',
+                                _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"FN">>, _attrs, _els}.
-
-decode_vcard_FN_cdata(<<>>) -> undefined;
-decode_vcard_FN_cdata(_val) -> _val.
+    {xmlel, <<"host-unknown">>, _attrs, _els}.
 
-encode_vcard_FN_cdata(undefined, _acc) -> _acc;
-encode_vcard_FN_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_stream_error_host_gone({xmlel, <<"host-gone">>,
+                              _attrs, _els}) ->
+    'host-gone'.
 
-decode_vcard_NICKNAME({xmlel, <<"NICKNAME">>, _attrs,
-                      _els}) ->
-    Cdata = decode_vcard_NICKNAME_els(_els, <<>>), Cdata.
+encode_stream_error_host_gone('host-gone',
+                             _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"host-gone">>, _attrs, _els}.
 
-decode_vcard_NICKNAME_els([], Cdata) ->
-    decode_vcard_NICKNAME_cdata(Cdata);
-decode_vcard_NICKNAME_els([{xmlcdata, _data} | _els],
-                         Cdata) ->
-    decode_vcard_NICKNAME_els(_els,
-                             <<Cdata/binary, _data/binary>>);
-decode_vcard_NICKNAME_els([_ | _els], Cdata) ->
-    decode_vcard_NICKNAME_els(_els, Cdata).
+decode_stream_error_connection_timeout({xmlel,
+                                       <<"connection-timeout">>, _attrs,
+                                       _els}) ->
+    'connection-timeout'.
 
-encode_vcard_NICKNAME(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_NICKNAME_cdata(Cdata, []),
+encode_stream_error_connection_timeout('connection-timeout',
+                                      _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"NICKNAME">>, _attrs, _els}.
+    {xmlel, <<"connection-timeout">>, _attrs, _els}.
 
-decode_vcard_NICKNAME_cdata(<<>>) -> undefined;
-decode_vcard_NICKNAME_cdata(_val) -> _val.
+decode_stream_error_conflict({xmlel, <<"conflict">>,
+                             _attrs, _els}) ->
+    conflict.
 
-encode_vcard_NICKNAME_cdata(undefined, _acc) -> _acc;
-encode_vcard_NICKNAME_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_stream_error_conflict(conflict, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"conflict">>, _attrs, _els}.
 
-decode_vcard_BDAY({xmlel, <<"BDAY">>, _attrs, _els}) ->
-    Cdata = decode_vcard_BDAY_els(_els, <<>>), Cdata.
+decode_stream_error_bad_namespace_prefix({xmlel,
+                                         <<"bad-namespace-prefix">>, _attrs,
+                                         _els}) ->
+    'bad-namespace-prefix'.
 
-decode_vcard_BDAY_els([], Cdata) ->
-    decode_vcard_BDAY_cdata(Cdata);
-decode_vcard_BDAY_els([{xmlcdata, _data} | _els],
-                     Cdata) ->
-    decode_vcard_BDAY_els(_els,
-                         <<Cdata/binary, _data/binary>>);
-decode_vcard_BDAY_els([_ | _els], Cdata) ->
-    decode_vcard_BDAY_els(_els, Cdata).
+encode_stream_error_bad_namespace_prefix('bad-namespace-prefix',
+                                        _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"bad-namespace-prefix">>, _attrs, _els}.
 
-encode_vcard_BDAY(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_BDAY_cdata(Cdata, []),
+decode_stream_error_bad_format({xmlel, <<"bad-format">>,
+                               _attrs, _els}) ->
+    'bad-format'.
+
+encode_stream_error_bad_format('bad-format',
+                              _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"BDAY">>, _attrs, _els}.
+    {xmlel, <<"bad-format">>, _attrs, _els}.
 
-decode_vcard_BDAY_cdata(<<>>) -> undefined;
-decode_vcard_BDAY_cdata(_val) -> _val.
+decode_stream_error_text({xmlel, <<"text">>, _attrs,
+                         _els}) ->
+    Data = decode_stream_error_text_els(_els, <<>>),
+    Lang = decode_stream_error_text_attrs(_attrs,
+                                         undefined),
+    {text, Lang, Data}.
 
-encode_vcard_BDAY_cdata(undefined, _acc) -> _acc;
-encode_vcard_BDAY_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_stream_error_text_els([], Data) ->
+    decode_stream_error_text_cdata(Data);
+decode_stream_error_text_els([{xmlcdata, _data} | _els],
+                            Data) ->
+    decode_stream_error_text_els(_els,
+                                <<Data/binary, _data/binary>>);
+decode_stream_error_text_els([_ | _els], Data) ->
+    decode_stream_error_text_els(_els, Data).
 
-decode_vcard_JABBERID({xmlel, <<"JABBERID">>, _attrs,
-                      _els}) ->
-    Cdata = decode_vcard_JABBERID_els(_els, <<>>), Cdata.
+decode_stream_error_text_attrs([{<<"xml:lang">>, _val}
+                               | _attrs],
+                              _Lang) ->
+    decode_stream_error_text_attrs(_attrs, _val);
+decode_stream_error_text_attrs([_ | _attrs], Lang) ->
+    decode_stream_error_text_attrs(_attrs, Lang);
+decode_stream_error_text_attrs([], Lang) ->
+    'decode_stream_error_text_attr_xml:lang'(Lang).
 
-decode_vcard_JABBERID_els([], Cdata) ->
-    decode_vcard_JABBERID_cdata(Cdata);
-decode_vcard_JABBERID_els([{xmlcdata, _data} | _els],
-                         Cdata) ->
-    decode_vcard_JABBERID_els(_els,
-                             <<Cdata/binary, _data/binary>>);
-decode_vcard_JABBERID_els([_ | _els], Cdata) ->
-    decode_vcard_JABBERID_els(_els, Cdata).
+encode_stream_error_text({text, Lang, Data},
+                        _xmlns_attrs) ->
+    _els = encode_stream_error_text_cdata(Data, []),
+    _attrs = 'encode_stream_error_text_attr_xml:lang'(Lang,
+                                                     _xmlns_attrs),
+    {xmlel, <<"text">>, _attrs, _els}.
 
-encode_vcard_JABBERID(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_JABBERID_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"JABBERID">>, _attrs, _els}.
+'decode_stream_error_text_attr_xml:lang'(undefined) ->
+    undefined;
+'decode_stream_error_text_attr_xml:lang'(_val) -> _val.
 
-decode_vcard_JABBERID_cdata(<<>>) -> undefined;
-decode_vcard_JABBERID_cdata(_val) -> _val.
+'encode_stream_error_text_attr_xml:lang'(undefined,
+                                        _acc) ->
+    _acc;
+'encode_stream_error_text_attr_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
 
-encode_vcard_JABBERID_cdata(undefined, _acc) -> _acc;
-encode_vcard_JABBERID_cdata(_val, _acc) ->
+decode_stream_error_text_cdata(<<>>) -> undefined;
+decode_stream_error_text_cdata(_val) -> _val.
+
+encode_stream_error_text_cdata(undefined, _acc) -> _acc;
+encode_stream_error_text_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_MAILER({xmlel, <<"MAILER">>, _attrs,
-                    _els}) ->
-    Cdata = decode_vcard_MAILER_els(_els, <<>>), Cdata.
+decode_time({xmlel, <<"time">>, _attrs, _els}) ->
+    {Utc, Tzo} = decode_time_els(_els, undefined,
+                                undefined),
+    {time, Tzo, Utc}.
 
-decode_vcard_MAILER_els([], Cdata) ->
-    decode_vcard_MAILER_cdata(Cdata);
-decode_vcard_MAILER_els([{xmlcdata, _data} | _els],
-                       Cdata) ->
-    decode_vcard_MAILER_els(_els,
-                           <<Cdata/binary, _data/binary>>);
-decode_vcard_MAILER_els([_ | _els], Cdata) ->
-    decode_vcard_MAILER_els(_els, Cdata).
+decode_time_els([], Utc, Tzo) -> {Utc, Tzo};
+decode_time_els([{xmlel, <<"tzo">>, _attrs, _} = _el
+                | _els],
+               Utc, Tzo) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"urn:xmpp:time">> ->
+          decode_time_els(_els, Utc, decode_time_tzo(_el));
+       true -> decode_time_els(_els, Utc, Tzo)
+    end;
+decode_time_els([{xmlel, <<"utc">>, _attrs, _} = _el
+                | _els],
+               Utc, Tzo) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"urn:xmpp:time">> ->
+          decode_time_els(_els, decode_time_utc(_el), Tzo);
+       true -> decode_time_els(_els, Utc, Tzo)
+    end;
+decode_time_els([_ | _els], Utc, Tzo) ->
+    decode_time_els(_els, Utc, Tzo).
 
-encode_vcard_MAILER(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_MAILER_cdata(Cdata, []),
+encode_time({time, Tzo, Utc}, _xmlns_attrs) ->
+    _els = 'encode_time_$tzo'(Tzo,
+                             'encode_time_$utc'(Utc, [])),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"MAILER">>, _attrs, _els}.
+    {xmlel, <<"time">>, _attrs, _els}.
 
-decode_vcard_MAILER_cdata(<<>>) -> undefined;
-decode_vcard_MAILER_cdata(_val) -> _val.
+'encode_time_$utc'(undefined, _acc) -> _acc;
+'encode_time_$utc'(Utc, _acc) ->
+    [encode_time_utc(Utc, []) | _acc].
 
-encode_vcard_MAILER_cdata(undefined, _acc) -> _acc;
-encode_vcard_MAILER_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_time_$tzo'(undefined, _acc) -> _acc;
+'encode_time_$tzo'(Tzo, _acc) ->
+    [encode_time_tzo(Tzo, []) | _acc].
 
-decode_vcard_TZ({xmlel, <<"TZ">>, _attrs, _els}) ->
-    Cdata = decode_vcard_TZ_els(_els, <<>>), Cdata.
+decode_time_tzo({xmlel, <<"tzo">>, _attrs, _els}) ->
+    Cdata = decode_time_tzo_els(_els, <<>>), Cdata.
 
-decode_vcard_TZ_els([], Cdata) ->
-    decode_vcard_TZ_cdata(Cdata);
-decode_vcard_TZ_els([{xmlcdata, _data} | _els],
+decode_time_tzo_els([], Cdata) ->
+    decode_time_tzo_cdata(Cdata);
+decode_time_tzo_els([{xmlcdata, _data} | _els],
                    Cdata) ->
-    decode_vcard_TZ_els(_els,
+    decode_time_tzo_els(_els,
                        <<Cdata/binary, _data/binary>>);
-decode_vcard_TZ_els([_ | _els], Cdata) ->
-    decode_vcard_TZ_els(_els, Cdata).
-
-encode_vcard_TZ(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_TZ_cdata(Cdata, []),
+decode_time_tzo_els([_ | _els], Cdata) ->
+    decode_time_tzo_els(_els, Cdata).
+
+encode_time_tzo(Cdata, _xmlns_attrs) ->
+    _els = encode_time_tzo_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"TZ">>, _attrs, _els}.
+    {xmlel, <<"tzo">>, _attrs, _els}.
 
-decode_vcard_TZ_cdata(<<>>) -> undefined;
-decode_vcard_TZ_cdata(_val) -> _val.
+decode_time_tzo_cdata(<<>>) -> undefined;
+decode_time_tzo_cdata(_val) ->
+    case catch dec_tzo(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"tzo">>,
+                       <<"urn:xmpp:time">>});
+      _res -> _res
+    end.
 
-encode_vcard_TZ_cdata(undefined, _acc) -> _acc;
-encode_vcard_TZ_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_time_tzo_cdata(undefined, _acc) -> _acc;
+encode_time_tzo_cdata(_val, _acc) ->
+    [{xmlcdata, enc_tzo(_val)} | _acc].
 
-decode_vcard_TITLE({xmlel, <<"TITLE">>, _attrs,
-                   _els}) ->
-    Cdata = decode_vcard_TITLE_els(_els, <<>>), Cdata.
+decode_time_utc({xmlel, <<"utc">>, _attrs, _els}) ->
+    Cdata = decode_time_utc_els(_els, <<>>), Cdata.
 
-decode_vcard_TITLE_els([], Cdata) ->
-    decode_vcard_TITLE_cdata(Cdata);
-decode_vcard_TITLE_els([{xmlcdata, _data} | _els],
-                      Cdata) ->
-    decode_vcard_TITLE_els(_els,
-                          <<Cdata/binary, _data/binary>>);
-decode_vcard_TITLE_els([_ | _els], Cdata) ->
-    decode_vcard_TITLE_els(_els, Cdata).
+decode_time_utc_els([], Cdata) ->
+    decode_time_utc_cdata(Cdata);
+decode_time_utc_els([{xmlcdata, _data} | _els],
+                   Cdata) ->
+    decode_time_utc_els(_els,
+                       <<Cdata/binary, _data/binary>>);
+decode_time_utc_els([_ | _els], Cdata) ->
+    decode_time_utc_els(_els, Cdata).
 
-encode_vcard_TITLE(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_TITLE_cdata(Cdata, []),
+encode_time_utc(Cdata, _xmlns_attrs) ->
+    _els = encode_time_utc_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"TITLE">>, _attrs, _els}.
-
-decode_vcard_TITLE_cdata(<<>>) -> undefined;
-decode_vcard_TITLE_cdata(_val) -> _val.
+    {xmlel, <<"utc">>, _attrs, _els}.
 
-encode_vcard_TITLE_cdata(undefined, _acc) -> _acc;
-encode_vcard_TITLE_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_time_utc_cdata(<<>>) -> undefined;
+decode_time_utc_cdata(_val) ->
+    case catch dec_utc(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"utc">>,
+                       <<"urn:xmpp:time">>});
+      _res -> _res
+    end.
 
-decode_vcard_ROLE({xmlel, <<"ROLE">>, _attrs, _els}) ->
-    Cdata = decode_vcard_ROLE_els(_els, <<>>), Cdata.
+encode_time_utc_cdata(undefined, _acc) -> _acc;
+encode_time_utc_cdata(_val, _acc) ->
+    [{xmlcdata, enc_utc(_val)} | _acc].
 
-decode_vcard_ROLE_els([], Cdata) ->
-    decode_vcard_ROLE_cdata(Cdata);
-decode_vcard_ROLE_els([{xmlcdata, _data} | _els],
-                     Cdata) ->
-    decode_vcard_ROLE_els(_els,
-                         <<Cdata/binary, _data/binary>>);
-decode_vcard_ROLE_els([_ | _els], Cdata) ->
-    decode_vcard_ROLE_els(_els, Cdata).
+decode_ping({xmlel, <<"ping">>, _attrs, _els}) ->
+    {ping}.
 
-encode_vcard_ROLE(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_ROLE_cdata(Cdata, []),
+encode_ping({ping}, _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"ROLE">>, _attrs, _els}.
+    {xmlel, <<"ping">>, _attrs, _els}.
 
-decode_vcard_ROLE_cdata(<<>>) -> undefined;
-decode_vcard_ROLE_cdata(_val) -> _val.
+decode_session({xmlel, <<"session">>, _attrs, _els}) ->
+    {session}.
 
-encode_vcard_ROLE_cdata(undefined, _acc) -> _acc;
-encode_vcard_ROLE_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_session({session}, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"session">>, _attrs, _els}.
 
-decode_vcard_KEYWORD({xmlel, <<"KEYWORD">>, _attrs,
-                     _els}) ->
-    Cdata = decode_vcard_KEYWORD_els(_els, <<>>), Cdata.
+decode_register({xmlel, <<"query">>, _attrs, _els}) ->
+    {Zip, Misc, Address, Instructions, Text, Last, First,
+     Password, Registered, Date, Phone, State, Name,
+     Username, Remove, Key, City, Nick, Url, Email} =
+       decode_register_els(_els, undefined, undefined,
+                           undefined, undefined, undefined, undefined,
+                           undefined, undefined, false, undefined, undefined,
+                           undefined, undefined, undefined, false, undefined,
+                           undefined, undefined, undefined, undefined),
+    {register, Registered, Remove, Instructions, Username,
+     Nick, Password, Name, First, Last, Email, Address, City,
+     State, Zip, Phone, Url, Date, Misc, Text, Key}.
 
-decode_vcard_KEYWORD_els([], Cdata) ->
-    decode_vcard_KEYWORD_cdata(Cdata);
-decode_vcard_KEYWORD_els([{xmlcdata, _data} | _els],
-                        Cdata) ->
-    decode_vcard_KEYWORD_els(_els,
-                            <<Cdata/binary, _data/binary>>);
-decode_vcard_KEYWORD_els([_ | _els], Cdata) ->
-    decode_vcard_KEYWORD_els(_els, Cdata).
+decode_register_els([], Zip, Misc, Address,
+                   Instructions, Text, Last, First, Password, Registered,
+                   Date, Phone, State, Name, Username, Remove, Key, City,
+                   Nick, Url, Email) ->
+    {Zip, Misc, Address, Instructions, Text, Last, First,
+     Password, Registered, Date, Phone, State, Name,
+     Username, Remove, Key, City, Nick, Url, Email};
+decode_register_els([{xmlel, <<"registered">>, _attrs,
+                     _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              decode_register_registered(_el), Date, Phone,
+                              State, Name, Username, Remove, Key, City, Nick,
+                              Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"remove">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              decode_register_remove(_el), Key, City, Nick,
+                              Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"instructions">>, _attrs,
+                     _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              decode_register_instructions(_el), Text, Last,
+                              First, Password, Registered, Date, Phone, State,
+                              Name, Username, Remove, Key, City, Nick, Url,
+                              Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"username">>, _attrs,
+                     _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name,
+                              decode_register_username(_el), Remove, Key, City,
+                              Nick, Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"nick">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, decode_register_nick(_el),
+                              Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"password">>, _attrs,
+                     _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First,
+                              decode_register_password(_el), Registered, Date,
+                              Phone, State, Name, Username, Remove, Key, City,
+                              Nick, Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"name">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State,
+                              decode_register_name(_el), Username, Remove, Key,
+                              City, Nick, Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"first">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last,
+                              decode_register_first(_el), Password, Registered,
+                              Date, Phone, State, Name, Username, Remove, Key,
+                              City, Nick, Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"last">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, decode_register_last(_el),
+                              First, Password, Registered, Date, Phone, State,
+                              Name, Username, Remove, Key, City, Nick, Url,
+                              Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"email">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url,
+                              decode_register_email(_el));
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"address">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc,
+                              decode_register_address(_el), Instructions, Text,
+                              Last, First, Password, Registered, Date, Phone,
+                              State, Name, Username, Remove, Key, City, Nick,
+                              Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"city">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, decode_register_city(_el), Nick,
+                              Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"state">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone,
+                              decode_register_state(_el), Name, Username,
+                              Remove, Key, City, Nick, Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"zip">>, _attrs, _} = _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, decode_register_zip(_el),
+                              Misc, Address, Instructions, Text, Last, First,
+                              Password, Registered, Date, Phone, State, Name,
+                              Username, Remove, Key, City, Nick, Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"phone">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, decode_register_phone(_el),
+                              State, Name, Username, Remove, Key, City, Nick,
+                              Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"url">>, _attrs, _} = _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick,
+                              decode_register_url(_el), Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"date">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, decode_register_date(_el), Phone,
+                              State, Name, Username, Remove, Key, City, Nick,
+                              Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"misc">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip,
+                              decode_register_misc(_el), Address, Instructions,
+                              Text, Last, First, Password, Registered, Date,
+                              Phone, State, Name, Username, Remove, Key, City,
+                              Nick, Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"text">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, decode_register_text(_el), Last,
+                              First, Password, Registered, Date, Phone, State,
+                              Name, Username, Remove, Key, City, Nick, Url,
+                              Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([{xmlel, <<"key">>, _attrs, _} = _el
+                    | _els],
+                   Zip, Misc, Address, Instructions, Text, Last, First,
+                   Password, Registered, Date, Phone, State, Name,
+                   Username, Remove, Key, City, Nick, Url, Email) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:register">> ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, decode_register_key(_el), City, Nick,
+                              Url, Email);
+       true ->
+          decode_register_els(_els, Zip, Misc, Address,
+                              Instructions, Text, Last, First, Password,
+                              Registered, Date, Phone, State, Name, Username,
+                              Remove, Key, City, Nick, Url, Email)
+    end;
+decode_register_els([_ | _els], Zip, Misc, Address,
+                   Instructions, Text, Last, First, Password, Registered,
+                   Date, Phone, State, Name, Username, Remove, Key, City,
+                   Nick, Url, Email) ->
+    decode_register_els(_els, Zip, Misc, Address,
+                       Instructions, Text, Last, First, Password, Registered,
+                       Date, Phone, State, Name, Username, Remove, Key, City,
+                       Nick, Url, Email).
 
-encode_vcard_KEYWORD(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_KEYWORD_cdata(Cdata, []),
+encode_register({register, Registered, Remove,
+                Instructions, Username, Nick, Password, Name, First,
+                Last, Email, Address, City, State, Zip, Phone, Url,
+                Date, Misc, Text, Key},
+               _xmlns_attrs) ->
+    _els = 'encode_register_$email'(Email,
+                                   'encode_register_$url'(Url,
+                                                          'encode_register_$nick'(Nick,
+                                                                                  'encode_register_$city'(City,
+                                                                                                          'encode_register_$key'(Key,
+                                                                                                                                 'encode_register_$remove'(Remove,
+                                                                                                                                                           'encode_register_$username'(Username,
+                                                                                                                                                                                       'encode_register_$name'(Name,
+                                                                                                                                                                                                               'encode_register_$state'(State,
+                                                                                                                                                                                                                                        'encode_register_$phone'(Phone,
+                                                                                                                                                                                                                                                                 'encode_register_$date'(Date,
+                                                                                                                                                                                                                                                                                         'encode_register_$registered'(Registered,
+                                                                                                                                                                                                                                                                                                                       'encode_register_$password'(Password,
+                                                                                                                                                                                                                                                                                                                                                   'encode_register_$first'(First,
+                                                                                                                                                                                                                                                                                                                                                                            'encode_register_$last'(Last,
+                                                                                                                                                                                                                                                                                                                                                                                                    'encode_register_$text'(Text,
+                                                                                                                                                                                                                                                                                                                                                                                                                            'encode_register_$instructions'(Instructions,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                            'encode_register_$address'(Address,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       'encode_register_$misc'(Misc,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               'encode_register_$zip'(Zip,
+                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      [])))))))))))))))))))),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"KEYWORD">>, _attrs, _els}.
-
-decode_vcard_KEYWORD_cdata(<<>>) -> undefined;
-decode_vcard_KEYWORD_cdata(_val) -> _val.
-
-encode_vcard_KEYWORD_cdata(undefined, _acc) -> _acc;
-encode_vcard_KEYWORD_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+    {xmlel, <<"query">>, _attrs, _els}.
 
-decode_vcard_NOTE({xmlel, <<"NOTE">>, _attrs, _els}) ->
-    Cdata = decode_vcard_NOTE_els(_els, <<>>), Cdata.
+'encode_register_$zip'(undefined, _acc) -> _acc;
+'encode_register_$zip'(Zip, _acc) ->
+    [encode_register_zip(Zip, []) | _acc].
 
-decode_vcard_NOTE_els([], Cdata) ->
-    decode_vcard_NOTE_cdata(Cdata);
-decode_vcard_NOTE_els([{xmlcdata, _data} | _els],
-                     Cdata) ->
-    decode_vcard_NOTE_els(_els,
-                         <<Cdata/binary, _data/binary>>);
-decode_vcard_NOTE_els([_ | _els], Cdata) ->
-    decode_vcard_NOTE_els(_els, Cdata).
+'encode_register_$misc'(undefined, _acc) -> _acc;
+'encode_register_$misc'(Misc, _acc) ->
+    [encode_register_misc(Misc, []) | _acc].
 
-encode_vcard_NOTE(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_NOTE_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"NOTE">>, _attrs, _els}.
+'encode_register_$address'(undefined, _acc) -> _acc;
+'encode_register_$address'(Address, _acc) ->
+    [encode_register_address(Address, []) | _acc].
 
-decode_vcard_NOTE_cdata(<<>>) -> undefined;
-decode_vcard_NOTE_cdata(_val) -> _val.
+'encode_register_$instructions'(undefined, _acc) ->
+    _acc;
+'encode_register_$instructions'(Instructions, _acc) ->
+    [encode_register_instructions(Instructions, []) | _acc].
 
-encode_vcard_NOTE_cdata(undefined, _acc) -> _acc;
-encode_vcard_NOTE_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_register_$text'(undefined, _acc) -> _acc;
+'encode_register_$text'(Text, _acc) ->
+    [encode_register_text(Text, []) | _acc].
 
-decode_vcard_PRODID({xmlel, <<"PRODID">>, _attrs,
-                    _els}) ->
-    Cdata = decode_vcard_PRODID_els(_els, <<>>), Cdata.
+'encode_register_$last'(undefined, _acc) -> _acc;
+'encode_register_$last'(Last, _acc) ->
+    [encode_register_last(Last, []) | _acc].
 
-decode_vcard_PRODID_els([], Cdata) ->
-    decode_vcard_PRODID_cdata(Cdata);
-decode_vcard_PRODID_els([{xmlcdata, _data} | _els],
-                       Cdata) ->
-    decode_vcard_PRODID_els(_els,
-                           <<Cdata/binary, _data/binary>>);
-decode_vcard_PRODID_els([_ | _els], Cdata) ->
-    decode_vcard_PRODID_els(_els, Cdata).
+'encode_register_$first'(undefined, _acc) -> _acc;
+'encode_register_$first'(First, _acc) ->
+    [encode_register_first(First, []) | _acc].
 
-encode_vcard_PRODID(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_PRODID_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"PRODID">>, _attrs, _els}.
+'encode_register_$password'(undefined, _acc) -> _acc;
+'encode_register_$password'(Password, _acc) ->
+    [encode_register_password(Password, []) | _acc].
 
-decode_vcard_PRODID_cdata(<<>>) -> undefined;
-decode_vcard_PRODID_cdata(_val) -> _val.
+'encode_register_$registered'(false, _acc) -> _acc;
+'encode_register_$registered'(Registered, _acc) ->
+    [encode_register_registered(Registered, []) | _acc].
 
-encode_vcard_PRODID_cdata(undefined, _acc) -> _acc;
-encode_vcard_PRODID_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_register_$date'(undefined, _acc) -> _acc;
+'encode_register_$date'(Date, _acc) ->
+    [encode_register_date(Date, []) | _acc].
 
-decode_vcard_REV({xmlel, <<"REV">>, _attrs, _els}) ->
-    Cdata = decode_vcard_REV_els(_els, <<>>), Cdata.
+'encode_register_$phone'(undefined, _acc) -> _acc;
+'encode_register_$phone'(Phone, _acc) ->
+    [encode_register_phone(Phone, []) | _acc].
 
-decode_vcard_REV_els([], Cdata) ->
-    decode_vcard_REV_cdata(Cdata);
-decode_vcard_REV_els([{xmlcdata, _data} | _els],
-                    Cdata) ->
-    decode_vcard_REV_els(_els,
-                        <<Cdata/binary, _data/binary>>);
-decode_vcard_REV_els([_ | _els], Cdata) ->
-    decode_vcard_REV_els(_els, Cdata).
+'encode_register_$state'(undefined, _acc) -> _acc;
+'encode_register_$state'(State, _acc) ->
+    [encode_register_state(State, []) | _acc].
 
-encode_vcard_REV(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_REV_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"REV">>, _attrs, _els}.
+'encode_register_$name'(undefined, _acc) -> _acc;
+'encode_register_$name'(Name, _acc) ->
+    [encode_register_name(Name, []) | _acc].
 
-decode_vcard_REV_cdata(<<>>) -> undefined;
-decode_vcard_REV_cdata(_val) -> _val.
+'encode_register_$username'(undefined, _acc) -> _acc;
+'encode_register_$username'(Username, _acc) ->
+    [encode_register_username(Username, []) | _acc].
 
-encode_vcard_REV_cdata(undefined, _acc) -> _acc;
-encode_vcard_REV_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_register_$remove'(false, _acc) -> _acc;
+'encode_register_$remove'(Remove, _acc) ->
+    [encode_register_remove(Remove, []) | _acc].
 
-decode_vcard_SORT_STRING({xmlel, <<"SORT-STRING">>,
-                         _attrs, _els}) ->
-    Cdata = decode_vcard_SORT_STRING_els(_els, <<>>), Cdata.
+'encode_register_$key'(undefined, _acc) -> _acc;
+'encode_register_$key'(Key, _acc) ->
+    [encode_register_key(Key, []) | _acc].
 
-decode_vcard_SORT_STRING_els([], Cdata) ->
-    decode_vcard_SORT_STRING_cdata(Cdata);
-decode_vcard_SORT_STRING_els([{xmlcdata, _data} | _els],
-                            Cdata) ->
-    decode_vcard_SORT_STRING_els(_els,
-                                <<Cdata/binary, _data/binary>>);
-decode_vcard_SORT_STRING_els([_ | _els], Cdata) ->
-    decode_vcard_SORT_STRING_els(_els, Cdata).
+'encode_register_$city'(undefined, _acc) -> _acc;
+'encode_register_$city'(City, _acc) ->
+    [encode_register_city(City, []) | _acc].
 
-encode_vcard_SORT_STRING(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_SORT_STRING_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"SORT-STRING">>, _attrs, _els}.
+'encode_register_$nick'(undefined, _acc) -> _acc;
+'encode_register_$nick'(Nick, _acc) ->
+    [encode_register_nick(Nick, []) | _acc].
 
-decode_vcard_SORT_STRING_cdata(<<>>) -> undefined;
-decode_vcard_SORT_STRING_cdata(_val) -> _val.
+'encode_register_$url'(undefined, _acc) -> _acc;
+'encode_register_$url'(Url, _acc) ->
+    [encode_register_url(Url, []) | _acc].
 
-encode_vcard_SORT_STRING_cdata(undefined, _acc) -> _acc;
-encode_vcard_SORT_STRING_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+'encode_register_$email'(undefined, _acc) -> _acc;
+'encode_register_$email'(Email, _acc) ->
+    [encode_register_email(Email, []) | _acc].
 
-decode_vcard_UID({xmlel, <<"UID">>, _attrs, _els}) ->
-    Cdata = decode_vcard_UID_els(_els, <<>>), Cdata.
+decode_register_key({xmlel, <<"key">>, _attrs, _els}) ->
+    Cdata = decode_register_key_els(_els, <<>>), Cdata.
 
-decode_vcard_UID_els([], Cdata) ->
-    decode_vcard_UID_cdata(Cdata);
-decode_vcard_UID_els([{xmlcdata, _data} | _els],
-                    Cdata) ->
-    decode_vcard_UID_els(_els,
-                        <<Cdata/binary, _data/binary>>);
-decode_vcard_UID_els([_ | _els], Cdata) ->
-    decode_vcard_UID_els(_els, Cdata).
+decode_register_key_els([], Cdata) ->
+    decode_register_key_cdata(Cdata);
+decode_register_key_els([{xmlcdata, _data} | _els],
+                       Cdata) ->
+    decode_register_key_els(_els,
+                           <<Cdata/binary, _data/binary>>);
+decode_register_key_els([_ | _els], Cdata) ->
+    decode_register_key_els(_els, Cdata).
 
-encode_vcard_UID(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_UID_cdata(Cdata, []),
+encode_register_key(Cdata, _xmlns_attrs) ->
+    _els = encode_register_key_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"UID">>, _attrs, _els}.
+    {xmlel, <<"key">>, _attrs, _els}.
 
-decode_vcard_UID_cdata(<<>>) -> undefined;
-decode_vcard_UID_cdata(_val) -> _val.
+decode_register_key_cdata(<<>>) -> none;
+decode_register_key_cdata(_val) -> _val.
 
-encode_vcard_UID_cdata(undefined, _acc) -> _acc;
-encode_vcard_UID_cdata(_val, _acc) ->
+encode_register_key_cdata(none, _acc) -> _acc;
+encode_register_key_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_URL({xmlel, <<"URL">>, _attrs, _els}) ->
-    Cdata = decode_vcard_URL_els(_els, <<>>), Cdata.
+decode_register_text({xmlel, <<"text">>, _attrs,
+                     _els}) ->
+    Cdata = decode_register_text_els(_els, <<>>), Cdata.
 
-decode_vcard_URL_els([], Cdata) ->
-    decode_vcard_URL_cdata(Cdata);
-decode_vcard_URL_els([{xmlcdata, _data} | _els],
-                    Cdata) ->
-    decode_vcard_URL_els(_els,
-                        <<Cdata/binary, _data/binary>>);
-decode_vcard_URL_els([_ | _els], Cdata) ->
-    decode_vcard_URL_els(_els, Cdata).
+decode_register_text_els([], Cdata) ->
+    decode_register_text_cdata(Cdata);
+decode_register_text_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_register_text_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_register_text_els([_ | _els], Cdata) ->
+    decode_register_text_els(_els, Cdata).
 
-encode_vcard_URL(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_URL_cdata(Cdata, []),
+encode_register_text(Cdata, _xmlns_attrs) ->
+    _els = encode_register_text_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"URL">>, _attrs, _els}.
+    {xmlel, <<"text">>, _attrs, _els}.
 
-decode_vcard_URL_cdata(<<>>) -> undefined;
-decode_vcard_URL_cdata(_val) -> _val.
+decode_register_text_cdata(<<>>) -> none;
+decode_register_text_cdata(_val) -> _val.
 
-encode_vcard_URL_cdata(undefined, _acc) -> _acc;
-encode_vcard_URL_cdata(_val, _acc) ->
+encode_register_text_cdata(none, _acc) -> _acc;
+encode_register_text_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_DESC({xmlel, <<"DESC">>, _attrs, _els}) ->
-    Cdata = decode_vcard_DESC_els(_els, <<>>), Cdata.
-
-decode_vcard_DESC_els([], Cdata) ->
-    decode_vcard_DESC_cdata(Cdata);
-decode_vcard_DESC_els([{xmlcdata, _data} | _els],
-                     Cdata) ->
-    decode_vcard_DESC_els(_els,
-                         <<Cdata/binary, _data/binary>>);
-decode_vcard_DESC_els([_ | _els], Cdata) ->
-    decode_vcard_DESC_els(_els, Cdata).
+decode_register_misc({xmlel, <<"misc">>, _attrs,
+                     _els}) ->
+    Cdata = decode_register_misc_els(_els, <<>>), Cdata.
 
-encode_vcard_DESC(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_DESC_cdata(Cdata, []),
+decode_register_misc_els([], Cdata) ->
+    decode_register_misc_cdata(Cdata);
+decode_register_misc_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_register_misc_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_register_misc_els([_ | _els], Cdata) ->
+    decode_register_misc_els(_els, Cdata).
+
+encode_register_misc(Cdata, _xmlns_attrs) ->
+    _els = encode_register_misc_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"DESC">>, _attrs, _els}.
+    {xmlel, <<"misc">>, _attrs, _els}.
 
-decode_vcard_DESC_cdata(<<>>) -> undefined;
-decode_vcard_DESC_cdata(_val) -> _val.
+decode_register_misc_cdata(<<>>) -> none;
+decode_register_misc_cdata(_val) -> _val.
 
-encode_vcard_DESC_cdata(undefined, _acc) -> _acc;
-encode_vcard_DESC_cdata(_val, _acc) ->
+encode_register_misc_cdata(none, _acc) -> _acc;
+encode_register_misc_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_TYPE({xmlel, <<"TYPE">>, _attrs, _els}) ->
-    Cdata = decode_vcard_TYPE_els(_els, <<>>), Cdata.
+decode_register_date({xmlel, <<"date">>, _attrs,
+                     _els}) ->
+    Cdata = decode_register_date_els(_els, <<>>), Cdata.
 
-decode_vcard_TYPE_els([], Cdata) ->
-    decode_vcard_TYPE_cdata(Cdata);
-decode_vcard_TYPE_els([{xmlcdata, _data} | _els],
-                     Cdata) ->
-    decode_vcard_TYPE_els(_els,
-                         <<Cdata/binary, _data/binary>>);
-decode_vcard_TYPE_els([_ | _els], Cdata) ->
-    decode_vcard_TYPE_els(_els, Cdata).
+decode_register_date_els([], Cdata) ->
+    decode_register_date_cdata(Cdata);
+decode_register_date_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_register_date_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_register_date_els([_ | _els], Cdata) ->
+    decode_register_date_els(_els, Cdata).
 
-encode_vcard_TYPE(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_TYPE_cdata(Cdata, []),
+encode_register_date(Cdata, _xmlns_attrs) ->
+    _els = encode_register_date_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"TYPE">>, _attrs, _els}.
+    {xmlel, <<"date">>, _attrs, _els}.
 
-decode_vcard_TYPE_cdata(<<>>) -> undefined;
-decode_vcard_TYPE_cdata(_val) -> _val.
+decode_register_date_cdata(<<>>) -> none;
+decode_register_date_cdata(_val) -> _val.
 
-encode_vcard_TYPE_cdata(undefined, _acc) -> _acc;
-encode_vcard_TYPE_cdata(_val, _acc) ->
+encode_register_date_cdata(none, _acc) -> _acc;
+encode_register_date_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_EXTVAL({xmlel, <<"EXTVAL">>, _attrs,
-                    _els}) ->
-    Cdata = decode_vcard_EXTVAL_els(_els, <<>>), Cdata.
+decode_register_url({xmlel, <<"url">>, _attrs, _els}) ->
+    Cdata = decode_register_url_els(_els, <<>>), Cdata.
 
-decode_vcard_EXTVAL_els([], Cdata) ->
-    decode_vcard_EXTVAL_cdata(Cdata);
-decode_vcard_EXTVAL_els([{xmlcdata, _data} | _els],
+decode_register_url_els([], Cdata) ->
+    decode_register_url_cdata(Cdata);
+decode_register_url_els([{xmlcdata, _data} | _els],
                        Cdata) ->
-    decode_vcard_EXTVAL_els(_els,
+    decode_register_url_els(_els,
                            <<Cdata/binary, _data/binary>>);
-decode_vcard_EXTVAL_els([_ | _els], Cdata) ->
-    decode_vcard_EXTVAL_els(_els, Cdata).
+decode_register_url_els([_ | _els], Cdata) ->
+    decode_register_url_els(_els, Cdata).
 
-encode_vcard_EXTVAL(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_EXTVAL_cdata(Cdata, []),
+encode_register_url(Cdata, _xmlns_attrs) ->
+    _els = encode_register_url_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"EXTVAL">>, _attrs, _els}.
+    {xmlel, <<"url">>, _attrs, _els}.
 
-decode_vcard_EXTVAL_cdata(<<>>) -> undefined;
-decode_vcard_EXTVAL_cdata(_val) -> _val.
+decode_register_url_cdata(<<>>) -> none;
+decode_register_url_cdata(_val) -> _val.
 
-encode_vcard_EXTVAL_cdata(undefined, _acc) -> _acc;
-encode_vcard_EXTVAL_cdata(_val, _acc) ->
+encode_register_url_cdata(none, _acc) -> _acc;
+encode_register_url_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_vcard_PUBLIC({xmlel, <<"PUBLIC">>, _attrs,
-                    _els}) ->
-    public.
-
-encode_vcard_PUBLIC(public, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"PUBLIC">>, _attrs, _els}.
+decode_register_phone({xmlel, <<"phone">>, _attrs,
+                      _els}) ->
+    Cdata = decode_register_phone_els(_els, <<>>), Cdata.
 
-decode_vcard_PRIVATE({xmlel, <<"PRIVATE">>, _attrs,
-                     _els}) ->
-    private.
+decode_register_phone_els([], Cdata) ->
+    decode_register_phone_cdata(Cdata);
+decode_register_phone_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_register_phone_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_register_phone_els([_ | _els], Cdata) ->
+    decode_register_phone_els(_els, Cdata).
 
-encode_vcard_PRIVATE(private, _xmlns_attrs) ->
-    _els = [],
+encode_register_phone(Cdata, _xmlns_attrs) ->
+    _els = encode_register_phone_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"PRIVATE">>, _attrs, _els}.
+    {xmlel, <<"phone">>, _attrs, _els}.
 
-decode_vcard_CONFIDENTIAL({xmlel, <<"CONFIDENTIAL">>,
-                          _attrs, _els}) ->
-    confidential.
+decode_register_phone_cdata(<<>>) -> none;
+decode_register_phone_cdata(_val) -> _val.
 
-encode_vcard_CONFIDENTIAL(confidential, _xmlns_attrs) ->
-    _els = [],
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"CONFIDENTIAL">>, _attrs, _els}.
+encode_register_phone_cdata(none, _acc) -> _acc;
+encode_register_phone_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_N({xmlel, <<"N">>, _attrs, _els}) ->
-    {Middle, Suffix, Prefix, Family, Given} =
-       decode_vcard_N_els(_els, undefined, undefined,
-                          undefined, undefined, undefined),
-    {vcard_name, Family, Given, Middle, Prefix, Suffix}.
+decode_register_zip({xmlel, <<"zip">>, _attrs, _els}) ->
+    Cdata = decode_register_zip_els(_els, <<>>), Cdata.
 
-decode_vcard_N_els([], Middle, Suffix, Prefix, Family,
-                  Given) ->
-    {Middle, Suffix, Prefix, Family, Given};
-decode_vcard_N_els([{xmlel, <<"FAMILY">>, _attrs, _} =
-                       _el
-                   | _els],
-                  Middle, Suffix, Prefix, Family, Given) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_N_els(_els, Middle, Suffix, Prefix,
-                             decode_vcard_FAMILY(_el), Given);
-       true ->
-          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
-                             Given)
-    end;
-decode_vcard_N_els([{xmlel, <<"GIVEN">>, _attrs, _} =
-                       _el
-                   | _els],
-                  Middle, Suffix, Prefix, Family, Given) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
-                             decode_vcard_GIVEN(_el));
-       true ->
-          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
-                             Given)
-    end;
-decode_vcard_N_els([{xmlel, <<"MIDDLE">>, _attrs, _} =
-                       _el
-                   | _els],
-                  Middle, Suffix, Prefix, Family, Given) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_N_els(_els, decode_vcard_MIDDLE(_el),
-                             Suffix, Prefix, Family, Given);
-       true ->
-          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
-                             Given)
-    end;
-decode_vcard_N_els([{xmlel, <<"PREFIX">>, _attrs, _} =
-                       _el
-                   | _els],
-                  Middle, Suffix, Prefix, Family, Given) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_N_els(_els, Middle, Suffix,
-                             decode_vcard_PREFIX(_el), Family, Given);
-       true ->
-          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
-                             Given)
-    end;
-decode_vcard_N_els([{xmlel, <<"SUFFIX">>, _attrs, _} =
-                       _el
-                   | _els],
-                  Middle, Suffix, Prefix, Family, Given) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_N_els(_els, Middle,
-                             decode_vcard_SUFFIX(_el), Prefix, Family, Given);
-       true ->
-          decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
-                             Given)
-    end;
-decode_vcard_N_els([_ | _els], Middle, Suffix, Prefix,
-                  Family, Given) ->
-    decode_vcard_N_els(_els, Middle, Suffix, Prefix, Family,
-                      Given).
+decode_register_zip_els([], Cdata) ->
+    decode_register_zip_cdata(Cdata);
+decode_register_zip_els([{xmlcdata, _data} | _els],
+                       Cdata) ->
+    decode_register_zip_els(_els,
+                           <<Cdata/binary, _data/binary>>);
+decode_register_zip_els([_ | _els], Cdata) ->
+    decode_register_zip_els(_els, Cdata).
 
-encode_vcard_N({vcard_name, Family, Given, Middle,
-               Prefix, Suffix},
-              _xmlns_attrs) ->
-    _els = 'encode_vcard_N_$given'(Given,
-                                  'encode_vcard_N_$family'(Family,
-                                                           'encode_vcard_N_$prefix'(Prefix,
-                                                                                    'encode_vcard_N_$suffix'(Suffix,
-                                                                                                             'encode_vcard_N_$middle'(Middle,
-                                                                                                                                      []))))),
+encode_register_zip(Cdata, _xmlns_attrs) ->
+    _els = encode_register_zip_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"N">>, _attrs, _els}.
+    {xmlel, <<"zip">>, _attrs, _els}.
 
-'encode_vcard_N_$middle'(undefined, _acc) -> _acc;
-'encode_vcard_N_$middle'(Middle, _acc) ->
-    [encode_vcard_MIDDLE(Middle, []) | _acc].
+decode_register_zip_cdata(<<>>) -> none;
+decode_register_zip_cdata(_val) -> _val.
 
-'encode_vcard_N_$suffix'(undefined, _acc) -> _acc;
-'encode_vcard_N_$suffix'(Suffix, _acc) ->
-    [encode_vcard_SUFFIX(Suffix, []) | _acc].
+encode_register_zip_cdata(none, _acc) -> _acc;
+encode_register_zip_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-'encode_vcard_N_$prefix'(undefined, _acc) -> _acc;
-'encode_vcard_N_$prefix'(Prefix, _acc) ->
-    [encode_vcard_PREFIX(Prefix, []) | _acc].
+decode_register_state({xmlel, <<"state">>, _attrs,
+                      _els}) ->
+    Cdata = decode_register_state_els(_els, <<>>), Cdata.
+
+decode_register_state_els([], Cdata) ->
+    decode_register_state_cdata(Cdata);
+decode_register_state_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_register_state_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_register_state_els([_ | _els], Cdata) ->
+    decode_register_state_els(_els, Cdata).
+
+encode_register_state(Cdata, _xmlns_attrs) ->
+    _els = encode_register_state_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"state">>, _attrs, _els}.
 
-'encode_vcard_N_$family'(undefined, _acc) -> _acc;
-'encode_vcard_N_$family'(Family, _acc) ->
-    [encode_vcard_FAMILY(Family, []) | _acc].
+decode_register_state_cdata(<<>>) -> none;
+decode_register_state_cdata(_val) -> _val.
 
-'encode_vcard_N_$given'(undefined, _acc) -> _acc;
-'encode_vcard_N_$given'(Given, _acc) ->
-    [encode_vcard_GIVEN(Given, []) | _acc].
+encode_register_state_cdata(none, _acc) -> _acc;
+encode_register_state_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_ADR({xmlel, <<"ADR">>, _attrs, _els}) ->
-    {Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-     Locality, Work, Intl, Parcel, Postal, Dom, Region} =
-       decode_vcard_ADR_els(_els, undefined, undefined,
-                            undefined, false, false, undefined, undefined,
-                            undefined, false, false, false, false, false,
-                            undefined),
-    {vcard_adr, Home, Work, Postal, Parcel, Dom, Intl, Pref,
-     Pobox, Extadd, Street, Locality, Region, Pcode, Ctry}.
+decode_register_city({xmlel, <<"city">>, _attrs,
+                     _els}) ->
+    Cdata = decode_register_city_els(_els, <<>>), Cdata.
 
-decode_vcard_ADR_els([], Street, Extadd, Pcode, Home,
-                    Pref, Pobox, Ctry, Locality, Work, Intl, Parcel, Postal,
-                    Dom, Region) ->
-    {Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-     Locality, Work, Intl, Parcel, Postal, Dom, Region};
-decode_vcard_ADR_els([{xmlel, <<"HOME">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode,
-                               decode_vcard_HOME(_el), Pref, Pobox, Ctry,
-                               Locality, Work, Intl, Parcel, Postal, Dom,
-                               Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"WORK">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality,
-                               decode_vcard_WORK(_el), Intl, Parcel, Postal,
-                               Dom, Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"POSTAL">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               decode_vcard_POSTAL(_el), Dom, Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"PARCEL">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl,
-                               decode_vcard_PARCEL(_el), Postal, Dom, Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"DOM">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, decode_vcard_DOM(_el), Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"INTL">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work,
-                               decode_vcard_INTL(_el), Parcel, Postal, Dom,
-                               Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"PREF">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               decode_vcard_PREF(_el), Pobox, Ctry, Locality,
-                               Work, Intl, Parcel, Postal, Dom, Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"POBOX">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, decode_vcard_POBOX(_el), Ctry, Locality,
-                               Work, Intl, Parcel, Postal, Dom, Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"EXTADD">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street,
-                               decode_vcard_EXTADD(_el), Pcode, Home, Pref,
-                               Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"STREET">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, decode_vcard_STREET(_el),
-                               Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                               Locality, Work, Intl, Parcel, Postal, Dom,
-                               Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"LOCALITY">>, _attrs,
-                      _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, decode_vcard_LOCALITY(_el),
-                               Work, Intl, Parcel, Postal, Dom, Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"REGION">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, decode_vcard_REGION(_el));
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"PCODE">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd,
-                               decode_vcard_PCODE(_el), Home, Pref, Pobox,
-                               Ctry, Locality, Work, Intl, Parcel, Postal, Dom,
-                               Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([{xmlel, <<"CTRY">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Street, Extadd, Pcode, Home, Pref, Pobox, Ctry,
-                    Locality, Work, Intl, Parcel, Postal, Dom, Region) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, decode_vcard_CTRY(_el), Locality,
-                               Work, Intl, Parcel, Postal, Dom, Region);
-       true ->
-          decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                               Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                               Postal, Dom, Region)
-    end;
-decode_vcard_ADR_els([_ | _els], Street, Extadd, Pcode,
-                    Home, Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                    Postal, Dom, Region) ->
-    decode_vcard_ADR_els(_els, Street, Extadd, Pcode, Home,
-                        Pref, Pobox, Ctry, Locality, Work, Intl, Parcel,
-                        Postal, Dom, Region).
+decode_register_city_els([], Cdata) ->
+    decode_register_city_cdata(Cdata);
+decode_register_city_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_register_city_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_register_city_els([_ | _els], Cdata) ->
+    decode_register_city_els(_els, Cdata).
 
-encode_vcard_ADR({vcard_adr, Home, Work, Postal, Parcel,
-                 Dom, Intl, Pref, Pobox, Extadd, Street, Locality,
-                 Region, Pcode, Ctry},
-                _xmlns_attrs) ->
-    _els = 'encode_vcard_ADR_$region'(Region,
-                                     'encode_vcard_ADR_$dom'(Dom,
-                                                             'encode_vcard_ADR_$postal'(Postal,
-                                                                                        'encode_vcard_ADR_$parcel'(Parcel,
-                                                                                                                   'encode_vcard_ADR_$intl'(Intl,
-                                                                                                                                            'encode_vcard_ADR_$work'(Work,
-                                                                                                                                                                     'encode_vcard_ADR_$locality'(Locality,
-                                                                                                                                                                                                  'encode_vcard_ADR_$ctry'(Ctry,
-                                                                                                                                                                                                                           'encode_vcard_ADR_$pobox'(Pobox,
-                                                                                                                                                                                                                                                     'encode_vcard_ADR_$pref'(Pref,
-                                                                                                                                                                                                                                                                              'encode_vcard_ADR_$home'(Home,
-                                                                                                                                                                                                                                                                                                       'encode_vcard_ADR_$pcode'(Pcode,
-                                                                                                                                                                                                                                                                                                                                 'encode_vcard_ADR_$extadd'(Extadd,
-                                                                                                                                                                                                                                                                                                                                                            'encode_vcard_ADR_$street'(Street,
-                                                                                                                                                                                                                                                                                                                                                                                       [])))))))))))))),
+encode_register_city(Cdata, _xmlns_attrs) ->
+    _els = encode_register_city_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"ADR">>, _attrs, _els}.
+    {xmlel, <<"city">>, _attrs, _els}.
+
+decode_register_city_cdata(<<>>) -> none;
+decode_register_city_cdata(_val) -> _val.
+
+encode_register_city_cdata(none, _acc) -> _acc;
+encode_register_city_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_register_address({xmlel, <<"address">>, _attrs,
+                        _els}) ->
+    Cdata = decode_register_address_els(_els, <<>>), Cdata.
+
+decode_register_address_els([], Cdata) ->
+    decode_register_address_cdata(Cdata);
+decode_register_address_els([{xmlcdata, _data} | _els],
+                           Cdata) ->
+    decode_register_address_els(_els,
+                               <<Cdata/binary, _data/binary>>);
+decode_register_address_els([_ | _els], Cdata) ->
+    decode_register_address_els(_els, Cdata).
+
+encode_register_address(Cdata, _xmlns_attrs) ->
+    _els = encode_register_address_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"address">>, _attrs, _els}.
+
+decode_register_address_cdata(<<>>) -> none;
+decode_register_address_cdata(_val) -> _val.
+
+encode_register_address_cdata(none, _acc) -> _acc;
+encode_register_address_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_register_email({xmlel, <<"email">>, _attrs,
+                      _els}) ->
+    Cdata = decode_register_email_els(_els, <<>>), Cdata.
+
+decode_register_email_els([], Cdata) ->
+    decode_register_email_cdata(Cdata);
+decode_register_email_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_register_email_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_register_email_els([_ | _els], Cdata) ->
+    decode_register_email_els(_els, Cdata).
+
+encode_register_email(Cdata, _xmlns_attrs) ->
+    _els = encode_register_email_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"email">>, _attrs, _els}.
+
+decode_register_email_cdata(<<>>) -> none;
+decode_register_email_cdata(_val) -> _val.
+
+encode_register_email_cdata(none, _acc) -> _acc;
+encode_register_email_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_register_last({xmlel, <<"last">>, _attrs,
+                     _els}) ->
+    Cdata = decode_register_last_els(_els, <<>>), Cdata.
+
+decode_register_last_els([], Cdata) ->
+    decode_register_last_cdata(Cdata);
+decode_register_last_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_register_last_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_register_last_els([_ | _els], Cdata) ->
+    decode_register_last_els(_els, Cdata).
+
+encode_register_last(Cdata, _xmlns_attrs) ->
+    _els = encode_register_last_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"last">>, _attrs, _els}.
+
+decode_register_last_cdata(<<>>) -> none;
+decode_register_last_cdata(_val) -> _val.
+
+encode_register_last_cdata(none, _acc) -> _acc;
+encode_register_last_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_register_first({xmlel, <<"first">>, _attrs,
+                      _els}) ->
+    Cdata = decode_register_first_els(_els, <<>>), Cdata.
+
+decode_register_first_els([], Cdata) ->
+    decode_register_first_cdata(Cdata);
+decode_register_first_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_register_first_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_register_first_els([_ | _els], Cdata) ->
+    decode_register_first_els(_els, Cdata).
+
+encode_register_first(Cdata, _xmlns_attrs) ->
+    _els = encode_register_first_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"first">>, _attrs, _els}.
+
+decode_register_first_cdata(<<>>) -> none;
+decode_register_first_cdata(_val) -> _val.
+
+encode_register_first_cdata(none, _acc) -> _acc;
+encode_register_first_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_register_name({xmlel, <<"name">>, _attrs,
+                     _els}) ->
+    Cdata = decode_register_name_els(_els, <<>>), Cdata.
+
+decode_register_name_els([], Cdata) ->
+    decode_register_name_cdata(Cdata);
+decode_register_name_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_register_name_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_register_name_els([_ | _els], Cdata) ->
+    decode_register_name_els(_els, Cdata).
+
+encode_register_name(Cdata, _xmlns_attrs) ->
+    _els = encode_register_name_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"name">>, _attrs, _els}.
+
+decode_register_name_cdata(<<>>) -> none;
+decode_register_name_cdata(_val) -> _val.
+
+encode_register_name_cdata(none, _acc) -> _acc;
+encode_register_name_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_register_password({xmlel, <<"password">>, _attrs,
+                         _els}) ->
+    Cdata = decode_register_password_els(_els, <<>>), Cdata.
+
+decode_register_password_els([], Cdata) ->
+    decode_register_password_cdata(Cdata);
+decode_register_password_els([{xmlcdata, _data} | _els],
+                            Cdata) ->
+    decode_register_password_els(_els,
+                                <<Cdata/binary, _data/binary>>);
+decode_register_password_els([_ | _els], Cdata) ->
+    decode_register_password_els(_els, Cdata).
+
+encode_register_password(Cdata, _xmlns_attrs) ->
+    _els = encode_register_password_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"password">>, _attrs, _els}.
+
+decode_register_password_cdata(<<>>) -> none;
+decode_register_password_cdata(_val) -> _val.
+
+encode_register_password_cdata(none, _acc) -> _acc;
+encode_register_password_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_register_nick({xmlel, <<"nick">>, _attrs,
+                     _els}) ->
+    Cdata = decode_register_nick_els(_els, <<>>), Cdata.
+
+decode_register_nick_els([], Cdata) ->
+    decode_register_nick_cdata(Cdata);
+decode_register_nick_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_register_nick_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_register_nick_els([_ | _els], Cdata) ->
+    decode_register_nick_els(_els, Cdata).
+
+encode_register_nick(Cdata, _xmlns_attrs) ->
+    _els = encode_register_nick_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"nick">>, _attrs, _els}.
+
+decode_register_nick_cdata(<<>>) -> none;
+decode_register_nick_cdata(_val) -> _val.
+
+encode_register_nick_cdata(none, _acc) -> _acc;
+encode_register_nick_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_register_username({xmlel, <<"username">>, _attrs,
+                         _els}) ->
+    Cdata = decode_register_username_els(_els, <<>>), Cdata.
+
+decode_register_username_els([], Cdata) ->
+    decode_register_username_cdata(Cdata);
+decode_register_username_els([{xmlcdata, _data} | _els],
+                            Cdata) ->
+    decode_register_username_els(_els,
+                                <<Cdata/binary, _data/binary>>);
+decode_register_username_els([_ | _els], Cdata) ->
+    decode_register_username_els(_els, Cdata).
+
+encode_register_username(Cdata, _xmlns_attrs) ->
+    _els = encode_register_username_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"username">>, _attrs, _els}.
+
+decode_register_username_cdata(<<>>) -> none;
+decode_register_username_cdata(_val) -> _val.
+
+encode_register_username_cdata(none, _acc) -> _acc;
+encode_register_username_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_register_instructions({xmlel, <<"instructions">>,
+                             _attrs, _els}) ->
+    Cdata = decode_register_instructions_els(_els, <<>>),
+    Cdata.
+
+decode_register_instructions_els([], Cdata) ->
+    decode_register_instructions_cdata(Cdata);
+decode_register_instructions_els([{xmlcdata, _data}
+                                 | _els],
+                                Cdata) ->
+    decode_register_instructions_els(_els,
+                                    <<Cdata/binary, _data/binary>>);
+decode_register_instructions_els([_ | _els], Cdata) ->
+    decode_register_instructions_els(_els, Cdata).
+
+encode_register_instructions(Cdata, _xmlns_attrs) ->
+    _els = encode_register_instructions_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"instructions">>, _attrs, _els}.
+
+decode_register_instructions_cdata(<<>>) -> undefined;
+decode_register_instructions_cdata(_val) -> _val.
 
-'encode_vcard_ADR_$street'(undefined, _acc) -> _acc;
-'encode_vcard_ADR_$street'(Street, _acc) ->
-    [encode_vcard_STREET(Street, []) | _acc].
+encode_register_instructions_cdata(undefined, _acc) ->
+    _acc;
+encode_register_instructions_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-'encode_vcard_ADR_$extadd'(undefined, _acc) -> _acc;
-'encode_vcard_ADR_$extadd'(Extadd, _acc) ->
-    [encode_vcard_EXTADD(Extadd, []) | _acc].
+decode_register_remove({xmlel, <<"remove">>, _attrs,
+                       _els}) ->
+    true.
 
-'encode_vcard_ADR_$pcode'(undefined, _acc) -> _acc;
-'encode_vcard_ADR_$pcode'(Pcode, _acc) ->
-    [encode_vcard_PCODE(Pcode, []) | _acc].
+encode_register_remove(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"remove">>, _attrs, _els}.
 
-'encode_vcard_ADR_$home'(false, _acc) -> _acc;
-'encode_vcard_ADR_$home'(Home, _acc) ->
-    [encode_vcard_HOME(Home, []) | _acc].
+decode_register_registered({xmlel, <<"registered">>,
+                           _attrs, _els}) ->
+    true.
 
-'encode_vcard_ADR_$pref'(false, _acc) -> _acc;
-'encode_vcard_ADR_$pref'(Pref, _acc) ->
-    [encode_vcard_PREF(Pref, []) | _acc].
+encode_register_registered(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"registered">>, _attrs, _els}.
 
-'encode_vcard_ADR_$pobox'(undefined, _acc) -> _acc;
-'encode_vcard_ADR_$pobox'(Pobox, _acc) ->
-    [encode_vcard_POBOX(Pobox, []) | _acc].
+decode_feature_register({xmlel, <<"register">>, _attrs,
+                        _els}) ->
+    {feature_register}.
 
-'encode_vcard_ADR_$ctry'(undefined, _acc) -> _acc;
-'encode_vcard_ADR_$ctry'(Ctry, _acc) ->
-    [encode_vcard_CTRY(Ctry, []) | _acc].
+encode_feature_register({feature_register},
+                       _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"register">>, _attrs, _els}.
 
-'encode_vcard_ADR_$locality'(undefined, _acc) -> _acc;
-'encode_vcard_ADR_$locality'(Locality, _acc) ->
-    [encode_vcard_LOCALITY(Locality, []) | _acc].
+decode_caps({xmlel, <<"c">>, _attrs, _els}) ->
+    {Hash, Node, Ver} = decode_caps_attrs(_attrs, undefined,
+                                         undefined, undefined),
+    {caps, Hash, Node, Ver}.
 
-'encode_vcard_ADR_$work'(false, _acc) -> _acc;
-'encode_vcard_ADR_$work'(Work, _acc) ->
-    [encode_vcard_WORK(Work, []) | _acc].
+decode_caps_attrs([{<<"hash">>, _val} | _attrs], _Hash,
+                 Node, Ver) ->
+    decode_caps_attrs(_attrs, _val, Node, Ver);
+decode_caps_attrs([{<<"node">>, _val} | _attrs], Hash,
+                 _Node, Ver) ->
+    decode_caps_attrs(_attrs, Hash, _val, Ver);
+decode_caps_attrs([{<<"ver">>, _val} | _attrs], Hash,
+                 Node, _Ver) ->
+    decode_caps_attrs(_attrs, Hash, Node, _val);
+decode_caps_attrs([_ | _attrs], Hash, Node, Ver) ->
+    decode_caps_attrs(_attrs, Hash, Node, Ver);
+decode_caps_attrs([], Hash, Node, Ver) ->
+    {decode_caps_attr_hash(Hash),
+     decode_caps_attr_node(Node), decode_caps_attr_ver(Ver)}.
 
-'encode_vcard_ADR_$intl'(false, _acc) -> _acc;
-'encode_vcard_ADR_$intl'(Intl, _acc) ->
-    [encode_vcard_INTL(Intl, []) | _acc].
+encode_caps({caps, Hash, Node, Ver}, _xmlns_attrs) ->
+    _els = [],
+    _attrs = encode_caps_attr_ver(Ver,
+                                 encode_caps_attr_node(Node,
+                                                       encode_caps_attr_hash(Hash,
+                                                                             _xmlns_attrs))),
+    {xmlel, <<"c">>, _attrs, _els}.
 
-'encode_vcard_ADR_$parcel'(false, _acc) -> _acc;
-'encode_vcard_ADR_$parcel'(Parcel, _acc) ->
-    [encode_vcard_PARCEL(Parcel, []) | _acc].
+decode_caps_attr_hash(undefined) -> undefined;
+decode_caps_attr_hash(_val) -> _val.
 
-'encode_vcard_ADR_$postal'(false, _acc) -> _acc;
-'encode_vcard_ADR_$postal'(Postal, _acc) ->
-    [encode_vcard_POSTAL(Postal, []) | _acc].
+encode_caps_attr_hash(undefined, _acc) -> _acc;
+encode_caps_attr_hash(_val, _acc) ->
+    [{<<"hash">>, _val} | _acc].
 
-'encode_vcard_ADR_$dom'(false, _acc) -> _acc;
-'encode_vcard_ADR_$dom'(Dom, _acc) ->
-    [encode_vcard_DOM(Dom, []) | _acc].
+decode_caps_attr_node(undefined) -> undefined;
+decode_caps_attr_node(_val) -> _val.
 
-'encode_vcard_ADR_$region'(undefined, _acc) -> _acc;
-'encode_vcard_ADR_$region'(Region, _acc) ->
-    [encode_vcard_REGION(Region, []) | _acc].
+encode_caps_attr_node(undefined, _acc) -> _acc;
+encode_caps_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
-decode_vcard_LABEL({xmlel, <<"LABEL">>, _attrs,
-                   _els}) ->
-    {Line, Home, Pref, Work, Intl, Parcel, Postal, Dom} =
-       decode_vcard_LABEL_els(_els, [], false, false, false,
-                              false, false, false, false),
-    {vcard_label, Home, Work, Postal, Parcel, Dom, Intl,
-     Pref, Line}.
+decode_caps_attr_ver(undefined) -> undefined;
+decode_caps_attr_ver(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"ver">>, <<"c">>,
+                       <<"http://jabber.org/protocol/caps">>});
+      _res -> _res
+    end.
 
-decode_vcard_LABEL_els([], Line, Home, Pref, Work, Intl,
-                      Parcel, Postal, Dom) ->
-    {lists:reverse(Line), Home, Pref, Work, Intl, Parcel,
-     Postal, Dom};
-decode_vcard_LABEL_els([{xmlel, <<"HOME">>, _attrs, _} =
-                           _el
-                       | _els],
-                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_LABEL_els(_els, Line,
-                                 decode_vcard_HOME(_el), Pref, Work, Intl,
-                                 Parcel, Postal, Dom);
-       true ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 Intl, Parcel, Postal, Dom)
-    end;
-decode_vcard_LABEL_els([{xmlel, <<"WORK">>, _attrs, _} =
-                           _el
-                       | _els],
-                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref,
-                                 decode_vcard_WORK(_el), Intl, Parcel, Postal,
-                                 Dom);
-       true ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 Intl, Parcel, Postal, Dom)
-    end;
-decode_vcard_LABEL_els([{xmlel, <<"POSTAL">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 Intl, Parcel, decode_vcard_POSTAL(_el), Dom);
-       true ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 Intl, Parcel, Postal, Dom)
-    end;
-decode_vcard_LABEL_els([{xmlel, <<"PARCEL">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 Intl, decode_vcard_PARCEL(_el), Postal, Dom);
-       true ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 Intl, Parcel, Postal, Dom)
-    end;
-decode_vcard_LABEL_els([{xmlel, <<"DOM">>, _attrs, _} =
-                           _el
-                       | _els],
-                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 Intl, Parcel, Postal, decode_vcard_DOM(_el));
-       true ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 Intl, Parcel, Postal, Dom)
-    end;
-decode_vcard_LABEL_els([{xmlel, <<"INTL">>, _attrs, _} =
-                           _el
-                       | _els],
-                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 decode_vcard_INTL(_el), Parcel, Postal, Dom);
-       true ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 Intl, Parcel, Postal, Dom)
-    end;
-decode_vcard_LABEL_els([{xmlel, <<"PREF">>, _attrs, _} =
-                           _el
-                       | _els],
-                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_LABEL_els(_els, Line, Home,
-                                 decode_vcard_PREF(_el), Work, Intl, Parcel,
-                                 Postal, Dom);
-       true ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 Intl, Parcel, Postal, Dom)
-    end;
-decode_vcard_LABEL_els([{xmlel, <<"LINE">>, _attrs, _} =
-                           _el
-                       | _els],
-                      Line, Home, Pref, Work, Intl, Parcel, Postal, Dom) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_LABEL_els(_els,
-                                 case decode_vcard_LINE(_el) of
-                                   undefined -> Line;
-                                   _new_el -> [_new_el | Line]
-                                 end,
-                                 Home, Pref, Work, Intl, Parcel, Postal, Dom);
-       true ->
-          decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                                 Intl, Parcel, Postal, Dom)
-    end;
-decode_vcard_LABEL_els([_ | _els], Line, Home, Pref,
-                      Work, Intl, Parcel, Postal, Dom) ->
-    decode_vcard_LABEL_els(_els, Line, Home, Pref, Work,
-                          Intl, Parcel, Postal, Dom).
+encode_caps_attr_ver(undefined, _acc) -> _acc;
+encode_caps_attr_ver(_val, _acc) ->
+    [{<<"ver">>, base64:encode(_val)} | _acc].
 
-encode_vcard_LABEL({vcard_label, Home, Work, Postal,
-                   Parcel, Dom, Intl, Pref, Line},
-                  _xmlns_attrs) ->
-    _els = 'encode_vcard_LABEL_$dom'(Dom,
-                                    'encode_vcard_LABEL_$postal'(Postal,
-                                                                 'encode_vcard_LABEL_$parcel'(Parcel,
-                                                                                              'encode_vcard_LABEL_$intl'(Intl,
-                                                                                                                         'encode_vcard_LABEL_$work'(Work,
-                                                                                                                                                    'encode_vcard_LABEL_$pref'(Pref,
-                                                                                                                                                                               'encode_vcard_LABEL_$home'(Home,
-                                                                                                                                                                                                          'encode_vcard_LABEL_$line'(Line,
-                                                                                                                                                                                                                                     [])))))))),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"LABEL">>, _attrs, _els}.
+decode_p1_ack({xmlel, <<"ack">>, _attrs, _els}) ->
+    {p1_ack}.
 
-'encode_vcard_LABEL_$line'([], _acc) -> _acc;
-'encode_vcard_LABEL_$line'([Line | _els], _acc) ->
-    'encode_vcard_LABEL_$line'(_els,
-                              [encode_vcard_LINE(Line, []) | _acc]).
+encode_p1_ack({p1_ack}, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"ack">>, _attrs, _els}.
 
-'encode_vcard_LABEL_$home'(false, _acc) -> _acc;
-'encode_vcard_LABEL_$home'(Home, _acc) ->
-    [encode_vcard_HOME(Home, []) | _acc].
+decode_p1_rebind({xmlel, <<"rebind">>, _attrs, _els}) ->
+    {p1_rebind}.
 
-'encode_vcard_LABEL_$pref'(false, _acc) -> _acc;
-'encode_vcard_LABEL_$pref'(Pref, _acc) ->
-    [encode_vcard_PREF(Pref, []) | _acc].
+encode_p1_rebind({p1_rebind}, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"rebind">>, _attrs, _els}.
 
-'encode_vcard_LABEL_$work'(false, _acc) -> _acc;
-'encode_vcard_LABEL_$work'(Work, _acc) ->
-    [encode_vcard_WORK(Work, []) | _acc].
+decode_p1_push({xmlel, <<"push">>, _attrs, _els}) ->
+    {p1_push}.
 
-'encode_vcard_LABEL_$intl'(false, _acc) -> _acc;
-'encode_vcard_LABEL_$intl'(Intl, _acc) ->
-    [encode_vcard_INTL(Intl, []) | _acc].
+encode_p1_push({p1_push}, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"push">>, _attrs, _els}.
 
-'encode_vcard_LABEL_$parcel'(false, _acc) -> _acc;
-'encode_vcard_LABEL_$parcel'(Parcel, _acc) ->
-    [encode_vcard_PARCEL(Parcel, []) | _acc].
+decode_stream_features({xmlel, <<"stream:features">>,
+                       _attrs, _els}) ->
+    __Els = decode_stream_features_els(_els, []),
+    {stream_features, __Els}.
 
-'encode_vcard_LABEL_$postal'(false, _acc) -> _acc;
-'encode_vcard_LABEL_$postal'(Postal, _acc) ->
-    [encode_vcard_POSTAL(Postal, []) | _acc].
+decode_stream_features_els([], __Els) ->
+    lists:reverse(__Els);
+decode_stream_features_els([{xmlel, _, _, _} = _el
+                           | _els],
+                          __Els) ->
+    decode_stream_features_els(_els, [decode(_el) | __Els]);
+decode_stream_features_els([_ | _els], __Els) ->
+    decode_stream_features_els(_els, __Els).
 
-'encode_vcard_LABEL_$dom'(false, _acc) -> _acc;
-'encode_vcard_LABEL_$dom'(Dom, _acc) ->
-    [encode_vcard_DOM(Dom, []) | _acc].
+encode_stream_features({stream_features, __Els},
+                      _xmlns_attrs) ->
+    _els = [encode(_el) || _el <- __Els],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"stream:features">>, _attrs, _els}.
 
-decode_vcard_TEL({xmlel, <<"TEL">>, _attrs, _els}) ->
-    {Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-     Work, Cell, Modem, Isdn, Video} =
-       decode_vcard_TEL_els(_els, [], false, false, false,
-                            false, false, false, false, false, false, false,
-                            false, false, false),
-    {vcard_tel, Home, Work, Voice, Fax, Pager, Msg, Cell,
-     Video, Bbs, Modem, Isdn, Pcs, Pref, Number}.
+decode_compression({xmlel, <<"compression">>, _attrs,
+                   _els}) ->
+    Methods = decode_compression_els(_els, []),
+    {compression, Methods}.
 
-decode_vcard_TEL_els([], [Number], Pager, Pcs, Bbs,
-                    Voice, Home, Pref, Msg, Fax, Work, Cell, Modem, Isdn,
-                    Video) ->
-    {Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-     Work, Cell, Modem, Isdn, Video};
-decode_vcard_TEL_els([{xmlel, <<"HOME">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, decode_vcard_HOME(_el), Pref, Msg, Fax,
-                               Work, Cell, Modem, Isdn, Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
-    end;
-decode_vcard_TEL_els([{xmlel, <<"WORK">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax,
-                               decode_vcard_WORK(_el), Cell, Modem, Isdn,
-                               Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
-    end;
-decode_vcard_TEL_els([{xmlel, <<"VOICE">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               decode_vcard_VOICE(_el), Home, Pref, Msg, Fax,
-                               Work, Cell, Modem, Isdn, Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
-    end;
-decode_vcard_TEL_els([{xmlel, <<"FAX">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, decode_vcard_FAX(_el),
-                               Work, Cell, Modem, Isdn, Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
-    end;
-decode_vcard_TEL_els([{xmlel, <<"PAGER">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number,
-                               decode_vcard_PAGER(_el), Pcs, Bbs, Voice, Home,
-                               Pref, Msg, Fax, Work, Cell, Modem, Isdn, Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
-    end;
-decode_vcard_TEL_els([{xmlel, <<"MSG">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, decode_vcard_MSG(_el), Fax,
-                               Work, Cell, Modem, Isdn, Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
-    end;
-decode_vcard_TEL_els([{xmlel, <<"CELL">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work,
-                               decode_vcard_CELL(_el), Modem, Isdn, Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
-    end;
-decode_vcard_TEL_els([{xmlel, <<"VIDEO">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, decode_vcard_VIDEO(_el));
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
-    end;
-decode_vcard_TEL_els([{xmlel, <<"BBS">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs,
-                               decode_vcard_BBS(_el), Voice, Home, Pref, Msg,
-                               Fax, Work, Cell, Modem, Isdn, Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
-    end;
-decode_vcard_TEL_els([{xmlel, <<"MODEM">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
+decode_compression_els([], Methods) ->
+    lists:reverse(Methods);
+decode_compression_els([{xmlel, <<"method">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Methods) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell,
-                               decode_vcard_MODEM(_el), Isdn, Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/features/compress">> ->
+          decode_compression_els(_els,
+                                 case decode_compression_method(_el) of
+                                   undefined -> Methods;
+                                   _new_el -> [_new_el | Methods]
+                                 end);
+       true -> decode_compression_els(_els, Methods)
     end;
-decode_vcard_TEL_els([{xmlel, <<"ISDN">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
+decode_compression_els([_ | _els], Methods) ->
+    decode_compression_els(_els, Methods).
+
+encode_compression({compression, Methods},
+                  _xmlns_attrs) ->
+    _els = 'encode_compression_$methods'(Methods, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"compression">>, _attrs, _els}.
+
+'encode_compression_$methods'([], _acc) -> _acc;
+'encode_compression_$methods'([Methods | _els], _acc) ->
+    'encode_compression_$methods'(_els,
+                                 [encode_compression_method(Methods, [])
+                                  | _acc]).
+
+decode_compression_method({xmlel, <<"method">>, _attrs,
+                          _els}) ->
+    Cdata = decode_compression_method_els(_els, <<>>),
+    Cdata.
+
+decode_compression_method_els([], Cdata) ->
+    decode_compression_method_cdata(Cdata);
+decode_compression_method_els([{xmlcdata, _data}
+                              | _els],
+                             Cdata) ->
+    decode_compression_method_els(_els,
+                                 <<Cdata/binary, _data/binary>>);
+decode_compression_method_els([_ | _els], Cdata) ->
+    decode_compression_method_els(_els, Cdata).
+
+encode_compression_method(Cdata, _xmlns_attrs) ->
+    _els = encode_compression_method_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"method">>, _attrs, _els}.
+
+decode_compression_method_cdata(<<>>) -> undefined;
+decode_compression_method_cdata(_val) -> _val.
+
+encode_compression_method_cdata(undefined, _acc) ->
+    _acc;
+encode_compression_method_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_compressed({xmlel, <<"compressed">>, _attrs,
+                  _els}) ->
+    {compressed}.
+
+encode_compressed({compressed}, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"compressed">>, _attrs, _els}.
+
+decode_compress({xmlel, <<"compress">>, _attrs,
+                _els}) ->
+    Methods = decode_compress_els(_els, []),
+    {compress, Methods}.
+
+decode_compress_els([], Methods) ->
+    lists:reverse(Methods);
+decode_compress_els([{xmlel, <<"method">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Methods) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               decode_vcard_ISDN(_el), Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/compress">> ->
+          decode_compress_els(_els,
+                              case decode_compress_method(_el) of
+                                undefined -> Methods;
+                                _new_el -> [_new_el | Methods]
+                              end);
+       true -> decode_compress_els(_els, Methods)
     end;
-decode_vcard_TEL_els([{xmlel, <<"PCS">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
+decode_compress_els([_ | _els], Methods) ->
+    decode_compress_els(_els, Methods).
+
+encode_compress({compress, Methods}, _xmlns_attrs) ->
+    _els = 'encode_compress_$methods'(Methods, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"compress">>, _attrs, _els}.
+
+'encode_compress_$methods'([], _acc) -> _acc;
+'encode_compress_$methods'([Methods | _els], _acc) ->
+    'encode_compress_$methods'(_els,
+                              [encode_compress_method(Methods, []) | _acc]).
+
+decode_compress_method({xmlel, <<"method">>, _attrs,
+                       _els}) ->
+    Cdata = decode_compress_method_els(_els, <<>>), Cdata.
+
+decode_compress_method_els([], Cdata) ->
+    decode_compress_method_cdata(Cdata);
+decode_compress_method_els([{xmlcdata, _data} | _els],
+                          Cdata) ->
+    decode_compress_method_els(_els,
+                              <<Cdata/binary, _data/binary>>);
+decode_compress_method_els([_ | _els], Cdata) ->
+    decode_compress_method_els(_els, Cdata).
+
+encode_compress_method(Cdata, _xmlns_attrs) ->
+    _els = encode_compress_method_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"method">>, _attrs, _els}.
+
+decode_compress_method_cdata(<<>>) -> undefined;
+decode_compress_method_cdata(_val) -> _val.
+
+encode_compress_method_cdata(undefined, _acc) -> _acc;
+encode_compress_method_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
+
+decode_compress_failure({xmlel, <<"failure">>, _attrs,
+                        _els}) ->
+    Reason = decode_compress_failure_els(_els, undefined),
+    {compress_failure, Reason}.
+
+decode_compress_failure_els([], Reason) -> Reason;
+decode_compress_failure_els([{xmlel, <<"setup-failed">>,
+                             _attrs, _} =
+                                _el
+                            | _els],
+                           Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager,
-                               decode_vcard_PCS(_el), Bbs, Voice, Home, Pref,
-                               Msg, Fax, Work, Cell, Modem, Isdn, Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/compress">> ->
+          decode_compress_failure_els(_els,
+                                      decode_compress_failure_setup_failed(_el));
+       true -> decode_compress_failure_els(_els, Reason)
     end;
-decode_vcard_TEL_els([{xmlel, <<"PREF">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
+decode_compress_failure_els([{xmlel,
+                             <<"processing-failed">>, _attrs, _} =
+                                _el
+                            | _els],
+                           Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, decode_vcard_PREF(_el), Msg, Fax,
-                               Work, Cell, Modem, Isdn, Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/compress">> ->
+          decode_compress_failure_els(_els,
+                                      decode_compress_failure_processing_failed(_el));
+       true -> decode_compress_failure_els(_els, Reason)
     end;
-decode_vcard_TEL_els([{xmlel, <<"NUMBER">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Number, Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                    Work, Cell, Modem, Isdn, Video) ->
+decode_compress_failure_els([{xmlel,
+                             <<"unsupported-method">>, _attrs, _} =
+                                _el
+                            | _els],
+                           Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_TEL_els(_els,
-                               case decode_vcard_NUMBER(_el) of
-                                 undefined -> Number;
-                                 _new_el -> [_new_el | Number]
-                               end,
-                               Pager, Pcs, Bbs, Voice, Home, Pref, Msg, Fax,
-                               Work, Cell, Modem, Isdn, Video);
-       true ->
-          decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                               Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                               Isdn, Video)
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/compress">> ->
+          decode_compress_failure_els(_els,
+                                      decode_compress_failure_unsupported_method(_el));
+       true -> decode_compress_failure_els(_els, Reason)
     end;
-decode_vcard_TEL_els([_ | _els], Number, Pager, Pcs,
-                    Bbs, Voice, Home, Pref, Msg, Fax, Work, Cell, Modem,
-                    Isdn, Video) ->
-    decode_vcard_TEL_els(_els, Number, Pager, Pcs, Bbs,
-                        Voice, Home, Pref, Msg, Fax, Work, Cell, Modem, Isdn,
-                        Video).
+decode_compress_failure_els([_ | _els], Reason) ->
+    decode_compress_failure_els(_els, Reason).
+
+encode_compress_failure({compress_failure, Reason},
+                       _xmlns_attrs) ->
+    _els = 'encode_compress_failure_$reason'(Reason, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"failure">>, _attrs, _els}.
+
+'encode_compress_failure_$reason'(undefined, _acc) ->
+    _acc;
+'encode_compress_failure_$reason'('setup-failed' =
+                                     Reason,
+                                 _acc) ->
+    [encode_compress_failure_setup_failed(Reason, [])
+     | _acc];
+'encode_compress_failure_$reason'('processing-failed' =
+                                     Reason,
+                                 _acc) ->
+    [encode_compress_failure_processing_failed(Reason, [])
+     | _acc];
+'encode_compress_failure_$reason'('unsupported-method' =
+                                     Reason,
+                                 _acc) ->
+    [encode_compress_failure_unsupported_method(Reason, [])
+     | _acc].
+
+decode_compress_failure_unsupported_method({xmlel,
+                                           <<"unsupported-method">>, _attrs,
+                                           _els}) ->
+    'unsupported-method'.
+
+encode_compress_failure_unsupported_method('unsupported-method',
+                                          _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"unsupported-method">>, _attrs, _els}.
+
+decode_compress_failure_processing_failed({xmlel,
+                                          <<"processing-failed">>, _attrs,
+                                          _els}) ->
+    'processing-failed'.
+
+encode_compress_failure_processing_failed('processing-failed',
+                                         _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"processing-failed">>, _attrs, _els}.
+
+decode_compress_failure_setup_failed({xmlel,
+                                     <<"setup-failed">>, _attrs, _els}) ->
+    'setup-failed'.
+
+encode_compress_failure_setup_failed('setup-failed',
+                                    _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"setup-failed">>, _attrs, _els}.
+
+decode_starttls_failure({xmlel, <<"failure">>, _attrs,
+                        _els}) ->
+    {starttls_failure}.
+
+encode_starttls_failure({starttls_failure},
+                       _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"failure">>, _attrs, _els}.
+
+decode_starttls_proceed({xmlel, <<"proceed">>, _attrs,
+                        _els}) ->
+    {starttls_proceed}.
 
-encode_vcard_TEL({vcard_tel, Home, Work, Voice, Fax,
-                 Pager, Msg, Cell, Video, Bbs, Modem, Isdn, Pcs, Pref,
-                 Number},
-                _xmlns_attrs) ->
-    _els = 'encode_vcard_TEL_$video'(Video,
-                                    'encode_vcard_TEL_$isdn'(Isdn,
-                                                             'encode_vcard_TEL_$modem'(Modem,
-                                                                                       'encode_vcard_TEL_$cell'(Cell,
-                                                                                                                'encode_vcard_TEL_$work'(Work,
-                                                                                                                                         'encode_vcard_TEL_$fax'(Fax,
-                                                                                                                                                                 'encode_vcard_TEL_$msg'(Msg,
-                                                                                                                                                                                         'encode_vcard_TEL_$pref'(Pref,
-                                                                                                                                                                                                                  'encode_vcard_TEL_$home'(Home,
-                                                                                                                                                                                                                                           'encode_vcard_TEL_$voice'(Voice,
-                                                                                                                                                                                                                                                                     'encode_vcard_TEL_$bbs'(Bbs,
-                                                                                                                                                                                                                                                                                             'encode_vcard_TEL_$pcs'(Pcs,
-                                                                                                                                                                                                                                                                                                                     'encode_vcard_TEL_$pager'(Pager,
-                                                                                                                                                                                                                                                                                                                                               'encode_vcard_TEL_$number'(Number,
-                                                                                                                                                                                                                                                                                                                                                                          [])))))))))))))),
+encode_starttls_proceed({starttls_proceed},
+                       _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"TEL">>, _attrs, _els}.
+    {xmlel, <<"proceed">>, _attrs, _els}.
 
-'encode_vcard_TEL_$number'(Number, _acc) ->
-    [encode_vcard_NUMBER(Number, []) | _acc].
+decode_starttls({xmlel, <<"starttls">>, _attrs,
+                _els}) ->
+    Required = decode_starttls_els(_els, false),
+    {starttls, Required}.
 
-'encode_vcard_TEL_$pager'(false, _acc) -> _acc;
-'encode_vcard_TEL_$pager'(Pager, _acc) ->
-    [encode_vcard_PAGER(Pager, []) | _acc].
+decode_starttls_els([], Required) -> Required;
+decode_starttls_els([{xmlel, <<"required">>, _attrs,
+                     _} =
+                        _el
+                    | _els],
+                   Required) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-tls">> ->
+          decode_starttls_els(_els,
+                              decode_starttls_required(_el));
+       true -> decode_starttls_els(_els, Required)
+    end;
+decode_starttls_els([_ | _els], Required) ->
+    decode_starttls_els(_els, Required).
 
-'encode_vcard_TEL_$pcs'(false, _acc) -> _acc;
-'encode_vcard_TEL_$pcs'(Pcs, _acc) ->
-    [encode_vcard_PCS(Pcs, []) | _acc].
+encode_starttls({starttls, Required}, _xmlns_attrs) ->
+    _els = 'encode_starttls_$required'(Required, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"starttls">>, _attrs, _els}.
 
-'encode_vcard_TEL_$bbs'(false, _acc) -> _acc;
-'encode_vcard_TEL_$bbs'(Bbs, _acc) ->
-    [encode_vcard_BBS(Bbs, []) | _acc].
+'encode_starttls_$required'(false, _acc) -> _acc;
+'encode_starttls_$required'(Required, _acc) ->
+    [encode_starttls_required(Required, []) | _acc].
 
-'encode_vcard_TEL_$voice'(false, _acc) -> _acc;
-'encode_vcard_TEL_$voice'(Voice, _acc) ->
-    [encode_vcard_VOICE(Voice, []) | _acc].
+decode_starttls_required({xmlel, <<"required">>, _attrs,
+                         _els}) ->
+    true.
 
-'encode_vcard_TEL_$home'(false, _acc) -> _acc;
-'encode_vcard_TEL_$home'(Home, _acc) ->
-    [encode_vcard_HOME(Home, []) | _acc].
+encode_starttls_required(true, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"required">>, _attrs, _els}.
 
-'encode_vcard_TEL_$pref'(false, _acc) -> _acc;
-'encode_vcard_TEL_$pref'(Pref, _acc) ->
-    [encode_vcard_PREF(Pref, []) | _acc].
+decode_sasl_mechanisms({xmlel, <<"mechanisms">>, _attrs,
+                       _els}) ->
+    List = decode_sasl_mechanisms_els(_els, []),
+    {sasl_mechanisms, List}.
 
-'encode_vcard_TEL_$msg'(false, _acc) -> _acc;
-'encode_vcard_TEL_$msg'(Msg, _acc) ->
-    [encode_vcard_MSG(Msg, []) | _acc].
+decode_sasl_mechanisms_els([], List) ->
+    lists:reverse(List);
+decode_sasl_mechanisms_els([{xmlel, <<"mechanism">>,
+                            _attrs, _} =
+                               _el
+                           | _els],
+                          List) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_mechanisms_els(_els,
+                                     case decode_sasl_mechanism(_el) of
+                                       undefined -> List;
+                                       _new_el -> [_new_el | List]
+                                     end);
+       true -> decode_sasl_mechanisms_els(_els, List)
+    end;
+decode_sasl_mechanisms_els([_ | _els], List) ->
+    decode_sasl_mechanisms_els(_els, List).
 
-'encode_vcard_TEL_$fax'(false, _acc) -> _acc;
-'encode_vcard_TEL_$fax'(Fax, _acc) ->
-    [encode_vcard_FAX(Fax, []) | _acc].
+encode_sasl_mechanisms({sasl_mechanisms, List},
+                      _xmlns_attrs) ->
+    _els = 'encode_sasl_mechanisms_$list'(List, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"mechanisms">>, _attrs, _els}.
 
-'encode_vcard_TEL_$work'(false, _acc) -> _acc;
-'encode_vcard_TEL_$work'(Work, _acc) ->
-    [encode_vcard_WORK(Work, []) | _acc].
+'encode_sasl_mechanisms_$list'([], _acc) -> _acc;
+'encode_sasl_mechanisms_$list'([List | _els], _acc) ->
+    'encode_sasl_mechanisms_$list'(_els,
+                                  [encode_sasl_mechanism(List, []) | _acc]).
 
-'encode_vcard_TEL_$cell'(false, _acc) -> _acc;
-'encode_vcard_TEL_$cell'(Cell, _acc) ->
-    [encode_vcard_CELL(Cell, []) | _acc].
+decode_sasl_mechanism({xmlel, <<"mechanism">>, _attrs,
+                      _els}) ->
+    Cdata = decode_sasl_mechanism_els(_els, <<>>), Cdata.
 
-'encode_vcard_TEL_$modem'(false, _acc) -> _acc;
-'encode_vcard_TEL_$modem'(Modem, _acc) ->
-    [encode_vcard_MODEM(Modem, []) | _acc].
+decode_sasl_mechanism_els([], Cdata) ->
+    decode_sasl_mechanism_cdata(Cdata);
+decode_sasl_mechanism_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_sasl_mechanism_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_sasl_mechanism_els([_ | _els], Cdata) ->
+    decode_sasl_mechanism_els(_els, Cdata).
 
-'encode_vcard_TEL_$isdn'(false, _acc) -> _acc;
-'encode_vcard_TEL_$isdn'(Isdn, _acc) ->
-    [encode_vcard_ISDN(Isdn, []) | _acc].
+encode_sasl_mechanism(Cdata, _xmlns_attrs) ->
+    _els = encode_sasl_mechanism_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"mechanism">>, _attrs, _els}.
 
-'encode_vcard_TEL_$video'(false, _acc) -> _acc;
-'encode_vcard_TEL_$video'(Video, _acc) ->
-    [encode_vcard_VIDEO(Video, []) | _acc].
+decode_sasl_mechanism_cdata(<<>>) -> undefined;
+decode_sasl_mechanism_cdata(_val) -> _val.
 
-decode_vcard_EMAIL({xmlel, <<"EMAIL">>, _attrs,
-                   _els}) ->
-    {X400, Userid, Internet, Home, Pref, Work} =
-       decode_vcard_EMAIL_els(_els, false, [], false, false,
-                              false, false),
-    {vcard_email, Home, Work, Internet, Pref, X400, Userid}.
+encode_sasl_mechanism_cdata(undefined, _acc) -> _acc;
+encode_sasl_mechanism_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_EMAIL_els([], X400, [Userid], Internet,
-                      Home, Pref, Work) ->
-    {X400, Userid, Internet, Home, Pref, Work};
-decode_vcard_EMAIL_els([{xmlel, <<"HOME">>, _attrs, _} =
-                           _el
-                       | _els],
-                      X400, Userid, Internet, Home, Pref, Work) ->
+decode_sasl_failure({xmlel, <<"failure">>, _attrs,
+                    _els}) ->
+    {Text, Reason} = decode_sasl_failure_els(_els, [],
+                                            undefined),
+    {sasl_failure, Reason, Text}.
+
+decode_sasl_failure_els([], Text, Reason) ->
+    {lists:reverse(Text), Reason};
+decode_sasl_failure_els([{xmlel, <<"text">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
-                                 decode_vcard_HOME(_el), Pref, Work);
-       true ->
-          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
-                                 Home, Pref, Work)
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els,
+                                  case decode_sasl_failure_text(_el) of
+                                    undefined -> Text;
+                                    _new_el -> [_new_el | Text]
+                                  end,
+                                  Reason);
+       true -> decode_sasl_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_els([{xmlel, <<"aborted">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els, Text,
+                                  decode_sasl_failure_aborted(_el));
+       true -> decode_sasl_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_els([{xmlel, <<"account-disabled">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els, Text,
+                                  decode_sasl_failure_account_disabled(_el));
+       true -> decode_sasl_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_els([{xmlel,
+                         <<"credentials-expired">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els, Text,
+                                  decode_sasl_failure_credentials_expired(_el));
+       true -> decode_sasl_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_els([{xmlel,
+                         <<"encryption-required">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els, Text,
+                                  decode_sasl_failure_encryption_required(_el));
+       true -> decode_sasl_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_els([{xmlel,
+                         <<"incorrect-encoding">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els, Text,
+                                  decode_sasl_failure_incorrect_encoding(_el));
+       true -> decode_sasl_failure_els(_els, Text, Reason)
+    end;
+decode_sasl_failure_els([{xmlel, <<"invalid-authzid">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els, Text,
+                                  decode_sasl_failure_invalid_authzid(_el));
+       true -> decode_sasl_failure_els(_els, Text, Reason)
     end;
-decode_vcard_EMAIL_els([{xmlel, <<"WORK">>, _attrs, _} =
-                           _el
-                       | _els],
-                      X400, Userid, Internet, Home, Pref, Work) ->
+decode_sasl_failure_els([{xmlel,
+                         <<"invalid-mechanism">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
-                                 Home, Pref, decode_vcard_WORK(_el));
-       true ->
-          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
-                                 Home, Pref, Work)
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els, Text,
+                                  decode_sasl_failure_invalid_mechanism(_el));
+       true -> decode_sasl_failure_els(_els, Text, Reason)
     end;
-decode_vcard_EMAIL_els([{xmlel, <<"INTERNET">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      X400, Userid, Internet, Home, Pref, Work) ->
+decode_sasl_failure_els([{xmlel,
+                         <<"malformed-request">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_EMAIL_els(_els, X400, Userid,
-                                 decode_vcard_INTERNET(_el), Home, Pref, Work);
-       true ->
-          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
-                                 Home, Pref, Work)
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els, Text,
+                                  decode_sasl_failure_malformed_request(_el));
+       true -> decode_sasl_failure_els(_els, Text, Reason)
     end;
-decode_vcard_EMAIL_els([{xmlel, <<"PREF">>, _attrs, _} =
-                           _el
-                       | _els],
-                      X400, Userid, Internet, Home, Pref, Work) ->
+decode_sasl_failure_els([{xmlel,
+                         <<"mechanism-too-weak">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
-                                 Home, decode_vcard_PREF(_el), Work);
-       true ->
-          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
-                                 Home, Pref, Work)
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els, Text,
+                                  decode_sasl_failure_mechanism_too_weak(_el));
+       true -> decode_sasl_failure_els(_els, Text, Reason)
     end;
-decode_vcard_EMAIL_els([{xmlel, <<"X400">>, _attrs, _} =
-                           _el
-                       | _els],
-                      X400, Userid, Internet, Home, Pref, Work) ->
+decode_sasl_failure_els([{xmlel, <<"not-authorized">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_EMAIL_els(_els, decode_vcard_X400(_el),
-                                 Userid, Internet, Home, Pref, Work);
-       true ->
-          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
-                                 Home, Pref, Work)
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els, Text,
+                                  decode_sasl_failure_not_authorized(_el));
+       true -> decode_sasl_failure_els(_els, Text, Reason)
     end;
-decode_vcard_EMAIL_els([{xmlel, <<"USERID">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      X400, Userid, Internet, Home, Pref, Work) ->
+decode_sasl_failure_els([{xmlel,
+                         <<"temporary-auth-failure">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_EMAIL_els(_els, X400,
-                                 case decode_vcard_USERID(_el) of
-                                   undefined -> Userid;
-                                   _new_el -> [_new_el | Userid]
-                                 end,
-                                 Internet, Home, Pref, Work);
-       true ->
-          decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
-                                 Home, Pref, Work)
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-sasl">> ->
+          decode_sasl_failure_els(_els, Text,
+                                  decode_sasl_failure_temporary_auth_failure(_el));
+       true -> decode_sasl_failure_els(_els, Text, Reason)
     end;
-decode_vcard_EMAIL_els([_ | _els], X400, Userid,
-                      Internet, Home, Pref, Work) ->
-    decode_vcard_EMAIL_els(_els, X400, Userid, Internet,
-                          Home, Pref, Work).
+decode_sasl_failure_els([_ | _els], Text, Reason) ->
+    decode_sasl_failure_els(_els, Text, Reason).
 
-encode_vcard_EMAIL({vcard_email, Home, Work, Internet,
-                   Pref, X400, Userid},
-                  _xmlns_attrs) ->
-    _els = 'encode_vcard_EMAIL_$work'(Work,
-                                     'encode_vcard_EMAIL_$pref'(Pref,
-                                                                'encode_vcard_EMAIL_$home'(Home,
-                                                                                           'encode_vcard_EMAIL_$internet'(Internet,
-                                                                                                                          'encode_vcard_EMAIL_$userid'(Userid,
-                                                                                                                                                       'encode_vcard_EMAIL_$x400'(X400,
-                                                                                                                                                                                  [])))))),
+encode_sasl_failure({sasl_failure, Reason, Text},
+                   _xmlns_attrs) ->
+    _els = 'encode_sasl_failure_$reason'(Reason,
+                                        'encode_sasl_failure_$text'(Text, [])),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"EMAIL">>, _attrs, _els}.
-
-'encode_vcard_EMAIL_$x400'(false, _acc) -> _acc;
-'encode_vcard_EMAIL_$x400'(X400, _acc) ->
-    [encode_vcard_X400(X400, []) | _acc].
-
-'encode_vcard_EMAIL_$userid'(Userid, _acc) ->
-    [encode_vcard_USERID(Userid, []) | _acc].
-
-'encode_vcard_EMAIL_$internet'(false, _acc) -> _acc;
-'encode_vcard_EMAIL_$internet'(Internet, _acc) ->
-    [encode_vcard_INTERNET(Internet, []) | _acc].
+    {xmlel, <<"failure">>, _attrs, _els}.
 
-'encode_vcard_EMAIL_$home'(false, _acc) -> _acc;
-'encode_vcard_EMAIL_$home'(Home, _acc) ->
-    [encode_vcard_HOME(Home, []) | _acc].
+'encode_sasl_failure_$text'([], _acc) -> _acc;
+'encode_sasl_failure_$text'([Text | _els], _acc) ->
+    'encode_sasl_failure_$text'(_els,
+                               [encode_sasl_failure_text(Text, []) | _acc]).
 
-'encode_vcard_EMAIL_$pref'(false, _acc) -> _acc;
-'encode_vcard_EMAIL_$pref'(Pref, _acc) ->
-    [encode_vcard_PREF(Pref, []) | _acc].
+'encode_sasl_failure_$reason'(undefined, _acc) -> _acc;
+'encode_sasl_failure_$reason'(aborted = Reason, _acc) ->
+    [encode_sasl_failure_aborted(Reason, []) | _acc];
+'encode_sasl_failure_$reason'('account-disabled' =
+                                 Reason,
+                             _acc) ->
+    [encode_sasl_failure_account_disabled(Reason, [])
+     | _acc];
+'encode_sasl_failure_$reason'('credentials-expired' =
+                                 Reason,
+                             _acc) ->
+    [encode_sasl_failure_credentials_expired(Reason, [])
+     | _acc];
+'encode_sasl_failure_$reason'('encryption-required' =
+                                 Reason,
+                             _acc) ->
+    [encode_sasl_failure_encryption_required(Reason, [])
+     | _acc];
+'encode_sasl_failure_$reason'('incorrect-encoding' =
+                                 Reason,
+                             _acc) ->
+    [encode_sasl_failure_incorrect_encoding(Reason, [])
+     | _acc];
+'encode_sasl_failure_$reason'('invalid-authzid' =
+                                 Reason,
+                             _acc) ->
+    [encode_sasl_failure_invalid_authzid(Reason, [])
+     | _acc];
+'encode_sasl_failure_$reason'('invalid-mechanism' =
+                                 Reason,
+                             _acc) ->
+    [encode_sasl_failure_invalid_mechanism(Reason, [])
+     | _acc];
+'encode_sasl_failure_$reason'('malformed-request' =
+                                 Reason,
+                             _acc) ->
+    [encode_sasl_failure_malformed_request(Reason, [])
+     | _acc];
+'encode_sasl_failure_$reason'('mechanism-too-weak' =
+                                 Reason,
+                             _acc) ->
+    [encode_sasl_failure_mechanism_too_weak(Reason, [])
+     | _acc];
+'encode_sasl_failure_$reason'('not-authorized' = Reason,
+                             _acc) ->
+    [encode_sasl_failure_not_authorized(Reason, []) | _acc];
+'encode_sasl_failure_$reason'('temporary-auth-failure' =
+                                 Reason,
+                             _acc) ->
+    [encode_sasl_failure_temporary_auth_failure(Reason, [])
+     | _acc].
 
-'encode_vcard_EMAIL_$work'(false, _acc) -> _acc;
-'encode_vcard_EMAIL_$work'(Work, _acc) ->
-    [encode_vcard_WORK(Work, []) | _acc].
+decode_sasl_failure_temporary_auth_failure({xmlel,
+                                           <<"temporary-auth-failure">>,
+                                           _attrs, _els}) ->
+    'temporary-auth-failure'.
 
-decode_vcard_GEO({xmlel, <<"GEO">>, _attrs, _els}) ->
-    {Lat, Lon} = decode_vcard_GEO_els(_els, [], []),
-    {vcard_geo, Lat, Lon}.
+encode_sasl_failure_temporary_auth_failure('temporary-auth-failure',
+                                          _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"temporary-auth-failure">>, _attrs, _els}.
 
-decode_vcard_GEO_els([], [Lat], [Lon]) -> {Lat, Lon};
-decode_vcard_GEO_els([{xmlel, <<"LAT">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Lat, Lon) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_GEO_els(_els,
-                               case decode_vcard_LAT(_el) of
-                                 undefined -> Lat;
-                                 _new_el -> [_new_el | Lat]
-                               end,
-                               Lon);
-       true -> decode_vcard_GEO_els(_els, Lat, Lon)
-    end;
-decode_vcard_GEO_els([{xmlel, <<"LON">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Lat, Lon) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_GEO_els(_els, Lat,
-                               case decode_vcard_LON(_el) of
-                                 undefined -> Lon;
-                                 _new_el -> [_new_el | Lon]
-                               end);
-       true -> decode_vcard_GEO_els(_els, Lat, Lon)
-    end;
-decode_vcard_GEO_els([_ | _els], Lat, Lon) ->
-    decode_vcard_GEO_els(_els, Lat, Lon).
+decode_sasl_failure_not_authorized({xmlel,
+                                   <<"not-authorized">>, _attrs, _els}) ->
+    'not-authorized'.
 
-encode_vcard_GEO({vcard_geo, Lat, Lon}, _xmlns_attrs) ->
-    _els = 'encode_vcard_GEO_$lon'(Lon,
-                                  'encode_vcard_GEO_$lat'(Lat, [])),
+encode_sasl_failure_not_authorized('not-authorized',
+                                  _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"GEO">>, _attrs, _els}.
+    {xmlel, <<"not-authorized">>, _attrs, _els}.
 
-'encode_vcard_GEO_$lat'(Lat, _acc) ->
-    [encode_vcard_LAT(Lat, []) | _acc].
+decode_sasl_failure_mechanism_too_weak({xmlel,
+                                       <<"mechanism-too-weak">>, _attrs,
+                                       _els}) ->
+    'mechanism-too-weak'.
 
-'encode_vcard_GEO_$lon'(Lon, _acc) ->
-    [encode_vcard_LON(Lon, []) | _acc].
+encode_sasl_failure_mechanism_too_weak('mechanism-too-weak',
+                                      _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"mechanism-too-weak">>, _attrs, _els}.
 
-decode_vcard_BINVAL({xmlel, <<"BINVAL">>, _attrs,
-                    _els}) ->
-    Cdata = decode_vcard_BINVAL_els(_els, <<>>), Cdata.
+decode_sasl_failure_malformed_request({xmlel,
+                                      <<"malformed-request">>, _attrs,
+                                      _els}) ->
+    'malformed-request'.
 
-decode_vcard_BINVAL_els([], Cdata) ->
-    decode_vcard_BINVAL_cdata(Cdata);
-decode_vcard_BINVAL_els([{xmlcdata, _data} | _els],
-                       Cdata) ->
-    decode_vcard_BINVAL_els(_els,
-                           <<Cdata/binary, _data/binary>>);
-decode_vcard_BINVAL_els([_ | _els], Cdata) ->
-    decode_vcard_BINVAL_els(_els, Cdata).
+encode_sasl_failure_malformed_request('malformed-request',
+                                     _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"malformed-request">>, _attrs, _els}.
 
-encode_vcard_BINVAL(Cdata, _xmlns_attrs) ->
-    _els = encode_vcard_BINVAL_cdata(Cdata, []),
+decode_sasl_failure_invalid_mechanism({xmlel,
+                                      <<"invalid-mechanism">>, _attrs,
+                                      _els}) ->
+    'invalid-mechanism'.
+
+encode_sasl_failure_invalid_mechanism('invalid-mechanism',
+                                     _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"BINVAL">>, _attrs, _els}.
+    {xmlel, <<"invalid-mechanism">>, _attrs, _els}.
 
-decode_vcard_BINVAL_cdata(<<>>) -> undefined;
-decode_vcard_BINVAL_cdata(_val) ->
-    case catch base64:decode(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"BINVAL">>,
-                       <<"vcard-temp">>});
-      _res -> _res
-    end.
+decode_sasl_failure_invalid_authzid({xmlel,
+                                    <<"invalid-authzid">>, _attrs, _els}) ->
+    'invalid-authzid'.
 
-encode_vcard_BINVAL_cdata(undefined, _acc) -> _acc;
-encode_vcard_BINVAL_cdata(_val, _acc) ->
-    [{xmlcdata, base64:encode(_val)} | _acc].
+encode_sasl_failure_invalid_authzid('invalid-authzid',
+                                   _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"invalid-authzid">>, _attrs, _els}.
 
-decode_vcard_LOGO({xmlel, <<"LOGO">>, _attrs, _els}) ->
-    {Type, Extval, Binval} = decode_vcard_LOGO_els(_els,
-                                                  undefined, undefined,
-                                                  undefined),
-    {vcard_logo, Type, Binval, Extval}.
+decode_sasl_failure_incorrect_encoding({xmlel,
+                                       <<"incorrect-encoding">>, _attrs,
+                                       _els}) ->
+    'incorrect-encoding'.
 
-decode_vcard_LOGO_els([], Type, Extval, Binval) ->
-    {Type, Extval, Binval};
-decode_vcard_LOGO_els([{xmlel, <<"TYPE">>, _attrs, _} =
-                          _el
-                      | _els],
-                     Type, Extval, Binval) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_LOGO_els(_els, decode_vcard_TYPE(_el),
-                                Extval, Binval);
-       true ->
-          decode_vcard_LOGO_els(_els, Type, Extval, Binval)
-    end;
-decode_vcard_LOGO_els([{xmlel, <<"BINVAL">>, _attrs,
-                       _} =
-                          _el
-                      | _els],
-                     Type, Extval, Binval) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_LOGO_els(_els, Type, Extval,
-                                decode_vcard_BINVAL(_el));
-       true ->
-          decode_vcard_LOGO_els(_els, Type, Extval, Binval)
-    end;
-decode_vcard_LOGO_els([{xmlel, <<"EXTVAL">>, _attrs,
-                       _} =
-                          _el
-                      | _els],
-                     Type, Extval, Binval) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_LOGO_els(_els, Type,
-                                decode_vcard_EXTVAL(_el), Binval);
-       true ->
-          decode_vcard_LOGO_els(_els, Type, Extval, Binval)
-    end;
-decode_vcard_LOGO_els([_ | _els], Type, Extval,
-                     Binval) ->
-    decode_vcard_LOGO_els(_els, Type, Extval, Binval).
+encode_sasl_failure_incorrect_encoding('incorrect-encoding',
+                                      _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"incorrect-encoding">>, _attrs, _els}.
 
-encode_vcard_LOGO({vcard_logo, Type, Binval, Extval},
-                 _xmlns_attrs) ->
-    _els = 'encode_vcard_LOGO_$binval'(Binval,
-                                      'encode_vcard_LOGO_$extval'(Extval,
-                                                                  'encode_vcard_LOGO_$type'(Type,
-                                                                                            []))),
+decode_sasl_failure_encryption_required({xmlel,
+                                        <<"encryption-required">>, _attrs,
+                                        _els}) ->
+    'encryption-required'.
+
+encode_sasl_failure_encryption_required('encryption-required',
+                                       _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"LOGO">>, _attrs, _els}.
+    {xmlel, <<"encryption-required">>, _attrs, _els}.
 
-'encode_vcard_LOGO_$type'(undefined, _acc) -> _acc;
-'encode_vcard_LOGO_$type'(Type, _acc) ->
-    [encode_vcard_TYPE(Type, []) | _acc].
+decode_sasl_failure_credentials_expired({xmlel,
+                                        <<"credentials-expired">>, _attrs,
+                                        _els}) ->
+    'credentials-expired'.
 
-'encode_vcard_LOGO_$extval'(undefined, _acc) -> _acc;
-'encode_vcard_LOGO_$extval'(Extval, _acc) ->
-    [encode_vcard_EXTVAL(Extval, []) | _acc].
+encode_sasl_failure_credentials_expired('credentials-expired',
+                                       _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"credentials-expired">>, _attrs, _els}.
 
-'encode_vcard_LOGO_$binval'(undefined, _acc) -> _acc;
-'encode_vcard_LOGO_$binval'(Binval, _acc) ->
-    [encode_vcard_BINVAL(Binval, []) | _acc].
+decode_sasl_failure_account_disabled({xmlel,
+                                     <<"account-disabled">>, _attrs, _els}) ->
+    'account-disabled'.
 
-decode_vcard_PHOTO({xmlel, <<"PHOTO">>, _attrs,
-                   _els}) ->
-    {Type, Extval, Binval} = decode_vcard_PHOTO_els(_els,
-                                                   undefined, undefined,
-                                                   undefined),
-    {vcard_photo, Type, Binval, Extval}.
+encode_sasl_failure_account_disabled('account-disabled',
+                                    _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"account-disabled">>, _attrs, _els}.
 
-decode_vcard_PHOTO_els([], Type, Extval, Binval) ->
-    {Type, Extval, Binval};
-decode_vcard_PHOTO_els([{xmlel, <<"TYPE">>, _attrs, _} =
-                           _el
-                       | _els],
-                      Type, Extval, Binval) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_PHOTO_els(_els, decode_vcard_TYPE(_el),
-                                 Extval, Binval);
-       true ->
-          decode_vcard_PHOTO_els(_els, Type, Extval, Binval)
-    end;
-decode_vcard_PHOTO_els([{xmlel, <<"BINVAL">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Type, Extval, Binval) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_PHOTO_els(_els, Type, Extval,
-                                 decode_vcard_BINVAL(_el));
-       true ->
-          decode_vcard_PHOTO_els(_els, Type, Extval, Binval)
-    end;
-decode_vcard_PHOTO_els([{xmlel, <<"EXTVAL">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Type, Extval, Binval) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_PHOTO_els(_els, Type,
-                                 decode_vcard_EXTVAL(_el), Binval);
-       true ->
-          decode_vcard_PHOTO_els(_els, Type, Extval, Binval)
-    end;
-decode_vcard_PHOTO_els([_ | _els], Type, Extval,
-                      Binval) ->
-    decode_vcard_PHOTO_els(_els, Type, Extval, Binval).
+decode_sasl_failure_aborted({xmlel, <<"aborted">>,
+                            _attrs, _els}) ->
+    aborted.
 
-encode_vcard_PHOTO({vcard_photo, Type, Binval, Extval},
-                  _xmlns_attrs) ->
-    _els = 'encode_vcard_PHOTO_$binval'(Binval,
-                                       'encode_vcard_PHOTO_$extval'(Extval,
-                                                                    'encode_vcard_PHOTO_$type'(Type,
-                                                                                               []))),
+encode_sasl_failure_aborted(aborted, _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"PHOTO">>, _attrs, _els}.
+    {xmlel, <<"aborted">>, _attrs, _els}.
 
-'encode_vcard_PHOTO_$type'(undefined, _acc) -> _acc;
-'encode_vcard_PHOTO_$type'(Type, _acc) ->
-    [encode_vcard_TYPE(Type, []) | _acc].
+decode_sasl_failure_text({xmlel, <<"text">>, _attrs,
+                         _els}) ->
+    Data = decode_sasl_failure_text_els(_els, <<>>),
+    Lang = decode_sasl_failure_text_attrs(_attrs,
+                                         undefined),
+    {text, Lang, Data}.
 
-'encode_vcard_PHOTO_$extval'(undefined, _acc) -> _acc;
-'encode_vcard_PHOTO_$extval'(Extval, _acc) ->
-    [encode_vcard_EXTVAL(Extval, []) | _acc].
+decode_sasl_failure_text_els([], Data) ->
+    decode_sasl_failure_text_cdata(Data);
+decode_sasl_failure_text_els([{xmlcdata, _data} | _els],
+                            Data) ->
+    decode_sasl_failure_text_els(_els,
+                                <<Data/binary, _data/binary>>);
+decode_sasl_failure_text_els([_ | _els], Data) ->
+    decode_sasl_failure_text_els(_els, Data).
 
-'encode_vcard_PHOTO_$binval'(undefined, _acc) -> _acc;
-'encode_vcard_PHOTO_$binval'(Binval, _acc) ->
-    [encode_vcard_BINVAL(Binval, []) | _acc].
+decode_sasl_failure_text_attrs([{<<"xml:lang">>, _val}
+                               | _attrs],
+                              _Lang) ->
+    decode_sasl_failure_text_attrs(_attrs, _val);
+decode_sasl_failure_text_attrs([_ | _attrs], Lang) ->
+    decode_sasl_failure_text_attrs(_attrs, Lang);
+decode_sasl_failure_text_attrs([], Lang) ->
+    'decode_sasl_failure_text_attr_xml:lang'(Lang).
 
-decode_vcard_ORG({xmlel, <<"ORG">>, _attrs, _els}) ->
-    {Units, Name} = decode_vcard_ORG_els(_els, [], []),
-    {vcard_org, Name, Units}.
+encode_sasl_failure_text({text, Lang, Data},
+                        _xmlns_attrs) ->
+    _els = encode_sasl_failure_text_cdata(Data, []),
+    _attrs = 'encode_sasl_failure_text_attr_xml:lang'(Lang,
+                                                     _xmlns_attrs),
+    {xmlel, <<"text">>, _attrs, _els}.
 
-decode_vcard_ORG_els([], Units, [Name]) ->
-    {lists:reverse(Units), Name};
-decode_vcard_ORG_els([{xmlel, <<"ORGNAME">>, _attrs,
-                      _} =
-                         _el
-                     | _els],
-                    Units, Name) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ORG_els(_els, Units,
-                               case decode_vcard_ORGNAME(_el) of
-                                 undefined -> Name;
-                                 _new_el -> [_new_el | Name]
-                               end);
-       true -> decode_vcard_ORG_els(_els, Units, Name)
-    end;
-decode_vcard_ORG_els([{xmlel, <<"ORGUNIT">>, _attrs,
-                      _} =
-                         _el
-                     | _els],
-                    Units, Name) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_ORG_els(_els,
-                               case decode_vcard_ORGUNIT(_el) of
-                                 undefined -> Units;
-                                 _new_el -> [_new_el | Units]
-                               end,
-                               Name);
-       true -> decode_vcard_ORG_els(_els, Units, Name)
-    end;
-decode_vcard_ORG_els([_ | _els], Units, Name) ->
-    decode_vcard_ORG_els(_els, Units, Name).
+'decode_sasl_failure_text_attr_xml:lang'(undefined) ->
+    undefined;
+'decode_sasl_failure_text_attr_xml:lang'(_val) -> _val.
 
-encode_vcard_ORG({vcard_org, Name, Units},
-                _xmlns_attrs) ->
-    _els = 'encode_vcard_ORG_$name'(Name,
-                                   'encode_vcard_ORG_$units'(Units, [])),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"ORG">>, _attrs, _els}.
+'encode_sasl_failure_text_attr_xml:lang'(undefined,
+                                        _acc) ->
+    _acc;
+'encode_sasl_failure_text_attr_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
 
-'encode_vcard_ORG_$units'([], _acc) -> _acc;
-'encode_vcard_ORG_$units'([Units | _els], _acc) ->
-    'encode_vcard_ORG_$units'(_els,
-                             [encode_vcard_ORGUNIT(Units, []) | _acc]).
+decode_sasl_failure_text_cdata(<<>>) -> undefined;
+decode_sasl_failure_text_cdata(_val) -> _val.
 
-'encode_vcard_ORG_$name'(Name, _acc) ->
-    [encode_vcard_ORGNAME(Name, []) | _acc].
+encode_sasl_failure_text_cdata(undefined, _acc) -> _acc;
+encode_sasl_failure_text_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_vcard_SOUND({xmlel, <<"SOUND">>, _attrs,
-                   _els}) ->
-    {Phonetic, Extval, Binval} =
-       decode_vcard_SOUND_els(_els, undefined, undefined,
-                              undefined),
-    {vcard_sound, Phonetic, Binval, Extval}.
+decode_sasl_success({xmlel, <<"success">>, _attrs,
+                    _els}) ->
+    Text = decode_sasl_success_els(_els, <<>>),
+    {sasl_success, Text}.
 
-decode_vcard_SOUND_els([], Phonetic, Extval, Binval) ->
-    {Phonetic, Extval, Binval};
-decode_vcard_SOUND_els([{xmlel, <<"BINVAL">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Phonetic, Extval, Binval) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_SOUND_els(_els, Phonetic, Extval,
-                                 decode_vcard_BINVAL(_el));
-       true ->
-          decode_vcard_SOUND_els(_els, Phonetic, Extval, Binval)
-    end;
-decode_vcard_SOUND_els([{xmlel, <<"EXTVAL">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Phonetic, Extval, Binval) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_SOUND_els(_els, Phonetic,
-                                 decode_vcard_EXTVAL(_el), Binval);
-       true ->
-          decode_vcard_SOUND_els(_els, Phonetic, Extval, Binval)
-    end;
-decode_vcard_SOUND_els([{xmlel, <<"PHONETIC">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Phonetic, Extval, Binval) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_SOUND_els(_els, decode_vcard_PHONETIC(_el),
-                                 Extval, Binval);
-       true ->
-          decode_vcard_SOUND_els(_els, Phonetic, Extval, Binval)
-    end;
-decode_vcard_SOUND_els([_ | _els], Phonetic, Extval,
-                      Binval) ->
-    decode_vcard_SOUND_els(_els, Phonetic, Extval, Binval).
+decode_sasl_success_els([], Text) ->
+    decode_sasl_success_cdata(Text);
+decode_sasl_success_els([{xmlcdata, _data} | _els],
+                       Text) ->
+    decode_sasl_success_els(_els,
+                           <<Text/binary, _data/binary>>);
+decode_sasl_success_els([_ | _els], Text) ->
+    decode_sasl_success_els(_els, Text).
 
-encode_vcard_SOUND({vcard_sound, Phonetic, Binval,
-                   Extval},
-                  _xmlns_attrs) ->
-    _els = 'encode_vcard_SOUND_$binval'(Binval,
-                                       'encode_vcard_SOUND_$extval'(Extval,
-                                                                    'encode_vcard_SOUND_$phonetic'(Phonetic,
-                                                                                                   []))),
+encode_sasl_success({sasl_success, Text},
+                   _xmlns_attrs) ->
+    _els = encode_sasl_success_cdata(Text, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"SOUND">>, _attrs, _els}.
-
-'encode_vcard_SOUND_$phonetic'(undefined, _acc) -> _acc;
-'encode_vcard_SOUND_$phonetic'(Phonetic, _acc) ->
-    [encode_vcard_PHONETIC(Phonetic, []) | _acc].
+    {xmlel, <<"success">>, _attrs, _els}.
 
-'encode_vcard_SOUND_$extval'(undefined, _acc) -> _acc;
-'encode_vcard_SOUND_$extval'(Extval, _acc) ->
-    [encode_vcard_EXTVAL(Extval, []) | _acc].
+decode_sasl_success_cdata(<<>>) -> undefined;
+decode_sasl_success_cdata(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"success">>,
+                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
+      _res -> _res
+    end.
 
-'encode_vcard_SOUND_$binval'(undefined, _acc) -> _acc;
-'encode_vcard_SOUND_$binval'(Binval, _acc) ->
-    [encode_vcard_BINVAL(Binval, []) | _acc].
+encode_sasl_success_cdata(undefined, _acc) -> _acc;
+encode_sasl_success_cdata(_val, _acc) ->
+    [{xmlcdata, base64:encode(_val)} | _acc].
 
-decode_vcard_KEY({xmlel, <<"KEY">>, _attrs, _els}) ->
-    {Cred, Type} = decode_vcard_KEY_els(_els, [],
-                                       undefined),
-    {vcard_key, Type, Cred}.
+decode_sasl_response({xmlel, <<"response">>, _attrs,
+                     _els}) ->
+    Text = decode_sasl_response_els(_els, <<>>),
+    {sasl_response, Text}.
 
-decode_vcard_KEY_els([], [Cred], Type) -> {Cred, Type};
-decode_vcard_KEY_els([{xmlel, <<"TYPE">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Cred, Type) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_KEY_els(_els, Cred,
-                               decode_vcard_TYPE(_el));
-       true -> decode_vcard_KEY_els(_els, Cred, Type)
-    end;
-decode_vcard_KEY_els([{xmlel, <<"CRED">>, _attrs, _} =
-                         _el
-                     | _els],
-                    Cred, Type) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_KEY_els(_els,
-                               case decode_vcard_CRED(_el) of
-                                 undefined -> Cred;
-                                 _new_el -> [_new_el | Cred]
-                               end,
-                               Type);
-       true -> decode_vcard_KEY_els(_els, Cred, Type)
-    end;
-decode_vcard_KEY_els([_ | _els], Cred, Type) ->
-    decode_vcard_KEY_els(_els, Cred, Type).
+decode_sasl_response_els([], Text) ->
+    decode_sasl_response_cdata(Text);
+decode_sasl_response_els([{xmlcdata, _data} | _els],
+                        Text) ->
+    decode_sasl_response_els(_els,
+                            <<Text/binary, _data/binary>>);
+decode_sasl_response_els([_ | _els], Text) ->
+    decode_sasl_response_els(_els, Text).
 
-encode_vcard_KEY({vcard_key, Type, Cred},
-                _xmlns_attrs) ->
-    _els = 'encode_vcard_KEY_$type'(Type,
-                                   'encode_vcard_KEY_$cred'(Cred, [])),
+encode_sasl_response({sasl_response, Text},
+                    _xmlns_attrs) ->
+    _els = encode_sasl_response_cdata(Text, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"KEY">>, _attrs, _els}.
+    {xmlel, <<"response">>, _attrs, _els}.
 
-'encode_vcard_KEY_$cred'(Cred, _acc) ->
-    [encode_vcard_CRED(Cred, []) | _acc].
+decode_sasl_response_cdata(<<>>) -> undefined;
+decode_sasl_response_cdata(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"response">>,
+                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
+      _res -> _res
+    end.
 
-'encode_vcard_KEY_$type'(undefined, _acc) -> _acc;
-'encode_vcard_KEY_$type'(Type, _acc) ->
-    [encode_vcard_TYPE(Type, []) | _acc].
+encode_sasl_response_cdata(undefined, _acc) -> _acc;
+encode_sasl_response_cdata(_val, _acc) ->
+    [{xmlcdata, base64:encode(_val)} | _acc].
 
-decode_vcard_CATEGORIES({xmlel, <<"CATEGORIES">>,
-                        _attrs, _els}) ->
-    Keywords = decode_vcard_CATEGORIES_els(_els, []),
-    Keywords.
+decode_sasl_challenge({xmlel, <<"challenge">>, _attrs,
+                      _els}) ->
+    Text = decode_sasl_challenge_els(_els, <<>>),
+    {sasl_challenge, Text}.
 
-decode_vcard_CATEGORIES_els([], Keywords) ->
-    lists:reverse(Keywords);
-decode_vcard_CATEGORIES_els([{xmlel, <<"KEYWORD">>,
-                             _attrs, _} =
-                                _el
-                            | _els],
-                           Keywords) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_CATEGORIES_els(_els,
-                                      case decode_vcard_KEYWORD(_el) of
-                                        undefined -> Keywords;
-                                        _new_el -> [_new_el | Keywords]
-                                      end);
-       true -> decode_vcard_CATEGORIES_els(_els, Keywords)
-    end;
-decode_vcard_CATEGORIES_els([_ | _els], Keywords) ->
-    decode_vcard_CATEGORIES_els(_els, Keywords).
+decode_sasl_challenge_els([], Text) ->
+    decode_sasl_challenge_cdata(Text);
+decode_sasl_challenge_els([{xmlcdata, _data} | _els],
+                         Text) ->
+    decode_sasl_challenge_els(_els,
+                             <<Text/binary, _data/binary>>);
+decode_sasl_challenge_els([_ | _els], Text) ->
+    decode_sasl_challenge_els(_els, Text).
 
-encode_vcard_CATEGORIES(Keywords, _xmlns_attrs) ->
-    _els = 'encode_vcard_CATEGORIES_$keywords'(Keywords,
-                                              []),
+encode_sasl_challenge({sasl_challenge, Text},
+                     _xmlns_attrs) ->
+    _els = encode_sasl_challenge_cdata(Text, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"CATEGORIES">>, _attrs, _els}.
+    {xmlel, <<"challenge">>, _attrs, _els}.
 
-'encode_vcard_CATEGORIES_$keywords'([], _acc) -> _acc;
-'encode_vcard_CATEGORIES_$keywords'([Keywords | _els],
-                                   _acc) ->
-    'encode_vcard_CATEGORIES_$keywords'(_els,
-                                       [encode_vcard_KEYWORD(Keywords, [])
-                                        | _acc]).
+decode_sasl_challenge_cdata(<<>>) -> undefined;
+decode_sasl_challenge_cdata(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"challenge">>,
+                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
+      _res -> _res
+    end.
 
-decode_vcard_CLASS({xmlel, <<"CLASS">>, _attrs,
-                   _els}) ->
-    Class = decode_vcard_CLASS_els(_els, undefined), Class.
+encode_sasl_challenge_cdata(undefined, _acc) -> _acc;
+encode_sasl_challenge_cdata(_val, _acc) ->
+    [{xmlcdata, base64:encode(_val)} | _acc].
 
-decode_vcard_CLASS_els([], Class) -> Class;
-decode_vcard_CLASS_els([{xmlel, <<"PUBLIC">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Class) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_CLASS_els(_els, decode_vcard_PUBLIC(_el));
-       true -> decode_vcard_CLASS_els(_els, Class)
-    end;
-decode_vcard_CLASS_els([{xmlel, <<"PRIVATE">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Class) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_CLASS_els(_els, decode_vcard_PRIVATE(_el));
-       true -> decode_vcard_CLASS_els(_els, Class)
-    end;
-decode_vcard_CLASS_els([{xmlel, <<"CONFIDENTIAL">>,
-                        _attrs, _} =
-                           _el
-                       | _els],
-                      Class) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_CLASS_els(_els,
-                                 decode_vcard_CONFIDENTIAL(_el));
-       true -> decode_vcard_CLASS_els(_els, Class)
-    end;
-decode_vcard_CLASS_els([_ | _els], Class) ->
-    decode_vcard_CLASS_els(_els, Class).
+decode_sasl_abort({xmlel, <<"abort">>, _attrs, _els}) ->
+    {sasl_abort}.
 
-encode_vcard_CLASS(Class, _xmlns_attrs) ->
-    _els = 'encode_vcard_CLASS_$class'(Class, []),
+encode_sasl_abort({sasl_abort}, _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"CLASS">>, _attrs, _els}.
+    {xmlel, <<"abort">>, _attrs, _els}.
 
-'encode_vcard_CLASS_$class'(undefined, _acc) -> _acc;
-'encode_vcard_CLASS_$class'(public = Class, _acc) ->
-    [encode_vcard_PUBLIC(Class, []) | _acc];
-'encode_vcard_CLASS_$class'(private = Class, _acc) ->
-    [encode_vcard_PRIVATE(Class, []) | _acc];
-'encode_vcard_CLASS_$class'(confidential = Class,
-                           _acc) ->
-    [encode_vcard_CONFIDENTIAL(Class, []) | _acc].
+decode_sasl_auth({xmlel, <<"auth">>, _attrs, _els}) ->
+    Text = decode_sasl_auth_els(_els, <<>>),
+    Mechanism = decode_sasl_auth_attrs(_attrs, undefined),
+    {sasl_auth, Mechanism, Text}.
 
-decode_vcard_AGENT({xmlel, <<"AGENT">>, _attrs,
-                   _els}) ->
-    {Vcard, Extval} = decode_vcard_AGENT_els(_els,
-                                            undefined, undefined),
-    {vcard_agent, Vcard, Extval}.
+decode_sasl_auth_els([], Text) ->
+    decode_sasl_auth_cdata(Text);
+decode_sasl_auth_els([{xmlcdata, _data} | _els],
+                    Text) ->
+    decode_sasl_auth_els(_els,
+                        <<Text/binary, _data/binary>>);
+decode_sasl_auth_els([_ | _els], Text) ->
+    decode_sasl_auth_els(_els, Text).
 
-decode_vcard_AGENT_els([], Vcard, Extval) ->
-    {Vcard, Extval};
-decode_vcard_AGENT_els([{xmlel, <<"vCard">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Vcard, Extval) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_AGENT_els(_els, decode_vcard(_el), Extval);
-       true -> decode_vcard_AGENT_els(_els, Vcard, Extval)
-    end;
-decode_vcard_AGENT_els([{xmlel, <<"EXTVAL">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Vcard, Extval) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_AGENT_els(_els, Vcard,
-                                 decode_vcard_EXTVAL(_el));
-       true -> decode_vcard_AGENT_els(_els, Vcard, Extval)
-    end;
-decode_vcard_AGENT_els([_ | _els], Vcard, Extval) ->
-    decode_vcard_AGENT_els(_els, Vcard, Extval).
+decode_sasl_auth_attrs([{<<"mechanism">>, _val}
+                       | _attrs],
+                      _Mechanism) ->
+    decode_sasl_auth_attrs(_attrs, _val);
+decode_sasl_auth_attrs([_ | _attrs], Mechanism) ->
+    decode_sasl_auth_attrs(_attrs, Mechanism);
+decode_sasl_auth_attrs([], Mechanism) ->
+    decode_sasl_auth_attr_mechanism(Mechanism).
 
-encode_vcard_AGENT({vcard_agent, Vcard, Extval},
-                  _xmlns_attrs) ->
-    _els = 'encode_vcard_AGENT_$extval'(Extval,
-                                       'encode_vcard_AGENT_$vcard'(Vcard, [])),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"AGENT">>, _attrs, _els}.
+encode_sasl_auth({sasl_auth, Mechanism, Text},
+                _xmlns_attrs) ->
+    _els = encode_sasl_auth_cdata(Text, []),
+    _attrs = encode_sasl_auth_attr_mechanism(Mechanism,
+                                            _xmlns_attrs),
+    {xmlel, <<"auth">>, _attrs, _els}.
 
-'encode_vcard_AGENT_$vcard'(undefined, _acc) -> _acc;
-'encode_vcard_AGENT_$vcard'(Vcard, _acc) ->
-    [encode_vcard(Vcard, []) | _acc].
+decode_sasl_auth_attr_mechanism(undefined) ->
+    erlang:error({missing_attr, <<"mechanism">>, <<"auth">>,
+                 <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
+decode_sasl_auth_attr_mechanism(_val) -> _val.
 
-'encode_vcard_AGENT_$extval'(undefined, _acc) -> _acc;
-'encode_vcard_AGENT_$extval'(Extval, _acc) ->
-    [encode_vcard_EXTVAL(Extval, []) | _acc].
+encode_sasl_auth_attr_mechanism(_val, _acc) ->
+    [{<<"mechanism">>, _val} | _acc].
 
-decode_vcard({xmlel, <<"vCard">>, _attrs, _els}) ->
-    {Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-     Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-     Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-     Label, Fn, Version, N, Photo, Logo, Geo} =
-       decode_vcard_els(_els, undefined, [], undefined, [],
-                        undefined, undefined, undefined, undefined, undefined,
-                        undefined, undefined, undefined, undefined, undefined,
-                        undefined, undefined, undefined, undefined, undefined,
-                        undefined, undefined, [], [], [], undefined, undefined,
-                        undefined, undefined, undefined, undefined),
-    {vcard, Version, Fn, N, Nickname, Photo, Bday, Adr,
-     Label, Tel, Email, Jabberid, Mailer, Tz, Geo, Title,
-     Role, Logo, Org, Categories, Note, Prodid, Agent, Rev,
-     Sort_string, Sound, Uid, Url, Class, Key, Desc}.
+decode_sasl_auth_cdata(<<>>) -> undefined;
+decode_sasl_auth_cdata(_val) ->
+    case catch base64:decode(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"auth">>,
+                       <<"urn:ietf:params:xml:ns:xmpp-sasl">>});
+      _res -> _res
+    end.
 
-decode_vcard_els([], Mailer, Adr, Class, Categories,
-                Desc, Uid, Agent, Prodid, Jabberid, Sound, Note, Role,
-                Title, Nickname, Rev, Sort_string, Org, Bday, Key, Tz,
-                Url, Email, Tel, Label, Fn, Version, N, Photo, Logo,
-                Geo) ->
-    {Mailer, lists:reverse(Adr), Class, Categories, Desc,
-     Uid, Agent, Prodid, Jabberid, Sound, Note, Role, Title,
-     Nickname, Rev, Sort_string, Org, Bday, Key, Tz, Url,
-     lists:reverse(Email), lists:reverse(Tel),
-     lists:reverse(Label), Fn, Version, N, Photo, Logo, Geo};
-decode_vcard_els([{xmlel, <<"N">>, _attrs, _} = _el
-                 | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version,
-                           decode_vcard_N(_el), Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
-    end;
-decode_vcard_els([{xmlel, <<"ADR">>, _attrs, _} = _el
-                 | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer,
-                           case decode_vcard_ADR(_el) of
-                             undefined -> Adr;
-                             _new_el -> [_new_el | Adr]
-                           end,
-                           Class, Categories, Desc, Uid, Agent, Prodid,
-                           Jabberid, Sound, Note, Role, Title, Nickname, Rev,
-                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
-    end;
-decode_vcard_els([{xmlel, <<"LABEL">>, _attrs, _} = _el
-                 | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel,
-                           case decode_vcard_LABEL(_el) of
-                             undefined -> Label;
-                             _new_el -> [_new_el | Label]
-                           end,
-                           Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
-    end;
-decode_vcard_els([{xmlel, <<"TEL">>, _attrs, _} = _el
-                 | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email,
-                           case decode_vcard_TEL(_el) of
-                             undefined -> Tel;
-                             _new_el -> [_new_el | Tel]
-                           end,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
-    end;
-decode_vcard_els([{xmlel, <<"EMAIL">>, _attrs, _} = _el
-                 | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url,
-                           case decode_vcard_EMAIL(_el) of
-                             undefined -> Email;
-                             _new_el -> [_new_el | Email]
-                           end,
-                           Tel, Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
-    end;
-decode_vcard_els([{xmlel, <<"GEO">>, _attrs, _} = _el
-                 | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, decode_vcard_GEO(_el));
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
-    end;
-decode_vcard_els([{xmlel, <<"LOGO">>, _attrs, _} = _el
-                 | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, decode_vcard_LOGO(_el), Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
-    end;
-decode_vcard_els([{xmlel, <<"PHOTO">>, _attrs, _} = _el
-                 | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           decode_vcard_PHOTO(_el), Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
-    end;
-decode_vcard_els([{xmlel, <<"ORG">>, _attrs, _} = _el
-                 | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+encode_sasl_auth_cdata(undefined, _acc) -> _acc;
+encode_sasl_auth_cdata(_val, _acc) ->
+    [{xmlcdata, base64:encode(_val)} | _acc].
+
+decode_bind({xmlel, <<"bind">>, _attrs, _els}) ->
+    {Jid, Resource} = decode_bind_els(_els, undefined,
+                                     undefined),
+    {bind, Jid, Resource}.
+
+decode_bind_els([], Jid, Resource) -> {Jid, Resource};
+decode_bind_els([{xmlel, <<"jid">>, _attrs, _} = _el
+                | _els],
+               Jid, Resource) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string,
-                           decode_vcard_ORG(_el), Bday, Key, Tz, Url, Email,
-                           Tel, Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-bind">> ->
+          decode_bind_els(_els, decode_bind_jid(_el), Resource);
+       true -> decode_bind_els(_els, Jid, Resource)
     end;
-decode_vcard_els([{xmlel, <<"SOUND">>, _attrs, _} = _el
-                 | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+decode_bind_els([{xmlel, <<"resource">>, _attrs, _} =
+                    _el
+                | _els],
+               Jid, Resource) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid,
-                           decode_vcard_SOUND(_el), Note, Role, Title,
-                           Nickname, Rev, Sort_string, Org, Bday, Key, Tz, Url,
-                           Email, Tel, Label, Fn, Version, N, Photo, Logo,
-                           Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns == <<>>;
+       _xmlns == <<"urn:ietf:params:xml:ns:xmpp-bind">> ->
+          decode_bind_els(_els, Jid, decode_bind_resource(_el));
+       true -> decode_bind_els(_els, Jid, Resource)
     end;
-decode_vcard_els([{xmlel, <<"KEY">>, _attrs, _} = _el
+decode_bind_els([_ | _els], Jid, Resource) ->
+    decode_bind_els(_els, Jid, Resource).
+
+encode_bind({bind, Jid, Resource}, _xmlns_attrs) ->
+    _els = 'encode_bind_$resource'(Resource,
+                                  'encode_bind_$jid'(Jid, [])),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"bind">>, _attrs, _els}.
+
+'encode_bind_$jid'(undefined, _acc) -> _acc;
+'encode_bind_$jid'(Jid, _acc) ->
+    [encode_bind_jid(Jid, []) | _acc].
+
+'encode_bind_$resource'(undefined, _acc) -> _acc;
+'encode_bind_$resource'(Resource, _acc) ->
+    [encode_bind_resource(Resource, []) | _acc].
+
+decode_bind_resource({xmlel, <<"resource">>, _attrs,
+                     _els}) ->
+    Cdata = decode_bind_resource_els(_els, <<>>), Cdata.
+
+decode_bind_resource_els([], Cdata) ->
+    decode_bind_resource_cdata(Cdata);
+decode_bind_resource_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_bind_resource_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_bind_resource_els([_ | _els], Cdata) ->
+    decode_bind_resource_els(_els, Cdata).
+
+encode_bind_resource(Cdata, _xmlns_attrs) ->
+    _els = encode_bind_resource_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"resource">>, _attrs, _els}.
+
+decode_bind_resource_cdata(<<>>) -> undefined;
+decode_bind_resource_cdata(_val) ->
+    case catch resourceprep(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"resource">>,
+                       <<"urn:ietf:params:xml:ns:xmpp-bind">>});
+      _res -> _res
+    end.
+
+encode_bind_resource_cdata(undefined, _acc) -> _acc;
+encode_bind_resource_cdata(_val, _acc) ->
+    [{xmlcdata, resourceprep(_val)} | _acc].
+
+decode_bind_jid({xmlel, <<"jid">>, _attrs, _els}) ->
+    Cdata = decode_bind_jid_els(_els, <<>>), Cdata.
+
+decode_bind_jid_els([], Cdata) ->
+    decode_bind_jid_cdata(Cdata);
+decode_bind_jid_els([{xmlcdata, _data} | _els],
+                   Cdata) ->
+    decode_bind_jid_els(_els,
+                       <<Cdata/binary, _data/binary>>);
+decode_bind_jid_els([_ | _els], Cdata) ->
+    decode_bind_jid_els(_els, Cdata).
+
+encode_bind_jid(Cdata, _xmlns_attrs) ->
+    _els = encode_bind_jid_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"jid">>, _attrs, _els}.
+
+decode_bind_jid_cdata(<<>>) -> undefined;
+decode_bind_jid_cdata(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_cdata_value, <<>>, <<"jid">>,
+                       <<"urn:ietf:params:xml:ns:xmpp-bind">>});
+      _res -> _res
+    end.
+
+encode_bind_jid_cdata(undefined, _acc) -> _acc;
+encode_bind_jid_cdata(_val, _acc) ->
+    [{xmlcdata, enc_jid(_val)} | _acc].
+
+decode_error({xmlel, <<"error">>, _attrs, _els}) ->
+    {Text, Reason} = decode_error_els(_els, undefined,
+                                     undefined),
+    {Type, By} = decode_error_attrs(_attrs, undefined,
+                                   undefined),
+    {error, Type, By, Reason, Text}.
+
+decode_error_els([], Text, Reason) -> {Text, Reason};
+decode_error_els([{xmlel, <<"text">>, _attrs, _} = _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           decode_vcard_KEY(_el), Tz, Url, Email, Tel, Label,
-                           Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, decode_error_text(_el), Reason);
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"VERSION">>, _attrs, _} =
+decode_error_els([{xmlel, <<"bad-request">>, _attrs,
+                  _} =
                      _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn,
-                           decode_vcard_VERSION(_el), N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
-    end;
-decode_vcard_els([{xmlel, <<"FN">>, _attrs, _} = _el
-                 | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label,
-                           decode_vcard_FN(_el), Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_bad_request(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"NICKNAME">>, _attrs, _} =
+decode_error_els([{xmlel, <<"conflict">>, _attrs, _} =
                      _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, decode_vcard_NICKNAME(_el), Rev,
-                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_conflict(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"BDAY">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"feature-not-implemented">>,
+                  _attrs, _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org,
-                           decode_vcard_BDAY(_el), Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_feature_not_implemented(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"JABBERID">>, _attrs, _} =
+decode_error_els([{xmlel, <<"forbidden">>, _attrs, _} =
                      _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid,
-                           decode_vcard_JABBERID(_el), Sound, Note, Role,
-                           Title, Nickname, Rev, Sort_string, Org, Bday, Key,
-                           Tz, Url, Email, Tel, Label, Fn, Version, N, Photo,
-                           Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_forbidden(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"MAILER">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"gone">>, _attrs, _} = _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, decode_vcard_MAILER(_el), Adr,
-                           Class, Categories, Desc, Uid, Agent, Prodid,
-                           Jabberid, Sound, Note, Role, Title, Nickname, Rev,
-                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text, decode_error_gone(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"TZ">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"internal-server-error">>,
+                  _attrs, _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, decode_vcard_TZ(_el), Url, Email, Tel, Label,
-                           Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_internal_server_error(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"TITLE">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"item-not-found">>, _attrs,
+                  _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, decode_vcard_TITLE(_el), Nickname, Rev,
-                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_item_not_found(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"ROLE">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"jid-malformed">>, _attrs,
+                  _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           decode_vcard_ROLE(_el), Title, Nickname, Rev,
-                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_jid_malformed(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"NOTE">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"not-acceptable">>, _attrs,
+                  _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound,
-                           decode_vcard_NOTE(_el), Role, Title, Nickname, Rev,
-                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_not_acceptable(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"PRODID">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"not-allowed">>, _attrs,
+                  _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, decode_vcard_PRODID(_el),
-                           Jabberid, Sound, Note, Role, Title, Nickname, Rev,
-                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_not_allowed(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"REV">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"not-authorized">>, _attrs,
+                  _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, decode_vcard_REV(_el),
-                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_not_authorized(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"AGENT">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"policy-violation">>,
+                  _attrs, _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, decode_vcard_AGENT(_el), Prodid,
-                           Jabberid, Sound, Note, Role, Title, Nickname, Rev,
-                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_policy_violation(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"SORT-STRING">>, _attrs,
-                  _} =
+decode_error_els([{xmlel, <<"recipient-unavailable">>,
+                  _attrs, _} =
                      _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev,
-                           decode_vcard_SORT_STRING(_el), Org, Bday, Key, Tz,
-                           Url, Email, Tel, Label, Fn, Version, N, Photo, Logo,
-                           Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_recipient_unavailable(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"UID">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"redirect">>, _attrs, _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, decode_vcard_UID(_el), Agent, Prodid,
-                           Jabberid, Sound, Note, Role, Title, Nickname, Rev,
-                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_redirect(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"URL">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"registration-required">>,
+                  _attrs, _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, decode_vcard_URL(_el), Email, Tel, Label,
-                           Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_registration_required(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"DESC">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"remote-server-not-found">>,
+                  _attrs, _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           decode_vcard_DESC(_el), Uid, Agent, Prodid,
-                           Jabberid, Sound, Note, Role, Title, Nickname, Rev,
-                           Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                           Label, Fn, Version, N, Photo, Logo, Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_remote_server_not_found(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"CATEGORIES">>, _attrs, _} =
+decode_error_els([{xmlel, <<"remote-server-timeout">>,
+                  _attrs, _} =
                      _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr, Class,
-                           decode_vcard_CATEGORIES(_el), Desc, Uid, Agent,
-                           Prodid, Jabberid, Sound, Note, Role, Title,
-                           Nickname, Rev, Sort_string, Org, Bday, Key, Tz, Url,
-                           Email, Tel, Label, Fn, Version, N, Photo, Logo,
-                           Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_remote_server_timeout(_el));
+       true -> decode_error_els(_els, Text, Reason)
     end;
-decode_vcard_els([{xmlel, <<"CLASS">>, _attrs, _} = _el
+decode_error_els([{xmlel, <<"resource-constraint">>,
+                  _attrs, _} =
+                     _el
                  | _els],
-                Mailer, Adr, Class, Categories, Desc, Uid, Agent,
-                Prodid, Jabberid, Sound, Note, Role, Title, Nickname,
-                Rev, Sort_string, Org, Bday, Key, Tz, Url, Email, Tel,
-                Label, Fn, Version, N, Photo, Logo, Geo) ->
+                Text, Reason) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"vcard-temp">> ->
-          decode_vcard_els(_els, Mailer, Adr,
-                           decode_vcard_CLASS(_el), Categories, Desc, Uid,
-                           Agent, Prodid, Jabberid, Sound, Note, Role, Title,
-                           Nickname, Rev, Sort_string, Org, Bday, Key, Tz, Url,
-                           Email, Tel, Label, Fn, Version, N, Photo, Logo,
-                           Geo);
-       true ->
-          decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                           Desc, Uid, Agent, Prodid, Jabberid, Sound, Note,
-                           Role, Title, Nickname, Rev, Sort_string, Org, Bday,
-                           Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                           Photo, Logo, Geo)
-    end;
-decode_vcard_els([_ | _els], Mailer, Adr, Class,
-                Categories, Desc, Uid, Agent, Prodid, Jabberid, Sound,
-                Note, Role, Title, Nickname, Rev, Sort_string, Org,
-                Bday, Key, Tz, Url, Email, Tel, Label, Fn, Version, N,
-                Photo, Logo, Geo) ->
-    decode_vcard_els(_els, Mailer, Adr, Class, Categories,
-                    Desc, Uid, Agent, Prodid, Jabberid, Sound, Note, Role,
-                    Title, Nickname, Rev, Sort_string, Org, Bday, Key, Tz,
-                    Url, Email, Tel, Label, Fn, Version, N, Photo, Logo,
-                    Geo).
-
-encode_vcard({vcard, Version, Fn, N, Nickname, Photo,
-             Bday, Adr, Label, Tel, Email, Jabberid, Mailer, Tz, Geo,
-             Title, Role, Logo, Org, Categories, Note, Prodid, Agent,
-             Rev, Sort_string, Sound, Uid, Url, Class, Key, Desc},
-            _xmlns_attrs) ->
-    _els = 'encode_vcard_$geo'(Geo,
-                              'encode_vcard_$logo'(Logo,
-                                                   'encode_vcard_$photo'(Photo,
-                                                                         'encode_vcard_$n'(N,
-                                                                                           'encode_vcard_$version'(Version,
-                                                                                                                   'encode_vcard_$fn'(Fn,
-                                                                                                                                      'encode_vcard_$label'(Label,
-                                                                                                                                                            'encode_vcard_$tel'(Tel,
-                                                                                                                                                                                'encode_vcard_$email'(Email,
-                                                                                                                                                                                                      'encode_vcard_$url'(Url,
-                                                                                                                                                                                                                          'encode_vcard_$tz'(Tz,
-                                                                                                                                                                                                                                             'encode_vcard_$key'(Key,
-                                                                                                                                                                                                                                                                 'encode_vcard_$bday'(Bday,
-                                                                                                                                                                                                                                                                                      'encode_vcard_$org'(Org,
-                                                                                                                                                                                                                                                                                                          'encode_vcard_$sort_string'(Sort_string,
-                                                                                                                                                                                                                                                                                                                                      'encode_vcard_$rev'(Rev,
-                                                                                                                                                                                                                                                                                                                                                          'encode_vcard_$nickname'(Nickname,
-                                                                                                                                                                                                                                                                                                                                                                                   'encode_vcard_$title'(Title,
-                                                                                                                                                                                                                                                                                                                                                                                                         'encode_vcard_$role'(Role,
-                                                                                                                                                                                                                                                                                                                                                                                                                              'encode_vcard_$note'(Note,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                   'encode_vcard_$sound'(Sound,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                         'encode_vcard_$jabberid'(Jabberid,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  'encode_vcard_$prodid'(Prodid,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         'encode_vcard_$agent'(Agent,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               'encode_vcard_$uid'(Uid,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   'encode_vcard_$desc'(Desc,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        'encode_vcard_$categories'(Categories,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   'encode_vcard_$class'(Class,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         'encode_vcard_$adr'(Adr,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             'encode_vcard_$mailer'(Mailer,
-                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    [])))))))))))))))))))))))))))))),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"vCard">>, _attrs, _els}.
-
-'encode_vcard_$mailer'(undefined, _acc) -> _acc;
-'encode_vcard_$mailer'(Mailer, _acc) ->
-    [encode_vcard_MAILER(Mailer, []) | _acc].
-
-'encode_vcard_$adr'([], _acc) -> _acc;
-'encode_vcard_$adr'([Adr | _els], _acc) ->
-    'encode_vcard_$adr'(_els,
-                       [encode_vcard_ADR(Adr, []) | _acc]).
-
-'encode_vcard_$class'(undefined, _acc) -> _acc;
-'encode_vcard_$class'(Class, _acc) ->
-    [encode_vcard_CLASS(Class, []) | _acc].
-
-'encode_vcard_$categories'([], _acc) -> _acc;
-'encode_vcard_$categories'(Categories, _acc) ->
-    [encode_vcard_CATEGORIES(Categories, []) | _acc].
-
-'encode_vcard_$desc'(undefined, _acc) -> _acc;
-'encode_vcard_$desc'(Desc, _acc) ->
-    [encode_vcard_DESC(Desc, []) | _acc].
-
-'encode_vcard_$uid'(undefined, _acc) -> _acc;
-'encode_vcard_$uid'(Uid, _acc) ->
-    [encode_vcard_UID(Uid, []) | _acc].
-
-'encode_vcard_$agent'(undefined, _acc) -> _acc;
-'encode_vcard_$agent'(Agent, _acc) ->
-    [encode_vcard_AGENT(Agent, []) | _acc].
-
-'encode_vcard_$prodid'(undefined, _acc) -> _acc;
-'encode_vcard_$prodid'(Prodid, _acc) ->
-    [encode_vcard_PRODID(Prodid, []) | _acc].
-
-'encode_vcard_$jabberid'(undefined, _acc) -> _acc;
-'encode_vcard_$jabberid'(Jabberid, _acc) ->
-    [encode_vcard_JABBERID(Jabberid, []) | _acc].
-
-'encode_vcard_$sound'(undefined, _acc) -> _acc;
-'encode_vcard_$sound'(Sound, _acc) ->
-    [encode_vcard_SOUND(Sound, []) | _acc].
-
-'encode_vcard_$note'(undefined, _acc) -> _acc;
-'encode_vcard_$note'(Note, _acc) ->
-    [encode_vcard_NOTE(Note, []) | _acc].
-
-'encode_vcard_$role'(undefined, _acc) -> _acc;
-'encode_vcard_$role'(Role, _acc) ->
-    [encode_vcard_ROLE(Role, []) | _acc].
-
-'encode_vcard_$title'(undefined, _acc) -> _acc;
-'encode_vcard_$title'(Title, _acc) ->
-    [encode_vcard_TITLE(Title, []) | _acc].
-
-'encode_vcard_$nickname'(undefined, _acc) -> _acc;
-'encode_vcard_$nickname'(Nickname, _acc) ->
-    [encode_vcard_NICKNAME(Nickname, []) | _acc].
-
-'encode_vcard_$rev'(undefined, _acc) -> _acc;
-'encode_vcard_$rev'(Rev, _acc) ->
-    [encode_vcard_REV(Rev, []) | _acc].
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_resource_constraint(_el));
+       true -> decode_error_els(_els, Text, Reason)
+    end;
+decode_error_els([{xmlel, <<"service-unavailable">>,
+                  _attrs, _} =
+                     _el
+                 | _els],
+                Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_service_unavailable(_el));
+       true -> decode_error_els(_els, Text, Reason)
+    end;
+decode_error_els([{xmlel, <<"subscription-required">>,
+                  _attrs, _} =
+                     _el
+                 | _els],
+                Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_subscription_required(_el));
+       true -> decode_error_els(_els, Text, Reason)
+    end;
+decode_error_els([{xmlel, <<"undefined-condition">>,
+                  _attrs, _} =
+                     _el
+                 | _els],
+                Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_undefined_condition(_el));
+       true -> decode_error_els(_els, Text, Reason)
+    end;
+decode_error_els([{xmlel, <<"unexpected-request">>,
+                  _attrs, _} =
+                     _el
+                 | _els],
+                Text, Reason) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns ==
+        <<"urn:ietf:params:xml:ns:xmpp-stanzas">> ->
+          decode_error_els(_els, Text,
+                           decode_error_unexpected_request(_el));
+       true -> decode_error_els(_els, Text, Reason)
+    end;
+decode_error_els([_ | _els], Text, Reason) ->
+    decode_error_els(_els, Text, Reason).
 
-'encode_vcard_$sort_string'(undefined, _acc) -> _acc;
-'encode_vcard_$sort_string'(Sort_string, _acc) ->
-    [encode_vcard_SORT_STRING(Sort_string, []) | _acc].
+decode_error_attrs([{<<"type">>, _val} | _attrs], _Type,
+                  By) ->
+    decode_error_attrs(_attrs, _val, By);
+decode_error_attrs([{<<"by">>, _val} | _attrs], Type,
+                  _By) ->
+    decode_error_attrs(_attrs, Type, _val);
+decode_error_attrs([_ | _attrs], Type, By) ->
+    decode_error_attrs(_attrs, Type, By);
+decode_error_attrs([], Type, By) ->
+    {decode_error_attr_type(Type),
+     decode_error_attr_by(By)}.
 
-'encode_vcard_$org'(undefined, _acc) -> _acc;
-'encode_vcard_$org'(Org, _acc) ->
-    [encode_vcard_ORG(Org, []) | _acc].
+encode_error({error, Type, By, Reason, Text},
+            _xmlns_attrs) ->
+    _els = 'encode_error_$reason'(Reason,
+                                 'encode_error_$text'(Text, [])),
+    _attrs = encode_error_attr_by(By,
+                                 encode_error_attr_type(Type, _xmlns_attrs)),
+    {xmlel, <<"error">>, _attrs, _els}.
 
-'encode_vcard_$bday'(undefined, _acc) -> _acc;
-'encode_vcard_$bday'(Bday, _acc) ->
-    [encode_vcard_BDAY(Bday, []) | _acc].
+'encode_error_$text'(undefined, _acc) -> _acc;
+'encode_error_$text'(Text, _acc) ->
+    [encode_error_text(Text,
+                      [{<<"xmlns">>,
+                        <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc].
 
-'encode_vcard_$key'(undefined, _acc) -> _acc;
-'encode_vcard_$key'(Key, _acc) ->
-    [encode_vcard_KEY(Key, []) | _acc].
+'encode_error_$reason'(undefined, _acc) -> _acc;
+'encode_error_$reason'('bad-request' = Reason, _acc) ->
+    [encode_error_bad_request(Reason,
+                             [{<<"xmlns">>,
+                               <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'(conflict = Reason, _acc) ->
+    [encode_error_conflict(Reason,
+                          [{<<"xmlns">>,
+                            <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('feature-not-implemented' =
+                          Reason,
+                      _acc) ->
+    [encode_error_feature_not_implemented(Reason,
+                                         [{<<"xmlns">>,
+                                           <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'(forbidden = Reason, _acc) ->
+    [encode_error_forbidden(Reason,
+                           [{<<"xmlns">>,
+                             <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'({gone, _} = Reason, _acc) ->
+    [encode_error_gone(Reason,
+                      [{<<"xmlns">>,
+                        <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('internal-server-error' = Reason,
+                      _acc) ->
+    [encode_error_internal_server_error(Reason,
+                                       [{<<"xmlns">>,
+                                         <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('item-not-found' = Reason,
+                      _acc) ->
+    [encode_error_item_not_found(Reason,
+                                [{<<"xmlns">>,
+                                  <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('jid-malformed' = Reason,
+                      _acc) ->
+    [encode_error_jid_malformed(Reason,
+                               [{<<"xmlns">>,
+                                 <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('not-acceptable' = Reason,
+                      _acc) ->
+    [encode_error_not_acceptable(Reason,
+                                [{<<"xmlns">>,
+                                  <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('not-allowed' = Reason, _acc) ->
+    [encode_error_not_allowed(Reason,
+                             [{<<"xmlns">>,
+                               <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('not-authorized' = Reason,
+                      _acc) ->
+    [encode_error_not_authorized(Reason,
+                                [{<<"xmlns">>,
+                                  <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('policy-violation' = Reason,
+                      _acc) ->
+    [encode_error_policy_violation(Reason,
+                                  [{<<"xmlns">>,
+                                    <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('recipient-unavailable' = Reason,
+                      _acc) ->
+    [encode_error_recipient_unavailable(Reason,
+                                       [{<<"xmlns">>,
+                                         <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'({redirect, _} = Reason, _acc) ->
+    [encode_error_redirect(Reason,
+                          [{<<"xmlns">>,
+                            <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('registration-required' = Reason,
+                      _acc) ->
+    [encode_error_registration_required(Reason,
+                                       [{<<"xmlns">>,
+                                         <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('remote-server-not-found' =
+                          Reason,
+                      _acc) ->
+    [encode_error_remote_server_not_found(Reason,
+                                         [{<<"xmlns">>,
+                                           <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('remote-server-timeout' = Reason,
+                      _acc) ->
+    [encode_error_remote_server_timeout(Reason,
+                                       [{<<"xmlns">>,
+                                         <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('resource-constraint' = Reason,
+                      _acc) ->
+    [encode_error_resource_constraint(Reason,
+                                     [{<<"xmlns">>,
+                                       <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('service-unavailable' = Reason,
+                      _acc) ->
+    [encode_error_service_unavailable(Reason,
+                                     [{<<"xmlns">>,
+                                       <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('subscription-required' = Reason,
+                      _acc) ->
+    [encode_error_subscription_required(Reason,
+                                       [{<<"xmlns">>,
+                                         <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('undefined-condition' = Reason,
+                      _acc) ->
+    [encode_error_undefined_condition(Reason,
+                                     [{<<"xmlns">>,
+                                       <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc];
+'encode_error_$reason'('unexpected-request' = Reason,
+                      _acc) ->
+    [encode_error_unexpected_request(Reason,
+                                    [{<<"xmlns">>,
+                                      <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}])
+     | _acc].
 
-'encode_vcard_$tz'(undefined, _acc) -> _acc;
-'encode_vcard_$tz'(Tz, _acc) ->
-    [encode_vcard_TZ(Tz, []) | _acc].
+decode_error_attr_type(undefined) ->
+    erlang:error({missing_attr, <<"type">>, <<"error">>,
+                 <<"jabber:client">>});
+decode_error_attr_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [auth, cancel, continue, modify, wait])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"type">>, <<"error">>,
+                       <<"jabber:client">>});
+      _res -> _res
+    end.
 
-'encode_vcard_$url'(undefined, _acc) -> _acc;
-'encode_vcard_$url'(Url, _acc) ->
-    [encode_vcard_URL(Url, []) | _acc].
+encode_error_attr_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
 
-'encode_vcard_$email'([], _acc) -> _acc;
-'encode_vcard_$email'([Email | _els], _acc) ->
-    'encode_vcard_$email'(_els,
-                         [encode_vcard_EMAIL(Email, []) | _acc]).
+decode_error_attr_by(undefined) -> undefined;
+decode_error_attr_by(_val) -> _val.
 
-'encode_vcard_$tel'([], _acc) -> _acc;
-'encode_vcard_$tel'([Tel | _els], _acc) ->
-    'encode_vcard_$tel'(_els,
-                       [encode_vcard_TEL(Tel, []) | _acc]).
+encode_error_attr_by(undefined, _acc) -> _acc;
+encode_error_attr_by(_val, _acc) ->
+    [{<<"by">>, _val} | _acc].
 
-'encode_vcard_$label'([], _acc) -> _acc;
-'encode_vcard_$label'([Label | _els], _acc) ->
-    'encode_vcard_$label'(_els,
-                         [encode_vcard_LABEL(Label, []) | _acc]).
+decode_error_text({xmlel, <<"text">>, _attrs, _els}) ->
+    Data = decode_error_text_els(_els, <<>>),
+    Lang = decode_error_text_attrs(_attrs, undefined),
+    {text, Lang, Data}.
 
-'encode_vcard_$fn'(undefined, _acc) -> _acc;
-'encode_vcard_$fn'(Fn, _acc) ->
-    [encode_vcard_FN(Fn, []) | _acc].
+decode_error_text_els([], Data) ->
+    decode_error_text_cdata(Data);
+decode_error_text_els([{xmlcdata, _data} | _els],
+                     Data) ->
+    decode_error_text_els(_els,
+                         <<Data/binary, _data/binary>>);
+decode_error_text_els([_ | _els], Data) ->
+    decode_error_text_els(_els, Data).
 
-'encode_vcard_$version'(undefined, _acc) -> _acc;
-'encode_vcard_$version'(Version, _acc) ->
-    [encode_vcard_VERSION(Version, []) | _acc].
+decode_error_text_attrs([{<<"xml:lang">>, _val}
+                        | _attrs],
+                       _Lang) ->
+    decode_error_text_attrs(_attrs, _val);
+decode_error_text_attrs([_ | _attrs], Lang) ->
+    decode_error_text_attrs(_attrs, Lang);
+decode_error_text_attrs([], Lang) ->
+    'decode_error_text_attr_xml:lang'(Lang).
 
-'encode_vcard_$n'(undefined, _acc) -> _acc;
-'encode_vcard_$n'(N, _acc) ->
-    [encode_vcard_N(N, []) | _acc].
+encode_error_text({text, Lang, Data}, _xmlns_attrs) ->
+    _els = encode_error_text_cdata(Data, []),
+    _attrs = 'encode_error_text_attr_xml:lang'(Lang,
+                                              _xmlns_attrs),
+    {xmlel, <<"text">>, _attrs, _els}.
 
-'encode_vcard_$photo'(undefined, _acc) -> _acc;
-'encode_vcard_$photo'(Photo, _acc) ->
-    [encode_vcard_PHOTO(Photo, []) | _acc].
+'decode_error_text_attr_xml:lang'(undefined) ->
+    undefined;
+'decode_error_text_attr_xml:lang'(_val) -> _val.
 
-'encode_vcard_$logo'(undefined, _acc) -> _acc;
-'encode_vcard_$logo'(Logo, _acc) ->
-    [encode_vcard_LOGO(Logo, []) | _acc].
+'encode_error_text_attr_xml:lang'(undefined, _acc) ->
+    _acc;
+'encode_error_text_attr_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
 
-'encode_vcard_$geo'(undefined, _acc) -> _acc;
-'encode_vcard_$geo'(Geo, _acc) ->
-    [encode_vcard_GEO(Geo, []) | _acc].
+decode_error_text_cdata(<<>>) -> undefined;
+decode_error_text_cdata(_val) -> _val.
 
-decode_xdata_field_required({xmlel, <<"required">>,
-                            _attrs, _els}) ->
-    true.
+encode_error_text_cdata(undefined, _acc) -> _acc;
+encode_error_text_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-encode_xdata_field_required(true, _xmlns_attrs) ->
+decode_error_unexpected_request({xmlel,
+                                <<"unexpected-request">>, _attrs, _els}) ->
+    'unexpected-request'.
+
+encode_error_unexpected_request('unexpected-request',
+                               _xmlns_attrs) ->
     _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"required">>, _attrs, _els}.
-
-decode_xdata_field_desc({xmlel, <<"desc">>, _attrs,
-                        _els}) ->
-    Cdata = decode_xdata_field_desc_els(_els, <<>>), Cdata.
+    {xmlel, <<"unexpected-request">>, _attrs, _els}.
 
-decode_xdata_field_desc_els([], Cdata) ->
-    decode_xdata_field_desc_cdata(Cdata);
-decode_xdata_field_desc_els([{xmlcdata, _data} | _els],
-                           Cdata) ->
-    decode_xdata_field_desc_els(_els,
-                               <<Cdata/binary, _data/binary>>);
-decode_xdata_field_desc_els([_ | _els], Cdata) ->
-    decode_xdata_field_desc_els(_els, Cdata).
+decode_error_undefined_condition({xmlel,
+                                 <<"undefined-condition">>, _attrs, _els}) ->
+    'undefined-condition'.
 
-encode_xdata_field_desc(Cdata, _xmlns_attrs) ->
-    _els = encode_xdata_field_desc_cdata(Cdata, []),
+encode_error_undefined_condition('undefined-condition',
+                                _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"desc">>, _attrs, _els}.
-
-decode_xdata_field_desc_cdata(<<>>) -> undefined;
-decode_xdata_field_desc_cdata(_val) -> _val.
+    {xmlel, <<"undefined-condition">>, _attrs, _els}.
 
-encode_xdata_field_desc_cdata(undefined, _acc) -> _acc;
-encode_xdata_field_desc_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_error_subscription_required({xmlel,
+                                   <<"subscription-required">>, _attrs,
+                                   _els}) ->
+    'subscription-required'.
 
-decode_xdata_field_value({xmlel, <<"value">>, _attrs,
-                         _els}) ->
-    Cdata = decode_xdata_field_value_els(_els, <<>>), Cdata.
+encode_error_subscription_required('subscription-required',
+                                  _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"subscription-required">>, _attrs, _els}.
 
-decode_xdata_field_value_els([], Cdata) ->
-    decode_xdata_field_value_cdata(Cdata);
-decode_xdata_field_value_els([{xmlcdata, _data} | _els],
-                            Cdata) ->
-    decode_xdata_field_value_els(_els,
-                                <<Cdata/binary, _data/binary>>);
-decode_xdata_field_value_els([_ | _els], Cdata) ->
-    decode_xdata_field_value_els(_els, Cdata).
+decode_error_service_unavailable({xmlel,
+                                 <<"service-unavailable">>, _attrs, _els}) ->
+    'service-unavailable'.
 
-encode_xdata_field_value(Cdata, _xmlns_attrs) ->
-    _els = encode_xdata_field_value_cdata(Cdata, []),
+encode_error_service_unavailable('service-unavailable',
+                                _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"value">>, _attrs, _els}.
-
-decode_xdata_field_value_cdata(<<>>) -> undefined;
-decode_xdata_field_value_cdata(_val) -> _val.
+    {xmlel, <<"service-unavailable">>, _attrs, _els}.
 
-encode_xdata_field_value_cdata(undefined, _acc) -> _acc;
-encode_xdata_field_value_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_error_resource_constraint({xmlel,
+                                 <<"resource-constraint">>, _attrs, _els}) ->
+    'resource-constraint'.
 
-decode_xdata_field_option({xmlel, <<"option">>, _attrs,
-                          _els}) ->
-    Value = decode_xdata_field_option_els(_els, []), Value.
+encode_error_resource_constraint('resource-constraint',
+                                _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"resource-constraint">>, _attrs, _els}.
 
-decode_xdata_field_option_els([], [Value]) -> Value;
-decode_xdata_field_option_els([{xmlel, <<"value">>,
-                               _attrs, _} =
-                                  _el
-                              | _els],
-                             Value) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_field_option_els(_els,
-                                        case decode_xdata_field_value(_el) of
-                                          undefined -> Value;
-                                          _new_el -> [_new_el | Value]
-                                        end);
-       true -> decode_xdata_field_option_els(_els, Value)
-    end;
-decode_xdata_field_option_els([_ | _els], Value) ->
-    decode_xdata_field_option_els(_els, Value).
+decode_error_remote_server_timeout({xmlel,
+                                   <<"remote-server-timeout">>, _attrs,
+                                   _els}) ->
+    'remote-server-timeout'.
 
-encode_xdata_field_option(Value, _xmlns_attrs) ->
-    _els = 'encode_xdata_field_option_$value'(Value, []),
+encode_error_remote_server_timeout('remote-server-timeout',
+                                  _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"option">>, _attrs, _els}.
+    {xmlel, <<"remote-server-timeout">>, _attrs, _els}.
 
-'encode_xdata_field_option_$value'(Value, _acc) ->
-    [encode_xdata_field_value(Value, []) | _acc].
+decode_error_remote_server_not_found({xmlel,
+                                     <<"remote-server-not-found">>, _attrs,
+                                     _els}) ->
+    'remote-server-not-found'.
 
-decode_xdata_field({xmlel, <<"field">>, _attrs,
-                   _els}) ->
-    {Options, Values, Desc, Required} =
-       decode_xdata_field_els(_els, [], [], undefined, false),
-    {Label, Type, Var} = decode_xdata_field_attrs(_attrs,
-                                                 undefined, undefined,
-                                                 undefined),
-    {xdata_field, Label, Type, Var, Required, Desc, Values,
-     Options}.
+encode_error_remote_server_not_found('remote-server-not-found',
+                                    _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"remote-server-not-found">>, _attrs, _els}.
 
-decode_xdata_field_els([], Options, Values, Desc,
-                      Required) ->
-    {lists:reverse(Options), lists:reverse(Values), Desc,
-     Required};
-decode_xdata_field_els([{xmlel, <<"required">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Options, Values, Desc, Required) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_field_els(_els, Options, Values, Desc,
-                                 decode_xdata_field_required(_el));
-       true ->
-          decode_xdata_field_els(_els, Options, Values, Desc,
-                                 Required)
-    end;
-decode_xdata_field_els([{xmlel, <<"desc">>, _attrs, _} =
-                           _el
-                       | _els],
-                      Options, Values, Desc, Required) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_field_els(_els, Options, Values,
-                                 decode_xdata_field_desc(_el), Required);
-       true ->
-          decode_xdata_field_els(_els, Options, Values, Desc,
-                                 Required)
-    end;
-decode_xdata_field_els([{xmlel, <<"value">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Options, Values, Desc, Required) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_field_els(_els, Options,
-                                 case decode_xdata_field_value(_el) of
-                                   undefined -> Values;
-                                   _new_el -> [_new_el | Values]
-                                 end,
-                                 Desc, Required);
-       true ->
-          decode_xdata_field_els(_els, Options, Values, Desc,
-                                 Required)
-    end;
-decode_xdata_field_els([{xmlel, <<"option">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Options, Values, Desc, Required) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_field_els(_els,
-                                 case decode_xdata_field_option(_el) of
-                                   undefined -> Options;
-                                   _new_el -> [_new_el | Options]
-                                 end,
-                                 Values, Desc, Required);
-       true ->
-          decode_xdata_field_els(_els, Options, Values, Desc,
-                                 Required)
-    end;
-decode_xdata_field_els([_ | _els], Options, Values,
-                      Desc, Required) ->
-    decode_xdata_field_els(_els, Options, Values, Desc,
-                          Required).
+decode_error_registration_required({xmlel,
+                                   <<"registration-required">>, _attrs,
+                                   _els}) ->
+    'registration-required'.
 
-decode_xdata_field_attrs([{<<"label">>, _val} | _attrs],
-                        _Label, Type, Var) ->
-    decode_xdata_field_attrs(_attrs, _val, Type, Var);
-decode_xdata_field_attrs([{<<"type">>, _val} | _attrs],
-                        Label, _Type, Var) ->
-    decode_xdata_field_attrs(_attrs, Label, _val, Var);
-decode_xdata_field_attrs([{<<"var">>, _val} | _attrs],
-                        Label, Type, _Var) ->
-    decode_xdata_field_attrs(_attrs, Label, Type, _val);
-decode_xdata_field_attrs([_ | _attrs], Label, Type,
-                        Var) ->
-    decode_xdata_field_attrs(_attrs, Label, Type, Var);
-decode_xdata_field_attrs([], Label, Type, Var) ->
-    {decode_xdata_field_attr_label(Label),
-     decode_xdata_field_attr_type(Type),
-     decode_xdata_field_attr_var(Var)}.
+encode_error_registration_required('registration-required',
+                                  _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"registration-required">>, _attrs, _els}.
 
-encode_xdata_field({xdata_field, Label, Type, Var,
-                   Required, Desc, Values, Options},
-                  _xmlns_attrs) ->
-    _els = 'encode_xdata_field_$required'(Required,
-                                         'encode_xdata_field_$desc'(Desc,
-                                                                    'encode_xdata_field_$values'(Values,
-                                                                                                 'encode_xdata_field_$options'(Options,
-                                                                                                                               [])))),
-    _attrs = encode_xdata_field_attr_var(Var,
-                                        encode_xdata_field_attr_type(Type,
-                                                                     encode_xdata_field_attr_label(Label,
-                                                                                                   _xmlns_attrs))),
-    {xmlel, <<"field">>, _attrs, _els}.
+decode_error_redirect({xmlel, <<"redirect">>, _attrs,
+                      _els}) ->
+    Uri = decode_error_redirect_els(_els, <<>>),
+    {redirect, Uri}.
 
-'encode_xdata_field_$options'([], _acc) -> _acc;
-'encode_xdata_field_$options'([Options | _els], _acc) ->
-    'encode_xdata_field_$options'(_els,
-                                 [encode_xdata_field_option(Options, [])
-                                  | _acc]).
+decode_error_redirect_els([], Uri) ->
+    decode_error_redirect_cdata(Uri);
+decode_error_redirect_els([{xmlcdata, _data} | _els],
+                         Uri) ->
+    decode_error_redirect_els(_els,
+                             <<Uri/binary, _data/binary>>);
+decode_error_redirect_els([_ | _els], Uri) ->
+    decode_error_redirect_els(_els, Uri).
 
-'encode_xdata_field_$values'([], _acc) -> _acc;
-'encode_xdata_field_$values'([Values | _els], _acc) ->
-    'encode_xdata_field_$values'(_els,
-                                [encode_xdata_field_value(Values, []) | _acc]).
+encode_error_redirect({redirect, Uri}, _xmlns_attrs) ->
+    _els = encode_error_redirect_cdata(Uri, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"redirect">>, _attrs, _els}.
 
-'encode_xdata_field_$desc'(undefined, _acc) -> _acc;
-'encode_xdata_field_$desc'(Desc, _acc) ->
-    [encode_xdata_field_desc(Desc, []) | _acc].
+decode_error_redirect_cdata(<<>>) -> undefined;
+decode_error_redirect_cdata(_val) -> _val.
 
-'encode_xdata_field_$required'(false, _acc) -> _acc;
-'encode_xdata_field_$required'(Required, _acc) ->
-    [encode_xdata_field_required(Required, []) | _acc].
+encode_error_redirect_cdata(undefined, _acc) -> _acc;
+encode_error_redirect_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_xdata_field_attr_label(undefined) -> undefined;
-decode_xdata_field_attr_label(_val) -> _val.
+decode_error_recipient_unavailable({xmlel,
+                                   <<"recipient-unavailable">>, _attrs,
+                                   _els}) ->
+    'recipient-unavailable'.
 
-encode_xdata_field_attr_label(undefined, _acc) -> _acc;
-encode_xdata_field_attr_label(_val, _acc) ->
-    [{<<"label">>, _val} | _acc].
+encode_error_recipient_unavailable('recipient-unavailable',
+                                  _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"recipient-unavailable">>, _attrs, _els}.
 
-decode_xdata_field_attr_type(undefined) -> undefined;
-decode_xdata_field_attr_type(_val) ->
-    case catch xml_gen:dec_enum(_val,
-                               [boolean, fixed, hidden, 'jid-multi',
-                                'jid-single', 'list-multi', 'list-single',
-                                'text-multi', 'text-private', 'text-single'])
-       of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"type">>, <<"field">>,
-                       <<"jabber:x:data">>});
-      _res -> _res
-    end.
+decode_error_policy_violation({xmlel,
+                              <<"policy-violation">>, _attrs, _els}) ->
+    'policy-violation'.
 
-encode_xdata_field_attr_type(undefined, _acc) -> _acc;
-encode_xdata_field_attr_type(_val, _acc) ->
-    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
+encode_error_policy_violation('policy-violation',
+                             _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"policy-violation">>, _attrs, _els}.
 
-decode_xdata_field_attr_var(undefined) -> undefined;
-decode_xdata_field_attr_var(_val) -> _val.
+decode_error_not_authorized({xmlel,
+                            <<"not-authorized">>, _attrs, _els}) ->
+    'not-authorized'.
 
-encode_xdata_field_attr_var(undefined, _acc) -> _acc;
-encode_xdata_field_attr_var(_val, _acc) ->
-    [{<<"var">>, _val} | _acc].
+encode_error_not_authorized('not-authorized',
+                           _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"not-authorized">>, _attrs, _els}.
 
-decode_xdata_instructions({xmlel, <<"instructions">>,
-                          _attrs, _els}) ->
-    Cdata = decode_xdata_instructions_els(_els, <<>>),
-    Cdata.
+decode_error_not_allowed({xmlel, <<"not-allowed">>,
+                         _attrs, _els}) ->
+    'not-allowed'.
 
-decode_xdata_instructions_els([], Cdata) ->
-    decode_xdata_instructions_cdata(Cdata);
-decode_xdata_instructions_els([{xmlcdata, _data}
-                              | _els],
-                             Cdata) ->
-    decode_xdata_instructions_els(_els,
-                                 <<Cdata/binary, _data/binary>>);
-decode_xdata_instructions_els([_ | _els], Cdata) ->
-    decode_xdata_instructions_els(_els, Cdata).
+encode_error_not_allowed('not-allowed', _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"not-allowed">>, _attrs, _els}.
 
-encode_xdata_instructions(Cdata, _xmlns_attrs) ->
-    _els = encode_xdata_instructions_cdata(Cdata, []),
+decode_error_not_acceptable({xmlel,
+                            <<"not-acceptable">>, _attrs, _els}) ->
+    'not-acceptable'.
+
+encode_error_not_acceptable('not-acceptable',
+                           _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"instructions">>, _attrs, _els}.
+    {xmlel, <<"not-acceptable">>, _attrs, _els}.
 
-decode_xdata_instructions_cdata(<<>>) -> undefined;
-decode_xdata_instructions_cdata(_val) -> _val.
+decode_error_jid_malformed({xmlel, <<"jid-malformed">>,
+                           _attrs, _els}) ->
+    'jid-malformed'.
 
-encode_xdata_instructions_cdata(undefined, _acc) ->
-    _acc;
-encode_xdata_instructions_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_error_jid_malformed('jid-malformed',
+                          _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"jid-malformed">>, _attrs, _els}.
 
-decode_xdata_title({xmlel, <<"title">>, _attrs,
-                   _els}) ->
-    Cdata = decode_xdata_title_els(_els, <<>>), Cdata.
+decode_error_item_not_found({xmlel,
+                            <<"item-not-found">>, _attrs, _els}) ->
+    'item-not-found'.
 
-decode_xdata_title_els([], Cdata) ->
-    decode_xdata_title_cdata(Cdata);
-decode_xdata_title_els([{xmlcdata, _data} | _els],
-                      Cdata) ->
-    decode_xdata_title_els(_els,
-                          <<Cdata/binary, _data/binary>>);
-decode_xdata_title_els([_ | _els], Cdata) ->
-    decode_xdata_title_els(_els, Cdata).
+encode_error_item_not_found('item-not-found',
+                           _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"item-not-found">>, _attrs, _els}.
 
-encode_xdata_title(Cdata, _xmlns_attrs) ->
-    _els = encode_xdata_title_cdata(Cdata, []),
+decode_error_internal_server_error({xmlel,
+                                   <<"internal-server-error">>, _attrs,
+                                   _els}) ->
+    'internal-server-error'.
+
+encode_error_internal_server_error('internal-server-error',
+                                  _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"title">>, _attrs, _els}.
+    {xmlel, <<"internal-server-error">>, _attrs, _els}.
 
-decode_xdata_title_cdata(<<>>) -> undefined;
-decode_xdata_title_cdata(_val) -> _val.
+decode_error_gone({xmlel, <<"gone">>, _attrs, _els}) ->
+    Uri = decode_error_gone_els(_els, <<>>), {gone, Uri}.
 
-encode_xdata_title_cdata(undefined, _acc) -> _acc;
-encode_xdata_title_cdata(_val, _acc) ->
+decode_error_gone_els([], Uri) ->
+    decode_error_gone_cdata(Uri);
+decode_error_gone_els([{xmlcdata, _data} | _els],
+                     Uri) ->
+    decode_error_gone_els(_els,
+                         <<Uri/binary, _data/binary>>);
+decode_error_gone_els([_ | _els], Uri) ->
+    decode_error_gone_els(_els, Uri).
+
+encode_error_gone({gone, Uri}, _xmlns_attrs) ->
+    _els = encode_error_gone_cdata(Uri, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"gone">>, _attrs, _els}.
+
+decode_error_gone_cdata(<<>>) -> undefined;
+decode_error_gone_cdata(_val) -> _val.
+
+encode_error_gone_cdata(undefined, _acc) -> _acc;
+encode_error_gone_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_xdata_reported({xmlel, <<"reported">>, _attrs,
-                      _els}) ->
-    Fields = decode_xdata_reported_els(_els, []), Fields.
+decode_error_forbidden({xmlel, <<"forbidden">>, _attrs,
+                       _els}) ->
+    forbidden.
 
-decode_xdata_reported_els([], Fields) ->
-    lists:reverse(Fields);
-decode_xdata_reported_els([{xmlel, <<"field">>, _attrs,
-                           _} =
-                              _el
-                          | _els],
-                         Fields) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_reported_els(_els,
-                                    case decode_xdata_field(_el) of
-                                      undefined -> Fields;
-                                      _new_el -> [_new_el | Fields]
-                                    end);
-       true -> decode_xdata_reported_els(_els, Fields)
-    end;
-decode_xdata_reported_els([_ | _els], Fields) ->
-    decode_xdata_reported_els(_els, Fields).
+encode_error_forbidden(forbidden, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"forbidden">>, _attrs, _els}.
+
+decode_error_feature_not_implemented({xmlel,
+                                     <<"feature-not-implemented">>, _attrs,
+                                     _els}) ->
+    'feature-not-implemented'.
 
-encode_xdata_reported(Fields, _xmlns_attrs) ->
-    _els = 'encode_xdata_reported_$fields'(Fields, []),
+encode_error_feature_not_implemented('feature-not-implemented',
+                                    _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"reported">>, _attrs, _els}.
+    {xmlel, <<"feature-not-implemented">>, _attrs, _els}.
 
-'encode_xdata_reported_$fields'([], _acc) -> _acc;
-'encode_xdata_reported_$fields'([Fields | _els],
-                               _acc) ->
-    'encode_xdata_reported_$fields'(_els,
-                                   [encode_xdata_field(Fields, []) | _acc]).
+decode_error_conflict({xmlel, <<"conflict">>, _attrs,
+                      _els}) ->
+    conflict.
 
-decode_xdata_item({xmlel, <<"item">>, _attrs, _els}) ->
-    Fields = decode_xdata_item_els(_els, []), Fields.
+encode_error_conflict(conflict, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"conflict">>, _attrs, _els}.
 
-decode_xdata_item_els([], Fields) ->
-    lists:reverse(Fields);
-decode_xdata_item_els([{xmlel, <<"field">>, _attrs, _} =
-                          _el
-                      | _els],
-                     Fields) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_item_els(_els,
-                                case decode_xdata_field(_el) of
-                                  undefined -> Fields;
-                                  _new_el -> [_new_el | Fields]
-                                end);
-       true -> decode_xdata_item_els(_els, Fields)
-    end;
-decode_xdata_item_els([_ | _els], Fields) ->
-    decode_xdata_item_els(_els, Fields).
+decode_error_bad_request({xmlel, <<"bad-request">>,
+                         _attrs, _els}) ->
+    'bad-request'.
 
-encode_xdata_item(Fields, _xmlns_attrs) ->
-    _els = 'encode_xdata_item_$fields'(Fields, []),
+encode_error_bad_request('bad-request', _xmlns_attrs) ->
+    _els = [],
     _attrs = _xmlns_attrs,
-    {xmlel, <<"item">>, _attrs, _els}.
-
-'encode_xdata_item_$fields'([], _acc) -> _acc;
-'encode_xdata_item_$fields'([Fields | _els], _acc) ->
-    'encode_xdata_item_$fields'(_els,
-                               [encode_xdata_field(Fields, []) | _acc]).
+    {xmlel, <<"bad-request">>, _attrs, _els}.
 
-decode_xdata({xmlel, <<"x">>, _attrs, _els}) ->
-    {Fields, Items, Instructions, Reported, Title} =
-       decode_xdata_els(_els, [], [], [], undefined,
-                        undefined),
-    Type = decode_xdata_attrs(_attrs, undefined),
-    {xdata, Type, Instructions, Title, Reported, Items,
-     Fields}.
+decode_presence({xmlel, <<"presence">>, _attrs,
+                _els}) ->
+    {Error, Status, Show, Priority, __Els} =
+       decode_presence_els(_els, undefined, [], undefined,
+                           undefined, []),
+    {Id, Type, From, To, Lang} =
+       decode_presence_attrs(_attrs, undefined, undefined,
+                             undefined, undefined, undefined),
+    {presence, Id, Type, Lang, From, To, Show, Status,
+     Priority, Error, __Els}.
 
-decode_xdata_els([], Fields, Items, Instructions,
-                Reported, Title) ->
-    {lists:reverse(Fields), lists:reverse(Items),
-     lists:reverse(Instructions), Reported, Title};
-decode_xdata_els([{xmlel, <<"instructions">>, _attrs,
-                  _} =
-                     _el
-                 | _els],
-                Fields, Items, Instructions, Reported, Title) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_els(_els, Fields, Items,
-                           case decode_xdata_instructions(_el) of
-                             undefined -> Instructions;
-                             _new_el -> [_new_el | Instructions]
-                           end,
-                           Reported, Title);
-       true ->
-          decode_xdata_els(_els, Fields, Items, Instructions,
-                           Reported, Title)
-    end;
-decode_xdata_els([{xmlel, <<"title">>, _attrs, _} = _el
-                 | _els],
-                Fields, Items, Instructions, Reported, Title) ->
+decode_presence_els([], Error, Status, Show, Priority,
+                   __Els) ->
+    {Error, lists:reverse(Status), Show, Priority,
+     lists:reverse(__Els)};
+decode_presence_els([{xmlel, <<"error">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Error, Status, Show, Priority, __Els) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_els(_els, Fields, Items, Instructions,
-                           Reported, decode_xdata_title(_el));
+    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
+          decode_presence_els(_els, decode_error(_el), Status,
+                              Show, Priority, __Els);
        true ->
-          decode_xdata_els(_els, Fields, Items, Instructions,
-                           Reported, Title)
+          decode_presence_els(_els, Error, Status, Show, Priority,
+                              __Els)
     end;
-decode_xdata_els([{xmlel, <<"reported">>, _attrs, _} =
-                     _el
-                 | _els],
-                Fields, Items, Instructions, Reported, Title) ->
+decode_presence_els([{xmlel, <<"show">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Error, Status, Show, Priority, __Els) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_els(_els, Fields, Items, Instructions,
-                           decode_xdata_reported(_el), Title);
+    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
+          decode_presence_els(_els, Error, Status,
+                              decode_presence_show(_el), Priority, __Els);
        true ->
-          decode_xdata_els(_els, Fields, Items, Instructions,
-                           Reported, Title)
+          decode_presence_els(_els, Error, Status, Show, Priority,
+                              __Els)
     end;
-decode_xdata_els([{xmlel, <<"item">>, _attrs, _} = _el
-                 | _els],
-                Fields, Items, Instructions, Reported, Title) ->
+decode_presence_els([{xmlel, <<"status">>, _attrs, _} =
+                        _el
+                    | _els],
+                   Error, Status, Show, Priority, __Els) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_els(_els, Fields,
-                           case decode_xdata_item(_el) of
-                             undefined -> Items;
-                             _new_el -> [_new_el | Items]
-                           end,
-                           Instructions, Reported, Title);
+    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
+          decode_presence_els(_els, Error,
+                              case decode_presence_status(_el) of
+                                undefined -> Status;
+                                _new_el -> [_new_el | Status]
+                              end,
+                              Show, Priority, __Els);
        true ->
-          decode_xdata_els(_els, Fields, Items, Instructions,
-                           Reported, Title)
+          decode_presence_els(_els, Error, Status, Show, Priority,
+                              __Els)
     end;
-decode_xdata_els([{xmlel, <<"field">>, _attrs, _} = _el
-                 | _els],
-                Fields, Items, Instructions, Reported, Title) ->
+decode_presence_els([{xmlel, <<"priority">>, _attrs,
+                     _} =
+                        _el
+                    | _els],
+                   Error, Status, Show, Priority, __Els) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>; _xmlns == <<"jabber:x:data">> ->
-          decode_xdata_els(_els,
-                           case decode_xdata_field(_el) of
-                             undefined -> Fields;
-                             _new_el -> [_new_el | Fields]
-                           end,
-                           Items, Instructions, Reported, Title);
+    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
+          decode_presence_els(_els, Error, Status, Show,
+                              decode_presence_priority(_el), __Els);
        true ->
-          decode_xdata_els(_els, Fields, Items, Instructions,
-                           Reported, Title)
+          decode_presence_els(_els, Error, Status, Show, Priority,
+                              __Els)
     end;
-decode_xdata_els([_ | _els], Fields, Items,
-                Instructions, Reported, Title) ->
-    decode_xdata_els(_els, Fields, Items, Instructions,
-                    Reported, Title).
+decode_presence_els([{xmlel, _, _, _} = _el | _els],
+                   Error, Status, Show, Priority, __Els) ->
+    decode_presence_els(_els, Error, Status, Show, Priority,
+                       [decode(_el) | __Els]);
+decode_presence_els([_ | _els], Error, Status, Show,
+                   Priority, __Els) ->
+    decode_presence_els(_els, Error, Status, Show, Priority,
+                       __Els).
 
-decode_xdata_attrs([{<<"type">>, _val} | _attrs],
-                  _Type) ->
-    decode_xdata_attrs(_attrs, _val);
-decode_xdata_attrs([_ | _attrs], Type) ->
-    decode_xdata_attrs(_attrs, Type);
-decode_xdata_attrs([], Type) ->
-    decode_xdata_attr_type(Type).
+decode_presence_attrs([{<<"id">>, _val} | _attrs], _Id,
+                     Type, From, To, Lang) ->
+    decode_presence_attrs(_attrs, _val, Type, From, To,
+                         Lang);
+decode_presence_attrs([{<<"type">>, _val} | _attrs], Id,
+                     _Type, From, To, Lang) ->
+    decode_presence_attrs(_attrs, Id, _val, From, To, Lang);
+decode_presence_attrs([{<<"from">>, _val} | _attrs], Id,
+                     Type, _From, To, Lang) ->
+    decode_presence_attrs(_attrs, Id, Type, _val, To, Lang);
+decode_presence_attrs([{<<"to">>, _val} | _attrs], Id,
+                     Type, From, _To, Lang) ->
+    decode_presence_attrs(_attrs, Id, Type, From, _val,
+                         Lang);
+decode_presence_attrs([{<<"xml:lang">>, _val} | _attrs],
+                     Id, Type, From, To, _Lang) ->
+    decode_presence_attrs(_attrs, Id, Type, From, To, _val);
+decode_presence_attrs([_ | _attrs], Id, Type, From, To,
+                     Lang) ->
+    decode_presence_attrs(_attrs, Id, Type, From, To, Lang);
+decode_presence_attrs([], Id, Type, From, To, Lang) ->
+    {decode_presence_attr_id(Id),
+     decode_presence_attr_type(Type),
+     decode_presence_attr_from(From),
+     decode_presence_attr_to(To),
+     'decode_presence_attr_xml:lang'(Lang)}.
 
-encode_xdata({xdata, Type, Instructions, Title,
-             Reported, Items, Fields},
-            _xmlns_attrs) ->
-    _els = 'encode_xdata_$title'(Title,
-                                'encode_xdata_$reported'(Reported,
-                                                         'encode_xdata_$instructions'(Instructions,
-                                                                                      'encode_xdata_$items'(Items,
-                                                                                                            'encode_xdata_$fields'(Fields,
-                                                                                                                                   []))))),
-    _attrs = encode_xdata_attr_type(Type, _xmlns_attrs),
-    {xmlel, <<"x">>, _attrs, _els}.
+encode_presence({presence, Id, Type, Lang, From, To,
+                Show, Status, Priority, Error, __Els},
+               _xmlns_attrs) ->
+    _els = 'encode_presence_$priority'(Priority,
+                                      'encode_presence_$show'(Show,
+                                                              'encode_presence_$status'(Status,
+                                                                                        'encode_presence_$error'(Error,
+                                                                                                                 [encode(_el)
+                                                                                                                  || _el
+                                                                                                                         <- __Els])))),
+    _attrs = 'encode_presence_attr_xml:lang'(Lang,
+                                            encode_presence_attr_to(To,
+                                                                    encode_presence_attr_from(From,
+                                                                                              encode_presence_attr_type(Type,
+                                                                                                                        encode_presence_attr_id(Id,
+                                                                                                                                                _xmlns_attrs))))),
+    {xmlel, <<"presence">>, _attrs, _els}.
 
-'encode_xdata_$fields'([], _acc) -> _acc;
-'encode_xdata_$fields'([Fields | _els], _acc) ->
-    'encode_xdata_$fields'(_els,
-                          [encode_xdata_field(Fields, []) | _acc]).
+'encode_presence_$error'(undefined, _acc) -> _acc;
+'encode_presence_$error'(Error, _acc) ->
+    [encode_error(Error, []) | _acc].
 
-'encode_xdata_$items'([], _acc) -> _acc;
-'encode_xdata_$items'([Items | _els], _acc) ->
-    'encode_xdata_$items'(_els,
-                         [encode_xdata_item(Items, []) | _acc]).
+'encode_presence_$status'([], _acc) -> _acc;
+'encode_presence_$status'([Status | _els], _acc) ->
+    'encode_presence_$status'(_els,
+                             [encode_presence_status(Status, []) | _acc]).
 
-'encode_xdata_$instructions'([], _acc) -> _acc;
-'encode_xdata_$instructions'([Instructions | _els],
-                            _acc) ->
-    'encode_xdata_$instructions'(_els,
-                                [encode_xdata_instructions(Instructions, [])
-                                 | _acc]).
+'encode_presence_$show'(undefined, _acc) -> _acc;
+'encode_presence_$show'(Show, _acc) ->
+    [encode_presence_show(Show, []) | _acc].
 
-'encode_xdata_$reported'(undefined, _acc) -> _acc;
-'encode_xdata_$reported'(Reported, _acc) ->
-    [encode_xdata_reported(Reported, []) | _acc].
+'encode_presence_$priority'(undefined, _acc) -> _acc;
+'encode_presence_$priority'(Priority, _acc) ->
+    [encode_presence_priority(Priority, []) | _acc].
 
-'encode_xdata_$title'(undefined, _acc) -> _acc;
-'encode_xdata_$title'(Title, _acc) ->
-    [encode_xdata_title(Title, []) | _acc].
+decode_presence_attr_id(undefined) -> undefined;
+decode_presence_attr_id(_val) -> _val.
 
-decode_xdata_attr_type(undefined) ->
-    erlang:error({missing_attr, <<"type">>, <<"x">>,
-                 <<"jabber:x:data">>});
-decode_xdata_attr_type(_val) ->
+encode_presence_attr_id(undefined, _acc) -> _acc;
+encode_presence_attr_id(_val, _acc) ->
+    [{<<"id">>, _val} | _acc].
+
+decode_presence_attr_type(undefined) -> undefined;
+decode_presence_attr_type(_val) ->
     case catch xml_gen:dec_enum(_val,
-                               [cancel, form, result, submit])
+                               [unavailable, subscribe, subscribed,
+                                unsubscribe, unsubscribed, probe, error])
        of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"type">>, <<"x">>,
-                       <<"jabber:x:data">>});
+         erlang:error({bad_attr_value, <<"type">>,
+                       <<"presence">>, <<"jabber:client">>});
       _res -> _res
     end.
 
-encode_xdata_attr_type(_val, _acc) ->
+encode_presence_attr_type(undefined, _acc) -> _acc;
+encode_presence_attr_type(_val, _acc) ->
     [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
 
-decode_pubsub_subscription({xmlel, <<"subscription">>,
-                           _attrs, _els}) ->
-    {Jid, Node, Subid, Type} =
-       decode_pubsub_subscription_attrs(_attrs, undefined,
-                                        undefined, undefined, undefined),
-    {pubsub_subscription, Jid, Node, Subid, Type}.
-
-decode_pubsub_subscription_attrs([{<<"jid">>, _val}
-                                 | _attrs],
-                                _Jid, Node, Subid, Type) ->
-    decode_pubsub_subscription_attrs(_attrs, _val, Node,
-                                    Subid, Type);
-decode_pubsub_subscription_attrs([{<<"node">>, _val}
-                                 | _attrs],
-                                Jid, _Node, Subid, Type) ->
-    decode_pubsub_subscription_attrs(_attrs, Jid, _val,
-                                    Subid, Type);
-decode_pubsub_subscription_attrs([{<<"subid">>, _val}
-                                 | _attrs],
-                                Jid, Node, _Subid, Type) ->
-    decode_pubsub_subscription_attrs(_attrs, Jid, Node,
-                                    _val, Type);
-decode_pubsub_subscription_attrs([{<<"subscription">>,
-                                  _val}
-                                 | _attrs],
-                                Jid, Node, Subid, _Type) ->
-    decode_pubsub_subscription_attrs(_attrs, Jid, Node,
-                                    Subid, _val);
-decode_pubsub_subscription_attrs([_ | _attrs], Jid,
-                                Node, Subid, Type) ->
-    decode_pubsub_subscription_attrs(_attrs, Jid, Node,
-                                    Subid, Type);
-decode_pubsub_subscription_attrs([], Jid, Node, Subid,
-                                Type) ->
-    {decode_pubsub_subscription_attr_jid(Jid),
-     decode_pubsub_subscription_attr_node(Node),
-     decode_pubsub_subscription_attr_subid(Subid),
-     decode_pubsub_subscription_attr_subscription(Type)}.
-
-encode_pubsub_subscription({pubsub_subscription, Jid,
-                           Node, Subid, Type},
-                          _xmlns_attrs) ->
-    _els = [],
-    _attrs =
-       encode_pubsub_subscription_attr_subscription(Type,
-                                                    encode_pubsub_subscription_attr_subid(Subid,
-                                                                                          encode_pubsub_subscription_attr_node(Node,
-                                                                                                                               encode_pubsub_subscription_attr_jid(Jid,
-                                                                                                                                                                   _xmlns_attrs)))),
-    {xmlel, <<"subscription">>, _attrs, _els}.
-
-decode_pubsub_subscription_attr_jid(undefined) ->
-    erlang:error({missing_attr, <<"jid">>,
-                 <<"subscription">>,
-                 <<"http://jabber.org/protocol/pubsub">>});
-decode_pubsub_subscription_attr_jid(_val) ->
+decode_presence_attr_from(undefined) -> undefined;
+decode_presence_attr_from(_val) ->
     case catch dec_jid(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"jid">>,
-                       <<"subscription">>,
-                       <<"http://jabber.org/protocol/pubsub">>});
+         erlang:error({bad_attr_value, <<"from">>,
+                       <<"presence">>, <<"jabber:client">>});
       _res -> _res
     end.
 
-encode_pubsub_subscription_attr_jid(_val, _acc) ->
-    [{<<"jid">>, enc_jid(_val)} | _acc].
-
-decode_pubsub_subscription_attr_node(undefined) ->
-    undefined;
-decode_pubsub_subscription_attr_node(_val) -> _val.
-
-encode_pubsub_subscription_attr_node(undefined, _acc) ->
-    _acc;
-encode_pubsub_subscription_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
-
-decode_pubsub_subscription_attr_subid(undefined) ->
-    undefined;
-decode_pubsub_subscription_attr_subid(_val) -> _val.
-
-encode_pubsub_subscription_attr_subid(undefined,
-                                     _acc) ->
-    _acc;
-encode_pubsub_subscription_attr_subid(_val, _acc) ->
-    [{<<"subid">>, _val} | _acc].
+encode_presence_attr_from(undefined, _acc) -> _acc;
+encode_presence_attr_from(_val, _acc) ->
+    [{<<"from">>, enc_jid(_val)} | _acc].
 
-decode_pubsub_subscription_attr_subscription(undefined) ->
-    undefined;
-decode_pubsub_subscription_attr_subscription(_val) ->
-    case catch xml_gen:dec_enum(_val,
-                               [none, pending, subscribed, unconfigured])
-       of
+decode_presence_attr_to(undefined) -> undefined;
+decode_presence_attr_to(_val) ->
+    case catch dec_jid(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"subscription">>,
-                       <<"subscription">>,
-                       <<"http://jabber.org/protocol/pubsub">>});
+         erlang:error({bad_attr_value, <<"to">>, <<"presence">>,
+                       <<"jabber:client">>});
       _res -> _res
     end.
 
-encode_pubsub_subscription_attr_subscription(undefined,
-                                            _acc) ->
-    _acc;
-encode_pubsub_subscription_attr_subscription(_val,
-                                            _acc) ->
-    [{<<"subscription">>, xml_gen:enc_enum(_val)} | _acc].
+encode_presence_attr_to(undefined, _acc) -> _acc;
+encode_presence_attr_to(_val, _acc) ->
+    [{<<"to">>, enc_jid(_val)} | _acc].
 
-decode_pubsub_affiliation({xmlel, <<"affiliation">>,
-                          _attrs, _els}) ->
-    {Node, Type} = decode_pubsub_affiliation_attrs(_attrs,
-                                                  undefined, undefined),
-    {pubsub_affiliation, Node, Type}.
+'decode_presence_attr_xml:lang'(undefined) -> undefined;
+'decode_presence_attr_xml:lang'(_val) -> _val.
 
-decode_pubsub_affiliation_attrs([{<<"node">>, _val}
-                                | _attrs],
-                               _Node, Type) ->
-    decode_pubsub_affiliation_attrs(_attrs, _val, Type);
-decode_pubsub_affiliation_attrs([{<<"affiliation">>,
-                                 _val}
-                                | _attrs],
-                               Node, _Type) ->
-    decode_pubsub_affiliation_attrs(_attrs, Node, _val);
-decode_pubsub_affiliation_attrs([_ | _attrs], Node,
-                               Type) ->
-    decode_pubsub_affiliation_attrs(_attrs, Node, Type);
-decode_pubsub_affiliation_attrs([], Node, Type) ->
-    {decode_pubsub_affiliation_attr_node(Node),
-     decode_pubsub_affiliation_attr_affiliation(Type)}.
+'encode_presence_attr_xml:lang'(undefined, _acc) ->
+    _acc;
+'encode_presence_attr_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
 
-encode_pubsub_affiliation({pubsub_affiliation, Node,
-                          Type},
-                         _xmlns_attrs) ->
-    _els = [],
-    _attrs =
-       encode_pubsub_affiliation_attr_affiliation(Type,
-                                                  encode_pubsub_affiliation_attr_node(Node,
-                                                                                      _xmlns_attrs)),
-    {xmlel, <<"affiliation">>, _attrs, _els}.
+decode_presence_priority({xmlel, <<"priority">>, _attrs,
+                         _els}) ->
+    Cdata = decode_presence_priority_els(_els, <<>>), Cdata.
 
-decode_pubsub_affiliation_attr_node(undefined) ->
-    erlang:error({missing_attr, <<"node">>,
-                 <<"affiliation">>,
-                 <<"http://jabber.org/protocol/pubsub">>});
-decode_pubsub_affiliation_attr_node(_val) -> _val.
+decode_presence_priority_els([], Cdata) ->
+    decode_presence_priority_cdata(Cdata);
+decode_presence_priority_els([{xmlcdata, _data} | _els],
+                            Cdata) ->
+    decode_presence_priority_els(_els,
+                                <<Cdata/binary, _data/binary>>);
+decode_presence_priority_els([_ | _els], Cdata) ->
+    decode_presence_priority_els(_els, Cdata).
 
-encode_pubsub_affiliation_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
+encode_presence_priority(Cdata, _xmlns_attrs) ->
+    _els = encode_presence_priority_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"priority">>, _attrs, _els}.
 
-decode_pubsub_affiliation_attr_affiliation(undefined) ->
-    erlang:error({missing_attr, <<"affiliation">>,
-                 <<"affiliation">>,
-                 <<"http://jabber.org/protocol/pubsub">>});
-decode_pubsub_affiliation_attr_affiliation(_val) ->
-    case catch xml_gen:dec_enum(_val,
-                               [member, none, outcast, owner, publisher,
-                                'publish-only'])
-       of
+decode_presence_priority_cdata(<<>>) -> undefined;
+decode_presence_priority_cdata(_val) ->
+    case catch xml_gen:dec_int(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"affiliation">>,
-                       <<"affiliation">>,
-                       <<"http://jabber.org/protocol/pubsub">>});
+         erlang:error({bad_cdata_value, <<>>, <<"priority">>,
+                       <<"jabber:client">>});
       _res -> _res
     end.
 
-encode_pubsub_affiliation_attr_affiliation(_val,
-                                          _acc) ->
-    [{<<"affiliation">>, xml_gen:enc_enum(_val)} | _acc].
+encode_presence_priority_cdata(undefined, _acc) -> _acc;
+encode_presence_priority_cdata(_val, _acc) ->
+    [{xmlcdata, xml_gen:enc_int(_val)} | _acc].
 
-decode_pubsub_item({xmlel, <<"item">>, _attrs, _els}) ->
-    __Els = decode_pubsub_item_els(_els, []),
-    Id = decode_pubsub_item_attrs(_attrs, undefined),
-    {pubsub_item, Id, __Els}.
+decode_presence_status({xmlel, <<"status">>, _attrs,
+                       _els}) ->
+    Data = decode_presence_status_els(_els, <<>>),
+    Lang = decode_presence_status_attrs(_attrs, undefined),
+    {text, Lang, Data}.
 
-decode_pubsub_item_els([], __Els) ->
-    lists:reverse(__Els);
-decode_pubsub_item_els([{xmlel, _, _, _} = _el | _els],
-                      __Els) ->
-    decode_pubsub_item_els(_els, [decode(_el) | __Els]);
-decode_pubsub_item_els([_ | _els], __Els) ->
-    decode_pubsub_item_els(_els, __Els).
+decode_presence_status_els([], Data) ->
+    decode_presence_status_cdata(Data);
+decode_presence_status_els([{xmlcdata, _data} | _els],
+                          Data) ->
+    decode_presence_status_els(_els,
+                              <<Data/binary, _data/binary>>);
+decode_presence_status_els([_ | _els], Data) ->
+    decode_presence_status_els(_els, Data).
 
-decode_pubsub_item_attrs([{<<"id">>, _val} | _attrs],
-                        _Id) ->
-    decode_pubsub_item_attrs(_attrs, _val);
-decode_pubsub_item_attrs([_ | _attrs], Id) ->
-    decode_pubsub_item_attrs(_attrs, Id);
-decode_pubsub_item_attrs([], Id) ->
-    decode_pubsub_item_attr_id(Id).
+decode_presence_status_attrs([{<<"xml:lang">>, _val}
+                             | _attrs],
+                            _Lang) ->
+    decode_presence_status_attrs(_attrs, _val);
+decode_presence_status_attrs([_ | _attrs], Lang) ->
+    decode_presence_status_attrs(_attrs, Lang);
+decode_presence_status_attrs([], Lang) ->
+    'decode_presence_status_attr_xml:lang'(Lang).
 
-encode_pubsub_item({pubsub_item, Id, __Els},
-                  _xmlns_attrs) ->
-    _els = [encode(_el) || _el <- __Els],
-    _attrs = encode_pubsub_item_attr_id(Id, _xmlns_attrs),
-    {xmlel, <<"item">>, _attrs, _els}.
+encode_presence_status({text, Lang, Data},
+                      _xmlns_attrs) ->
+    _els = encode_presence_status_cdata(Data, []),
+    _attrs = 'encode_presence_status_attr_xml:lang'(Lang,
+                                                   _xmlns_attrs),
+    {xmlel, <<"status">>, _attrs, _els}.
 
-decode_pubsub_item_attr_id(undefined) -> undefined;
-decode_pubsub_item_attr_id(_val) -> _val.
+'decode_presence_status_attr_xml:lang'(undefined) ->
+    undefined;
+'decode_presence_status_attr_xml:lang'(_val) -> _val.
 
-encode_pubsub_item_attr_id(undefined, _acc) -> _acc;
-encode_pubsub_item_attr_id(_val, _acc) ->
-    [{<<"id">>, _val} | _acc].
+'encode_presence_status_attr_xml:lang'(undefined,
+                                      _acc) ->
+    _acc;
+'encode_presence_status_attr_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
 
-decode_pubsub_items({xmlel, <<"items">>, _attrs,
-                    _els}) ->
-    Items = decode_pubsub_items_els(_els, []),
-    {Max_items, Node, Subid} =
-       decode_pubsub_items_attrs(_attrs, undefined, undefined,
-                                 undefined),
-    {pubsub_items, Node, Max_items, Subid, Items}.
+decode_presence_status_cdata(<<>>) -> undefined;
+decode_presence_status_cdata(_val) -> _val.
 
-decode_pubsub_items_els([], Items) ->
-    lists:reverse(Items);
-decode_pubsub_items_els([{xmlel, <<"item">>, _attrs,
-                         _} =
-                            _el
-                        | _els],
-                       Items) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
-          decode_pubsub_items_els(_els,
-                                  case decode_pubsub_item(_el) of
-                                    undefined -> Items;
-                                    _new_el -> [_new_el | Items]
-                                  end);
-       true -> decode_pubsub_items_els(_els, Items)
-    end;
-decode_pubsub_items_els([_ | _els], Items) ->
-    decode_pubsub_items_els(_els, Items).
+encode_presence_status_cdata(undefined, _acc) -> _acc;
+encode_presence_status_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_pubsub_items_attrs([{<<"max_items">>, _val}
-                          | _attrs],
-                         _Max_items, Node, Subid) ->
-    decode_pubsub_items_attrs(_attrs, _val, Node, Subid);
-decode_pubsub_items_attrs([{<<"node">>, _val} | _attrs],
-                         Max_items, _Node, Subid) ->
-    decode_pubsub_items_attrs(_attrs, Max_items, _val,
-                             Subid);
-decode_pubsub_items_attrs([{<<"subid">>, _val}
-                          | _attrs],
-                         Max_items, Node, _Subid) ->
-    decode_pubsub_items_attrs(_attrs, Max_items, Node,
-                             _val);
-decode_pubsub_items_attrs([_ | _attrs], Max_items, Node,
-                         Subid) ->
-    decode_pubsub_items_attrs(_attrs, Max_items, Node,
-                             Subid);
-decode_pubsub_items_attrs([], Max_items, Node, Subid) ->
-    {decode_pubsub_items_attr_max_items(Max_items),
-     decode_pubsub_items_attr_node(Node),
-     decode_pubsub_items_attr_subid(Subid)}.
+decode_presence_show({xmlel, <<"show">>, _attrs,
+                     _els}) ->
+    Cdata = decode_presence_show_els(_els, <<>>), Cdata.
 
-encode_pubsub_items({pubsub_items, Node, Max_items,
-                    Subid, Items},
-                   _xmlns_attrs) ->
-    _els = 'encode_pubsub_items_$items'(Items, []),
-    _attrs = encode_pubsub_items_attr_subid(Subid,
-                                           encode_pubsub_items_attr_node(Node,
-                                                                         encode_pubsub_items_attr_max_items(Max_items,
-                                                                                                            _xmlns_attrs))),
-    {xmlel, <<"items">>, _attrs, _els}.
+decode_presence_show_els([], Cdata) ->
+    decode_presence_show_cdata(Cdata);
+decode_presence_show_els([{xmlcdata, _data} | _els],
+                        Cdata) ->
+    decode_presence_show_els(_els,
+                            <<Cdata/binary, _data/binary>>);
+decode_presence_show_els([_ | _els], Cdata) ->
+    decode_presence_show_els(_els, Cdata).
 
-'encode_pubsub_items_$items'([], _acc) -> _acc;
-'encode_pubsub_items_$items'([Items | _els], _acc) ->
-    'encode_pubsub_items_$items'(_els,
-                                [encode_pubsub_item(Items, []) | _acc]).
+encode_presence_show(Cdata, _xmlns_attrs) ->
+    _els = encode_presence_show_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"show">>, _attrs, _els}.
 
-decode_pubsub_items_attr_max_items(undefined) ->
-    undefined;
-decode_pubsub_items_attr_max_items(_val) ->
-    case catch xml_gen:dec_int(_val, 0, infinity) of
+decode_presence_show_cdata(<<>>) -> undefined;
+decode_presence_show_cdata(_val) ->
+    case catch xml_gen:dec_enum(_val, [away, chat, dnd, xa])
+       of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"max_items">>,
-                       <<"items">>, <<"http://jabber.org/protocol/pubsub">>});
+         erlang:error({bad_cdata_value, <<>>, <<"show">>,
+                       <<"jabber:client">>});
       _res -> _res
     end.
 
-encode_pubsub_items_attr_max_items(undefined, _acc) ->
-    _acc;
-encode_pubsub_items_attr_max_items(_val, _acc) ->
-    [{<<"max_items">>, xml_gen:enc_int(_val)} | _acc].
+encode_presence_show_cdata(undefined, _acc) -> _acc;
+encode_presence_show_cdata(_val, _acc) ->
+    [{xmlcdata, xml_gen:enc_enum(_val)} | _acc].
 
-decode_pubsub_items_attr_node(undefined) ->
-    erlang:error({missing_attr, <<"node">>, <<"items">>,
-                 <<"http://jabber.org/protocol/pubsub">>});
-decode_pubsub_items_attr_node(_val) -> _val.
+decode_message({xmlel, <<"message">>, _attrs, _els}) ->
+    {Error, Thread, Subject, Body, __Els} =
+       decode_message_els(_els, undefined, undefined, [], [],
+                          []),
+    {Id, Type, From, To, Lang} =
+       decode_message_attrs(_attrs, undefined, undefined,
+                            undefined, undefined, undefined),
+    {message, Id, Type, Lang, From, To, Subject, Body,
+     Thread, Error, __Els}.
 
-encode_pubsub_items_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
+decode_message_els([], Error, Thread, Subject, Body,
+                  __Els) ->
+    {Error, Thread, lists:reverse(Subject),
+     lists:reverse(Body), lists:reverse(__Els)};
+decode_message_els([{xmlel, <<"error">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Error, Thread, Subject, Body, __Els) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
+          decode_message_els(_els, decode_error(_el), Thread,
+                             Subject, Body, __Els);
+       true ->
+          decode_message_els(_els, Error, Thread, Subject, Body,
+                             __Els)
+    end;
+decode_message_els([{xmlel, <<"subject">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Error, Thread, Subject, Body, __Els) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
+          decode_message_els(_els, Error, Thread,
+                             case decode_message_subject(_el) of
+                               undefined -> Subject;
+                               _new_el -> [_new_el | Subject]
+                             end,
+                             Body, __Els);
+       true ->
+          decode_message_els(_els, Error, Thread, Subject, Body,
+                             __Els)
+    end;
+decode_message_els([{xmlel, <<"thread">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Error, Thread, Subject, Body, __Els) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
+          decode_message_els(_els, Error,
+                             decode_message_thread(_el), Subject, Body, __Els);
+       true ->
+          decode_message_els(_els, Error, Thread, Subject, Body,
+                             __Els)
+    end;
+decode_message_els([{xmlel, <<"body">>, _attrs, _} = _el
+                   | _els],
+                  Error, Thread, Subject, Body, __Els) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
+          decode_message_els(_els, Error, Thread, Subject,
+                             case decode_message_body(_el) of
+                               undefined -> Body;
+                               _new_el -> [_new_el | Body]
+                             end,
+                             __Els);
+       true ->
+          decode_message_els(_els, Error, Thread, Subject, Body,
+                             __Els)
+    end;
+decode_message_els([{xmlel, _, _, _} = _el | _els],
+                  Error, Thread, Subject, Body, __Els) ->
+    decode_message_els(_els, Error, Thread, Subject, Body,
+                      [decode(_el) | __Els]);
+decode_message_els([_ | _els], Error, Thread, Subject,
+                  Body, __Els) ->
+    decode_message_els(_els, Error, Thread, Subject, Body,
+                      __Els).
 
-decode_pubsub_items_attr_subid(undefined) -> undefined;
-decode_pubsub_items_attr_subid(_val) -> _val.
+decode_message_attrs([{<<"id">>, _val} | _attrs], _Id,
+                    Type, From, To, Lang) ->
+    decode_message_attrs(_attrs, _val, Type, From, To,
+                        Lang);
+decode_message_attrs([{<<"type">>, _val} | _attrs], Id,
+                    _Type, From, To, Lang) ->
+    decode_message_attrs(_attrs, Id, _val, From, To, Lang);
+decode_message_attrs([{<<"from">>, _val} | _attrs], Id,
+                    Type, _From, To, Lang) ->
+    decode_message_attrs(_attrs, Id, Type, _val, To, Lang);
+decode_message_attrs([{<<"to">>, _val} | _attrs], Id,
+                    Type, From, _To, Lang) ->
+    decode_message_attrs(_attrs, Id, Type, From, _val,
+                        Lang);
+decode_message_attrs([{<<"xml:lang">>, _val} | _attrs],
+                    Id, Type, From, To, _Lang) ->
+    decode_message_attrs(_attrs, Id, Type, From, To, _val);
+decode_message_attrs([_ | _attrs], Id, Type, From, To,
+                    Lang) ->
+    decode_message_attrs(_attrs, Id, Type, From, To, Lang);
+decode_message_attrs([], Id, Type, From, To, Lang) ->
+    {decode_message_attr_id(Id),
+     decode_message_attr_type(Type),
+     decode_message_attr_from(From),
+     decode_message_attr_to(To),
+     'decode_message_attr_xml:lang'(Lang)}.
+
+encode_message({message, Id, Type, Lang, From, To,
+               Subject, Body, Thread, Error, __Els},
+              _xmlns_attrs) ->
+    _els = 'encode_message_$body'(Body,
+                                 'encode_message_$subject'(Subject,
+                                                           'encode_message_$thread'(Thread,
+                                                                                    'encode_message_$error'(Error,
+                                                                                                            [encode(_el)
+                                                                                                             || _el
+                                                                                                                    <- __Els])))),
+    _attrs = 'encode_message_attr_xml:lang'(Lang,
+                                           encode_message_attr_to(To,
+                                                                  encode_message_attr_from(From,
+                                                                                           encode_message_attr_type(Type,
+                                                                                                                    encode_message_attr_id(Id,
+                                                                                                                                           _xmlns_attrs))))),
+    {xmlel, <<"message">>, _attrs, _els}.
 
-encode_pubsub_items_attr_subid(undefined, _acc) -> _acc;
-encode_pubsub_items_attr_subid(_val, _acc) ->
-    [{<<"subid">>, _val} | _acc].
+'encode_message_$error'(undefined, _acc) -> _acc;
+'encode_message_$error'(Error, _acc) ->
+    [encode_error(Error, []) | _acc].
 
-decode_pubsub_event_retract({xmlel, <<"retract">>,
-                            _attrs, _els}) ->
-    Id = decode_pubsub_event_retract_attrs(_attrs,
-                                          undefined),
-    Id.
+'encode_message_$thread'(undefined, _acc) -> _acc;
+'encode_message_$thread'(Thread, _acc) ->
+    [encode_message_thread(Thread, []) | _acc].
 
-decode_pubsub_event_retract_attrs([{<<"id">>, _val}
-                                  | _attrs],
-                                 _Id) ->
-    decode_pubsub_event_retract_attrs(_attrs, _val);
-decode_pubsub_event_retract_attrs([_ | _attrs], Id) ->
-    decode_pubsub_event_retract_attrs(_attrs, Id);
-decode_pubsub_event_retract_attrs([], Id) ->
-    decode_pubsub_event_retract_attr_id(Id).
+'encode_message_$subject'([], _acc) -> _acc;
+'encode_message_$subject'([Subject | _els], _acc) ->
+    'encode_message_$subject'(_els,
+                             [encode_message_subject(Subject, []) | _acc]).
 
-encode_pubsub_event_retract(Id, _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_pubsub_event_retract_attr_id(Id,
-                                                _xmlns_attrs),
-    {xmlel, <<"retract">>, _attrs, _els}.
+'encode_message_$body'([], _acc) -> _acc;
+'encode_message_$body'([Body | _els], _acc) ->
+    'encode_message_$body'(_els,
+                          [encode_message_body(Body, []) | _acc]).
 
-decode_pubsub_event_retract_attr_id(undefined) ->
-    erlang:error({missing_attr, <<"id">>, <<"retract">>,
-                 <<"http://jabber.org/protocol/pubsub#event">>});
-decode_pubsub_event_retract_attr_id(_val) -> _val.
+decode_message_attr_id(undefined) -> undefined;
+decode_message_attr_id(_val) -> _val.
 
-encode_pubsub_event_retract_attr_id(_val, _acc) ->
+encode_message_attr_id(undefined, _acc) -> _acc;
+encode_message_attr_id(_val, _acc) ->
     [{<<"id">>, _val} | _acc].
 
-decode_pubsub_event_item({xmlel, <<"item">>, _attrs,
-                         _els}) ->
-    {Id, Node, Publisher} =
-       decode_pubsub_event_item_attrs(_attrs, undefined,
-                                      undefined, undefined),
-    {pubsub_event_item, Id, Node, Publisher}.
+decode_message_attr_type(undefined) -> normal;
+decode_message_attr_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [chat, normal, groupchat, headline, error])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"type">>, <<"message">>,
+                       <<"jabber:client">>});
+      _res -> _res
+    end.
 
-decode_pubsub_event_item_attrs([{<<"id">>, _val}
-                               | _attrs],
-                              _Id, Node, Publisher) ->
-    decode_pubsub_event_item_attrs(_attrs, _val, Node,
-                                  Publisher);
-decode_pubsub_event_item_attrs([{<<"node">>, _val}
-                               | _attrs],
-                              Id, _Node, Publisher) ->
-    decode_pubsub_event_item_attrs(_attrs, Id, _val,
-                                  Publisher);
-decode_pubsub_event_item_attrs([{<<"publisher">>, _val}
-                               | _attrs],
-                              Id, Node, _Publisher) ->
-    decode_pubsub_event_item_attrs(_attrs, Id, Node, _val);
-decode_pubsub_event_item_attrs([_ | _attrs], Id, Node,
-                              Publisher) ->
-    decode_pubsub_event_item_attrs(_attrs, Id, Node,
-                                  Publisher);
-decode_pubsub_event_item_attrs([], Id, Node,
-                              Publisher) ->
-    {decode_pubsub_event_item_attr_id(Id),
-     decode_pubsub_event_item_attr_node(Node),
-     decode_pubsub_event_item_attr_publisher(Publisher)}.
+encode_message_attr_type(normal, _acc) -> _acc;
+encode_message_attr_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
 
-encode_pubsub_event_item({pubsub_event_item, Id, Node,
-                         Publisher},
-                        _xmlns_attrs) ->
-    _els = [],
-    _attrs =
-       encode_pubsub_event_item_attr_publisher(Publisher,
-                                               encode_pubsub_event_item_attr_node(Node,
-                                                                                  encode_pubsub_event_item_attr_id(Id,
-                                                                                                                   _xmlns_attrs))),
-    {xmlel, <<"item">>, _attrs, _els}.
+decode_message_attr_from(undefined) -> undefined;
+decode_message_attr_from(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"from">>, <<"message">>,
+                       <<"jabber:client">>});
+      _res -> _res
+    end.
 
-decode_pubsub_event_item_attr_id(undefined) ->
-    undefined;
-decode_pubsub_event_item_attr_id(_val) -> _val.
+encode_message_attr_from(undefined, _acc) -> _acc;
+encode_message_attr_from(_val, _acc) ->
+    [{<<"from">>, enc_jid(_val)} | _acc].
 
-encode_pubsub_event_item_attr_id(undefined, _acc) ->
-    _acc;
-encode_pubsub_event_item_attr_id(_val, _acc) ->
-    [{<<"id">>, _val} | _acc].
+decode_message_attr_to(undefined) -> undefined;
+decode_message_attr_to(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"to">>, <<"message">>,
+                       <<"jabber:client">>});
+      _res -> _res
+    end.
 
-decode_pubsub_event_item_attr_node(undefined) ->
-    undefined;
-decode_pubsub_event_item_attr_node(_val) -> _val.
+encode_message_attr_to(undefined, _acc) -> _acc;
+encode_message_attr_to(_val, _acc) ->
+    [{<<"to">>, enc_jid(_val)} | _acc].
 
-encode_pubsub_event_item_attr_node(undefined, _acc) ->
-    _acc;
-encode_pubsub_event_item_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
+'decode_message_attr_xml:lang'(undefined) -> undefined;
+'decode_message_attr_xml:lang'(_val) -> _val.
 
-decode_pubsub_event_item_attr_publisher(undefined) ->
-    undefined;
-decode_pubsub_event_item_attr_publisher(_val) -> _val.
+'encode_message_attr_xml:lang'(undefined, _acc) -> _acc;
+'encode_message_attr_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
 
-encode_pubsub_event_item_attr_publisher(undefined,
-                                       _acc) ->
-    _acc;
-encode_pubsub_event_item_attr_publisher(_val, _acc) ->
-    [{<<"publisher">>, _val} | _acc].
+decode_message_thread({xmlel, <<"thread">>, _attrs,
+                      _els}) ->
+    Cdata = decode_message_thread_els(_els, <<>>), Cdata.
 
-decode_pubsub_event_items({xmlel, <<"items">>, _attrs,
-                          _els}) ->
-    {Items, Retract} = decode_pubsub_event_items_els(_els,
-                                                    [], []),
-    Node = decode_pubsub_event_items_attrs(_attrs,
-                                          undefined),
-    {pubsub_event_items, Node, Retract, Items}.
+decode_message_thread_els([], Cdata) ->
+    decode_message_thread_cdata(Cdata);
+decode_message_thread_els([{xmlcdata, _data} | _els],
+                         Cdata) ->
+    decode_message_thread_els(_els,
+                             <<Cdata/binary, _data/binary>>);
+decode_message_thread_els([_ | _els], Cdata) ->
+    decode_message_thread_els(_els, Cdata).
 
-decode_pubsub_event_items_els([], Items, Retract) ->
-    {lists:reverse(Items), lists:reverse(Retract)};
-decode_pubsub_event_items_els([{xmlel, <<"retract">>,
-                               _attrs, _} =
-                                  _el
-                              | _els],
-                             Items, Retract) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns ==
-        <<"http://jabber.org/protocol/pubsub#event">> ->
-          decode_pubsub_event_items_els(_els, Items,
-                                        case decode_pubsub_event_retract(_el)
-                                            of
-                                          undefined -> Retract;
-                                          _new_el -> [_new_el | Retract]
-                                        end);
-       true ->
-          decode_pubsub_event_items_els(_els, Items, Retract)
-    end;
-decode_pubsub_event_items_els([{xmlel, <<"item">>,
-                               _attrs, _} =
-                                  _el
-                              | _els],
-                             Items, Retract) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns ==
-        <<"http://jabber.org/protocol/pubsub#event">> ->
-          decode_pubsub_event_items_els(_els,
-                                        case decode_pubsub_event_item(_el) of
-                                          undefined -> Items;
-                                          _new_el -> [_new_el | Items]
-                                        end,
-                                        Retract);
-       true ->
-          decode_pubsub_event_items_els(_els, Items, Retract)
-    end;
-decode_pubsub_event_items_els([_ | _els], Items,
-                             Retract) ->
-    decode_pubsub_event_items_els(_els, Items, Retract).
+encode_message_thread(Cdata, _xmlns_attrs) ->
+    _els = encode_message_thread_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"thread">>, _attrs, _els}.
 
-decode_pubsub_event_items_attrs([{<<"node">>, _val}
-                                | _attrs],
-                               _Node) ->
-    decode_pubsub_event_items_attrs(_attrs, _val);
-decode_pubsub_event_items_attrs([_ | _attrs], Node) ->
-    decode_pubsub_event_items_attrs(_attrs, Node);
-decode_pubsub_event_items_attrs([], Node) ->
-    decode_pubsub_event_items_attr_node(Node).
+decode_message_thread_cdata(<<>>) -> undefined;
+decode_message_thread_cdata(_val) -> _val.
 
-encode_pubsub_event_items({pubsub_event_items, Node,
-                          Retract, Items},
-                         _xmlns_attrs) ->
-    _els = 'encode_pubsub_event_items_$retract'(Retract,
-                                               'encode_pubsub_event_items_$items'(Items,
-                                                                                  [])),
-    _attrs = encode_pubsub_event_items_attr_node(Node,
-                                                _xmlns_attrs),
-    {xmlel, <<"items">>, _attrs, _els}.
+encode_message_thread_cdata(undefined, _acc) -> _acc;
+encode_message_thread_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-'encode_pubsub_event_items_$items'([], _acc) -> _acc;
-'encode_pubsub_event_items_$items'([Items | _els],
-                                  _acc) ->
-    'encode_pubsub_event_items_$items'(_els,
-                                      [encode_pubsub_event_item(Items, [])
-                                       | _acc]).
+decode_message_body({xmlel, <<"body">>, _attrs,
+                    _els}) ->
+    Data = decode_message_body_els(_els, <<>>),
+    Lang = decode_message_body_attrs(_attrs, undefined),
+    {text, Lang, Data}.
 
-'encode_pubsub_event_items_$retract'([], _acc) -> _acc;
-'encode_pubsub_event_items_$retract'([Retract | _els],
-                                    _acc) ->
-    'encode_pubsub_event_items_$retract'(_els,
-                                        [encode_pubsub_event_retract(Retract,
-                                                                     [])
-                                         | _acc]).
+decode_message_body_els([], Data) ->
+    decode_message_body_cdata(Data);
+decode_message_body_els([{xmlcdata, _data} | _els],
+                       Data) ->
+    decode_message_body_els(_els,
+                           <<Data/binary, _data/binary>>);
+decode_message_body_els([_ | _els], Data) ->
+    decode_message_body_els(_els, Data).
 
-decode_pubsub_event_items_attr_node(undefined) ->
-    erlang:error({missing_attr, <<"node">>, <<"items">>,
-                 <<"http://jabber.org/protocol/pubsub#event">>});
-decode_pubsub_event_items_attr_node(_val) -> _val.
+decode_message_body_attrs([{<<"xml:lang">>, _val}
+                          | _attrs],
+                         _Lang) ->
+    decode_message_body_attrs(_attrs, _val);
+decode_message_body_attrs([_ | _attrs], Lang) ->
+    decode_message_body_attrs(_attrs, Lang);
+decode_message_body_attrs([], Lang) ->
+    'decode_message_body_attr_xml:lang'(Lang).
 
-encode_pubsub_event_items_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
+encode_message_body({text, Lang, Data}, _xmlns_attrs) ->
+    _els = encode_message_body_cdata(Data, []),
+    _attrs = 'encode_message_body_attr_xml:lang'(Lang,
+                                                _xmlns_attrs),
+    {xmlel, <<"body">>, _attrs, _els}.
 
-decode_pubsub_event({xmlel, <<"event">>, _attrs,
-                    _els}) ->
-    Items = decode_pubsub_event_els(_els, []),
-    {pubsub_event, Items}.
+'decode_message_body_attr_xml:lang'(undefined) ->
+    undefined;
+'decode_message_body_attr_xml:lang'(_val) -> _val.
 
-decode_pubsub_event_els([], Items) ->
-    lists:reverse(Items);
-decode_pubsub_event_els([{xmlel, <<"items">>, _attrs,
-                         _} =
-                            _el
-                        | _els],
-                       Items) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns ==
-        <<"http://jabber.org/protocol/pubsub#event">> ->
-          decode_pubsub_event_els(_els,
-                                  case decode_pubsub_event_items(_el) of
-                                    undefined -> Items;
-                                    _new_el -> [_new_el | Items]
-                                  end);
-       true -> decode_pubsub_event_els(_els, Items)
-    end;
-decode_pubsub_event_els([_ | _els], Items) ->
-    decode_pubsub_event_els(_els, Items).
+'encode_message_body_attr_xml:lang'(undefined, _acc) ->
+    _acc;
+'encode_message_body_attr_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
 
-encode_pubsub_event({pubsub_event, Items},
-                   _xmlns_attrs) ->
-    _els = 'encode_pubsub_event_$items'(Items, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"event">>, _attrs, _els}.
+decode_message_body_cdata(<<>>) -> undefined;
+decode_message_body_cdata(_val) -> _val.
 
-'encode_pubsub_event_$items'([], _acc) -> _acc;
-'encode_pubsub_event_$items'([Items | _els], _acc) ->
-    'encode_pubsub_event_$items'(_els,
-                                [encode_pubsub_event_items(Items, []) | _acc]).
+encode_message_body_cdata(undefined, _acc) -> _acc;
+encode_message_body_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_pubsub_subscriptions({xmlel, <<"subscriptions">>,
-                            _attrs, _els}) ->
-    Subscriptions = decode_pubsub_subscriptions_els(_els,
-                                                   []),
-    Node = decode_pubsub_subscriptions_attrs(_attrs,
-                                            undefined),
-    {Node, Subscriptions}.
+decode_message_subject({xmlel, <<"subject">>, _attrs,
+                       _els}) ->
+    Data = decode_message_subject_els(_els, <<>>),
+    Lang = decode_message_subject_attrs(_attrs, undefined),
+    {text, Lang, Data}.
 
-decode_pubsub_subscriptions_els([], Subscriptions) ->
-    lists:reverse(Subscriptions);
-decode_pubsub_subscriptions_els([{xmlel,
-                                 <<"subscription">>, _attrs, _} =
-                                    _el
-                                | _els],
-                               Subscriptions) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
-          decode_pubsub_subscriptions_els(_els,
-                                          case decode_pubsub_subscription(_el)
-                                              of
-                                            undefined -> Subscriptions;
-                                            _new_el ->
-                                                [_new_el | Subscriptions]
-                                          end);
-       true ->
-          decode_pubsub_subscriptions_els(_els, Subscriptions)
-    end;
-decode_pubsub_subscriptions_els([_ | _els],
-                               Subscriptions) ->
-    decode_pubsub_subscriptions_els(_els, Subscriptions).
+decode_message_subject_els([], Data) ->
+    decode_message_subject_cdata(Data);
+decode_message_subject_els([{xmlcdata, _data} | _els],
+                          Data) ->
+    decode_message_subject_els(_els,
+                              <<Data/binary, _data/binary>>);
+decode_message_subject_els([_ | _els], Data) ->
+    decode_message_subject_els(_els, Data).
 
-decode_pubsub_subscriptions_attrs([{<<"node">>, _val}
-                                  | _attrs],
-                                 _Node) ->
-    decode_pubsub_subscriptions_attrs(_attrs, _val);
-decode_pubsub_subscriptions_attrs([_ | _attrs], Node) ->
-    decode_pubsub_subscriptions_attrs(_attrs, Node);
-decode_pubsub_subscriptions_attrs([], Node) ->
-    decode_pubsub_subscriptions_attr_node(Node).
+decode_message_subject_attrs([{<<"xml:lang">>, _val}
+                             | _attrs],
+                            _Lang) ->
+    decode_message_subject_attrs(_attrs, _val);
+decode_message_subject_attrs([_ | _attrs], Lang) ->
+    decode_message_subject_attrs(_attrs, Lang);
+decode_message_subject_attrs([], Lang) ->
+    'decode_message_subject_attr_xml:lang'(Lang).
 
-encode_pubsub_subscriptions({Node, Subscriptions},
-                           _xmlns_attrs) ->
-    _els =
-       'encode_pubsub_subscriptions_$subscriptions'(Subscriptions,
-                                                    []),
-    _attrs = encode_pubsub_subscriptions_attr_node(Node,
-                                                  _xmlns_attrs),
-    {xmlel, <<"subscriptions">>, _attrs, _els}.
+encode_message_subject({text, Lang, Data},
+                      _xmlns_attrs) ->
+    _els = encode_message_subject_cdata(Data, []),
+    _attrs = 'encode_message_subject_attr_xml:lang'(Lang,
+                                                   _xmlns_attrs),
+    {xmlel, <<"subject">>, _attrs, _els}.
 
-'encode_pubsub_subscriptions_$subscriptions'([],
-                                            _acc) ->
+'decode_message_subject_attr_xml:lang'(undefined) ->
+    undefined;
+'decode_message_subject_attr_xml:lang'(_val) -> _val.
+
+'encode_message_subject_attr_xml:lang'(undefined,
+                                      _acc) ->
     _acc;
-'encode_pubsub_subscriptions_$subscriptions'([Subscriptions
-                                             | _els],
-                                            _acc) ->
-    'encode_pubsub_subscriptions_$subscriptions'(_els,
-                                                [encode_pubsub_subscription(Subscriptions,
-                                                                            [])
-                                                 | _acc]).
+'encode_message_subject_attr_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
 
-decode_pubsub_subscriptions_attr_node(undefined) ->
-    none;
-decode_pubsub_subscriptions_attr_node(_val) -> _val.
+decode_message_subject_cdata(<<>>) -> undefined;
+decode_message_subject_cdata(_val) -> _val.
 
-encode_pubsub_subscriptions_attr_node(none, _acc) ->
-    _acc;
-encode_pubsub_subscriptions_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
+encode_message_subject_cdata(undefined, _acc) -> _acc;
+encode_message_subject_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_pubsub_affiliations({xmlel, <<"affiliations">>,
-                           _attrs, _els}) ->
-    Affiliations = decode_pubsub_affiliations_els(_els, []),
-    Affiliations.
+decode_iq({xmlel, <<"iq">>, _attrs, _els}) ->
+    {Error, __Els} = decode_iq_els(_els, undefined, []),
+    {Id, Type, From, To, Lang} = decode_iq_attrs(_attrs,
+                                                undefined, undefined,
+                                                undefined, undefined,
+                                                undefined),
+    {iq, Id, Type, Lang, From, To, Error, __Els}.
 
-decode_pubsub_affiliations_els([], Affiliations) ->
-    lists:reverse(Affiliations);
-decode_pubsub_affiliations_els([{xmlel,
-                                <<"affiliation">>, _attrs, _} =
-                                   _el
-                               | _els],
-                              Affiliations) ->
+decode_iq_els([], Error, __Els) ->
+    {Error, lists:reverse(__Els)};
+decode_iq_els([{xmlel, <<"error">>, _attrs, _} = _el
+              | _els],
+             Error, __Els) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
-          decode_pubsub_affiliations_els(_els,
-                                         case decode_pubsub_affiliation(_el) of
-                                           undefined -> Affiliations;
-                                           _new_el -> [_new_el | Affiliations]
-                                         end);
-       true ->
-          decode_pubsub_affiliations_els(_els, Affiliations)
+    if _xmlns == <<>>; _xmlns == <<"jabber:client">> ->
+          decode_iq_els(_els, decode_error(_el), __Els);
+       true -> decode_iq_els(_els, Error, __Els)
     end;
-decode_pubsub_affiliations_els([_ | _els],
-                              Affiliations) ->
-    decode_pubsub_affiliations_els(_els, Affiliations).
+decode_iq_els([{xmlel, _, _, _} = _el | _els], Error,
+             __Els) ->
+    decode_iq_els(_els, Error, [decode(_el) | __Els]);
+decode_iq_els([_ | _els], Error, __Els) ->
+    decode_iq_els(_els, Error, __Els).
+
+decode_iq_attrs([{<<"id">>, _val} | _attrs], _Id, Type,
+               From, To, Lang) ->
+    decode_iq_attrs(_attrs, _val, Type, From, To, Lang);
+decode_iq_attrs([{<<"type">>, _val} | _attrs], Id,
+               _Type, From, To, Lang) ->
+    decode_iq_attrs(_attrs, Id, _val, From, To, Lang);
+decode_iq_attrs([{<<"from">>, _val} | _attrs], Id, Type,
+               _From, To, Lang) ->
+    decode_iq_attrs(_attrs, Id, Type, _val, To, Lang);
+decode_iq_attrs([{<<"to">>, _val} | _attrs], Id, Type,
+               From, _To, Lang) ->
+    decode_iq_attrs(_attrs, Id, Type, From, _val, Lang);
+decode_iq_attrs([{<<"xml:lang">>, _val} | _attrs], Id,
+               Type, From, To, _Lang) ->
+    decode_iq_attrs(_attrs, Id, Type, From, To, _val);
+decode_iq_attrs([_ | _attrs], Id, Type, From, To,
+               Lang) ->
+    decode_iq_attrs(_attrs, Id, Type, From, To, Lang);
+decode_iq_attrs([], Id, Type, From, To, Lang) ->
+    {decode_iq_attr_id(Id), decode_iq_attr_type(Type),
+     decode_iq_attr_from(From), decode_iq_attr_to(To),
+     'decode_iq_attr_xml:lang'(Lang)}.
+
+encode_iq({iq, Id, Type, Lang, From, To, Error, __Els},
+         _xmlns_attrs) ->
+    _els = 'encode_iq_$error'(Error,
+                             [encode(_el) || _el <- __Els]),
+    _attrs = 'encode_iq_attr_xml:lang'(Lang,
+                                      encode_iq_attr_to(To,
+                                                        encode_iq_attr_from(From,
+                                                                            encode_iq_attr_type(Type,
+                                                                                                encode_iq_attr_id(Id,
+                                                                                                                  _xmlns_attrs))))),
+    {xmlel, <<"iq">>, _attrs, _els}.
 
-encode_pubsub_affiliations(Affiliations,
-                          _xmlns_attrs) ->
-    _els =
-       'encode_pubsub_affiliations_$affiliations'(Affiliations,
-                                                  []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"affiliations">>, _attrs, _els}.
+'encode_iq_$error'(undefined, _acc) -> _acc;
+'encode_iq_$error'(Error, _acc) ->
+    [encode_error(Error, []) | _acc].
 
-'encode_pubsub_affiliations_$affiliations'([], _acc) ->
-    _acc;
-'encode_pubsub_affiliations_$affiliations'([Affiliations
-                                           | _els],
-                                          _acc) ->
-    'encode_pubsub_affiliations_$affiliations'(_els,
-                                              [encode_pubsub_affiliation(Affiliations,
-                                                                         [])
-                                               | _acc]).
+decode_iq_attr_id(undefined) ->
+    erlang:error({missing_attr, <<"id">>, <<"iq">>,
+                 <<"jabber:client">>});
+decode_iq_attr_id(_val) -> _val.
 
-decode_pubsub_subscribe({xmlel, <<"subscribe">>, _attrs,
-                        _els}) ->
-    {Node, Jid} = decode_pubsub_subscribe_attrs(_attrs,
-                                               undefined, undefined),
-    {Node, Jid}.
+encode_iq_attr_id(_val, _acc) ->
+    [{<<"id">>, _val} | _acc].
 
-decode_pubsub_subscribe_attrs([{<<"node">>, _val}
-                              | _attrs],
-                             _Node, Jid) ->
-    decode_pubsub_subscribe_attrs(_attrs, _val, Jid);
-decode_pubsub_subscribe_attrs([{<<"jid">>, _val}
-                              | _attrs],
-                             Node, _Jid) ->
-    decode_pubsub_subscribe_attrs(_attrs, Node, _val);
-decode_pubsub_subscribe_attrs([_ | _attrs], Node,
-                             Jid) ->
-    decode_pubsub_subscribe_attrs(_attrs, Node, Jid);
-decode_pubsub_subscribe_attrs([], Node, Jid) ->
-    {decode_pubsub_subscribe_attr_node(Node),
-     decode_pubsub_subscribe_attr_jid(Jid)}.
+decode_iq_attr_type(undefined) ->
+    erlang:error({missing_attr, <<"type">>, <<"iq">>,
+                 <<"jabber:client">>});
+decode_iq_attr_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [get, set, result, error])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"type">>, <<"iq">>,
+                       <<"jabber:client">>});
+      _res -> _res
+    end.
 
-encode_pubsub_subscribe({Node, Jid}, _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_pubsub_subscribe_attr_jid(Jid,
-                                             encode_pubsub_subscribe_attr_node(Node,
-                                                                               _xmlns_attrs)),
-    {xmlel, <<"subscribe">>, _attrs, _els}.
+encode_iq_attr_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
 
-decode_pubsub_subscribe_attr_node(undefined) ->
-    undefined;
-decode_pubsub_subscribe_attr_node(_val) -> _val.
+decode_iq_attr_from(undefined) -> undefined;
+decode_iq_attr_from(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"from">>, <<"iq">>,
+                       <<"jabber:client">>});
+      _res -> _res
+    end.
 
-encode_pubsub_subscribe_attr_node(undefined, _acc) ->
-    _acc;
-encode_pubsub_subscribe_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
+encode_iq_attr_from(undefined, _acc) -> _acc;
+encode_iq_attr_from(_val, _acc) ->
+    [{<<"from">>, enc_jid(_val)} | _acc].
 
-decode_pubsub_subscribe_attr_jid(undefined) ->
-    erlang:error({missing_attr, <<"jid">>, <<"subscribe">>,
-                 <<"http://jabber.org/protocol/pubsub">>});
-decode_pubsub_subscribe_attr_jid(_val) ->
+decode_iq_attr_to(undefined) -> undefined;
+decode_iq_attr_to(_val) ->
     case catch dec_jid(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"jid">>,
-                       <<"subscribe">>,
-                       <<"http://jabber.org/protocol/pubsub">>});
+         erlang:error({bad_attr_value, <<"to">>, <<"iq">>,
+                       <<"jabber:client">>});
       _res -> _res
     end.
 
-encode_pubsub_subscribe_attr_jid(_val, _acc) ->
-    [{<<"jid">>, enc_jid(_val)} | _acc].
+encode_iq_attr_to(undefined, _acc) -> _acc;
+encode_iq_attr_to(_val, _acc) ->
+    [{<<"to">>, enc_jid(_val)} | _acc].
 
-decode_pubsub_publish({xmlel, <<"publish">>, _attrs,
-                      _els}) ->
-    Items = decode_pubsub_publish_els(_els, []),
-    Node = decode_pubsub_publish_attrs(_attrs, undefined),
-    {Node, Items}.
+'decode_iq_attr_xml:lang'(undefined) -> undefined;
+'decode_iq_attr_xml:lang'(_val) -> _val.
 
-decode_pubsub_publish_els([], Items) ->
-    lists:reverse(Items);
-decode_pubsub_publish_els([{xmlel, <<"item">>, _attrs,
-                           _} =
-                              _el
-                          | _els],
-                         Items) ->
+'encode_iq_attr_xml:lang'(undefined, _acc) -> _acc;
+'encode_iq_attr_xml:lang'(_val, _acc) ->
+    [{<<"xml:lang">>, _val} | _acc].
+
+decode_stats({xmlel, <<"query">>, _attrs, _els}) ->
+    Stat = decode_stats_els(_els, []), {stats, Stat}.
+
+decode_stats_els([], Stat) -> lists:reverse(Stat);
+decode_stats_els([{xmlel, <<"stat">>, _attrs, _} = _el
+                 | _els],
+                Stat) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
     if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
-          decode_pubsub_publish_els(_els,
-                                    case decode_pubsub_item(_el) of
-                                      undefined -> Items;
-                                      _new_el -> [_new_el | Items]
-                                    end);
-       true -> decode_pubsub_publish_els(_els, Items)
+       _xmlns == <<"http://jabber.org/protocol/stats">> ->
+          decode_stats_els(_els,
+                           case decode_stat(_el) of
+                             undefined -> Stat;
+                             _new_el -> [_new_el | Stat]
+                           end);
+       true -> decode_stats_els(_els, Stat)
     end;
-decode_pubsub_publish_els([_ | _els], Items) ->
-    decode_pubsub_publish_els(_els, Items).
-
-decode_pubsub_publish_attrs([{<<"node">>, _val}
-                            | _attrs],
-                           _Node) ->
-    decode_pubsub_publish_attrs(_attrs, _val);
-decode_pubsub_publish_attrs([_ | _attrs], Node) ->
-    decode_pubsub_publish_attrs(_attrs, Node);
-decode_pubsub_publish_attrs([], Node) ->
-    decode_pubsub_publish_attr_node(Node).
-
-encode_pubsub_publish({Node, Items}, _xmlns_attrs) ->
-    _els = 'encode_pubsub_publish_$items'(Items, []),
-    _attrs = encode_pubsub_publish_attr_node(Node,
-                                            _xmlns_attrs),
-    {xmlel, <<"publish">>, _attrs, _els}.
-
-'encode_pubsub_publish_$items'([], _acc) -> _acc;
-'encode_pubsub_publish_$items'([Items | _els], _acc) ->
-    'encode_pubsub_publish_$items'(_els,
-                                  [encode_pubsub_item(Items, []) | _acc]).
+decode_stats_els([_ | _els], Stat) ->
+    decode_stats_els(_els, Stat).
 
-decode_pubsub_publish_attr_node(undefined) ->
-    erlang:error({missing_attr, <<"node">>, <<"publish">>,
-                 <<"http://jabber.org/protocol/pubsub">>});
-decode_pubsub_publish_attr_node(_val) -> _val.
+encode_stats({stats, Stat}, _xmlns_attrs) ->
+    _els = 'encode_stats_$stat'(Stat, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"query">>, _attrs, _els}.
 
-encode_pubsub_publish_attr_node(_val, _acc) ->
-    [{<<"node">>, _val} | _acc].
+'encode_stats_$stat'([], _acc) -> _acc;
+'encode_stats_$stat'([Stat | _els], _acc) ->
+    'encode_stats_$stat'(_els,
+                        [encode_stat(Stat, []) | _acc]).
 
-decode_pubsub({xmlel, <<"pubsub">>, _attrs, _els}) ->
-    {Affiliations, Subscriptions, Subscribe, Publish} =
-       decode_pubsub_els(_els, undefined, undefined, undefined,
-                         undefined),
-    {pubsub, Subscriptions, Affiliations, Publish,
-     Subscribe}.
+decode_stat({xmlel, <<"stat">>, _attrs, _els}) ->
+    Error = decode_stat_els(_els, []),
+    {Name, Units, Value} = decode_stat_attrs(_attrs,
+                                            undefined, undefined, undefined),
+    {stat, Name, Units, Value, Error}.
 
-decode_pubsub_els([], Affiliations, Subscriptions,
-                 Subscribe, Publish) ->
-    {Affiliations, Subscriptions, Subscribe, Publish};
-decode_pubsub_els([{xmlel, <<"subscriptions">>, _attrs,
-                   _} =
-                      _el
-                  | _els],
-                 Affiliations, Subscriptions, Subscribe, Publish) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
-          decode_pubsub_els(_els, Affiliations,
-                            decode_pubsub_subscriptions(_el), Subscribe,
-                            Publish);
-       true ->
-          decode_pubsub_els(_els, Affiliations, Subscriptions,
-                            Subscribe, Publish)
-    end;
-decode_pubsub_els([{xmlel, <<"affiliations">>, _attrs,
-                   _} =
-                      _el
-                  | _els],
-                 Affiliations, Subscriptions, Subscribe, Publish) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
-          decode_pubsub_els(_els, decode_pubsub_affiliations(_el),
-                            Subscriptions, Subscribe, Publish);
-       true ->
-          decode_pubsub_els(_els, Affiliations, Subscriptions,
-                            Subscribe, Publish)
-    end;
-decode_pubsub_els([{xmlel, <<"subscribe">>, _attrs, _} =
-                      _el
-                  | _els],
-                 Affiliations, Subscriptions, Subscribe, Publish) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
-          decode_pubsub_els(_els, Affiliations, Subscriptions,
-                            decode_pubsub_subscribe(_el), Publish);
-       true ->
-          decode_pubsub_els(_els, Affiliations, Subscriptions,
-                            Subscribe, Publish)
-    end;
-decode_pubsub_els([{xmlel, <<"publish">>, _attrs, _} =
-                      _el
-                  | _els],
-                 Affiliations, Subscriptions, Subscribe, Publish) ->
+decode_stat_els([], Error) -> lists:reverse(Error);
+decode_stat_els([{xmlel, <<"error">>, _attrs, _} = _el
+                | _els],
+               Error) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
     if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/pubsub">> ->
-          decode_pubsub_els(_els, Affiliations, Subscriptions,
-                            Subscribe, decode_pubsub_publish(_el));
-       true ->
-          decode_pubsub_els(_els, Affiliations, Subscriptions,
-                            Subscribe, Publish)
+       _xmlns == <<"http://jabber.org/protocol/stats">> ->
+          decode_stat_els(_els,
+                          case decode_stat_error(_el) of
+                            undefined -> Error;
+                            _new_el -> [_new_el | Error]
+                          end);
+       true -> decode_stat_els(_els, Error)
     end;
-decode_pubsub_els([_ | _els], Affiliations,
-                 Subscriptions, Subscribe, Publish) ->
-    decode_pubsub_els(_els, Affiliations, Subscriptions,
-                     Subscribe, Publish).
+decode_stat_els([_ | _els], Error) ->
+    decode_stat_els(_els, Error).
 
-encode_pubsub({pubsub, Subscriptions, Affiliations,
-              Publish, Subscribe},
-             _xmlns_attrs) ->
-    _els = 'encode_pubsub_$publish'(Publish,
-                                   'encode_pubsub_$subscribe'(Subscribe,
-                                                              'encode_pubsub_$subscriptions'(Subscriptions,
-                                                                                             'encode_pubsub_$affiliations'(Affiliations,
-                                                                                                                           [])))),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"pubsub">>, _attrs, _els}.
+decode_stat_attrs([{<<"name">>, _val} | _attrs], _Name,
+                 Units, Value) ->
+    decode_stat_attrs(_attrs, _val, Units, Value);
+decode_stat_attrs([{<<"units">>, _val} | _attrs], Name,
+                 _Units, Value) ->
+    decode_stat_attrs(_attrs, Name, _val, Value);
+decode_stat_attrs([{<<"value">>, _val} | _attrs], Name,
+                 Units, _Value) ->
+    decode_stat_attrs(_attrs, Name, Units, _val);
+decode_stat_attrs([_ | _attrs], Name, Units, Value) ->
+    decode_stat_attrs(_attrs, Name, Units, Value);
+decode_stat_attrs([], Name, Units, Value) ->
+    {decode_stat_attr_name(Name),
+     decode_stat_attr_units(Units),
+     decode_stat_attr_value(Value)}.
 
-'encode_pubsub_$affiliations'(undefined, _acc) -> _acc;
-'encode_pubsub_$affiliations'(Affiliations, _acc) ->
-    [encode_pubsub_affiliations(Affiliations, []) | _acc].
+encode_stat({stat, Name, Units, Value, Error},
+           _xmlns_attrs) ->
+    _els = 'encode_stat_$error'(Error, []),
+    _attrs = encode_stat_attr_value(Value,
+                                   encode_stat_attr_units(Units,
+                                                          encode_stat_attr_name(Name,
+                                                                                _xmlns_attrs))),
+    {xmlel, <<"stat">>, _attrs, _els}.
 
-'encode_pubsub_$subscriptions'(undefined, _acc) -> _acc;
-'encode_pubsub_$subscriptions'(Subscriptions, _acc) ->
-    [encode_pubsub_subscriptions(Subscriptions, []) | _acc].
+'encode_stat_$error'([], _acc) -> _acc;
+'encode_stat_$error'([Error | _els], _acc) ->
+    'encode_stat_$error'(_els,
+                        [encode_stat_error(Error, []) | _acc]).
 
-'encode_pubsub_$subscribe'(undefined, _acc) -> _acc;
-'encode_pubsub_$subscribe'(Subscribe, _acc) ->
-    [encode_pubsub_subscribe(Subscribe, []) | _acc].
+decode_stat_attr_name(undefined) ->
+    erlang:error({missing_attr, <<"name">>, <<"stat">>,
+                 <<"http://jabber.org/protocol/stats">>});
+decode_stat_attr_name(_val) -> _val.
 
-'encode_pubsub_$publish'(undefined, _acc) -> _acc;
-'encode_pubsub_$publish'(Publish, _acc) ->
-    [encode_pubsub_publish(Publish, []) | _acc].
+encode_stat_attr_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
 
-decode_delay({xmlel, <<"delay">>, _attrs, _els}) ->
-    {Stamp, From} = decode_delay_attrs(_attrs, undefined,
-                                      undefined),
-    {delay, Stamp, From}.
+decode_stat_attr_units(undefined) -> undefined;
+decode_stat_attr_units(_val) -> _val.
 
-decode_delay_attrs([{<<"stamp">>, _val} | _attrs],
-                  _Stamp, From) ->
-    decode_delay_attrs(_attrs, _val, From);
-decode_delay_attrs([{<<"from">>, _val} | _attrs], Stamp,
-                  _From) ->
-    decode_delay_attrs(_attrs, Stamp, _val);
-decode_delay_attrs([_ | _attrs], Stamp, From) ->
-    decode_delay_attrs(_attrs, Stamp, From);
-decode_delay_attrs([], Stamp, From) ->
-    {decode_delay_attr_stamp(Stamp),
-     decode_delay_attr_from(From)}.
+encode_stat_attr_units(undefined, _acc) -> _acc;
+encode_stat_attr_units(_val, _acc) ->
+    [{<<"units">>, _val} | _acc].
 
-encode_delay({delay, Stamp, From}, _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_delay_attr_from(From,
-                                   encode_delay_attr_stamp(Stamp,
-                                                           _xmlns_attrs)),
-    {xmlel, <<"delay">>, _attrs, _els}.
+decode_stat_attr_value(undefined) -> undefined;
+decode_stat_attr_value(_val) -> _val.
 
-decode_delay_attr_stamp(undefined) ->
-    erlang:error({missing_attr, <<"stamp">>, <<"delay">>,
-                 <<"urn:xmpp:delay">>});
-decode_delay_attr_stamp(_val) ->
-    case catch dec_utc(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"stamp">>, <<"delay">>,
-                       <<"urn:xmpp:delay">>});
-      _res -> _res
-    end.
+encode_stat_attr_value(undefined, _acc) -> _acc;
+encode_stat_attr_value(_val, _acc) ->
+    [{<<"value">>, _val} | _acc].
 
-encode_delay_attr_stamp(_val, _acc) ->
-    [{<<"stamp">>, enc_utc(_val)} | _acc].
+decode_stat_error({xmlel, <<"error">>, _attrs, _els}) ->
+    Cdata = decode_stat_error_els(_els, <<>>),
+    Code = decode_stat_error_attrs(_attrs, undefined),
+    {Code, Cdata}.
 
-decode_delay_attr_from(undefined) -> undefined;
-decode_delay_attr_from(_val) ->
-    case catch dec_jid(_val) of
+decode_stat_error_els([], Cdata) ->
+    decode_stat_error_cdata(Cdata);
+decode_stat_error_els([{xmlcdata, _data} | _els],
+                     Cdata) ->
+    decode_stat_error_els(_els,
+                         <<Cdata/binary, _data/binary>>);
+decode_stat_error_els([_ | _els], Cdata) ->
+    decode_stat_error_els(_els, Cdata).
+
+decode_stat_error_attrs([{<<"code">>, _val} | _attrs],
+                       _Code) ->
+    decode_stat_error_attrs(_attrs, _val);
+decode_stat_error_attrs([_ | _attrs], Code) ->
+    decode_stat_error_attrs(_attrs, Code);
+decode_stat_error_attrs([], Code) ->
+    decode_stat_error_attr_code(Code).
+
+encode_stat_error({Code, Cdata}, _xmlns_attrs) ->
+    _els = encode_stat_error_cdata(Cdata, []),
+    _attrs = encode_stat_error_attr_code(Code,
+                                        _xmlns_attrs),
+    {xmlel, <<"error">>, _attrs, _els}.
+
+decode_stat_error_attr_code(undefined) ->
+    erlang:error({missing_attr, <<"code">>, <<"error">>,
+                 <<"http://jabber.org/protocol/stats">>});
+decode_stat_error_attr_code(_val) ->
+    case catch xml_gen:dec_int(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"from">>, <<"delay">>,
-                       <<"urn:xmpp:delay">>});
+         erlang:error({bad_attr_value, <<"code">>, <<"error">>,
+                       <<"http://jabber.org/protocol/stats">>});
       _res -> _res
     end.
 
-encode_delay_attr_from(undefined, _acc) -> _acc;
-encode_delay_attr_from(_val, _acc) ->
-    [{<<"from">>, enc_jid(_val)} | _acc].
+encode_stat_error_attr_code(_val, _acc) ->
+    [{<<"code">>, xml_gen:enc_int(_val)} | _acc].
 
-decode_legacy_delay({xmlel, <<"x">>, _attrs, _els}) ->
-    {Stamp, From} = decode_legacy_delay_attrs(_attrs,
-                                             undefined, undefined),
-    {legacy_delay, Stamp, From}.
+decode_stat_error_cdata(<<>>) -> undefined;
+decode_stat_error_cdata(_val) -> _val.
 
-decode_legacy_delay_attrs([{<<"stamp">>, _val}
-                          | _attrs],
-                         _Stamp, From) ->
-    decode_legacy_delay_attrs(_attrs, _val, From);
-decode_legacy_delay_attrs([{<<"from">>, _val} | _attrs],
-                         Stamp, _From) ->
-    decode_legacy_delay_attrs(_attrs, Stamp, _val);
-decode_legacy_delay_attrs([_ | _attrs], Stamp, From) ->
-    decode_legacy_delay_attrs(_attrs, Stamp, From);
-decode_legacy_delay_attrs([], Stamp, From) ->
-    {decode_legacy_delay_attr_stamp(Stamp),
-     decode_legacy_delay_attr_from(From)}.
+encode_stat_error_cdata(undefined, _acc) -> _acc;
+encode_stat_error_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-encode_legacy_delay({legacy_delay, Stamp, From},
-                   _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_legacy_delay_attr_from(From,
-                                          encode_legacy_delay_attr_stamp(Stamp,
-                                                                         _xmlns_attrs)),
-    {xmlel, <<"x">>, _attrs, _els}.
+decode_bookmarks_storage({xmlel, <<"storage">>, _attrs,
+                         _els}) ->
+    {Conference, Url} = decode_bookmarks_storage_els(_els,
+                                                    [], []),
+    {bookmark_storage, Conference, Url}.
 
-decode_legacy_delay_attr_stamp(undefined) ->
-    erlang:error({missing_attr, <<"stamp">>, <<"x">>,
-                 <<"jabber:x:delay">>});
-decode_legacy_delay_attr_stamp(_val) -> _val.
+decode_bookmarks_storage_els([], Conference, Url) ->
+    {lists:reverse(Conference), lists:reverse(Url)};
+decode_bookmarks_storage_els([{xmlel, <<"conference">>,
+                              _attrs, _} =
+                                 _el
+                             | _els],
+                            Conference, Url) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"storage:bookmarks">> ->
+          decode_bookmarks_storage_els(_els,
+                                       case decode_bookmark_conference(_el) of
+                                         undefined -> Conference;
+                                         _new_el -> [_new_el | Conference]
+                                       end,
+                                       Url);
+       true ->
+          decode_bookmarks_storage_els(_els, Conference, Url)
+    end;
+decode_bookmarks_storage_els([{xmlel, <<"url">>, _attrs,
+                              _} =
+                                 _el
+                             | _els],
+                            Conference, Url) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"storage:bookmarks">> ->
+          decode_bookmarks_storage_els(_els, Conference,
+                                       case decode_bookmark_url(_el) of
+                                         undefined -> Url;
+                                         _new_el -> [_new_el | Url]
+                                       end);
+       true ->
+          decode_bookmarks_storage_els(_els, Conference, Url)
+    end;
+decode_bookmarks_storage_els([_ | _els], Conference,
+                            Url) ->
+    decode_bookmarks_storage_els(_els, Conference, Url).
 
-encode_legacy_delay_attr_stamp(_val, _acc) ->
-    [{<<"stamp">>, _val} | _acc].
+encode_bookmarks_storage({bookmark_storage, Conference,
+                         Url},
+                        _xmlns_attrs) ->
+    _els = 'encode_bookmarks_storage_$url'(Url,
+                                          'encode_bookmarks_storage_$conference'(Conference,
+                                                                                 [])),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"storage">>, _attrs, _els}.
 
-decode_legacy_delay_attr_from(undefined) -> undefined;
-decode_legacy_delay_attr_from(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"from">>, <<"x">>,
-                       <<"jabber:x:delay">>});
-      _res -> _res
-    end.
+'encode_bookmarks_storage_$conference'([], _acc) ->
+    _acc;
+'encode_bookmarks_storage_$conference'([Conference
+                                       | _els],
+                                      _acc) ->
+    'encode_bookmarks_storage_$conference'(_els,
+                                          [encode_bookmark_conference(Conference,
+                                                                      [])
+                                           | _acc]).
 
-encode_legacy_delay_attr_from(undefined, _acc) -> _acc;
-encode_legacy_delay_attr_from(_val, _acc) ->
-    [{<<"from">>, enc_jid(_val)} | _acc].
+'encode_bookmarks_storage_$url'([], _acc) -> _acc;
+'encode_bookmarks_storage_$url'([Url | _els], _acc) ->
+    'encode_bookmarks_storage_$url'(_els,
+                                   [encode_bookmark_url(Url, []) | _acc]).
 
-decode_bytestreams_streamhost({xmlel, <<"streamhost">>,
-                              _attrs, _els}) ->
-    {Jid, Host, Port} =
-       decode_bytestreams_streamhost_attrs(_attrs, undefined,
+decode_bookmark_url({xmlel, <<"url">>, _attrs, _els}) ->
+    {Name, Url} = decode_bookmark_url_attrs(_attrs,
                                            undefined, undefined),
-    {streamhost, Jid, Host, Port}.
+    {bookmark_url, Name, Url}.
 
-decode_bytestreams_streamhost_attrs([{<<"jid">>, _val}
-                                    | _attrs],
-                                   _Jid, Host, Port) ->
-    decode_bytestreams_streamhost_attrs(_attrs, _val, Host,
-                                       Port);
-decode_bytestreams_streamhost_attrs([{<<"host">>, _val}
-                                    | _attrs],
-                                   Jid, _Host, Port) ->
-    decode_bytestreams_streamhost_attrs(_attrs, Jid, _val,
-                                       Port);
-decode_bytestreams_streamhost_attrs([{<<"port">>, _val}
-                                    | _attrs],
-                                   Jid, Host, _Port) ->
-    decode_bytestreams_streamhost_attrs(_attrs, Jid, Host,
-                                       _val);
-decode_bytestreams_streamhost_attrs([_ | _attrs], Jid,
-                                   Host, Port) ->
-    decode_bytestreams_streamhost_attrs(_attrs, Jid, Host,
-                                       Port);
-decode_bytestreams_streamhost_attrs([], Jid, Host,
-                                   Port) ->
-    {decode_bytestreams_streamhost_attr_jid(Jid),
-     decode_bytestreams_streamhost_attr_host(Host),
-     decode_bytestreams_streamhost_attr_port(Port)}.
+decode_bookmark_url_attrs([{<<"name">>, _val} | _attrs],
+                         _Name, Url) ->
+    decode_bookmark_url_attrs(_attrs, _val, Url);
+decode_bookmark_url_attrs([{<<"url">>, _val} | _attrs],
+                         Name, _Url) ->
+    decode_bookmark_url_attrs(_attrs, Name, _val);
+decode_bookmark_url_attrs([_ | _attrs], Name, Url) ->
+    decode_bookmark_url_attrs(_attrs, Name, Url);
+decode_bookmark_url_attrs([], Name, Url) ->
+    {decode_bookmark_url_attr_name(Name),
+     decode_bookmark_url_attr_url(Url)}.
 
-encode_bytestreams_streamhost({streamhost, Jid, Host,
-                              Port},
-                             _xmlns_attrs) ->
+encode_bookmark_url({bookmark_url, Name, Url},
+                   _xmlns_attrs) ->
     _els = [],
-    _attrs = encode_bytestreams_streamhost_attr_port(Port,
-                                                    encode_bytestreams_streamhost_attr_host(Host,
-                                                                                            encode_bytestreams_streamhost_attr_jid(Jid,
-                                                                                                                                   _xmlns_attrs))),
-    {xmlel, <<"streamhost">>, _attrs, _els}.
+    _attrs = encode_bookmark_url_attr_url(Url,
+                                         encode_bookmark_url_attr_name(Name,
+                                                                       _xmlns_attrs)),
+    {xmlel, <<"url">>, _attrs, _els}.
 
-decode_bytestreams_streamhost_attr_jid(undefined) ->
-    erlang:error({missing_attr, <<"jid">>, <<"streamhost">>,
-                 <<"http://jabber.org/protocol/bytestreams">>});
-decode_bytestreams_streamhost_attr_jid(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"jid">>,
-                       <<"streamhost">>,
-                       <<"http://jabber.org/protocol/bytestreams">>});
-      _res -> _res
-    end.
+decode_bookmark_url_attr_name(undefined) ->
+    erlang:error({missing_attr, <<"name">>, <<"url">>,
+                 <<"storage:bookmarks">>});
+decode_bookmark_url_attr_name(_val) -> _val.
 
-encode_bytestreams_streamhost_attr_jid(_val, _acc) ->
-    [{<<"jid">>, enc_jid(_val)} | _acc].
+encode_bookmark_url_attr_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
 
-decode_bytestreams_streamhost_attr_host(undefined) ->
-    erlang:error({missing_attr, <<"host">>,
-                 <<"streamhost">>,
-                 <<"http://jabber.org/protocol/bytestreams">>});
-decode_bytestreams_streamhost_attr_host(_val) -> _val.
+decode_bookmark_url_attr_url(undefined) ->
+    erlang:error({missing_attr, <<"url">>, <<"url">>,
+                 <<"storage:bookmarks">>});
+decode_bookmark_url_attr_url(_val) -> _val.
 
-encode_bytestreams_streamhost_attr_host(_val, _acc) ->
-    [{<<"host">>, _val} | _acc].
+encode_bookmark_url_attr_url(_val, _acc) ->
+    [{<<"url">>, _val} | _acc].
 
-decode_bytestreams_streamhost_attr_port(undefined) ->
-    1080;
-decode_bytestreams_streamhost_attr_port(_val) ->
-    case catch xml_gen:dec_int(_val, 0, 65535) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"port">>,
-                       <<"streamhost">>,
-                       <<"http://jabber.org/protocol/bytestreams">>});
-      _res -> _res
-    end.
+decode_bookmark_conference({xmlel, <<"conference">>,
+                           _attrs, _els}) ->
+    {Password, Nick} = decode_bookmark_conference_els(_els,
+                                                     undefined, undefined),
+    {Name, Jid, Autojoin} =
+       decode_bookmark_conference_attrs(_attrs, undefined,
+                                        undefined, undefined),
+    {bookmark_conference, Name, Jid, Autojoin, Nick,
+     Password}.
 
-encode_bytestreams_streamhost_attr_port(1080, _acc) ->
+decode_bookmark_conference_els([], Password, Nick) ->
+    {Password, Nick};
+decode_bookmark_conference_els([{xmlel, <<"nick">>,
+                                _attrs, _} =
+                                   _el
+                               | _els],
+                              Password, Nick) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"storage:bookmarks">> ->
+          decode_bookmark_conference_els(_els, Password,
+                                         decode_conference_nick(_el));
+       true ->
+          decode_bookmark_conference_els(_els, Password, Nick)
+    end;
+decode_bookmark_conference_els([{xmlel, <<"password">>,
+                                _attrs, _} =
+                                   _el
+                               | _els],
+                              Password, Nick) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"storage:bookmarks">> ->
+          decode_bookmark_conference_els(_els,
+                                         decode_conference_password(_el),
+                                         Nick);
+       true ->
+          decode_bookmark_conference_els(_els, Password, Nick)
+    end;
+decode_bookmark_conference_els([_ | _els], Password,
+                              Nick) ->
+    decode_bookmark_conference_els(_els, Password, Nick).
+
+decode_bookmark_conference_attrs([{<<"name">>, _val}
+                                 | _attrs],
+                                _Name, Jid, Autojoin) ->
+    decode_bookmark_conference_attrs(_attrs, _val, Jid,
+                                    Autojoin);
+decode_bookmark_conference_attrs([{<<"jid">>, _val}
+                                 | _attrs],
+                                Name, _Jid, Autojoin) ->
+    decode_bookmark_conference_attrs(_attrs, Name, _val,
+                                    Autojoin);
+decode_bookmark_conference_attrs([{<<"autojoin">>, _val}
+                                 | _attrs],
+                                Name, Jid, _Autojoin) ->
+    decode_bookmark_conference_attrs(_attrs, Name, Jid,
+                                    _val);
+decode_bookmark_conference_attrs([_ | _attrs], Name,
+                                Jid, Autojoin) ->
+    decode_bookmark_conference_attrs(_attrs, Name, Jid,
+                                    Autojoin);
+decode_bookmark_conference_attrs([], Name, Jid,
+                                Autojoin) ->
+    {decode_bookmark_conference_attr_name(Name),
+     decode_bookmark_conference_attr_jid(Jid),
+     decode_bookmark_conference_attr_autojoin(Autojoin)}.
+
+encode_bookmark_conference({bookmark_conference, Name,
+                           Jid, Autojoin, Nick, Password},
+                          _xmlns_attrs) ->
+    _els = 'encode_bookmark_conference_$nick'(Nick,
+                                             'encode_bookmark_conference_$password'(Password,
+                                                                                    [])),
+    _attrs =
+       encode_bookmark_conference_attr_autojoin(Autojoin,
+                                                encode_bookmark_conference_attr_jid(Jid,
+                                                                                    encode_bookmark_conference_attr_name(Name,
+                                                                                                                         _xmlns_attrs))),
+    {xmlel, <<"conference">>, _attrs, _els}.
+
+'encode_bookmark_conference_$password'(undefined,
+                                      _acc) ->
     _acc;
-encode_bytestreams_streamhost_attr_port(_val, _acc) ->
-    [{<<"port">>, xml_gen:enc_int(_val)} | _acc].
+'encode_bookmark_conference_$password'(Password,
+                                      _acc) ->
+    [encode_conference_password(Password, []) | _acc].
 
-decode_bytestreams_streamhost_used({xmlel,
-                                   <<"streamhost-used">>, _attrs, _els}) ->
-    Jid = decode_bytestreams_streamhost_used_attrs(_attrs,
-                                                  undefined),
-    Jid.
+'encode_bookmark_conference_$nick'(undefined, _acc) ->
+    _acc;
+'encode_bookmark_conference_$nick'(Nick, _acc) ->
+    [encode_conference_nick(Nick, []) | _acc].
 
-decode_bytestreams_streamhost_used_attrs([{<<"jid">>,
-                                          _val}
-                                         | _attrs],
-                                        _Jid) ->
-    decode_bytestreams_streamhost_used_attrs(_attrs, _val);
-decode_bytestreams_streamhost_used_attrs([_ | _attrs],
-                                        Jid) ->
-    decode_bytestreams_streamhost_used_attrs(_attrs, Jid);
-decode_bytestreams_streamhost_used_attrs([], Jid) ->
-    decode_bytestreams_streamhost_used_attr_jid(Jid).
+decode_bookmark_conference_attr_name(undefined) ->
+    erlang:error({missing_attr, <<"name">>,
+                 <<"conference">>, <<"storage:bookmarks">>});
+decode_bookmark_conference_attr_name(_val) -> _val.
 
-encode_bytestreams_streamhost_used(Jid, _xmlns_attrs) ->
-    _els = [],
-    _attrs =
-       encode_bytestreams_streamhost_used_attr_jid(Jid,
-                                                   _xmlns_attrs),
-    {xmlel, <<"streamhost-used">>, _attrs, _els}.
+encode_bookmark_conference_attr_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
 
-decode_bytestreams_streamhost_used_attr_jid(undefined) ->
-    erlang:error({missing_attr, <<"jid">>,
-                 <<"streamhost-used">>,
-                 <<"http://jabber.org/protocol/bytestreams">>});
-decode_bytestreams_streamhost_used_attr_jid(_val) ->
+decode_bookmark_conference_attr_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>, <<"conference">>,
+                 <<"storage:bookmarks">>});
+decode_bookmark_conference_attr_jid(_val) ->
     case catch dec_jid(_val) of
       {'EXIT', _} ->
          erlang:error({bad_attr_value, <<"jid">>,
-                       <<"streamhost-used">>,
-                       <<"http://jabber.org/protocol/bytestreams">>});
+                       <<"conference">>, <<"storage:bookmarks">>});
       _res -> _res
     end.
 
-encode_bytestreams_streamhost_used_attr_jid(_val,
-                                           _acc) ->
+encode_bookmark_conference_attr_jid(_val, _acc) ->
     [{<<"jid">>, enc_jid(_val)} | _acc].
 
-decode_bytestreams_activate({xmlel, <<"activate">>,
-                            _attrs, _els}) ->
-    Cdata = decode_bytestreams_activate_els(_els, <<>>),
-    Cdata.
-
-decode_bytestreams_activate_els([], Cdata) ->
-    decode_bytestreams_activate_cdata(Cdata);
-decode_bytestreams_activate_els([{xmlcdata, _data}
-                                | _els],
-                               Cdata) ->
-    decode_bytestreams_activate_els(_els,
-                                   <<Cdata/binary, _data/binary>>);
-decode_bytestreams_activate_els([_ | _els], Cdata) ->
-    decode_bytestreams_activate_els(_els, Cdata).
-
-encode_bytestreams_activate(Cdata, _xmlns_attrs) ->
-    _els = encode_bytestreams_activate_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"activate">>, _attrs, _els}.
-
-decode_bytestreams_activate_cdata(<<>>) -> undefined;
-decode_bytestreams_activate_cdata(_val) ->
-    case catch dec_jid(_val) of
+decode_bookmark_conference_attr_autojoin(undefined) ->
+    false;
+decode_bookmark_conference_attr_autojoin(_val) ->
+    case catch dec_bool(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_cdata_value, <<>>, <<"activate">>,
-                       <<"http://jabber.org/protocol/bytestreams">>});
+         erlang:error({bad_attr_value, <<"autojoin">>,
+                       <<"conference">>, <<"storage:bookmarks">>});
       _res -> _res
     end.
 
-encode_bytestreams_activate_cdata(undefined, _acc) ->
+encode_bookmark_conference_attr_autojoin(false, _acc) ->
     _acc;
-encode_bytestreams_activate_cdata(_val, _acc) ->
-    [{xmlcdata, enc_jid(_val)} | _acc].
+encode_bookmark_conference_attr_autojoin(_val, _acc) ->
+    [{<<"autojoin">>, enc_bool(_val)} | _acc].
 
-decode_bytestreams({xmlel, <<"query">>, _attrs,
-                   _els}) ->
-    {Hosts, Used, Activate} = decode_bytestreams_els(_els,
-                                                    [], undefined, undefined),
-    {Dstaddr, Sid, Mode} = decode_bytestreams_attrs(_attrs,
-                                                   undefined, undefined,
-                                                   undefined),
-    {bytestreams, Hosts, Used, Activate, Dstaddr, Mode,
-     Sid}.
+decode_conference_password({xmlel, <<"password">>,
+                           _attrs, _els}) ->
+    Cdata = decode_conference_password_els(_els, <<>>),
+    Cdata.
 
-decode_bytestreams_els([], Hosts, Used, Activate) ->
-    {lists:reverse(Hosts), Used, Activate};
-decode_bytestreams_els([{xmlel, <<"streamhost">>,
-                        _attrs, _} =
-                           _el
-                       | _els],
-                      Hosts, Used, Activate) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns ==
-        <<"http://jabber.org/protocol/bytestreams">> ->
-          decode_bytestreams_els(_els,
-                                 case decode_bytestreams_streamhost(_el) of
-                                   undefined -> Hosts;
-                                   _new_el -> [_new_el | Hosts]
-                                 end,
-                                 Used, Activate);
-       true ->
-          decode_bytestreams_els(_els, Hosts, Used, Activate)
-    end;
-decode_bytestreams_els([{xmlel, <<"streamhost-used">>,
-                        _attrs, _} =
-                           _el
-                       | _els],
-                      Hosts, Used, Activate) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns ==
-        <<"http://jabber.org/protocol/bytestreams">> ->
-          decode_bytestreams_els(_els, Hosts,
-                                 decode_bytestreams_streamhost_used(_el),
-                                 Activate);
-       true ->
-          decode_bytestreams_els(_els, Hosts, Used, Activate)
-    end;
-decode_bytestreams_els([{xmlel, <<"activate">>, _attrs,
-                        _} =
-                           _el
-                       | _els],
-                      Hosts, Used, Activate) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns ==
-        <<"http://jabber.org/protocol/bytestreams">> ->
-          decode_bytestreams_els(_els, Hosts, Used,
-                                 decode_bytestreams_activate(_el));
-       true ->
-          decode_bytestreams_els(_els, Hosts, Used, Activate)
-    end;
-decode_bytestreams_els([_ | _els], Hosts, Used,
-                      Activate) ->
-    decode_bytestreams_els(_els, Hosts, Used, Activate).
+decode_conference_password_els([], Cdata) ->
+    decode_conference_password_cdata(Cdata);
+decode_conference_password_els([{xmlcdata, _data}
+                               | _els],
+                              Cdata) ->
+    decode_conference_password_els(_els,
+                                  <<Cdata/binary, _data/binary>>);
+decode_conference_password_els([_ | _els], Cdata) ->
+    decode_conference_password_els(_els, Cdata).
 
-decode_bytestreams_attrs([{<<"dstaddr">>, _val}
-                         | _attrs],
-                        _Dstaddr, Sid, Mode) ->
-    decode_bytestreams_attrs(_attrs, _val, Sid, Mode);
-decode_bytestreams_attrs([{<<"sid">>, _val} | _attrs],
-                        Dstaddr, _Sid, Mode) ->
-    decode_bytestreams_attrs(_attrs, Dstaddr, _val, Mode);
-decode_bytestreams_attrs([{<<"mode">>, _val} | _attrs],
-                        Dstaddr, Sid, _Mode) ->
-    decode_bytestreams_attrs(_attrs, Dstaddr, Sid, _val);
-decode_bytestreams_attrs([_ | _attrs], Dstaddr, Sid,
-                        Mode) ->
-    decode_bytestreams_attrs(_attrs, Dstaddr, Sid, Mode);
-decode_bytestreams_attrs([], Dstaddr, Sid, Mode) ->
-    {decode_bytestreams_attr_dstaddr(Dstaddr),
-     decode_bytestreams_attr_sid(Sid),
-     decode_bytestreams_attr_mode(Mode)}.
+encode_conference_password(Cdata, _xmlns_attrs) ->
+    _els = encode_conference_password_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"password">>, _attrs, _els}.
 
-encode_bytestreams({bytestreams, Hosts, Used, Activate,
-                   Dstaddr, Mode, Sid},
-                  _xmlns_attrs) ->
-    _els = 'encode_bytestreams_$activate'(Activate,
-                                         'encode_bytestreams_$used'(Used,
-                                                                    'encode_bytestreams_$hosts'(Hosts,
-                                                                                                []))),
-    _attrs = encode_bytestreams_attr_mode(Mode,
-                                         encode_bytestreams_attr_sid(Sid,
-                                                                     encode_bytestreams_attr_dstaddr(Dstaddr,
-                                                                                                     _xmlns_attrs))),
-    {xmlel, <<"query">>, _attrs, _els}.
+decode_conference_password_cdata(<<>>) -> undefined;
+decode_conference_password_cdata(_val) -> _val.
 
-'encode_bytestreams_$hosts'([], _acc) -> _acc;
-'encode_bytestreams_$hosts'([Hosts | _els], _acc) ->
-    'encode_bytestreams_$hosts'(_els,
-                               [encode_bytestreams_streamhost(Hosts, [])
-                                | _acc]).
+encode_conference_password_cdata(undefined, _acc) ->
+    _acc;
+encode_conference_password_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-'encode_bytestreams_$used'(undefined, _acc) -> _acc;
-'encode_bytestreams_$used'(Used, _acc) ->
-    [encode_bytestreams_streamhost_used(Used, []) | _acc].
+decode_conference_nick({xmlel, <<"nick">>, _attrs,
+                       _els}) ->
+    Cdata = decode_conference_nick_els(_els, <<>>), Cdata.
 
-'encode_bytestreams_$activate'(undefined, _acc) -> _acc;
-'encode_bytestreams_$activate'(Activate, _acc) ->
-    [encode_bytestreams_activate(Activate, []) | _acc].
+decode_conference_nick_els([], Cdata) ->
+    decode_conference_nick_cdata(Cdata);
+decode_conference_nick_els([{xmlcdata, _data} | _els],
+                          Cdata) ->
+    decode_conference_nick_els(_els,
+                              <<Cdata/binary, _data/binary>>);
+decode_conference_nick_els([_ | _els], Cdata) ->
+    decode_conference_nick_els(_els, Cdata).
 
-decode_bytestreams_attr_dstaddr(undefined) -> undefined;
-decode_bytestreams_attr_dstaddr(_val) -> _val.
+encode_conference_nick(Cdata, _xmlns_attrs) ->
+    _els = encode_conference_nick_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"nick">>, _attrs, _els}.
 
-encode_bytestreams_attr_dstaddr(undefined, _acc) ->
-    _acc;
-encode_bytestreams_attr_dstaddr(_val, _acc) ->
-    [{<<"dstaddr">>, _val} | _acc].
+decode_conference_nick_cdata(<<>>) -> undefined;
+decode_conference_nick_cdata(_val) -> _val.
 
-decode_bytestreams_attr_sid(undefined) -> undefined;
-decode_bytestreams_attr_sid(_val) -> _val.
+encode_conference_nick_cdata(undefined, _acc) -> _acc;
+encode_conference_nick_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-encode_bytestreams_attr_sid(undefined, _acc) -> _acc;
-encode_bytestreams_attr_sid(_val, _acc) ->
-    [{<<"sid">>, _val} | _acc].
+decode_private({xmlel, <<"query">>, _attrs, _els}) ->
+    __Els = decode_private_els(_els, []), {private, __Els}.
 
-decode_bytestreams_attr_mode(undefined) -> tcp;
-decode_bytestreams_attr_mode(_val) ->
-    case catch xml_gen:dec_enum(_val, [tcp, udp]) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"mode">>, <<"query">>,
-                       <<"http://jabber.org/protocol/bytestreams">>});
-      _res -> _res
-    end.
+decode_private_els([], __Els) -> lists:reverse(__Els);
+decode_private_els([{xmlel, _, _, _} = _el | _els],
+                  __Els) ->
+    decode_private_els(_els, [decode(_el) | __Els]);
+decode_private_els([_ | _els], __Els) ->
+    decode_private_els(_els, __Els).
 
-encode_bytestreams_attr_mode(tcp, _acc) -> _acc;
-encode_bytestreams_attr_mode(_val, _acc) ->
-    [{<<"mode">>, xml_gen:enc_enum(_val)} | _acc].
+encode_private({private, __Els}, _xmlns_attrs) ->
+    _els = [encode(_el) || _el <- __Els],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"query">>, _attrs, _els}.
 
-decode_muc_history({xmlel, <<"history">>, _attrs,
+decode_disco_items({xmlel, <<"query">>, _attrs,
                    _els}) ->
-    {Maxchars, Maxstanzas, Seconds, Since} =
-       decode_muc_history_attrs(_attrs, undefined, undefined,
-                                undefined, undefined),
-    {muc_history, Maxchars, Maxstanzas, Seconds, Since}.
+    Items = decode_disco_items_els(_els, []),
+    Node = decode_disco_items_attrs(_attrs, undefined),
+    {disco_items, Node, Items}.
 
-decode_muc_history_attrs([{<<"maxchars">>, _val}
-                         | _attrs],
-                        _Maxchars, Maxstanzas, Seconds, Since) ->
-    decode_muc_history_attrs(_attrs, _val, Maxstanzas,
-                            Seconds, Since);
-decode_muc_history_attrs([{<<"maxstanzas">>, _val}
-                         | _attrs],
-                        Maxchars, _Maxstanzas, Seconds, Since) ->
-    decode_muc_history_attrs(_attrs, Maxchars, _val,
-                            Seconds, Since);
-decode_muc_history_attrs([{<<"seconds">>, _val}
-                         | _attrs],
-                        Maxchars, Maxstanzas, _Seconds, Since) ->
-    decode_muc_history_attrs(_attrs, Maxchars, Maxstanzas,
-                            _val, Since);
-decode_muc_history_attrs([{<<"since">>, _val} | _attrs],
-                        Maxchars, Maxstanzas, Seconds, _Since) ->
-    decode_muc_history_attrs(_attrs, Maxchars, Maxstanzas,
-                            Seconds, _val);
-decode_muc_history_attrs([_ | _attrs], Maxchars,
-                        Maxstanzas, Seconds, Since) ->
-    decode_muc_history_attrs(_attrs, Maxchars, Maxstanzas,
-                            Seconds, Since);
-decode_muc_history_attrs([], Maxchars, Maxstanzas,
-                        Seconds, Since) ->
-    {decode_muc_history_attr_maxchars(Maxchars),
-     decode_muc_history_attr_maxstanzas(Maxstanzas),
-     decode_muc_history_attr_seconds(Seconds),
-     decode_muc_history_attr_since(Since)}.
+decode_disco_items_els([], Items) ->
+    lists:reverse(Items);
+decode_disco_items_els([{xmlel, <<"item">>, _attrs, _} =
+                           _el
+                       | _els],
+                      Items) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns ==
+        <<"http://jabber.org/protocol/disco#items">> ->
+          decode_disco_items_els(_els,
+                                 case decode_disco_item(_el) of
+                                   undefined -> Items;
+                                   _new_el -> [_new_el | Items]
+                                 end);
+       true -> decode_disco_items_els(_els, Items)
+    end;
+decode_disco_items_els([_ | _els], Items) ->
+    decode_disco_items_els(_els, Items).
 
-encode_muc_history({muc_history, Maxchars, Maxstanzas,
-                   Seconds, Since},
+decode_disco_items_attrs([{<<"node">>, _val} | _attrs],
+                        _Node) ->
+    decode_disco_items_attrs(_attrs, _val);
+decode_disco_items_attrs([_ | _attrs], Node) ->
+    decode_disco_items_attrs(_attrs, Node);
+decode_disco_items_attrs([], Node) ->
+    decode_disco_items_attr_node(Node).
+
+encode_disco_items({disco_items, Node, Items},
                   _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_muc_history_attr_since(Since,
-                                          encode_muc_history_attr_seconds(Seconds,
-                                                                          encode_muc_history_attr_maxstanzas(Maxstanzas,
-                                                                                                             encode_muc_history_attr_maxchars(Maxchars,
-                                                                                                                                              _xmlns_attrs)))),
-    {xmlel, <<"history">>, _attrs, _els}.
+    _els = 'encode_disco_items_$items'(Items, []),
+    _attrs = encode_disco_items_attr_node(Node,
+                                         _xmlns_attrs),
+    {xmlel, <<"query">>, _attrs, _els}.
 
-decode_muc_history_attr_maxchars(undefined) ->
-    undefined;
-decode_muc_history_attr_maxchars(_val) ->
-    case catch xml_gen:dec_int(_val, 0, infinity) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"maxchars">>,
-                       <<"history">>, <<"http://jabber.org/protocol/muc">>});
-      _res -> _res
-    end.
+'encode_disco_items_$items'([], _acc) -> _acc;
+'encode_disco_items_$items'([Items | _els], _acc) ->
+    'encode_disco_items_$items'(_els,
+                               [encode_disco_item(Items, []) | _acc]).
 
-encode_muc_history_attr_maxchars(undefined, _acc) ->
-    _acc;
-encode_muc_history_attr_maxchars(_val, _acc) ->
-    [{<<"maxchars">>, xml_gen:enc_int(_val)} | _acc].
+decode_disco_items_attr_node(undefined) -> undefined;
+decode_disco_items_attr_node(_val) -> _val.
 
-decode_muc_history_attr_maxstanzas(undefined) ->
-    undefined;
-decode_muc_history_attr_maxstanzas(_val) ->
-    case catch xml_gen:dec_int(_val, 0, infinity) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"maxstanzas">>,
-                       <<"history">>, <<"http://jabber.org/protocol/muc">>});
-      _res -> _res
-    end.
+encode_disco_items_attr_node(undefined, _acc) -> _acc;
+encode_disco_items_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
-encode_muc_history_attr_maxstanzas(undefined, _acc) ->
-    _acc;
-encode_muc_history_attr_maxstanzas(_val, _acc) ->
-    [{<<"maxstanzas">>, xml_gen:enc_int(_val)} | _acc].
+decode_disco_item({xmlel, <<"item">>, _attrs, _els}) ->
+    {Jid, Name, Node} = decode_disco_item_attrs(_attrs,
+                                               undefined, undefined,
+                                               undefined),
+    {disco_item, Jid, Name, Node}.
 
-decode_muc_history_attr_seconds(undefined) -> undefined;
-decode_muc_history_attr_seconds(_val) ->
-    case catch xml_gen:dec_int(_val, 0, infinity) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"seconds">>,
-                       <<"history">>, <<"http://jabber.org/protocol/muc">>});
-      _res -> _res
-    end.
+decode_disco_item_attrs([{<<"jid">>, _val} | _attrs],
+                       _Jid, Name, Node) ->
+    decode_disco_item_attrs(_attrs, _val, Name, Node);
+decode_disco_item_attrs([{<<"name">>, _val} | _attrs],
+                       Jid, _Name, Node) ->
+    decode_disco_item_attrs(_attrs, Jid, _val, Node);
+decode_disco_item_attrs([{<<"node">>, _val} | _attrs],
+                       Jid, Name, _Node) ->
+    decode_disco_item_attrs(_attrs, Jid, Name, _val);
+decode_disco_item_attrs([_ | _attrs], Jid, Name,
+                       Node) ->
+    decode_disco_item_attrs(_attrs, Jid, Name, Node);
+decode_disco_item_attrs([], Jid, Name, Node) ->
+    {decode_disco_item_attr_jid(Jid),
+     decode_disco_item_attr_name(Name),
+     decode_disco_item_attr_node(Node)}.
 
-encode_muc_history_attr_seconds(undefined, _acc) ->
-    _acc;
-encode_muc_history_attr_seconds(_val, _acc) ->
-    [{<<"seconds">>, xml_gen:enc_int(_val)} | _acc].
+encode_disco_item({disco_item, Jid, Name, Node},
+                 _xmlns_attrs) ->
+    _els = [],
+    _attrs = encode_disco_item_attr_node(Node,
+                                        encode_disco_item_attr_name(Name,
+                                                                    encode_disco_item_attr_jid(Jid,
+                                                                                               _xmlns_attrs))),
+    {xmlel, <<"item">>, _attrs, _els}.
 
-decode_muc_history_attr_since(undefined) -> undefined;
-decode_muc_history_attr_since(_val) ->
-    case catch dec_utc(_val) of
+decode_disco_item_attr_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>, <<"item">>,
+                 <<"http://jabber.org/protocol/disco#items">>});
+decode_disco_item_attr_jid(_val) ->
+    case catch dec_jid(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"since">>,
-                       <<"history">>, <<"http://jabber.org/protocol/muc">>});
+         erlang:error({bad_attr_value, <<"jid">>, <<"item">>,
+                       <<"http://jabber.org/protocol/disco#items">>});
       _res -> _res
     end.
 
-encode_muc_history_attr_since(undefined, _acc) -> _acc;
-encode_muc_history_attr_since(_val, _acc) ->
-    [{<<"since">>, enc_utc(_val)} | _acc].
-
-decode_muc_user_reason({xmlel, <<"reason">>, _attrs,
-                       _els}) ->
-    Cdata = decode_muc_user_reason_els(_els, <<>>), Cdata.
+encode_disco_item_attr_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
 
-decode_muc_user_reason_els([], Cdata) ->
-    decode_muc_user_reason_cdata(Cdata);
-decode_muc_user_reason_els([{xmlcdata, _data} | _els],
-                          Cdata) ->
-    decode_muc_user_reason_els(_els,
-                              <<Cdata/binary, _data/binary>>);
-decode_muc_user_reason_els([_ | _els], Cdata) ->
-    decode_muc_user_reason_els(_els, Cdata).
+decode_disco_item_attr_name(undefined) -> undefined;
+decode_disco_item_attr_name(_val) -> _val.
 
-encode_muc_user_reason(Cdata, _xmlns_attrs) ->
-    _els = encode_muc_user_reason_cdata(Cdata, []),
-    _attrs = _xmlns_attrs,
-    {xmlel, <<"reason">>, _attrs, _els}.
+encode_disco_item_attr_name(undefined, _acc) -> _acc;
+encode_disco_item_attr_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
 
-decode_muc_user_reason_cdata(<<>>) -> undefined;
-decode_muc_user_reason_cdata(_val) -> _val.
+decode_disco_item_attr_node(undefined) -> undefined;
+decode_disco_item_attr_node(_val) -> _val.
 
-encode_muc_user_reason_cdata(undefined, _acc) -> _acc;
-encode_muc_user_reason_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+encode_disco_item_attr_node(undefined, _acc) -> _acc;
+encode_disco_item_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
 
-decode_muc_user_decline({xmlel, <<"decline">>, _attrs,
-                        _els}) ->
-    Reason = decode_muc_user_decline_els(_els, undefined),
-    {To, From} = decode_muc_user_decline_attrs(_attrs,
-                                              undefined, undefined),
-    {muc_decline, Reason, From, To}.
+decode_disco_info({xmlel, <<"query">>, _attrs, _els}) ->
+    {Xdata, Feature, Identity} = decode_disco_info_els(_els,
+                                                      [], [], []),
+    Node = decode_disco_info_attrs(_attrs, undefined),
+    {disco_info, Node, Identity, Feature, Xdata}.
 
-decode_muc_user_decline_els([], Reason) -> Reason;
-decode_muc_user_decline_els([{xmlel, <<"reason">>,
-                             _attrs, _} =
-                                _el
-                            | _els],
-                           Reason) ->
+decode_disco_info_els([], Xdata, Feature, Identity) ->
+    {lists:reverse(Xdata), lists:reverse(Feature),
+     lists:reverse(Identity)};
+decode_disco_info_els([{xmlel, <<"identity">>, _attrs,
+                       _} =
+                          _el
+                      | _els],
+                     Xdata, Feature, Identity) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
     if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
-          decode_muc_user_decline_els(_els,
-                                      decode_muc_user_reason(_el));
-       true -> decode_muc_user_decline_els(_els, Reason)
+       _xmlns == <<"http://jabber.org/protocol/disco#info">> ->
+          decode_disco_info_els(_els, Xdata, Feature,
+                                case decode_disco_identity(_el) of
+                                  undefined -> Identity;
+                                  _new_el -> [_new_el | Identity]
+                                end);
+       true ->
+          decode_disco_info_els(_els, Xdata, Feature, Identity)
     end;
-decode_muc_user_decline_els([_ | _els], Reason) ->
-    decode_muc_user_decline_els(_els, Reason).
+decode_disco_info_els([{xmlel, <<"feature">>, _attrs,
+                       _} =
+                          _el
+                      | _els],
+                     Xdata, Feature, Identity) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>;
+       _xmlns == <<"http://jabber.org/protocol/disco#info">> ->
+          decode_disco_info_els(_els, Xdata,
+                                case decode_disco_feature(_el) of
+                                  undefined -> Feature;
+                                  _new_el -> [_new_el | Feature]
+                                end,
+                                Identity);
+       true ->
+          decode_disco_info_els(_els, Xdata, Feature, Identity)
+    end;
+decode_disco_info_els([{xmlel, <<"x">>, _attrs, _} = _el
+                      | _els],
+                     Xdata, Feature, Identity) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<"jabber:x:data">> ->
+          decode_disco_info_els(_els,
+                                case decode_xdata(_el) of
+                                  undefined -> Xdata;
+                                  _new_el -> [_new_el | Xdata]
+                                end,
+                                Feature, Identity);
+       true ->
+          decode_disco_info_els(_els, Xdata, Feature, Identity)
+    end;
+decode_disco_info_els([_ | _els], Xdata, Feature,
+                     Identity) ->
+    decode_disco_info_els(_els, Xdata, Feature, Identity).
+
+decode_disco_info_attrs([{<<"node">>, _val} | _attrs],
+                       _Node) ->
+    decode_disco_info_attrs(_attrs, _val);
+decode_disco_info_attrs([_ | _attrs], Node) ->
+    decode_disco_info_attrs(_attrs, Node);
+decode_disco_info_attrs([], Node) ->
+    decode_disco_info_attr_node(Node).
+
+encode_disco_info({disco_info, Node, Identity, Feature,
+                  Xdata},
+                 _xmlns_attrs) ->
+    _els = 'encode_disco_info_$identity'(Identity,
+                                        'encode_disco_info_$feature'(Feature,
+                                                                     'encode_disco_info_$xdata'(Xdata,
+                                                                                                []))),
+    _attrs = encode_disco_info_attr_node(Node,
+                                        _xmlns_attrs),
+    {xmlel, <<"query">>, _attrs, _els}.
+
+'encode_disco_info_$xdata'([], _acc) -> _acc;
+'encode_disco_info_$xdata'([Xdata | _els], _acc) ->
+    'encode_disco_info_$xdata'(_els,
+                              [encode_xdata(Xdata,
+                                            [{<<"xmlns">>,
+                                              <<"jabber:x:data">>}])
+                               | _acc]).
+
+'encode_disco_info_$feature'([], _acc) -> _acc;
+'encode_disco_info_$feature'([Feature | _els], _acc) ->
+    'encode_disco_info_$feature'(_els,
+                                [encode_disco_feature(Feature, []) | _acc]).
+
+'encode_disco_info_$identity'([], _acc) -> _acc;
+'encode_disco_info_$identity'([Identity | _els],
+                             _acc) ->
+    'encode_disco_info_$identity'(_els,
+                                 [encode_disco_identity(Identity, []) | _acc]).
+
+decode_disco_info_attr_node(undefined) -> undefined;
+decode_disco_info_attr_node(_val) -> _val.
+
+encode_disco_info_attr_node(undefined, _acc) -> _acc;
+encode_disco_info_attr_node(_val, _acc) ->
+    [{<<"node">>, _val} | _acc].
+
+decode_disco_feature({xmlel, <<"feature">>, _attrs,
+                     _els}) ->
+    Var = decode_disco_feature_attrs(_attrs, undefined),
+    Var.
 
-decode_muc_user_decline_attrs([{<<"to">>, _val}
-                              | _attrs],
-                             _To, From) ->
-    decode_muc_user_decline_attrs(_attrs, _val, From);
-decode_muc_user_decline_attrs([{<<"from">>, _val}
-                              | _attrs],
-                             To, _From) ->
-    decode_muc_user_decline_attrs(_attrs, To, _val);
-decode_muc_user_decline_attrs([_ | _attrs], To, From) ->
-    decode_muc_user_decline_attrs(_attrs, To, From);
-decode_muc_user_decline_attrs([], To, From) ->
-    {decode_muc_user_decline_attr_to(To),
-     decode_muc_user_decline_attr_from(From)}.
+decode_disco_feature_attrs([{<<"var">>, _val} | _attrs],
+                          _Var) ->
+    decode_disco_feature_attrs(_attrs, _val);
+decode_disco_feature_attrs([_ | _attrs], Var) ->
+    decode_disco_feature_attrs(_attrs, Var);
+decode_disco_feature_attrs([], Var) ->
+    decode_disco_feature_attr_var(Var).
 
-encode_muc_user_decline({muc_decline, Reason, From, To},
-                       _xmlns_attrs) ->
-    _els = 'encode_muc_user_decline_$reason'(Reason, []),
-    _attrs = encode_muc_user_decline_attr_from(From,
-                                              encode_muc_user_decline_attr_to(To,
-                                                                              _xmlns_attrs)),
-    {xmlel, <<"decline">>, _attrs, _els}.
+encode_disco_feature(Var, _xmlns_attrs) ->
+    _els = [],
+    _attrs = encode_disco_feature_attr_var(Var,
+                                          _xmlns_attrs),
+    {xmlel, <<"feature">>, _attrs, _els}.
 
-'encode_muc_user_decline_$reason'(undefined, _acc) ->
-    _acc;
-'encode_muc_user_decline_$reason'(Reason, _acc) ->
-    [encode_muc_user_reason(Reason, []) | _acc].
+decode_disco_feature_attr_var(undefined) ->
+    erlang:error({missing_attr, <<"var">>, <<"feature">>,
+                 <<"http://jabber.org/protocol/disco#info">>});
+decode_disco_feature_attr_var(_val) -> _val.
 
-decode_muc_user_decline_attr_to(undefined) -> undefined;
-decode_muc_user_decline_attr_to(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"to">>, <<"decline">>,
-                       <<"http://jabber.org/protocol/muc#user">>});
-      _res -> _res
-    end.
+encode_disco_feature_attr_var(_val, _acc) ->
+    [{<<"var">>, _val} | _acc].
 
-encode_muc_user_decline_attr_to(undefined, _acc) ->
-    _acc;
-encode_muc_user_decline_attr_to(_val, _acc) ->
-    [{<<"to">>, enc_jid(_val)} | _acc].
+decode_disco_identity({xmlel, <<"identity">>, _attrs,
+                      _els}) ->
+    {Category, Type, Name} =
+       decode_disco_identity_attrs(_attrs, undefined,
+                                   undefined, undefined),
+    {identity, Category, Type, Name}.
 
-decode_muc_user_decline_attr_from(undefined) ->
-    undefined;
-decode_muc_user_decline_attr_from(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"from">>, <<"decline">>,
-                       <<"http://jabber.org/protocol/muc#user">>});
-      _res -> _res
-    end.
+decode_disco_identity_attrs([{<<"category">>, _val}
+                            | _attrs],
+                           _Category, Type, Name) ->
+    decode_disco_identity_attrs(_attrs, _val, Type, Name);
+decode_disco_identity_attrs([{<<"type">>, _val}
+                            | _attrs],
+                           Category, _Type, Name) ->
+    decode_disco_identity_attrs(_attrs, Category, _val,
+                               Name);
+decode_disco_identity_attrs([{<<"name">>, _val}
+                            | _attrs],
+                           Category, Type, _Name) ->
+    decode_disco_identity_attrs(_attrs, Category, Type,
+                               _val);
+decode_disco_identity_attrs([_ | _attrs], Category,
+                           Type, Name) ->
+    decode_disco_identity_attrs(_attrs, Category, Type,
+                               Name);
+decode_disco_identity_attrs([], Category, Type, Name) ->
+    {decode_disco_identity_attr_category(Category),
+     decode_disco_identity_attr_type(Type),
+     decode_disco_identity_attr_name(Name)}.
 
-encode_muc_user_decline_attr_from(undefined, _acc) ->
-    _acc;
-encode_muc_user_decline_attr_from(_val, _acc) ->
-    [{<<"from">>, enc_jid(_val)} | _acc].
+encode_disco_identity({identity, Category, Type, Name},
+                     _xmlns_attrs) ->
+    _els = [],
+    _attrs = encode_disco_identity_attr_name(Name,
+                                            encode_disco_identity_attr_type(Type,
+                                                                            encode_disco_identity_attr_category(Category,
+                                                                                                                _xmlns_attrs))),
+    {xmlel, <<"identity">>, _attrs, _els}.
 
-decode_muc_user_destroy({xmlel, <<"destroy">>, _attrs,
-                        _els}) ->
-    Reason = decode_muc_user_destroy_els(_els, undefined),
-    Jid = decode_muc_user_destroy_attrs(_attrs, undefined),
-    {muc_user_destroy, Reason, Jid}.
+decode_disco_identity_attr_category(undefined) ->
+    erlang:error({missing_attr, <<"category">>,
+                 <<"identity">>,
+                 <<"http://jabber.org/protocol/disco#info">>});
+decode_disco_identity_attr_category(_val) -> _val.
 
-decode_muc_user_destroy_els([], Reason) -> Reason;
-decode_muc_user_destroy_els([{xmlel, <<"reason">>,
-                             _attrs, _} =
-                                _el
-                            | _els],
-                           Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
-          decode_muc_user_destroy_els(_els,
-                                      decode_muc_user_reason(_el));
-       true -> decode_muc_user_destroy_els(_els, Reason)
-    end;
-decode_muc_user_destroy_els([_ | _els], Reason) ->
-    decode_muc_user_destroy_els(_els, Reason).
+encode_disco_identity_attr_category(_val, _acc) ->
+    [{<<"category">>, _val} | _acc].
 
-decode_muc_user_destroy_attrs([{<<"jid">>, _val}
-                              | _attrs],
-                             _Jid) ->
-    decode_muc_user_destroy_attrs(_attrs, _val);
-decode_muc_user_destroy_attrs([_ | _attrs], Jid) ->
-    decode_muc_user_destroy_attrs(_attrs, Jid);
-decode_muc_user_destroy_attrs([], Jid) ->
-    decode_muc_user_destroy_attr_jid(Jid).
+decode_disco_identity_attr_type(undefined) ->
+    erlang:error({missing_attr, <<"type">>, <<"identity">>,
+                 <<"http://jabber.org/protocol/disco#info">>});
+decode_disco_identity_attr_type(_val) -> _val.
 
-encode_muc_user_destroy({muc_user_destroy, Reason, Jid},
-                       _xmlns_attrs) ->
-    _els = 'encode_muc_user_destroy_$reason'(Reason, []),
-    _attrs = encode_muc_user_destroy_attr_jid(Jid,
-                                             _xmlns_attrs),
-    {xmlel, <<"destroy">>, _attrs, _els}.
+encode_disco_identity_attr_type(_val, _acc) ->
+    [{<<"type">>, _val} | _acc].
 
-'encode_muc_user_destroy_$reason'(undefined, _acc) ->
+decode_disco_identity_attr_name(undefined) -> undefined;
+decode_disco_identity_attr_name(_val) -> _val.
+
+encode_disco_identity_attr_name(undefined, _acc) ->
     _acc;
-'encode_muc_user_destroy_$reason'(Reason, _acc) ->
-    [encode_muc_user_reason(Reason, []) | _acc].
+encode_disco_identity_attr_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
 
-decode_muc_user_destroy_attr_jid(undefined) ->
-    undefined;
-decode_muc_user_destroy_attr_jid(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"jid">>, <<"destroy">>,
-                       <<"http://jabber.org/protocol/muc#user">>});
-      _res -> _res
-    end.
+decode_block_list({xmlel, <<"blocklist">>, _attrs,
+                  _els}) ->
+    {block_list}.
 
-encode_muc_user_destroy_attr_jid(undefined, _acc) ->
-    _acc;
-encode_muc_user_destroy_attr_jid(_val, _acc) ->
-    [{<<"jid">>, enc_jid(_val)} | _acc].
+encode_block_list({block_list}, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"blocklist">>, _attrs, _els}.
 
-decode_muc_user_invite({xmlel, <<"invite">>, _attrs,
-                       _els}) ->
-    Reason = decode_muc_user_invite_els(_els, undefined),
-    {To, From} = decode_muc_user_invite_attrs(_attrs,
-                                             undefined, undefined),
-    {muc_invite, Reason, From, To}.
+decode_unblock({xmlel, <<"unblock">>, _attrs, _els}) ->
+    Items = decode_unblock_els(_els, []), {unblock, Items}.
 
-decode_muc_user_invite_els([], Reason) -> Reason;
-decode_muc_user_invite_els([{xmlel, <<"reason">>,
-                            _attrs, _} =
-                               _el
-                           | _els],
-                          Reason) ->
+decode_unblock_els([], Items) -> lists:reverse(Items);
+decode_unblock_els([{xmlel, <<"item">>, _attrs, _} = _el
+                   | _els],
+                  Items) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
-          decode_muc_user_invite_els(_els,
-                                     decode_muc_user_reason(_el));
-       true -> decode_muc_user_invite_els(_els, Reason)
+    if _xmlns == <<>>; _xmlns == <<"urn:xmpp:blocking">> ->
+          decode_unblock_els(_els,
+                             case decode_block_item(_el) of
+                               undefined -> Items;
+                               _new_el -> [_new_el | Items]
+                             end);
+       true -> decode_unblock_els(_els, Items)
     end;
-decode_muc_user_invite_els([_ | _els], Reason) ->
-    decode_muc_user_invite_els(_els, Reason).
-
-decode_muc_user_invite_attrs([{<<"to">>, _val}
-                             | _attrs],
-                            _To, From) ->
-    decode_muc_user_invite_attrs(_attrs, _val, From);
-decode_muc_user_invite_attrs([{<<"from">>, _val}
-                             | _attrs],
-                            To, _From) ->
-    decode_muc_user_invite_attrs(_attrs, To, _val);
-decode_muc_user_invite_attrs([_ | _attrs], To, From) ->
-    decode_muc_user_invite_attrs(_attrs, To, From);
-decode_muc_user_invite_attrs([], To, From) ->
-    {decode_muc_user_invite_attr_to(To),
-     decode_muc_user_invite_attr_from(From)}.
-
-encode_muc_user_invite({muc_invite, Reason, From, To},
-                      _xmlns_attrs) ->
-    _els = 'encode_muc_user_invite_$reason'(Reason, []),
-    _attrs = encode_muc_user_invite_attr_from(From,
-                                             encode_muc_user_invite_attr_to(To,
-                                                                            _xmlns_attrs)),
-    {xmlel, <<"invite">>, _attrs, _els}.
+decode_unblock_els([_ | _els], Items) ->
+    decode_unblock_els(_els, Items).
 
-'encode_muc_user_invite_$reason'(undefined, _acc) ->
-    _acc;
-'encode_muc_user_invite_$reason'(Reason, _acc) ->
-    [encode_muc_user_reason(Reason, []) | _acc].
+encode_unblock({unblock, Items}, _xmlns_attrs) ->
+    _els = 'encode_unblock_$items'(Items, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"unblock">>, _attrs, _els}.
 
-decode_muc_user_invite_attr_to(undefined) -> undefined;
-decode_muc_user_invite_attr_to(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"to">>, <<"invite">>,
-                       <<"http://jabber.org/protocol/muc#user">>});
-      _res -> _res
-    end.
+'encode_unblock_$items'([], _acc) -> _acc;
+'encode_unblock_$items'([Items | _els], _acc) ->
+    'encode_unblock_$items'(_els,
+                           [encode_block_item(Items, []) | _acc]).
 
-encode_muc_user_invite_attr_to(undefined, _acc) -> _acc;
-encode_muc_user_invite_attr_to(_val, _acc) ->
-    [{<<"to">>, enc_jid(_val)} | _acc].
+decode_block({xmlel, <<"block">>, _attrs, _els}) ->
+    Items = decode_block_els(_els, []), {block, Items}.
 
-decode_muc_user_invite_attr_from(undefined) ->
-    undefined;
-decode_muc_user_invite_attr_from(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"from">>, <<"invite">>,
-                       <<"http://jabber.org/protocol/muc#user">>});
-      _res -> _res
-    end.
+decode_block_els([], Items) -> lists:reverse(Items);
+decode_block_els([{xmlel, <<"item">>, _attrs, _} = _el
+                 | _els],
+                Items) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"urn:xmpp:blocking">> ->
+          decode_block_els(_els,
+                           case decode_block_item(_el) of
+                             undefined -> Items;
+                             _new_el -> [_new_el | Items]
+                           end);
+       true -> decode_block_els(_els, Items)
+    end;
+decode_block_els([_ | _els], Items) ->
+    decode_block_els(_els, Items).
 
-encode_muc_user_invite_attr_from(undefined, _acc) ->
-    _acc;
-encode_muc_user_invite_attr_from(_val, _acc) ->
-    [{<<"from">>, enc_jid(_val)} | _acc].
+encode_block({block, Items}, _xmlns_attrs) ->
+    _els = 'encode_block_$items'(Items, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"block">>, _attrs, _els}.
 
-decode_muc_user_actor({xmlel, <<"actor">>, _attrs,
-                      _els}) ->
-    {Jid, Nick} = decode_muc_user_actor_attrs(_attrs,
-                                             undefined, undefined),
-    {muc_actor, Jid, Nick}.
+'encode_block_$items'([], _acc) -> _acc;
+'encode_block_$items'([Items | _els], _acc) ->
+    'encode_block_$items'(_els,
+                         [encode_block_item(Items, []) | _acc]).
 
-decode_muc_user_actor_attrs([{<<"jid">>, _val}
-                            | _attrs],
-                           _Jid, Nick) ->
-    decode_muc_user_actor_attrs(_attrs, _val, Nick);
-decode_muc_user_actor_attrs([{<<"nick">>, _val}
-                            | _attrs],
-                           Jid, _Nick) ->
-    decode_muc_user_actor_attrs(_attrs, Jid, _val);
-decode_muc_user_actor_attrs([_ | _attrs], Jid, Nick) ->
-    decode_muc_user_actor_attrs(_attrs, Jid, Nick);
-decode_muc_user_actor_attrs([], Jid, Nick) ->
-    {decode_muc_user_actor_attr_jid(Jid),
-     decode_muc_user_actor_attr_nick(Nick)}.
+decode_block_item({xmlel, <<"item">>, _attrs, _els}) ->
+    Jid = decode_block_item_attrs(_attrs, undefined), Jid.
 
-encode_muc_user_actor({muc_actor, Jid, Nick},
-                     _xmlns_attrs) ->
+decode_block_item_attrs([{<<"jid">>, _val} | _attrs],
+                       _Jid) ->
+    decode_block_item_attrs(_attrs, _val);
+decode_block_item_attrs([_ | _attrs], Jid) ->
+    decode_block_item_attrs(_attrs, Jid);
+decode_block_item_attrs([], Jid) ->
+    decode_block_item_attr_jid(Jid).
+
+encode_block_item(Jid, _xmlns_attrs) ->
     _els = [],
-    _attrs = encode_muc_user_actor_attr_nick(Nick,
-                                            encode_muc_user_actor_attr_jid(Jid,
-                                                                           _xmlns_attrs)),
-    {xmlel, <<"actor">>, _attrs, _els}.
+    _attrs = encode_block_item_attr_jid(Jid, _xmlns_attrs),
+    {xmlel, <<"item">>, _attrs, _els}.
 
-decode_muc_user_actor_attr_jid(undefined) -> undefined;
-decode_muc_user_actor_attr_jid(_val) ->
+decode_block_item_attr_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>, <<"item">>,
+                 <<"urn:xmpp:blocking">>});
+decode_block_item_attr_jid(_val) ->
     case catch dec_jid(_val) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"jid">>, <<"actor">>,
-                       <<"http://jabber.org/protocol/muc#user">>});
+         erlang:error({bad_attr_value, <<"jid">>, <<"item">>,
+                       <<"urn:xmpp:blocking">>});
       _res -> _res
     end.
 
-encode_muc_user_actor_attr_jid(undefined, _acc) -> _acc;
-encode_muc_user_actor_attr_jid(_val, _acc) ->
+encode_block_item_attr_jid(_val, _acc) ->
     [{<<"jid">>, enc_jid(_val)} | _acc].
 
-decode_muc_user_actor_attr_nick(undefined) -> undefined;
-decode_muc_user_actor_attr_nick(_val) -> _val.
+decode_privacy({xmlel, <<"query">>, _attrs, _els}) ->
+    {Lists, Default, Active} = decode_privacy_els(_els, [],
+                                                 undefined, undefined),
+    {privacy, Lists, Default, Active}.
 
-encode_muc_user_actor_attr_nick(undefined, _acc) ->
-    _acc;
-encode_muc_user_actor_attr_nick(_val, _acc) ->
-    [{<<"nick">>, _val} | _acc].
+decode_privacy_els([], Lists, Default, Active) ->
+    {lists:reverse(Lists), Default, Active};
+decode_privacy_els([{xmlel, <<"list">>, _attrs, _} = _el
+                   | _els],
+                  Lists, Default, Active) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
+          decode_privacy_els(_els,
+                             case decode_privacy_list(_el) of
+                               undefined -> Lists;
+                               _new_el -> [_new_el | Lists]
+                             end,
+                             Default, Active);
+       true -> decode_privacy_els(_els, Lists, Default, Active)
+    end;
+decode_privacy_els([{xmlel, <<"default">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Lists, Default, Active) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
+          decode_privacy_els(_els, Lists,
+                             decode_privacy_default_list(_el), Active);
+       true -> decode_privacy_els(_els, Lists, Default, Active)
+    end;
+decode_privacy_els([{xmlel, <<"active">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Lists, Default, Active) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
+          decode_privacy_els(_els, Lists, Default,
+                             decode_privacy_active_list(_el));
+       true -> decode_privacy_els(_els, Lists, Default, Active)
+    end;
+decode_privacy_els([_ | _els], Lists, Default,
+                  Active) ->
+    decode_privacy_els(_els, Lists, Default, Active).
 
-decode_muc_user_continue({xmlel, <<"continue">>, _attrs,
-                         _els}) ->
-    Thread = decode_muc_user_continue_attrs(_attrs,
+encode_privacy({privacy, Lists, Default, Active},
+              _xmlns_attrs) ->
+    _els = 'encode_privacy_$active'(Active,
+                                   'encode_privacy_$default'(Default,
+                                                             'encode_privacy_$lists'(Lists,
+                                                                                     []))),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"query">>, _attrs, _els}.
+
+'encode_privacy_$lists'([], _acc) -> _acc;
+'encode_privacy_$lists'([Lists | _els], _acc) ->
+    'encode_privacy_$lists'(_els,
+                           [encode_privacy_list(Lists, []) | _acc]).
+
+'encode_privacy_$default'(undefined, _acc) -> _acc;
+'encode_privacy_$default'(Default, _acc) ->
+    [encode_privacy_default_list(Default, []) | _acc].
+
+'encode_privacy_$active'(undefined, _acc) -> _acc;
+'encode_privacy_$active'(Active, _acc) ->
+    [encode_privacy_active_list(Active, []) | _acc].
+
+decode_privacy_active_list({xmlel, <<"active">>, _attrs,
+                           _els}) ->
+    Name = decode_privacy_active_list_attrs(_attrs,
                                            undefined),
-    Thread.
+    Name.
 
-decode_muc_user_continue_attrs([{<<"thread">>, _val}
-                               | _attrs],
-                              _Thread) ->
-    decode_muc_user_continue_attrs(_attrs, _val);
-decode_muc_user_continue_attrs([_ | _attrs], Thread) ->
-    decode_muc_user_continue_attrs(_attrs, Thread);
-decode_muc_user_continue_attrs([], Thread) ->
-    decode_muc_user_continue_attr_thread(Thread).
+decode_privacy_active_list_attrs([{<<"name">>, _val}
+                                 | _attrs],
+                                _Name) ->
+    decode_privacy_active_list_attrs(_attrs, _val);
+decode_privacy_active_list_attrs([_ | _attrs], Name) ->
+    decode_privacy_active_list_attrs(_attrs, Name);
+decode_privacy_active_list_attrs([], Name) ->
+    decode_privacy_active_list_attr_name(Name).
 
-encode_muc_user_continue(Thread, _xmlns_attrs) ->
+encode_privacy_active_list(Name, _xmlns_attrs) ->
     _els = [],
-    _attrs = encode_muc_user_continue_attr_thread(Thread,
+    _attrs = encode_privacy_active_list_attr_name(Name,
                                                  _xmlns_attrs),
-    {xmlel, <<"continue">>, _attrs, _els}.
+    {xmlel, <<"active">>, _attrs, _els}.
 
-decode_muc_user_continue_attr_thread(undefined) ->
-    undefined;
-decode_muc_user_continue_attr_thread(_val) -> _val.
+decode_privacy_active_list_attr_name(undefined) -> none;
+decode_privacy_active_list_attr_name(_val) -> _val.
 
-encode_muc_user_continue_attr_thread(undefined, _acc) ->
+encode_privacy_active_list_attr_name(none, _acc) ->
     _acc;
-encode_muc_user_continue_attr_thread(_val, _acc) ->
-    [{<<"thread">>, _val} | _acc].
+encode_privacy_active_list_attr_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
+
+decode_privacy_default_list({xmlel, <<"default">>,
+                            _attrs, _els}) ->
+    Name = decode_privacy_default_list_attrs(_attrs,
+                                            undefined),
+    Name.
+
+decode_privacy_default_list_attrs([{<<"name">>, _val}
+                                  | _attrs],
+                                 _Name) ->
+    decode_privacy_default_list_attrs(_attrs, _val);
+decode_privacy_default_list_attrs([_ | _attrs], Name) ->
+    decode_privacy_default_list_attrs(_attrs, Name);
+decode_privacy_default_list_attrs([], Name) ->
+    decode_privacy_default_list_attr_name(Name).
+
+encode_privacy_default_list(Name, _xmlns_attrs) ->
+    _els = [],
+    _attrs = encode_privacy_default_list_attr_name(Name,
+                                                  _xmlns_attrs),
+    {xmlel, <<"default">>, _attrs, _els}.
+
+decode_privacy_default_list_attr_name(undefined) ->
+    none;
+decode_privacy_default_list_attr_name(_val) -> _val.
+
+encode_privacy_default_list_attr_name(none, _acc) ->
+    _acc;
+encode_privacy_default_list_attr_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
+
+decode_privacy_list({xmlel, <<"list">>, _attrs,
+                    _els}) ->
+    Items = decode_privacy_list_els(_els, []),
+    Name = decode_privacy_list_attrs(_attrs, undefined),
+    {privacy_list, Name, Items}.
+
+decode_privacy_list_els([], Items) ->
+    lists:reverse(Items);
+decode_privacy_list_els([{xmlel, <<"item">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Items) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
+          decode_privacy_list_els(_els,
+                                  case decode_privacy_item(_el) of
+                                    undefined -> Items;
+                                    _new_el -> [_new_el | Items]
+                                  end);
+       true -> decode_privacy_list_els(_els, Items)
+    end;
+decode_privacy_list_els([_ | _els], Items) ->
+    decode_privacy_list_els(_els, Items).
 
-decode_muc_user_status({xmlel, <<"status">>, _attrs,
-                       _els}) ->
-    Code = decode_muc_user_status_attrs(_attrs, undefined),
-    Code.
+decode_privacy_list_attrs([{<<"name">>, _val} | _attrs],
+                         _Name) ->
+    decode_privacy_list_attrs(_attrs, _val);
+decode_privacy_list_attrs([_ | _attrs], Name) ->
+    decode_privacy_list_attrs(_attrs, Name);
+decode_privacy_list_attrs([], Name) ->
+    decode_privacy_list_attr_name(Name).
 
-decode_muc_user_status_attrs([{<<"code">>, _val}
-                             | _attrs],
-                            _Code) ->
-    decode_muc_user_status_attrs(_attrs, _val);
-decode_muc_user_status_attrs([_ | _attrs], Code) ->
-    decode_muc_user_status_attrs(_attrs, Code);
-decode_muc_user_status_attrs([], Code) ->
-    decode_muc_user_status_attr_code(Code).
+encode_privacy_list({privacy_list, Name, Items},
+                   _xmlns_attrs) ->
+    _els = 'encode_privacy_list_$items'(Items, []),
+    _attrs = encode_privacy_list_attr_name(Name,
+                                          _xmlns_attrs),
+    {xmlel, <<"list">>, _attrs, _els}.
 
-encode_muc_user_status(Code, _xmlns_attrs) ->
-    _els = [],
-    _attrs = encode_muc_user_status_attr_code(Code,
-                                             _xmlns_attrs),
-    {xmlel, <<"status">>, _attrs, _els}.
+'encode_privacy_list_$items'([], _acc) -> _acc;
+'encode_privacy_list_$items'([Items | _els], _acc) ->
+    'encode_privacy_list_$items'(_els,
+                                [encode_privacy_item(Items, []) | _acc]).
 
-decode_muc_user_status_attr_code(undefined) ->
-    undefined;
-decode_muc_user_status_attr_code(_val) ->
-    case catch xml_gen:dec_int(_val, 100, 999) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"code">>, <<"status">>,
-                       <<"http://jabber.org/protocol/muc#user">>});
-      _res -> _res
-    end.
+decode_privacy_list_attr_name(undefined) ->
+    erlang:error({missing_attr, <<"name">>, <<"list">>,
+                 <<"jabber:iq:privacy">>});
+decode_privacy_list_attr_name(_val) -> _val.
 
-encode_muc_user_status_attr_code(undefined, _acc) ->
-    _acc;
-encode_muc_user_status_attr_code(_val, _acc) ->
-    [{<<"code">>, xml_gen:enc_int(_val)} | _acc].
+encode_privacy_list_attr_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
 
-decode_muc_user_item({xmlel, <<"item">>, _attrs,
-                     _els}) ->
-    {Actor, Continue, Reason} =
-       decode_muc_user_item_els(_els, undefined, undefined,
-                                undefined),
-    {Affiliation, Role, Jid, Nick} =
-       decode_muc_user_item_attrs(_attrs, undefined, undefined,
-                                  undefined, undefined),
-    {muc_item, Actor, Continue, Reason, Affiliation, Role,
-     Jid, Nick}.
+decode_privacy_item({xmlel, <<"item">>, _attrs,
+                    _els}) ->
+    Kinds = decode_privacy_item_els(_els, []),
+    {Action, Order, Type, Value} =
+       decode_privacy_item_attrs(_attrs, undefined, undefined,
+                                 undefined, undefined),
+    {privacy_item, Order, Action, Type, Value, Kinds}.
 
-decode_muc_user_item_els([], Actor, Continue, Reason) ->
-    {Actor, Continue, Reason};
-decode_muc_user_item_els([{xmlel, <<"actor">>, _attrs,
-                          _} =
-                             _el
-                         | _els],
-                        Actor, Continue, Reason) ->
+decode_privacy_item_els([], Kinds) ->
+    lists:reverse(Kinds);
+decode_privacy_item_els([{xmlel, <<"message">>, _attrs,
+                         _} =
+                            _el
+                        | _els],
+                       Kinds) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
-          decode_muc_user_item_els(_els,
-                                   decode_muc_user_actor(_el), Continue,
-                                   Reason);
-       true ->
-          decode_muc_user_item_els(_els, Actor, Continue, Reason)
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
+          decode_privacy_item_els(_els, Kinds);
+       true -> decode_privacy_item_els(_els, Kinds)
     end;
-decode_muc_user_item_els([{xmlel, <<"continue">>,
-                          _attrs, _} =
-                             _el
-                         | _els],
-                        Actor, Continue, Reason) ->
+decode_privacy_item_els([{xmlel, <<"iq">>, _attrs, _} =
+                            _el
+                        | _els],
+                       Kinds) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
-          decode_muc_user_item_els(_els, Actor,
-                                   decode_muc_user_continue(_el), Reason);
-       true ->
-          decode_muc_user_item_els(_els, Actor, Continue, Reason)
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
+          decode_privacy_item_els(_els, Kinds);
+       true -> decode_privacy_item_els(_els, Kinds)
     end;
-decode_muc_user_item_els([{xmlel, <<"reason">>, _attrs,
-                          _} =
-                             _el
-                         | _els],
-                        Actor, Continue, Reason) ->
+decode_privacy_item_els([{xmlel, <<"presence-in">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Kinds) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
-          decode_muc_user_item_els(_els, Actor, Continue,
-                                   decode_muc_user_reason(_el));
-       true ->
-          decode_muc_user_item_els(_els, Actor, Continue, Reason)
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
+          decode_privacy_item_els(_els, Kinds);
+       true -> decode_privacy_item_els(_els, Kinds)
     end;
-decode_muc_user_item_els([_ | _els], Actor, Continue,
-                        Reason) ->
-    decode_muc_user_item_els(_els, Actor, Continue, Reason).
+decode_privacy_item_els([{xmlel, <<"presence-out">>,
+                         _attrs, _} =
+                            _el
+                        | _els],
+                       Kinds) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:privacy">> ->
+          decode_privacy_item_els(_els, Kinds);
+       true -> decode_privacy_item_els(_els, Kinds)
+    end;
+decode_privacy_item_els([_ | _els], Kinds) ->
+    decode_privacy_item_els(_els, Kinds).
 
-decode_muc_user_item_attrs([{<<"affiliation">>, _val}
-                           | _attrs],
-                          _Affiliation, Role, Jid, Nick) ->
-    decode_muc_user_item_attrs(_attrs, _val, Role, Jid,
-                              Nick);
-decode_muc_user_item_attrs([{<<"role">>, _val}
-                           | _attrs],
-                          Affiliation, _Role, Jid, Nick) ->
-    decode_muc_user_item_attrs(_attrs, Affiliation, _val,
-                              Jid, Nick);
-decode_muc_user_item_attrs([{<<"jid">>, _val} | _attrs],
-                          Affiliation, Role, _Jid, Nick) ->
-    decode_muc_user_item_attrs(_attrs, Affiliation, Role,
-                              _val, Nick);
-decode_muc_user_item_attrs([{<<"nick">>, _val}
-                           | _attrs],
-                          Affiliation, Role, Jid, _Nick) ->
-    decode_muc_user_item_attrs(_attrs, Affiliation, Role,
-                              Jid, _val);
-decode_muc_user_item_attrs([_ | _attrs], Affiliation,
-                          Role, Jid, Nick) ->
-    decode_muc_user_item_attrs(_attrs, Affiliation, Role,
-                              Jid, Nick);
-decode_muc_user_item_attrs([], Affiliation, Role, Jid,
-                          Nick) ->
-    {decode_muc_user_item_attr_affiliation(Affiliation),
-     decode_muc_user_item_attr_role(Role),
-     decode_muc_user_item_attr_jid(Jid),
-     decode_muc_user_item_attr_nick(Nick)}.
+decode_privacy_item_attrs([{<<"action">>, _val}
+                          | _attrs],
+                         _Action, Order, Type, Value) ->
+    decode_privacy_item_attrs(_attrs, _val, Order, Type,
+                             Value);
+decode_privacy_item_attrs([{<<"order">>, _val}
+                          | _attrs],
+                         Action, _Order, Type, Value) ->
+    decode_privacy_item_attrs(_attrs, Action, _val, Type,
+                             Value);
+decode_privacy_item_attrs([{<<"type">>, _val} | _attrs],
+                         Action, Order, _Type, Value) ->
+    decode_privacy_item_attrs(_attrs, Action, Order, _val,
+                             Value);
+decode_privacy_item_attrs([{<<"value">>, _val}
+                          | _attrs],
+                         Action, Order, Type, _Value) ->
+    decode_privacy_item_attrs(_attrs, Action, Order, Type,
+                             _val);
+decode_privacy_item_attrs([_ | _attrs], Action, Order,
+                         Type, Value) ->
+    decode_privacy_item_attrs(_attrs, Action, Order, Type,
+                             Value);
+decode_privacy_item_attrs([], Action, Order, Type,
+                         Value) ->
+    {decode_privacy_item_attr_action(Action),
+     decode_privacy_item_attr_order(Order),
+     decode_privacy_item_attr_type(Type),
+     decode_privacy_item_attr_value(Value)}.
 
-encode_muc_user_item({muc_item, Actor, Continue, Reason,
-                     Affiliation, Role, Jid, Nick},
-                    _xmlns_attrs) ->
-    _els = 'encode_muc_user_item_$reason'(Reason,
-                                         'encode_muc_user_item_$continue'(Continue,
-                                                                          'encode_muc_user_item_$actor'(Actor,
-                                                                                                        []))),
-    _attrs = encode_muc_user_item_attr_nick(Nick,
-                                           encode_muc_user_item_attr_jid(Jid,
-                                                                         encode_muc_user_item_attr_role(Role,
-                                                                                                        encode_muc_user_item_attr_affiliation(Affiliation,
-                                                                                                                                              _xmlns_attrs)))),
+encode_privacy_item({privacy_item, Order, Action, Type,
+                    Value, Kinds},
+                   _xmlns_attrs) ->
+    _els = 'encode_privacy_item_$kinds'(Kinds, []),
+    _attrs = encode_privacy_item_attr_value(Value,
+                                           encode_privacy_item_attr_type(Type,
+                                                                         encode_privacy_item_attr_order(Order,
+                                                                                                        encode_privacy_item_attr_action(Action,
+                                                                                                                                        _xmlns_attrs)))),
     {xmlel, <<"item">>, _attrs, _els}.
 
-'encode_muc_user_item_$actor'(undefined, _acc) -> _acc;
-'encode_muc_user_item_$actor'(Actor, _acc) ->
-    [encode_muc_user_actor(Actor, []) | _acc].
-
-'encode_muc_user_item_$continue'(undefined, _acc) ->
-    _acc;
-'encode_muc_user_item_$continue'(Continue, _acc) ->
-    [encode_muc_user_continue(Continue, []) | _acc].
-
-'encode_muc_user_item_$reason'(undefined, _acc) -> _acc;
-'encode_muc_user_item_$reason'(Reason, _acc) ->
-    [encode_muc_user_reason(Reason, []) | _acc].
+'encode_privacy_item_$kinds'([], _acc) -> _acc;
+'encode_privacy_item_$kinds'([message = Kinds | _els],
+                            _acc) ->
+    'encode_privacy_item_$kinds'(_els,
+                                [encode_privacy_message(Kinds, []) | _acc]);
+'encode_privacy_item_$kinds'([iq = Kinds | _els],
+                            _acc) ->
+    'encode_privacy_item_$kinds'(_els,
+                                [encode_privacy_iq(Kinds, []) | _acc]);
+'encode_privacy_item_$kinds'(['presence-in' = Kinds
+                             | _els],
+                            _acc) ->
+    'encode_privacy_item_$kinds'(_els,
+                                [encode_privacy_presence_in(Kinds, [])
+                                 | _acc]);
+'encode_privacy_item_$kinds'(['presence-out' = Kinds
+                             | _els],
+                            _acc) ->
+    'encode_privacy_item_$kinds'(_els,
+                                [encode_privacy_presence_out(Kinds, [])
+                                 | _acc]).
 
-decode_muc_user_item_attr_affiliation(undefined) ->
-    undefined;
-decode_muc_user_item_attr_affiliation(_val) ->
-    case catch xml_gen:dec_enum(_val,
-                               [admin, member, none, outcast, owner])
-       of
+decode_privacy_item_attr_action(undefined) ->
+    erlang:error({missing_attr, <<"action">>, <<"item">>,
+                 <<"jabber:iq:privacy">>});
+decode_privacy_item_attr_action(_val) ->
+    case catch xml_gen:dec_enum(_val, [allow, deny]) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"affiliation">>,
-                       <<"item">>, <<"http://jabber.org/protocol/muc#user">>});
+         erlang:error({bad_attr_value, <<"action">>, <<"item">>,
+                       <<"jabber:iq:privacy">>});
       _res -> _res
     end.
 
-encode_muc_user_item_attr_affiliation(undefined,
-                                     _acc) ->
-    _acc;
-encode_muc_user_item_attr_affiliation(_val, _acc) ->
-    [{<<"affiliation">>, xml_gen:enc_enum(_val)} | _acc].
+encode_privacy_item_attr_action(_val, _acc) ->
+    [{<<"action">>, xml_gen:enc_enum(_val)} | _acc].
 
-decode_muc_user_item_attr_role(undefined) -> undefined;
-decode_muc_user_item_attr_role(_val) ->
-    case catch xml_gen:dec_enum(_val,
-                               [moderator, none, participant, visitor])
-       of
+decode_privacy_item_attr_order(undefined) ->
+    erlang:error({missing_attr, <<"order">>, <<"item">>,
+                 <<"jabber:iq:privacy">>});
+decode_privacy_item_attr_order(_val) ->
+    case catch xml_gen:dec_int(_val, 0, infinity) of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"role">>, <<"item">>,
-                       <<"http://jabber.org/protocol/muc#user">>});
+         erlang:error({bad_attr_value, <<"order">>, <<"item">>,
+                       <<"jabber:iq:privacy">>});
       _res -> _res
     end.
 
-encode_muc_user_item_attr_role(undefined, _acc) -> _acc;
-encode_muc_user_item_attr_role(_val, _acc) ->
-    [{<<"role">>, xml_gen:enc_enum(_val)} | _acc].
+encode_privacy_item_attr_order(_val, _acc) ->
+    [{<<"order">>, xml_gen:enc_int(_val)} | _acc].
 
-decode_muc_user_item_attr_jid(undefined) -> undefined;
-decode_muc_user_item_attr_jid(_val) ->
-    case catch dec_jid(_val) of
+decode_privacy_item_attr_type(undefined) -> undefined;
+decode_privacy_item_attr_type(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [group, jid, subscription])
+       of
       {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"jid">>, <<"item">>,
-                       <<"http://jabber.org/protocol/muc#user">>});
+         erlang:error({bad_attr_value, <<"type">>, <<"item">>,
+                       <<"jabber:iq:privacy">>});
       _res -> _res
     end.
 
-encode_muc_user_item_attr_jid(undefined, _acc) -> _acc;
-encode_muc_user_item_attr_jid(_val, _acc) ->
-    [{<<"jid">>, enc_jid(_val)} | _acc].
+encode_privacy_item_attr_type(undefined, _acc) -> _acc;
+encode_privacy_item_attr_type(_val, _acc) ->
+    [{<<"type">>, xml_gen:enc_enum(_val)} | _acc].
 
-decode_muc_user_item_attr_nick(undefined) -> undefined;
-decode_muc_user_item_attr_nick(_val) -> _val.
+decode_privacy_item_attr_value(undefined) -> undefined;
+decode_privacy_item_attr_value(_val) -> _val.
 
-encode_muc_user_item_attr_nick(undefined, _acc) -> _acc;
-encode_muc_user_item_attr_nick(_val, _acc) ->
-    [{<<"nick">>, _val} | _acc].
+encode_privacy_item_attr_value(undefined, _acc) -> _acc;
+encode_privacy_item_attr_value(_val, _acc) ->
+    [{<<"value">>, _val} | _acc].
 
-decode_muc_user({xmlel, <<"x">>, _attrs, _els}) ->
-    {Status_codes, Items, Invites, Decline, Destroy} =
-       decode_muc_user_els(_els, [], [], [], undefined,
-                           undefined),
-    Password = decode_muc_user_attrs(_attrs, undefined),
-    {muc_user, Decline, Destroy, Invites, Items,
-     Status_codes, Password}.
+decode_privacy_presence_out({xmlel, <<"presence-out">>,
+                            _attrs, _els}) ->
+    'presence-out'.
 
-decode_muc_user_els([], Status_codes, Items, Invites,
-                   Decline, Destroy) ->
-    {lists:reverse(Status_codes), lists:reverse(Items),
-     lists:reverse(Invites), Decline, Destroy};
-decode_muc_user_els([{xmlel, <<"decline">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Status_codes, Items, Invites, Decline, Destroy) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
-          decode_muc_user_els(_els, Status_codes, Items, Invites,
-                              decode_muc_user_decline(_el), Destroy);
-       true ->
-          decode_muc_user_els(_els, Status_codes, Items, Invites,
-                              Decline, Destroy)
-    end;
-decode_muc_user_els([{xmlel, <<"destroy">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Status_codes, Items, Invites, Decline, Destroy) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
-          decode_muc_user_els(_els, Status_codes, Items, Invites,
-                              Decline, decode_muc_user_destroy(_el));
-       true ->
-          decode_muc_user_els(_els, Status_codes, Items, Invites,
-                              Decline, Destroy)
-    end;
-decode_muc_user_els([{xmlel, <<"invite">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Status_codes, Items, Invites, Decline, Destroy) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
-          decode_muc_user_els(_els, Status_codes, Items,
-                              case decode_muc_user_invite(_el) of
-                                undefined -> Invites;
-                                _new_el -> [_new_el | Invites]
-                              end,
-                              Decline, Destroy);
-       true ->
-          decode_muc_user_els(_els, Status_codes, Items, Invites,
-                              Decline, Destroy)
-    end;
-decode_muc_user_els([{xmlel, <<"item">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Status_codes, Items, Invites, Decline, Destroy) ->
+encode_privacy_presence_out('presence-out',
+                           _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"presence-out">>, _attrs, _els}.
+
+decode_privacy_presence_in({xmlel, <<"presence-in">>,
+                           _attrs, _els}) ->
+    'presence-in'.
+
+encode_privacy_presence_in('presence-in',
+                          _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"presence-in">>, _attrs, _els}.
+
+decode_privacy_iq({xmlel, <<"iq">>, _attrs, _els}) ->
+    iq.
+
+encode_privacy_iq(iq, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"iq">>, _attrs, _els}.
+
+decode_privacy_message({xmlel, <<"message">>, _attrs,
+                       _els}) ->
+    message.
+
+encode_privacy_message(message, _xmlns_attrs) ->
+    _els = [],
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"message">>, _attrs, _els}.
+
+decode_roster({xmlel, <<"query">>, _attrs, _els}) ->
+    Items = decode_roster_els(_els, []),
+    Ver = decode_roster_attrs(_attrs, undefined),
+    {roster, Items, Ver}.
+
+decode_roster_els([], Items) -> lists:reverse(Items);
+decode_roster_els([{xmlel, <<"item">>, _attrs, _} = _el
+                  | _els],
+                 Items) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
-          decode_muc_user_els(_els, Status_codes,
-                              case decode_muc_user_item(_el) of
-                                undefined -> Items;
-                                _new_el -> [_new_el | Items]
-                              end,
-                              Invites, Decline, Destroy);
-       true ->
-          decode_muc_user_els(_els, Status_codes, Items, Invites,
-                              Decline, Destroy)
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:roster">> ->
+          decode_roster_els(_els,
+                            case decode_roster_item(_el) of
+                              undefined -> Items;
+                              _new_el -> [_new_el | Items]
+                            end);
+       true -> decode_roster_els(_els, Items)
     end;
-decode_muc_user_els([{xmlel, <<"status">>, _attrs, _} =
-                        _el
-                    | _els],
-                   Status_codes, Items, Invites, Decline, Destroy) ->
+decode_roster_els([_ | _els], Items) ->
+    decode_roster_els(_els, Items).
+
+decode_roster_attrs([{<<"ver">>, _val} | _attrs],
+                   _Ver) ->
+    decode_roster_attrs(_attrs, _val);
+decode_roster_attrs([_ | _attrs], Ver) ->
+    decode_roster_attrs(_attrs, Ver);
+decode_roster_attrs([], Ver) ->
+    decode_roster_attr_ver(Ver).
+
+encode_roster({roster, Items, Ver}, _xmlns_attrs) ->
+    _els = 'encode_roster_$items'(Items, []),
+    _attrs = encode_roster_attr_ver(Ver, _xmlns_attrs),
+    {xmlel, <<"query">>, _attrs, _els}.
+
+'encode_roster_$items'([], _acc) -> _acc;
+'encode_roster_$items'([Items | _els], _acc) ->
+    'encode_roster_$items'(_els,
+                          [encode_roster_item(Items, []) | _acc]).
+
+decode_roster_attr_ver(undefined) -> undefined;
+decode_roster_attr_ver(_val) -> _val.
+
+encode_roster_attr_ver(undefined, _acc) -> _acc;
+encode_roster_attr_ver(_val, _acc) ->
+    [{<<"ver">>, _val} | _acc].
+
+decode_roster_item({xmlel, <<"item">>, _attrs, _els}) ->
+    Groups = decode_roster_item_els(_els, []),
+    {Jid, Name, Subscription, Ask} =
+       decode_roster_item_attrs(_attrs, undefined, undefined,
+                                undefined, undefined),
+    {roster_item, Jid, Name, Groups, Subscription, Ask}.
+
+decode_roster_item_els([], Groups) ->
+    lists:reverse(Groups);
+decode_roster_item_els([{xmlel, <<"group">>, _attrs,
+                        _} =
+                           _el
+                       | _els],
+                      Groups) ->
     _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#user">> ->
-          decode_muc_user_els(_els,
-                              case decode_muc_user_status(_el) of
-                                undefined -> Status_codes;
-                                _new_el -> [_new_el | Status_codes]
-                              end,
-                              Items, Invites, Decline, Destroy);
-       true ->
-          decode_muc_user_els(_els, Status_codes, Items, Invites,
-                              Decline, Destroy)
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:roster">> ->
+          decode_roster_item_els(_els,
+                                 case decode_roster_group(_el) of
+                                   undefined -> Groups;
+                                   _new_el -> [_new_el | Groups]
+                                 end);
+       true -> decode_roster_item_els(_els, Groups)
     end;
-decode_muc_user_els([_ | _els], Status_codes, Items,
-                   Invites, Decline, Destroy) ->
-    decode_muc_user_els(_els, Status_codes, Items, Invites,
-                       Decline, Destroy).
+decode_roster_item_els([_ | _els], Groups) ->
+    decode_roster_item_els(_els, Groups).
 
-decode_muc_user_attrs([{<<"password">>, _val} | _attrs],
-                     _Password) ->
-    decode_muc_user_attrs(_attrs, _val);
-decode_muc_user_attrs([_ | _attrs], Password) ->
-    decode_muc_user_attrs(_attrs, Password);
-decode_muc_user_attrs([], Password) ->
-    decode_muc_user_attr_password(Password).
+decode_roster_item_attrs([{<<"jid">>, _val} | _attrs],
+                        _Jid, Name, Subscription, Ask) ->
+    decode_roster_item_attrs(_attrs, _val, Name,
+                            Subscription, Ask);
+decode_roster_item_attrs([{<<"name">>, _val} | _attrs],
+                        Jid, _Name, Subscription, Ask) ->
+    decode_roster_item_attrs(_attrs, Jid, _val,
+                            Subscription, Ask);
+decode_roster_item_attrs([{<<"subscription">>, _val}
+                         | _attrs],
+                        Jid, Name, _Subscription, Ask) ->
+    decode_roster_item_attrs(_attrs, Jid, Name, _val, Ask);
+decode_roster_item_attrs([{<<"ask">>, _val} | _attrs],
+                        Jid, Name, Subscription, _Ask) ->
+    decode_roster_item_attrs(_attrs, Jid, Name,
+                            Subscription, _val);
+decode_roster_item_attrs([_ | _attrs], Jid, Name,
+                        Subscription, Ask) ->
+    decode_roster_item_attrs(_attrs, Jid, Name,
+                            Subscription, Ask);
+decode_roster_item_attrs([], Jid, Name, Subscription,
+                        Ask) ->
+    {decode_roster_item_attr_jid(Jid),
+     decode_roster_item_attr_name(Name),
+     decode_roster_item_attr_subscription(Subscription),
+     decode_roster_item_attr_ask(Ask)}.
 
-encode_muc_user({muc_user, Decline, Destroy, Invites,
-                Items, Status_codes, Password},
-               _xmlns_attrs) ->
-    _els = 'encode_muc_user_$destroy'(Destroy,
-                                     'encode_muc_user_$decline'(Decline,
-                                                                'encode_muc_user_$invites'(Invites,
-                                                                                           'encode_muc_user_$items'(Items,
-                                                                                                                    'encode_muc_user_$status_codes'(Status_codes,
-                                                                                                                                                    []))))),
-    _attrs = encode_muc_user_attr_password(Password,
-                                          _xmlns_attrs),
-    {xmlel, <<"x">>, _attrs, _els}.
+encode_roster_item({roster_item, Jid, Name, Groups,
+                   Subscription, Ask},
+                  _xmlns_attrs) ->
+    _els = 'encode_roster_item_$groups'(Groups, []),
+    _attrs = encode_roster_item_attr_ask(Ask,
+                                        encode_roster_item_attr_subscription(Subscription,
+                                                                             encode_roster_item_attr_name(Name,
+                                                                                                          encode_roster_item_attr_jid(Jid,
+                                                                                                                                      _xmlns_attrs)))),
+    {xmlel, <<"item">>, _attrs, _els}.
 
-'encode_muc_user_$status_codes'([], _acc) -> _acc;
-'encode_muc_user_$status_codes'([Status_codes | _els],
-                               _acc) ->
-    'encode_muc_user_$status_codes'(_els,
-                                   [encode_muc_user_status(Status_codes, [])
-                                    | _acc]).
+'encode_roster_item_$groups'([], _acc) -> _acc;
+'encode_roster_item_$groups'([Groups | _els], _acc) ->
+    'encode_roster_item_$groups'(_els,
+                                [encode_roster_group(Groups, []) | _acc]).
 
-'encode_muc_user_$items'([], _acc) -> _acc;
-'encode_muc_user_$items'([Items | _els], _acc) ->
-    'encode_muc_user_$items'(_els,
-                            [encode_muc_user_item(Items, []) | _acc]).
+decode_roster_item_attr_jid(undefined) ->
+    erlang:error({missing_attr, <<"jid">>, <<"item">>,
+                 <<"jabber:iq:roster">>});
+decode_roster_item_attr_jid(_val) ->
+    case catch dec_jid(_val) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"jid">>, <<"item">>,
+                       <<"jabber:iq:roster">>});
+      _res -> _res
+    end.
 
-'encode_muc_user_$invites'([], _acc) -> _acc;
-'encode_muc_user_$invites'([Invites | _els], _acc) ->
-    'encode_muc_user_$invites'(_els,
-                              [encode_muc_user_invite(Invites, []) | _acc]).
+encode_roster_item_attr_jid(_val, _acc) ->
+    [{<<"jid">>, enc_jid(_val)} | _acc].
 
-'encode_muc_user_$decline'(undefined, _acc) -> _acc;
-'encode_muc_user_$decline'(Decline, _acc) ->
-    [encode_muc_user_decline(Decline, []) | _acc].
+decode_roster_item_attr_name(undefined) -> undefined;
+decode_roster_item_attr_name(_val) -> _val.
 
-'encode_muc_user_$destroy'(undefined, _acc) -> _acc;
-'encode_muc_user_$destroy'(Destroy, _acc) ->
-    [encode_muc_user_destroy(Destroy, []) | _acc].
+encode_roster_item_attr_name(undefined, _acc) -> _acc;
+encode_roster_item_attr_name(_val, _acc) ->
+    [{<<"name">>, _val} | _acc].
 
-decode_muc_user_attr_password(undefined) -> undefined;
-decode_muc_user_attr_password(_val) -> _val.
+decode_roster_item_attr_subscription(undefined) -> none;
+decode_roster_item_attr_subscription(_val) ->
+    case catch xml_gen:dec_enum(_val,
+                               [none, to, from, both, remove])
+       of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"subscription">>,
+                       <<"item">>, <<"jabber:iq:roster">>});
+      _res -> _res
+    end.
 
-encode_muc_user_attr_password(undefined, _acc) -> _acc;
-encode_muc_user_attr_password(_val, _acc) ->
-    [{<<"password">>, _val} | _acc].
+encode_roster_item_attr_subscription(none, _acc) ->
+    _acc;
+encode_roster_item_attr_subscription(_val, _acc) ->
+    [{<<"subscription">>, xml_gen:enc_enum(_val)} | _acc].
 
-decode_muc_owner_password({xmlel, <<"password">>,
-                          _attrs, _els}) ->
-    Cdata = decode_muc_owner_password_els(_els, <<>>),
-    Cdata.
+decode_roster_item_attr_ask(undefined) -> undefined;
+decode_roster_item_attr_ask(_val) ->
+    case catch xml_gen:dec_enum(_val, [subscribe]) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"ask">>, <<"item">>,
+                       <<"jabber:iq:roster">>});
+      _res -> _res
+    end.
 
-decode_muc_owner_password_els([], Cdata) ->
-    decode_muc_owner_password_cdata(Cdata);
-decode_muc_owner_password_els([{xmlcdata, _data}
-                              | _els],
-                             Cdata) ->
-    decode_muc_owner_password_els(_els,
-                                 <<Cdata/binary, _data/binary>>);
-decode_muc_owner_password_els([_ | _els], Cdata) ->
-    decode_muc_owner_password_els(_els, Cdata).
+encode_roster_item_attr_ask(undefined, _acc) -> _acc;
+encode_roster_item_attr_ask(_val, _acc) ->
+    [{<<"ask">>, xml_gen:enc_enum(_val)} | _acc].
 
-encode_muc_owner_password(Cdata, _xmlns_attrs) ->
-    _els = encode_muc_owner_password_cdata(Cdata, []),
+decode_roster_group({xmlel, <<"group">>, _attrs,
+                    _els}) ->
+    Cdata = decode_roster_group_els(_els, <<>>), Cdata.
+
+decode_roster_group_els([], Cdata) ->
+    decode_roster_group_cdata(Cdata);
+decode_roster_group_els([{xmlcdata, _data} | _els],
+                       Cdata) ->
+    decode_roster_group_els(_els,
+                           <<Cdata/binary, _data/binary>>);
+decode_roster_group_els([_ | _els], Cdata) ->
+    decode_roster_group_els(_els, Cdata).
+
+encode_roster_group(Cdata, _xmlns_attrs) ->
+    _els = encode_roster_group_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"password">>, _attrs, _els}.
+    {xmlel, <<"group">>, _attrs, _els}.
 
-decode_muc_owner_password_cdata(<<>>) -> undefined;
-decode_muc_owner_password_cdata(_val) -> _val.
+decode_roster_group_cdata(<<>>) ->
+    erlang:error({missing_cdata, <<>>, <<"group">>,
+                 <<"jabber:iq:roster">>});
+decode_roster_group_cdata(_val) -> _val.
 
-encode_muc_owner_password_cdata(undefined, _acc) ->
-    _acc;
-encode_muc_owner_password_cdata(_val, _acc) ->
+encode_roster_group_cdata(_val, _acc) ->
     [{xmlcdata, _val} | _acc].
 
-decode_muc_owner_reason({xmlel, <<"reason">>, _attrs,
-                        _els}) ->
-    Cdata = decode_muc_owner_reason_els(_els, <<>>), Cdata.
+decode_version({xmlel, <<"query">>, _attrs, _els}) ->
+    {Version_ver, Version_os, Version_name} =
+       decode_version_els(_els, undefined, undefined,
+                          undefined),
+    {version, Version_name, Version_ver, Version_os}.
 
-decode_muc_owner_reason_els([], Cdata) ->
-    decode_muc_owner_reason_cdata(Cdata);
-decode_muc_owner_reason_els([{xmlcdata, _data} | _els],
-                           Cdata) ->
-    decode_muc_owner_reason_els(_els,
-                               <<Cdata/binary, _data/binary>>);
-decode_muc_owner_reason_els([_ | _els], Cdata) ->
-    decode_muc_owner_reason_els(_els, Cdata).
+decode_version_els([], Version_ver, Version_os,
+                  Version_name) ->
+    {Version_ver, Version_os, Version_name};
+decode_version_els([{xmlel, <<"name">>, _attrs, _} = _el
+                   | _els],
+                  Version_ver, Version_os, Version_name) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:version">> ->
+          decode_version_els(_els, Version_ver, Version_os,
+                             decode_version_name(_el));
+       true ->
+          decode_version_els(_els, Version_ver, Version_os,
+                             Version_name)
+    end;
+decode_version_els([{xmlel, <<"version">>, _attrs, _} =
+                       _el
+                   | _els],
+                  Version_ver, Version_os, Version_name) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:version">> ->
+          decode_version_els(_els, decode_version_ver(_el),
+                             Version_os, Version_name);
+       true ->
+          decode_version_els(_els, Version_ver, Version_os,
+                             Version_name)
+    end;
+decode_version_els([{xmlel, <<"os">>, _attrs, _} = _el
+                   | _els],
+                  Version_ver, Version_os, Version_name) ->
+    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
+    if _xmlns == <<>>; _xmlns == <<"jabber:iq:version">> ->
+          decode_version_els(_els, Version_ver,
+                             decode_version_os(_el), Version_name);
+       true ->
+          decode_version_els(_els, Version_ver, Version_os,
+                             Version_name)
+    end;
+decode_version_els([_ | _els], Version_ver, Version_os,
+                  Version_name) ->
+    decode_version_els(_els, Version_ver, Version_os,
+                      Version_name).
 
-encode_muc_owner_reason(Cdata, _xmlns_attrs) ->
-    _els = encode_muc_owner_reason_cdata(Cdata, []),
+encode_version({version, Version_name, Version_ver,
+               Version_os},
+              _xmlns_attrs) ->
+    _els = 'encode_version_$version_name'(Version_name,
+                                         'encode_version_$version_os'(Version_os,
+                                                                      'encode_version_$version_ver'(Version_ver,
+                                                                                                    []))),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"reason">>, _attrs, _els}.
+    {xmlel, <<"query">>, _attrs, _els}.
+
+'encode_version_$version_ver'(undefined, _acc) -> _acc;
+'encode_version_$version_ver'(Version_ver, _acc) ->
+    [encode_version_ver(Version_ver, []) | _acc].
+
+'encode_version_$version_os'(undefined, _acc) -> _acc;
+'encode_version_$version_os'(Version_os, _acc) ->
+    [encode_version_os(Version_os, []) | _acc].
+
+'encode_version_$version_name'(undefined, _acc) -> _acc;
+'encode_version_$version_name'(Version_name, _acc) ->
+    [encode_version_name(Version_name, []) | _acc].
 
-decode_muc_owner_reason_cdata(<<>>) -> undefined;
-decode_muc_owner_reason_cdata(_val) -> _val.
+decode_version_os({xmlel, <<"os">>, _attrs, _els}) ->
+    Cdata = decode_version_os_els(_els, <<>>), Cdata.
 
-encode_muc_owner_reason_cdata(undefined, _acc) -> _acc;
-encode_muc_owner_reason_cdata(_val, _acc) ->
-    [{xmlcdata, _val} | _acc].
+decode_version_os_els([], Cdata) ->
+    decode_version_os_cdata(Cdata);
+decode_version_os_els([{xmlcdata, _data} | _els],
+                     Cdata) ->
+    decode_version_os_els(_els,
+                         <<Cdata/binary, _data/binary>>);
+decode_version_os_els([_ | _els], Cdata) ->
+    decode_version_os_els(_els, Cdata).
 
-decode_muc_owner_destroy({xmlel, <<"destroy">>, _attrs,
-                         _els}) ->
-    {Password, Reason} = decode_muc_owner_destroy_els(_els,
-                                                     undefined, undefined),
-    Jid = decode_muc_owner_destroy_attrs(_attrs, undefined),
-    {muc_owner_destroy, Jid, Reason, Password}.
+encode_version_os(Cdata, _xmlns_attrs) ->
+    _els = encode_version_os_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"os">>, _attrs, _els}.
 
-decode_muc_owner_destroy_els([], Password, Reason) ->
-    {Password, Reason};
-decode_muc_owner_destroy_els([{xmlel, <<"password">>,
-                              _attrs, _} =
-                                 _el
-                             | _els],
-                            Password, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#owner">> ->
-          decode_muc_owner_destroy_els(_els,
-                                       decode_muc_owner_password(_el), Reason);
-       true ->
-          decode_muc_owner_destroy_els(_els, Password, Reason)
-    end;
-decode_muc_owner_destroy_els([{xmlel, <<"reason">>,
-                              _attrs, _} =
-                                 _el
-                             | _els],
-                            Password, Reason) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#owner">> ->
-          decode_muc_owner_destroy_els(_els, Password,
-                                       decode_muc_owner_reason(_el));
-       true ->
-          decode_muc_owner_destroy_els(_els, Password, Reason)
-    end;
-decode_muc_owner_destroy_els([_ | _els], Password,
-                            Reason) ->
-    decode_muc_owner_destroy_els(_els, Password, Reason).
+decode_version_os_cdata(<<>>) ->
+    erlang:error({missing_cdata, <<>>, <<"os">>,
+                 <<"jabber:iq:version">>});
+decode_version_os_cdata(_val) -> _val.
 
-decode_muc_owner_destroy_attrs([{<<"jid">>, _val}
-                               | _attrs],
-                              _Jid) ->
-    decode_muc_owner_destroy_attrs(_attrs, _val);
-decode_muc_owner_destroy_attrs([_ | _attrs], Jid) ->
-    decode_muc_owner_destroy_attrs(_attrs, Jid);
-decode_muc_owner_destroy_attrs([], Jid) ->
-    decode_muc_owner_destroy_attr_jid(Jid).
+encode_version_os_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-encode_muc_owner_destroy({muc_owner_destroy, Jid,
-                         Reason, Password},
-                        _xmlns_attrs) ->
-    _els = 'encode_muc_owner_destroy_$reason'(Reason,
-                                             'encode_muc_owner_destroy_$password'(Password,
-                                                                                  [])),
-    _attrs = encode_muc_owner_destroy_attr_jid(Jid,
-                                              _xmlns_attrs),
-    {xmlel, <<"destroy">>, _attrs, _els}.
+decode_version_ver({xmlel, <<"version">>, _attrs,
+                   _els}) ->
+    Cdata = decode_version_ver_els(_els, <<>>), Cdata.
 
-'encode_muc_owner_destroy_$password'(undefined, _acc) ->
-    _acc;
-'encode_muc_owner_destroy_$password'(Password, _acc) ->
-    [encode_muc_owner_password(Password, []) | _acc].
+decode_version_ver_els([], Cdata) ->
+    decode_version_ver_cdata(Cdata);
+decode_version_ver_els([{xmlcdata, _data} | _els],
+                      Cdata) ->
+    decode_version_ver_els(_els,
+                          <<Cdata/binary, _data/binary>>);
+decode_version_ver_els([_ | _els], Cdata) ->
+    decode_version_ver_els(_els, Cdata).
 
-'encode_muc_owner_destroy_$reason'(undefined, _acc) ->
-    _acc;
-'encode_muc_owner_destroy_$reason'(Reason, _acc) ->
-    [encode_muc_owner_reason(Reason, []) | _acc].
+encode_version_ver(Cdata, _xmlns_attrs) ->
+    _els = encode_version_ver_cdata(Cdata, []),
+    _attrs = _xmlns_attrs,
+    {xmlel, <<"version">>, _attrs, _els}.
 
-decode_muc_owner_destroy_attr_jid(undefined) ->
-    undefined;
-decode_muc_owner_destroy_attr_jid(_val) ->
-    case catch dec_jid(_val) of
-      {'EXIT', _} ->
-         erlang:error({bad_attr_value, <<"jid">>, <<"destroy">>,
-                       <<"http://jabber.org/protocol/muc#owner">>});
-      _res -> _res
-    end.
+decode_version_ver_cdata(<<>>) ->
+    erlang:error({missing_cdata, <<>>, <<"version">>,
+                 <<"jabber:iq:version">>});
+decode_version_ver_cdata(_val) -> _val.
 
-encode_muc_owner_destroy_attr_jid(undefined, _acc) ->
-    _acc;
-encode_muc_owner_destroy_attr_jid(_val, _acc) ->
-    [{<<"jid">>, enc_jid(_val)} | _acc].
+encode_version_ver_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_muc_owner({xmlel, <<"query">>, _attrs, _els}) ->
-    {Config, Destroy} = decode_muc_owner_els(_els,
-                                            undefined, undefined),
-    {muc_owner, Destroy, Config}.
+decode_version_name({xmlel, <<"name">>, _attrs,
+                    _els}) ->
+    Cdata = decode_version_name_els(_els, <<>>), Cdata.
 
-decode_muc_owner_els([], Config, Destroy) ->
-    {Config, Destroy};
-decode_muc_owner_els([{xmlel, <<"destroy">>, _attrs,
-                      _} =
-                         _el
-                     | _els],
-                    Config, Destroy) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc#owner">> ->
-          decode_muc_owner_els(_els, Config,
-                               decode_muc_owner_destroy(_el));
-       true -> decode_muc_owner_els(_els, Config, Destroy)
-    end;
-decode_muc_owner_els([{xmlel, <<"x">>, _attrs, _} = _el
-                     | _els],
-                    Config, Destroy) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<"jabber:x:data">> ->
-          decode_muc_owner_els(_els, decode_xdata(_el), Destroy);
-       true -> decode_muc_owner_els(_els, Config, Destroy)
-    end;
-decode_muc_owner_els([_ | _els], Config, Destroy) ->
-    decode_muc_owner_els(_els, Config, Destroy).
+decode_version_name_els([], Cdata) ->
+    decode_version_name_cdata(Cdata);
+decode_version_name_els([{xmlcdata, _data} | _els],
+                       Cdata) ->
+    decode_version_name_els(_els,
+                           <<Cdata/binary, _data/binary>>);
+decode_version_name_els([_ | _els], Cdata) ->
+    decode_version_name_els(_els, Cdata).
 
-encode_muc_owner({muc_owner, Destroy, Config},
-                _xmlns_attrs) ->
-    _els = 'encode_muc_owner_$destroy'(Destroy,
-                                      'encode_muc_owner_$config'(Config, [])),
+encode_version_name(Cdata, _xmlns_attrs) ->
+    _els = encode_version_name_cdata(Cdata, []),
     _attrs = _xmlns_attrs,
-    {xmlel, <<"query">>, _attrs, _els}.
+    {xmlel, <<"name">>, _attrs, _els}.
 
-'encode_muc_owner_$config'(undefined, _acc) -> _acc;
-'encode_muc_owner_$config'(Config, _acc) ->
-    [encode_xdata(Config,
-                 [{<<"xmlns">>, <<"jabber:x:data">>}])
-     | _acc].
+decode_version_name_cdata(<<>>) ->
+    erlang:error({missing_cdata, <<>>, <<"name">>,
+                 <<"jabber:iq:version">>});
+decode_version_name_cdata(_val) -> _val.
 
-'encode_muc_owner_$destroy'(undefined, _acc) -> _acc;
-'encode_muc_owner_$destroy'(Destroy, _acc) ->
-    [encode_muc_owner_destroy(Destroy, []) | _acc].
+encode_version_name_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
 
-decode_muc({xmlel, <<"x">>, _attrs, _els}) ->
-    History = decode_muc_els(_els, undefined),
-    Password = decode_muc_attrs(_attrs, undefined),
-    {muc, History, Password}.
+decode_last({xmlel, <<"query">>, _attrs, _els}) ->
+    Text = decode_last_els(_els, <<>>),
+    Seconds = decode_last_attrs(_attrs, undefined),
+    {last, Seconds, Text}.
 
-decode_muc_els([], History) -> History;
-decode_muc_els([{xmlel, <<"history">>, _attrs, _} = _el
-               | _els],
-              History) ->
-    _xmlns = xml:get_attr_s(<<"xmlns">>, _attrs),
-    if _xmlns == <<>>;
-       _xmlns == <<"http://jabber.org/protocol/muc">> ->
-          decode_muc_els(_els, decode_muc_history(_el));
-       true -> decode_muc_els(_els, History)
-    end;
-decode_muc_els([_ | _els], History) ->
-    decode_muc_els(_els, History).
+decode_last_els([], Text) -> decode_last_cdata(Text);
+decode_last_els([{xmlcdata, _data} | _els], Text) ->
+    decode_last_els(_els, <<Text/binary, _data/binary>>);
+decode_last_els([_ | _els], Text) ->
+    decode_last_els(_els, Text).
 
-decode_muc_attrs([{<<"password">>, _val} | _attrs],
-                _Password) ->
-    decode_muc_attrs(_attrs, _val);
-decode_muc_attrs([_ | _attrs], Password) ->
-    decode_muc_attrs(_attrs, Password);
-decode_muc_attrs([], Password) ->
-    decode_muc_attr_password(Password).
+decode_last_attrs([{<<"seconds">>, _val} | _attrs],
+                 _Seconds) ->
+    decode_last_attrs(_attrs, _val);
+decode_last_attrs([_ | _attrs], Seconds) ->
+    decode_last_attrs(_attrs, Seconds);
+decode_last_attrs([], Seconds) ->
+    decode_last_attr_seconds(Seconds).
 
-encode_muc({muc, History, Password}, _xmlns_attrs) ->
-    _els = 'encode_muc_$history'(History, []),
-    _attrs = encode_muc_attr_password(Password,
+encode_last({last, Seconds, Text}, _xmlns_attrs) ->
+    _els = encode_last_cdata(Text, []),
+    _attrs = encode_last_attr_seconds(Seconds,
                                      _xmlns_attrs),
-    {xmlel, <<"x">>, _attrs, _els}.
+    {xmlel, <<"query">>, _attrs, _els}.
 
-'encode_muc_$history'(undefined, _acc) -> _acc;
-'encode_muc_$history'(History, _acc) ->
-    [encode_muc_history(History, []) | _acc].
+decode_last_attr_seconds(undefined) -> undefined;
+decode_last_attr_seconds(_val) ->
+    case catch xml_gen:dec_int(_val, 0, infinity) of
+      {'EXIT', _} ->
+         erlang:error({bad_attr_value, <<"seconds">>,
+                       <<"query">>, <<"jabber:iq:last">>});
+      _res -> _res
+    end.
 
-decode_muc_attr_password(undefined) -> undefined;
-decode_muc_attr_password(_val) -> _val.
+encode_last_attr_seconds(undefined, _acc) -> _acc;
+encode_last_attr_seconds(_val, _acc) ->
+    [{<<"seconds">>, xml_gen:enc_int(_val)} | _acc].
 
-encode_muc_attr_password(undefined, _acc) -> _acc;
-encode_muc_attr_password(_val, _acc) ->
-    [{<<"password">>, _val} | _acc].
+decode_last_cdata(<<>>) -> undefined;
+decode_last_cdata(_val) -> _val.
+
+encode_last_cdata(undefined, _acc) -> _acc;
+encode_last_cdata(_val, _acc) ->
+    [{xmlcdata, _val} | _acc].
index d1ee438e926fbd232407d91f825632feef2882a7..1187ad5bd6feaaad07d37d07818f7d8e64a5bdc9 100644 (file)
 %% Created automatically by XML generator (xml_gen.erl)
 %% Source: xmpp_codec.spec
 
--record(bind, {jid, resource}).
-
--record(block, {items = []}).
-
--record(block_list, {}).
-
--record(bookmark_conference,
-       {name, jid, autojoin = false, nick, password}).
-
--record(bookmark_storage, {conference = [], url = []}).
-
--record(bookmark_url, {name, url}).
-
--record(bytestreams,
-       {hosts = [], used, activate, dstaddr, mode = tcp, sid}).
-
--record(caps, {hash, node, ver}).
-
--record(compress, {methods = []}).
-
--record(compress_failure, {reason}).
-
--record(compressed, {}).
-
--record(compression, {methods = []}).
-
--record(delay, {stamp, from}).
-
--record(disco_info,
-       {node, identity = [], feature = [], xdata = []}).
-
--record(disco_item, {jid, name, node}).
-
--record(disco_items, {node, items = []}).
-
--record(error, {type, by, reason, text}).
-
 -record(feature_register, {}).
 
--record(gone, {uri}).
-
--record(identity, {category, type, name}).
+-record(sasl_success, {text :: any()}).
 
--record(iq,
-       {id, type, lang, from, to, error, sub_els = []}).
+-record(streamhost, {jid :: any(),
+                     host :: binary(),
+                     port = 1080 :: non_neg_integer()}).
 
--record(last, {seconds, text}).
-
--record(legacy_delay, {stamp, from}).
-
--record(message,
-       {id, type = normal, lang, from, to, subject = [],
-        body = [], thread, error, sub_els = []}).
-
--record(muc, {history, password}).
+-record(ping, {}).
 
--record(muc_actor, {jid, nick}).
+-record(delay, {stamp :: any(),
+                from :: any()}).
 
--record(muc_decline, {reason, from, to}).
+-record(muc_history, {maxchars :: non_neg_integer(),
+                      maxstanzas :: non_neg_integer(),
+                      seconds :: non_neg_integer(),
+                      since :: any()}).
 
--record(muc_history,
-       {maxchars, maxstanzas, seconds, since}).
+-record(pubsub_affiliation, {node :: binary(),
+                             type :: 'member' | 'none' | 'outcast' | 'owner' | 'publish-only' | 'publisher'}).
 
--record(muc_invite, {reason, from, to}).
+-record(muc_decline, {reason :: binary(),
+                      from :: any(),
+                      to :: any()}).
 
--record(muc_item,
-       {actor, continue, reason, affiliation, role, jid,
-        nick}).
+-record(starttls_proceed, {}).
 
--record(muc_owner, {destroy, config}).
+-record(starttls_failure, {}).
 
--record(muc_owner_destroy, {jid, reason, password}).
+-record(sasl_challenge, {text :: any()}).
 
--record(muc_user,
-       {decline, destroy, invites = [], items = [],
-        status_codes = [], password}).
+-record(gone, {uri :: binary()}).
 
--record(muc_user_destroy, {reason, jid}).
+-record(private, {sub_els = [] :: [any()]}).
 
 -record(p1_ack, {}).
 
--record(p1_push, {}).
-
--record(p1_rebind, {}).
-
--record(ping, {}).
-
--record(presence,
-       {id, type, lang, from, to, show, status = [], priority,
-        error, sub_els = []}).
-
--record(privacy, {lists = [], default, active}).
+-record(pubsub_item, {id :: binary(),
+                      sub_els = [] :: [any()]}).
 
--record(privacy_item,
-       {order, action, type, value, kinds = []}).
+-record(roster_item, {jid :: any(),
+                      name :: binary(),
+                      groups = [] :: [binary()],
+                      subscription = none :: 'both' | 'from' | 'none' | 'remove' | 'to',
+                      ask :: 'subscribe'}).
 
--record(privacy_list, {name, items = []}).
+-record(roster, {items = [] :: [#roster_item{}],
+                 ver :: binary()}).
 
--record(private, {sub_els = []}).
+-record(pubsub_event_item, {id :: binary(),
+                            node :: binary(),
+                            publisher :: binary()}).
 
--record(pubsub,
-       {subscriptions, affiliations, publish, subscribe}).
+-record(muc_actor, {jid :: any(),
+                    nick :: binary()}).
 
--record(pubsub_affiliation, {node, type}).
+-record(stat, {name :: binary(),
+               units :: binary(),
+               value :: binary(),
+               error = [] :: [{integer(),binary()}]}).
 
--record(pubsub_event, {items = []}).
+-record('see-other-host', {host :: binary()}).
 
--record(pubsub_event_item, {id, node, publisher}).
+-record(compress, {methods = [] :: [binary()]}).
 
--record(pubsub_event_items,
-       {node, retract = [], items = []}).
+-record(starttls, {required = false :: boolean()}).
 
--record(pubsub_item, {id, sub_els = []}).
+-record(last, {seconds :: non_neg_integer(),
+               text :: binary()}).
 
--record(pubsub_items,
-       {node, max_items, subid, items = []}).
+-record(pubsub_event_items, {node :: binary(),
+                             retract = [] :: [binary()],
+                             items = [] :: [#pubsub_event_item{}]}).
 
--record(pubsub_subscription, {jid, node, subid, type}).
+-record(pubsub_event, {items = [] :: [#pubsub_event_items{}]}).
 
--record(redirect, {uri}).
+-record(redirect, {uri :: binary()}).
 
--record(register,
-       {registered = false, remove = false, instructions,
-        username, nick, password, name, first, last, email,
-        address, city, state, zip, phone, url, date, misc, text,
-        key}).
+-record(sasl_response, {text :: any()}).
 
--record(roster, {items = [], ver}).
+-record(sasl_auth, {mechanism :: binary(),
+                    text :: any()}).
 
--record(roster_item,
-       {jid, name, groups = [], subscription = none, ask}).
-
--record(sasl_abort, {}).
-
--record(sasl_auth, {mechanism, text}).
+-record(p1_push, {}).
 
--record(sasl_challenge, {text}).
+-record(legacy_delay, {stamp :: binary(),
+                       from :: any()}).
 
--record(sasl_failure, {reason, text = []}).
+-record(muc_user_destroy, {reason :: binary(),
+                           jid :: any()}).
 
--record(sasl_mechanisms, {list = []}).
+-record(disco_item, {jid :: any(),
+                     name :: binary(),
+                     node :: binary()}).
 
--record(sasl_response, {text}).
+-record(disco_items, {node :: binary(),
+                      items = [] :: [#disco_item{}]}).
 
--record(sasl_success, {text}).
+-record(unblock, {items = [] :: [any()]}).
 
--record('see-other-host', {host}).
+-record(block, {items = [] :: [any()]}).
 
 -record(session, {}).
 
--record(starttls, {required = false}).
+-record(compression, {methods = [] :: [binary()]}).
 
--record(starttls_failure, {}).
+-record(muc_owner_destroy, {jid :: any(),
+                            reason :: binary(),
+                            password :: binary()}).
 
--record(starttls_proceed, {}).
+-record(pubsub_subscription, {jid :: any(),
+                              node :: binary(),
+                              subid :: binary(),
+                              type :: 'none' | 'pending' | 'subscribed' | 'unconfigured'}).
 
--record(stat, {name, units, value, error = []}).
+-record(caps, {hash :: binary(),
+               node :: binary(),
+               ver :: any()}).
 
--record(stats, {stat = []}).
+-record(muc, {history :: #muc_history{},
+              password :: binary()}).
 
--record(stream_error, {reason, text}).
+-record(stream_features, {sub_els = [] :: [any()]}).
 
--record(stream_features, {sub_els = []}).
+-record(stats, {stat = [] :: [#stat{}]}).
 
--record(streamhost, {jid, host, port = 1080}).
+-record(pubsub, {subscriptions :: {binary(),[#pubsub_subscription{}]},
+                 affiliations :: [#pubsub_affiliation{}],
+                 publish :: {binary(),[#pubsub_item{}]},
+                 subscribe :: {binary(),_}}).
 
--record(text, {lang, data}).
+-record(pubsub_items, {node :: binary(),
+                       max_items :: non_neg_integer(),
+                       subid :: binary(),
+                       items = [] :: [#pubsub_item{}]}).
 
--record(time, {tzo, utc}).
-
--record(unblock, {items = []}).
-
--record(vcard,
-       {version, fn, n, nickname, photo, bday, adr = [],
-        label = [], tel = [], email = [], jabberid, mailer, tz,
-        geo, title, role, logo, org, categories = [], note,
-        prodid, agent, rev, sort_string, sound, uid, url, class,
-        key, desc}).
-
--record(vcard_adr,
-       {home = false, work = false, postal = false,
-        parcel = false, dom = false, intl = false, pref = false,
-        pobox, extadd, street, locality, region, pcode, ctry}).
-
--record(vcard_agent, {vcard, extval}).
-
--record(vcard_email,
-       {home = false, work = false, internet = false,
-        pref = false, x400 = false, userid}).
-
--record(vcard_geo, {lat, lon}).
-
--record(vcard_key, {type, cred}).
-
--record(vcard_label,
-       {home = false, work = false, postal = false,
-        parcel = false, dom = false, intl = false, pref = false,
-        line = []}).
+-record(p1_rebind, {}).
 
--record(vcard_logo, {type, binval, extval}).
+-record(compress_failure, {reason :: 'processing-failed' | 'setup-failed' | 'unsupported-method'}).
 
--record(vcard_name,
-       {family, given, middle, prefix, suffix}).
+-record(sasl_abort, {}).
 
--record(vcard_org, {name, units = []}).
+-record(vcard_email, {home = false :: boolean(),
+                      work = false :: boolean(),
+                      internet = false :: boolean(),
+                      pref = false :: boolean(),
+                      x400 = false :: boolean(),
+                      userid :: binary()}).
 
--record(vcard_photo, {type, binval, extval}).
+-record(text, {lang :: binary(),
+               data :: binary()}).
 
--record(vcard_sound, {phonetic, binval, extval}).
+-record(vcard_geo, {lat :: binary(),
+                    lon :: binary()}).
 
--record(vcard_tel,
-       {home = false, work = false, voice = false, fax = false,
-        pager = false, msg = false, cell = false, video = false,
-        bbs = false, modem = false, isdn = false, pcs = false,
-        pref = false, number}).
+-record(compressed, {}).
 
--record(version,
-       {version_name, version_ver, version_os}).
+-record(sasl_failure, {reason :: 'aborted' | 'account-disabled' | 'credentials-expired' | 'encryption-required' | 'incorrect-encoding' | 'invalid-authzid' | 'invalid-mechanism' | 'malformed-request' | 'mechanism-too-weak' | 'not-authorized' | 'temporary-auth-failure',
+                       text = [] :: [#text{}]}).
 
--record(xdata,
-       {type, instructions = [], title, reported, items = [],
-        fields = []}).
+-record(block_list, {}).
 
--record(xdata_field,
-       {label, type, var, required = false, desc, values = [],
-        options = []}).
+-record(xdata_field, {label :: binary(),
+                      type :: 'boolean' | 'fixed' | 'hidden' | 'jid-multi' | 'jid-single' | 'list-multi' | 'list-single' | 'text-multi' | 'text-private' | 'text-single',
+                      var :: binary(),
+                      required = false :: boolean(),
+                      desc :: binary(),
+                      values = [] :: [binary()],
+                      options = [] :: [binary()]}).
+
+-record(version, {version_name :: binary(),
+                  version_ver :: binary(),
+                  version_os :: binary()}).
+
+-record(muc_invite, {reason :: binary(),
+                     from :: any(),
+                     to :: any()}).
+
+-record(bind, {jid :: any(),
+               resource :: any()}).
+
+-record(muc_item, {actor :: #muc_actor{},
+                   continue :: binary(),
+                   reason :: binary(),
+                   affiliation :: 'admin' | 'member' | 'none' | 'outcast' | 'owner',
+                   role :: 'moderator' | 'none' | 'participant' | 'visitor',
+                   jid :: any(),
+                   nick :: binary()}).
+
+-record(muc_user, {decline :: #muc_decline{},
+                   destroy :: #muc_user_destroy{},
+                   invites = [] :: [#muc_invite{}],
+                   items = [] :: [#muc_item{}],
+                   status_codes = [] :: [pos_integer()],
+                   password :: binary()}).
+
+-record(bytestreams, {hosts = [] :: [#streamhost{}],
+                      used :: any(),
+                      activate :: any(),
+                      dstaddr :: binary(),
+                      mode = tcp :: 'tcp' | 'udp',
+                      sid :: binary()}).
+
+-record(vcard_org, {name :: binary(),
+                    units = [] :: [binary()]}).
+
+-record(vcard_tel, {home = false :: boolean(),
+                    work = false :: boolean(),
+                    voice = false :: boolean(),
+                    fax = false :: boolean(),
+                    pager = false :: boolean(),
+                    msg = false :: boolean(),
+                    cell = false :: boolean(),
+                    video = false :: boolean(),
+                    bbs = false :: boolean(),
+                    modem = false :: boolean(),
+                    isdn = false :: boolean(),
+                    pcs = false :: boolean(),
+                    pref = false :: boolean(),
+                    number :: binary()}).
+
+-record(vcard_key, {type :: binary(),
+                    cred :: binary()}).
+
+-record(vcard_name, {family :: binary(),
+                     given :: binary(),
+                     middle :: binary(),
+                     prefix :: binary(),
+                     suffix :: binary()}).
+
+-record(identity, {category :: binary(),
+                   type :: binary(),
+                   name :: binary()}).
+
+-record(bookmark_conference, {name :: binary(),
+                              jid :: any(),
+                              autojoin = false :: any(),
+                              nick :: binary(),
+                              password :: binary()}).
+
+-record(register, {registered = false :: boolean(),
+                   remove = false :: boolean(),
+                   instructions :: binary(),
+                   username :: binary(),
+                   nick :: binary(),
+                   password :: binary(),
+                   name :: binary(),
+                   first :: binary(),
+                   last :: binary(),
+                   email :: binary(),
+                   address :: binary(),
+                   city :: binary(),
+                   state :: binary(),
+                   zip :: binary(),
+                   phone :: binary(),
+                   url :: binary(),
+                   date :: binary(),
+                   misc :: binary(),
+                   text :: binary(),
+                   key :: binary()}).
+
+-record(bookmark_url, {name :: binary(),
+                       url :: binary()}).
+
+-record(bookmark_storage, {conference = [] :: [#bookmark_conference{}],
+                           url = [] :: [#bookmark_url{}]}).
+
+-record(vcard_sound, {phonetic :: binary(),
+                      binval :: any(),
+                      extval :: binary()}).
+
+-record(vcard_photo, {type :: binary(),
+                      binval :: any(),
+                      extval :: binary()}).
+
+-record(vcard_label, {home = false :: boolean(),
+                      work = false :: boolean(),
+                      postal = false :: boolean(),
+                      parcel = false :: boolean(),
+                      dom = false :: boolean(),
+                      intl = false :: boolean(),
+                      pref = false :: boolean(),
+                      line = [] :: [binary()]}).
+
+-record(vcard_adr, {home = false :: boolean(),
+                    work = false :: boolean(),
+                    postal = false :: boolean(),
+                    parcel = false :: boolean(),
+                    dom = false :: boolean(),
+                    intl = false :: boolean(),
+                    pref = false :: boolean(),
+                    pobox :: binary(),
+                    extadd :: binary(),
+                    street :: binary(),
+                    locality :: binary(),
+                    region :: binary(),
+                    pcode :: binary(),
+                    ctry :: binary()}).
+
+-record(xdata, {type :: 'cancel' | 'form' | 'result' | 'submit',
+                instructions = [] :: [binary()],
+                title :: binary(),
+                reported :: [#xdata_field{}],
+                items = [] :: [[#xdata_field{}]],
+                fields = [] :: [#xdata_field{}]}).
+
+-record(muc_owner, {destroy :: #muc_owner_destroy{},
+                    config :: #xdata{}}).
+
+-record(disco_info, {node :: binary(),
+                     identity = [] :: [#identity{}],
+                     feature = [] :: [binary()],
+                     xdata = [] :: [#xdata{}]}).
+
+-record(sasl_mechanisms, {list = [] :: [binary()]}).
+
+-record(error, {type :: 'auth' | 'cancel' | 'continue' | 'modify' | 'wait',
+                by :: binary(),
+                reason :: atom() | #gone{} | #redirect{},
+                text :: #text{}}).
+
+-record(presence, {id :: binary(),
+                   type :: 'error' | 'probe' | 'subscribe' | 'subscribed' | 'unavailable' | 'unsubscribe' | 'unsubscribed',
+                   lang :: binary(),
+                   from :: any(),
+                   to :: any(),
+                   show :: 'away' | 'chat' | 'dnd' | 'xa',
+                   status = [] :: [#text{}],
+                   priority :: integer(),
+                   error :: #error{},
+                   sub_els = [] :: [any()]}).
+
+-record(message, {id :: binary(),
+                  type = normal :: 'chat' | 'error' | 'groupchat' | 'headline' | 'normal',
+                  lang :: binary(),
+                  from :: any(),
+                  to :: any(),
+                  subject = [] :: [#text{}],
+                  body = [] :: [#text{}],
+                  thread :: binary(),
+                  error :: #error{},
+                  sub_els = [] :: [any()]}).
+
+-record(iq, {id :: binary(),
+             type :: 'error' | 'get' | 'result' | 'set',
+             lang :: binary(),
+             from :: any(),
+             to :: any(),
+             error :: #error{},
+             sub_els = [] :: [any()]}).
+
+-record(privacy_item, {order :: non_neg_integer(),
+                       action :: 'allow' | 'deny',
+                       type :: 'group' | 'jid' | 'subscription',
+                       value :: binary(),
+                       kinds = [] :: ['iq' | 'message' | 'presence-in' | 'presence-out']}).
+
+-record(privacy_list, {name :: binary(),
+                       items = [] :: [#privacy_item{}]}).
+
+-record(privacy, {lists = [] :: [#privacy_list{}],
+                  default :: binary(),
+                  active :: binary()}).
+
+-record(stream_error, {reason :: atom() | #'see-other-host'{},
+                       text :: #text{}}).
+
+-record(vcard_logo, {type :: binary(),
+                     binval :: any(),
+                     extval :: binary()}).
+
+-record(vcard, {version :: binary(),
+                fn :: binary(),
+                n :: #vcard_name{},
+                nickname :: binary(),
+                photo :: #vcard_photo{},
+                bday :: binary(),
+                adr = [] :: [#vcard_adr{}],
+                label = [] :: [#vcard_label{}],
+                tel = [] :: [#vcard_tel{}],
+                email = [] :: [#vcard_email{}],
+                jabberid :: binary(),
+                mailer :: binary(),
+                tz :: binary(),
+                geo :: #vcard_geo{},
+                title :: binary(),
+                role :: binary(),
+                logo :: #vcard_logo{},
+                org :: #vcard_org{},
+                categories = [] :: [binary()],
+                note :: binary(),
+                prodid :: binary(),
+                rev :: binary(),
+                sort_string :: binary(),
+                sound :: #vcard_sound{},
+                uid :: binary(),
+                url :: binary(),
+                class :: 'confidential' | 'private' | 'public',
+                key :: #vcard_key{},
+                desc :: binary()}).
+
+-record(time, {tzo :: any(),
+               utc :: any()}).
index f3ac758b20206172ebd7c9d81dcc05505f85115e..11840cb2c5524a1dd428532fbde4efa7e65cf151 100644 (file)
                #ref{name = vcard_PRIVATE, min = 0, max = 1, label = '$class'},
                #ref{name = vcard_CONFIDENTIAL, min = 0, max = 1, label = '$class'}]}}.
 
-{vcard_AGENT,
- #elem{name = <<"AGENT">>,
-       xmlns = <<"vcard-temp">>,
-       result = {vcard_agent, '$vcard', '$extval'},
-       refs = [#ref{name = vcard, min = 0, max = 1, label = '$vcard'},
-               #ref{name = vcard_EXTVAL, min = 0, max = 1, label = '$extval'}]}}.
+%% {vcard_AGENT,
+%%  #elem{name = <<"AGENT">>,
+%%        xmlns = <<"vcard-temp">>,
+%%        result = {vcard_agent, '$vcard', '$extval'},
+%%        refs = [#ref{name = vcard, min = 0, max = 1, label = '$vcard'},
+%%                #ref{name = vcard_EXTVAL, min = 0, max = 1, label = '$extval'}]}}.
 
 {vcard,
  #elem{name = <<"vCard">>,
        result = {vcard, '$version', '$fn', '$n', '$nickname', '$photo',
                  '$bday', '$adr', '$label', '$tel', '$email', '$jabberid',
                  '$mailer', '$tz', '$geo', '$title', '$role', '$logo',
-                 '$org', '$categories', '$note', '$prodid', '$agent',
+                 '$org', '$categories', '$note', '$prodid', %% '$agent',
                  '$rev', '$sort_string', '$sound', '$uid', '$url', '$class',
                  '$key', '$desc'},
        refs = [#ref{name = vcard_N, min = 0, max = 1, label = '$n'},
                #ref{name = vcard_NOTE, min = 0, max = 1, label = '$note'},
                #ref{name = vcard_PRODID, min = 0, max = 1, label = '$prodid'},
                #ref{name = vcard_REV, min = 0, max = 1, label = '$rev'},
-               #ref{name = vcard_AGENT, min = 0, max = 1, label = '$agent'},
+               %%#ref{name = vcard_AGENT, min = 0, max = 1, label = '$agent'},
                #ref{name = vcard_SORT_STRING, min = 0, max = 1,
                     label = '$sort_string'},
                #ref{name = vcard_UID, min = 0, max = 1, label = '$uid'},