function exec($args, $stdin, &$stdout, &$stderr, &$system)
	{
		$object = new mObject(getNode($_SESSION['murrix']['path']));

		$user = $object->getUser();
			
		$stdout .= "<table cellspacing=\"0\">";
		$stdout .= "<tr><td class=\"titlename\">Name</td><td>".cmd($object->getName(), "exec=show'&node_id=".$object->getNodeId())."</td></tr>";
		$stdout .= "<tr><td class=\"titlename\">Icon</td><td>".img(geticon($object->getIcon(), 16))."</td></tr>";
		$stdout .= "<tr><td class=\"titlename\">Id</td><td>".$object->getNodeId()."</td></tr>";
		$stdout .= "<tr><td class=\"titlename\">Revision</td><td>".$object->getVersion()."</td></tr>";
		$stdout .= "<tr><td class=\"titlename\">Language</td><td>".$object->getLanguage()."</td></tr>";
		$stdout .= "<tr><td class=\"titlename\">Class</td><td>".$object->getClassName()."</td></tr>";
		$stdout .= "<tr><td class=\"titlename\">Rights</td><td>".$object->getRights()."</td></tr>";
		$stdout .= "<tr><td class=\"titlename\">User</td><td>".$user->username."</td></tr>";
		$stdout .= "<tr><td class=\"titlename\">Time</td><td>".$object->getCreated()."</td></tr>";
		$stdout .= "</table>";
		
		return true;
	}
	function actionSave(&$system, $args)
	{
		$bError = false;
		if (empty($args['name']))
		{
			$system->addAlert(ucf(i18n("please enter a name")));
			$bError = true;
		}

		if (!(strpos($args['name'], "\\") === false) || !(strpos($args['name'], "/") === false) || !(strpos($args['name'], "+") === false))
		{
			$system->addAlert(ucf(i18n("you can not use '\\', '/' or '+' in the name")));
			$bError = true;
		}

		if (!$bError)
		{
			$object = new mObject($this->getNodeId($args));
			if ($object->getNodeId() > 0)
			{
				if ($object->hasRight("write"))
				{
					$object->name = trim($args['name']);
					$object->icon = trim($args['icon']);
					
					$newlang = ($object->getLanguage() != trim($args['language']));
					$object->language = trim($args['language']);
	
					$vars = $object->getVars();
	
					foreach ($vars as $var)
					{
						$key = "v".$var->id;
						
						$value = (isset($args[$key]) ? $args[$key] : (isset($args[$var->id]) ? $args[$var->id] : ""));
						
						if (empty($value) && $var->getRequired() && $var->getType() != "boolean")
						{
							$system->addAlert(utf8e(ucf(str_replace("_", " ", i18n($var->getName(true))))." ".i18n("is a required field")));
							return;
						}
						
						$object->setVarValue($var->name, $value);
					}
					
					if ($args['newversion'] == "on" || $newlang)
						$ret = $object->save();
					else
						$ret = $object->saveCurrent();
						
					if ($ret)
					{
						$system->addRedirect("exec=show&node_id=".$object->getNodeId());

						clearNodeFileCache($object->getNodeId());
						
						$links = $object->getLinks();
						foreach ($links as $link)
						{
							if ($link['type'] == "sub")
								clearNodeFileCache($link['remote_id']);
						}
					}
					else
					{
						$message = "Operation unsuccessfull.<br/>";
						$message .= "Error output:<br/>";
						$message .= $object->getLastError();
						$system->addAlert($message);
					}
				}
			}
		}
	}
function fetch($query, $debug = false)
{
	if (isset($_SESSION['murrix']['querycache'][$query]) && !$debug)
		return $_SESSION['murrix']['querycache'][$query];

	$query2 = $query;
	$commands = array("FETCH", "WHERE", "NODESORTBY", "SORTBY");
	$cmdstr = implode("|", $commands);

	$links = false;
	$vars = 0;
	$return = "object";
	$sort = array();
	$vars_array = array();

	$nodesortby = "";
	
	foreach ($commands as $ord)
	{
		if (preg_match("/^[ ]*($ord) (.+?)( ($cmdstr|$)|$)/", $query, $matches))
		{
			switch ($matches[1])
			{
				case "FETCH":
					switch (trim($matches[2]))
					{
					case "count":
						$select = "SELECT count(objects.id) AS count ";
						$return = "count";
						break;
	
					case "node":
						$select = "SELECT objects.id AS id, objects.node_id AS node_id, objects.language AS language, objects.version AS version ";
						$return = "node";
						break;
	
					case "object":
					default:
						$select = "SELECT objects.id AS id ";
						$return = "object";
						break;
					}
					break;
	
				case "WHERE":
					$org_where = trim($matches[2]);
					if (preg_match_all("/[ ]*(.+?)( AND| OR|$)/", $org_where, $wmatches))
					{
						$wmatches = $wmatches[1];
						//PrintPre($wmatches);
						foreach ($wmatches AS $match)
						{
							$match = trim($match);
							if ($match{0} == "(")
								$match = substr($match, 1, strlen($match)-1);
	
							$parts = explode(":", $match, 2);
	
							$invert = "";
							if ($parts[0]{0} == "!")
							{
								$invert = "!";
								$parts[0] = substr($parts[0], 1, strlen($parts[0])-1);
							}
	
							switch ($parts[0])
							{
							case "property":
								$org_where = str_replace($match, "$invert(objects.".$parts[1].")", $org_where);
								break;
	
							case "var":
								$parts2 = explode("=", $parts[1]);
	
								if (!isset($vars_array[$parts2[0]]))
								{
									$vars++;
									$vars_array[$parts2[0]] = $vars;
								}
								$num = $vars_array[$parts2[0]];
								$org_where = str_replace($match, "values$num.data$invert=".$parts2[1], $org_where);
								break;
	
							case "link":
								$parts2 = explode("=", $parts[1]);
								switch ($parts2[0])
								{
								case "node_top":
									$org_where = str_replace($match, "$invert(links.node_top=".$parts2[1]." AND links.node_bottom=objects.node_id)", $org_where);
									break;
	
								case "node_bottom":
									$org_where = str_replace($match, "$invert(links.node_bottom=".$parts2[1]." AND links.node_top=objects.node_id)", $org_where);
									break;
	
								case "type":
									$org_where = str_replace($match, "$invert(links.type=".$parts2[1].")", $org_where);
									break;
	
								case "node_id":
								default:
									$org_where = str_replace($match, "$invert((links.node_bottom=".$parts2[1]." AND links.node_top=objects.node_id) OR (links.node_top=".$parts2[1]." AND links.node_bottom=objects.node_id))", $org_where);
									break;
								}
								$links = true;
								break;
							}
						}
					}
	
					$where_more = "";
					foreach ($vars_array as $key => $value)
					{
						$where_more .= "(values$value.object_id=objects.id AND values$value.var_id=vars$value.id AND vars$value.name='$key') AND ";
					}
	
					$where = "WHERE $where_more ($org_where)";
					break;
	
				case "NODESORTBY":
					$org_sort = trim($matches[2]);
					if (preg_match_all("/[ ]*(.+?)(,|$)/", $org_sort, $wmatches))
					{
						$wmatches = $wmatches[1];
	
						foreach ($wmatches AS $match)
						{
							$match = trim($match);
	
							$parts = explode(":", $match, 2);
	
							$invert = " DESC";
							if ($parts[0]{0} == "!")
							{
								$invert = " ASC";
								$parts[0] = substr($parts[0], 1, strlen($parts[0])-1);
							}
	
							switch ($parts[0])
							{
							case "property":
								$org_sort = str_replace($match, "objects.".$parts[1].$invert, $org_sort);
								break;
							}
						}
					}
						$nodesortby = "ORDER BY $org_sort";
					break;
	
				case "SORTBY":
					$org_sort = trim($matches[2]);
					if (preg_match_all("/[ ]*(.+?)(,|$)/", $org_sort, $wmatches))
					{
						$wmatches = $wmatches[1];
	
						foreach ($wmatches AS $match)
						{
							$match = trim($match);
	
							$parts = explode(":", $match, 2);
	
							$invert = false;
							if ($parts[0]{0} == "!")
							{
								$invert = true;
								$parts[0] = substr($parts[0], 1, strlen($parts[0])-1);
							}
	
							switch ($parts[0])
							{
							case "property":
								$sort[] = array("property:".$parts[1], $invert);
								//$org_sort = str_replace($match, "objects.".$parts[1].($invert ? "" : " DESC"), $org_sort);
								break;
	
							case "var":
								$sort[] = array($parts[1], $invert);
								break;
							}
						}
					}
					//if (!empty($org_sort))
					//	$sortby = "ORDER BY $org_sort";
					break;
			}
	
			$len = strlen($matches[0]) - strlen($matches[3]);
			$query = trim(substr($query, $len, strlen($query)-$len));
		}
		else
		{
			if (!empty($query))
			{
				echo "nåt galet hände..\n";
				echo $query;
			}
		}
	}
	
	global $db_prefix;

	$from = "FROM `".$db_prefix."objects` AS `objects`";
	
	for ($n = 1; $n <= $vars; $n++)
		$from .= ", `".$db_prefix."vars` AS `vars$n`, `".$db_prefix."values` AS `values$n`";
		
	if ($links)
		$from .= ", `".$db_prefix."links` AS `links`";

	$sql = "$select $from $where $nodesortby";

	$result = mysql_query($sql) or die("fetch " . mysql_errno() . " " . mysql_error());

	if ($return == "count")
	{
		$row = mysql_fetch_array($result, MYSQL_ASSOC);
		//$_SESSION['debug'] += microtime_float()-$time;
		$_SESSION['murrix']['querycache'][$query2] = $row['count'];
		return $row['count'];
	}

	if ($return == "object")
	{
		$objects = array();
		while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
		{
			$object = new mObject();
			if (!$object->loadByObjectId($row['id']))
				echo $object->getLastError();
			$objects[] = $object;
		}
	}
	else if ($return == "node")
	{
		$objects = array();
		while ($row = mysql_fetch_array($result, MYSQL_ASSOC))
		{
			$object = new mObject();
			$object->node_id = $row['node_id'];
			$object->id = $row['id'];
			$object->version = $row['version'];
			$object->language = $row['language'];
			$objects[] = $object;
		}

		$nodes = array();
		$node_list = array();
		foreach ($objects as $object)
		{
			// We have a prior version already
			if (isset($node_list[$object->getNodeId()]))
			{
				if ($node_list[$object->getNodeId()] != $_SESSION['murrix']['language']) // Not a perfect match
				{
					if ($object->getLanguage() == $_SESSION['murrix']['language']) // We have a better match
					{
						$nodes[$object->getNodeId()] = $object;
						$node_list[$object->getNodeId()] = $object->getLanguage();
					}
				}
				/*else // Perfect language match
				{
					if ($node_list[$object->getNodeId()]->version < $object->version)// Do we have a better version
					{
						$nodes[$object->getNodeId()] = $object;
						$node_list[$object->getNodeId()] = $object->getLanguage();
					}
				}*/
			}
			else // We have no prior match
			{
				$nodes[$object->getNodeId()] = $object;
				$node_list[$object->getNodeId()] = $object->getLanguage();
			}
		}

		$objects2 = array_values($nodes);
		
		$objects = array();
		foreach ($objects2 as $object2)
		{
			$object = new mObject();
			if (!$object->loadByObjectId($object2->getId()))
				echo $object->getLastError();
			$objects[] = $object;
		}
	}
	
	if (!empty($sort))
	{
		$sort = array_reverse($sort);
		foreach ($sort as $sortby)
		{
			SortBy(&$objects, $sortby[0], $sortby[1]);
		}
	}
	
	$_SESSION['murrix']['querycache'][$query2] = $objects;
	return $objects;
}