@Test
public void testRecognizeProperty() {

	FileDefinition file = new FileDefinition( new File( "some-file" ));
	String[] validLines = {
		"property: value;",
		"   property : value  ;",
		"PROPERTY: value; # with an inline comment",
		"property: value1, value2  ,  value3;",
		"property:;",
		"property : key6 = \" key; 6 \";"
	};
	// Comments do not matter here
	for( String line : validLines ) {
		FileDefinitionParser parser = new FileDefinitionParser( null, false );
		BlockComponent holder = new BlockComponent( file );
		int code = parser.recognizeProperty( line, holder );
		Assert.assertEquals( "Expected a YES code for '" + line + "'", FileDefinitionParser.P_CODE_YES, code );
		Assert.assertEquals( "No parsing error was expected for '" + line + "'", 0, parser.getFileRelations().getParsingErrors().size());
		Assert.assertEquals( "Expected ONE block to be registered for '" + line + "'", 1, holder.getInnerBlocks().size());
		BlockProperty prop = (BlockProperty) holder.getInnerBlocks().iterator().next();
		Assert.assertEquals( "Expected ONE property for '" + line + "'", AbstractBlock.PROPERTY, prop.getInstructionType());
		Assert.assertEquals( "Invalid property name for '" + line + "'", "property", prop.getName().toLowerCase());
	}
	// Exports with quotes and semicolons in values
	validLines = new String[] {
		"exports : random[port] key6 = \" key; 6 \";",
		"exports : random[port] key6 = \" key; 6 \", key7=\"value7\";"
	};
	// Comments do not matter here
	for( String line : validLines ) {
		FileDefinitionParser parser = new FileDefinitionParser( null, false );
		BlockComponent holder = new BlockComponent( file );
		int code = parser.recognizeProperty( line, holder );
		Assert.assertEquals( "Expected a YES code for '" + line + "'", FileDefinitionParser.P_CODE_YES, code );
		Assert.assertEquals( "No parsing error was expected for '" + line + "'", 0, parser.getFileRelations().getParsingErrors().size());
		Assert.assertEquals( "Expected ONE block to be registered for '" + line + "'", 1, holder.getInnerBlocks().size());
		BlockProperty prop = (BlockProperty) holder.getInnerBlocks().iterator().next();
		Assert.assertEquals( "Expected ONE property for '" + line + "'", AbstractBlock.PROPERTY, prop.getInstructionType());
		Assert.assertEquals( "Invalid property name for '" + line + "'", "exports", prop.getName().toLowerCase());
	}
	// In-line comments
	String[][] commentedLines = {
		{ "property: value;", "" },
		{ "property: value;", "# stuck comment" },
		{ "property: value;", "#" },
		{ "property: value1, value2;", "\t# some in-line comment   " }
	};
	for( String[] line : commentedLines ) {
		FileDefinitionParser parser = new FileDefinitionParser( null, false );
		String theLine = line[ 0 ] + line[ 1 ];
		BlockComponent holder = new BlockComponent( file );
		int code = parser.recognizeProperty( theLine, holder );
		Assert.assertEquals( "Expected a YES code for '" + theLine + "'", FileDefinitionParser.P_CODE_YES, code );
		Assert.assertEquals( "No parsing error was expected for '" + theLine + "'", 0, parser.getFileRelations().getParsingErrors().size());
		Assert.assertEquals( "Expected ONE block to be registered for '" + theLine + "'", 1, holder.getInnerBlocks().size());
		BlockProperty prop = (BlockProperty) holder.getInnerBlocks().iterator().next();
		Assert.assertEquals( "Expected ONE property for '" + theLine + "'", AbstractBlock.PROPERTY, prop.getInstructionType());
		String expected = Utils.isEmptyOrWhitespaces( line[ 1 ]) ? null : line[ 1 ];
		Assert.assertEquals( "Invalid in-line comment for '" + theLine + "'", expected, prop.getInlineComment());
	}
	// Invalid lines
	String[] invalidLines = {
		"property = value;",
		"property",
		"facet",
		"",
		" #"
	};
	for( String line : invalidLines ) {
		FileDefinitionParser parser = new FileDefinitionParser( null, false );
		BlockComponent holder = new BlockComponent( file );
		int code = parser.recognizeProperty( line, holder );
		Assert.assertEquals( "Expected a NO code for '" + line + "'", FileDefinitionParser.P_CODE_NO, code );
	}
	// Test error codes
	Map<String,ErrorCode> invalidLineToErrorCode = new LinkedHashMap<> ();
	invalidLineToErrorCode.put( "property: value", ErrorCode.P_PROPERTY_ENDS_WITH_SEMI_COLON );
	invalidLineToErrorCode.put( "property:", ErrorCode.P_PROPERTY_ENDS_WITH_SEMI_COLON );
	invalidLineToErrorCode.put( "property: value;;", ErrorCode.P_ONE_BLOCK_PER_LINE );
	invalidLineToErrorCode.put( "exports : key6 = key; 6 \";", ErrorCode.P_ONE_BLOCK_PER_LINE );
	for( Map.Entry<String,ErrorCode> entry : invalidLineToErrorCode.entrySet()) {
		String line = entry.getKey();
		FileDefinitionParser parser = new FileDefinitionParser( null, false );
		BlockComponent holder = new BlockComponent( file );
		FileDefinition def = parser.getFileRelations();
		int code = parser.recognizeProperty( line, holder );
		Assert.assertEquals( "Expected a YES code for '" + line + "'", FileDefinitionParser.P_CODE_YES, code );
		Assert.assertEquals( "A parsing error was expected for '" + line + "'", 1, def.getParsingErrors().size());
		Assert.assertEquals( "Expected ONE block to be registered for '" + line + "'", 1, holder.getInnerBlocks().size());
		Assert.assertEquals( "Expected ONE property for '" + line + "'",
				AbstractBlock.PROPERTY,
				holder.getInnerBlocks().iterator().next().getInstructionType());
		ParsingError error = def.getParsingErrors().iterator().next();
		Assert.assertEquals( "Expecting parsing error for '" + line + "'", entry.getValue().getCategory(), ErrorCategory.PARSING );
		Assert.assertEquals( "Invalid error code for '" + line + "'", entry.getValue(), error.getErrorCode());
	}
	// Complex errors
	invalidLines = new String[] {
		"property: value ; facet toto {",
		"property: value ; invalid comment"
	};
	for( String line : invalidLines ) {
		FileDefinitionParser parser = new FileDefinitionParser( null, false );
		BlockComponent holder = new BlockComponent( file );
		FileDefinition def = parser.getFileRelations();
		int code = parser.recognizeProperty( line, holder );
		Assert.assertEquals( "Expected a YES code for '" + line + "'", FileDefinitionParser.P_CODE_YES, code );
		Assert.assertEquals( "Two parsing errors were expected for '" + line + "'", 2, def.getParsingErrors().size());
		Assert.assertEquals( "Expected ONE block to be registered for '" + line + "'", 1, holder.getInnerBlocks().size());
		Assert.assertEquals( "Expected ONE property for '" + line + "'",
				AbstractBlock.PROPERTY,
				holder.getInnerBlocks().iterator().next().getInstructionType());
		Iterator<ParsingError> iterator = def.getParsingErrors().iterator();
		ParsingError error = iterator.next();
		Assert.assertEquals( "Expecting parsing error for '" + line + "'", error.getErrorCode().getCategory(), ErrorCategory.PARSING );
		Assert.assertEquals( "Invalid error code for '" + line + "'", ErrorCode.P_PROPERTY_ENDS_WITH_SEMI_COLON, error.getErrorCode());
		error = iterator.next();
		Assert.assertEquals( "Expecting parsing error for '" + line + "'", error.getErrorCode().getCategory(), ErrorCategory.PARSING );
		Assert.assertEquals( "Invalid error code for '" + line + "'", ErrorCode.P_ONE_BLOCK_PER_LINE, error.getErrorCode());
	}
}