diff --git a/README.md b/README.md
index bb2961b1c..d427d607d 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,9 @@
 # CakePHP
 
-[![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=master)](http://travis-ci.org/cakephp/cakephp)
 [![Latest Stable Version](https://poser.pugx.org/cakephp/cakephp/v/stable.svg)](https://packagist.org/packages/cakephp/cakephp)
 [![License](https://poser.pugx.org/cakephp/cakephp/license.svg)](https://packagist.org/packages/cakephp/cakephp)
+[![Bake Status](https://secure.travis-ci.org/cakephp/cakephp.png?branch=master)](http://travis-ci.org/cakephp/cakephp)
+[![Code consistency](http://squizlabs.github.io/PHP_CodeSniffer/analysis/cakephp/cakephp/grade.svg)](http://squizlabs.github.io/PHP_CodeSniffer/analysis/cakephp/cakephp/)
 
 [![CakePHP](http://cakephp.org/img/cake-logo.png)](http://www.cakephp.org)
 
diff --git a/lib/Cake/Controller/Controller.php b/lib/Cake/Controller/Controller.php
index 6727434ae..c92467b05 100644
--- a/lib/Cake/Controller/Controller.php
+++ b/lib/Cake/Controller/Controller.php
@@ -611,7 +611,7 @@ class Controller extends Object implements CakeEventListener {
 
 /**
  * Returns a list of all events that will fire in the controller during its lifecycle.
- * You can override this function to add you own listener callbacks
+ * You can override this function to add your own listener callbacks
  *
  * @return array
  */
diff --git a/lib/Cake/Core/App.php b/lib/Cake/Core/App.php
index 05fa1393a..bb8369c25 100644
--- a/lib/Cake/Core/App.php
+++ b/lib/Cake/Core/App.php
@@ -33,7 +33,7 @@ App::uses('CakePlugin', 'Core');
  * CakePHP is organized around the idea of packages, each class belongs to a package or folder where other
  * classes reside. You can configure each package location in your application using `App::build('APackage/SubPackage', $paths)`
  * to inform the framework where should each class be loaded. Almost every class in the CakePHP framework can be swapped
- * by your own compatible implementation. If you wish to use you own class instead of the classes the framework provides,
+ * by your own compatible implementation. If you wish to use your own class instead of the classes the framework provides,
  * just add the class to your libs folder mocking the directory location of where CakePHP expects to find it.
  *
  * For instance if you'd like to use your own HttpSocket class, put it under
diff --git a/lib/Cake/Model/Datasource/CakeSession.php b/lib/Cake/Model/Datasource/CakeSession.php
index 96a66d899..6d7d53a20 100644
--- a/lib/Cake/Model/Datasource/CakeSession.php
+++ b/lib/Cake/Model/Datasource/CakeSession.php
@@ -378,7 +378,7 @@ class CakeSession {
  */
 	public static function read($name = null) {
 		if (empty($name) && $name !== null) {
-			return false;
+			return null;
 		}
 		if (!self::_hasSession() || !self::start()) {
 			return null;
diff --git a/lib/Cake/Model/Datasource/DboSource.php b/lib/Cake/Model/Datasource/DboSource.php
index 5377f969b..a60c4ee42 100644
--- a/lib/Cake/Model/Datasource/DboSource.php
+++ b/lib/Cake/Model/Datasource/DboSource.php
@@ -396,7 +396,7 @@ class DboSource extends DataSource {
  *
  * @param string $sql SQL statement
  * @param array $params Additional options for the query.
- * @return bool
+ * @return mixed Resource or object representing the result set, or false on failure
  */
 	public function rawQuery($sql, $params = array()) {
 		$this->took = $this->numRows = false;
diff --git a/lib/Cake/Model/Model.php b/lib/Cake/Model/Model.php
index bfe6f257a..1cd07b820 100644
--- a/lib/Cake/Model/Model.php
+++ b/lib/Cake/Model/Model.php
@@ -776,7 +776,7 @@ class Model extends Object implements CakeEventListener {
 
 /**
  * Returns a list of all events that will fire in the model during it's lifecycle.
- * You can override this function to add you own listener callbacks
+ * You can override this function to add your own listener callbacks
  *
  * @return array
  */
@@ -3361,11 +3361,19 @@ class Model extends Object implements CakeEventListener {
 /**
  * Returns false if any fields passed match any (by default, all if $or = false) of their matching values.
  *
+ * Can be used as a validation method. When used as a validation method, the `$or` parameter
+ * contains an array of fields to be validated.
+ *
  * @param array $fields Field/value pairs to search (if no values specified, they are pulled from $this->data)
- * @param bool $or If false, all fields specified must match in order for a false return value
+ * @param bool|array $or If false, all fields specified must match in order for a false return value
  * @return bool False if any records matching any fields are found
  */
 	public function isUnique($fields, $or = true) {
+		if (is_array($or)) {
+			$args = func_get_args();
+			$fields = $args[1];
+			$or = isset($args[2]) ? $args[2] : true;
+		}
 		if (!is_array($fields)) {
 			$fields = func_get_args();
 			if (is_bool($fields[count($fields) - 1])) {
diff --git a/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php b/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php
index 7f70ea82c..534aaa1ed 100644
--- a/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php
+++ b/lib/Cake/Test/Case/Model/Datasource/CakeSessionTest.php
@@ -280,7 +280,7 @@ class CakeSessionTest extends CakeTestCase {
  * @return void
  */
 	public function testReadyEmpty() {
-		$this->assertFalse(TestCakeSession::read(''));
+		$this->assertNull(TestCakeSession::read(''));
 	}
 
 /**
diff --git a/lib/Cake/Test/Case/Model/ModelReadTest.php b/lib/Cake/Test/Case/Model/ModelReadTest.php
index 294ce636f..b684f06d0 100644
--- a/lib/Cake/Test/Case/Model/ModelReadTest.php
+++ b/lib/Cake/Test/Case/Model/ModelReadTest.php
@@ -6550,12 +6550,43 @@ class ModelReadTest extends BaseModelTest {
 		}
 	}
 
+/**
+ * Test that find() with array conditions works when there is only one element.
+ *
+ * @return void
+ */
+	public function testFindAllArrayConditions() {
+		$this->loadFixtures('User');
+		$TestModel = new User();
+		$TestModel->cacheQueries = false;
+
+		$result = $TestModel->find('all', array(
+			'conditions' => array('User.id' => array(3)),
+		));
+		$expected = array(
+			array(
+				'User' => array(
+					'id' => '3',
+					'user' => 'larry',
+					'password' => '5f4dcc3b5aa765d61d8327deb882cf99',
+					'created' => '2007-03-17 01:20:23',
+					'updated' => '2007-03-17 01:22:31'
+			))
+		);
+		$this->assertEquals($expected, $result);
+
+		$result = $TestModel->find('all', array(
+			'conditions' => array('User.user' => array('larry')),
+		));
+		$this->assertEquals($expected, $result);
+	}
+
 /**
  * test find('list') method
  *
  * @return void
  */
-	public function testGenerateFindList() {
+	public function testFindList() {
 		$this->loadFixtures('Article', 'Apple', 'Post', 'Author', 'User', 'Comment');
 
 		$TestModel = new Article();
@@ -6825,6 +6856,32 @@ class ModelReadTest extends BaseModelTest {
 		$this->assertEquals($expected, $result);
 	}
 
+/**
+ * Test that find(list) works with array conditions that have only one element.
+ *
+ * @return void
+ */
+	public function testFindListArrayCondition() {
+		$this->loadFixtures('User');
+		$TestModel = new User();
+		$TestModel->cacheQueries = false;
+
+		$result = $TestModel->find('list', array(
+			'fields' => array('id', 'user'),
+			'conditions' => array('User.id' => array(3)),
+		));
+		$expected = array(
+			3 => 'larry'
+		);
+		$this->assertEquals($expected, $result);
+
+		$result = $TestModel->find('list', array(
+			'fields' => array('id', 'user'),
+			'conditions' => array('User.user' => array('larry')),
+		));
+		$this->assertEquals($expected, $result);
+	}
+
 /**
  * testFindField method
  *
diff --git a/lib/Cake/Test/Case/Model/ModelValidationTest.php b/lib/Cake/Test/Case/Model/ModelValidationTest.php
index b04bbb46d..8c17e72a9 100644
--- a/lib/Cake/Test/Case/Model/ModelValidationTest.php
+++ b/lib/Cake/Test/Case/Model/ModelValidationTest.php
@@ -2405,6 +2405,50 @@ class ModelValidationTest extends BaseModelTest {
 		$this->assertEquals($expected, $result);
 	}
 
+/**
+ * Test the isUnique method when used as a validator for multiple fields.
+ *
+ * @return void
+ */
+	public function testIsUniqueValidator() {
+		$this->loadFixtures('Article');
+		$Article = ClassRegistry::init('Article');
+		$Article->validate = array(
+			'user_id' => array(
+				'duplicate' => array(
+					'rule' => array('isUnique', array('user_id', 'title'), false)
+				)
+			)
+		);
+		$data = array(
+			'user_id' => 1,
+			'title' => 'First Article',
+		);
+		$Article->create($data);
+		$this->assertFalse($Article->validates(), 'Contains a dupe');
+
+		$data = array(
+			'user_id' => 1,
+			'title' => 'Unique Article',
+		);
+		$Article->create($data);
+		$this->assertTrue($Article->validates(), 'Should pass');
+
+		$Article->validate = array(
+			'user_id' => array(
+				'duplicate' => array(
+					'rule' => array('isUnique', array('user_id', 'title'))
+				)
+			)
+		);
+		$data = array(
+			'user_id' => 1,
+			'title' => 'Unique Article',
+		);
+		$Article->create($data);
+		$this->assertFalse($Article->validates(), 'Should fail, conditions are combined with or');
+	}
+
 }
 
 /**
diff --git a/lib/Cake/Utility/Hash.php b/lib/Cake/Utility/Hash.php
index eae832d89..141dfd410 100644
--- a/lib/Cake/Utility/Hash.php
+++ b/lib/Cake/Utility/Hash.php
@@ -632,6 +632,9 @@ class Hash {
  */
 	public static function expand($data, $separator = '.') {
 		$result = array();
+
+		$stack = array();
+
 		foreach ($data as $flat => $value) {
 			$keys = explode($separator, $flat);
 			$keys = array_reverse($keys);
@@ -644,7 +647,24 @@ class Hash {
 					$k => $child
 				);
 			}
-			$result = self::merge($result, $child);
+
+			$stack[] = array($child, &$result);
+
+			while (!empty($stack)) {
+				foreach ($stack as $curKey => &$curMerge) {
+					foreach ($curMerge[0] as $key => &$val) {
+						if (!empty($curMerge[1][$key]) && (array)$curMerge[1][$key] === $curMerge[1][$key] && (array)$val === $val) {
+							$stack[] = array(&$val, &$curMerge[1][$key]);
+						} elseif ((int)$key === $key && isset($curMerge[1][$key])) {
+							$curMerge[1][] = $val;
+						} else {
+							$curMerge[1][$key] = $val;
+						}
+					}
+					unset($stack[$curKey]);
+				}
+				unset($curMerge);
+			}
 		}
 		return $result;
 	}
@@ -664,19 +684,28 @@ class Hash {
  * @link http://book.cakephp.org/2.0/en/core-utility-libraries/hash.html#Hash::merge
  */
 	public static function merge(array $data, $merge) {
-		$args = func_get_args();
-		$return = current($args);
+		$args = array_slice(func_get_args(), 1);
+		$return = $data;
 
-		while (($arg = next($args)) !== false) {
-			foreach ((array)$arg as $key => $val) {
-				if (!empty($return[$key]) && is_array($return[$key]) && is_array($val)) {
-					$return[$key] = self::merge($return[$key], $val);
-				} elseif (is_int($key) && isset($return[$key])) {
-					$return[] = $val;
-				} else {
-					$return[$key] = $val;
+		foreach ($args as &$curArg) {
+			$stack[] = array((array)$curArg, &$return);
+		}
+		unset($curArg);
+
+		while (!empty($stack)) {
+			foreach ($stack as $curKey => &$curMerge) {
+				foreach ($curMerge[0] as $key => &$val) {
+					if (!empty($curMerge[1][$key]) && (array)$curMerge[1][$key] === $curMerge[1][$key] && (array)$val === $val) {
+						$stack[] = array(&$val, &$curMerge[1][$key]);
+					} elseif ((int)$key === $key && isset($curMerge[1][$key])) {
+						$curMerge[1][] = $val;
+					} else {
+						$curMerge[1][$key] = $val;
+					}
 				}
+				unset($stack[$curKey]);
 			}
+			unset($curMerge);
 		}
 		return $return;
 	}