protected function doGetBundles() {
		$cache = $this->getCache();
		if($cache)
			$bundles = $cache->fetch('asgard.bundles');

		if(!isset($bundles) || $bundles === false) {
			$bundles = array_merge($this->addedBundles, $this->getBundles());

			$newBundles = false;
			foreach($bundles as $k=>$v) {
				if(is_string($v)) {
					$bundle = realpath($v);
					if(!$bundle)
						throw new \Exception('Bundle '.$v.' does not exist.');
					unset($bundles[$k]);
					$bundles[$bundle] = null;
					$newBundles = true;

					if(file_exists($bundle.'/Bundle.php'))
						require_once $bundle.'/Bundle.php';
				}
			}
			if($newBundles) {
				foreach(get_declared_classes() as $class) {
					if(!is_subclass_of($class, 'Asgard\Core\BundleLoader'))
						continue;
					$reflector = new \ReflectionClass($class);
					$dir = dirname($reflector->getFileName());
					if(array_key_exists($dir, $bundles) && $bundles[$dir] === null) {
						unset($bundles[$dir]);
						$bundles[] = new $class;
					}
				}
			}
			foreach($bundles as $bundle=>$obj) {
				if($obj === null) {
					$obj = new BundleLoader;
					$obj->setPath($bundle);
					$bundles[$bundle] = $obj;
				}
			}

			#Remove duplicates
			$kbundles = array_keys($bundles);
			$vbundles = array_values($bundles);
			foreach($vbundles as $k=>$b) {
				$key = $kbundles[$k];
				for($i=$k+1; isset($bundles[$i]); $i++) {
					if($b->getPath() === $bundles[$i]->getPath())
						unset($bundles[$k]);
				}
			}

			foreach($bundles as $bundle) {
				$bundle->setHooksAnnotationReader($this->getHooksAnnotationReader());
				$bundle->setControllersAnnotationReader($this->getControllersAnnotationReader());
			}

			if($cache)
				$cache->save('asgard.bundles', $bundles);
		}

		return $bundles;
	}