anchor.diff:  format_value(Val) when is_list(Val) ->
       Val.
   
  -
   %% @doc Map a ACL group atom to its corresponding URI.
   -spec uri_for_group(atom()) -> string().
   uri_for_group('AllUsers') ->
       ?ALL_USERS_GROUP;
   uri_for_group('AuthUsers') ->
       ?AUTH_USERS_GROUP.
  +
   %% ===================================================================
   %% Eunit tests
   %% ===================================================================
  
positive.code: %% @doc Convert an internal representation of an ACL
  %% into XML.
  -spec acl_to_xml(acl()) -> binary().
  acl_to_xml(?ACL{owner=Owner, grants=Grants}) ->
      {OwnerName, OwnerId, _} = Owner,
      XmlDoc =
          [{'AccessControlPolicy',
            [
             {'Owner',
              [
               {'ID', [OwnerId]},
               {'DisplayName', [OwnerName]}
              ]},
             {'AccessControlList', grants_xml(Grants)}
            ]}],
      export_xml(XmlDoc);
  acl_to_xml(#acl_v1{owner=Owner, grants=Grants}) ->
      {OwnerName, OwnerId} = Owner,
      XmlDoc =
          [{'AccessControlPolicy',
            [
             {'Owner',
              [
               {'ID', [OwnerId]},
               {'DisplayName', [OwnerName]}
              ]},
             {'AccessControlList', grants_xml(Grants)}
            ]}],
      export_xml(XmlDoc).
  
  list_objects_response_to_xml(Resp) ->
      Contents = [key_content_to_xml(Content) ||
                     Content <- (Resp?LORESP.contents)],
      %% CommonPrefixes = common_prefixes_to_xml(Resp?LORESP.common_prefixes),
      CommonPrefixes = [],
      XmlDoc = [{'ListBucketResult',
                 [{'Name', [format_value(Resp?LORESP.name)]},
                  {'Prefix', [format_value(Resp?LORESP.prefix)]},
                  {'Marker', [format_value(Resp?LORESP.marker)]},
                  {'MaxKeys', [format_value(Resp?LORESP.max_keys)]},
                  {'Delimiter', [format_value(Resp?LORESP.delimiter)]},
                  {'IsTruncated', [format_value(Resp?LORESP.is_truncated)]}] ++
                     Contents ++ CommonPrefixes}],
      export_xml(XmlDoc).
  
  key_content_to_xml(KeyContent) ->
      {'Contents', [{'Key', [format_value(KeyContent?LOKC.key)]},
                    {'LastModified', [format_value(KeyContent?LOKC.last_modified)]},
                    {'ETag', ["\"" ++ format_value(KeyContent?LOKC.etag) ++ "\""]},
                    {'Size', [format_value(KeyContent?LOKC.size)]},
                    {'StorageClass', [format_value(KeyContent?LOKC.storage_class)]},
                    owner_element(KeyContent?LOKC.owner)]}.
  
  %% @doc Assemble the xml for the set of grantees for an acl.
  -spec grants_xml([acl_grant()]) -> term().
  grants_xml(Grantees) ->
      grants_xml(Grantees, []).
  
  %% @doc Assemble the xml for the set of grantees for an acl.
  -spec grants_xml([acl_grant()], list()) -> list().
  grants_xml([], Acc) ->
      lists:flatten(Acc);
  grants_xml([HeadGrantee | RestGrantees], Acc) ->
      case HeadGrantee of
          {{GranteeName, GranteeId}, Perms} ->
              GranteeXml = [grant_xml(GranteeName, GranteeId, Perm) ||
                               Perm <- Perms];
          {Group, Perms} ->
              GranteeXml = [grant_xml(Group, Perm) ||
                               Perm <- Perms]
      end,
      grants_xml(RestGrantees, [GranteeXml | Acc]).
  
  %% @doc Assemble the xml for a group grantee for an acl.
  -spec grant_xml(atom(), acl_perm()) -> term().
  grant_xml(Group, Permission) ->
      {'Grant',
       [
        {'Grantee',
         [{'xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance"},
          {'xsi:type', "Group"}],
         [
          {'URI', [uri_for_group(Group)]}
         ]},
        {'Permission', [atom_to_list(Permission)]}
       ]}.
  
  %% @doc Assemble the xml for a single grantee for an acl.
  -spec grant_xml(string(), string(), acl_perm()) -> term().
  grant_xml(DisplayName, CanonicalId, Permission) ->
      {'Grant',
       [
        {'Grantee',
         [{'xmlns:xsi', "http://www.w3.org/2001/XMLSchema-instance"},
          {'xsi:type', "CanonicalUser"}],
         [
          {'ID', [CanonicalId]},
          {'DisplayName', [DisplayName]}
         ]},
        {'Permission', [atom_to_list(Permission)]}
       ]}.
  
  owner_element(#list_objects_owner_v1{id=Id, display_name=Name}) ->
      {'Owner', [{'ID', [format_value(Id)]},
                 {'DisplayName', [format_value(Name)]}]}.
  
  export_xml(XmlDoc) ->
      unicode:characters_to_binary(
        xmerl:export_simple(XmlDoc, xmerl_xml, [{prolog, ?XML_PROLOG}]), unicode, unicode).
  
  format_value(undefined) ->
      [];
  format_value(true) ->
      "true";
  format_value(false) ->
      "false";
  format_value(Val) when is_binary(Val) ->
      binary_to_list(Val);
  format_value(Val) when is_integer(Val) ->
  
negative.code: -include("list_objects.hrl").
  
  -ifdef(TEST).
  -include_lib("eunit/include/eunit.hrl").
  -endif.
  
  %% Public API
  -export([to_xml/1]).
  
  -define(XML_SCHEMA_INSTANCE, "http://www.w3.org/2001/XMLSchema-instance").
  
  -type attributes() :: [{atom(), string()}].
  -type external_node() :: {atom(), [string()]}.
  -type internal_node() :: {atom(), [internal_node() | external_node()]} |
                           {atom(), attributes(), [internal_node() | external_node()]}.
  
  %% ===================================================================
  %% Public API
  %% ===================================================================
  
  -spec to_xml(term()) -> binary().
  to_xml(undefined) ->
      [];
  to_xml([]) ->
      [];
  to_xml(?ACL{}=Acl) ->
      acl_to_xml(Acl);
  to_xml(#acl_v1{}=Acl) ->
      acl_to_xml(Acl);
  to_xml(?LORESP{}=ListObjsResp) ->
      list_objects_response_to_xml(ListObjsResp).
  
  