anchor.diff:      Datatype = proplists:get_value(datatype, Props),
       lists:member(riak_kv_crdt:to_mod(Datatype), ?V2_TOP_LEVEL_TYPES).
   
  +has_consistent(Props) ->
  +    proplists:get_value(consistent, Props) /= undefined.
  +
  +valid_consistent(Props) ->
  +    case proplists:get_value(consistent, Props) of
  +        true ->
  +            true;
  +        false ->
  +            true;
  +        _ ->
  +            false
  +    end.
  +
  +is_consistent(Props) ->
  +    proplists:get_value(consistent, Props) =:= true.
  +
  +
  +has_n_val(Props) ->
  +    proplists:get_value(n_val, Props) /= undefined.
  +
  +n_val_changed(Existing, New) ->
  +    NewN = proplists:get_value(n_val, New),
  +    proplists:get_value(n_val, Existing) =/= NewN andalso
  +        NewN =/= undefined.
  +
   default_bucket({<<"default">>, _}) ->
       true;
   default_bucket(B) when is_binary(B) ->
  
positive.code:     end;
  coerce_bool(_) ->
      error.
  
  %% @private riak datatype support requires a bucket type of `datatype'
  %% and `allow_mult' set to `true'. These function enforces those
  
negative.code: immutable(_, _New, undefined, _) ->
      true;
  immutable(update, New, Existing, {_Good, Bad}) ->
      case proplists:get_value(consistent, Existing) of
          Consistent when Consistent =:= false orelse
                          Consistent =:= undefined ->
              %% not an existing consistent type (or bucket) so validate it
              %% as a datatype (immutable_dt also covers the case where it was
              %% not a datatype, yes i know this is kind of wierd when you read the
              %% test, sorry...)
              NewDT = proplists:get_value(datatype, New),
              NewAM = proplists:get_value(allow_mult, New),
              ExistingDT = proplists:get_value(datatype, Existing),
              immutable_dt(NewDT, NewAM, ExistingDT, Bad);
          true ->
              %% existing type (or bucket) is consistent
              immutable_consistent(New, Existing, Bad)
      end.
  
  immutable_consistent(New, Existing, Bad) ->
      NewCS = proplists:get_value(consistent, New),
      OldN = proplists:get_value(n_val, Existing),
      NewN = proplists:get_value(n_val, New),
      immutable_consistent(NewCS, OldN, NewN, Bad).
  
  %% Consistent properties must remain consistent and
  %% the n_val must not change. This function assumes the
  %% existing value for consistent is true.
  immutable_consistent(undefined, _N, undefined, _Bad) ->
      %% consistent and n_val not modified
      true;
  immutable_consistent(true, _N, undefined, _Bad) ->
      %% consistent still set to true and n_val not modified
      true;
  immutable_consistent(Consistent, _N, _N, _Bad) when Consistent =:= undefined orelse
                                                      Consistent =:= true ->
      %% consistent not modified or still set to true and n_val
      %% modified but set to same value
      true;
  immutable_consistent(Consistent, _OldN, _NewN, Bad) when Consistent =:= undefined orelse
                                                           Consistent =:= true ->
      %% consistent not modified or still set to true but n_val modified
      has_n_val(Bad);
  immutable_consistent(_Consistent, OldN, NewN, Bad) when OldN =:= NewN orelse
                                                          NewN =:= undefined ->
      %% consistent modified but set to invalid value or false, n_val not modified
      %% or set to existing value
      has_consistent(Bad);
  immutable_consistent(_Consistent, _OldN, _NewN, Bad) ->
      has_consistent(Bad) andalso has_n_val(Bad).
  
  
  %% If data type and allow mult and are in New they must match what is in existing
  %% or be in Bad
  immutable_dt(undefined, undefined, _Meh1, _Bad) ->
      %% datatype and allow_mult are not being modified, so its valid
      true;
  immutable_dt(undefined, _, undefined, _Bad) ->
      %% data type not in new or existing, so its valid
      true;
  immutable_dt(_Datatype, undefined, _Datatype, _Bad) ->
      %% data types from new and existing match and allow mult not modified, valid
      true;
  immutable_dt(_Datatype, true, _Datatype, _Bad) ->
    %% data type from new and existing match and allow mult still set to true, valid
      true;
  immutable_dt(undefined, true, _Datatype, _Bad) ->
      %% data type not modified and allow_mult still set to true, vald
      true;
  immutable_dt(_Datatype, undefined, _Datatype2, Bad) ->
      %% data types do not match, allow_mult not modified
      has_datatype(Bad);
  immutable_dt(_Datatype, true, _Datatype2, Bad) ->
      %% data types do not match, allow_mult still set to true
      has_datatype(Bad);
  immutable_dt(_Datatype, false, undefined, Bad) ->
      %% datatype defined when it wasn't before
      has_datatype(Bad);
  immutable_dt(_Datatype, false, _Datatype, Bad) ->
      %% attempt to set allow_mult to false when data type set is invalid, datatype not modified
      has_allow_mult(Bad);
  immutable_dt(undefined, false, _Meh, Bad) ->
      %% data type not modified but exists and allow_mult set to false is invalid
      has_allow_mult(Bad);
  immutable_dt(_Datatype, false, _Datatype2, Bad) ->
      %% data type changed and allow mult modified to be false, both are invalid
      has_allow_mult(Bad) andalso has_datatype(Bad);
  immutable_dt(undefined, _, _Datatype, Bad) ->
      %% datatype not modified but allow_mult is invalid
      has_allow_mult(Bad);
  immutable_dt(_Datatype, _, _Datatype, Bad) ->
      %% allow mult is invalid but data types still match
      has_allow_mult(Bad);
  immutable_dt(_, _, _, Bad) ->
      %% allow_mult and data type are invalid
      has_allow_mult(Bad) andalso has_datatype(Bad).
  
  only_create_if_valid({Good, Bad}, New) ->
      DT = proplists:get_value(datatype, New),
      AM = proplists:get_value(allow_mult, New),
      CS = proplists:get_value(consistent, New),
      case {DT, AM, CS} of
          %% if consistent or datatype properties are not defined then properties should be
          %% valid since no other properties generated can be in valid
          {undefined, _AllowMult, Consistent} when Consistent =:= false orelse
                                                   Consistent =:= undefined ->
              true;
          %% if datatype is defined, its not a consistent type and allow_mult=true
          %% then the datatype must be valid
          {Datatype, true, Consistent} when Consistent =:= false orelse
                                            Consistent =:= undefined ->
              case lists:member(riak_kv_crdt:to_mod(Datatype), ?V2_TOP_LEVEL_TYPES) of
                  true ->
                      has_datatype(Good) andalso has_allow_mult(Good);
                  false ->
                      has_datatype(Bad) andalso has_allow_mult(Good)
              end;
          %% if the datatype is defined, the type is not consistent and allow_mult is false
          %% then allow_mult should be in the Bad list and the datatype may be depending on if it
          %% is valid
          {Datatype, _, Consistent} when Consistent =:= false orelse
                                         Consistent =:= undefined->
              case lists:member(riak_kv_crdt:to_mod(Datatype), ?V2_TOP_LEVEL_TYPES) of
                  true ->
                      has_allow_mult(Bad) andalso has_datatype(Good);
                  false ->
                      has_datatype(Bad) andalso has_allow_mult(Bad)
              end;
          %% the type is consistent, whether it has a datatype or allow_mult set is irrelevant (for now
          %% at least)
          {_, _, true} ->
              has_consistent(Good);
          %% the type was not inconsistent (explicitly or implicitly) but the value is invalid
          {_, _, _Consistent} ->
              has_consistent(Bad)
      end.
  
  has_datatype(Props) ->
  