diff --git a/CHANGES.txt b/CHANGES.txt
index 46a2e2f798a0e41dd6a312ec22fb86d5887d4733_Q0hBTkdFUy50eHQ=..3aefd4db0de3b5241e2fcab096873f3dd87fa594_Q0hBTkdFUy50eHQ= 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,3 +1,8 @@
+Version 2.5.0 released 2012-03-29
+
+* New item_sort_key option for encoder to allow fine grained control of sorted
+  output
+
 Version 2.4.0 released 2012-03-06
 
 * New bigint_as_string option for encoder to trade JavaScript number precision
diff --git a/conf.py b/conf.py
index 46a2e2f798a0e41dd6a312ec22fb86d5887d4733_Y29uZi5weQ==..3aefd4db0de3b5241e2fcab096873f3dd87fa594_Y29uZi5weQ== 100644
--- a/conf.py
+++ b/conf.py
@@ -42,5 +42,5 @@
 # other places throughout the built documents.
 #
 # The short X.Y version.
-version = '2.4'
+version = '2.5'
 # The full version, including alpha/beta/rc tags.
@@ -46,5 +46,5 @@
 # The full version, including alpha/beta/rc tags.
-release = '2.4.0'
+release = '2.5.0'
 
 # There are two options for replacing |today|: either, you set today to some
 # non-false value, then it is used:
diff --git a/index.rst b/index.rst
index 46a2e2f798a0e41dd6a312ec22fb86d5887d4733_aW5kZXgucnN0..3aefd4db0de3b5241e2fcab096873f3dd87fa594_aW5kZXgucnN0 100644
--- a/index.rst
+++ b/index.rst
@@ -129,7 +129,7 @@
 Basic Usage
 -----------
 
-.. function:: dump(obj, fp[, skipkeys[, ensure_ascii[, check_circular[, allow_nan[, cls[, indent[, separators[, encoding[, default[, use_decimal[, namedtuple_as_object[, tuple_as_array[, **kw]]]]]]]]]]]]])
+.. function:: dump(obj, fp[, skipkeys[, ensure_ascii[, check_circular[, allow_nan[, cls[, indent[, separators[, encoding[, default[, use_decimal[, namedtuple_as_object[, tuple_as_array[, bigint_as_string[, sort_keys[, item_sort_key[, **kw]]]]]]]]]]]]]]]])
 
    Serialize *obj* as a JSON formatted stream to *fp* (a ``.write()``-supporting
    file-like object).
@@ -189,7 +189,10 @@
    .. versionchanged:: 2.2.0
       The default of *use_decimal* changed to ``True`` in 2.2.0.
 
-  If *namedtuple_as_object* is true (default: ``True``),
-  objects with ``_asdict()`` methods will be encoded
-  as JSON objects.
+   If *namedtuple_as_object* is true (default: ``True``),
+   objects with ``_asdict()`` methods will be encoded
+   as JSON objects.
+
+   .. versionchanged:: 2.2.0
+     *namedtuple_as_object* is new in 2.2.0.
 
@@ -195,4 +198,11 @@
 
-  .. versionchanged:: 2.2.0
-    *namedtuple_as_object* is new in 2.2.0.
+   .. versionchanged:: 2.3.0
+     *namedtuple_as_object* no longer requires that these objects be
+     subclasses of :class:`tuple`.
+
+   If *tuple_as_array* is true (default: ``True``),
+   :class:`tuple` (and subclasses) will be encoded as JSON arrays.
+
+   .. versionchanged:: 2.2.0
+     *tuple_as_array* is new in 2.2.0.
 
@@ -198,5 +208,9 @@
 
-  .. versionchanged:: 2.3.0
-    *namedtuple_as_object* no longer requires that these objects be
-    subclasses of :class:`tuple`.
+   If *bigint_as_string* is true (default: ``False``), :class:`int`` ``2**53``
+   and higher or lower than ``-2**53`` will be encoded as strings. This is to
+   avoid the rounding that happens in Javascript otherwise. Note that this
+   option loses type information, so use with extreme caution.
+
+   .. versionchanged:: 2.4.0
+     *bigint_as_string* is new in 2.4.0.
 
@@ -202,4 +216,5 @@
 
-  If *tuple_as_array* is true (default: ``True``),
-  :class:`tuple` (and subclasses) will be encoded as JSON arrays.
+   If *sort_keys* is true (not the default), then the output of dictionaries
+   will be sorted by key; this is useful for regression tests to ensure that
+   JSON serializations can be compared on a day-to-day basis.
 
@@ -205,6 +220,11 @@
 
-  .. versionchanged:: 2.2.0
-    *tuple_as_array* is new in 2.2.0.
+   If *item_sort_key* is a callable (not the default), then the output of
+   dictionaries will be sorted with it. The callable will be used like this:
+   ``sorted(dct.items(), key=sort_item_key)``. This option takes precedence
+   over *sort_keys*.
+
+   .. versionchanged:: 2.5.0
+      *item_sort_key* is new in 2.5.0.
 
     .. note::
 
@@ -213,7 +233,7 @@
         container protocol to delimit them.
 
 
-.. function:: dumps(obj[, skipkeys[, ensure_ascii[, check_circular[, allow_nan[, cls[, indent[, separators[, encoding[, default[, use_decimal[, namedtuple_as_object[, tuple_as_array[, **kw]]]]]]]]]]]]])
+.. function:: dumps(obj[, skipkeys[, ensure_ascii[, check_circular[, allow_nan[, cls[, indent[, separators[, encoding[, default[, use_decimal[, namedtuple_as_object[, tuple_as_array[, bigint_as_string[, sort_keys[, item_sort_key[, **kw]]]]]]]]]]]]]]]])
 
    Serialize *obj* to a JSON formatted :class:`str`.
 
@@ -410,7 +430,7 @@
       :exc:`JSONDecodeError` will be raised if the given JSON
       document is not valid.
 
-.. class:: JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default[, use_decimal[, namedtuple_as_object[, tuple_as_array]]]]]]]]]]]])
+.. class:: JSONEncoder([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default[, use_decimal[, namedtuple_as_object[, tuple_as_array[, bigint_as_string[, item_sort_key]]]]]]]]]]]]])
 
    Extensible JSON encoder for Python data structures.
 
@@ -465,6 +485,14 @@
    will be sorted by key; this is useful for regression tests to ensure that
    JSON serializations can be compared on a day-to-day basis.
 
+   If *item_sort_key* is a callable (not the default), then the output of
+   dictionaries will be sorted with it. The callable will be used like this:
+   ``sorted(dct.items(), key=sort_item_key)``. This option takes precedence
+   over *sort_keys*.
+
+   .. versionchanged:: 2.5.0
+      *item_sort_key* is new in 2.5.0.
+
    If *indent* is a string, then JSON array elements and object members
    will be pretty-printed with a newline followed by that string repeated
    for each level of nesting. ``None`` (the default) selects the most compact
@@ -504,6 +532,15 @@
    .. versionchanged:: 2.2.0
      *tuple_as_array* is new in 2.2.0.
 
+   If *bigint_as_string* is true (default: ``False``), :class:`int`` ``2**53``
+   and higher or lower than ``-2**53`` will be encoded as strings. This is to
+   avoid the rounding that happens in Javascript otherwise. Note that this
+   option loses type information, so use with extreme caution.
+
+   .. versionchanged:: 2.4.0
+     *bigint_as_string* is new in 2.4.0.
+
+
    .. method:: default(o)
 
       Implement this method in a subclass such that it returns a serializable
@@ -544,7 +581,7 @@
       Note that :meth:`encode` has much better performance than
       :meth:`iterencode`.
 
-.. class:: JSONEncoderForHTML([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default]]]]]]]]])
+.. class:: JSONEncoderForHTML([skipkeys[, ensure_ascii[, check_circular[, allow_nan[, sort_keys[, indent[, separators[, encoding[, default[, use_decimal[, namedtuple_as_object[, tuple_as_array[, bigint_as_string[, item_sort_key]]]]]]]]]]]]])
 
    Subclass of :class:`JSONEncoder` that escapes &, <, and > for embedding in HTML.
 
diff --git a/setup.py b/setup.py
index 46a2e2f798a0e41dd6a312ec22fb86d5887d4733_c2V0dXAucHk=..3aefd4db0de3b5241e2fcab096873f3dd87fa594_c2V0dXAucHk= 100644
--- a/setup.py
+++ b/setup.py
@@ -7,7 +7,7 @@
     DistutilsPlatformError
 
 IS_PYPY = hasattr(sys, 'pypy_translation_info')
-VERSION = '2.4.0'
+VERSION = '2.5.0'
 DESCRIPTION = "Simple, fast, extensible JSON encoder/decoder for Python"
 LONG_DESCRIPTION = open('README.rst', 'r').read()
 
diff --git a/simplejson/__init__.py b/simplejson/__init__.py
index 46a2e2f798a0e41dd6a312ec22fb86d5887d4733_c2ltcGxlanNvbi9fX2luaXRfXy5weQ==..3aefd4db0de3b5241e2fcab096873f3dd87fa594_c2ltcGxlanNvbi9fX2luaXRfXy5weQ== 100644
--- a/simplejson/__init__.py
+++ b/simplejson/__init__.py
@@ -97,7 +97,7 @@
     $ echo '{ 1.2:3.4}' | python -m simplejson.tool
     Expecting property name: line 1 column 2 (char 2)
 """
-__version__ = '2.4.0'
+__version__ = '2.5.0'
 __all__ = [
     'dump', 'dumps', 'load', 'loads',
     'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
@@ -101,7 +101,7 @@
 __all__ = [
     'dump', 'dumps', 'load', 'loads',
     'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
-    'OrderedDict', 'simple_first'
+    'OrderedDict', 'simple_first',
 ]
 
 __author__ = 'Bob Ippolito <bob@redivi.com>'
@@ -146,7 +146,8 @@
         allow_nan=True, cls=None, indent=None, separators=None,
         encoding='utf-8', default=None, use_decimal=True,
         namedtuple_as_object=True, tuple_as_array=True,
-        bigint_as_string=False, item_sort_key=None, **kw):
+        bigint_as_string=False, sort_keys=False, item_sort_key=None,
+        **kw):
     """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
     ``.write()``-supporting file-like object).
 
@@ -203,7 +204,11 @@
 
     If specified, *item_sort_key* is a callable used to sort the items in
     each dictionary. This is useful if you want to sort items other than
-    in alphabetical order by key.
+    in alphabetical order by key. This option takes precedence over
+    *sort_keys*.
+
+    If *sort_keys* is true (default: ``False``), the output of dictionaries
+    will be sorted by item.
 
     To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
     ``.default()`` method to serialize additional types), specify it with
@@ -228,6 +233,7 @@
             namedtuple_as_object=namedtuple_as_object,
             tuple_as_array=tuple_as_array,
             bigint_as_string=bigint_as_string,
+            sort_keys=sort_keys,
             item_sort_key=item_sort_key,
             **kw).iterencode(obj)
     # could accelerate with writelines in some versions of Python, at
@@ -240,7 +246,7 @@
         allow_nan=True, cls=None, indent=None, separators=None,
         encoding='utf-8', default=None, use_decimal=True,
         namedtuple_as_object=True, tuple_as_array=True,
-        bigint_as_string=False, item_sort_key=None,
+        bigint_as_string=False, sort_keys=False, item_sort_key=None,
         **kw):
     """Serialize ``obj`` to a JSON formatted ``str``.
 
@@ -287,9 +293,9 @@
     If *tuple_as_array* is true (default: ``True``),
     :class:`tuple` (and subclasses) will be encoded as JSON arrays.
 
-    If bigint_as_string is true (not the default), ints 2**53 and higher
+    If *bigint_as_string* is true (not the default), ints 2**53 and higher
     or lower than -2**53 will be encoded as strings. This is to avoid the
     rounding that happens in Javascript otherwise.
 
     If specified, *item_sort_key* is a callable used to sort the items in
     each dictionary. This is useful if you want to sort items other than
@@ -291,9 +297,13 @@
     or lower than -2**53 will be encoded as strings. This is to avoid the
     rounding that happens in Javascript otherwise.
 
     If specified, *item_sort_key* is a callable used to sort the items in
     each dictionary. This is useful if you want to sort items other than
-    in alphabetical order by key.
+    in alphabetical order by key. This option takes precendence over
+    *sort_keys*.
+
+    If *sort_keys* is true (default: ``False``), the output of dictionaries
+    will be sorted by item.
 
     To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
     ``.default()`` method to serialize additional types), specify it with
@@ -306,7 +316,8 @@
         cls is None and indent is None and separators is None and
         encoding == 'utf-8' and default is None and use_decimal
         and namedtuple_as_object and tuple_as_array
-        and not bigint_as_string and not item_sort_key and not kw):
+        and not bigint_as_string and not sort_keys
+        and not item_sort_key and not kw):
         return _default_encoder.encode(obj)
     if cls is None:
         cls = JSONEncoder
@@ -318,6 +329,7 @@
         namedtuple_as_object=namedtuple_as_object,
         tuple_as_array=tuple_as_array,
         bigint_as_string=bigint_as_string,
+        sort_keys=sort_keys,
         item_sort_key=item_sort_key,
         **kw).encode(obj)
 
@@ -495,4 +507,4 @@
     """Helper function to pass to item_sort_key to sort simple
     elements to the top, then container elements.
     """
-    return isinstance(kv[1],(list,dict,tuple)), kv[0]
+    return (isinstance(kv[1], (list, dict, tuple)), kv[0])
diff --git a/simplejson/_speedups.c b/simplejson/_speedups.c
index 46a2e2f798a0e41dd6a312ec22fb86d5887d4733_c2ltcGxlanNvbi9fc3BlZWR1cHMuYw==..3aefd4db0de3b5241e2fcab096873f3dd87fa594_c2ltcGxlanNvbi9fc3BlZWR1cHMuYw== 100644
--- a/simplejson/_speedups.c
+++ b/simplejson/_speedups.c
@@ -2361,9 +2361,9 @@
         */
     }
 
-	if (PyCallable_Check(s->item_sort_key)) {
+    if (PyCallable_Check(s->item_sort_key)) {
         if (PyDict_CheckExact(dct))
             items = PyDict_Items(dct);
         else
             items = PyMapping_Items(dct);
         PyObject_CallMethod(items, "sort", "OO", Py_None, s->item_sort_key);
@@ -2365,9 +2365,9 @@
         if (PyDict_CheckExact(dct))
             items = PyDict_Items(dct);
         else
             items = PyMapping_Items(dct);
         PyObject_CallMethod(items, "sort", "OO", Py_None, s->item_sort_key);
-	}
+    }
     else if (PyObject_IsTrue(s->sort_keys)) {
         /* First sort the keys then replace them with (key, value) tuples. */
         Py_ssize_t i, nitems;
diff --git a/simplejson/encoder.py b/simplejson/encoder.py
index 46a2e2f798a0e41dd6a312ec22fb86d5887d4733_c2ltcGxlanNvbi9lbmNvZGVyLnB5..3aefd4db0de3b5241e2fcab096873f3dd87fa594_c2ltcGxlanNvbi9lbmNvZGVyLnB5 100644
--- a/simplejson/encoder.py
+++ b/simplejson/encoder.py
@@ -358,6 +358,8 @@
         str=str,
         tuple=tuple,
     ):
+    if _item_sort_key and not callable(_item_sort_key):
+        raise TypeError("item_sort_key must be None or callable")
 
     def _iterencode_list(lst, _current_indent_level):
         if not lst:
diff --git a/simplejson/tests/test_item_sort_key.py b/simplejson/tests/test_item_sort_key.py
index 46a2e2f798a0e41dd6a312ec22fb86d5887d4733_c2ltcGxlanNvbi90ZXN0cy90ZXN0X2l0ZW1fc29ydF9rZXkucHk=..3aefd4db0de3b5241e2fcab096873f3dd87fa594_c2ltcGxlanNvbi90ZXN0cy90ZXN0X2l0ZW1fc29ydF9rZXkucHk= 100644
--- a/simplejson/tests/test_item_sort_key.py
+++ b/simplejson/tests/test_item_sort_key.py
@@ -5,6 +5,6 @@
 
 class TestItemSortKey(TestCase):
     def test_simple_first(self):
-        a={'a': 1, 'c': 5, 'jack': 'jill', 'pick': 'axe', 'array': [1, 5, 6, 9], 'tuple': (83, 12, 3), 'crate': 'dog', 'zeak': 'oh'}
+        a = {'a': 1, 'c': 5, 'jack': 'jill', 'pick': 'axe', 'array': [1, 5, 6, 9], 'tuple': (83, 12, 3), 'crate': 'dog', 'zeak': 'oh'}
         self.assertEquals(
             '{"a": 1, "c": 5, "crate": "dog", "jack": "jill", "pick": "axe", "zeak": "oh", "array": [1, 5, 6, 9], "tuple": [83, 12, 3]}',
@@ -9,5 +9,5 @@
         self.assertEquals(
             '{"a": 1, "c": 5, "crate": "dog", "jack": "jill", "pick": "axe", "zeak": "oh", "array": [1, 5, 6, 9], "tuple": [83, 12, 3]}',
-            json.dumps(a,item_sort_key=json.simple_first))
+            json.dumps(a, item_sort_key=json.simple_first))
 
     def test_case(self):
@@ -12,5 +12,5 @@
 
     def test_case(self):
-        a={'a': 1, 'c': 5, 'Jack': 'jill', 'pick': 'axe', 'Array': [1, 5, 6, 9], 'tuple': (83, 12, 3), 'crate': 'dog', 'zeak': 'oh'}
+        a = {'a': 1, 'c': 5, 'Jack': 'jill', 'pick': 'axe', 'Array': [1, 5, 6, 9], 'tuple': (83, 12, 3), 'crate': 'dog', 'zeak': 'oh'}
         self.assertEquals(
             '{"Array": [1, 5, 6, 9], "Jack": "jill", "a": 1, "c": 5, "crate": "dog", "pick": "axe", "tuple": [83, 12, 3], "zeak": "oh"}',
@@ -15,5 +15,5 @@
         self.assertEquals(
             '{"Array": [1, 5, 6, 9], "Jack": "jill", "a": 1, "c": 5, "crate": "dog", "pick": "axe", "tuple": [83, 12, 3], "zeak": "oh"}',
-            json.dumps(a,item_sort_key=itemgetter(0)))
+            json.dumps(a, item_sort_key=itemgetter(0)))
         self.assertEquals(
             '{"a": 1, "Array": [1, 5, 6, 9], "c": 5, "crate": "dog", "Jack": "jill", "pick": "axe", "tuple": [83, 12, 3], "zeak": "oh"}',
@@ -18,4 +18,3 @@
         self.assertEquals(
             '{"a": 1, "Array": [1, 5, 6, 9], "c": 5, "crate": "dog", "Jack": "jill", "pick": "axe", "tuple": [83, 12, 3], "zeak": "oh"}',
-            json.dumps(a,item_sort_key=lambda kv: kv[0].lower()))
-
+            json.dumps(a, item_sort_key=lambda kv: kv[0].lower()))