inputs_type load_inputs( boost::property_tree::ptree& pt ) {
	using boost::property_tree::ptree;
	typedef ptree::const_assoc_iterator citer;
	inputs_type result;

	std::pair< citer, citer > inputs = pt.equal_range( "input" );
	for( citer& i = inputs.first; i != inputs.second; ++i ) {
		const ptree& input = i->second;
		result.push_back( Input() );

		result.back().semantic = 
			input.get_child( "<xmlattr>.semantic" ).data();
		result.back().source =
			input.get_child( "<xmlattr>.source" ).data();

		result.back().offset = input.get<size_t>( "<xmlattr>.offset", 0 );
		std::cout << result.back().semantic << " from " << 
			result.back().source << " at " <<
			result.back().offset << std::endl;
	}

	return result;
}
sources_type load_sources( boost::property_tree::ptree& pt ) {
	using boost::property_tree::ptree;
	typedef ptree::const_assoc_iterator citer;
	sources_type result;

	std::pair< citer, citer > sources = pt.equal_range( "source" );
	for( citer& i = sources.first; i != sources.second; ++i ) {
		const std::string& id = i->second.get_child( "<xmlattr>.id" ).data();
		const ptree& arr = i->second.get_child( "float_array" );

		size_t count = arr.get<size_t>( "<xmlattr>.count" );
		std::cout << "Loading " << count << " from " << id << std::endl;
		result[ id ].reserve( count );

		std::stringstream ss( arr.data() );
		for( size_t f = 0; f < count; ++f ) {
			float val;
			ss >> val;
			result[ id ].push_back( val );
		}
	}

	return result;
}