 					test = loaded_module.imports[exported.helper].split('.')
 					test2 = test.pop()
 					test = test.join('.')
+					
 					loaded_modules[module_name][version_name].exports[export_name].helper = {
 						callback: loaded_modules[test][loaded_module.modules[test]].exports[test2].helper
 						name: loaded_modules[test][loaded_module.modules[test]].exports[test2].name

		
		# validate filename
		if output.filename
			filename = output.filename
		else if generator.filename
			filename = generator.filename
		else
			throw new Error "Filename is required for output."
		
		# append path to filename
		if output.path
			if !fs.existsSync output.path
				mkdirp output.path
			filename = "#{output.path}/#{filename}"
		
		# validate spec
		if !output.spec
			throw new Error "Spec is required."
		
		# load spec from file
		if typeof(output.spec) == 'string'
			output.spec = yaml.safeLoad fs.readFileSync(".crystal/spec/#{output.spec}", 'utf8')
		output.spec = parse output.spec, project
		
		# validate spec
		if generator.schema
			validate = skeemas.validate output.spec, generator.schema
			if !validate.valid
				console.log validate.errors
				console.log("ERROR: Specification failed validation.")
				for error in validate.errors
					console.log "- #{error.message} for specification (#{error.context.substr(2)})"
				throw new Error "ERROR: Invalid specification."

		# get content from output
		if generator.helper
			helpers = [generator.helper]
		else
			helpers = null
		content = generator.engine output.spec, generator.template, helpers
		
		# transform content
		if output.transformer
			if typeof(output.transformer) == 'string'
				content = imports[output.transformer].transformer content
			else
				content = output.transformer content
		if generator.transformer
			content = generator.transformer content
		
			# get file/cache/ checksum
		filename_checksum = crypto.createHash('md5').update(filename, 'utf8').digest('hex')
		if fs.existsSync ".crystal/cache/#{filename_checksum}"
			if !fs.existsSync filename
				if force != true
					throw new Error "ERROR: File (#{filename}) has been manually deleted outside of Crystal. Use -f to force code generation and overwrite this deletion."
			else
				cache_checksum = fs.readFileSync(".crystal/cache/#{filename_checksum}", 'utf8')
				file_checksum = crypto.createHash('md5').update(fs.readFileSync(filename, 'utf8'), 'utf8').digest('hex')
				
				# validate checksum
				if cache_checksum != file_checksum && force != true
					throw new Error "ERROR: File (#{filename}) has been manually changed outside of Crystal. Use -f to force code generation and overwrite these changes."
		
		# get content checksum
		content_checksum = crypto.createHash('md5').update(content, 'utf8').digest('hex')
		
		# cache checksum
		if !fs.existsSync ".crystal/cache"
			mkdirp.sync ".crystal/cache"
		fs.writeFileSync ".crystal/cache/#{filename_checksum}", content_checksum

		# write content to file
		file_last_path = filename.lastIndexOf('/')
		if file_last_path != -1
			mkdirp.sync filename.substr(0, file_last_path)
		fs.writeFileSync filename, content
		
		#console.log "- #{filename}"
		
		#if generator.outputs
			#loadOutputs generator.outputs, generator.imports, project, force

generate = (project) ->
	console.log "Generating code from: #{this.path}"


loaded_modules = {}

loadModules = (modules) ->
	# load each module
	for module_id of modules
