function compareValues( actual, expected ) {
	var expectedValue;
	var actualString;
	var actualValue;
	var parts;
	var msg1;
	var msg2;
	var a;
	var b;

	if ( contains( expected, '||' ) ) {
		parts = expected.split( '||' );
		a = trim( parts[ 0 ] );
		b = trim( parts[ 1 ] );
		msg1 = compareValues( actual, a );
		msg2 = compareValues( actual, b );
		if ( msg1 && msg2 ) {
			return 'Actual value is `'+actual+'`, but expected `'+a+'` or `'+b+'`';
		}
		return null;
	}
	if ( isEmptyString( expected ) ) {
		return 'Return annotation is empty';
	}
	if ( contains( expected, 'e.g.' ) ) {
		// Early return since we cannot compare actual value to return annotation value:
		return null;
	}
	if ( startsWith( expected, '<' ) && endsWith( expected, '>' ) ) {
		if ( !checkForPlaceholders( actual, expected ) ) {
			return 'Expected a '+expected+', but received: `'+actual+'`';
		}
		if (
			contains( BOXED_TYPE_ANNOTATIONS, expected ) &&
			isPrimitive( actual )
		) {
			return 'Expected a '+expected+', but received an unboxed primitive: `'+actual+'`';
		}
		if (
			contains( PRIMITIVE_TYPE_ANNOTATIONS, expected ) &&
			isBoxedPrimitive( actual )
		) {
			return 'Expected a '+expected+', but received a boxed primitive: `'+actual+'`';
		}
		return null;
	}
	if ( isPrimitive( actual ) ) {
		if ( isString( actual) ) {
			if (
				!RE_UNESCAPED_QUOTE.test( actual ) &&
				( !startsWith( expected, '\'' ) || !endsWith( expected, '\'' ) )
			) {
				return '`'+expected+'` should be wrapped in single quotes';
			}
			expected = removeFirst( removeLast( expected ) );
		}
		if ( !checkPrimitive( actual, expected ) ) {
			return 'Displayed return value is `'+expected+'`, but expected `'+actual+'` instead';
		}
		return null;
	}
	if ( isTypedArray( actual ) || isComplexTypedArray( actual ) || isBooleanArray( actual ) ) {
		return checkTypedArrays( actual, expected );
	}
	if ( isArray( actual ) ) {
		if ( !checkArray( actual, expected ) ) {
			return 'Displayed return value is `'+expected+'`, but expected `'+createAnnotationValue( actual )+'` instead';
		}
		return null;
	}
	if ( isComplex64( actual ) || isComplex128( actual ) ) {
		return checkComplex( actual, expected );
	}
	if ( isRegExp( actual ) ) {
		actual = actual.toString();
		if ( actual !== expected ) {
			return 'Displayed return value is `'+expected+'`, but expected `'+actual+'` instead';
		}
		return null;
	}
	if ( isFunction( actual ) ) {
		actual = actual.toString();
		if ( actual !== expected ) {
			return 'Displayed return value is `'+expected+'`, but expected `'+actual+'` instead';
		}
		return null;
	}
	if ( isObjectLike( actual ) ) {
		if ( !contains( expected, '...' ) ) {
			try {
				expectedValue = parse( expected );
			} catch ( err ) {
				return 'Malformed return annotation. Encountered error while parsing: '+err.message;
			}
			actualString = createAnnotationValue( actual, OPTS );
			actualValue = parse( actualString );
			if ( !deepEqual( expectedValue, actualValue ) ) {
				return 'Displayed return value is `'+expected+'`, but expected `'+actualString+'` instead';
			}
		}
		return null;
	}
	return null;
}
Checks whether a return value is equal to the value of a return annotation.

@private
@param {*} actual - actual return value
@param {string} expected - return value annotation
@returns {(string|null)} error message in case of mismatch, `null` otherwise

@example
var out = compareValues( [ 1, 2, 3 ], '[ 1, 2, ... ]' );
// returns null