Add support of the GSUP E Interface messages

Encoding and decoding of the following GSUP messages were added to support inter-MSC handover functionality:
* E Prepare Handover Request/Result/Error
* E Prepare Subsequent Handover Request/Result/Error
* E Send End Signal Request/Result/Error
* E Forward Access Signalling Request
* E Process Access Signalling Request
* E Close, E Abort, E Routing Error.

Tests for GSUP E Interface messages were added from libosmocore library.

diff --git a/include/gsup_protocol.hrl b/include/gsup_protocol.hrl
index 2b5676e..d6f0235 100644
--- a/include/gsup_protocol.hrl
+++ b/include/gsup_protocol.hrl
@@ -40,7 +40,21 @@
                   | ready_for_sm_res
                   | check_imei_req
                   | check_imei_err
-                  | check_imei_res.
+                  | check_imei_res
+                  | e_prepare_handover_req
+                  | e_prepare_handover_err
+                  | e_prepare_handover_res
+                  | e_prepare_subseq_handover_req
+                  | e_prepare_subseq_handover_err
+                  | e_prepare_subseq_handover_res
+                  | e_send_end_signal_req
+                  | e_send_end_signal_err
+                  | e_send_end_signal_res
+                  | e_process_access_signalling_req
+                  | e_forward_access_signalling_req
+                  | e_close
+                  | e_abort
+                  | e_routing_err.
 
 -type 'GSUPMessage'() :: #{
   message_type := 'GSUPMessageType'(),
@@ -84,7 +98,13 @@
   sm_alert_reason => integer(),
   imei => binary(),
   imei_check_result => integer(),
-  message_class => integer()
+  message_class => integer(),
+  source_name => binary(),
+  destination_name => binary(),
+  an_apdu => binary(),
+  rr_cause => integer(),
+  session_management_cause => integer(),
+  bssap_cause => integer()
 }.
 
 -define(SESSION_STATE_BEGIN, 1).
@@ -127,6 +147,12 @@
 -define(SM_ALERT_REASON, 16#46).
 -define(IMEI, 16#50).
 -define(IMEI_CHECK_RESULT, 16#51).
+-define(SOURCE_NAME, 16#60).
+-define(DESTINATION_NAME, 16#61).
+-define(AN_APDU, 16#62).
+-define(RR_CAUSE, 16#63).
+-define(BSSAP_CAUSE, 16#64).
+-define(SESSION_MANAGEMENT_CAUSE, 16#65).
 
 -define(MANDATORY_DEFAULT, [imsi, message_type]).
 
@@ -166,7 +192,21 @@
   16#2e => #{message_type => ready_for_sm_res, mandatory => []},
   16#30 => #{message_type => check_imei_req, mandatory => [imei]},
   16#31 => #{message_type => check_imei_err, mandatory => [cause]},
-  16#32 => #{message_type => check_imei_res, mandatory => [imei_check_result]}
+  16#32 => #{message_type => check_imei_res, mandatory => [imei_check_result]},
+  16#34 => #{message_type => e_prepare_handover_req, mandatory => [message_class, source_name, destination_name, an_apdu, session_id, session_state]},
+  16#35 => #{message_type => e_prepare_handover_err, mandatory => [message_class, source_name, destination_name, an_apdu, session_id, session_state, bssap_cause]},
+  16#36 => #{message_type => e_prepare_handover_res, mandatory => [message_class, source_name, destination_name, an_apdu, session_id, session_state]},
+  16#38 => #{message_type => e_prepare_subseq_handover_req, mandatory => [message_class, source_name, destination_name, an_apdu, session_id, session_state]},
+  16#39 => #{message_type => e_prepare_subseq_handover_err, mandatory => [message_class, source_name, destination_name, an_apdu, session_id, session_state, bssap_cause]},
+  16#3a => #{message_type => e_prepare_subseq_handover_res, mandatory => [message_class, source_name, destination_name, an_apdu, session_id, session_state]},
+  16#3c => #{message_type => e_send_end_signal_req, mandatory => [message_class, source_name, destination_name, an_apdu, session_id, session_state]},
+  16#3d => #{message_type => e_send_end_signal_err, mandatory => [message_class, source_name, destination_name, an_apdu, session_id, session_state, bssap_cause]},
+  16#3e => #{message_type => e_send_end_signal_res, mandatory => [message_class, source_name, destination_name, an_apdu, session_id, session_state]},
+  16#40 => #{message_type => e_process_access_signalling_req, mandatory => [message_class, source_name, destination_name, an_apdu, session_id, session_state]},
+  16#44 => #{message_type => e_forward_access_signalling_req, mandatory => [message_class, source_name, destination_name, an_apdu, session_id, session_state]},
+  16#47 => #{message_type => e_close, mandatory => [message_class, source_name, destination_name, session_id, session_state]},
+  16#4b => #{message_type => e_abort, mandatory => [message_class, session_id, session_state, bssap_cause]},
+  16#4e => #{message_type => e_routing_err, mandatory => [message_class, source_name, destination_name, session_id, session_state]}
 }).
 
 -define(AUTH_TUPLE_MANDATORY, [rand, sres, kc]).
diff --git a/src/gsup_protocol.erl b/src/gsup_protocol.erl
index a8c1754..fe5f38c 100644
--- a/src/gsup_protocol.erl
+++ b/src/gsup_protocol.erl
@@ -151,6 +151,27 @@
   ?CHECK_LEN(imei_check_result, Len, 1, 1),
   decode_ie(Tail, Map#{imei_check_result => IMEIResult});
 
+decode_ie(<<?SOURCE_NAME, Len, SourceName:Len/binary, Tail/binary>>, Map) ->
+  decode_ie(Tail, Map#{source_name => SourceName});
+
+decode_ie(<<?DESTINATION_NAME, Len, DestName:Len/binary, Tail/binary>>, Map) ->
+  decode_ie(Tail, Map#{destination_name => DestName});
+
+decode_ie(<<?AN_APDU, Len, AN_APDU:Len/binary, Tail/binary>>, Map) ->
+  decode_ie(Tail, Map#{an_apdu => AN_APDU});
+
+decode_ie(<<?RR_CAUSE, Len, RRCause:Len/unit:8, Tail/binary>>, Map) ->
+  ?CHECK_LEN(rr_cause, Len, 1, 1),
+  decode_ie(Tail, Map#{rr_cause => RRCause});
+
+decode_ie(<<?BSSAP_CAUSE, Len, BSSAPCause:Len/unit:8, Tail/binary>>, Map) ->
+  ?CHECK_LEN(bssap_cause, Len, 1, 1),
+  decode_ie(Tail, Map#{bssap_cause => BSSAPCause});
+
+decode_ie(<<?SESSION_MANAGEMENT_CAUSE, Len, SMCause:Len/unit:8, Tail/binary>>, Map) ->
+  ?CHECK_LEN(session_management_cause, Len, 1, 1),
+  decode_ie(Tail, Map#{session_management_cause => SMCause});
+
 decode_ie(<<_, Len, _:Len/binary, Tail/binary>>, Map) -> %% skip unknown IE
   decode_ie(Tail, Map);
 
@@ -415,6 +436,33 @@
   ?CHECK_SIZE(imei_check_result, Len, Value),
   encode_ie(maps:without([imei_check_result], GSUPMessage), <<Head/binary, ?IMEI_CHECK_RESULT, Len, Value:Len/unit:8>>);
 
+encode_ie(#{source_name := Value} = GSUPMessage, Head) ->
+  Len = size(Value),
+  encode_ie(maps:without([source_name], GSUPMessage), <<Head/binary, ?SOURCE_NAME, Len, Value/binary>>);
+
+encode_ie(#{destination_name := Value} = GSUPMessage, Head) ->
+  Len = size(Value),
+  encode_ie(maps:without([destination_name], GSUPMessage), <<Head/binary, ?DESTINATION_NAME, Len, Value/binary>>);
+
+encode_ie(#{an_apdu := Value} = GSUPMessage, Head) ->
+  Len = size(Value),
+  encode_ie(maps:without([an_apdu], GSUPMessage), <<Head/binary, ?AN_APDU, Len, Value/binary>>);
+
+encode_ie(#{rr_cause := Value} = GSUPMessage, Head) ->
+  Len = 1,
+  ?CHECK_SIZE(rr_cause, Len, Value),
+  encode_ie(maps:without([rr_cause], GSUPMessage), <<Head/binary, ?RR_CAUSE, Len, Value:Len/unit:8>>);
+
+encode_ie(#{bssap_cause := Value} = GSUPMessage, Head) ->
+  Len = 1,
+  ?CHECK_SIZE(bssap_cause, Len, Value),
+  encode_ie(maps:without([bssap_cause], GSUPMessage), <<Head/binary, ?BSSAP_CAUSE, Len, Value:Len/unit:8>>);
+
+encode_ie(#{session_management_cause := Value} = GSUPMessage, Head) ->
+  Len = 1,
+  ?CHECK_SIZE(session_management_cause, Len, Value),
+  encode_ie(maps:without([session_management_cause], GSUPMessage), <<Head/binary, ?SESSION_MANAGEMENT_CAUSE, Len, Value:Len/unit:8>>);
+
 encode_ie(_, Head) -> Head.
 
 encode_bcd(BCDNumber) -> encode_bcd(BCDNumber, <<>>).
diff --git a/src/osmo_gsup.app.src b/src/osmo_gsup.app.src
index cf9f18b..e93b1e3 100644
--- a/src/osmo_gsup.app.src
+++ b/src/osmo_gsup.app.src
@@ -1,6 +1,6 @@
 {application, osmo_gsup, [
   {description, "OSMOCOM GSUP library"},
-  {vsn, "0.1.1"},
+  {vsn, "0.2.0"},
   {registered, []},
   {applications, [
     kernel,
diff --git a/test/gsup_encode_decode_test.erl b/test/gsup_encode_decode_test.erl
index f7daa36..9fcba6c 100644
--- a/test/gsup_encode_decode_test.erl
+++ b/test/gsup_encode_decode_test.erl
@@ -11,6 +11,11 @@
 -define(TEST_IMSI_IE, 16#01, 16#08, 16#21, 16#43, 16#65, 16#87, 16#09, 16#21, 16#43, 16#f5).
 -define(TEST_MSISDN_IE, 16#08, 16#07, 16#91, 16#94, 16#61, 16#46, 16#32, 16#24, 16#43).
 -define(TEST_CLASS_SUBSCR_IE, 16#0a, 16#01, 16#01).
+-define(TEST_CLASS_INTER_MSC_IE, 16#0a, 16#01, 16#04).
+-define(TEST_AN_APDU_IE, 16#62, 16#05, 16#01, 16#42, 16#42, 16#42, 16#42).
+-define(TEST_SOURCE_NAME_IE, 16#60, 16#05, "MSC-A").
+-define(TEST_DESTINATION_NAME_IE, 16#61, 16#05, "MSC-B").
+
 
 missing_params_test() ->
   ?assertError({mandatory_ie_missing,location_cancellation_err,[cause]}, gsup_protocol:decode(<<16#1d, ?TEST_IMSI_IE>>)),
@@ -394,3 +399,284 @@
   ?assertEqual(Map, gsup_protocol:decode(Bin)),
   ?assertEqual(Bin, gsup_protocol:encode(Map)).
 
+e_prepare_handover_req_test() ->
+  Bin = <<16#34, ?TEST_IMSI_IE,
+    %% Session ID and state (begin)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#01,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE,
+    ?TEST_AN_APDU_IE %% (Handover Request)
+  >>,
+  Map = #{an_apdu => <<1,66,66,66,66>>,
+                   destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_prepare_handover_req,
+                   session_id => 3735928559,session_state => 1,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_prepare_handover_err_test() ->
+  Bin = <<16#35, ?TEST_IMSI_IE,
+    %% Session ID and state (continue)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#02,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE,
+    ?TEST_AN_APDU_IE, %% (Handover Request) ??? unknown IE
+    %% cause bssap
+    16#64, 16#01, 16#51
+  >>,
+  Map = #{an_apdu => <<1,66,66,66,66>>,
+                   bssap_cause => 81,destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_prepare_handover_err,
+                   session_id => 3735928559,session_state => 2,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_prepare_handover_res_test() ->
+  Bin = <<16#36, ?TEST_IMSI_IE,
+    %% Session ID and state (continue)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#02,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE,
+    ?TEST_AN_APDU_IE %% (Handover Request)
+  >>,
+  Map = #{an_apdu => <<1,66,66,66,66>>,
+                   destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_prepare_handover_res,
+                   session_id => 3735928559,session_state => 2,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_prepare_subseq_handover_req_test() ->
+  Bin = <<16#38, ?TEST_IMSI_IE,
+    %% Session ID and state (begin)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#01,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE,
+    ?TEST_AN_APDU_IE %% (Handover Request)
+  >>,
+  Map = #{an_apdu => <<1,66,66,66,66>>,
+                   destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_prepare_subseq_handover_req,
+                   session_id => 3735928559,session_state => 1,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_prepare_subseq_handover_err_test() ->
+  Bin = <<16#39, ?TEST_IMSI_IE,
+    %% Session ID and state (continue)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#02,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE,
+    ?TEST_AN_APDU_IE, %% (Handover Request) ??? unknown IE
+    %% cause bssap
+    16#64, 16#01, 16#51
+  >>,
+  Map = #{an_apdu => <<1,66,66,66,66>>,
+                   bssap_cause => 81,destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_prepare_subseq_handover_err,
+                   session_id => 3735928559,session_state => 2,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_prepare_subseq_handover_res_test() ->
+  Bin = <<16#3a, ?TEST_IMSI_IE,
+    %% Session ID and state (continue)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#02,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE,
+    ?TEST_AN_APDU_IE %% (Handover Request)
+  >>,
+  Map = #{an_apdu => <<1,66,66,66,66>>,
+                   destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_prepare_subseq_handover_res,
+                   session_id => 3735928559,session_state => 2,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_send_end_signal_req_test() ->
+  Bin = <<16#3c, ?TEST_IMSI_IE,
+    %% Session ID and state (end)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#03,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE,
+    ?TEST_AN_APDU_IE %% (Handover Request)
+  >>,
+  Map = #{an_apdu => <<1,66,66,66,66>>,
+                   destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_send_end_signal_req,
+                   session_id => 3735928559,session_state => 3,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_send_end_signal_err_test() ->
+  Bin = <<16#3d, ?TEST_IMSI_IE,
+    %% Session ID and state (end)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#03,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE,
+    ?TEST_AN_APDU_IE, %% (Handover Request) ??? unknown IE
+    %% cause bssap
+    16#64, 16#01, 16#51
+  >>,
+  Map = #{an_apdu => <<1,66,66,66,66>>,
+                   bssap_cause => 81,destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_send_end_signal_err,
+                   session_id => 3735928559,session_state => 3,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_send_end_signal_res_test() ->
+  Bin = <<16#3e, ?TEST_IMSI_IE,
+    %% Session ID and state (end)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#03,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE,
+    ?TEST_AN_APDU_IE %% (Handover Request)
+  >>,
+  Map = #{an_apdu => <<1,66,66,66,66>>,
+                   destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_send_end_signal_res,
+                   session_id => 3735928559,session_state => 3,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_process_access_signalling_req_test() ->
+  Bin = <<16#40, ?TEST_IMSI_IE,
+    %% Session ID and state (continue)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#02,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE,
+    ?TEST_AN_APDU_IE %% (Handover Request)
+  >>,
+  Map = #{an_apdu => <<1,66,66,66,66>>,
+                   destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_process_access_signalling_req,
+                   session_id => 3735928559,session_state => 2,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_forward_access_signalling_req_test() ->
+  Bin = <<16#44, ?TEST_IMSI_IE,
+    %% Session ID and state (continue)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#02,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE,
+    ?TEST_AN_APDU_IE %% (Handover Request)
+  >>,
+  Map = #{an_apdu => <<1,66,66,66,66>>,
+                   destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_forward_access_signalling_req,
+                   session_id => 3735928559,session_state => 2,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_close_test() ->
+  Bin = <<16#47, ?TEST_IMSI_IE,
+    %% Session ID and state (end)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#03,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE
+  >>,
+  Map = #{
+                   destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_close,
+                   session_id => 3735928559,session_state => 3,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_abort_test() ->
+  Bin = <<16#4b, ?TEST_IMSI_IE,
+    %% Session ID and state (end)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#03,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+     %% cause bssap
+    16#64, 16#01, 16#51
+ >>,
+  Map = #{
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   bssap_cause => 81,message_type => e_abort,
+                   session_id => 3735928559,session_state => 3},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+
+e_routing_error_test() ->
+  Bin = <<16#4e, ?TEST_IMSI_IE,
+    %% Session ID and state (end)
+    16#30, 16#04, 16#de, 16#ad, 16#be, 16#ef,
+    16#31, 16#01, 16#03,
+
+    ?TEST_CLASS_INTER_MSC_IE,
+    ?TEST_SOURCE_NAME_IE,
+    ?TEST_DESTINATION_NAME_IE
+  >>,
+  Map = #{
+                   destination_name => <<"MSC-B">>,
+                   imsi => <<"123456789012345">>,message_class => 4,
+                   message_type => e_routing_err,
+                   session_id => 3735928559,session_state => 3,
+                   source_name => <<"MSC-A">>},
+  ?assertEqual(Map, gsup_protocol:decode(Bin)),
+  ?assertEqual(Bin, gsup_protocol:encode(Map)).
+