@Test
public void testFindAllExportedVariables_veryComplex() {

	// Create a model
	Component root = new Component( "root" );
	Component serverWithApp = new Component( "server with app" );
	Component serverWithAnotherApp = new Component( "server with another app" );
	Component db = new Component( "database" );
	root.addChild( db );
	root.addChild( serverWithAnotherApp );
	root.addChild( serverWithApp );
	serverWithAnotherApp.extendComponent( serverWithApp );
	Facet serverFacet = new Facet( "server facet" );
	Facet anotherServerFacet = new Facet( "another server facet" );
	anotherServerFacet.extendFacet( serverFacet );
	serverFacet.addExportedVariable( new ExportedVariable( "url-suffix", "some/path" ));
	serverWithApp.associateFacet( anotherServerFacet );
	serverWithApp.addExportedVariable( new ExportedVariable( "ip", null ));
	serverWithApp.addExportedVariable( new ExportedVariable( serverWithApp.getName() + ".port", "8080" ));
	serverWithApp.addExportedVariable( new ExportedVariable( "env", "test" ));
	// Override the value of a variable that comes from a super facet/component
	serverWithAnotherApp.addExportedVariable( new ExportedVariable( serverFacet.getName() + ".url-suffix", "another/path" ));
	serverWithAnotherApp.addExportedVariable( new ExportedVariable( "whatever", "something" ));
	serverWithAnotherApp.addExportedVariable( new ExportedVariable( "env", "prod" ));
	db.addExportedVariable( new ExportedVariable( "ip", null ));
	db.addExportedVariable( new ExportedVariable( "port", "3306" ));
	// Check assertions
	Assert.assertEquals( 0, ComponentHelpers.findAllExportedVariables( root ).size());
	Map<String,String> exports = ComponentHelpers.findAllExportedVariables( db );
	Assert.assertEquals( 2, exports.size());
	Assert.assertTrue( exports.containsKey( "database.ip" ));
	Assert.assertNull( exports.get( "database.ip" ));
	Assert.assertEquals( "3306", exports.get( "database.port" ));
	exports = ComponentHelpers.findAllExportedVariables( serverWithApp );
	Assert.assertEquals( 5, exports.size());
	Assert.assertTrue( exports.containsKey( serverWithApp.getName() + ".ip" ));
	Assert.assertNull( exports.get( serverWithApp.getName() + ".ip" ));
	Assert.assertEquals( "8080", exports.get( serverWithApp.getName() + ".port" ));
	Assert.assertEquals( "test", exports.get( serverWithApp.getName() + ".env" ));
	Assert.assertEquals( "some/path", exports.get( serverWithApp.getName() + ".url-suffix" ));
	Assert.assertEquals( "some/path", exports.get( serverFacet.getName() + ".url-suffix" ));
	// Since there is inheritance, there will be variables duplication
	exports = ComponentHelpers.findAllExportedVariables( serverWithAnotherApp );
	Assert.assertEquals( 10, exports.size());
	Assert.assertTrue( exports.containsKey( serverWithApp.getName() + ".ip" ));
	Assert.assertNull( exports.get( serverWithApp.getName() + ".ip" ));
	Assert.assertTrue( exports.containsKey( serverWithAnotherApp.getName() + ".ip" ));
	Assert.assertNull( exports.get( serverWithAnotherApp.getName() + ".ip" ));
	Assert.assertEquals( "8080", exports.get( serverWithApp.getName() + ".port" ));
	Assert.assertEquals( "8080", exports.get( serverWithAnotherApp.getName() + ".port" ));
	Assert.assertEquals( "another/path", exports.get( serverFacet.getName() + ".url-suffix" ));
	Assert.assertEquals( "some/path", exports.get( serverWithApp.getName() + ".url-suffix" ));
	Assert.assertEquals( "some/path", exports.get( serverWithAnotherApp.getName() + ".url-suffix" ));
	Assert.assertEquals( "something", exports.get( serverWithAnotherApp.getName() + ".whatever" ));
	Assert.assertEquals( "prod", exports.get( serverWithApp.getName() + ".env" ));
	Assert.assertEquals( "prod", exports.get( serverWithAnotherApp.getName() + ".env" ));
}