anchor.diff:  	   end,
       Bytes = encode_tag_val({Class,NewForm,No}),
       {Bytes,size(Bytes)}.
  -
  -%%===============================================================================
  -%% Change the tag (used when an implicit tagged type has a reference to something else)
  -%% The constructed bit in the tag is taken from the tag to be replaced.
  -%%
  -%% change_tag(NewTag,[Tag,Buffer]) -> [NewTag,Buffer]
  -%%===============================================================================
  -
  -%change_tag({NewClass,NewTagNr}, Buffer) ->
  -%    {{OldClass, OldForm, OldTagNo}, Buffer1, RemovedBytes} = decode_tag(lists:flatten(Buffer)),
  -%    [encode_tag_val({NewClass, OldForm, NewTagNr}) | Buffer1].
  -
  -
  -%%===============================================================================
  -%%
  -%% This comment is valid for all the encode/decode functions
  -%%
  -%% C = Constraint -> typically {'ValueRange',LowerBound,UpperBound}
  -%%     used for PER-coding but not for BER-coding.
  -%%
  -%% Val = Value.  If Val is an atom then it is a symbolic integer value
  -%%       (i.e the atom must be one of the names in the NamedNumberList).
  -%%       The NamedNumberList is used to translate the atom to an integer value
  -%%       before encoding.
  -%%
  -%%===============================================================================
  -
  -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  -%% encode_open_type(Value) -> CompleteList
  -%% Value = list of bytes of an already encoded value (the list must be flat)
  -%%         | binary
  -
  -%% This version does not consider Explicit tagging of the open type. It
  -%% is only left because of backward compatibility.
  -encode_open_type(Val) when is_list(Val) ->
  -    {Val, byte_size(list_to_binary(Val))};
  -encode_open_type(Val) ->
  -    {Val, byte_size(Val)}.
  -
  -%%
  -encode_open_type(Val, []) when is_list(Val) ->
  -    {Val, byte_size(list_to_binary(Val))};
  -encode_open_type(Val, []) ->
  -    {Val, byte_size(Val)};
  -encode_open_type(Val, Tag) when is_list(Val) ->
  -    encode_tags(Tag, Val, byte_size(list_to_binary(Val)));
  -encode_open_type(Val, Tag) ->
  -    encode_tags(Tag, Val, byte_size(Val)).
  -
  -
  -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  -%% decode_open_type(Buffer) -> Value
  -%% Bytes = [byte] with BER encoded data
  -%% Value = [byte] with decoded data (which must be decoded again as some type)
  -%%
  -decode_open_type(Bytes) ->
  -%    {_Tag, Len, _RemainingBuffer, RemovedBytes} = decode_tag_and_length(Bytes),
  -%    N = Len + RemovedBytes,
  -    {_Tag, Len, RemainingBuffer, RemovedBytes} = decode_tag_and_length(Bytes),
  -    {_RemainingBuffer2, RemovedBytes2} = skipvalue(Len, RemainingBuffer, RemovedBytes),
  -    N = RemovedBytes2,
  -    <<Val:N/binary, RemainingBytes/binary>> = Bytes,
  -%    {Val, RemainingBytes, Len + RemovedBytes}.
  -    {Val,RemainingBytes,N}.
  -
  -decode_open_type(<<>>,[]=ExplTag) -> % R9C-0.patch-40
  -    exit({error, {asn1,{no_optional_tag, ExplTag}}});
  -decode_open_type(Bytes,ExplTag) ->
  -    {Tag, Len, RemainingBuffer, RemovedBytes} = decode_tag_and_length(Bytes),
  -    case {Tag,ExplTag} of
  -% 	{{Class,Form,32},[#tag{class=Class,number=No,form=32}]} ->
  -% 	    {_Tag2, Len2, RemainingBuffer2, RemovedBytes2} = decode_tag_and_length(RemainingBuffer),
  -% 	    {_RemainingBuffer3, RemovedBytes3} = skipvalue(Len2, RemainingBuffer2, RemovedBytes2),
  -% 	    N = RemovedBytes3,
  -% 	    <<_:RemovedBytes/unit:8,Val:N/binary,RemainingBytes/binary>> = Bytes,
  -% 	    {Val, RemainingBytes, N + RemovedBytes};
  -	{{Class,Form,No},[#tag{class=Class,number=No,form=Form}]} ->
  -	    {_RemainingBuffer2, RemovedBytes2} =
  -		skipvalue(Len, RemainingBuffer),
  -	    N = RemovedBytes2,
  -	    <<_:RemovedBytes/unit:8,Val:N/binary,RemainingBytes/binary>> = Bytes,
  -	    {Val, RemainingBytes, N + RemovedBytes};
  -	_ ->
  -	    {_RemainingBuffer2, RemovedBytes2} =
  -		skipvalue(Len, RemainingBuffer, RemovedBytes),
  -	    N = RemovedBytes2,
  -	    <<Val:N/binary, RemainingBytes/binary>> = Bytes,
  -	    {Val, RemainingBytes, N}
  -    end.
  -
  -decode_open_type(ber_bin,Bytes,ExplTag) ->
  -    decode_open_type(Bytes,ExplTag);
  -decode_open_type(ber,Bytes,ExplTag) ->
  -    {Val,RemBytes,Len}=decode_open_type(Bytes,ExplTag),
  -    {binary_to_list(Val),RemBytes,Len}.
  -
  -%%===============================================================================
  -%%===============================================================================
  -%%===============================================================================
  -%% Boolean, ITU_T X.690 Chapter 8.2
  -%%===============================================================================
  -%%===============================================================================
  -%%===============================================================================
  -
  -%%===============================================================================
  -%% encode_boolean(Integer, tag | notag) -> [octet list]
  -%%===============================================================================
  -
  -encode_boolean({Name, Val}, DoTag) when is_atom(Name) ->
  -    dotag(DoTag, ?N_BOOLEAN, encode_boolean(Val));
  -encode_boolean(true,[]) ->
  -    {[1,1,16#FF],3};
  -encode_boolean(false,[]) ->
  -    {[1,1,0],3};
  -encode_boolean(Val, DoTag) ->
  -    dotag(DoTag, ?N_BOOLEAN, encode_boolean(Val)).
  -
  -%% encode_boolean(Boolean) -> [Len, Boolean] = [1, $FF | 0]
  -encode_boolean(true)   ->    {[16#FF],1};
  -encode_boolean(false)  ->    {[0],1};
  -encode_boolean(X) -> exit({error,{asn1, {encode_boolean, X}}}).
  -
  -
  -%%===============================================================================
  -%% decode_boolean(BuffList, HasTag, TotalLen) -> {true, Remain, RemovedBytes} |
  -%%                                               {false, Remain, RemovedBytes}
  -%%===============================================================================
  -
  -decode_boolean(Buffer, Tags, OptOrMand) ->
  -    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_BOOLEAN}),
  -    decode_boolean_notag(Buffer, NewTags, OptOrMand).
  -
  -decode_boolean_notag(Buffer, Tags, OptOrMand) ->
  -    {RestTags, {FormLen,Buffer0,Rb0}} =
  -	check_tags_i(Tags, Buffer, OptOrMand),
  -    case FormLen of
  -	{?CONSTRUCTED,Len} ->
  -	    {Buffer00,RestBytes} = split_list(Buffer0,Len),
  -	    {Val,Buffer1,Rb1} = decode_boolean_notag(Buffer00, RestTags, OptOrMand),
  -	    {Buffer2, Rb2} = restbytes2(RestBytes,Buffer1,noext),
  -	    {Val, Buffer2, Rb0+Rb1+Rb2};
  -	{_,_} ->
  -	    decode_boolean2(Buffer0, Rb0)
  -    end.
  -
  -decode_boolean2(<<0:8, Buffer/binary>>, RemovedBytes) ->
  -    {false, Buffer, RemovedBytes + 1};
  -decode_boolean2(<<_:8, Buffer/binary>>, RemovedBytes) ->
  -    {true, Buffer, RemovedBytes + 1};
  -decode_boolean2(Buffer, _) ->
  -    exit({error,{asn1, {decode_boolean, Buffer}}}).
  -
  -
  -%%===========================================================================
  -%% Integer, ITU_T X.690 Chapter 8.3
  -
  -%% encode_integer(Constraint, Value, Tag) -> [octet list]
  -%% encode_integer(Constraint, Name, NamedNumberList, Tag) -> [octet list]
  -%%    Value = INTEGER | {Name,INTEGER}
  -%%    Tag = tag | notag
  -%%===========================================================================
  -
  -encode_integer(C, Val, []) when is_integer(Val) ->
  -    {EncVal,Len} = encode_integer(C, Val),
  -    dotag_universal(?N_INTEGER,EncVal,Len);
  -encode_integer(C, Val, Tag) when is_integer(Val) ->
  -    dotag(Tag, ?N_INTEGER, encode_integer(C, Val));
  -encode_integer(C,{Name,Val},Tag) when is_atom(Name) ->
  -    encode_integer(C,Val,Tag);
  -encode_integer(_, Val, _) ->
  -    exit({error,{asn1, {encode_integer, Val}}}).
  -
  -
  -encode_integer(C, Val, NamedNumberList, Tag) when is_atom(Val) ->
  -    case lists:keyfind(Val, 1, NamedNumberList) of
  -	{_, NewVal} ->
  -	    dotag(Tag, ?N_INTEGER, encode_integer(C, NewVal));
  -	_ ->
  -	    exit({error,{asn1, {encode_integer_namednumber, Val}}})
  -    end;
  -encode_integer(C,{_,Val},NamedNumberList,Tag) ->
  -    encode_integer(C,Val,NamedNumberList,Tag);
  -encode_integer(C, Val, _NamedNumberList, Tag) ->
  -    dotag(Tag, ?N_INTEGER, encode_integer(C, Val)).
  -
  -
  -encode_integer(_C, Val) ->
  -    Bytes =
  -	if
  -	    Val >= 0 ->
  -		encode_integer_pos(Val, []);
  -	    true ->
  -		encode_integer_neg(Val, [])
  -	end,
  -    {Bytes,length(Bytes)}.
  -
  -encode_integer_pos(0, L=[B|_Acc]) when B < 128 ->
  -    L;
  -encode_integer_pos(N, Acc) ->
  -    encode_integer_pos((N bsr 8), [N band 16#ff| Acc]).
  -
  -encode_integer_neg(-1, L=[B1|_T]) when B1 > 127 ->
  -    L;
  -encode_integer_neg(N, Acc) ->
  -    encode_integer_neg(N bsr 8, [N band 16#ff|Acc]).
  -
  -%%===============================================================================
  -%% decode integer
  -%%    (Buffer, Range, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
  -%%    (Buffer, Range, NamedNumberList, HasTag, TotalLen) -> {Integer, Remain, RemovedBytes}
  -%%===============================================================================
  -
  -decode_integer(Buffer, Range, Tags, OptOrMand) ->
  -    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_INTEGER}),
  -    decode_integer_notag(Buffer, Range, [], NewTags, OptOrMand).
  -
  -decode_integer(Buffer, Range, NamedNumberList, Tags, OptOrMand) ->
  -    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_INTEGER}),
  -    decode_integer_notag(Buffer, Range, NamedNumberList, NewTags, OptOrMand).
  -
  -decode_integer_notag(Buffer, Range, NamedNumberList, NewTags, OptOrMand) ->
  -    {RestTags, {FormLen, Buffer0, Rb0}} =
  -	check_tags_i(NewTags, Buffer, OptOrMand),
  -%    Result = {Val, Buffer2, RemovedBytes} =
  -	case FormLen of
  -	    {?CONSTRUCTED,Len} ->
  -		{Buffer00, RestBytes} = split_list(Buffer0,Len),
  -		{Val01, Buffer01, Rb01} =
  -		    decode_integer_notag(Buffer00, Range, NamedNumberList,
  -					 RestTags, OptOrMand),
  -		{Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
  -		{Val01, Buffer02, Rb0+Rb01+Rb02};
  -	    {_, Len} ->
  -		Result =
  -		    decode_integer2(Len,Buffer0,Rb0+Len),
  -		Result2 = check_integer_constraint(Result,Range),
  -		resolve_named_value(Result2,NamedNumberList)
  -	end.
  -
  -resolve_named_value(Result={Val,Buffer,RemBytes},NamedNumberList) ->
  -    case NamedNumberList of
  -	[] -> Result;
  -	_ ->
  -	    NewVal = case lists:keyfind(Val, 2, NamedNumberList) of
  -			 {NamedVal, _} ->
  -			     NamedVal;
  -			 _ ->
  -			     Val
  -		     end,
  -	    {NewVal, Buffer, RemBytes}
  -    end.
  -
  -check_integer_constraint(Result={Val, _Buffer,_},Range) ->
  -    case Range of
  -	[] -> % No length constraint
  -	    Result;
  -	{Lb,Ub} when Val >= Lb, Ub >= Val -> % variable length constraint
  -	    Result;
  -	Val -> % fixed value constraint
  -	    Result;
  -	{_,_} ->
  -	    exit({error,{asn1,{integer_range,Range,Val}}});
  -	SingleValue when is_integer(SingleValue) ->
  -	    exit({error,{asn1,{integer_range,Range,Val}}});
  -	_ -> % some strange constraint that we don't support yet
  -	    Result
  -    end.
  -
  -%%============================================================================
  -%% Enumerated value, ITU_T X.690 Chapter 8.4
  -
  -%% encode enumerated value
  -%%============================================================================
  -encode_enumerated(Val, []) when is_integer(Val) ->
  -    {EncVal,Len} = encode_integer(false,Val),
  -    dotag_universal(?N_ENUMERATED,EncVal,Len);
  -encode_enumerated(Val, DoTag) when is_integer(Val) ->
  -    dotag(DoTag, ?N_ENUMERATED, encode_integer(false,Val));
  -encode_enumerated({Name,Val}, DoTag) when is_atom(Name) ->
  -    encode_enumerated(Val, DoTag).
  -
  -%% The encode_enumerated functions below this line can be removed when the
  -%% new code generation is stable. (the functions might have to be kept here
  -%% a while longer for compatibility reasons)
  -
  -encode_enumerated(C, Val, {NamedNumberList,ExtList}, DoTag) when is_atom(Val) ->
  -    case catch encode_enumerated(C, Val, NamedNumberList, DoTag) of
  -	{'EXIT',_} -> encode_enumerated(C, Val, ExtList, DoTag);
  -	Result -> Result
  -    end;
  -
  -encode_enumerated(C, Val, NamedNumberList, DoTag) when is_atom(Val) ->
  -    case lists:keyfind(Val, 1, NamedNumberList) of
  -	{_, NewVal} when DoTag =:= [] ->
  -	    {EncVal,Len} = encode_integer(C,NewVal),
  -	    dotag_universal(?N_ENUMERATED,EncVal,Len);
  -	{_, NewVal} ->
  -	    dotag(DoTag, ?N_ENUMERATED, encode_integer(C, NewVal));
  -	_ ->
  -	    exit({error,{asn1, {enumerated_not_in_range, Val}}})
  -    end;
  -
  -encode_enumerated(C, {asn1_enum, Val}, {_,_}, DoTag) when is_integer(Val) ->
  -    dotag(DoTag, ?N_ENUMERATED, encode_integer(C,Val));
  -
  -encode_enumerated(C, {Name,Val}, NamedNumberList, DoTag) when is_atom(Name) ->
  -    encode_enumerated(C, Val, NamedNumberList, DoTag);
  -
  -encode_enumerated(_, Val, _, _) ->
  -    exit({error,{asn1, {enumerated_not_namednumber, Val}}}).
  -
  -
  -
  -%%============================================================================
  -%% decode enumerated value
  -%%   (Buffer, Range, NamedNumberList, HasTag, TotalLen) ->
  -%%                                    {Value, RemainingBuffer, RemovedBytes}
  -%%===========================================================================
  -decode_enumerated(Buffer, Range, NamedNumberList, Tags, OptOrMand) ->
  -    NewTags = new_tags(Tags,#tag{class=?UNIVERSAL,number=?N_ENUMERATED}),
  -    decode_enumerated_notag(Buffer, Range, NamedNumberList,
  -			    NewTags, OptOrMand).
  -
  -decode_enumerated_notag(Buffer, Range, NNList = {NamedNumberList,ExtList}, Tags, OptOrMand) ->
  -    {RestTags, {FormLen, Buffer0, Rb0}} =
  -	check_tags_i(Tags, Buffer, OptOrMand),
  -
  -    case FormLen of
  -	{?CONSTRUCTED,Len} ->
  -	    {Buffer00,RestBytes} = split_list(Buffer0,Len),
  -	    {Val01, Buffer01, Rb01} =
  -		decode_enumerated_notag(Buffer00, Range, NNList, RestTags, OptOrMand),
  -	    {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
  -	    {Val01, Buffer02, Rb0+Rb01+Rb02};
  -	{_,Len} ->
  -	    {Val01, Buffer01, Rb01} =
  -		decode_integer2(Len, Buffer0, Rb0+Len),
  -	    case decode_enumerated1(Val01, NamedNumberList) of
  -		{asn1_enum,Val01} ->
  -		    {decode_enumerated1(Val01,ExtList), Buffer01, Rb01};
  -		Result01 ->
  -		    {Result01, Buffer01, Rb01}
  -	    end
  -    end;
  -
  -decode_enumerated_notag(Buffer, Range, NNList, Tags, OptOrMand) ->
  -    {RestTags, {FormLen, Buffer0, Rb0}} =
  -	check_tags_i(Tags, Buffer, OptOrMand),
  -
  -    case FormLen of
  -	{?CONSTRUCTED,Len} ->
  -	    {Buffer00,RestBytes} = split_list(Buffer0,Len),
  -	    {Val01, Buffer01, Rb01} =
  -		decode_enumerated_notag(Buffer00, Range, NNList, RestTags, OptOrMand),
  -	    {Buffer02, Rb02} = restbytes2(RestBytes,Buffer01,noext),
  -	    {Val01, Buffer02, Rb0+Rb01+Rb02};
  -	{_,Len} ->
  -	    {Val01, Buffer02, Rb02} =
  -		decode_integer2(Len, Buffer0, Rb0+Len),
  -	    case decode_enumerated1(Val01, NNList) of
  -		{asn1_enum,_} ->
  -		    exit({error,{asn1, {illegal_enumerated, Val01}}});
  -		Result01 ->
  -		    {Result01, Buffer02, Rb02}
  -	    end
  -    end.
  -
  -decode_enumerated1(Val, NamedNumberList) ->
  -    %% it must be a named integer
  -    case lists:keyfind(Val, 2, NamedNumberList) of
  -	{NamedVal, _} ->
  -	    NamedVal;
  -	_ ->
  -	    {asn1_enum,Val}
  -    end.
  -
   
   %%============================================================================
   %%
  
positive.code:     <<Length:LL/unit:8,Rest/binary>> = T,
      {{Length,Rest}, LL+1}.
  
  %decode_length([128 | T]) ->
  %    {{indefinite, T},1};
  %decode_length([H | T]) when H =< 127 ->
  %    {{H, T},1};
  %decode_length([H | T]) ->
  %    dec_long_length(H band 16#7F, T, 0, 1).
  
  
  %%dec_long_length(0, Buffer, Acc, Len) ->
  %%    {{Acc, Buffer},Len};
  %%dec_long_length(Bytes, [H | T], Acc, Len) ->
  %%    dec_long_length(Bytes - 1, T, (Acc bsl 8) + H, Len+1).
  
  %%===========================================================================
  %% Decode tag and length
  %%
  %% decode_tag_and_length(Buffer) -> {Tag, Len, RemainingBuffer, RemovedBytes}
  %%
  %%===========================================================================
  
  decode_tag_and_length(Buffer) ->
      {Tag, Buffer2, RemBytesTag} = decode_tag(Buffer),
      {{Len, Buffer3}, RemBytesLen} = decode_length(Buffer2),
      {Tag, Len, Buffer3, RemBytesTag+RemBytesLen}.
  
  
  %%============================================================================
  %% Check if valid tag
  %%
  %% check_if_valid_tag(Tag, List_of_valid_tags, OptOrMand) -> name of the tag
  %%============================================================================
  
  check_if_valid_tag(<<0,0,_/binary>>,_,_) ->
      asn1_EOC;
  check_if_valid_tag(<<>>, _, OptOrMand) ->
      check_if_valid_tag2_error([], OptOrMand);
  check_if_valid_tag(Bytes, ListOfTags, OptOrMand) when is_binary(Bytes) ->
      {Tag, _, _} = decode_tag(Bytes),
      check_if_valid_tag(Tag, ListOfTags, OptOrMand);
  
  %% This alternative should be removed in the near future
  %% Bytes as input should be the only necessary call
  check_if_valid_tag(Tag, ListOfTags, OptOrMand) ->
      {Class, _Form, TagNo} = Tag,
      C = code_class(Class),
      T = case C of
  	    'UNIVERSAL' ->
  		code_type(TagNo);
  	    _ ->
  		TagNo
  	end,
      check_if_valid_tag2({C,T}, ListOfTags, Tag, OptOrMand).
  
  check_if_valid_tag2(_Class_TagNo, [], Tag, MandOrOpt) ->
      check_if_valid_tag2_error(Tag,MandOrOpt);
  check_if_valid_tag2(Class_TagNo, [{TagName,TagList}|T], Tag, OptOrMand) ->
      case check_if_valid_tag_loop(Class_TagNo, TagList) of
  	true ->
  	    TagName;
  	false ->
  	    check_if_valid_tag2(Class_TagNo, T, Tag, OptOrMand)
      end.
  
  -spec check_if_valid_tag2_error(term(), atom()) -> no_return().
  
  check_if_valid_tag2_error(Tag,mandatory) ->
      exit({error,{asn1,{invalid_tag,Tag}}});
  check_if_valid_tag2_error(Tag,_) ->
      exit({error,{asn1,{no_optional_tag,Tag}}}).
  
  check_if_valid_tag_loop(_Class_TagNo,[]) ->
      false;
  check_if_valid_tag_loop(Class_TagNo,[H|T]) ->
      %% It is not possible to distinguish between SEQUENCE OF and SEQUENCE, and
      %% between SET OF and SET because both are coded as 16 and 17, respectively.
      H_without_OF = case H of
  		       {C, 'SEQUENCE OF'} ->
  			   {C, 'SEQUENCE'};
  		       {C, 'SET OF'} ->
  			   {C, 'SET'};
  		       Else ->
  			   Else
  		   end,
  
      case H_without_OF of
  	Class_TagNo ->
  	    true;
  	{_,_} ->
  	    check_if_valid_tag_loop(Class_TagNo,T);
  	_ ->
  	    check_if_valid_tag_loop(Class_TagNo,H),
  	    check_if_valid_tag_loop(Class_TagNo,T)
      end.
  
  
  
  code_class(0) -> 'UNIVERSAL';
  code_class(16#40) -> 'APPLICATION';
  code_class(16#80) -> 'CONTEXT';
  code_class(16#C0) -> 'PRIVATE'.
  
  
  code_type(1) -> 'BOOLEAN';
  code_type(2) -> 'INTEGER';
  code_type(3) -> 'BIT STRING';
  code_type(4) -> 'OCTET STRING';
  code_type(5) -> 'NULL';
  code_type(6) -> 'OBJECT IDENTIFIER';
  code_type(7) -> 'ObjectDescriptor';
  code_type(8) -> 'EXTERNAL';
  code_type(9) -> 'REAL';
  code_type(10) -> 'ENUMERATED';
  code_type(11) -> 'EMBEDDED_PDV';
  code_type(16) -> 'SEQUENCE';
  % code_type(16) -> 'SEQUENCE OF';
  code_type(17) -> 'SET';
  % code_type(17) -> 'SET OF';
  code_type(18) -> 'NumericString';
  code_type(19) -> 'PrintableString';
  code_type(20) -> 'TeletexString';
  code_type(21) -> 'VideotexString';
  code_type(22) -> 'IA5String';
  code_type(23) -> 'UTCTime';
  code_type(24) -> 'GeneralizedTime';
  code_type(25) -> 'GraphicString';
  code_type(26) -> 'VisibleString';
  code_type(27) -> 'GeneralString';
  code_type(28) -> 'UniversalString';
  code_type(30) -> 'BMPString';
  code_type(Else) -> exit({error,{asn1,{unrecognized_type,Else}}}).
  
  %%-------------------------------------------------------------------------
  %% decoding of the components of a SET
  %%-------------------------------------------------------------------------
  
  decode_set(Rb, indefinite, <<0,0,Bytes/binary>>, _OptOrMand, _Fun3, Acc) ->
     {lists:reverse(Acc),Bytes,Rb+2};
  
  decode_set(Rb, indefinite, Bytes, OptOrMand, Fun3, Acc) ->
      case Fun3(Bytes, OptOrMand) of
  	{_Term, _Remain, 0} ->
  	    {lists:reverse(Acc),Bytes,Rb};
  	{Term, Remain, Rb1} ->
  	    Fun3(Bytes, OptOrMand),
  	    decode_set(Rb+Rb1, indefinite, Remain, OptOrMand, Fun3, [Term|Acc])
      end;
  %%   {Term, Remain, Rb1} = Fun3(Bytes, OptOrMand),
  %%   decode_set(Rb+Rb1, indefinite, Remain, OptOrMand, Fun3, [Term|Acc]);
  
  decode_set(Rb, Num, Bytes, _OptOrMand, _Fun3, Acc) when Num == 0 ->
     {lists:reverse(Acc), Bytes, Rb};
  
  decode_set(_, Num, _, _, _, _) when Num < 0 ->
     exit({error,{asn1,{length_error,'SET'}}});
  
  decode_set(Rb, Num, Bytes, OptOrMand, Fun3, Acc) ->
      case Fun3(Bytes, OptOrMand) of
  	{_Term, _Remain, 0} ->
  	    {lists:reverse(Acc),Bytes,Rb};
  	{Term, Remain, Rb1} ->
  	    Fun3(Bytes, OptOrMand),
  	    decode_set(Rb+Rb1, Num-Rb1, Remain, OptOrMand, Fun3, [Term|Acc])
      end.
  %%    {Term, Remain, Rb1} = Fun3(Bytes, OptOrMand),
  %%    decode_set(Rb+Rb1, Num-Rb1, Remain, OptOrMand, Fun3, [Term|Acc]).
  
  
  %%-------------------------------------------------------------------------
  %% decoding of SEQUENCE OF and SET OF
  %%-------------------------------------------------------------------------
  
  decode_components(Rb, indefinite, <<0,0,Bytes/binary>>, _Fun3, _TagIn, Acc) ->
     {lists:reverse(Acc),Bytes,Rb+2};
  
  decode_components(Rb, indefinite, Bytes, Fun3, TagIn, Acc) ->
     {Term, Remain, Rb1} = Fun3(Bytes, mandatory, TagIn),
     decode_components(Rb+Rb1, indefinite, Remain, Fun3, TagIn, [Term|Acc]);
  
  decode_components(Rb, Num, Bytes, _Fun3, _TagIn, Acc) when Num == 0 ->
     {lists:reverse(Acc), Bytes, Rb};
  
  decode_components(_, Num, _, _, _, _) when Num < 0 ->
     exit({error,{asn1,{length_error,'SET/SEQUENCE OF'}}});
  
  decode_components(Rb, Num, Bytes, Fun3, TagIn, Acc) ->
     {Term, Remain, Rb1} = Fun3(Bytes, mandatory, TagIn),
     decode_components(Rb+Rb1, Num-Rb1, Remain, Fun3, TagIn, [Term|Acc]).
  
  %%decode_components(Rb, indefinite, [0,0|Bytes], _Fun3, _TagIn, Acc) ->
  %%   {lists:reverse(Acc),Bytes,Rb+2};
  
  decode_components(Rb, indefinite, <<0,0,Bytes/binary>>, _Fun4, _TagIn, _Fun, Acc) ->
     {lists:reverse(Acc),Bytes,Rb+2};
  
  decode_components(Rb, indefinite, Bytes, _Fun4, TagIn, _Fun, Acc) ->
     {Term, Remain, Rb1} = _Fun4(Bytes, mandatory, TagIn, _Fun),
     decode_components(Rb+Rb1, indefinite, Remain, _Fun4, TagIn, _Fun, [Term|Acc]);
  
  decode_components(Rb, Num, Bytes, _Fun4, _TagIn, _Fun, Acc) when Num == 0 ->
     {lists:reverse(Acc), Bytes, Rb};
  
  decode_components(_, Num, _, _, _, _, _) when Num < 0 ->
     exit({error,{asn1,{length_error,'SET/SEQUENCE OF'}}});
  
  decode_components(Rb, Num, Bytes, _Fun4, TagIn, _Fun, Acc) ->
     {Term, Remain, Rb1} = _Fun4(Bytes, mandatory, TagIn, _Fun),
     decode_components(Rb+Rb1, Num-Rb1, Remain, _Fun4, TagIn, _Fun, [Term|Acc]).
  
  
  
  %%-------------------------------------------------------------------------
  %% INTERNAL HELPER FUNCTIONS (not exported)
  %%-------------------------------------------------------------------------
  
  
  %%==========================================================================
  %% Encode tag
  %%
  %% dotag(tag | notag, TagValpattern | TagValTuple, [Length, Value]) -> [Tag]
  %% TagValPattern is a correct bitpattern for a tag
  %% TagValTuple is a tuple of three bitpatterns, Class, Form and TagNo where
  %%     Class = UNIVERSAL | APPLICATION | CONTEXT | PRIVATE
  %%     Form  = Primitive | Constructed
  %%     TagNo = Number of tag
  %%==========================================================================
  
  
  dotag([], Tag, {Bytes,Len}) ->
      dotag_universal(Tag,Bytes,Len);
  dotag(Tags, Tag, {Bytes,Len}) ->
      encode_tags(Tags ++ [#tag{class=?UNIVERSAL,number=Tag,form=?PRIMITIVE}],
  		Bytes, Len);
  
  dotag(Tags, Tag, Bytes) ->
      encode_tags(Tags ++ [#tag{class=?UNIVERSAL,number=Tag,form=?PRIMITIVE}],
  		Bytes, size(Bytes)).
  
  dotag_universal(UniversalTag,Bytes,Len) when Len =< 16#7F->
      {[UniversalTag,Len,Bytes],2+Len};
  
negative.code:     mk_object_val(Val bsr 7, [((Val band 127) bor 128) | Ack], Len + 1).
  
  
  %%============================================================================
  %% Length handling
  %%
  