anchor.diff:  -module('utf8').
   
   %% API exports
  --export([encode/1]).
  +-export([encode/1, decode/1]).
   
   %%====================================================================
   %% API functions
  
positive.code: error_on_encode_surrogate_code_points_test() ->
      ?assertThrow(surrogate_value_disallowed, utf8:encode([16#D87f])).
  
  -endif.
  
negative.code:       2#10:2,    Four:6
      >>.
  
  decode(<<>>, ReversedCodePoints) ->
      ReversedCodePoints;
  % Decode ASCII.
  decode(<<0:1, ASCII:7, Rest/binary>>, List) ->
      decode(Rest, [ASCII|List]);
  
  % Decode two byte form.
  decode(<<2#110:3, Upper:5, 2#10:2, Lower:6, Rest/binary>>, List) ->
      <<CodePoint:11/big>> = <<Upper:5, Lower:6>>,
      if
          CodePoint < 16#0080 ->
              throw(overlong_form);
          true ->
              decode(Rest, [CodePoint|List])
      end;
  
  % Decode three byte form.
  decode(<<2#1110:4, Upper:4,
           2#10:2, Middle:6,
           2#10:2, Lower:6, Rest/binary>>, List) ->
      <<CodePoint:16/big>> = <<Upper:4, Middle:6, Lower:6>>,
      if
          CodePoint < 16#0800 ->
              throw(overlong_form);
          16#D800 =< CodePoint, CodePoint =< 16#DFFF ->
              throw(surrogate_value_disallowed);
          true ->
              decode(Rest, [CodePoint|List])
      end;
  
  % Decode four byte form.
  decode(<<2#11110:5, First:3,
           2#10:2,    Second:6,
           2#10:2,    Third:6,
           2#10:2,    Fourth:6, Rest/binary>>, List) ->
      <<CodePoint:21/big>> = <<First:3, Second:6, Third:6, Fourth:6>>,
      case CodePoint < 16#010000 of
          true -> throw(overlong_form);
          _ -> decode(Rest, [CodePoint|List])
      end.
  
  %%====================================================================
  %% Tests
  