anchor.diff:  -type info_item() ::
           {login, name()} |
           {password, ((ClearPassword :: nonempty_string()) |
  -                    (PasswordHash :: binary()))} |
  +                    (PasswordHash :: encrypted_password()))} |
           {created, erlang:timestamp()} |
           {fullname, string()} |
           {timezone, echessd_lib:administrative_offset()} |
  
positive.code: -spec check_property_(InfoItem :: info_item()) -> Value :: any().
  check_property_({password, V}) when is_binary(V) ->
      V;
  check_property_({password, V}) when is_list(V) ->
      true = is_string(V),
      crypto:sha(V);
  check_property_({created, V}) when ?is_now(V) ->
      V;
  check_property_({games, V}) ->
  
negative.code:         {style, StyleID :: atom()} |
          {jid, string()} |
          {games, [echessd_game:id()]}.
  
  -type encrypted_password() ::
          legacy_sha1_encrypted_password() |
          {Algo :: password_encryption_algo(),
           Salt :: binary(),
           EncryptedPassword :: binary()}.
  
  -type password_encryption_algo() :: sha.
  
  -type legacy_sha1_encrypted_password() :: binary().
  
  -type info_item_key() ::
          password | created | login | fullname | timezone |
  