anchor.diff:  
   i(I) ->
       lists:duplicate(I*4+4,$\s) .
  +
  +to_atom(L) when is_list(L) ->
  +    list_to_atom(L);
  +to_atom(B) when is_binary(B) ->
  +    binary_to_atom(B, latin1);
  +to_atom(A) when is_atom(A) ->
  +    A.
  +
  +%% duplicated from yang.erl
  +find_enum([{enum, _, Key, I}|T], X) ->
  +    V = get_en_value(I),
  +    if X == V ->
  +            [{Key, V}];
  +       X == Key ->
  +            [{Key, V}|find_enum(T, X)];
  +       true ->
  +            find_enum(T, X)
  +    end;
  +find_enum([_|T], X) ->
  +    find_enum(T, X);
  +find_enum([], _) ->
  +    [].
  +
  +get_en_value(I) ->
  +    {value, _, V, _} = lists:keyfind(value, 1, I),
  +    V.
  +
  +%% ===================================================================
  +%% EUnit Test Code
  +%% ===================================================================
  +-ifdef(TEST).
  +
  +validate_json_simplest_test_() ->
  +    Y = testdata("y0.yang", fun y0/0),
  +    {with, Y,
  +     [
  +      fun simplest_rpc_test1/1
  +     ]}.
  +
  +validate_json_test_() ->
  +    Y = testdata("y.yang", fun y1/0),
  +    {with, Y,
  +     [
  +      fun valid_rpc_test/1,
  +      fun missing_list_test/1
  +     ]}.
  +
  +simplest_rpc_test(Y) ->
  +    {ok, [{a,17,[]}], []} =
  +        yang_json:validate_request(
  +          {call, <<"y0:t0">>,
  +           {struct, [{<<"a">>,17}]}}, Y).
  +
  +simplest_rpc_test1(Y) ->
  +    {ok, [{l,[],[{leaf,_,<<"x">>,[{type,_,<<"uint32">>,_}]}]}], []} =
  +        yang_json:validate_request(
  +          {call, <<"y0:t1">>,
  +           {struct, [{<<"l">>,{array, []}}]}}, Y).
  +
  +valid_rpc_test(Y) ->
  +    {ok, [
  +          {a, 17, [{{<<"y">>,<<"foo">>},_,<<"in_a">>,_},
  +                   {type,_,<<"uint32">>,[]},
  +                   {mandatory,_,true,[]}]},
  +          {b, [<<"abc">>], [{type,_,<<"string">>,[]},
  +                            {'min-elements',_,<<"1">>,[]}]},
  +          {c, [
  +               [{x, 1}, {y, <<"abc">>}]
  +              ], [{leaf,_,<<"x">>,[{{<<"y">>,<<"foo">>},_,<<"in_x">>,_},
  +                                   {type,_,<<"uint32">>,_}]},
  +                  {leaf,_,<<"y">>,[{type,_,<<"string">>,_}]}]}
  +         ], [{{<<"y">>,<<"foo">>},_,<<"input">>,_}]} =
  +        yang_json:validate_request(
  +          {call,<<"y:t1">>,
  +           {struct,[{<<"a">>,17},
  +                    {<<"b">>, {array, [<<"abc">>]}},
  +                    {<<"c">>,{array,[
  +                                     {struct, [{<<"x">>,1},
  +                                               {<<"y">>,<<"abc">>}
  +                                              ]}
  +                                    ]}}
  +                   ]}
  +          }, Y).
  +
  +missing_list_test(Y) ->
  +    {error, {invalid_params, {required, [<<"b">>]} } } =
  +        yang_json:validate_request(
  +          {call,<<"y:t1">>,
  +           {struct,[{<<"a">>,17},
  +                    %% missing <<"b">>
  +                    {<<"c">>,{array,[{struct,[{<<"x">>,1},
  +                                              {<<"y">>,<<"abc">>}]}]}
  +                    }]}
  +          }, Y).
  +
  +testdata(File, Fn) ->
  +    {ok, Y} = yang_parser:deep_parse(
  +                File, [{open_hook, yang:bin_hook([{File, Fn}])}]),
  +    Y.
  +
  +enum_test() ->
  +    File = "e1.yang",
  +    {ok, [{module,_,<<"e1">>, Y}]} =
  +        yang_parser:deep_parse(
  +          File,
  +          [{open_hook, yang:bin_hook([{File, fun e1/0}])}]),
  +    [{leaf,_,<<"l">>,I}] = [E || {leaf,_,<<"l">>,_} = E <- Y],
  +    Type = lists:keyfind(type, 1, I),
  +    {true, <<"zero">>} = yang:check_type(<<"0">>, Type),
  +    {true, <<"zero">>} = yang:check_type(0, Type),
  +    {true, <<"zero">>} = yang:check_type("0", Type),
  +    {true, <<"then">>} = yang:check_type(<<"3">>, Type),
  +    {true, <<"then">>} = yang:check_type(<<"then">>, Type),
  +    {true, <<"3">>} = yang:check_type(<<"4">>, Type),
  +    <<"zero">> = yang_json:to_json_type(<<"0">>, Type),
  +    <<"zero">> = yang_json:to_json_type(0, Type),
  +    <<"zero">> = yang_json:to_json_type("0", Type),
  +    <<"zero">> = yang_json:to_json_type(<<"zero">>, Type),
  +    <<"zero">> = yang_json:to_json_type("zero", Type),
  +    ok.
  +
  +enum_type_test() ->
  +    Type = {type,186,<<"enumeration">>,
  +            [{{<<"$yang">>,<<"origtype">>},186,<<"exo:status-code">>,[]},
  +             {enum,41,<<"accepted">>,
  +              [{description,42,
  +                <<"Operation has been accepted and is in progress.">>,[]},
  +               {value,43,<<"0">>,[]}]},
  +             {enum,46,<<"complete">>,
  +              [{description,47,
  +                <<"The operation has completed successfully.">>,[]},
  +               {value,48,<<"1">>,[]}]},
  +             {enum,51,<<"time-out">>,
  +              [{description,52,<<"Operation has timed out.">>,[]},
  +               {value,53,<<"2">>,[]}]},
  +             {enum,56,<<"device-connected">>,
  +              [{description,57,
  +                <<"A connection has been established...">>,[]},
  +               {value,60,<<"3">>,[]}]},
  +             {enum,63,<<"device-unknown">>,
  +              [{description,64,
  +                <<"The device-id provided with the operation is...">>,[]},
  +               {value,66,<<"4">>,[]}]},
  +             {enum,70,<<"device-error">>,
  +              [{description,71,
  +                <<"The device encountered an error when ...">>,[]},
  +               {value,74,<<"5">>,[]}]},
  +             {enum,77,<<"format-error">>,
  +              [{description,78,<<"The RPC had an incorrect element ...">>,
  +                []},
  +               {value,79,<<"6">>,[]}]},
  +             {enum,82,<<"value-error">>,
  +              [{description,83,<<"The RPC had illegal values in ...">>,[]},
  +               {value,85,<<"7">>,[]}]}]},
  +    {true, <<"value-error">>} = yang:check_type(7, Type),
  +    {true, <<"value-error">>} = yang:check_type("7", Type),
  +    {true, <<"value-error">>} = yang:check_type(<<"7">>, Type),
  +    ok.
  +
  +e1() ->
  +    <<
  +"module e1 {
  +  namespace \"http://feuerlabs.com/test\";
  +  prefix e1;
  +
  +  leaf l {
  +    type enumeration {
  +      enum zero;
  +      enum one;
  +      enum then { value 3; }
  +      enum 3;
  +    }
  +  }
  +}"
  +>>.
  +
  +y0() ->
  +    <<
  +"module y0 {
  +  namespace \"http://feuerlabs.com/test\";
  +  prefix y;
  +
  +  rpc t0 {
  +    input {
  +       leaf a {
  +         type uint32;
  +         mandatory true;
  +       }
  +    }
  +  }
  +  rpc t1 {
  +    input {
  +      list l {
  +        leaf x {
  +          type uint32;
  +        }
  +      }
  +    }
  +  }
  +}"
  +>>.
  +
  +y1() ->
  +    <<
  +"module y {
  +  namespace \"http://feuerlabs.com/test\";
  +  prefix y;
  +
  +  extension foo {
  +    argument x;
  +  }
  +
  +  rpc t1 {
  +    input {
  +       y:foo 'input';
  +       leaf a {
  +         y:foo 'in_a';
  +         type uint32;
  +         mandatory true;
  +       }
  +       leaf-list b {
  +         type string;
  +         min-elements 1;
  +       }
  +       list c {
  +         leaf x {
  +           y:foo 'in_x';
  +           type uint32;
  +         }
  +         leaf y {
  +           type string;
  +         }
  +      }
  +    }
  +  }
  +}"
  +>>.
  +-endif.
  
positive.code: 
  record_defs(_RPCs, _M) ->
      [].
  
  to_json_rpc(Data, Arg, M) ->
      Imports = imports(Data, Arg),
  
negative.code: %%%---- END COPYRIGHT ---------------------------------------------------------
  -module(yang_json).
  -compile(export_all).
  
  -ifdef(TEST).
  -include_lib("eunit/include/eunit.hrl").
  -endif.
  
  -define(fd(Fl, A, B), Fl when A =< X, X =< B).
  
  