lib/HalDependencyResolver.js
function(modules, needs, arr) {
		arr = arr || [];

		// todo - this assumes the entire set of dependencies exists on the device (i.e. a module with the same n/f values)
		// but this is not the case, e.g. when upgrading from a 2 module system to 3 module system.
		for (var i = 0; i < modules.length; i++) {
			var m = modules[i];

			if (m.n !== needs.n) {
				continue;
			}
			if (m.f !== needs.f) {
				continue;
			}

			//found one!
			if (m.v < needs.v) {
				//
				// it's...
				//	  .---.       .-''-.     .-'''-.    .-'''-.     ,---------. .---.  .---.    ____    ,---.   .--.
				//	  | ,_|     .'_ _   \   / _     \  / _     \    \          \|   |  |_ _|  .'  __ `. |    \  |  |
				//	,-./  )    / ( ` )   ' (`' )/`--' (`' )/`--'     `--.  ,---'|   |  ( ' ) /   '  \  \|  ,  \ |  |
				//	\  '_ '`) . (_ o _)  |(_ o _).   (_ o _).           |   \   |   '-(_{;}_)|___|  /  ||  |\_ \|  |
				//	 > (_)  ) |  (_,_)___| (_,_). '.  (_,_). '.         :_ _:   |      (_,_)    _.-`   ||  _( )_\  |
				//	(  .  .-' '  \   .---..---.  \  :.---.  \  :        (_I_)   | _ _--.   | .'   _    || (_ o _)  |
				//	 `-'`-'|___\  `-'    /\    `-'  |\    `-'  |       (_(=)_)  |( ' ) |   | |  _( )_  ||  (_,_)\  |
				//	  |        \\       /  \       /  \       /         (_I_)   (_{;}_)|   | \ (_ o _) /|  |    |  |
				//	  `--------` `'-..-'    `-...-'    `-...-'          '---'   '(_,_) '---'  '.(_,_).' '--'    '--'
				//

				//arr.push(m);

				// instead of returning the module we found, lets return the module with the version we need,
				// and any dependencies it requires, I think that's more clear.

				var missing = extend(m, { v: needs.v });
				arr.push(missing);
				// todo mdm - this is wrong. we shouldn't be fabricating dependencies for a new version of a module
				// (need) from the installed version (m) - dependencies can and do change between versions.
				// The database of known modules should be the definitive source of module dependencies.

				// if we're updating this, we better check its dependencies too.
				if (m.d && (m.d.length > 0)) {
					//oh no!  this module has dependencies!
					// do we have to update those too?
					// (this doesn't fully make sense to me right now, but lets go with it.)
					// todo mdm - this won't do anything, since `m` is always a satisfied dependency
					// (it came from the modules array.)
					// at the very least we should be iterating over m.d[] as the needed modules
					arr = this._walkChain(modules, m, arr);
				}
			}
		}

		return arr;
	}
function(modules, needs, arr) {
		arr = arr || [];

		// todo - this assumes the entire set of dependencies exists on the device (i.e. a module with the same n/f values)
		// but this is not the case, e.g. when upgrading from a 2 module system to 3 module system.
		for (var i = 0; i < modules.length; i++) {
			var m = modules[i];

			if (m.n !== needs.n) {
				continue;
			}
			if (m.f !== needs.f) {
				continue;
			}

			//found one!
			if (m.v < needs.v) {
				//
				// it's...
				//	  .---.       .-''-.     .-'''-.    .-'''-.     ,---------. .---.  .---.    ____    ,---.   .--.
				//	  | ,_|     .'_ _   \   / _     \  / _     \    \          \|   |  |_ _|  .'  __ `. |    \  |  |
				//	,-./  )    / ( ` )   ' (`' )/`--' (`' )/`--'     `--.  ,---'|   |  ( ' ) /   '  \  \|  ,  \ |  |
				//	\  '_ '`) . (_ o _)  |(_ o _).   (_ o _).           |   \   |   '-(_{;}_)|___|  /  ||  |\_ \|  |
				//	 > (_)  ) |  (_,_)___| (_,_). '.  (_,_). '.         :_ _:   |      (_,_)    _.-`   ||  _( )_\  |
				//	(  .  .-' '  \   .---..---.  \  :.---.  \  :        (_I_)   | _ _--.   | .'   _    || (_ o _)  |
				//	 `-'`-'|___\  `-'    /\    `-'  |\    `-'  |       (_(=)_)  |( ' ) |   | |  _( )_  ||  (_,_)\  |
				//	  |        \\       /  \       /  \       /         (_I_)   (_{;}_)|   | \ (_ o _) /|  |    |  |
				//	  `--------` `'-..-'    `-...-'    `-...-'          '---'   '(_,_) '---'  '.(_,_).' '--'    '--'
				//

				//arr.push(m);

				// instead of returning the module we found, lets return the module with the version we need,
				// and any dependencies it requires, I think that's more clear.

				var missing = extend(m, { v: needs.v });
				arr.push(missing);
				// todo mdm - this is wrong. we shouldn't be fabricating dependencies for a new version of a module
				// (need) from the installed version (m) - dependencies can and do change between versions.
				// The database of known modules should be the definitive source of module dependencies.

				// if we're updating this, we better check its dependencies too.
				if (m.d && (m.d.length > 0)) {
					//oh no!  this module has dependencies!
					// do we have to update those too?
					// (this doesn't fully make sense to me right now, but lets go with it.)
					// todo mdm - this won't do anything, since `m` is always a satisfied dependency
					// (it came from the modules array.)
					// at the very least we should be iterating over m.d[] as the needed modules
					arr = this._walkChain(modules, m, arr);
				}
			}
		}

		return arr;
	}
/*
walk over the described modules until we've resolved our
dependency chain for all the dependent things
that need updating.

(typically system module 1, and 2)

@param modules - what was in the describe message (the modules on the device)
@param needs - what was described in the binary header info - the dependencies being checked
@param [arr] - our accumulator array
@returns {*|Array}
@private