diff --git a/pandora_console/ChangeLog b/pandora_console/ChangeLog
index 831ca1e2fd..290b2f1561 100644
--- a/pandora_console/ChangeLog
+++ b/pandora_console/ChangeLog
@@ -1,3 +1,15 @@
+2012-10-11  Sergio Martin <sergio.martin@artica.es>
+
+	* include/functions_events.php
+	include/javascript/pandora_events.js
+	include/ajax/events.php
+	include/constants.php
+	operation/events/events_validate.php
+	operation/events/events_list.php
+	operation/events/events.php: Change the validation events 
+	system to validate passing the ids searialized avoiding a lot
+	of operations. Improve counts and fix several bugs
+
 2012-10-11 Miguel de Dios <miguel.dedios@artica.es>
 	
 	* include/functions_agents.php: fixed the order of vars in the
diff --git a/pandora_console/include/ajax/events.php b/pandora_console/include/ajax/events.php
index b37105a887..5fd0bd5d57 100644
--- a/pandora_console/include/ajax/events.php
+++ b/pandora_console/include/ajax/events.php
@@ -31,6 +31,21 @@ $get_response = (bool) get_parameter ('get_response');
 $get_response_target = (bool) get_parameter ('get_response_target');
 $get_response_params = (bool) get_parameter ('get_response_params');
 $get_response_description = (bool) get_parameter ('get_response_description');
+$get_event_name = (bool) get_parameter ('get_event_name');
+
+if($get_event_name) {	
+	$event_id = get_parameter ('event_id');
+	
+	$name = db_get_value('evento','tevento','id_evento',$event_id);
+	
+	if($name === false) {
+		return;
+	}
+	
+	echo io_safe_output($name);
+	
+	return;
+}
 
 if($get_response_description) {	
 	$response_id = get_parameter ('response_id');
@@ -149,11 +164,10 @@ if($add_comment) {
 }
 
 if($change_status) { 
+	$event_ids = get_parameter ('event_ids');
 	$new_status = get_parameter ('new_status');
-	$event_id = get_parameter ('event_id');
-	$similars = true;
 	
-	$return = events_validate_event ($event_id, $similars, $new_status);
+	$return = events_change_status (explode(',',$event_ids), $new_status);
 
 	if ($return)
 		echo 'status_ok';
@@ -172,7 +186,7 @@ if($change_owner) {
 		$new_owner = '';
 	}
 
-	$return = events_change_owner_event($event_id, $similars, $new_owner, true);
+	$return = events_change_owner($event_id, $new_owner, true);
 
 	if ($return)
 		echo 'owner_ok';
@@ -185,18 +199,31 @@ if($change_owner) {
 if($get_extended_event) {
 	global $config;
 	
-	$dialog_page = get_parameter('dialog_page','general');
 	$event_id = get_parameter('event_id',false);
-	
-	$events = events_get_events_grouped("AND evento = (SELECT evento FROM tevento WHERE id_evento = $event_id)");
 
+	$event = events_get_event($event_id);
+	
 	// If the event is not found, we abort
-	if(empty($events)) {
+	if(empty($event)) {
 		echo 'not found';
 		return false;
 	}
-	else {
-		$event = reset($events);
+
+	$dialog_page = get_parameter('dialog_page','general');
+	$similar_ids = get_parameter('similar_ids', $event_id);
+	$group_rep = get_parameter('group_rep',false);
+	$event_rep = get_parameter('event_rep',1);
+	$user_comment = base64_decode(get_parameter('user_comment',false));
+	$timestamp_first = get_parameter('timestamp_first', $event['utimestamp']);
+	$timestamp_last = get_parameter('timestamp_last', $event['utimestamp']);
+
+	$event['similar_ids'] = $similar_ids;
+	$event['timestamp_first'] = $timestamp_first;
+	$event['timestamp_last'] = $timestamp_last;
+	$event['event_rep'] = $event_rep;
+	
+	if($user_comment !== false) {
+		$event['user_comment'] = $user_comment;
 	}
 	
 	// Check ACLs
@@ -222,9 +249,6 @@ if($get_extended_event) {
 			return false;
 		}
 	}
-
-
-	$group_rep = get_parameter('group_rep',false);
 	
 	// Print group_rep in a hidden field to recover it from javascript
 	html_print_input_hidden('group_rep',(int)$group_rep);
diff --git a/pandora_console/include/constants.php b/pandora_console/include/constants.php
index 63e55e8dd0..9158f93038 100644
--- a/pandora_console/include/constants.php
+++ b/pandora_console/include/constants.php
@@ -50,7 +50,10 @@ define ('ERR_NODATA', -70000);
 define ('ERR_CONNECTION', -80000);
 define ('ERR_DISABLED', -90000);
 
-
+/* Event status code */
+define ('EVENT_STATUS_NEW',0);
+define ('EVENT_STATUS_INPROCESS',2);
+define ('EVENT_STATUS_VALIDATED',1);
 
 /* Seconds in a time unit constants */
 define('SECONDS_1MINUTE', 60);
@@ -198,4 +201,4 @@ define ('STATUS_ALERT_DISABLED', 'alert_disabled.png');
 //For servers
 define ('STATUS_SERVER_OK', 'server_ok.png');
 define ('STATUS_SERVER_DOWN', 'server_down.png');
-?>
\ No newline at end of file
+?>
diff --git a/pandora_console/include/functions_events.php b/pandora_console/include/functions_events.php
index 49219f71f8..02d227244f 100644
--- a/pandora_console/include/functions_events.php
+++ b/pandora_console/include/functions_events.php
@@ -71,23 +71,23 @@ function events_get_events_grouped($sql_post, $offset = 0, $pagination = 1) {
 		case "mysql":
 			db_process_sql ('SET group_concat_max_len = 9999999');
 			$sql = "SELECT *, MAX(id_evento) AS id_evento,
-					GROUP_CONCAT(DISTINCT user_comment SEPARATOR '') AS user_comment,
-					MIN(estado) AS min_estado,
-					MAX(estado) AS max_estado,
+					GROUP_CONCAT(DISTINCT user_comment SEPARATOR '<br>') AS user_comment,
+					GROUP_CONCAT(DISTINCT id_evento SEPARATOR ',') AS similar_ids,
 					COUNT(*) AS event_rep, MAX(utimestamp) AS timestamp_rep, 
 					MIN(utimestamp) AS timestamp_rep_min
 				FROM tevento
 				WHERE 1=1 ".$sql_post."
-				GROUP BY evento, id_agentmodule
+				GROUP BY estado, evento, id_agentmodule
 				ORDER BY timestamp_rep DESC LIMIT ".$offset.",".$pagination;
 			break;
 		case "postgresql":
-			$sql = "SELECT *, MAX(id_evento) AS id_evento, array_to_string(array_agg(DISTINCT user_comment), '') AS user_comment,
-					MIN(estado) AS min_estado, MAX(estado) AS max_estado, COUNT(*) AS event_rep, MAX(utimestamp) AS timestamp_rep, 
+			$sql = "SELECT *, MAX(id_evento) AS id_evento, array_to_string(array_agg(DISTINCT user_comment), '<br>') AS user_comment,
+					array_to_string(array_agg(DISTINCT id_evento), ',') AS similar_ids,
+					COUNT(*) AS event_rep, MAX(utimestamp) AS timestamp_rep, 
 					MIN(utimestamp) AS timestamp_rep_min
 				FROM tevento
 				WHERE 1=1 ".$sql_post."
-				GROUP BY evento, id_agentmodule, id_evento, id_agente, id_usuario, id_grupo, estado, timestamp, utimestamp, event_type, id_alert_am, criticity, user_comment, tags, source, id_extra
+				GROUP BY estado, evento, id_agentmodule, id_evento, id_agente, id_usuario, id_grupo, estado, timestamp, utimestamp, event_type, id_alert_am, criticity, user_comment, tags, source, id_extra
 				ORDER BY timestamp_rep DESC LIMIT ".$pagination." OFFSET ".$offset;
 			break;
 		case "oracle":
@@ -98,12 +98,13 @@ function events_get_events_grouped($sql_post, $offset = 0, $pagination = 1) {
 			$sql = "SELECT a.*, b.event_rep, b.timestamp_rep
 				FROM (SELECT * FROM tevento WHERE 1=1 ".$sql_post.") a, 
 				(SELECT MAX (id_evento) AS id_evento,  to_char(evento) AS evento, 
-				id_agentmodule, COUNT(*) AS event_rep, MIN(estado) AS min_estado, MAX(estado) AS max_estado,
+				id_agentmodule, COUNT(*) AS event_rep,
 				LISTAGG(user_comment, '') AS user_comment, MAX(utimestamp) AS timestamp_rep, 
+				LISTAGG(id_evento, '') AS similar_ids,
 				MIN(utimestamp) AS timestamp_rep_min
 				FROM tevento 
 				WHERE 1=1 ".$sql_post." 
-				GROUP BY to_char(evento), id_agentmodule) b 
+				GROUP BY estado, to_char(evento), id_agentmodule) b 
 				WHERE a.id_evento=b.id_evento AND 
 				to_char(a.evento)=to_char(b.evento) 
 				AND a.id_agentmodule=b.id_agentmodule";
@@ -168,7 +169,6 @@ function events_delete_event ($id_event, $similar = true) {
 		$id_event = array_unique($id_event);
 	}
 	
-	db_process_sql_begin ();
 	$errors = 0;
 	
 	foreach ($id_event as $event) {
@@ -190,10 +190,8 @@ function events_delete_event ($id_event, $similar = true) {
 	}
 	
 	if ($errors > 1) {
-		db_process_sql_rollback ();
 		return false;
 	} else {
-		db_process_sql_commit ();
 		return true;
 	}
 }
@@ -275,7 +273,7 @@ function events_validate_event ($id_event, $similars = true, $new_status = 1) {
 }
 
 /**
- * Change the owner of an event if the event hasn't owner
+ * Change the status of one or various events
  *
  * @param mixed Event ID or array of events
  * @param bool Whether to change owner on similar events or not.
@@ -284,58 +282,118 @@ function events_validate_event ($id_event, $similars = true, $new_status = 1) {
  *
  * @return bool Whether or not it was successful
  */	
-function events_change_owner_event ($id_event, $similars = true, $new_owner = false, $force = false) {
+function events_change_status ($id_event, $new_status) { 
 	global $config;
 	
 	//Cleans up the selection for all unwanted values also casts any single values as an array 
 	$id_event = (array) safe_int ($id_event, 1);
-
-	/* We must validate all events like the selected */
-	if ($similars) {
-		foreach ($id_event as $id) {
-			$id_event = array_merge ($id_event, events_get_similar_ids ($id));
+	
+	// Update ack info if the new status is validated
+	if($new_status == EVENT_STATUS_VALIDATED) {
+		$ack_utimestamp = time();
+		$ack_user = $config['id_user'];
+	}
+	else {
+		$acl_utimestamp = 0;
+		$ack_user = '';
+	}
+	
+	switch($new_status) {
+		case EVENT_STATUS_NEW:
+			$status_string = 'New';
+			break;
+		case EVENT_STATUS_VALIDATED:
+			$status_string = 'Validated';
+			break;
+		case EVENT_STATUS_INPROCESS:
+			$status_string = 'In process';
+			break;
+		default:
+			$status_string = '';
+			break;
+	}
+		
+	foreach ($id_event as $k => $id) {
+		if (check_acl ($config["id_user"], events_get_group ($id), "IW") == 0) {
+			db_pandora_audit("ACL Violation", "Attempted updating event #".$id);
+			
+			unset($id_event[$k]);
 		}
-		$id_event = array_unique($id_event);
+	}
+	
+	if(empty($id_event)) {
+		return false;
+	}
+	
+	$values = array(
+		'estado' => $new_status,
+		'id_usuario' => $ack_user,
+		'ack_utimestamp' => $ack_utimestamp);
+		
+	$ret = db_process_sql_update('tevento', $values,
+		array('id_evento' => $id_event));
+	
+	if (($ret === false) || ($ret === 0)) {
+		return false;
+	}
+	
+	events_comment($id_event, '', "Change status to $status_string");
+	
+	return true;
+}
+
+/**
+ * Change the owner of an event if the event hasn't owner
+ *
+ * @param mixed Event ID or array of events
+ * @param string id_user of the new owner. If is false, the current owner will be setted
+ * @param bool flag to force the change or not (not force is change only when it hasn't owner)
+ *
+ * @return bool Whether or not it was successful
+ */	
+function events_change_owner ($id_event, $new_owner = false, $force = false) {
+	global $config;
+	
+	//Cleans up the selection for all unwanted values also casts any single values as an array 
+	$id_event = (array) safe_int ($id_event, 1);
+			
+	foreach ($id_event as $k => $id) {
+		if (check_acl ($config["id_user"], events_get_group ($id), "IW") == 0) {
+			db_pandora_audit("ACL Violation", "Attempted updating event #".$id);
+			unset($id_event[$k]);
+		}
+	}
+	
+	if(empty($id_event)) {
+		return false;
 	}
 	
 	// Only generate comment when is forced (sometimes is changed the owner when comment)
 	if($force) {
-		events_comment_event($event, $similars, '', 'Change owner');
+		events_comment($id_event, '', 'Change owner');
 	}
 	
+	// If no new_owner is provided, the current user will be the owner
 	if($new_owner === false) {
 		$new_owner = $config['id_user'];
 	}
-		
-	db_process_sql_begin ();
 	
-	foreach ($id_event as $event) {
-		if (check_acl ($config["id_user"], events_get_group ($event), "IW") == 0) {
-			db_pandora_audit("ACL Violation", "Attempted updating event #".$event);
-			return false;
-		}
-		
-		if($owner) {
-			$owner_user = db_get_value('owner_user', 'tevento', 'id_evento', $event);
-		}
-		
-		if(!empty($owner_user) && $force === false) {
-			continue;
-		}
-				
-		$values = array('owner_user' => $new_owner);
+	$values = array('owner_user' => $new_owner);
 
-		$ret = db_process_sql_update('tevento', $values,
-			array('id_evento' => $event), 'AND', false);
-		
-		if (($ret === false) || ($ret === 0)) {
-			db_process_sql_rollback ();
-			return false;
-		}
+	$where = array('id_evento' => $id_event);
+	
+	// If not force, add to where if owner_user <> ''
+	if(!$force) {
+		$where['owner_user'] = '<>';
 	}
 	
-	db_process_sql_commit ();
+	$ret = db_process_sql_update('tevento', $values,
+		$where, 'AND', false);
 	
+	if (($ret === false) || ($ret === 0)) {
+		return false;
+	}
+		
 	return true;
 }
 
@@ -343,29 +401,33 @@ function events_change_owner_event ($id_event, $similars = true, $new_owner = fa
  * Comment events in a transresponse
  *
  * @param mixed Event ID or array of events
- * @param bool Whether to validate similar events or not.
+ * @param string comment to be registered
+ * @param string action performed with the comment. Bu default just Added comment
  *
  * @return bool Whether or not it was successful
  */	
-function events_comment_event ($id_event, $similars = true, $comment = '', $response = 'Added comment') {
+function events_comment ($id_event, $comment = '', $action = 'Added comment') {
 	global $config;
 
 	//Cleans up the selection for all unwanted values also casts any single values as an array 
 	$id_event = (array) safe_int ($id_event, 1);
 	
-	/* We must validate all events like the selected */
-	if ($similars) {
-		foreach ($id_event as $id) {
-			$id_event = array_merge ($id_event, events_get_similar_ids ($id));
+	foreach ($id_event as $k => $id) {
+		if (check_acl ($config["id_user"], events_get_group ($id), "IW") == 0) {
+			db_pandora_audit("ACL Violation", "Attempted updating event #".$id);
+			
+			unset($id_event[$k]);
 		}
-		$id_event = array_unique($id_event);
+	}
+	
+	if(empty($id_event)) {
+		return false;
 	}
 	
 	// If the event hasn't owner, assign the user as owner
-	events_change_owner_event ($id_event, $similars);
-	
-	db_process_sql_begin ();
-		
+	events_change_owner ($id_event, $similars);
+			
+	// Give old ugly format to comment. TODO: Change this method for aux table or json
 	$comment = str_replace(array("\r\n", "\r", "\n"), '<br>', $comment);
 	
 	if ($comment != '') {
@@ -375,39 +437,36 @@ function events_comment_event ($id_event, $similars = true, $comment = '', $resp
 		$commentbox = '';
 	}
 	
-	foreach ($id_event as $event) {
-		if (check_acl ($config["id_user"], events_get_group ($event), "IW") == 0) {
-			db_pandora_audit("ACL Violation", "Attempted updating event #".$event);
-			
-			return false;
-		}
-		
-		$comment = '<b>-- '.$response.' by '.$config['id_user'].' '.'['.date ($config["date_format"]).'] --</b><br>'.$commentbox;
-		$fullevent = events_get_event($event);
-		if ($fullevent['user_comment'] != '') {
-			$comment .= '<br>'.$fullevent['user_comment'];
-		}
-		
-		$values = array(
-			'id_usuario' => $config['id_user'],
-			'user_comment' => $comment);
-		
-		$ret = db_process_sql_update('tevento', $values,
-			array('id_evento' => $event), 'AND', false);
-		
-		if (($ret === false) || ($ret === 0)) {
-			db_process_sql_rollback ();
-			return false;
-		}
+	$comment = '<b>-- '.$action.' by '.$config['id_user'].' '.'['.date ($config["date_format"]).'] --</b><br>'.$commentbox;
+	
+	// Update comment
+	switch ($config['dbtype']) {
+		// Oldstyle SQL to avoid innecesary PHP foreach
+		case 'mysql':
+			$sql_validation = "UPDATE tevento 
+								   SET estado = " . $new_status .", 
+									   id_usuario = '" . $config['id_user'] . "', 
+									   user_comment = concat(user_comment, '" . $comment . "') 
+								   WHERE id_evento in (" . implode(',', $id_event) . ")";
+			   
+			$ret = db_process_sql($sql_validation);	
+			break;				
+		case 'postgresql':
+		case 'oracle':
+			$sql_validation = "UPDATE tevento 
+								   SET estado = " . $new_status . ", 
+									   id_usuario = '" . $config['id_user'] . "', 
+									   user_comment=user_comment || '" . $comment . "') 
+								   WHERE id_evento in (" . implode(',', $id_event) . ")";	
+								   
+			$ret = db_process_sql($sql_validation);							   					
+			break;
 	}
 	
-/*
-	foreach ($id_event as $event) {
-		db_pandora_audit("Event validated", "Validated event #".$event);
+	if (($ret === false) || ($ret === 0)) {
+		return false;
 	}
-*/
-	db_process_sql_commit ();
-	
+		
 	return true;
 }
 
@@ -1187,7 +1246,7 @@ function events_page_responses ($event) {
 	$status = array(0 => __('New'), 2 => __('In process'), 1 => __('Validated'));
 
 	$data[1] = html_print_select($status, 'estado', $event['estado'], '', '', 0, true, false, false);
-	$data[1] .= html_print_button(__('Update'),'status_button',false,'event_change_status();','class="sub next"',true);
+	$data[1] .= html_print_button(__('Update'),'status_button',false,'event_change_status(\''.$event['similar_ids'] .'\');','class="sub next"',true);
 
 	$table_responses->data[] = $data;
 	
@@ -1369,10 +1428,10 @@ function events_page_details ($event) {
 		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('Name').'</div>';
 		$data[1] = ui_print_agent_name ($event["id_agente"], true);
 		$table_details->data[] = $data;
-		
+
 		$data = array();
 		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('IP Address').'</div>';
-		$data[1] = empty($agent['url_address']) ? '<i>'.__('N/A').'</i>' : $agent['url_address'];
+		$data[1] = empty($agent['direccion']) ? '<i>'.__('N/A').'</i>' : $agent['direccion'];
 		$table_details->data[] = $data;
 		
 		$data = array();
@@ -1382,17 +1441,12 @@ function events_page_details ($event) {
 
 		$data = array();
 		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('Last contact').'</div>';
-		$data[1] = $agent["ultimo_contacto"];
+		$data[1] = $agent["ultimo_contacto"] == "1970-01-01 00:00:00" ? '<i>'.__('N/A').'</i>' : $agent["ultimo_contacto"];
 		$table_details->data[] = $data;
-		
+
 		$data = array();
 		$data[0] = '<div style="font-weight:normal; margin-left: 20px;">'.__('Last remote contact').'</div>';
-		if ($agent["ultimo_contacto_remoto"] == "01-01-1970 00:00:00") { 
-			$data[1] .= __('Never');
-		}
-		else {
-			$data[1] .= $agent["ultimo_contacto_remoto"];
-		}
+		$data[1] = $agent["ultimo_contacto_remoto"] == "1970-01-01 00:00:00" ? '<i>'.__('N/A').'</i>' : $agent["ultimo_contacto_remoto"];
 		$table_details->data[] = $data;
 		
 		$data = array();
@@ -1559,7 +1613,10 @@ function events_page_details ($event) {
 function events_page_general ($event) {
 	global $img_sev;
 	global $config;
+	
+	//$group_rep = $event['similar_ids'] == -1 ? 1 : count(explode(',',$event['similar_ids']));
 	global $group_rep;
+
 	/////////
 	// General
 	/////////
@@ -1583,8 +1640,8 @@ function events_page_general ($event) {
 	
 	$data = array();
 	$data[0] = __('Timestamp');
-	if ($group_rep == 1 && $event["event_rep"] > 0) {
-		$data[1] = __('First event').': '.date ($config["date_format"], $event['timestamp_rep_min']).'<br>'.__('Last event').': '.date ($config["date_format"], $event['timestamp_rep']);
+	if ($group_rep == 1 && $event["event_rep"] > 1) {
+		$data[1] = __('First event').': '.date ($config["date_format"], $event['timestamp_first']).'<br>'.__('Last event').': '.date ($config["date_format"], $event['timestamp_last']);
 	}
 	else {
 		$data[1] = date ($config["date_format"], strtotime($event["timestamp"]));
@@ -1610,15 +1667,15 @@ function events_page_general ($event) {
 	$data = array();
 	$data[0] = __('Repeated');
 	if ($group_rep != 0) {
-		if($event["event_rep"] == 0) {
-			$data[1] = __('No');
+		if($event["event_rep"] <= 1) {
+			$data[1] = '<i>'.__('No').'</i>';
 		}
 		else {
 			$data[1] = sprintf("%d Times",$event["event_rep"]);
 		}
 	}
 	else {
-		$data[1] = __('No');
+		$data[1] = '<i>'.__('No').'</i>';
 	}
 	$table_general->data[] = $data;
 	
diff --git a/pandora_console/include/javascript/pandora_events.js b/pandora_console/include/javascript/pandora_events.js
index c4a053b407..4142c8b024 100644
--- a/pandora_console/include/javascript/pandora_events.js
+++ b/pandora_console/include/javascript/pandora_events.js
@@ -3,19 +3,35 @@ function show_event_dialog(event_id, group_rep, dialog_page, result) {
 	if(dialog_page == undefined) {
 		dialog_page = 'general';
 	}
+	
+	var similar_ids = $('#hidden-similar_ids_'+event_id).val();
+	var timestamp_first = $('#hidden-timestamp_first_'+event_id).val();
+	var timestamp_last = $('#hidden-timestamp_last_'+event_id).val();
+	var user_comment = $('#hidden-user_comment_'+event_id).val();
+	var event_rep = $('#hidden-event_rep_'+event_id).val();
+
+	// Check if the event
+	if(similar_ids == undefined) {
+		similar_ids = -1;
+	}
 
 	jQuery.post ("ajax.php",
 		{"page": "include/ajax/events",
 		"get_extended_event": 1,
 		"group_rep": group_rep,
+		"event_rep": event_rep,
 		"dialog_page": dialog_page,
+		"similar_ids": similar_ids,
+		"timestamp_first": timestamp_first,
+		"timestamp_last": timestamp_last,
+		"user_comment": user_comment,
 		"event_id": event_id},
 		function (data, status) {
 			$("#event_details_window").hide ()
 				.empty ()
 				.append (data)
 				.dialog ({
-					title: $("#hidden-event_title_"+event_id).val(),
+					title: get_event_name(event_id),
 					resizable: true,
 					draggable: true,
 					modal: true,
@@ -192,6 +208,30 @@ function get_response_description(response_id) {
 	return response_description;
 }
 
+// Get an event response description from db
+function get_event_name(event_id) {
+	var name = '';
+	
+	var params = [];
+	params.push("page=include/ajax/events");
+	params.push("get_event_name=1");
+	params.push("event_id="+event_id);
+	
+	jQuery.ajax ({
+		data: params.join ("&"),
+		type: 'POST',
+		url: action="ajax.php",
+		async: false,
+		timeout: 10000,
+		dataType: 'html',
+		success: function (data) {
+			name = data;
+		}
+	});
+	
+	return name;
+}
+
 function add_row_param(id_table, param) {
 	$('#'+id_table).append('<tr class="params_rows"><td style="text-align:left; padding-left:40px;">'+param+'</td><td style="text-align:left"><input type="text" name="'+param+'" id="'+param+'"></td></tr>');
 }
@@ -265,14 +305,14 @@ function perform_response(target) {
 }
 
 // Change the status of an event to new, in process or validated
-function event_change_status() {
-	var event_id = $('#hidden-id_event').val();
+function event_change_status(event_ids) {
 	var new_status = $('#estado').val();
+	var event_id = $('#hidden-id_event').val();
 	
 	var params = [];
 	params.push("page=include/ajax/events");
 	params.push("change_status=1");
-	params.push("event_id="+event_id);
+	params.push("event_ids="+event_ids);
 	params.push("new_status="+new_status);
 	
 	$('#button-status_button').attr('disabled','disabled');
@@ -289,7 +329,7 @@ function event_change_status() {
 			$('#button-status_button').removeAttr('disabled');
 			$('#response_loading').hide();
 			show_event_dialog(event_id, $('#hidden-group_rep').val(), 'responses', data);
-			if(data == 'ok') {
+			if(data == 'status_ok') {
 			}
 			else {
 			}
diff --git a/pandora_console/operation/events/events.php b/pandora_console/operation/events/events.php
index 42e014c851..6c874b076b 100644
--- a/pandora_console/operation/events/events.php
+++ b/pandora_console/operation/events/events.php
@@ -38,8 +38,6 @@ if (is_ajax ()) {
 	$delete_event = (bool) get_parameter ('delete_event');
 	$get_events_fired = (bool) get_parameter('get_events_fired');
 	$standby_alert = (bool) get_parameter('standby_alert');
-	$get_comment = (bool) get_parameter('get_comment');
-	$get_comment_header = (bool) get_parameter('get_comment_header');
 	
 	if ($get_event_tooltip) {
 		$id = (int) get_parameter ('id');
@@ -152,26 +150,6 @@ if (is_ajax ()) {
 		echo json_encode($return);
 	}
 	
-	if ($get_comment){
-		$id = (int) get_parameter ("id");
-		$event = events_get_event ($id);
-		
-		if ($event === false)
-			echo '';
-		else
-			echo $event['user_comment'];
-	}
-	
-	if ($get_comment_header){
-		$id = (int) get_parameter ("id");
-		$event = events_get_event ($id);
-		
-		if ($event === false)
-			echo '';
-		else
-			echo ui_print_truncate_text(strip_tags($event["user_comment"]));
-	}
-	
 	return;
 }
 
@@ -361,7 +339,7 @@ if ($validate) {
 
 //Process deletion (pass array or single value)
 if ($delete) {
-	$ids = (array) get_parameter ("eventid", -1);
+	$ids = (array) get_parameter ("validate_ids", -1);
 	
 	if ($ids[0] != -1) {
 		$return = events_delete_event ($ids, ($group_rep == 1));
@@ -376,9 +354,6 @@ else {
 		case 'list':
 			require_once('operation/events/events_list.php');
 			break;
-		case 'validate':
-			require_once('operation/events/events_validate.php');
-			break;
 	}
 }
 
@@ -394,8 +369,8 @@ ui_require_javascript_file('pandora_events');
 
 $(document).ready( function() {
 	
-	$("input[name=allbox]").change (function() {
-		$("input[name='eventid[]']").attr('checked', $(this).attr('checked'));
+	$("input[name=all_validate_box]").change (function() {
+		$("input[name='validate_ids[]']").attr('checked', $(this).attr('checked'));
 	});
 	
 	
@@ -618,7 +593,6 @@ $(document).ready( function() {
 			},
 			"html"
 		);
-		//toggleCommentForm(id);
 	});
 	
 	$("a.delete_event").click (function () {
@@ -683,6 +657,92 @@ $(document).ready( function() {
 		}
 	}
 	
+	function validate_event_advanced(id, new_status) {
+		$tr = $('#validate-'+id).parents ("tr");
+
+		var grouped = $('#group_rep').val();
+		
+		var similar_ids;
+		similar_ids = $('#hidden-similar_ids_'+id).val();
+				
+		$("#status_img_"+id).attr ("src", "images/spinner.gif");
+
+		jQuery.post ("ajax.php",
+			{"page" : "include/ajax/events",
+			"change_status" : 1,
+			"event_ids" : similar_ids,
+			"new_status" : new_status
+			},
+			function (data, status) {
+				if (data == "status_ok") {	
+					// Refresh interface elements, don't reload (awful)
+					// Validate
+					if (new_status == 1){
+						// Change status description
+						$("#status_row_"+id).html(<?php echo "'" . __('Event validated') . "'"; ?>);
+						
+						// Change state image
+						$("#validate-"+id).css("display", "none");
+						$("#status_img_"+id).attr ("src", "images/tick.png");
+						$("#status_img_"+id).attr ("title", <?php echo "'" . __('Event validated') . "'"; ?>);
+						$("#status_img_"+id).attr ("alt", <?php echo "'" . __('Event validated') . "'"; ?>);
+					} // In process
+					else if (new_status == 2){
+						// Change status description
+						$("#status_row_"+id).html(<?php echo "'" . __('Event in process') . "'"; ?>);
+						
+						// Remove delete link (if event is not grouped and there is more than one event)
+						if (grouped == 1) {
+							if (parseInt($("#count_event_group_"+id).text()) <= 1) {
+								$("#delete-"+id).replaceWith('<img alt="' + <?php echo "'" . __('Is not allowed delete events in process') . "'"; ?> + '" title="' + <?php echo "'" . __('Is not allowed delete events in process') . "'"; ?> + '" src="images/cross.disabled.png">');
+							}
+						}
+						else { // Remove delete link (if event is not grouped)
+							$("#delete-"+id).replaceWith('<img alt="' + <?php echo "'" . __('Is not allowed delete events in process') . "'"; ?> + '" title="' + <?php echo "'" . __('Is not allowed delete events in process') . "'"; ?> + '" src="images/cross.disabled.png">');
+						}
+						
+						// Change state image
+						$("#status_img_"+id).attr ("src", "images/hourglass.png");
+						$("#status_img_"+id).attr ("title", <?php echo "'" . __('Event in process') . "'"; ?>);
+						$("#status_img_"+id).attr ("alt", <?php echo "'" . __('Event in process') . "'"; ?>);
+						
+						// Remove row due to new state
+						if (($("#status").val() == 0) || ($("#status").val() == 1)){
+							
+							$.each($tr, function(index, value){
+								row = value;
+								
+								if ($(row).attr('id') != ''){
+									
+									row_id_name = $(row).attr('id').split('-').shift();
+									row_id_number = $(row).attr('id').split('-').pop() - 1;
+									row_id_number_next = parseInt($(row).attr('id').split('-').pop()) + 1;
+									previous_row_id = $(row).attr('id');
+									current_row_id = row_id_name + "-" + row_id_number;
+									selected_row_id = row_id_name + "-" + row_id_number + "-0";
+									next_row_id = row_id_name + '-' + row_id_number_next;
+									
+									$("#"+previous_row_id).css('display', 'none');
+									$("#"+current_row_id).css('display', 'none');
+									$("#"+selected_row_id).css('display', 'none');
+									$("#"+next_row_id).css('display', 'none');
+								}
+							});
+							
+						}
+					}
+				}
+				else {
+					$("#result")
+						.showMessage ("<?php echo __('Could not be validated')?>")
+						.addClass ("error");
+				}
+			},
+			"html"
+		);
+	}
+	
+	
 	// Autoload event giving the id as POST/GET parameter
 	<?php
 		$load_event = get_parameter('load_event',0);
diff --git a/pandora_console/operation/events/events_list.php b/pandora_console/operation/events/events_list.php
index bbbd066f9b..6b0f52a1ad 100644
--- a/pandora_console/operation/events/events_list.php
+++ b/pandora_console/operation/events/events_list.php
@@ -210,7 +210,7 @@ if ($id_user_ack != "0")
 
 if ($event_view_hr > 0) {
 	$unixtime = get_system_time () - ($event_view_hr * SECONDS_1HOUR);
-	$sql_post .= " AND (utimestamp > ".$unixtime . " OR estado = 2)";
+	$sql_post .= " AND (utimestamp > ".$unixtime . ")";
 }
 
 //Search by tag
@@ -586,7 +586,7 @@ if ($i != 0) {
 	$table->size[$i] = '80px';
 	$i++;
 	if (check_acl ($config["id_user"], 0, "IW") == 1) {
-		$table->head[$i] = html_print_checkbox ("allbox", "1", false, true);
+		$table->head[$i] = html_print_checkbox ("all_validate_box", "1", false, true);
 		$table->align[$i] = 'center';
 	}
 }
@@ -601,22 +601,8 @@ foreach ($result as $event) {
 	$table->rowclass[] = $myclass;
 	
 	//print status
-	// Grouped events
-	if ($group_rep != 0) {
-		if ($event["max_estado"] == 2) {
-			$estado = 2;
-		}
-		else if ($event["min_estado"] == 0) {
-			$estado = 0;
-		}
-		else {
-			$estado = 1;
-		}
-	}
-	// Ungrouped events
-	else {
-		$estado = $event["estado"];
-	}
+	$estado = $event["estado"];
+
 	// Colored box
 	switch($estado) {
 		case 0:
@@ -636,6 +622,27 @@ foreach ($result as $event) {
 	$i = 0;
 	
 	$data[$i] = "#".$event["id_evento"];
+	
+	// Pass grouped values in hidden fields to use it from modal window
+	if($group_rep) {
+		$similar_ids = $event['similar_ids'];
+		$timestamp_first = $event['timestamp_rep_min'];
+		$timestamp_last = $event['timestamp_rep'];
+	}
+	else {
+		$similar_ids = $event["id_evento"];
+		$timestamp_first = $event['utimestamp'];
+		$timestamp_last = $event['utimestamp'];
+	}
+	
+	// Store group data to show in extended view
+	$data[$i] .= html_print_input_hidden('similar_ids_'.$event["id_evento"], $similar_ids, true);
+	$data[$i] .= html_print_input_hidden('timestamp_first_'.$event["id_evento"], $timestamp_first, true);
+	$data[$i] .= html_print_input_hidden('timestamp_last_'.$event["id_evento"], $timestamp_last, true);	
+	$data[$i] .= html_print_input_hidden('event_rep_'.$event["id_evento"], $event['event_rep'], true);	
+	// Store concat comments to show in extended view	
+	$data[$i] .= html_print_input_hidden('user_comment_'.$event["id_evento"], base64_encode($event['user_comment']), true);		
+
 	$i++;
 		
 	if (in_array('estado',$show_fields)) {
@@ -822,7 +829,7 @@ foreach ($result as $event) {
 		$data[$i] = '';
 		// Validate event
 		if (($event["estado"] != 1) and (check_acl ($config["id_user"], $event["id_grupo"], "IW") == 1)) {
-			$data[$i] .= '<a href="javascript:" class="validate_event" id="validate-'.$event["id_evento"].'">';
+			$data[$i] .= '<a href="javascript:validate_event_advanced('.$event["id_evento"].', 1)" id="validate-'.$event["id_evento"].'">';
 			$data[$i] .= html_print_image ("images/ok.png", true,
 				array ("title" => __('Validate event')));
 			$data[$i] .= '</a>&nbsp;';
@@ -853,7 +860,7 @@ foreach ($result as $event) {
 		
 		if (check_acl ($config["id_user"], $event["id_grupo"], "IW") == 1) {
 			//Checkbox
-			$data[$i] = html_print_checkbox_extended ("eventid[]", $event["id_evento"], false, false, false, 'class="chk"', true);
+			$data[$i] = html_print_checkbox_extended ("validate_ids[]", $event['id_evento'], false, false, false, 'class="chk_val"', true);
 		}
 		array_push ($table->data, $data);
 	}
@@ -865,22 +872,31 @@ echo '<div id="events_list">';
 if (!empty ($table->data)) {
 	ui_pagination ($total_events, $url."&pure=".$config["pure"], $offset, $pagination);
 	
-	echo '<form method="post" id="form_events" action="'.$url.'&amp;section=validate">';
+	echo '<form method="post" id="form_events" action="'.$url.'">';
 	echo "<input type='hidden' name='delete' id='hidden_delete_events' value='0' />";
 	
 	html_print_table ($table);
 	
 	echo '<div style="width:'.$table->width.';" class="action-buttons">';
 	if (check_acl ($config["id_user"], 0, "IW") == 1) {
-		html_print_submit_button (__('Update'), 'validate_btn', false, 'class="sub ok"');
+		html_print_button(__('Validate selected'), 'validate_button', false, 'validate_selected();', 'class="sub ok"');
 	}
 	if (check_acl ($config["id_user"], 0,"IM") == 1) {
-		html_print_button(__('Delete'), 'delete_button', false, 'submit_delete();', 'class="sub delete"');
+		html_print_button(__('Delete selected'), 'delete_button', false, 'delete_selected();', 'class="sub delete"');
 		?>
 		<script type="text/javascript">
-		function submit_delete() {
-			$("#hidden_delete_events").val(1);
-			$("#form_events").submit();
+		function delete_selected() {
+			if(confirm('<?php echo __('Are you sure?'); ?>')) {
+				$("#hidden_delete_events").val(1);
+				$("#form_events").submit();
+			}
+		}
+		function validate_selected() {
+			$(".chk_val").each(function() { 
+				if($(this).is(":checked")) {
+					validate_event_advanced($(this).val(),1);
+				}
+			});  
 		}
 		</script>
 		<?php
diff --git a/pandora_console/operation/events/events_validate.php b/pandora_console/operation/events/events_validate.php
deleted file mode 100644
index bf44770cfa..0000000000
--- a/pandora_console/operation/events/events_validate.php
+++ /dev/null
@@ -1,121 +0,0 @@
-<?php
-
-// Pandora FMS - http://pandorafms.com
-// ==================================================
-// Copyright (c) 2005-2010 Artica Soluciones Tecnologicas
-// Please see http://pandorafms.org for full contribution list
-
-// This program is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public License
-// as published by the Free Software Foundation for version 2.
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-// GNU General Public License for more details.
-
-
-// Load global vars
-global $config;
-
-require_once ("include/functions_events.php"); //Event processing functions
-require_once ("include/functions_alerts.php"); //Alerts processing functions
-
-check_login ();
-
-if (! check_acl ($config["id_user"], 0, "IR")) {
-	db_pandora_audit("ACL Violation",
-		"Trying to access event viewer");
-	require ("general/noaccess.php");
-	return;
-}
-	
-$ids = (array) get_parameter ("eventid", -1);
-
-$url_val = "index.php?sec=eventos&amp;sec2=operation/events/events&amp;search=" .
-	rawurlencode($search) . "&amp;event_type=" . $event_type .
-	"&amp;severity=" . $severity . "&amp;status=" . $status . "&amp;ev_group=" .
-	$ev_group . "&amp;refr=" . $config["refr"] . "&amp;id_agent=" .
-	$id_agent . "&amp;id_event=" . $id_event . "&amp;pagination=" .
-	$pagination . "&amp;group_rep=" . $group_rep . "&amp;event_view_hr=" .
-	$event_view_hr . "&amp;id_user_ack=" . $id_user_ack . "&amp;offset=" . $offset . "&amp;validate=1";
-
-$event_list = "<b>".__('Events to validate').":</b>";
-
-$event_list .= '';
-$event_list .= "<ul>";
-$any_alert = false;
-$any_inprocess = false;
-
-
-$table->width = '80%';
-$table->id = "listtovalidate";
-$table->cellpadding = 4;
-$table->cellspacing = 4;
-$table->class = "databox";
-$table->head = array ();
-$table->data = array ();
-
-$table->head[0] = __('Events to validate');
-$table->align[0] = 'center';
-
-$table->data = array();
-foreach($ids as $key => $id) {
-	$event = events_get_event($id);
-	// Colored box
-	switch($event["estado"]) {
-		case 0:
-			$img_st = "images/star.png";
-			$title_st = __('New event');
-			break;
-		case 1:
-			$img_st = "images/tick.png";
-			$title_st = __('Event validated');
-			break;
-		case 2:
-			$img_st = "images/hourglass.png";
-			$title_st = __('Event in process');
-			break;
-	}
-	
-	$icon = html_print_image ($img_st, true, 
-		array ("class" => "image_status",
-			"width" => 16,
-			"height" => 16,
-			"title" => $title_st,
-			"id" => 'status_img_'.$event["id_evento"]));
-			
-	$table->data[$key][0] = $icon." ".io_safe_output($event['evento']);
-	$table->align[$key][0] = 'left';
-	if($event['id_alert_am'] != 0) {
-		$any_alert = true;
-	}
-}
-
-//Hiden row with description form
-$string = '<form  method="post" action="'.$url_val.'">';
-$string .= '<table border="0" style="width:80%; margin-left: 10%;"><tr><td align="left" valign="top" width="30px">';
-$string .=  '<td align="right"><b>' . __('Comment:') . '</b></td>';
-$string .= html_print_input_hidden('eventid', implode(',',$ids), true);
-$string .=  '<td align="left" width="450px"><b>' . html_print_textarea("comment", 2, 10, '', 'style="min-height: 10px; width: 250px;"', true) . '</b></td>';
-$string .= '<td align="left" width="200px">'; 
-$string .= '<div style="text-align:center;">';
-if ($event["estado"] == 0 ) {
-	$string .= html_print_select(array('1' => __('Validate'), '2' => __('Set in process'), '3' => __('Add comment')), 'select_validate', '', '', '', 0, true, false, false, 'select_validate').'<br><br>';
-}
-else if ($event["estado"] == 2 ) {
-	$string .= html_print_select(array('1' => __('Validate'), '3' => __('Add comment')), 'select_validate', '', '', '', 0, true, false, false, 'select_validate').'<br><br>';
-}
-
-$string .= html_print_submit_button (__('Change status'), 'validate', false, 'class="sub ok validate_event" id="validate"', true).'</div>';
-$string .= '</td><td width="400px">';
-
-if($any_alert) {
-	$string .= '<div class="standby_alert_checkbox" style="display: none">'.__('Set alert on standby').'<br>'.html_print_checkbox('standby-alert', 'ff2', false, true).'</div>';
-}
-$string .= '</td></tr></table></form>';
-
-echo $string;
-
-html_print_table($table);
-
-?>