std::size_t ReceivedMessageArgument::ComputeArrayItemCount() const
{
    // it is only valid to call ComputeArrayItemCount when the argument is the array start marker
    if( !IsArrayBegin() )
        throw WrongArgumentTypeException();

    std::size_t result = 0;
    unsigned int level = 0;
    const char *typeTag = typeTagPtr_ + 1;

    // iterate through all type tags. note that ReceivedMessage::Init
    // has already checked that the message is well formed.
    while( *typeTag ) {
        switch( *typeTag++ ) {
            case ARRAY_BEGIN_TYPE_TAG:
                level += 1;
                break;

            case ARRAY_END_TYPE_TAG:
                if(level == 0)
                    return result;
                level -= 1;
                break;

            default:
                if( level == 0 ) // only count items at level 0
                    ++result;
        }
    }

    return result;
}
void ReceivedMessageArgument::AsBlob( const void*& data, unsigned long& size ) const
{
    if( !typeTag_ )
        throw MissingArgumentException();
	else if( *typeTag_ == BLOB_TYPE_TAG )
		AsBlobUnchecked( data, size );
	else
		throw WrongArgumentTypeException();
}
const char* ReceivedMessageArgument::AsSymbol() const
{
    if( !typeTag_ )
        throw MissingArgumentException();
	else if( *typeTag_ == SYMBOL_TYPE_TAG )
		return argument_;
	else
		throw WrongArgumentTypeException();
}
double ReceivedMessageArgument::AsDouble() const
{
    if( !typeTag_ )
        throw MissingArgumentException();
	else if( *typeTag_ == DOUBLE_TYPE_TAG )
		return AsDoubleUnchecked();
	else
		throw WrongArgumentTypeException();
}
uint64 ReceivedMessageArgument::AsTimeTag() const
{
    if( !typeTag_ )
        throw MissingArgumentException();
	else if( *typeTag_ == TIME_TAG_TYPE_TAG )
		return AsTimeTagUnchecked();
	else
		throw WrongArgumentTypeException();
}
uint32 ReceivedMessageArgument::AsMidiMessage() const
{
    if( !typeTag_ )
        throw MissingArgumentException();
	else if( *typeTag_ == MIDI_MESSAGE_TYPE_TAG )
		return AsMidiMessageUnchecked();
	else
		throw WrongArgumentTypeException();
}
uint32 ReceivedMessageArgument::AsRgbaColor() const
{
    if( !typeTag_ )
        throw MissingArgumentException();
	else if( *typeTag_ == RGBA_COLOR_TYPE_TAG )
		return AsRgbaColorUnchecked();
	else
		throw WrongArgumentTypeException();
}
char ReceivedMessageArgument::AsChar() const
{
    if( !typeTag_ )
        throw MissingArgumentException();
	else if( *typeTag_ == CHAR_TYPE_TAG )
		return AsCharUnchecked();
	else
		throw WrongArgumentTypeException();
}
float ReceivedMessageArgument::AsFloat() const
{
    if( !typeTag_ )
        throw MissingArgumentException();
	else if( *typeTag_ == FLOAT_TYPE_TAG )
		return AsFloatUnchecked();
	else
		throw WrongArgumentTypeException();
}
int32 ReceivedMessageArgument::AsInt32() const
{
    if( !typeTag_ )
        throw MissingArgumentException();
	else if( *typeTag_ == INT32_TYPE_TAG )
		return AsInt32Unchecked();
	else
		throw WrongArgumentTypeException();
}
void ReceivedMessageArgument::AsBlob( const void*& data, osc_bundle_element_size_t& size ) const
{
    if( !typeTagPtr_ )
        throw MissingArgumentException();
	else if( *typeTagPtr_ == BLOB_TYPE_TAG )
		AsBlobUnchecked( data, size );
	else
		throw WrongArgumentTypeException();
}
const char* ReceivedMessageArgument::AsString() const
{
    if( !typeTagPtr_ )
        throw MissingArgumentException();
	else if( *typeTagPtr_ == STRING_TYPE_TAG )
		return argumentPtr_;
	else
		throw WrongArgumentTypeException();
}
int64 ReceivedMessageArgument::AsInt64() const
{
    if( !typeTagPtr_ )
        throw MissingArgumentException();
	else if( *typeTagPtr_ == INT64_TYPE_TAG )
		return AsInt64Unchecked();
	else
		throw WrongArgumentTypeException();
}
bool ReceivedMessageArgument::AsBool() const
{
    if( !typeTag_ )
        throw MissingArgumentException();
	else if( *typeTag_ == TRUE_TYPE_TAG )
		return true;
	else if( *typeTag_ == FALSE_TYPE_TAG )
		return false;
	else
		throw WrongArgumentTypeException();
}
            /**
                \brief Validates the arguments

                This method checks if the arguments are correct. It first
                checks if the sizes match, otherwise throws an WrongNumberOfArgumentsException.
                Then it iterates over all arguments and checks if the types are correct.
                If this is not the case it throws a WrongArgumentTypeException.

                \throws WrongNumberOfArgumentsException
                \throws WrongArgumentTypeException
             */
            void ValidateArguments() const {
                // If sizes do not match return false
                if (ArgumentDictionary::Instance()->IsRepeatedArgument(name)) {
                    if (arguments.size() < ArgumentDictionary::Instance()->Size(name)) {
                        throw WrongNumberOfArgumentsException();
                    }
                } else {
                    if (arguments.size() != ArgumentDictionary::Instance()->Size(name)) {
                        throw WrongNumberOfArgumentsException();
                    }
                }

                for (int i=0; i<arguments.size(); i++) {
                    if (!ArgumentDictionary::Instance()->IsA(name, i, arguments[i]->GetType())) {
                        throw WrongArgumentTypeException(
                                ArgumentDictionary::Instance()->TypeToString(ArgumentDictionary::Instance()->Type(name, i)),
                                ArgumentDictionary::Instance()->TypeToString(arguments[i]->GetType())
                        );
                    }
                }
            }