anchor.diff:      let getUtf8String   = System.Text.Encoding.UTF8.GetString
       let getAsciiString  = System.Text.Encoding.ASCII.GetString
   
  -let createTypedContent (ownerType : ProvidedTypeDefinition) client (bucket : Amazon.S3.Model.S3Bucket) (s3Object : Amazon.S3.Model.S3Object) = 
  -    let contents     = getContent client bucket s3Object
  -    let typedContent = runtimeType<string> "Content"
  -    typedContent.HideObjectMethods <- true
  +/// Create a nested type to represent the content of a S3 object
  +let createTypedContent (ownerType : ProvidedTypeDefinition) client (bucket : Amazon.S3.Model.S3Bucket) version (s3Object : Amazon.S3.Model.S3Object) = 
  +    let contents     = getContent client bucket version s3Object
  +    let typedContent = runtimeType<obj> "Content"
   
       typedContent.AddMemberDelayed(fun () -> ProvidedProperty("UTF8", typeof<string>, IsStatic = true, GetterCode = (fun args -> <@@ RuntimeHelper.getUtf8String(contents) @@>)))
       typedContent.AddMemberDelayed(fun () -> ProvidedProperty("ASCII", typeof<string>, IsStatic = true, GetterCode = (fun args -> <@@ RuntimeHelper.getAsciiString(contents) @@>)))
       typedContent.AddMember(ProvidedProperty("Raw", typeof<byte[]>, IsStatic = true, GetterCode = (fun args -> <@@ contents @@>)))
       typedContent
   
  -let createTypedS3Object (ownerType : ProvidedTypeDefinition) client (bucket : Amazon.S3.Model.S3Bucket) (s3Object : Amazon.S3.Model.S3Object) = 
  -    let typedS3Object = runtimeType<obj> s3Object.Key
  +/// Create a nested type to represent a non-versioned S3 object
  +let createTypedS3Object (ownerType : ProvidedTypeDefinition) client (bucket : Amazon.S3.Model.S3Bucket) typeName (s3Object : Amazon.S3.Model.S3Object) = 
  +    let typeName = 
  +        match typeName, s3Object with 
  +        | Some name, _ -> name 
  +        | _, (:? Amazon.S3.Model.S3ObjectVersion as s3ObjectVersion)
  +            -> if s3ObjectVersion.IsLatest 
  +               then sprintf "%s (Latest, %A)" s3ObjectVersion.VersionId s3ObjectVersion.LastModified
  +               else sprintf "%s (%A)" s3ObjectVersion.VersionId s3ObjectVersion.LastModified
  +        | _ -> s3Object.Key
  +    let typedS3Object = runtimeType<obj> typeName
       typedS3Object.AddXmlDocDelayed(fun () -> sprintf "A strongly typed interface to S3 object %s which is %d bytes in size" s3Object.Key s3Object.Size)
  -    typedS3Object.HideObjectMethods <- true
       
       let key, etag, size, lastModified, ownerId, ownerName = 
           s3Object.Key, s3Object.ETag, s3Object.Size, s3Object.LastModified.ToString(), s3Object.Owner.Id, s3Object.Owner.DisplayName
  
positive.code: // #region Helpers
  
  let erasedType<'T> assemblyName rootNamespace typeName = 
      ProvidedTypeDefinition(assemblyName, rootNamespace, typeName, Some(typeof<'T>))
  
  let runtimeType<'T> typeName = ProvidedTypeDefinition(typeName, Some typeof<'T>)
  
  // #endregion
  
  let thisAssembly = Assembly.GetExecutingAssembly()
  let rootNamespace = "S3Provider"
  
  let getBuckets (client : Amazon.S3.IAmazonS3) =
      let response = client.ListBuckets()
      response.Buckets
  
  let getObjects (client : Amazon.S3.IAmazonS3) (bucket : Amazon.S3.Model.S3Bucket) =
      let rec loop marker = seq {
          let req = new Amazon.S3.Model.ListObjectsRequest()
  
negative.code:             typedS3Account
  
      typedS3.DefineStaticParameters(parameters = typeParams, instantiationFunction = initFunction)
      typedS3
  
  [<TypeProvider>]
  