        BoatLog(BOAT_LOG_VERBOSE, "List descriptors of RLP Object MUST be available.");
        return NULL;
    }

    rlp_list_descriptors_ptr = rlp_object_ptr->object_list.list_descriptors_ptr;

    if( descriptor_index >= rlp_list_descriptors_ptr->descriptor_num )
    {
        if( rlp_list_descriptors_ptr->descriptor_num == 0 )
        {
            BoatLog(BOAT_LOG_VERBOSE, "Descriptor list of the RLP object is empty.");
        }
        else
        {
            BoatLog(BOAT_LOG_VERBOSE, "Descriptor index %u is out of range: [0, %u].", descriptor_index, rlp_list_descriptors_ptr->descriptor_num - 1);
        }
        
        return NULL;
    }
    
    
    return rlp_list_descriptors_ptr->rlp_object_ptr[descriptor_index];
}


/******************************************************************************
@brief Delete an RLP object and all its children

Function: RlpRecursiveDeleteObject()

    This function deletes an RlpObject and all its children RlpObject (if it's
    of LIST and there should be some children).

    NOTE: The caller takes care of the memory used by the struct RlpObject.


@see RlpRecursiveDeleteEncodedStream()

@return
    This function doesn't return anything.


@param[in] rlp_object_ptr
    The parent RlpObject to delete.

*******************************************************************************/
void RlpRecursiveDeleteObject(RlpObject *rlp_object_ptr)
{
    RlpListDescriptors *rlp_list_descriptors_ptr;
    BUINT32 descriptor_index;
    
    if( rlp_object_ptr == NULL )
    {
        return;
    }

    if( rlp_object_ptr->object_type!= RLP_OBJECT_TYPE_LIST )
    {
        return;
    }


    if( rlp_object_ptr->object_list.rlp_encoded_stream_object.stream_ptr!= NULL )
    {
        BoatFree(rlp_object_ptr->object_list.rlp_encoded_stream_object.stream_ptr);
        rlp_object_ptr->object_list.rlp_encoded_stream_object.stream_ptr = NULL;
        rlp_object_ptr->object_list.rlp_encoded_stream_object.stream_len = 0;
    }
    
    rlp_list_descriptors_ptr = rlp_object_ptr->object_list.list_descriptors_ptr;

    if( rlp_list_descriptors_ptr == NULL )
    {
        return;
    }

    
    for( descriptor_index = 0; 
         descriptor_index < rlp_list_descriptors_ptr->descriptor_num;
         descriptor_index++ )
    {
        RlpRecursiveDeleteObject(rlp_list_descriptors_ptr->rlp_object_ptr[descriptor_index]);
    }

    BoatFree(rlp_list_descriptors_ptr);
    rlp_object_ptr->object_list.list_descriptors_ptr = NULL;
    
    return;
}


/******************************************************************************
@brief Delete encoded RLP stream in an RLP object and all its children

Function: RlpRecursiveDeleteEncodedStream()

    This function deletes encoded RLP stream in an RlpObject and all its children
    RlpObject (if it's of LIST and there should be some children).

    This function only deletes the encoded RLP stream while leaves the RlpObject's
    descriptor as is. Thus the tree-ed structure of its children is not affected.

    This function is used in an RLP re-encoding operation. It cleans all previously
    encoded RLP stream and prepares for a re-encoding.


@see RlpRecursiveDeleteObject()

@return
    This function doesn't return anything.


@param[in] rlp_object_ptr
    The parent RlpObject which contains the encoded RLP stream to delete.

*******************************************************************************/
void RlpRecursiveDeleteEncodedStream(RlpObject *rlp_object_ptr)
{
    RlpListDescriptors *rlp_list_descriptors_ptr;
    BUINT32 descriptor_index;
    
    if( rlp_object_ptr == NULL )
    {
        return;
    }

    if( rlp_object_ptr->object_type!= RLP_OBJECT_TYPE_LIST )
    {
        return;
    }


    if( rlp_object_ptr->object_list.rlp_encoded_stream_object.stream_ptr!= NULL )
    {
        BoatFree(rlp_object_ptr->object_list.rlp_encoded_stream_object.stream_ptr);
        rlp_object_ptr->object_list.rlp_encoded_stream_object.stream_ptr = NULL;
        rlp_object_ptr->object_list.rlp_encoded_stream_object.stream_len = 0;
    }
    
    rlp_list_descriptors_ptr = rlp_object_ptr->object_list.list_descriptors_ptr;

    if( rlp_list_descriptors_ptr == NULL )
    {
        return;
    }

    
    for( descriptor_index = 0; 
         descriptor_index < rlp_list_descriptors_ptr->descriptor_num;
         descriptor_index++ )
    {
        RlpRecursiveDeleteEncodedStream(rlp_list_descriptors_ptr->rlp_object_ptr[descriptor_index]);
    }

    
    return;
}


/******************************************************************************
@brief Calculate the encoded RLP stream size in an RLP object and all its children

Function: RlpRecursiveCalcEncodingSize()

    This function calculates the size of the encoded RLP stream in an RlpObject
    and all its children RlpObject (if it's of LIST and there should be some children).

    The size returned is the total size of the stream that would be encoded by
    RlpEncode(). It's used to allocate memory before executing an RLP encoding
    operation.

    NOTE: This function doesn't actually encode the stream and doesn't allocate
    any dynamic memory.
    

@see RlpEncode()

@return
    This function returns the size of the encoded stream.


@param[in] rlp_object_ptr
    The RlpObject to be encode.

@param[out] rlp_head_size_ptr
    The RLP head size within the encoded stream.
    
*******************************************************************************/
BUINT32 RlpRecursiveCalcEncodingSize(RlpObject *rlp_object_ptr, BOAT_OUT BUINT8 *rlp_head_size_ptr)
{
    BUINT32 encoded_stream_len;
    BUINT32 sub_field_encoded_stream_len;
    BUINT32 sum_of_sub_field_len;
    BUINT8 trimmed_field_len[8];
    BUINT8 trimmed_sizeof_field_len;
    BUINT8 *field_ptr;
    BUINT32 field_len;

    RlpListDescriptors *rlp_list_descriptors_ptr;
    BUINT32 descriptor_index;
    
    if( rlp_object_ptr == NULL )
    {
        BoatLog(BOAT_LOG_VERBOSE, "Argument cannot be NULL.");
        return RLP_STREAM_LEN_UNKNOWN;
    }
    
    if( rlp_object_ptr->object_type == RLP_OBJECT_TYPE_STRING )
    {
        field_ptr = rlp_object_ptr->object_string.string_ptr;
        field_len = rlp_object_ptr->object_string.string_len;
        
        if(   field_ptr == NULL && field_len!= 0 )
        {
            BoatLog(BOAT_LOG_VERBOSE, "String cannot be null unless its length is 0.");
            return RLP_STREAM_LEN_UNKNOWN;
        }

        // Case 1. encoded stream = <field>, if field_len is 1    
        if( field_len == 1 && field_ptr[0] <= 0x7f)
        {
            if( rlp_head_size_ptr!= NULL ) *rlp_head_size_ptr = 0;
            encoded_stream_len = 1;
        }
        