anchor.diff:      typedS3Object.AddMember(ProvidedProperty("LastModified", typeof<DateTime>, IsStatic = true, GetterCode = (fun args -> <@@ RuntimeHelper.getDateTime(lastModified) @@>)))
       typedS3Object.AddMember(ProvidedProperty("OwnerId", typeof<string>, IsStatic = true, GetterCode = (fun args -> <@@ ownerId @@>)))
       typedS3Object.AddMember(ProvidedProperty("OwnerName", typeof<string>, IsStatic = true, GetterCode = (fun args -> <@@ ownerName @@>)))
  -
  -    typedS3Object.AddMemberDelayed(fun () -> createTypedContent typedS3Object client bucket s3Object)
  +    typedS3Object.AddMemberDelayed(fun () -> createTypedContent typedS3Object client bucket None s3Object)
   
       typedS3Object
   
  +/// Create a nested type to represent a versioned S3 object
  +let createTypedVersionedS3Object (ownerType : ProvidedTypeDefinition) client (bucket : Amazon.S3.Model.S3Bucket) (s3Object : Amazon.S3.Model.S3Object) =
  +    let typedS3Object = runtimeType<obj> s3Object.Key
  +    typedS3Object.AddXmlDocDelayed(fun () -> sprintf "A strongly typed interface to a versioned S3 object %s" s3Object.Key)
  +
  +    // nested type to represent the latest version of the object
  +    typedS3Object.AddMember(createTypedS3Object ownerType client bucket (Some "Latest") s3Object)
  +
  +    // then a nested type called Versions to represent all the versions of the object
  +    let typedS3ObjectVersions = runtimeType<obj> "Versions"
  +    typedS3Object.AddMember(typedS3ObjectVersions)
  +    typedS3ObjectVersions.AddMembersDelayed(fun () ->
  +        let versions = getObjectVersions client bucket s3Object
  +        versions |> Seq.map (createTypedS3Object ownerType client bucket None) |> Seq.toList)
  +
  +    typedS3Object
  +
  +/// Created a nested type to represent a S3 bucket
   let createTypedBucket (ownerType : ProvidedTypeDefinition) client (bucket : Amazon.S3.Model.S3Bucket) =
       let typedBucket = runtimeType<obj> bucket.BucketName
  -    typedBucket.AddXmlDocDelayed(fun () -> sprintf "A strongly typed interface to S3 bucket %s which was created on %A" bucket.BucketName bucket.CreationDate)
  -    typedBucket.HideObjectMethods <- true
  +    let isVersioned = isBucketVersioned client bucket
  +    typedBucket.AddXmlDocDelayed(fun () -> sprintf "A strongly typed interface to S3 bucket %s which was created on %A, and %s versioned" 
  +                                                   bucket.BucketName bucket.CreationDate (if isVersioned then "is" else "is not"))
   
       typedBucket.AddMember(ProvidedProperty("CreationDate", typeof<DateTime>, IsStatic = true, GetterCode = (fun args -> <@@ bucket.CreationDate @@>)))
  -    typedBucket.AddMembersDelayed(fun () -> getObjects client bucket |> Seq.map (createTypedS3Object typedBucket client bucket) |> Seq.toList)
  +
  +    let createTypedS3Object = 
  +        match isVersioned with
  +        | false -> createTypedS3Object typedBucket client bucket None
  +        | true  -> createTypedVersionedS3Object typedBucket client bucket
  +
  +    typedBucket.AddMembersDelayed(fun () -> getObjects client bucket |> Seq.map createTypedS3Object |> Seq.toList)
   
       typedBucket
   
  
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>]
  