--- ./include/classes/api/API.php.orig	2014-12-16 07:38:26.000000000 +0100
+++ ./include/classes/api/API.php	2015-03-01 14:40:19.326635175 +0100
@@ -68,6 +68,7 @@
 		'template' => 'CTemplate',
 		'templatescreen' => 'CTemplateScreen',
 		'templatescreenitem' => 'CTemplateScreenItem',
+		'trends' => 'CTrends',
 		'trigger' => 'CTrigger',
 		'triggerprototype' => 'CTriggerPrototype',
 		'user' => 'CUser',
@@ -378,6 +379,13 @@
 	}
 
 	/**
+	 * @return CTrends
+	 */
+	public static function Trends() {
+		return self::getObject('trends');
+	}
+
+	/**
 	 * @return CTrigger
 	 */
 	public static function Trigger() {
--- ./api/classes/CTrends.php.orig	2015-03-01 15:10:50.954791788 +0100
+++ ./api/classes/CTrends.php	2015-03-01 14:36:58.742618429 +0100
@@ -0,0 +1,280 @@
+<?php
+/*
+** Zabbix
+** Copyright (C) 2001-2014 Zabbix SIA
+**
+** 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; either version 2 of the License, or
+** (at your option) any later version.
+**
+** 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.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+**/
+
+
+/**
+ * Class containing methods for operations with trends.
+ *
+ * @package API
+ */
+class CTrends extends CZBXAPI {
+
+	protected $tableName = 'trends';
+	protected $tableAlias = 'h';
+	protected $sortColumns = array('itemid', 'clock');
+
+	public function __construct() {
+		// considering the quirky nature of the trends API,
+		// the parent::__construct() method should not be called.
+	}
+
+	/**
+	 * Get trends data.
+	 *
+	 * @param array $options
+	 * @param array $options['itemids']
+	 * @param boolean $options['editable']
+	 * @param string $options['pattern']
+	 * @param int $options['limit']
+	 * @param string $options['order']
+	 *
+	 * @return array|int item data as array or false if error
+	 */
+	public function get($options = array()) {
+		$result = array();
+		$nodeCheck = false;
+
+		$sqlParts = array(
+			'select'	=> array('trends' => 'h.itemid'),
+			'from'		=> array(),
+			'where'		=> array(),
+			'group'		=> array(),
+			'order'		=> array(),
+			'limit'		=> null
+		);
+
+		$defOptions = array(
+			'history'					=> ITEM_VALUE_TYPE_UINT64,
+			'nodeids'					=> null,
+			'hostids'					=> null,
+			'itemids'					=> null,
+			'triggerids'				=> null,
+			'editable'					=> null,
+			'nopermissions'				=> null,
+			// filter
+			'filter'					=> null,
+			'search'					=> null,
+			'searchByAny'				=> null,
+			'startSearch'				=> null,
+			'excludeSearch'				=> null,
+			'searchWildcardsEnabled'	=> null,
+			'time_from'					=> null,
+			'time_till'					=> null,
+			// output
+			'output'					=> API_OUTPUT_REFER,
+			'countOutput'				=> null,
+			'groupCount'				=> null,
+			'groupOutput'				=> null,
+			'preservekeys'				=> null,
+			'sortfield'					=> '',
+			'sortorder'					=> '',
+			'limit'						=> null
+		);
+		$options = zbx_array_merge($defOptions, $options);
+
+		$tables = array(
+			ITEM_VALUE_TYPE_FLOAT => 'trends',
+			ITEM_VALUE_TYPE_UINT64 => 'trends_uint'
+		);
+		if (!$tableName = $tables[$options['history']]) {
+			$tableName = 'trends';
+		}
+		$sqlParts['from']['trends'] = $tableName.' h';
+
+		// editable + PERMISSION CHECK
+		if (USER_TYPE_SUPER_ADMIN == self::$userData['type'] || $options['nopermissions']) {
+		}
+		else {
+			$items = API::Item()->get(array(
+				'itemids' => ($options['itemids'] === null) ? null : $options['itemids'],
+				'output' => array('itemid'),
+				'editable' => $options['editable'],
+				'preservekeys' => true,
+				'webitems' => true
+			));
+			$options['itemids'] = array_keys($items);
+		}
+
+		// nodeids
+		$nodeids = !is_null($options['nodeids']) ? $options['nodeids'] : get_current_nodeid();
+
+		// itemids
+		if (!is_null($options['itemids'])) {
+			zbx_value2array($options['itemids']);
+			$sqlParts['where']['itemid'] = dbConditionInt('h.itemid', $options['itemids']);
+
+			if (!$nodeCheck) {
+				$nodeCheck = true;
+				$sqlParts['where'] = sqlPartDbNode($sqlParts['where'], 'h.itemid', $nodeids);
+			}
+		}
+
+		// hostids
+		if (!is_null($options['hostids'])) {
+			zbx_value2array($options['hostids']);
+
+			$sqlParts['select']['hostid'] = 'i.hostid';
+			$sqlParts['from']['items'] = 'items i';
+			$sqlParts['where']['i'] = dbConditionInt('i.hostid', $options['hostids']);
+			$sqlParts['where']['hi'] = 'h.itemid=i.itemid';
+
+			if (!$nodeCheck) {
+				$nodeCheck = true;
+				$sqlParts['where'] = sqlPartDbNode($sqlParts['where'], 'i.hostid', $nodeids);
+			}
+		}
+
+		// should be last, after all ****IDS checks
+		if (!$nodeCheck) {
+			$sqlParts['where'] = sqlPartDbNode($sqlParts['where'], 'h.itemid', $nodeids);
+		}
+
+		// time_from
+		if (!is_null($options['time_from'])) {
+			$sqlParts['select']['clock'] = 'h.clock';
+			$sqlParts['where']['clock_from'] = 'h.clock>='.zbx_dbstr($options['time_from']);
+		}
+
+		// time_till
+		if (!is_null($options['time_till'])) {
+			$sqlParts['select']['clock'] = 'h.clock';
+			$sqlParts['where']['clock_till'] = 'h.clock<='.zbx_dbstr($options['time_till']);
+		}
+
+		// filter
+		if (is_array($options['filter'])) {
+			$this->dbFilter($sqlParts['from']['trends'], $options, $sqlParts);
+		}
+
+		// search
+		if (is_array($options['search'])) {
+			zbx_db_search($sqlParts['from']['trends'], $options, $sqlParts);
+		}
+
+		// output
+		if ($options['output'] == API_OUTPUT_EXTEND) {
+			unset($sqlParts['select']['clock']);
+			$sqlParts['select']['trends'] = 'h.*';
+		}
+
+		// countOutput
+		if (!is_null($options['countOutput'])) {
+			$options['sortfield'] = '';
+			$sqlParts['select'] = array('count(DISTINCT h.hostid) as rowscount');
+
+			// groupCount
+			if (!is_null($options['groupCount'])) {
+				foreach ($sqlParts['group'] as $key => $fields) {
+					$sqlParts['select'][$key] = $fields;
+				}
+			}
+		}
+
+		// groupOutput
+		$groupOutput = false;
+		if (!is_null($options['groupOutput'])) {
+			if (str_in_array('h.'.$options['groupOutput'], $sqlParts['select']) || str_in_array('h.*', $sqlParts['select'])) {
+				$groupOutput = true;
+			}
+		}
+
+		// sorting
+		$sqlParts = $this->applyQuerySortOptions($tableName, $this->tableAlias(), $options, $sqlParts);
+
+		// limit
+		if (zbx_ctype_digit($options['limit']) && $options['limit']) {
+			$sqlParts['limit'] = $options['limit'];
+		}
+
+		$itemids = array();
+
+		$sqlParts['select'] = array_unique($sqlParts['select']);
+		$sqlParts['from'] = array_unique($sqlParts['from']);
+		$sqlParts['where'] = array_unique($sqlParts['where']);
+		$sqlParts['order'] = array_unique($sqlParts['order']);
+
+		$sqlSelect = '';
+		$sqlFrom = '';
+		$sqlOrder = '';
+		if (!empty($sqlParts['select'])) {
+			$sqlSelect .= implode(',', $sqlParts['select']);
+		}
+		if (!empty($sqlParts['from'])) {
+			$sqlFrom .= implode(',', $sqlParts['from']);
+		}
+		$sqlWhere = !empty($sqlParts['where']) ? ' WHERE '.implode(' AND ', $sqlParts['where']) : '';
+		if (!empty($sqlParts['order'])) {
+			$sqlOrder .= ' ORDER BY '.implode(',', $sqlParts['order']);
+		}
+		$sqlLimit = $sqlParts['limit'];
+
+		$sql = 'SELECT '.$sqlSelect.
+				' FROM '.$sqlFrom.
+				$sqlWhere.
+				$sqlOrder;
+		$dbRes = DBselect($sql, $sqlLimit);
+		$count = 0;
+		$group = array();
+		while ($data = DBfetch($dbRes)) {
+			if ($options['countOutput']) {
+				$result = $data;
+			}
+			else {
+				$itemids[$data['itemid']] = $data['itemid'];
+
+				$result[$count] = array();
+
+				// hostids
+				if (isset($data['hostid'])) {
+					if (!isset($result[$count]['hosts'])) {
+						$result[$count]['hosts'] = array();
+					}
+					$result[$count]['hosts'][] = array('hostid' => $data['hostid']);
+					unset($data['hostid']);
+				}
+
+				// triggerids
+				if (isset($data['triggerid'])) {
+					if (!isset($result[$count]['triggers'])) {
+						$result[$count]['triggers'] = array();
+					}
+					$result[$count]['triggers'][] = array('triggerid' => $data['triggerid']);
+					unset($data['triggerid']);
+				}
+				$result[$count] += $data;
+
+				// grouping
+				if ($groupOutput) {
+					$dataid = $data[$options['groupOutput']];
+					if (!isset($group[$dataid])) {
+						$group[$dataid] = array();
+					}
+					$group[$dataid][] = $result[$count];
+				}
+				$count++;
+			}
+		}
+
+		if (is_null($options['preservekeys'])) {
+			$result = zbx_cleanHashes($result);
+		}
+		return $result;
+	}
+}
