diff --git a/config/global.ini.php b/config/global.ini.php
index ffff48ea6bc6bf7fa6b4e40dc868d6f19a0d524f..14742744e7b84e9cd605d70e9b024f64c854959e 100644
--- a/config/global.ini.php
+++ b/config/global.ini.php
@@ -72,6 +72,14 @@ enable_browser_archiving_triggering = 1
 ; the page first-post in the subcategory development which belongs to the blog category
 action_category_delimiter = /
 
+; this action name is used when the URL ends with a slash / 
+; it is useful to have an actual string to write in the UI
+action_default_name 		= index
+
+; this action name is used when the URL has no page title or page URL defined
+action_default_name_when_not_defined = "page title not defined"
+action_default_url_when_not_defined = "page url not defined"
+
 ; currency used by default when reporting money in Piwik
 ; the trailing space is required for php 5.2.x vs 5.3 compatibility
 default_currency = "$ "
@@ -139,9 +147,6 @@ swfobject_version = 2.2
 ; set to 0 if you want to stop tracking the visitors. Useful if you need to stop all the connections on the DB.
 record_statistics			= 1
 
-; this action name is used when the javascript variable piwik_action_name is not specified in the piwik javascript code, and when the URL has no path.
-default_action_name 		= index
-
 ; length of a visit in seconds. If a visitor comes back on the website visit_standard_length seconds after his last page view, it will be recorded as a new visit  
 visit_standard_length       = 1800
 
diff --git a/core/API/Proxy.php b/core/API/Proxy.php
index 0e83592378adc8e1ca5c58ac2d9ade443bbd45a8..26c11288c9787e11b2c037b4bd71f9f5a04e0661 100644
--- a/core/API/Proxy.php
+++ b/core/API/Proxy.php
@@ -246,7 +246,9 @@ class Piwik_API_Proxy
 	{
 		if($method->isPublic() 
 			&& !$method->isConstructor()
-			&& $method->getName() != 'getInstance' )
+			&& $method->getName() != 'getInstance'
+			&& false === strstr($method->getDocComment(), '@deprecated')
+			 )
 		{
 			$name = $method->getName();
 			$parameters = $method->getParameters();
diff --git a/core/ArchiveProcessing/Day.php b/core/ArchiveProcessing/Day.php
index 051fedad186ea3117f5b9818c295601edc95199b..2e3c0bbab72cdfb8f2f3d8723cdd30f70cbc074a 100644
--- a/core/ArchiveProcessing/Day.php
+++ b/core/ArchiveProcessing/Day.php
@@ -28,7 +28,7 @@ class Piwik_ArchiveProcessing_Day extends Piwik_ArchiveProcessing
 		$this->db = Zend_Registry::get('db');
 		$this->debugAlwaysArchive = Zend_Registry::get('config')->Debug->always_archive_data_day;
 	}
-	
+
 	/**
 	 * Main method to process logs for a day. The only logic done here is computing the number of visits, actions, etc.
 	 * All the other reports are computed inside plugins listening to the event 'ArchiveProcessing_Day.compute'.
diff --git a/core/Piwik.php b/core/Piwik.php
index 0d3595a452964c0c2fe28546348c9c44eafe6b5b..09a6b8d109a51121a4a3684cc93001843e2e8dd5 100644
--- a/core/Piwik.php
+++ b/core/Piwik.php
@@ -609,9 +609,10 @@ class Piwik
 			'log_action' => "CREATE TABLE {$prefixTables}log_action (
 									  idaction INTEGER(10) UNSIGNED NOT NULL AUTO_INCREMENT,
 									  name VARCHAR(255) NOT NULL,
+									  hash INTEGER(10) UNSIGNED NOT NULL,
   									  type TINYINT UNSIGNED NULL,
 									  PRIMARY KEY(idaction),
-									  INDEX index_type_name (type, name(15))
+									  INDEX index_type_hash (type, hash)
 						)  DEFAULT CHARSET=utf8 
 			",
 					
@@ -624,8 +625,8 @@ class Piwik
 							  visit_first_action_time DATETIME NOT NULL,
 							  visit_last_action_time DATETIME NOT NULL,
 							  visit_server_date DATE NOT NULL,
-							  visit_exit_idaction INTEGER(11) NOT NULL,
-							  visit_entry_idaction INTEGER(11) NOT NULL,
+							  visit_exit_idaction_url INTEGER(11) NOT NULL,
+							  visit_entry_idaction_url INTEGER(11) NOT NULL,
 							  visit_total_actions SMALLINT(5) UNSIGNED NOT NULL,
 							  visit_total_time SMALLINT(5) UNSIGNED NOT NULL,
 							  visit_goal_converted TINYINT(1) NOT NULL,
@@ -663,7 +664,7 @@ class Piwik
 									  `visitor_idcookie` char(32) NOT NULL,
 									  `server_time` datetime NOT NULL,
 									  `visit_server_date` date NOT NULL,
-									  `idaction` int(11) default NULL,
+									  `idaction_url` int(11) default NULL,
 									  `idlink_va` int(11) default NULL,
 									  `referer_idvisit` int(10) unsigned default NULL,
 									  `referer_visit_server_date` date default NULL,
@@ -684,8 +685,9 @@ class Piwik
 			'log_link_visit_action' => "CREATE TABLE {$prefixTables}log_link_visit_action (
 											  idlink_va INTEGER(11) NOT NULL AUTO_INCREMENT,
 											  idvisit INTEGER(10) UNSIGNED NOT NULL,
-											  idaction INTEGER(10) UNSIGNED NOT NULL,
-											  idaction_ref INTEGER(11) UNSIGNED NOT NULL,
+											  idaction_url INTEGER(10) UNSIGNED NOT NULL,
+											  idaction_url_ref INTEGER(10) UNSIGNED NOT NULL,
+											  idaction_name INTEGER(10) UNSIGNED,
 											  time_spent_ref_action INTEGER(10) UNSIGNED NOT NULL,
 											  PRIMARY KEY(idlink_va),
 											  INDEX index_idvisit(idvisit)
diff --git a/core/Tracker/Action.php b/core/Tracker/Action.php
index 5afe0738cf922bdb67215720fe2b5da30f41f0bf..bd0d924431060a6b7ef25a986db8652a3d506372 100644
--- a/core/Tracker/Action.php
+++ b/core/Tracker/Action.php
@@ -18,9 +18,10 @@
  * @subpackage Piwik_Tracker
  */
 interface Piwik_Tracker_Action_Interface {
-	const TYPE_ACTION   = 1;
+	const TYPE_ACTION_URL   = 1;
 	const TYPE_OUTLINK  = 2;
 	const TYPE_DOWNLOAD = 3;
+	const TYPE_ACTION_NAME = 4;
 	
 	public function setRequest($requestArray);
 	public function setIdSite( $idSite );
@@ -29,7 +30,8 @@ interface Piwik_Tracker_Action_Interface {
 	public function getActionName();
 	public function getActionType();
 	public function record( $idVisit, $idRefererAction, $timeSpentRefererAction );
-	public function getIdAction();
+	public function getIdActionUrl();
+	public function getIdActionName();
 	public function getIdLinkVisitAction();
 }
 
@@ -44,10 +46,6 @@ interface Piwik_Tracker_Action_Interface {
  * - An action is defined by a name.
  * - The name can be specified in the JS Code in the variable 'action_name'
  *    For example you can decide to use the javascript value document.title as an action_name
- * - If the name is not specified, we use the URL(path+query) to build a default name.
- *    For example for "http://piwik.org/test/my_page/test.html" 
- *    the name would be "test/my_page/test.html"
- * - If the name is empty we set it to default_action_name found in global.ini.php
  * - Handling UTF8 in the action name
  * PLUGIN_IDEA - An action is associated to URLs and link to the URL from the reports (currently actions do not link to the url of the pages)
  * PLUGIN_IDEA - An action hit by a visitor is associated to the HTML title of the page that triggered the action and this HTML title is displayed in the interface
@@ -60,16 +58,12 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface
 	private $request;
 	private $idSite;
 	private $idLinkVisitAction;
-	private $idAction = null;
+	private $idActionName = null;
+	private $idActionUrl = null;
 
 	private $actionName;
 	private $actionType;
-	private $url;
-	
-	protected function getDefaultActionName()
-	{
-		return Piwik_Tracker_Config::getInstance()->Tracker['default_action_name'];
-	}
+	private $actionUrl;
 	
 	public function setRequest($requestArray)
 	{
@@ -92,6 +86,29 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface
 	{
 		return $this->actionType;
 	}
+	public function getActionNameType()
+	{
+		$actionNameType = null;
+
+		// we can add here action types for names of other actions than page views (like downloads, outlinks)
+		switch( $this->getActionType() )
+		{
+			case Piwik_Tracker_Action_Interface::TYPE_ACTION_URL:
+				$actionNameType = Piwik_Tracker_Action_Interface::TYPE_ACTION_NAME;
+				break;
+		}
+
+		return $actionNameType;
+	}
+
+	public function getIdActionUrl()
+	{
+		return $this->idActionUrl;
+	}
+	public function getIdActionName()
+	{
+		return $this->idActionName;
+	}
 	
 	protected function setActionName($name)
 	{
@@ -115,44 +132,65 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface
 	}
 	
 	/**
-	 * Returns the idaction of the current action name.
-	 * This idaction is used in the visitor logging table to link the visit information 
+	 * Loads the idaction of the current action name and the current action url.
+	 * These idactions are used in the visitor logging table to link the visit information
 	 * (entry action, exit action) to the actions.
-	 * This idaction is also used in the table that links the visits and their actions.
+	 * These idactions are also used in the table that links the visits and their actions.
 	 * 
-	 * The methods takes care of creating a new record in the action table if the existing 
-	 * action name doesn't exist yet.
+	 * The methods takes care of creating a new record(s) in the action table if the existing
+	 * action name and action url doesn't exist yet.
 	 * 
-	 * @return int Id action that is associated to this action name in the Actions table lookup
 	 */
-	function getIdAction()
+	function loadIdActionNameAndUrl()
 	{
-		if(!is_null($this->idAction))
+		if( !is_null($this->idActionUrl) && !is_null($this->idActionName) )
 		{
-			return $this->idAction;
+			return;
 		}
-		$idAction = Piwik_Tracker::getDatabase()->fetch("/* SHARDING_ID_SITE = ".$this->idSite." */ 	SELECT idaction 
+		$idAction = Piwik_Tracker::getDatabase()->fetchAll("/* SHARDING_ID_SITE = ".$this->idSite." */
+							SELECT idaction, type 
 							FROM ".Piwik_Common::prefixTable('log_action')
-						."  WHERE name = ? AND type = ?", 
-						array($this->getActionName(), $this->getActionType()) 
+						."  WHERE "
+						."		( hash = CRC32(?) AND name = ? AND type = ? ) "
+						."	OR "
+						."		( hash = CRC32(?) AND name = ? AND type = ? ) ",
+						array($this->getActionName(), $this->getActionName(), $this->getActionNameType(),
+							$this->getActionUrl(), $this->getActionUrl(), $this->getActionType())
 					);
-		
-		// the action name has not been found, create it
-		if($idAction === false || $idAction == '')
+
+		if( $idAction !== false )
 		{
-			Piwik_Tracker::getDatabase()->query("/* SHARDING_ID_SITE = ".$this->idSite." */
-							INSERT INTO ". Piwik_Common::prefixTable('log_action'). " ( name, type ) 
-							VALUES (?,?)",
-						array($this->getActionName(),$this->getActionType())
-					);
-			$idAction = Piwik_Tracker::getDatabase()->lastInsertId();
+			foreach($idAction as $row)
+			{
+				if( $row['type'] == Piwik_Tracker_Action_Interface::TYPE_ACTION_NAME )
+				{
+					$this->idActionName = $row['idaction'];
+				}
+				else
+				{
+					$this->idActionUrl = $row['idaction'];
+				}
+			}
 		}
-		else
+
+		$sql = "/* SHARDING_ID_SITE = ".$this->idSite." */ 
+							INSERT INTO ". Piwik_Common::prefixTable('log_action'). 
+							"( name, hash, type ) VALUES (?,CRC32(?),?)";
+
+		if( is_null($this->idActionName) 
+		    && !is_null($this->getActionNameType()) )
 		{
-			$idAction = $idAction['idaction'];
+			Piwik_Tracker::getDatabase()->query($sql,
+				array($this->getActionName(), $this->getActionName(), $this->getActionNameType()));
+			$this->idActionName = Piwik_Tracker::getDatabase()->lastInsertId();
+		}
+
+		if( is_null($this->idActionUrl) )
+		{
+			Piwik_Tracker::getDatabase()->query($sql,
+				array($this->getActionUrl(), $this->getActionUrl(), $this->getActionType()));
+			$this->idActionUrl = Piwik_Tracker::getDatabase()->lastInsertId();
 		}
-		$this->idAction = $idAction;
-		return $this->idAction;
 	}
 	
 	/**
@@ -174,9 +212,11 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface
 	 */
 	 public function record( $idVisit, $idRefererAction, $timeSpentRefererAction)
 	 {
-	 	Piwik_Tracker::getDatabase()->query("/* SHARDING_ID_SITE = ".$this->idSite." */ INSERT INTO ".Piwik_Common::prefixTable('log_link_visit_action')
-						." (idvisit, idaction, idaction_ref, time_spent_ref_action) VALUES (?,?,?,?)",
-					array($idVisit, $this->getIdAction(), $idRefererAction, $timeSpentRefererAction)
+		$this->loadIdActionNameAndUrl();
+
+		Piwik_Tracker::getDatabase()->query("/* SHARDING_ID_SITE = ".$this->idSite." */ INSERT INTO ".Piwik_Common::prefixTable('log_link_visit_action')
+						." (idvisit, idaction_url, idaction_name, idaction_url_ref, time_spent_ref_action) VALUES (?,?,?,?,?)",
+					array($idVisit, $this->getIdActionUrl(), $this->getIdActionName(), $idRefererAction, $timeSpentRefererAction)
 					);
 		
 		$this->idLinkVisitAction = Piwik_Tracker::getDatabase()->lastInsertId(); 
@@ -209,9 +249,13 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface
 	 /**
 	 * Generates the name of the action from the URL or the specified name.
 	 * Sets the name as $this->actionName
+	  *
+	 * @return array
 	 */
 	protected function extractUrlAndActionNameFromRequest()
 	{
+		$actionName = null;
+		
 		// download?
 		$downloadUrl = Piwik_Common::getRequestVar( 'download', '', 'string', $this->request);
 		if(!empty($downloadUrl))
@@ -230,26 +274,15 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface
 				$url = $outlinkUrl;
 			}
 		}
-		
+
+		$actionName = Piwik_Common::getRequestVar( 'action_name', '', 'string', $this->request);
+
 		// defaults to page view 
 		if(empty($actionType))
 		{
-			$actionType = self::TYPE_ACTION;
+			$actionType = self::TYPE_ACTION_URL;
 			$url = Piwik_Common::getRequestVar( 'url', '', 'string', $this->request);
-			$actionName = Piwik_Common::getRequestVar( 'action_name', '', 'string', $this->request);
-			if( empty($actionName) )
-			{
-				$cleanedUrl = str_replace(array("\n", "\r", "\t"), "", $url);
-				$actionName = Piwik_Common::getPathAndQueryFromUrl($cleanedUrl);
-				// in case the $actionName is empty or ending with a slash, 
-				// we append the defaultActionName: a/b/ becomes a/b/index 
-				if(empty($actionName)
-					|| substr($actionName, -1) == '/')
-				{
-					$actionName .= $this->getDefaultActionName();
-				}
-			}
-			
+
 			// get the delimiter, by default '/'
 			$actionCategoryDelimiter = Piwik_Tracker_Config::getInstance()->General['action_category_delimiter'];
 			
@@ -268,13 +301,12 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface
 		
 		$url = trim($url);
 		$url = str_replace(array("\n", "\r"), "", $url);
-		if(empty($actionName))
-		{
-			$actionName = $url;
-		}
+
+		$actionName = trim($actionName);
+		$actionName = str_replace(array("\n", "\r"), "", $actionName);
 
 		return array(
-			'name' => $actionName,
+			'name' => empty($actionName) ? '' : $actionName,
 			'type' => $actionType,
 			'url'  => $url,
 		);
diff --git a/core/Tracker/Generator.php b/core/Tracker/Generator.php
index d0e5f016d2ee2b64b83223c9c5fce8dd1cb57f77..7a6dfdfe2193f3c27cb3d1ccd92667a98765b912 100644
--- a/core/Tracker/Generator.php
+++ b/core/Tracker/Generator.php
@@ -220,11 +220,11 @@ class Piwik_Tracker_Generator
 	 */
 	public function end()
 	{
-		Piwik_Tracker::disconnectDatabase();
 		if($this->profiling)
 		{
 			Piwik::printSqlProfilingReportTracker();
 		}
+		Piwik_Tracker::disconnectDatabase();
 	}
 	
 	/**
@@ -446,19 +446,12 @@ class Piwik_Tracker_Generator
 				// add the parameter to the url
 				$this->setCurrentRequest( $GETParamToAdd , $urlValue);
 			}
-			
-			// if we didn't set any campaign NOR any download click
-			// then we sometimes set a special action name to the current action
-			elseif(rand(0,2)==1)
-			{
-				$this->setCurrentRequest( 'action_name' , $this->getRandomString(1,1));
-			}
 		}
 		
 		$this->setCurrentRequest( 'url' ,$url);
 		
 		// setup the title of the page
-		$this->setCurrentRequest( 'title',$this->getRandomString(15,5));
+		$this->setCurrentRequest( 'action_name',$this->getRandomString(15,5));
 	}
 	
 	/**
diff --git a/core/Tracker/GoalManager.php b/core/Tracker/GoalManager.php
index 4dc148d86cd9ee2281e04af7c18b2a30c832b7cd..f1ff810891d6577fe07c9692cb7d6a5db0f128c4 100644
--- a/core/Tracker/GoalManager.php
+++ b/core/Tracker/GoalManager.php
@@ -17,7 +17,7 @@
 class Piwik_Tracker_GoalManager 
 {
 	/**
-	 * @var Piwik_Cookie 
+	 * @var Piwik_Cookie
 	 */
 	protected $cookie = null;
 	/**
@@ -41,7 +41,7 @@ class Piwik_Tracker_GoalManager
 		}
 		return array();
 	}
-	
+
 	static public function getGoalDefinition( $idSite, $idGoal )
 	{
 		$goals = self::getGoalDefinitions( $idSite );
@@ -54,7 +54,7 @@ class Piwik_Tracker_GoalManager
 		}
 		throw new Exception("The goal id = $idGoal couldn't be found.");
 	}
-	
+
 	static public function getGoalIds( $idSite )
 	{
 		$goals = self::getGoalDefinitions( $idSite );
@@ -65,13 +65,13 @@ class Piwik_Tracker_GoalManager
 		}
 		return $goalIds;
 	}
-	
+
 	private function isGoalPluginEnabled()
 	{
 		return Piwik_PluginsManager::getInstance()->isPluginActivated('Goals');
 	}
-	
-	//TODO does this code work for manually triggered goals, with custom revenue? 
+
+	//TODO does this code work for manually triggered goals, with custom revenue?
 	function detectGoalsMatchingUrl($idSite, $action)
 	{
 		if(!$this->isGoalPluginEnabled())
@@ -85,7 +85,7 @@ class Piwik_Tracker_GoalManager
 		{
 			$attribute = $goal['match_attribute'];
 			// if the attribute to match is not the type of the current action
-			if(		($actionType == Piwik_Tracker_Action::TYPE_ACTION && $attribute != 'url')
+			if(		($actionType == Piwik_Tracker_Action::TYPE_ACTION_URL && $attribute != 'url')
 				||	($actionType == Piwik_Tracker_Action::TYPE_DOWNLOAD && $attribute != 'file')
 				||	($actionType == Piwik_Tracker_Action::TYPE_OUTLINK && $attribute != 'external_website')
 				||	($attribute == 'manually')
@@ -93,9 +93,9 @@ class Piwik_Tracker_GoalManager
 			{
 				continue;
 			}
-			
+
 			$pattern_type = $goal['pattern_type'];
-			
+
 			switch($pattern_type)
 			{
 				case 'regex':
@@ -141,7 +141,7 @@ class Piwik_Tracker_GoalManager
 //		var_dump($this->convertedGoals);exit;
 		return count($this->convertedGoals) > 0;
 	}
-	
+
 	function detectGoalId($idSite, $idGoal, $request)
 	{
 		if(!$this->isGoalPluginEnabled())
@@ -159,12 +159,12 @@ class Piwik_Tracker_GoalManager
 		$this->convertedGoals[] = $goal;
 		return true;
 	}
-	
+
 	function recordGoals($visitorInformation, $action)
 	{
 		$location_country = isset($visitorInformation['location_country']) ? $visitorInformation['location_country'] : Piwik_Common::getCountry(Piwik_Common::getBrowserLanguage(), $enableLanguageToCountryGuess = Piwik_Tracker_Config::getInstance()->Tracker['enable_language_to_country_guess']);
 		$location_continent = isset($visitorInformation['location_continent']) ? $visitorInformation['location_continent'] : Piwik_Common::getContinent($location_country);
-		
+
 		$goal = array(
 			'idvisit' 			=> $visitorInformation['idvisit'],
 			'idsite' 			=> $visitorInformation['idsite'],
@@ -197,18 +197,18 @@ class Piwik_Tracker_GoalManager
 			$newGoal['revenue'] = $convertedGoal['revenue'];
 			if(!is_null($action))
 			{
-				$newGoal['idaction'] = $action->getIdAction();
+				$newGoal['idaction_url'] = $action->getIdActionUrl();
 				$newGoal['idlink_va'] = $action->getIdLinkVisitAction();
 			}
 			printDebug($newGoal);
-			
+
 			$fields = implode(", ", array_keys($newGoal));
 			$bindFields = substr(str_repeat( "?,",count($newGoal)),0,-1);
-			
+
 			try {
 				Piwik_Tracker::getDatabase()->query(
-					"INSERT INTO " . Piwik_Common::prefixTable('log_conversion') . "	($fields) 
-					VALUES ($bindFields) ", array_values($newGoal) 
+					"INSERT INTO " . Piwik_Common::prefixTable('log_conversion') . "	($fields)
+					VALUES ($bindFields) ", array_values($newGoal)
 				);
 			} catch( Exception $e) {
 				if(Piwik_Tracker::isErrNo($e, '1062'))
@@ -221,7 +221,6 @@ class Piwik_Tracker_GoalManager
 					throw $e;
 				}
 			}
-			//$idlog_goal = Piwik_Tracker::getDatabase()->lastInsertId();
 		}
 	}
 }
diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php
index 323a720806f890ecf1edaec8691f75c0f2f761e8..2b50bd1baf48c56a72a2ebe4b9fd13b47fe36a9c 100644
--- a/core/Tracker/Visit.php
+++ b/core/Tracker/Visit.php
@@ -95,7 +95,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 
 		$goalManager = new Piwik_Tracker_GoalManager();
 		$someGoalsConverted = false;
-		$actionId = 0;
+		$actionUrlId = 0;
 		$action = null;
 
 		$idGoal = Piwik_Common::getRequestVar('idgoal', 0, 'int', $this->request);
@@ -116,7 +116,9 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 			$action = $this->newAction();
 			$this->handleAction($action);
 			$someGoalsConverted = $goalManager->detectGoalsMatchingUrl($this->idsite, $action);
-			$actionId = $action->getIdAction();
+
+			$action->loadIdActionNameAndUrl();
+			$actionUrlId = $action->getIdActionUrl();
 		}
 
 		// the visitor and session
@@ -133,9 +135,9 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 		if( $this->isVisitorKnown()
 			&& $isLastActionInTheSameVisit)
 		{
-			$idActionReferer = $this->visitorInfo['visit_exit_idaction'];
+			$idActionReferer = $this->visitorInfo['visit_exit_idaction_url'];
 			try {
-				$this->handleKnownVisit($actionId, $someGoalsConverted);
+				$this->handleKnownVisit($actionUrlId, $someGoalsConverted);
 				if(!is_null($action))
 				{
 					$action->record( 	$this->visitorInfo['idvisit'],
@@ -156,7 +158,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 		if(!$this->isVisitorKnown()
 			|| !$isLastActionInTheSameVisit)
 		{
-			$this->handleNewVisit($actionId, $someGoalsConverted);
+			$this->handleNewVisit($actionUrlId, $someGoalsConverted);
 				if(!is_null($action))
 			{
 				$action->record( $this->visitorInfo['idvisit'], 0, 0 );
@@ -189,7 +191,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 		if(isset($GLOBALS['PIWIK_TRACKER_DEBUG']) && $GLOBALS['PIWIK_TRACKER_DEBUG'])
 		{
 			switch($action->getActionType()) {
-				case Piwik_Tracker_Action::TYPE_ACTION:
+				case Piwik_Tracker_Action::TYPE_ACTION_URL:
 					$type = "normal page view";
 					break;
 				case Piwik_Tracker_Action::TYPE_DOWNLOAD:
@@ -211,7 +213,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 	 *
 	 * 2) Update the visit information
 	 */
-	protected function handleKnownVisit($actionId, $someGoalsConverted)
+	protected function handleKnownVisit($actionUrlId, $someGoalsConverted)
 	{
 		$serverTime 	= $this->getCurrentTimestamp();
 		$datetimeServer = Piwik_Tracker::getDatetimeFromTimestamp($serverTime);
@@ -224,13 +226,12 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 		}
 
 		$sqlActionIdUpdate = '';
-		if(!empty($actionId))
+		if(!empty($actionUrlId))
 		{
-			$sqlActionIdUpdate = "visit_exit_idaction = ". $actionId .",
+			$sqlActionIdUpdate = "visit_exit_idaction_url = ". $actionUrlId .",
 									visit_total_actions = visit_total_actions + 1, ";
-			$this->visitorInfo['visit_exit_idaction'] = $actionId;
+			$this->visitorInfo['visit_exit_idaction_url'] = $actionUrlId;
 		}
-
 		$result = Piwik_Tracker::getDatabase()->query("/* SHARDING_ID_SITE = ". $this->idsite ." */
 							UPDATE ". Piwik_Common::prefixTable('log_visit')."
 							SET $sqlActionIdUpdate
@@ -244,7 +245,6 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 									$this->visitorInfo['idvisit'],
 									$this->visitorInfo['visitor_idcookie'] )
 				);
-
 		if(Piwik_Tracker::getDatabase()->rowCount($result) == 0)
 		{
 			throw new Piwik_Tracker_Visit_VisitorNotFoundInDatabase("The visitor with visitor_idcookie=".$this->visitorInfo['visitor_idcookie']." and idvisit=".$this->visitorInfo['idvisit']." wasn't found in the DB, we fallback to a new visitor");
@@ -267,7 +267,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 	 *
 	 * 2) Insert the visit information
 	 */
-	protected function handleNewVisit($actionId, $someGoalsConverted)
+	protected function handleNewVisit($actionUrlId, $someGoalsConverted)
 	{
 		printDebug("New Visit.");
 
@@ -297,8 +297,8 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 			'visit_first_action_time' => Piwik_Tracker::getDatetimeFromTimestamp($serverTime),
 			'visit_last_action_time' =>  Piwik_Tracker::getDatetimeFromTimestamp($serverTime),
 			'visit_server_date' 	=> $serverDate,
-			'visit_entry_idaction' 	=> $actionId,
-			'visit_exit_idaction' 	=> $actionId,
+			'visit_entry_idaction_url' => $actionUrlId,
+			'visit_exit_idaction_url' => $actionUrlId,
 			'visit_total_actions' 	=> 1,
 			'visit_total_time' 		=> $defaultTimeOnePageVisit,
 			'visit_goal_converted'  => $someGoalsConverted ? 1: 0,
@@ -531,7 +531,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 				$this->visitorInfo['visit_last_action_time'] = $timestampLastAction;
 				$this->visitorInfo['visit_first_action_time'] = $timestampFirstAction;
 				$this->visitorInfo['idvisit'] = $idVisit;
-				$this->visitorInfo['visit_exit_idaction'] = $idLastAction;
+				$this->visitorInfo['visit_exit_idaction_url'] = $idLastAction;
 
 				$this->visitorKnown = true;
 
@@ -569,7 +569,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 				$this->visitorInfo['visit_last_action_time'] = $visitRow['visit_last_action_time'];
 				$this->visitorInfo['visit_first_action_time'] = $visitRow['visit_first_action_time'];
 				$this->visitorInfo['idvisit'] = $visitRow['idvisit'];
-				$this->visitorInfo['visit_exit_idaction'] = $visitRow['visit_exit_idaction'];
+				$this->visitorInfo['visit_exit_idaction_url'] = $visitRow['visit_exit_idaction_url'];
 
 				$this->visitorKnown = true;
 
@@ -719,10 +719,10 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
 								$this->visitorInfo['idvisit'] );
 
 		// the last action ID is the current exit idaction
-		if(isset($this->visitorInfo['visit_exit_idaction'] ))
+		if(isset($this->visitorInfo['visit_exit_idaction_url'] ))
 		{
 			$this->cookie->set( 	Piwik_Tracker::COOKIE_INDEX_ID_LAST_ACTION,
-								$this->visitorInfo['visit_exit_idaction'] );
+								$this->visitorInfo['visit_exit_idaction_url'] );
 		}
 
 		// for a new visit, we flag the visit with visitor_returning
diff --git a/core/Updates/0.5.php b/core/Updates/0.5.php
new file mode 100644
index 0000000000000000000000000000000000000000..108e651617af8df95437d82380f9a33f869d6c9d
--- /dev/null
+++ b/core/Updates/0.5.php
@@ -0,0 +1,33 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html Gpl v3 or later
+ * @version $Id$
+ *
+ * @category Piwik
+ * @package Updates
+ */
+
+/**
+ * @package Updates
+ */
+class Piwik_Updates_0_5 implements Piwik_iUpdate
+{
+	static function update()
+	{
+		Piwik_Updater::updateDatabase(__FILE__, array(
+			'ALTER TABLE ' . Piwik::prefixTable('log_action'). ' ADD COLUMN `hash` INTEGER(10) UNSIGNED NOT NULL AFTER `name`;' => false,
+			'UPDATE '.  Piwik::prefixTable('log_action'). ' SET `hash` = CRC32(name);' => false,
+			'CREATE INDEX index_type_hash ON '. Piwik::prefixTable('log_action') .' (type, hash);' => false,
+			'DROP INDEX index_type_name ON '. Piwik::prefixTable('log_action') .';' => false,
+			'ALTER TABLE '. Piwik::prefixTable('log_visit') .' CHANGE visit_exit_idaction visit_exit_idaction_url INTEGER(11) NOT NULL;' => false,
+			'ALTER TABLE '. Piwik::prefixTable('log_visit') .' CHANGE visit_entry_idaction visit_entry_idaction_url INTEGER(11) NOT NULL;' => false,
+			'ALTER TABLE ' . Piwik::prefixTable('log_link_visit_action'). ' CHANGE `idaction_ref` `idaction_url_ref` INTEGER(10) UNSIGNED NOT NULL;' => false,
+			'ALTER TABLE ' . Piwik::prefixTable('log_link_visit_action'). ' CHANGE `idaction` `idaction_url` INTEGER(10) UNSIGNED NOT NULL;' => false,
+			'ALTER TABLE ' . Piwik::prefixTable('log_link_visit_action'). ' ADD COLUMN `idaction_name` INTEGER(10) UNSIGNED AFTER `idaction_url_ref`;' => false,
+			'ALTER TABLE ' . Piwik::prefixTable('log_conversion'). ' CHANGE `idaction` `idaction_url` INTEGER(11) UNSIGNED NOT NULL;' => false,
+		));
+	}
+}
diff --git a/core/Version.php b/core/Version.php
index 824001fe868bdefbbde5e1f40a7ac2cf5f2efd70..26e24c4dfc8cf7d082b1562cc9b4eba225a216a9 100644
--- a/core/Version.php
+++ b/core/Version.php
@@ -17,5 +17,5 @@
  */
 final class Piwik_Version
 {
-	const VERSION = '0.4.5';
+	const VERSION = '0.5';
 }
diff --git a/lang/en.php b/lang/en.php
index ba611f0103825e96d8f0e42fd0aa86ef0ed56f1c..c393c91e4358f72d39876679a718471d400f6090 100644
--- a/lang/en.php
+++ b/lang/en.php
@@ -200,6 +200,7 @@ $translations = array(
 	'CoreUpdater_ExceptionArchiveIncomplete' => 'Archive is incomplete: some files are missing (eg. %s).',
 	'Actions_Actions' => 'Actions',
 	'Actions_SubmenuPages' => 'Pages',
+	'Actions_SubmenuPageTitles' => 'Page titles',
 	'Actions_SubmenuOutlinks' => 'Outlinks',
 	'Actions_SubmenuDownloads' => 'Downloads',
 	'Actions_ColumnClicks' => 'Clicks',
@@ -207,6 +208,7 @@ $translations = array(
 	'Actions_ColumnDownloads' => 'Downloads',
 	'Actions_ColumnUniqueDownloads' => 'Unique Downloads',
 	'Actions_ColumnPageName' => 'Page Name',
+	'Actions_ColumnPageURL' => 'Page URL',
 	'Actions_ColumnClickedURL' => 'Clicked URL',
 	'Actions_ColumnDownloadURL' => 'Download URL',
 	'Dashboard_Dashboard' => 'Dashboard',
diff --git a/misc/generateVisits.php b/misc/generateVisits.php
index a2d2689129abfa0efb0b5e2dd03bc6fa70d9f4e7..35dec2be442ddb62042c4045e8604a491f5ec0e5 100644
--- a/misc/generateVisits.php
+++ b/misc/generateVisits.php
@@ -9,12 +9,29 @@ if(file_exists('../bootstrap.php'))
 	require_once '../bootstrap.php';
 }
 
+if(empty($_GET['choice']) || $_GET['choice'] != 'yes') {
+    echo "<div style='color:red;font-size:large'>WARNING!</div> <br>You are about to generate fake visits which will be recorded in your Piwik database.
+    <br>It will <b>not</b> be possible to easily delete these visits from the piwik logs.
+    <br><br>Are you sure you want to generate fake visits?
+    <br><br>
+    <a href='../index.php'><b>NO</b>, I do not want to generate fake visits</a>
+    <br><br>
+    <a href='?choice=yes'><b>YES</b>, I want to generate fake visits</a>
+    <br><br>
+    Note: you can edit the source code of this file to specify how many visits to generate, how many days, etc.
+	";
+    return;
+}
+
+
 // TODO - generator should generate pages with slash, then test that period archiving doesn't show the unique page view
 // TODO - should generate goals with keyword or referer that are not found for this day, to simulate a referer 5 days ago and conversion today
-$minVisitors = 200;
-$maxVisitors = 200;
+$minVisitors = 20;
+$maxVisitors = 100;
 $nbActions = 10;
-$daysToCompute = 5;
+$daysToCompute = 1;
+$idSite = 1;
+
 
 //-----------------------------------------------------------------------------
 error_reporting(E_ALL|E_NOTICE);
@@ -42,8 +59,7 @@ require_once PIWIK_INCLUDE_PATH . "/index.php";
 require_once "FrontController.php";
 
 Piwik::setMaxExecutionTime(0);
-
-$idSite = Piwik_Common::getRequestVar('idSite', 1, 'int');
+$idSite = Piwik_Common::getRequestVar('idSite', $idSite, 'int');
 
 try {
 	Piwik_FrontController::getInstance()->init();
diff --git a/plugins/Actions/API.php b/plugins/Actions/API.php
index 8a9851cf309a29adec8d71a3b6dc77db6e3de7ed..658d5da13ff3010883810596e7c8eebad3c4fd5d 100644
--- a/plugins/Actions/API.php
+++ b/plugins/Actions/API.php
@@ -50,10 +50,25 @@ class Piwik_Actions_API
 		$dataTable->queueFilter('ReplaceSummaryRowLabel');
 		return $dataTable;
 	}
-	
+
+	/**
+	 * Backward compatibility. Fallsback to getPageTitles() instead.
+	 * @deprecated Deprecated since Piwik 0.5
+	 */
 	public function getActions( $idSite, $period, $date, $expanded = false, $idSubtable = false )
 	{
-		return $this->getDataTable('Actions_actions', $idSite, $period, $date, $expanded, $idSubtable );
+	    return $this->getPageTitles( $idSite, $period, $date, $expanded, $idSubtable );
+	}
+	
+	public function getPageUrls( $idSite, $period, $date, $expanded = false, $idSubtable = false )
+	{
+		return $this->getDataTable('Actions_actions_url', $idSite, $period, $date, $expanded, $idSubtable );
+	}
+
+	public function getPageTitles( $idSite, $period, $date, $expanded = false, $idSubtable = false)
+	{
+		$dataTable = $this->getDataTable('Actions_actions', $idSite, $period, $date, $expanded, $idSubtable);
+		return $dataTable;
 	}
 
 	public function getDownloads( $idSite, $period, $date, $expanded = false, $idSubtable = false )
diff --git a/plugins/Actions/Actions.php b/plugins/Actions/Actions.php
index 1fc9d2c19e5c3b092a063ced0774f1354c54cd1f..199726675a42449361d106704d0a04b8423981c3 100644
--- a/plugins/Actions/Actions.php
+++ b/plugins/Actions/Actions.php
@@ -20,6 +20,9 @@
 class Piwik_Actions extends Piwik_Plugin
 {
 	static protected $actionCategoryDelimiter = null;
+	static protected $defaultActionName = null;
+	static protected $defaultActionNameWhenNotDefined = null;
+	static protected $defaultActionUrlWhenNotDefined = null;
 	static protected $limitLevelSubCategory = 10; // must be less than Piwik_DataTable::MAXIMUM_DEPTH_LEVEL_ALLOWED
 	protected $maximumRowsInDataTableLevelZero;
 	protected $maximumRowsInSubDataTable;
@@ -47,9 +50,13 @@ class Piwik_Actions extends Piwik_Plugin
 		);
 		return $hooks;
 	}
+	
 	public function __construct()
 	{
 		self::$actionCategoryDelimiter =  Zend_Registry::get('config')->General->action_category_delimiter;
+		self::$defaultActionName = Zend_Registry::get('config')->General->action_default_name;
+		self::$defaultActionNameWhenNotDefined = Zend_Registry::get('config')->General->action_default_name_when_not_defined;
+		self::$defaultActionUrlWhenNotDefined = Zend_Registry::get('config')->General->action_default_url_when_not_defined;
 		$this->columnToSortByBeforeTruncation = 'nb_visits';
 		$this->maximumRowsInDataTableLevelZero = Zend_Registry::get('config')->General->datatable_archiving_maximum_rows_actions;
 		$this->maximumRowsInSubDataTable = Zend_Registry::get('config')->General->datatable_archiving_maximum_rows_subtable_actions;
@@ -57,16 +64,18 @@ class Piwik_Actions extends Piwik_Plugin
 	
 	function addWidgets()
 	{
-		Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuPages', 'Actions', 'getActions');
+		Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuPages', 'Actions', 'getPageUrls');
+		Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuPageTitles', 'Actions', 'getPageTitles');
 		Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuOutlinks', 'Actions', 'getOutlinks');
 		Piwik_AddWidget( 'Actions_Actions', 'Actions_SubmenuDownloads', 'Actions', 'getDownloads');
 	}
 	
 	function addMenus()
 	{
-		Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPages', array('module' => 'Actions', 'action' => 'getActions'));
+		Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPages', array('module' => 'Actions', 'action' => 'getPageUrls'));
+		Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuPageTitles', array('module' => 'Actions', 'action' => 'getPageTitles'));
 		Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuOutlinks', array('module' => 'Actions', 'action' => 'getOutlinks'));
-		Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuDownloads', array('module' => 'Actions', 'action' => 'getDownloads'));		
+		Piwik_AddMenu('Actions_Actions', 'Actions_SubmenuDownloads', array('module' => 'Actions', 'action' => 'getDownloads'));
 	}
 	
 	static protected $invalidSummedColumnNameToRenamedNameForPeriodArchive = array(
@@ -88,6 +97,7 @@ class Piwik_Actions extends Piwik_Plugin
 				'Actions_actions',
 				'Actions_downloads',
 				'Actions_outlink',
+				'Actions_actions_url',
 		);
 		$archiveProcessing->archiveDataTable($dataTableToSum, self::$invalidSummedColumnNameToRenamedNameForPeriodArchive, $this->maximumRowsInDataTableLevelZero, $this->maximumRowsInSubDataTable, $this->columnToSortByBeforeTruncation);
 	}
@@ -106,9 +116,10 @@ class Piwik_Actions extends Piwik_Plugin
 		$archiveProcessing = $notification->getNotificationObject();
 		
 		$this->actionsTablesByType = array(
-			Piwik_Tracker_Action::TYPE_ACTION => array(),
+			Piwik_Tracker_Action::TYPE_ACTION_URL => array(),
 			Piwik_Tracker_Action::TYPE_DOWNLOAD => array(),
 			Piwik_Tracker_Action::TYPE_OUTLINK => array(),
+			Piwik_Tracker_Action::TYPE_ACTION_NAME => array(),
 		);
 		
 		// This row is used in the case where an action is know as an exit_action
@@ -122,7 +133,7 @@ class Piwik_Actions extends Piwik_Plugin
 										)));
 
 		/*
-		 * Actions global information
+		 * Actions urls global information
 		 */
 		$query = "SELECT 	name,
 							type,
@@ -131,7 +142,25 @@ class Piwik_Actions extends Piwik_Plugin
 							count(*) as nb_hits							
 					FROM (".$archiveProcessing->logTable." as t1
 						LEFT JOIN ".$archiveProcessing->logVisitActionTable." as t2 USING (idvisit))
-							LEFT JOIN ".$archiveProcessing->logActionTable." as t3 USING (idaction)
+							LEFT JOIN ".$archiveProcessing->logActionTable." as t3 ON (t2.idaction_url = t3.idaction)
+					WHERE visit_server_date = ?
+						AND idsite = ?
+					GROUP BY t3.idaction
+					ORDER BY nb_hits DESC";
+		$query = $archiveProcessing->db->query($query, array( $archiveProcessing->strDateStart, $archiveProcessing->idsite ));
+		$modified = $this->updateActionsTableWithRowQuery($query);
+
+		/*
+		 * Actions names global information
+		 */
+		$query = "SELECT 	name,
+							type,
+							count(distinct t1.idvisit) as nb_visits,
+							count(distinct visitor_idcookie) as nb_uniq_visitors,
+							count(*) as nb_hits
+					FROM (".$archiveProcessing->logTable." as t1
+						LEFT JOIN ".$archiveProcessing->logVisitActionTable." as t2 USING (idvisit))
+							LEFT JOIN ".$archiveProcessing->logActionTable." as t3 ON (t2.idaction_name = t3.idaction)
 					WHERE visit_server_date = ?
 						AND idsite = ?
 					GROUP BY t3.idaction
@@ -139,7 +168,6 @@ class Piwik_Actions extends Piwik_Plugin
 		$query = $archiveProcessing->db->query($query, array( $archiveProcessing->strDateStart, $archiveProcessing->idsite ));
 		$modified = $this->updateActionsTableWithRowQuery($query);
 
-		
 		/*
 		 * Entry actions
 		 */
@@ -151,10 +179,10 @@ class Piwik_Actions extends Piwik_Plugin
 							sum(visit_total_time) as entry_sum_visit_length,							
 							sum(case visit_total_actions when 1 then 1 else 0 end) as entry_bounce_count
 					FROM ".$archiveProcessing->logTable." 
-						JOIN ".$archiveProcessing->logActionTable." ON (visit_entry_idaction = idaction)
+						JOIN ".$archiveProcessing->logActionTable." ON (visit_entry_idaction_url = idaction)
 					WHERE visit_server_date = ?
 						AND idsite = ?
-					GROUP BY visit_entry_idaction
+					GROUP BY visit_entry_idaction_url
 					";
 		$query = $archiveProcessing->db->query($query, array( $archiveProcessing->strDateStart, $archiveProcessing->idsite ));
 		$modified = $this->updateActionsTableWithRowQuery($query);
@@ -169,10 +197,10 @@ class Piwik_Actions extends Piwik_Plugin
 							count(*) as exit_nb_visits,
 							sum(case visit_total_actions when 1 then 1 else 0 end) as exit_bounce_count
 				 	FROM ".$archiveProcessing->logTable." 
-						JOIN ".$archiveProcessing->logActionTable." ON (visit_exit_idaction = idaction)
+						JOIN ".$archiveProcessing->logActionTable." ON (visit_exit_idaction_url = idaction)
 				 	WHERE visit_server_date = ?
 				 		AND idsite = ?
-				 	GROUP BY visit_exit_idaction
+				 	GROUP BY visit_exit_idaction_url
 					";
 		$query = $archiveProcessing->db->query($query, array( $archiveProcessing->strDateStart, $archiveProcessing->idsite ));
 		$modified = $this->updateActionsTableWithRowQuery($query);
@@ -185,10 +213,10 @@ class Piwik_Actions extends Piwik_Plugin
 							sum(time_spent_ref_action) as sum_time_spent
 					FROM (".$archiveProcessing->logTable." log_visit 
 						JOIN ".$archiveProcessing->logVisitActionTable." log_link_visit_action USING (idvisit))
-							JOIN ".$archiveProcessing->logActionTable."  log_action ON (log_action.idaction = log_link_visit_action.idaction_ref)				 	
+							JOIN ".$archiveProcessing->logActionTable."  log_action ON (log_action.idaction = log_link_visit_action.idaction_url_ref)
 					WHERE visit_server_date = ?
 				 		AND idsite = ?
-				 	GROUP BY idaction_ref
+				 	GROUP BY idaction_url_ref
 				";
 		$query = $archiveProcessing->db->query($query, array( $archiveProcessing->strDateStart, $archiveProcessing->idsite ));
 		$modified = $this->updateActionsTableWithRowQuery($query);
@@ -197,10 +225,10 @@ class Piwik_Actions extends Piwik_Plugin
 
 	protected function archiveDayRecordInDatabase($archiveProcessing)
 	{
-		$dataTable = Piwik_ArchiveProcessing_Day::generateDataTable($this->actionsTablesByType[Piwik_Tracker_Action::TYPE_ACTION]);
+		$dataTable = Piwik_ArchiveProcessing_Day::generateDataTable($this->actionsTablesByType[Piwik_Tracker_Action::TYPE_ACTION_URL]);
 		$this->deleteInvalidSummedColumnsFromDataTable($dataTable);
 		$s = $dataTable->getSerialized( $this->maximumRowsInDataTableLevelZero, $this->maximumRowsInSubDataTable, $this->columnToSortByBeforeTruncation );
-		$archiveProcessing->insertBlobRecord('Actions_actions', $s);
+		$archiveProcessing->insertBlobRecord('Actions_actions_url', $s);
 		destroy($dataTable);
 
 		$dataTable = Piwik_ArchiveProcessing_Day::generateDataTable($this->actionsTablesByType[Piwik_Tracker_Action::TYPE_DOWNLOAD]);
@@ -215,6 +243,12 @@ class Piwik_Actions extends Piwik_Plugin
 		$archiveProcessing->insertBlobRecord('Actions_outlink', $s);
 		destroy($dataTable);
 
+		$dataTable = Piwik_ArchiveProcessing_Day::generateDataTable($this->actionsTablesByType[Piwik_Tracker_Action::TYPE_ACTION_NAME]);
+		$this->deleteInvalidSummedColumnsFromDataTable($dataTable);
+		$s = $dataTable->getSerialized( $this->maximumRowsInDataTableLevelZero, $this->maximumRowsInSubDataTable, $this->columnToSortByBeforeTruncation );
+		$archiveProcessing->insertBlobRecord('Actions_actions', $s);
+		destroy($dataTable);
+
 		unset($this->actionsTablesByType);
 	}
 	
@@ -232,30 +266,84 @@ class Piwik_Actions extends Piwik_Plugin
 			}
 		}
 	}
+	
+	/**
+	 * Explodes action name into an array of elements.
+	 *
+	 * for downloads:
+	 *  we explode link http://piwik.org/some/path/piwik.zip into an array( 'piwik.org', '/some/path/piwik.zip' );
+	 *
+	 * for outlinks:
+	 *  we explode link http://dev.piwik.org/some/path into an array( 'dev.piwik.org', '/some/path' );
+	 *
+	 * for action urls:
+	 *  we explode link http://piwik.org/some/path into an array( 'some', 'path' );
+	 *
+	 * for action names:
+	 *   we explode name 'Piwik / Category 1 / Category 2' into an array('Piwik', 'Category 1', 'Category 2');
+	 *
+	 * @param string action name
+	 * @param int action type
+	 * @return array of exploded elements from $name
+	 */
 	static public function getActionExplodedNames($name, $type)
 	{
+		$matches = array();
+		$isUrl = false;
+		
+		preg_match('@^http[s]?://([^/]+)[/]?([^#]*)[#]?(.*)$@i', $name, $matches);
+
+		if( count($matches) )
+		{
+			$isUrl = true;
+			$urlHost = $matches[1];
+			$urlPath = $matches[2];
+			$urlAnchor = $matches[3];
+		}
+		
 		if($type == Piwik_Tracker_Action::TYPE_DOWNLOAD
 			|| $type == Piwik_Tracker_Action::TYPE_OUTLINK)
 		{
-			$matches = $split_arr = array();
-			//TODO optimize with substring count rather than preg_match
-			if(preg_match("#://[^/]+(/)#", $name, $matches, PREG_OFFSET_CAPTURE))
+			if( $isUrl )
+			{
+				return array($urlHost, '/' . $urlPath);
+			}
+		}
+
+		if( $isUrl )
+		{
+			$name = $urlPath;
+			
+			if( empty($name) || substr($name, -1) == '/' )
 			{
-				$host = substr($name, 0, $matches[1][1]);
-				return array($host, substr($name, strlen($host)));
+				$name .= self::$defaultActionName;
 			}
-			return array($name, "/");
 		}
+		
 		if(empty(self::$actionCategoryDelimiter))
 		{
-			return array($name);
+			return array( trim($name) );
+		}
+
+		$split = explode(self::$actionCategoryDelimiter, $name, self::$limitLevelSubCategory);
+
+		// trim every category and remove empty categories
+		$split = array_map('trim', $split);
+		$split = array_filter($split, 'strlen');
+
+		if( empty($split) )
+		{
+		    if($type == Piwik_Tracker_Action::TYPE_ACTION_NAME) {
+		        $defaultName = self::$defaultActionNameWhenNotDefined;
+		    } else {
+		        $defaultName = self::$defaultActionUrlWhenNotDefined;
+		    }
+			return array( $defaultName );
 		}
-		return explode(	self::$actionCategoryDelimiter, 
-						$name, 
-						self::$limitLevelSubCategory);
+
+		return array_values( $split );
 	}
 	
-	
 	protected function updateActionsTableWithRowQuery($query)
 	{
 		$rowsProcessed = 0;
@@ -265,7 +353,7 @@ class Piwik_Actions extends Piwik_Plugin
 
 			// we work on the root table of the given TYPE (either ACTION or DOWNLOAD or OUTLINK etc.)
 			$currentTable =& $this->actionsTablesByType[$row['type']];
-			
+
 			// go to the level of the subcategory
 			$end = count($actionExplodedNames)-1;
 			for($level = 0 ; $level < $end; $level++)
@@ -274,15 +362,19 @@ class Piwik_Actions extends Piwik_Plugin
 				$currentTable =& $currentTable[$actionCategory];
 			}
 			$actionName = $actionExplodedNames[$end];
-			
-			// we are careful to prefix the pageName with some value 
+
+			// we are careful to prefix the page URL / name with some value
 			// so that if a page has the same name as a category 
 			// we don't merge both entries 
-			if($row['type'] == Piwik_Tracker_Action::TYPE_ACTION)
+			if($row['type'] == Piwik_Tracker_Action::TYPE_ACTION_URL )
 			{
 				$actionName = '/' . $actionName;
 			}
-						
+			else if( $row['type'] == Piwik_Tracker_Action::TYPE_ACTION_NAME )
+			{
+				$actionName = ' ' . $actionName;
+			}
+
 			// currentTable is now the array element corresponding the the action
 			// at this point we may be for example at the 4th level of depth in the hierarchy
 			$currentTable =& $currentTable[$actionName];
@@ -290,10 +382,19 @@ class Piwik_Actions extends Piwik_Plugin
 			// add the row to the matching sub category subtable
 			if(!($currentTable instanceof Piwik_DataTable_Row))
 			{
-				$currentTable = new Piwik_DataTable_Row(array(	
+				if( $row['type'] == Piwik_Tracker_Action::TYPE_ACTION_NAME )
+				{
+					$currentTable = new Piwik_DataTable_Row(array(
+							Piwik_DataTable_Row::COLUMNS => array('label' => (string)$actionName),
+						));	
+				}
+				else
+				{
+					$currentTable = new Piwik_DataTable_Row(array(
 							Piwik_DataTable_Row::COLUMNS => array('label' => (string)$actionName),
 							Piwik_DataTable_Row::METADATA => array('url' => (string)$row['name']),
 						));
+				}
 			}
 			
 			foreach($row as $name => $value)
@@ -325,7 +426,7 @@ class Piwik_Actions extends Piwik_Plugin
 			if($currentTable->getColumn('nb_hits') === false)
 			{
 				// to test this code: delete the entries in log_link_action_visit for
-				//  a given exit_idaction 
+				//  a given exit_idaction_url
 				foreach($this->defaultRow->getColumns() as $name => $value)
 				{
 					$currentTable->addColumn($name, $value);
diff --git a/plugins/Actions/Controller.php b/plugins/Actions/Controller.php
index 6943e3d53194928cf626b75191485e00467c3ff3..64974199b477095c215262e3377be92fd4f1e1a7 100644
--- a/plugins/Actions/Controller.php
+++ b/plugins/Actions/Controller.php
@@ -17,41 +17,52 @@
  */
 class Piwik_Actions_Controller extends Piwik_Controller 
 {
-	public function index()
+	public function getPageUrls($fetch = false)
 	{
-		$view = Piwik_View::factory('index');
-		
-		/* Actions, Downloads, Outlinks */
-		$view->dataTableActions = $this->getActions( true );
-		$view->dataTableDownloads = $this->getDownloads( true );
-		$view->dataTableOutlinks = $this->getOutlinks( true );
-		
-		echo $view->render();
+		$view = Piwik_ViewDataTable::factory();
+		$view->init(  	$this->pluginName, 
+						__FUNCTION__,
+						'Actions.getPageUrls',
+						'getPageUrlsSubDataTable' );
+		$view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnPageURL'));
+		$this->configureViewActions($view);
+		return $this->renderView($view, $fetch);
 	}
 	
-	public function getActions($fetch = false)
+	public function getPageUrlsSubDataTable($fetch = false)
 	{
 		$view = Piwik_ViewDataTable::factory();
 		$view->init(  	$this->pluginName, 
 						__FUNCTION__,
-						'Actions.getActions', 
-						'getActionsSubDataTable' );
+						'Actions.getPageUrls',
+						'getActionsSubDataTable'  );
 		$this->configureViewActions($view);
+		return $this->renderView($view, $fetch);
+	}
+
+	public function getPageTitles($fetch = false)
+	{
+		$view = Piwik_ViewDataTable::factory();
+		$view->init(  	$this->pluginName,
+						__FUNCTION__,
+						'Actions.getPageTitles',
+						'getPageTitlesSubDataTable' );
 		$view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnPageName'));
+		$this->configureViewActions($view);
 		return $this->renderView($view, $fetch);
 	}
-	
-	public function getActionsSubDataTable($fetch = false)
+
+	public function getPageTitlesSubDataTable($fetch = false)
 	{
 		$view = Piwik_ViewDataTable::factory();
-		$view->init(  	$this->pluginName, 
+		$view->init(  	$this->pluginName,
 						__FUNCTION__,
-						'Actions.getActions', 
-						'getActionsSubDataTable'  );
+						'Actions.getPageTitles',
+						'getPageTitlesSubDataTable'  );
 		$this->configureViewActions($view);
 		return $this->renderView($view, $fetch);
 	}
-	
+
 	public function getDownloads($fetch = false)
 	{
 		$view = Piwik_ViewDataTable::factory();
@@ -76,7 +87,7 @@ class Piwik_Actions_Controller extends Piwik_Controller
 		$view->disableSearchBox();
 		return $this->renderView($view, $fetch);
 	}
-	
+
 	public function getOutlinks($fetch = false)
 	{
 		$view = Piwik_ViewDataTable::factory();
@@ -101,7 +112,7 @@ class Piwik_Actions_Controller extends Piwik_Controller
 		$view->disableSearchBox();
 		return $this->renderView($view, $fetch);
 	}
-	
+
 	protected function configureViewActions($view)
 	{
 		$view->setTemplate('CoreHome/templates/datatable_actions.tpl');
@@ -123,7 +134,6 @@ class Piwik_Actions_Controller extends Piwik_Controller
 		
 		$view->setLimit( 100 );
 		$view->setColumnsToDisplay( array('label','nb_hits','nb_visits') );
-		$view->setColumnTranslation('label', Piwik_Translate('Actions_ColumnPageName'));
 		$view->setColumnTranslation('nb_hits', Piwik_Translate('General_ColumnPageviews'));
 		$view->setColumnTranslation('nb_visits', Piwik_Translate('General_ColumnUniquePageviews'));
 
@@ -171,7 +181,7 @@ class Piwik_Actions_Controller extends Piwik_Controller
 		$view->disableExcludeLowPopulation();
 		$view->setLimit( 15 );
 	}
-	
+
 	protected function getArrayFromRecursiveDataTable( $dataTable, $depth = 0 )
 	{
 		$table = array();
diff --git a/plugins/Actions/tests/Actions.test.php b/plugins/Actions/tests/Actions.test.php
new file mode 100644
index 0000000000000000000000000000000000000000..08f11e81ef721b82e04bf0ef8451201217f40cb4
--- /dev/null
+++ b/plugins/Actions/tests/Actions.test.php
@@ -0,0 +1,92 @@
+<?php
+if(!defined("PIWIK_PATH_TEST_TO_ROOT")) {
+	define('PIWIK_PATH_TEST_TO_ROOT', getcwd().'/../../..');
+}
+if(!defined('PIWIK_CONFIG_TEST_INCLUDED'))
+{
+	require_once PIWIK_PATH_TEST_TO_ROOT . "/tests/config_test.php";
+}
+
+require_once 'Actions/Actions.php';
+require_once 'Tracker/Action.php';
+require_once 'Tracker/Config.php';
+
+class Test_Piwik_Actions extends UnitTestCase
+{
+	function test_getActionExplodedNames()
+	{
+		$userFile = PIWIK_INCLUDE_PATH . '/tests/resources/plugins/Actions/Actions.config.ini.php';
+
+		Piwik::createConfigObject($userFile);
+
+		$action = new Test_Piwik_Actions_getActionExplodedNames();
+
+		$tests = array(
+			array(
+				'params' =>	array( 'name' => 'http://example.org/', 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
+				'expected' => array('index' ),
+			),
+			array(
+				'params' =>	array( 'name' => 'http://example.org/path/', 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
+				'expected' => array( 'path', 'index' ),
+			),
+			array(
+				'params' =>	array( 'name' => 'http://example.org/test/path', 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
+				'expected' => array( 'test', 'path' ),
+			),
+			array(
+				'params' =>	array( 'name' => 'Test / Path', 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
+				'expected' => array( 'Test', 'Path' ),
+			),
+			array(
+				'params' =>	array( 'name' => '    Test trim   ', 'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
+				'expected' => array( 'Test trim' ),
+			),
+			array(
+				'params' =>	array( 'name' => 'Category / Subcategory', 'type' => Piwik_Tracker_Action::TYPE_ACTION_NAME),
+				'expected' => array( 'Category', 'Subcategory' ),
+			),
+			array(
+				'params' =>	array( 'name' => '/path/index.php?var=test', 'type' => Piwik_Tracker_Action::TYPE_ACTION_NAME),
+				'expected' => array( 'path', 'index.php?var=test' ),
+			),
+			array(
+				'params' =>	array( 'name' => 'http://example.org/path/Default.aspx#anchor', 'type' => Piwik_Tracker_Action::TYPE_ACTION_NAME),
+				'expected' => array( 'path', 'Default.aspx' ),
+			),
+			array(
+				'params' =>	array( 'name' => '', 'type' => Piwik_Tracker_Action::TYPE_ACTION_NAME),
+				'expected' => array( 'index' ),
+			),
+			array(
+				'params' =>	array( 'name' => 'http://example.org/download.zip', 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD),
+				'expected' => array( 'example.org', '/download.zip' ),
+			),
+			array(
+				'params' =>	array( 'name' => 'http://example.org/download/1/', 'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD),
+				'expected' => array( 'example.org', '/download/1/' ),
+			),
+			array(
+				'params' =>	array( 'name' => 'http://example.org/link', 'type' => Piwik_Tracker_Action::TYPE_OUTLINK),
+				'expected' => array( 'example.org', '/link' ),
+			),
+			array(
+				'params' =>	array( 'name' => 'http://example.org/some/path/', 'type' => Piwik_Tracker_Action::TYPE_OUTLINK),
+				'expected' => array( 'example.org', '/some/path/' ),
+			),
+
+		);
+		foreach($tests as $test) {
+			$params = $test['params'];
+			$expected = $test['expected'];
+			$this->assertEqual($action->public_getActionExplodedNames($params['name'],$params['type']), $expected);
+		}
+	}
+}
+
+class Test_Piwik_Actions_getActionExplodedNames extends Piwik_Actions {
+	public function public_getActionExplodedNames($name, $type)
+	{
+		return self::getActionExplodedNames($name, $type);
+	}
+}
\ No newline at end of file
diff --git a/tests/core/Tracker/Action.test.php b/tests/core/Tracker/Action.test.php
index 5f6b510f9db15dbcf8ef7214feadfa3641008d62..2cc1fba21616006f73244ea87c49684532a10602 100644
--- a/tests/core/Tracker/Action.test.php
+++ b/tests/core/Tracker/Action.test.php
@@ -23,29 +23,53 @@ class Test_Piwik_TrackerAction extends UnitTestCase
 			// outlinks
 			array(
 				'request' => array( 'link' => 'http://example.org'),
-				'expected' => array(	'name' => 'http://example.org',
+				'expected' => array(	'name' => null,
+										'url' => 'http://example.org',
+										'type' => Piwik_Tracker_Action::TYPE_OUTLINK),
+			),
+			// outlinks with custom name
+			array(
+				'request' => array( 'link' => 'http://example.org', 'action_name' => 'Example.org'),
+				'expected' => array(	'name' => 'Example.org',
 										'url' => 'http://example.org',
 										'type' => Piwik_Tracker_Action::TYPE_OUTLINK),
 			),
 			// keep the case in urls, but trim
 			array(
 				'request' => array( 'link' => '	http://example.org/Category/Test/  	'),
-				'expected' => array(	'name' => 'http://example.org/Category/Test/',
+				'expected' => array(	'name' => null,
 										'url' => 'http://example.org/Category/Test/',
 										'type' => Piwik_Tracker_Action::TYPE_OUTLINK),
 			),
-			
+
+			// trim the custom name
+			array(
+				'request' => array( 'link' => '	http://example.org/Category/Test/  	', 'action_name' => '  Example dot org '),
+				'expected' => array(	'name' => 'Example dot org',
+										'url' => 'http://example.org/Category/Test/',
+										'type' => Piwik_Tracker_Action::TYPE_OUTLINK),
+			),
+
 			// downloads
 			array(
 				'request' => array( 'download' => 'http://example.org/*$test.zip'),
-				'expected' => array(	'name' => 'http://example.org/*$test.zip',
+				'expected' => array(	'name' => null,
 										'url' => 'http://example.org/*$test.zip',
 										'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD),
 			),
+
+			// downloads with custom name
+			array(
+				'request' => array( 'download' => 'http://example.org/*$test.zip', 'action_name' => 'Download test.zip'),
+				'expected' => array(	'name' => 'Download test.zip',
+										'url' => 'http://example.org/*$test.zip',
+										'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD),
+			),
+			
 			// keep the case and multiple / in urls
 			array(
 				'request' => array( 'download' => 'http://example.org/CATEGORY/test///test.pdf'),
-				'expected' => array(	'name' => 'http://example.org/CATEGORY/test///test.pdf',
+				'expected' => array(	'name' => null,
 										'url' => 'http://example.org/CATEGORY/test///test.pdf',
 										'type' => Piwik_Tracker_Action::TYPE_DOWNLOAD),
 			),
@@ -53,43 +77,62 @@ class Test_Piwik_TrackerAction extends UnitTestCase
 			// page view
 			array(
 				'request' => array( 'url' => 'http://example.org/'),
-				'expected' => array(	'name' => 'index',
+				'expected' => array(	'name' => null,
+										'url' => 'http://example.org/',
+										'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
+			),
+			array(
+				'request' => array( 'url' => 'http://example.org/', 'action_name' => 'Example.org Website'),
+				'expected' => array(	'name' => 'Example.org Website',
 										'url' => 'http://example.org/',
-										'type' => Piwik_Tracker_Action::TYPE_ACTION),
+										'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
 			),
 			array(
 				'request' => array( 'url' => 'http://example.org/CATEGORY/'),
-				'expected' => array(	'name' => 'CATEGORY/index',
+				'expected' => array(	'name' => null,
 										'url' => 'http://example.org/CATEGORY/',
-										'type' => Piwik_Tracker_Action::TYPE_ACTION),
+										'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
+			),
+			array(
+				'request' => array( 'url' => 'http://example.org/CATEGORY/TEST', 'action_name' => 'Example.org / Category / test /'),
+				'expected' => array(	'name' => 'Example.org/Category/test',
+										'url' => 'http://example.org/CATEGORY/TEST',
+										'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
+			),
+
+			// empty request
+			array(
+				'request' => array(),
+				'expected' => array(	'name' => null,	'url' => '/',
+										'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
 			),
 			array(
 				'request' => array( 'url' => 'http://example.org/category/',
 									'action_name' => 'custom name with/one delimiter/two delimiters/'),
 				'expected' => array(	'name' => 'custom name with/one delimiter/two delimiters',
 										'url' => 'http://example.org/category/',
-										'type' => Piwik_Tracker_Action::TYPE_ACTION),
+										'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
 			),
 			array(
 				'request' => array( 'url' => 'http://example.org/category/',
 									'action_name' => 'http://custom action name look like url/'),
 				'expected' => array(	'name' => 'http:/custom action name look like url',
 										'url' => 'http://example.org/category/',
-										'type' => Piwik_Tracker_Action::TYPE_ACTION),
+										'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
 			),
 			// testing: delete tab, trimmed, not strtolowered
 			array( 
 				'request' => array( 'url' => "http://example.org/category/test///test  wOw  	"),
-				'expected' => array(	'name' => 'category/test/test  wOw',
+				'expected' => array(	'name' => null,
 										'url' => 'http://example.org/category/test///test  wOw',
-										'type' => Piwik_Tracker_Action::TYPE_ACTION),
+										'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
 			),
 			// testing: inclusion of zero values in action name
 			array(
 				'request' => array( 'url' => "http://example.org/category/1/0/t/test"),
-				'expected' => array(	'name' => 'category/1/0/t/test',
+				'expected' => array(	'name' => null,
 										'url' => 'http://example.org/category/1/0/t/test',
-										'type' => Piwik_Tracker_Action::TYPE_ACTION),
+										'type' => Piwik_Tracker_Action::TYPE_ACTION_URL),
 			),
 		);
 		foreach($tests as $test) {
diff --git a/tests/resources/Tracker/Action.config.ini.php b/tests/resources/Tracker/Action.config.ini.php
index a5f8cbd30aba3daef96a581ee2ed8b9254369291..2f3bf5d2c2eb865f1e8503db3eb220fcf3b9d208 100644
--- a/tests/resources/Tracker/Action.config.ini.php
+++ b/tests/resources/Tracker/Action.config.ini.php
@@ -1,2 +1,4 @@
 [Tracker]
 action_category_delimiter = /
+default_action_name 	= index
+default_action_url 		= /
\ No newline at end of file
diff --git a/tests/resources/plugins/Actions/Actions.config.ini.php b/tests/resources/plugins/Actions/Actions.config.ini.php
new file mode 100644
index 0000000000000000000000000000000000000000..f1e96d26d6799a473021da6f72a5b47fedf20f78
--- /dev/null
+++ b/tests/resources/plugins/Actions/Actions.config.ini.php
@@ -0,0 +1,5 @@
+[General]
+action_category_delimiter = /
+
+[Tracker]
+default_action_name = index