public function annotate(callable $callable) {
		$fn = null;
		$invoke = function () {};

		// TODO can this be *any* cleaner?
		if(is_array($callable)) {
			// support shorthand array callable form
			// callable arrays will always have 2 elements--otherwise they don't pass the typehint
			$cls = new ReflectionClass($callable[0]);
			$fn = $cls->getMethod($callable[1]);
			$invoke = function ($args) use($fn, $callable) {
				return function () use($fn, $callable, $args) {
					return $fn->invokeArgs($callable[0], $args);
				};
			};
		} else if(!($callable instanceof \Closure)) {
			// support magic __invoke method form
			$cls = new ReflectionClass($callable);
			$fn = $cls->getMethod('__invoke');
			$invoke = function ($args) use($fn, $callable) {
				return function () use($fn, $callable, $args) {
					return $fn->invokeArgs($callable, $args);
				};
			};
		} else {
			// support all other callables
			$fn = new ReflectionFunction($callable);
			$invoke = function ($args) use($fn) {
				return function () use($fn, $args) {
					return $fn->invokeArgs($args);
				};
			};
		}

		$cacheId = sha1($fn->__toString());
		if(array_key_exists($cacheId, $this->fnCache)) {
			return $this->fnCache[$cacheId];
		}

		$args = $this->getArgs($fn);
		$annotated = $invoke($args);
		$this->fnCache[$cacheId] = $annotated;
		return $annotated;
	}