docs: def AddBlob(self, blob_hash, length, chunk_number):
      """Add another blob to this image using its hash."""
      if len(blob_hash.AsBytes()) != self._HASH_SIZE:
        raise ValueError("Hash '%s' doesn't have correct length (%d)." %
                         (blob_hash, self._HASH_SIZE))
  
      # If we're adding a new blob, we should increase the size. If we're just
      # updating an existing blob, the size should stay the same.
      # That is, if we read the index at the right offset and no hash is there, we
      # must not have seen this blob before, so we say we're adding a new one and
      # increase in size.
      if not self.ChunkExists(chunk_number):
        # We say that we've increased in size by the size of the blob,
        # but really we only store its hash in the AFF4SparseImage.
        self.size += length
        self._dirty = True
        # Keep track of the biggest chunk_number we've seen so far.
        if chunk_number > self.last_chunk:
          self.last_chunk = chunk_number
          self._dirty = True
  
      index_urn = self.urn.Add(self.CHUNK_ID_TEMPLATE % chunk_number)
      # TODO(amoser): This opens a subobject for each AddBlob call :/
      with aff4.FACTORY.Create(
          index_urn, aff4.AFF4MemoryStream, token=self.token) as fd:
        fd.write(blob_hash.AsBytes())
      if chunk_number in self.chunk_cache:
        self.chunk_cache.Pop(chunk_number)