Adds an rdf value to a collection.

    Adds an rdf value to a collection. Does not require that the collection be
    open. NOTE: The caller is responsible for ensuring that the collection
    exists and is of the correct type.

    Args:
      collection_urn: The urn of the collection to add to.
      rdf_value: The rdf value to add to the collection. If this value is not
        GrrMessage, it will be wrapped into GrrMessage (later when collection is
        iterated, this value will still be returned wrapped in GrrMessage).
      timestamp: The timestamp (in microseconds) to store the rdf value at.
        Defaults to the current time.
      suffix: A 'fractional timestamp' suffix to reduce the chance of
        collisions. Defaults to a random number.
      mutation_pool: A MutationPool object to write to.

    Returns:
      The pair (timestamp, suffix) which identifies the value within the
      collection.

    Raises:
      ValueError: rdf_value has unexpected type.

def StaticAdd(cls,
                collection_urn,
                rdf_value,
                timestamp=None,
                suffix=None,
                mutation_pool=None):
    """Adds an rdf value to a collection.

    Adds an rdf value to a collection. Does not require that the collection be
    open. NOTE: The caller is responsible for ensuring that the collection
    exists and is of the correct type.

    Args:
      collection_urn: The urn of the collection to add to.
      rdf_value: The rdf value to add to the collection. If this value is not
        GrrMessage, it will be wrapped into GrrMessage (later when collection is
        iterated, this value will still be returned wrapped in GrrMessage).
      timestamp: The timestamp (in microseconds) to store the rdf value at.
        Defaults to the current time.
      suffix: A 'fractional timestamp' suffix to reduce the chance of
        collisions. Defaults to a random number.
      mutation_pool: A MutationPool object to write to.

    Returns:
      The pair (timestamp, suffix) which identifies the value within the
      collection.

    Raises:
      ValueError: rdf_value has unexpected type.

    """
    if rdf_value is None:
      raise ValueError("Can't add None to MultiTypeCollection")
    if mutation_pool is None:
      raise ValueError("Mutation pool can't be none.")

    if not isinstance(rdf_value, rdf_flows.GrrMessage):
      rdf_value = rdf_flows.GrrMessage(payload=rdf_value)

    value_type = rdf_value.args_rdf_name or rdf_flows.GrrMessage.__name__

    # In order to make this fast, we never actually generate the
    # subcollections, we just use them. This means that we cannot use
    # ListChildren to get all the items stored in this
    # MultiTypeCollection.
    subpath = collection_urn.Add(value_type)
    sequential_collection.GrrMessageCollection.StaticAdd(
        subpath,
        rdf_value,
        timestamp=timestamp,
        suffix=suffix,
        mutation_pool=mutation_pool)

    mutation_pool.CollectionAddStoredTypeIndex(collection_urn, value_type)