function callHelper(args, useCurrentContext) {
	
	// Validate and parse the args
	var name = args && Base.getValue(args[0]),
		result = new Base.UnknownType(),
		isModule,
		eventDescription;
			
	if (!name) {
		name = new Base.UndefinedType();
	}
			
	if (Base.type(name) === "Unknown") {
				
		eventDescription = "A value that could not be evaluated was passed to require";
		Runtime.fireEvent("requireUnresolved", eventDescription, {
			name: "<Could not evaluate require path>"
		});
		Runtime.reportWarning("requireUnresolved", eventDescription, {
			name: "<Could not evaluate require path>"
		});
		return result;
	}
			
	name = Base.toString(name).value;
	
	// We don't process plugins or urls at compile time
	if (pluginRegExp.test(name) || name.indexOf(":") !== -1) {
		Runtime.fireEvent("requireUnresolved", 
			"Plugins and URLS can not be evaluated at compile-time and will be deferred to runtime.", {
				name: name
			});
	} else {
		
		// Resolve the path
		isModule = name[0] !== "/" && !name.match(fileRegExp);
		name = path.resolve(path.join(path.dirname(name[0] !== "." ? Runtime.fileStack[0] : Runtime.getCurrentFile()), name));
		name += isModule ? ".js" : "";
				
		// Make sure that the file exists and then process it
		if (fs.existsSync(name)) {
					
			Runtime.fireEvent("requireResolved", "The require path '" + name + "' was resolved", {
				name: name
			});
			result = CodeProcessor.processFile(name, isModule, useCurrentContext)[1];
					
		} else {
			eventDescription = "The require path '" + name + "' was resolved";
			Runtime.fireEvent("requireMissing", eventDescription, {
				name: name
			});
			Runtime.reportError("requireMissing", eventDescription, {
				name: name
			});
		}
	}
			
	return result;
}
	Runtime.on('tiPropertyReferenced', function (e) {
		var name = e.data.name,
			location = e.filename + ':' + e.line + ':' + e.column,
			deprecatedAPIInfo;

		if (e.data.node.deprecated) {
			// TODO: Change deprecated message when we have the 'deprecated since' info from jsca
			Runtime.reportWarning('deprecatedTiPropertyReferenced', '"' + name + '" has been deprecated', {
				property: name
			});

			deprecatedAPIInfo = results.deprecatedAPIs[name];
			if (deprecatedAPIInfo) {
				deprecatedAPIInfo.numInstances++;
				if (deprecatedAPIInfo.locations.hasOwnProperty(location)) {
					deprecatedAPIInfo.locations[location]++;
				} else {
					deprecatedAPIInfo.locations[location] = 1;
				}
			} else {
				results.deprecatedAPIs[name] = {
					numInstances: 1,
					locations: {}
				};
				results.deprecatedAPIs[name].locations[location] = 1;
			}
		}
	});
	Runtime.on('tiPropertyReferenced', function(e) {
		var platformList = e.data.node.userAgents,
			i = 0,
			len = platformList.length,
			isSupported = false,
			name = e.data.name;

		for(; i < len; i++) {
			if (platform === platformList[i].platform) {
				isSupported = true;
			}
		}
		if (!isSupported) {
			Runtime.reportWarning('invalidPlatformReferenced', 'Property "' + name +
				'" is not supported on ' + platform, {
					property: name,
					platform: platform
				});

			if (results.invalidAPIs[name]) {
				results.invalidAPIs[name] += 1;
			} else {
				results.invalidAPIs[name] = 1;
			}
		}
	});
	files.forEach(function (file) {
		file = Base.toString(file);
		if (Base.type(file) !== 'String') {
			eventDescription = 'A value that could not be evaluated was passed to Ti.include';
			Runtime.fireEvent('tiIncludeUnresolved', eventDescription, {
				name: '<Could not evaluate Ti.include path>'
			});
			Runtime.reportWarning('tiIncludeUnresolved', eventDescription, {
				name: '<Could not evaluate Ti.include path>'
			});
			return result;
		}
		file = file.value;
		
		if (file[0] === '.') {
			filePath = path.resolve(path.join(path.dirname(Runtime.getCurrentLocation().file), file));
		} else {
			filePath = path.resolve(path.join(path.dirname(Runtime.getEntryPointFile()), platform, file));
			if (!fs.existsSync(filePath)) {
				filePath = path.resolve(path.join(path.dirname(Runtime.getEntryPointFile()), file));
			}
		}
		
		// Make sure the file exists
		if (fs.existsSync(filePath)) {
			
			Runtime.fireEvent('tiIncludeResolved', 'The Ti.include path "' + filePath + '" was resolved', {
				file: filePath
			});
			
			// Fire the parsing begin event
			Runtime.fireEvent('fileProcessingBegin', 'Processing is beginning for file "' + filePath + '"', {
				file: filePath
			});
			
			// Eval the code
			evalFunc = Runtime.getGlobalObject().get('eval');
			evalFunc.call(thisVal, [new Base.StringType(fs.readFileSync(filePath).toString())], false, filePath);
			
			// Fire the parsing end event
			Runtime.fireEvent('fileProcessingEnd', 'Processing finished for file "' + filePath + '"', {
				file: filePath
			});
			
		} else {
			eventDescription = 'The Ti.include path "' + filePath + '" could not be found';
			Runtime.fireEvent('tiIncludeMissing', eventDescription, {
				name: filePath
			});
			Runtime.reportError('tiIncludeMissing', eventDescription, {
				name: filePath
			});
		}
	});
		callFunction: Base.wrapNativeCall(function callFunction(thisVal, args) {
			var name = Base.toString(args[0]);
			if (Base.type(name) != 'Unknown') {
				name = name.value;
				if (tiappProperties.hasOwnProperty(name)) {
					delete tiappProperties[name];
					Runtime.reportWarning('tiappPropertyInvalidated', 'Property "' + name +
						'" specified Tiapp.xml was removed, the value of this property cannot be guaranteed');
				}
			}
			return new Base.UndefinedType();
		})
			files.forEach(function (filename) {
				filename = Base.toString(filename);
				if (Base.type(filename) !== 'String') {
					eventDescription = 'A value that could not be evaluated was passed to Ti.include';
					Runtime.fireEvent('tiIncludeUnresolved', eventDescription);
					Runtime.reportWarning('tiIncludeUnresolved', eventDescription);
					return result;
				}
				filename = filename.value;

				if (filename[0] === '.') {
					filePath = path.resolve(path.join(path.dirname(Runtime.getCurrentLocation().filename), filename));
				} else {
					filePath = path.resolve(path.join(Runtime.sourceInformation.sourceDir, options.platform, filename));
					if (!existsSync(filePath)) {
						filePath = path.resolve(path.join(Runtime.sourceInformation.sourceDir, filename));
					}
				}

				// Make sure the file exists
				if (existsSync(filePath)) {

					Runtime.fireEvent('tiIncludeResolved', 'The Ti.include path "' + filePath + '" was resolved', {
						name: filename,
						path: filePath
					});

					// Fire the parsing begin event
					Runtime.fireEvent('enteredFile', 'Processing is beginning for file "' + filePath + '"', {
						filename: filePath
					});

					// Eval the code
					evalFunc = Base.getGlobalObject().get('eval');
					evalFunc.callFunction(thisVal, [new Base.StringType(fs.readFileSync(filePath).toString())], true, filePath);

					this._location = {
						filename: filePath,
						line: 1,
						column: 1
					};

				} else {
					eventDescription = 'The Ti.include path "' + filename + '" could not be found';
					Runtime.fireEvent('tiIncludeMissing', eventDescription, {
						name: filename
					});
					Runtime.reportError('tiIncludeMissing', eventDescription);
				}
			}.bind(this));
	Runtime.on('tiPropertyReferenced', function(e) {
		var platformList = e.data.node.userAgents,
			location = e.filename + ':' + e.line + ':' + e.column,
			i, len,
			isSupported = false,
			name = e.data.name,
			invalidAPI;

		for (i = 0, len = platformList.length; i < len; i++) {
			if (platform === platformList[i].platform) {
				isSupported = true;
			}
		}
		if (!isSupported) {
			Runtime.reportWarning('invalidPlatformReferenced', 'Property "' + name +
				'" is not supported on ' + platform, {
					property: name,
					platform: platform
				});

			invalidAPI = results.invalidAPIs[name];
			if (invalidAPI) {
				invalidAPI.numInstances++;
				if (invalidAPI.locations.hasOwnProperty(location)) {
					invalidAPI.locations[location]++;
				} else {
					invalidAPI.locations[location] = 1;
				}
			} else {
				results.invalidAPIs[name] = {
					numInstances: 1,
					locations: {}
				};
				results.invalidAPIs[name].locations[location] = 1;
			}
		}
	});
exports.getOverrides = function (options) {
	if (options.globalsOnly) {
		return [];
	}
	var tiappProperties = options.tiappProperties,
		setProperty = Base.wrapNativeCall(function setProperty(thisVal, args) {
			var name = Base.toString(args[0]);
			if (Base.type(name) != 'Unknown') {
				name = name.value;
				if (tiappProperties.hasOwnProperty(name)) {
					delete tiappProperties[name];
					Runtime.reportWarning('tiappPropertyInvalidated', 'Property "' + name +
						'" specified Tiapp.xml was overwritten, the value of this property cannot be guaranteed');
				}
			}
			return new Base.UndefinedType();
		}),
		p;

	function createGetFunction(type) {
		return Base.wrapNativeCall(function getProperty(thisVal, args) {
			var name = Base.toString(args[0]);
			if (Base.type(name) == 'Unknown') {
				return new Base.UnknownType();
			}
			name = name.value;
			if (!tiappProperties[name]) {
				return new Base.UnknownType();
			} else if (tiappProperties[name].type != type) {
				return new Base.UndefinedType();
			} else {
				return tiappProperties[name];
			}
		});
	}

	for (p in tiappProperties) {
		switch(tiappProperties[p].type) {
			case 'string':
				tiappProperties[p].value = new Base.StringType(tiappProperties[p].value);
				break;
			case 'bool':
				tiappProperties[p].value = new Base.BooleanType(tiappProperties[p].value);
				break;
			case 'int':
			case 'double':
				tiappProperties[p].value = new Base.NumberType(tiappProperties[p].value);
				break;
			default:
				Runtime.reportWarning('invalidTiappPropertyType', 'Invalid tiapp.xml property type "' + tiappProperties[p].type + '"');
				delete tiappProperties[p];
		}
	}

	return [{
		regex: /^Titanium\.App\.getBool$/,
		callFunction: createGetFunction('bool')
	},{
		regex: /^Titanium\.App\.getDouble$/,
		callFunction: createGetFunction('double')
	},{
		regex: /^Titanium\.App\.getInt$/,
		callFunction: createGetFunction('int')
	},{
		regex: /^Titanium\.App\.getString$/,
		callFunction: createGetFunction('string')
	},{
		regex: /^Titanium\.App\.hasProperty$/,
		callFunction: Base.wrapNativeCall(function callFunction(thisVal, args) {
			var name = Base.toString(args[0]);
			if (Base.type(name) == 'Unknown') {
				return new Base.UnknownType();
			}
			name = name.value;
			return tiappProperties[name] ? new Base.BooleanType(true) : new Base.UnknownType();
		})
	},{
		regex: /^Titanium\.App\.removeProperty$/,
		callFunction: Base.wrapNativeCall(function callFunction(thisVal, args) {
			var name = Base.toString(args[0]);
			if (Base.type(name) != 'Unknown') {
				name = name.value;
				if (tiappProperties.hasOwnProperty(name)) {
					delete tiappProperties[name];
					Runtime.reportWarning('tiappPropertyInvalidated', 'Property "' + name +
						'" specified Tiapp.xml was removed, the value of this property cannot be guaranteed');
				}
			}
			return new Base.UndefinedType();
		})
	},{
		regex: /^Titanium\.App\.setBool$/,
		callFunction: setProperty
	},{
		regex: /^Titanium\.App\.setDouble$/,
		callFunction: setProperty
	},{
		regex: /^Titanium\.App\.setInt$/,
		callFunction: setProperty
	},{
		regex: /^Titanium\.App\.setString$/,
		callFunction: setProperty
	}];
};
RequireFunction.prototype.call = function call(thisVal, args) {

	// Validate and parse the args
	var name = args && Base.getValue(args[0]),
		filePath,
		result = new Base.UnknownType(),
		isModule,
		eventDescription;

	if (!name) {
		name = new Base.UndefinedType();
	}

	name = Base.toString(name);
	if (Base.type(name) !== 'String') {
		eventDescription = 'A value that could not be evaluated was passed to require';
		Runtime.fireEvent('requireUnresolved', eventDescription);
		Runtime.reportWarning('requireUnresolved', eventDescription);
		return result;
	}
	name = name.value;
	if (pluginRegExp.test(name) || name.indexOf(':') !== -1) {
		Runtime.fireEvent('requireUnresolved',
			'Plugins and URLS can not be evaluated at compile-time and will be deferred until runtime.', {
				name: name
		});
	} else {

		// Determine if this is a Titanium module
		if (modules.commonjs && modules.commonjs && modules.commonjs.hasOwnProperty(name)) {
			isModule = true;
			filePath = modules.commonjs[name];
		} else if (modules[platform] && modules[platform] && modules[platform].hasOwnProperty(name)) {
			isModule = true;
		}

		if (isModule) {
			if (filePath) {
				if (cache[filePath]) {
					Runtime.fireEvent('requireResolved', 'The require path "' + filePath + '" was resolved', {
						name: filePath
					});
					result = cache[filePath];
				} else {
					result = processFile(filePath, true)[1];
					cache[filePath] = result;
				}
			} else {
				Runtime.fireEvent('requireSkipped',
					'Native modules cannot be evaluated at compile-time and will be deferred until runtime', {
						name: name
				});
			}
		} else {

			// Resolve the path
			isModule = !name.match(fileRegExp); // I kinda hate this, but there are too many incorrect usages of require in the wild to implement the spec correctly
			if (name[0] === '.') {
				filePath = path.resolve(path.join(path.dirname(Runtime.getCurrentLocation().filename), name));
				filePath += isModule ? '.js' : '';
			} else {
				filePath = path.resolve(path.join(path.dirname(Runtime.getEntryPointFile()), platform, name));
				filePath += isModule ? '.js' : '';
				if (!existsSync(filePath)) {
					filePath = path.resolve(path.join(path.dirname(Runtime.getEntryPointFile()), name));
					filePath += isModule ? '.js' : '';
				}
			}

			// Make sure that the file exists and then process it
			if (existsSync(filePath)) {
				if (cache[filePath]) {
					result = cache[filePath];
				} else {
					Runtime.fireEvent('requireResolved', 'The require path "' + filePath + '" was resolved', {
						name: filePath
					});
					result = processFile(filePath, isModule)[1];
					cache[filePath] = result;
				}

			} else {
				eventDescription = 'The require path "' + filePath + '" could not be found';
				Runtime.fireEvent('requireMissing', eventDescription, {
					name: filePath
				});
				Runtime.reportError('requireMissing', eventDescription, {
					name: filePath
				});
			}
		}
	}
	return result;
};