/*
 * This file is part of the Score-P software (http://www.score-p.org)
 *
 * Copyright (c) 2009-2012,
 * RWTH Aachen University, Germany
 *
 * Copyright (c) 2009-2012,
 * Gesellschaft fuer numerische Simulation mbH Braunschweig, Germany
 *
 * Copyright (c) 2009-2012, 2014,
 * Technische Universitaet Dresden, Germany
 *
 * Copyright (c) 2009-2012,
 * University of Oregon, Eugene, USA
 *
 * Copyright (c) 2009-2012,
 * Forschungszentrum Juelich GmbH, Germany
 *
 * Copyright (c) 2009-2012,
 * German Research School for Simulation Sciences GmbH, Juelich/Aachen, Germany
 *
 * Copyright (c) 2009-2012,
 * Technische Universitaet Muenchen, Germany
 *
 * This software may be modified and distributed under the terms of
 * a BSD-style license.  See the COPYING file in the package base
 * directory for details.
 *
 */


/**
 *  @internal
 *
 *  @file
 *  @source     templates/OTF2_DefWriter_inc.tmpl.c
 *
 *  @brief      This is the lowest user-visible layer which provides write
 *              operations for the event data of a single location (i.e.,
 *              data from a single thread). Due file writing is engaged by
 *              the memory buffer module, the related callbacks for
 *              buffer-flushing must be set for the whole archive handle.
 */


OTF2_ErrorCode
OTF2_DefWriter_WriteMappingTable( OTF2_DefWriter*   writerHandle,
                                  OTF2_MappingType  mappingType,
                                  const OTF2_IdMap* idMap )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint8( mappingType );
    if ( !idMap )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid IdMap argument." );
    }
    record_data_length += otf2_buffer_size_id_map( idMap );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_MAPPING_TABLE );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint8( writerHandle->buffer, mappingType );
    OTF2_Buffer_WriteIdMap( writerHandle->buffer, idMap );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteClockOffset( OTF2_DefWriter* writerHandle,
                                 OTF2_TimeStamp  time,
                                 int64_t         offset,
                                 double          standardDeviation )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_timestamp( time );
    record_data_length += otf2_buffer_size_int64( offset );
    record_data_length += otf2_buffer_size_float64( standardDeviation );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_CLOCK_OFFSET );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint64Full( writerHandle->buffer, time );
    OTF2_Buffer_WriteInt64( writerHandle->buffer, offset );
    OTF2_Buffer_WriteDouble( writerHandle->buffer, standardDeviation );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteString( OTF2_DefWriter* writerHandle,
                            OTF2_StringRef  self,
                            const char*     string )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    if ( !string )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid string argument." );
    }
    record_data_length += otf2_buffer_size_string( string );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_STRING );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteString( writerHandle->buffer, string );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteAttribute( OTF2_DefWriter*   writerHandle,
                               OTF2_AttributeRef self,
                               OTF2_StringRef    name,
                               OTF2_StringRef    description,
                               OTF2_Type         type )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint8( type );
    record_data_length += otf2_buffer_size_uint32( description );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_ATTRIBUTE );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, type );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, description );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteSystemTreeNode( OTF2_DefWriter*        writerHandle,
                                    OTF2_SystemTreeNodeRef self,
                                    OTF2_StringRef         name,
                                    OTF2_StringRef         className,
                                    OTF2_SystemTreeNodeRef parent )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( className );
    record_data_length += otf2_buffer_size_uint32( parent );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_SYSTEM_TREE_NODE );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, className );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, parent );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteLocationGroup( OTF2_DefWriter*        writerHandle,
                                   OTF2_LocationGroupRef  self,
                                   OTF2_StringRef         name,
                                   OTF2_LocationGroupType locationGroupType,
                                   OTF2_SystemTreeNodeRef systemTreeParent,
                                   OTF2_LocationGroupRef  creatingLocationGroup )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint8( locationGroupType );
    record_data_length += otf2_buffer_size_uint32( systemTreeParent );
    record_data_length += otf2_buffer_size_uint32( creatingLocationGroup );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_LOCATION_GROUP );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, locationGroupType );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, systemTreeParent );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, creatingLocationGroup );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteLocation( OTF2_DefWriter*       writerHandle,
                              OTF2_LocationRef      self,
                              OTF2_StringRef        name,
                              OTF2_LocationType     locationType,
                              uint64_t              numberOfEvents,
                              OTF2_LocationGroupRef locationGroup )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint64( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint8( locationType );
    record_data_length += otf2_buffer_size_uint64( numberOfEvents );
    record_data_length += otf2_buffer_size_uint32( locationGroup );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_LOCATION );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint64( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, locationType );
    OTF2_Buffer_WriteUint64( writerHandle->buffer, numberOfEvents );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, locationGroup );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteRegion( OTF2_DefWriter* writerHandle,
                            OTF2_RegionRef  self,
                            OTF2_StringRef  name,
                            OTF2_StringRef  canonicalName,
                            OTF2_StringRef  description,
                            OTF2_RegionRole regionRole,
                            OTF2_Paradigm   paradigm,
                            OTF2_RegionFlag regionFlags,
                            OTF2_StringRef  sourceFile,
                            uint32_t        beginLineNumber,
                            uint32_t        endLineNumber )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /* Generate pre 1.1 record fields */
    OTF2_RegionType regionType;
    otf2_local_def_region_provide_pre_1_1( &regionType,
                                           name,
                                           canonicalName,
                                           description,
                                           regionRole,
                                           paradigm,
                                           regionFlags,
                                           sourceFile,
                                           beginLineNumber,
                                           endLineNumber );

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( description );
    record_data_length += otf2_buffer_size_uint8( regionType );
    record_data_length += otf2_buffer_size_uint32( sourceFile );
    record_data_length += otf2_buffer_size_uint32( beginLineNumber );
    record_data_length += otf2_buffer_size_uint32( endLineNumber );
    record_data_length += otf2_buffer_size_uint32( canonicalName );
    record_data_length += otf2_buffer_size_uint8( regionRole );
    record_data_length += otf2_buffer_size_uint8( paradigm );
    record_data_length += otf2_buffer_size_uint32( regionFlags );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_REGION );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, description );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, regionType );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, sourceFile );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, beginLineNumber );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, endLineNumber );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, canonicalName );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, regionRole );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, paradigm );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, regionFlags );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteCallsite( OTF2_DefWriter*  writerHandle,
                              OTF2_CallsiteRef self,
                              OTF2_StringRef   sourceFile,
                              uint32_t         lineNumber,
                              OTF2_RegionRef   enteredRegion,
                              OTF2_RegionRef   leftRegion )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( sourceFile );
    record_data_length += otf2_buffer_size_uint32( lineNumber );
    record_data_length += otf2_buffer_size_uint32( enteredRegion );
    record_data_length += otf2_buffer_size_uint32( leftRegion );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_CALLSITE );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, sourceFile );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, lineNumber );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, enteredRegion );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, leftRegion );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteCallpath( OTF2_DefWriter*  writerHandle,
                              OTF2_CallpathRef self,
                              OTF2_CallpathRef parent,
                              OTF2_RegionRef   region )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( parent );
    record_data_length += otf2_buffer_size_uint32( region );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_CALLPATH );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, parent );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, region );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteGroup( OTF2_DefWriter* writerHandle,
                           OTF2_GroupRef   self,
                           OTF2_StringRef  name,
                           OTF2_GroupType  groupType,
                           OTF2_Paradigm   paradigm,
                           OTF2_GroupFlag  groupFlags,
                           uint32_t        numberOfMembers,
                           const uint64_t* members )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /* Generate pre 1.2 record fields */
    OTF2_GroupTypePre12 groupTypePre12;
    otf2_local_def_group_provide_pre_1_2( &groupTypePre12,
                                          name,
                                          groupType,
                                          paradigm,
                                          groupFlags,
                                          numberOfMembers,
                                          members );

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint8( groupTypePre12 );
    record_data_length += otf2_buffer_size_uint32( numberOfMembers );
    if ( numberOfMembers > 0 && !members )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid members array argument." );
    }
    record_data_length += otf2_buffer_array_size_uint64( numberOfMembers, members );
    record_data_length += otf2_buffer_size_uint8( groupType );
    record_data_length += otf2_buffer_size_uint8( paradigm );
    record_data_length += otf2_buffer_size_uint32( groupFlags );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_GROUP );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, groupTypePre12 );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, numberOfMembers );
    for ( uint32_t numberOfMembers_i = 0;
          numberOfMembers_i < numberOfMembers;
          numberOfMembers_i++ )
    {
        OTF2_Buffer_WriteUint64( writerHandle->buffer,
                                 members[ numberOfMembers_i ] );
    }
    OTF2_Buffer_WriteUint8( writerHandle->buffer, groupType );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, paradigm );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, groupFlags );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteMetricMember( OTF2_DefWriter*      writerHandle,
                                  OTF2_MetricMemberRef self,
                                  OTF2_StringRef       name,
                                  OTF2_StringRef       description,
                                  OTF2_MetricType      metricType,
                                  OTF2_MetricMode      metricMode,
                                  OTF2_Type            valueType,
                                  OTF2_Base            base,
                                  int64_t              exponent,
                                  OTF2_StringRef       unit )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( description );
    record_data_length += otf2_buffer_size_uint8( metricType );
    record_data_length += otf2_buffer_size_uint8( metricMode );
    record_data_length += otf2_buffer_size_uint8( valueType );
    record_data_length += otf2_buffer_size_uint8( base );
    record_data_length += otf2_buffer_size_int64( exponent );
    record_data_length += otf2_buffer_size_uint32( unit );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_METRIC_MEMBER );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, description );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, metricType );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, metricMode );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, valueType );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, base );
    OTF2_Buffer_WriteInt64( writerHandle->buffer, exponent );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, unit );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteMetricClass( OTF2_DefWriter*             writerHandle,
                                 OTF2_MetricRef              self,
                                 uint8_t                     numberOfMetrics,
                                 const OTF2_MetricMemberRef* metricMembers,
                                 OTF2_MetricOccurrence       metricOccurrence,
                                 OTF2_RecorderKind           recorderKind )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint8( numberOfMetrics );
    if ( numberOfMetrics > 0 && !metricMembers )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid metricMembers array argument." );
    }
    record_data_length += otf2_buffer_array_size_uint32( numberOfMetrics, metricMembers );
    record_data_length += otf2_buffer_size_uint8( metricOccurrence );
    record_data_length += otf2_buffer_size_uint8( recorderKind );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_METRIC_CLASS );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, numberOfMetrics );
    for ( uint8_t numberOfMetrics_i = 0;
          numberOfMetrics_i < numberOfMetrics;
          numberOfMetrics_i++ )
    {
        OTF2_Buffer_WriteUint32( writerHandle->buffer,
                                 metricMembers[ numberOfMetrics_i ] );
    }
    OTF2_Buffer_WriteUint8( writerHandle->buffer, metricOccurrence );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, recorderKind );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteMetricInstance( OTF2_DefWriter*  writerHandle,
                                    OTF2_MetricRef   self,
                                    OTF2_MetricRef   metricClass,
                                    OTF2_LocationRef recorder,
                                    OTF2_MetricScope metricScope,
                                    uint64_t         scope )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( metricClass );
    record_data_length += otf2_buffer_size_uint64( recorder );
    record_data_length += otf2_buffer_size_uint8( metricScope );
    record_data_length += otf2_buffer_size_uint64( scope );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_METRIC_INSTANCE );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, metricClass );
    OTF2_Buffer_WriteUint64( writerHandle->buffer, recorder );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, metricScope );
    OTF2_Buffer_WriteUint64( writerHandle->buffer, scope );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteComm( OTF2_DefWriter* writerHandle,
                          OTF2_CommRef    self,
                          OTF2_StringRef  name,
                          OTF2_GroupRef   group,
                          OTF2_CommRef    parent,
                          OTF2_CommFlag   flags )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( group );
    record_data_length += otf2_buffer_size_uint32( parent );
    record_data_length += otf2_buffer_size_uint32( flags );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_COMM );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, group );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, parent );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, flags );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteParameter( OTF2_DefWriter*    writerHandle,
                               OTF2_ParameterRef  self,
                               OTF2_StringRef     name,
                               OTF2_ParameterType parameterType )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint8( parameterType );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_PARAMETER );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, parameterType );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteRmaWin( OTF2_DefWriter* writerHandle,
                            OTF2_RmaWinRef  self,
                            OTF2_StringRef  name,
                            OTF2_CommRef    comm,
                            OTF2_RmaWinFlag flags )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( comm );
    record_data_length += otf2_buffer_size_uint32( flags );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_RMA_WIN );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, comm );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, flags );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteMetricClassRecorder( OTF2_DefWriter*  writerHandle,
                                         OTF2_MetricRef   metric,
                                         OTF2_LocationRef recorder )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( metric );
    record_data_length += otf2_buffer_size_uint64( recorder );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_METRIC_CLASS_RECORDER );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, metric );
    OTF2_Buffer_WriteUint64( writerHandle->buffer, recorder );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteSystemTreeNodeProperty( OTF2_DefWriter*        writerHandle,
                                            OTF2_SystemTreeNodeRef systemTreeNode,
                                            OTF2_StringRef         name,
                                            OTF2_Type              type,
                                            OTF2_AttributeValue    value )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /* Generate pre 2.0 record fields */
    OTF2_StringRef stringValue;
    otf2_local_def_system_tree_node_property_provide_pre_2_0( &stringValue,
                                                              name,
                                                              type,
                                                              value );

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( systemTreeNode );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( stringValue );
    record_data_length += otf2_buffer_size_uint8( type );
    record_data_length += otf2_buffer_size_attribute_value( value );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_SYSTEM_TREE_NODE_PROPERTY );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, systemTreeNode );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, stringValue );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, type );
    OTF2_Buffer_WriteAttributeValue( writerHandle->buffer, value );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteSystemTreeNodeDomain( OTF2_DefWriter*        writerHandle,
                                          OTF2_SystemTreeNodeRef systemTreeNode,
                                          OTF2_SystemTreeDomain  systemTreeDomain )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( systemTreeNode );
    record_data_length += otf2_buffer_size_uint8( systemTreeDomain );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_SYSTEM_TREE_NODE_DOMAIN );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, systemTreeNode );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, systemTreeDomain );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteLocationGroupProperty( OTF2_DefWriter*       writerHandle,
                                           OTF2_LocationGroupRef locationGroup,
                                           OTF2_StringRef        name,
                                           OTF2_Type             type,
                                           OTF2_AttributeValue   value )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /* Generate pre 2.0 record fields */
    OTF2_StringRef stringValue;
    otf2_local_def_location_group_property_provide_pre_2_0( &stringValue,
                                                            name,
                                                            type,
                                                            value );

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( locationGroup );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( stringValue );
    record_data_length += otf2_buffer_size_uint8( type );
    record_data_length += otf2_buffer_size_attribute_value( value );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_LOCATION_GROUP_PROPERTY );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, locationGroup );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, stringValue );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, type );
    OTF2_Buffer_WriteAttributeValue( writerHandle->buffer, value );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteLocationProperty( OTF2_DefWriter*     writerHandle,
                                      OTF2_LocationRef    location,
                                      OTF2_StringRef      name,
                                      OTF2_Type           type,
                                      OTF2_AttributeValue value )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /* Generate pre 2.0 record fields */
    OTF2_StringRef stringValue;
    otf2_local_def_location_property_provide_pre_2_0( &stringValue,
                                                      name,
                                                      type,
                                                      value );

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint64( location );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( stringValue );
    record_data_length += otf2_buffer_size_uint8( type );
    record_data_length += otf2_buffer_size_attribute_value( value );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_LOCATION_PROPERTY );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint64( writerHandle->buffer, location );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, stringValue );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, type );
    OTF2_Buffer_WriteAttributeValue( writerHandle->buffer, value );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteCartDimension( OTF2_DefWriter*       writerHandle,
                                   OTF2_CartDimensionRef self,
                                   OTF2_StringRef        name,
                                   uint32_t              size,
                                   OTF2_CartPeriodicity  cartPeriodicity )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( size );
    record_data_length += otf2_buffer_size_uint8( cartPeriodicity );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_CART_DIMENSION );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, size );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, cartPeriodicity );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteCartTopology( OTF2_DefWriter*              writerHandle,
                                  OTF2_CartTopologyRef         self,
                                  OTF2_StringRef               name,
                                  OTF2_CommRef                 communicator,
                                  uint8_t                      numberOfDimensions,
                                  const OTF2_CartDimensionRef* cartDimensions )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( communicator );
    record_data_length += otf2_buffer_size_uint8( numberOfDimensions );
    if ( numberOfDimensions > 0 && !cartDimensions )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid cartDimensions array argument." );
    }
    record_data_length += otf2_buffer_array_size_uint32( numberOfDimensions, cartDimensions );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_CART_TOPOLOGY );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, communicator );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, numberOfDimensions );
    for ( uint8_t numberOfDimensions_i = 0;
          numberOfDimensions_i < numberOfDimensions;
          numberOfDimensions_i++ )
    {
        OTF2_Buffer_WriteUint32( writerHandle->buffer,
                                 cartDimensions[ numberOfDimensions_i ] );
    }

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteCartCoordinate( OTF2_DefWriter*      writerHandle,
                                    OTF2_CartTopologyRef cartTopology,
                                    uint32_t             rank,
                                    uint8_t              numberOfDimensions,
                                    const uint32_t*      coordinates )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( cartTopology );
    record_data_length += otf2_buffer_size_uint32( rank );
    record_data_length += otf2_buffer_size_uint8( numberOfDimensions );
    if ( numberOfDimensions > 0 && !coordinates )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid coordinates array argument." );
    }
    record_data_length += otf2_buffer_array_size_uint32( numberOfDimensions, coordinates );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_CART_COORDINATE );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, cartTopology );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, rank );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, numberOfDimensions );
    for ( uint8_t numberOfDimensions_i = 0;
          numberOfDimensions_i < numberOfDimensions;
          numberOfDimensions_i++ )
    {
        OTF2_Buffer_WriteUint32( writerHandle->buffer,
                                 coordinates[ numberOfDimensions_i ] );
    }

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteSourceCodeLocation( OTF2_DefWriter*            writerHandle,
                                        OTF2_SourceCodeLocationRef self,
                                        OTF2_StringRef             file,
                                        uint32_t                   lineNumber )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( file );
    record_data_length += otf2_buffer_size_uint32( lineNumber );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_SOURCE_CODE_LOCATION );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, file );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, lineNumber );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteCallingContext( OTF2_DefWriter*            writerHandle,
                                    OTF2_CallingContextRef     self,
                                    OTF2_RegionRef             region,
                                    OTF2_SourceCodeLocationRef sourceCodeLocation,
                                    OTF2_CallingContextRef     parent )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( region );
    record_data_length += otf2_buffer_size_uint32( sourceCodeLocation );
    record_data_length += otf2_buffer_size_uint32( parent );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_CALLING_CONTEXT );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, region );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, sourceCodeLocation );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, parent );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteCallingContextProperty( OTF2_DefWriter*        writerHandle,
                                            OTF2_CallingContextRef callingContext,
                                            OTF2_StringRef         name,
                                            OTF2_Type              type,
                                            OTF2_AttributeValue    value )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( callingContext );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint8( type );
    record_data_length += otf2_buffer_size_attribute_value( value );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_CALLING_CONTEXT_PROPERTY );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, callingContext );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, type );
    OTF2_Buffer_WriteAttributeValue( writerHandle->buffer, value );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteInterruptGenerator( OTF2_DefWriter*             writerHandle,
                                        OTF2_InterruptGeneratorRef  self,
                                        OTF2_StringRef              name,
                                        OTF2_InterruptGeneratorMode interruptGeneratorMode,
                                        OTF2_Base                   base,
                                        int64_t                     exponent,
                                        uint64_t                    period )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint8( interruptGeneratorMode );
    record_data_length += otf2_buffer_size_uint8( base );
    record_data_length += otf2_buffer_size_int64( exponent );
    record_data_length += otf2_buffer_size_uint64( period );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_INTERRUPT_GENERATOR );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, interruptGeneratorMode );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, base );
    OTF2_Buffer_WriteInt64( writerHandle->buffer, exponent );
    OTF2_Buffer_WriteUint64( writerHandle->buffer, period );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteIoFileProperty( OTF2_DefWriter*     writerHandle,
                                    OTF2_IoFileRef      ioFile,
                                    OTF2_StringRef      name,
                                    OTF2_Type           type,
                                    OTF2_AttributeValue value )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( ioFile );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint8( type );
    record_data_length += otf2_buffer_size_attribute_value( value );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_IO_FILE_PROPERTY );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, ioFile );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, type );
    OTF2_Buffer_WriteAttributeValue( writerHandle->buffer, value );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteIoRegularFile( OTF2_DefWriter*        writerHandle,
                                   OTF2_IoFileRef         self,
                                   OTF2_StringRef         name,
                                   OTF2_SystemTreeNodeRef scope )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( scope );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_IO_REGULAR_FILE );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, scope );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteIoDirectory( OTF2_DefWriter*        writerHandle,
                                 OTF2_IoFileRef         self,
                                 OTF2_StringRef         name,
                                 OTF2_SystemTreeNodeRef scope )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( scope );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_IO_DIRECTORY );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, scope );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteIoHandle( OTF2_DefWriter*    writerHandle,
                              OTF2_IoHandleRef   self,
                              OTF2_StringRef     name,
                              OTF2_IoFileRef     file,
                              OTF2_IoParadigmRef ioParadigm,
                              OTF2_IoHandleFlag  ioHandleFlags,
                              OTF2_CommRef       comm,
                              OTF2_IoHandleRef   parent )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( file );
    record_data_length += otf2_buffer_size_uint8( ioParadigm );
    record_data_length += otf2_buffer_size_uint32( ioHandleFlags );
    record_data_length += otf2_buffer_size_uint32( comm );
    record_data_length += otf2_buffer_size_uint32( parent );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_IO_HANDLE );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, file );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, ioParadigm );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, ioHandleFlags );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, comm );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, parent );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteIoPreCreatedHandleState( OTF2_DefWriter*   writerHandle,
                                             OTF2_IoHandleRef  ioHandle,
                                             OTF2_IoAccessMode mode,
                                             OTF2_IoStatusFlag statusFlags )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( ioHandle );
    record_data_length += otf2_buffer_size_uint8( mode );
    record_data_length += otf2_buffer_size_uint32( statusFlags );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_IO_PRE_CREATED_HANDLE_STATE );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, ioHandle );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, mode );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, statusFlags );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteCallpathParameter( OTF2_DefWriter*     writerHandle,
                                       OTF2_CallpathRef    callpath,
                                       OTF2_ParameterRef   parameter,
                                       OTF2_Type           type,
                                       OTF2_AttributeValue value )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( callpath );
    record_data_length += otf2_buffer_size_uint32( parameter );
    record_data_length += otf2_buffer_size_uint8( type );
    record_data_length += otf2_buffer_size_attribute_value( value );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_CALLPATH_PARAMETER );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, callpath );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, parameter );
    OTF2_Buffer_WriteUint8( writerHandle->buffer, type );
    OTF2_Buffer_WriteAttributeValue( writerHandle->buffer, value );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}


OTF2_ErrorCode
OTF2_DefWriter_WriteInterComm( OTF2_DefWriter* writerHandle,
                               OTF2_CommRef    self,
                               OTF2_StringRef  name,
                               OTF2_GroupRef   groupA,
                               OTF2_GroupRef   groupB,
                               OTF2_CommRef    commonCommunicator,
                               OTF2_CommFlag   flags )
{
    if ( !writerHandle )
    {
        return UTILS_ERROR( OTF2_ERROR_INVALID_ARGUMENT,
                            "Invalid writerHandle argument." );
    }

    OTF2_ErrorCode ret;

    /*
     * Maximum memory usage of pure record data (excluding type ID
     * and record length information).
     */
    uint64_t record_data_length = 0;
    /*
     * Maximum record length is the record id byte, plus the individual sizes of the
     * attributes.
     */
    uint64_t record_length = 1;

    record_data_length += otf2_buffer_size_uint32( self );
    record_data_length += otf2_buffer_size_uint32( name );
    record_data_length += otf2_buffer_size_uint32( groupA );
    record_data_length += otf2_buffer_size_uint32( groupB );
    record_data_length += otf2_buffer_size_uint32( commonCommunicator );
    record_data_length += otf2_buffer_size_uint32( flags );
    /* Finalize the upper bound of the record. */
    record_length += record_data_length;

    /*
     * Additional byte to store real record length. Due to on-line compression
     * real record length can differ from maximum record length.
     */
    record_length += 1;
    if ( record_data_length >= UINT8_MAX )
    {
        record_length += 8;
    }

    ret = OTF2_Buffer_WriteMemoryRequest( writerHandle->buffer, record_length );
    if ( OTF2_SUCCESS != ret )
    {
        return ret;
    }

    OTF2_Buffer_WriteUint8( writerHandle->buffer, OTF2_LOCAL_DEF_INTER_COMM );

    /* Write initial record length */
    OTF2_Buffer_WriteInitialRecordLength( writerHandle->buffer, record_data_length );

    OTF2_Buffer_WriteUint32( writerHandle->buffer, self );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, name );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, groupA );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, groupB );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, commonCommunicator );
    OTF2_Buffer_WriteUint32( writerHandle->buffer, flags );

    /* Write real record length */
    return OTF2_Buffer_WriteFinalRecordLength( writerHandle->buffer, record_data_length );
}
