private function getControllerMethods ($controller)
	{
		
		// Check controller exists
		
		if (!\Sonic\Sonic::_classExists (__NAMESPACE__ . '\\' . $controller))
		{
			return array ();
		}
		
		// Set actions
		
		$actions	= array ();
		
		/**
		 * Reflect controller
		 */
		
		$reflection	= new \ReflectionClass (__NAMESPACE__ . '\\' . $controller);
		$className	= $reflection->getName ();
		
		// Get class methods
		
		foreach ($reflection->getMethods () as $method)
		{
			
			// Dont use methods from parent classes
			
			if ($method->getDeclaringClass ()->getName () != $className)
			{
				continue;
			}
			
			// Skip unless the method is public
			
			if (!$method->isPublic ())
			{
				continue;
			}
			
			// Skip methods starting with __
			
			if (substr ($method->getName (), 0, 2) == '__')
			{
				continue;
			}
			
			// Get class name and comment
			
			$name		= $method->getName ();
			$comment	= new \Sonic\Model\Tools\Comment ($method->getDocComment ());
			
			// Skip if @ignore is set in the method comment
			
			if ($comment->hasTag ('ignore'))
			{
				continue;
			}
			
			// Add action
			
			$actions[$name] = array (
				'description'	=> $comment->getShortDescription (),
				'notes'			=> $comment->getLongDescription (),
				'url'			=> URL_ROOT . str_replace ('\\', '/', strtolower ($controller)) . '/' . $name,
				'auth'			=> FALSE
			);
			
			// Deal with authenticated method
			
			if ($comment->hasTag ('authenticated'))
			{
				$actions[$name]['auth']	= TRUE;
			}
			
			// Add method parameters
			
			$params	= $comment->getTags ('param');
			
			if ($params)
			{
				
				foreach ($params as $param)
				{
					
					if (!preg_match ('/^(\w+)\s+\$([\w\d]+)\s*(.*?)$/', $param, $arr))
					{
						continue;
					}
					
					$actions[$name]['param'][]	= array (
						'type'			=> $arr[1],
						'name'			=> $arr[2],
						'description'	=> $arr[3]
					);
					
				}
				
			}
			
		}
		
		// Return actions
		
		return $actions;
		
	}