diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7e1cccce107dcfc60d0429cc126efdb4f79ce159..40969bf5ec771daa587adb4d99691a97e52ac277 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,7 @@
 # v2.1.11
 
-* _TBA_
+* bugfix release: __all__ in [coding](satella/coding/__init__.py) fixed
+* more docs
 
 # v2.1.10
 
diff --git a/docs/coding/concurrent.rst b/docs/coding/concurrent.rst
index d7f2aaaca0c06825190f832c3804b85314afb5a8..78bdc2bbe55a5b1c67875ce374ce0c60906877c4 100644
--- a/docs/coding/concurrent.rst
+++ b/docs/coding/concurrent.rst
@@ -1,3 +1,6 @@
+Concurrent data structures
+==========================
+
 CallableGroup
 -------------
 
diff --git a/docs/coding/functions.rst b/docs/coding/functions.rst
new file mode 100644
index 0000000000000000000000000000000000000000..3c5c4bcb067d5db552075f653f2876a7867d0c7e
--- /dev/null
+++ b/docs/coding/functions.rst
@@ -0,0 +1,19 @@
+Functions
+=========
+
+.. autofunction:: satella.coding.merge_dicts
+
+.. autofunction:: satella.coding.static_var
+
+.. autofunction:: satella.coding.silence_excs
+
+.. autoclass:: satella.coding.rethrow_as
+    :members:
+
+.. autofunction:: satella.coding.precondition
+
+.. autofunction:: satella.coding.for_argument
+
+
+
+
diff --git a/docs/coding/structures.rst b/docs/coding/structures.rst
index 25b881ec50876c5ee456b9ba4148afaee79956ac..a385f7118325f21c89e905c5fcdb5763b47350ef 100644
--- a/docs/coding/structures.rst
+++ b/docs/coding/structures.rst
@@ -1,3 +1,8 @@
+Structures
+==========
+
+The following is a guide to all the data structures that Satella defines.
+
 Heap
 ----
 
@@ -25,7 +30,36 @@ try to assign something else there.
 .. autofunction:: satella.coding.typednamedtuple
 
 
+
+OmniHashableMixin
+-----------------
+
+If you need quick __hash__ and __eq__ operators from listed fields of the class.
+
+.. autoclass:: satella.coding.OmniHashableMixin
+    :members:
+
+.. autofunction:: satella.coding.typednamedtuple
+
+
 Singleton
 ---------
 
+Makes the resulting object's ``__init__()`` be called at most once, then caches the object and returns the same
+upon each instantiation.
+
 .. autofunction:: satella.coding.Singleton
+
+DictObject
+----------
+
+DictObject is an object constructed out of a dict, that allows it's values to be obtained as getattr(), and not only
+getitem().
+
+.. autoclass:: satella.coding.DictObject
+    :members:
+
+You can use the following function to recursively turn every dict into a DictObject
+
+.. autofunction:: satella.coding.apply_dict_object
+
diff --git a/docs/index.rst b/docs/index.rst
index 8b02f2ea49a261cb0eee25c86c68aacebc060cae..bea568620e6a1a322e7845644b4fb1734e2aef5f 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -9,10 +9,12 @@ Welcome to satella's documentation!
            configuration/schema
            configuration/sources
            coding/monitor
+           coding/functions
            coding/structures
            coding/concurrent
            instrumentation/traceback
            instrumentation/metrics
+           json
            posix
            recipes
 
diff --git a/docs/json.rst b/docs/json.rst
new file mode 100644
index 0000000000000000000000000000000000000000..5cab7d1281149e98dcbd3663e6feda7e01e448f2
--- /dev/null
+++ b/docs/json.rst
@@ -0,0 +1,18 @@
+JSON
+====
+
+In order to better support JSON, you should declare each of your class that supports being converted to JSON
+with
+
+.. autoclass:: satella.json.JSONAble
+    :members:
+
+Then you can convert structures made out of standard serializable Python JSON objects, such as dicts
+and lists, and also JSONAble objects, by this all
+
+.. autofunction:: satella.json.json_encode
+
+You might also want to check out the JSONEncoder satella uses to do it.
+
+.. autoclass:: satella.json.JSONEncoder
+    :members:
diff --git a/docs/posix.rst b/docs/posix.rst
index fef31514d3f04930c5bcb564e3dda717c4170c72..7e9e789f6ff6525141eb400bd4fa941d562b42dc 100644
--- a/docs/posix.rst
+++ b/docs/posix.rst
@@ -1,3 +1,6 @@
+POSIX-specifics
+===============
+
 suicide
 -------
 
diff --git a/satella/__init__.py b/satella/__init__.py
index 4c95db2cc2112f2786d0486efd82f772a323769b..e314eee206fd0a518482fb650457609b8fedd842 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1,3 +1,3 @@
 # coding=UTF-8
-__version__ = '2.1.11a1'
+__version__ = '2.1.11'
 
diff --git a/satella/coding/__init__.py b/satella/coding/__init__.py
index e1022583b78f740fb26bd460d287c9f95c0b2c41..f6087502b4f7dcb957fecd13e46cc8eb0bca1833 100644
--- a/satella/coding/__init__.py
+++ b/satella/coding/__init__.py
@@ -12,7 +12,7 @@ from .fun_static import static_var
 
 
 __all__ = [
-    'typednamedtuple', 'OmniHashableMixin'
+    'typednamedtuple', 'OmniHashableMixin',
                        'TimeBasedHeap', 'Heap', 'CallableGroup', 'DictObject', 'apply_dict_object',
     'Monitor', 'RMonitor', 'CallableGroup', 'LockedDataset', 'merge_dicts',
     'for_argument',
diff --git a/satella/coding/algos.py b/satella/coding/algos.py
index db2f1d6bc777b7ec8f6edc5d52cd57ef62e73aab..d81879b20c58b2534f7865e0e086c771cd196d71 100644
--- a/satella/coding/algos.py
+++ b/satella/coding/algos.py
@@ -4,6 +4,11 @@ __all__ = ['merge_dicts']
 
 
 def merge_dicts(v1: tp.Any, v2: tp.Any) -> tp.Any:
+    """
+    Try to merge two dicts/list together. If key collision is found, value from v2 will be taken.
+
+    Lists will be concatenated, and dicts updated. v1 will be updated in-place!
+    """
     if isinstance(v1, dict) and isinstance(v2, dict):
         for k in v2.keys():
             try:
diff --git a/satella/coding/decorators.py b/satella/coding/decorators.py
index c503a3ebfa46fc8f860262571705f338ef7639f7..d670578727e5d75308a3ca8d7d9370c7c147461d 100644
--- a/satella/coding/decorators.py
+++ b/satella/coding/decorators.py
@@ -17,15 +17,15 @@ def precondition(*t_ops):
 
     You can do it like this:
 
-    @precondition(lambda x: x == 1)
-    def return_two(x):
-        return x*2
+    >>> @precondition(lambda x: x == 1)
+    >>> def return_two(x):
+    >>>     return x*2
 
     or
 
-    @precondition('x == 1')
-    def return_two(x):
-        ..
+    >>> @precondition('x == 1')
+    >>> def return_two(x):
+    >>>     ..
 
     If None is passed then argument will be always assumed to be True.
     You can use all standard locals in precondition.
@@ -69,17 +69,16 @@ def precondition(*t_ops):
 
 def for_argument(*t_ops, **t_kwops):
     """
-    Calls a callable for each of the arguments.
+    Calls a callable for each of the arguments. Pass None if you do not wish to process given argument.
 
     returns is a special keyword, a callable to process the result through
 
     Use like:
 
-    @for_argument(int, str, typed=bool, returns=int)
-    def check(val1, val2, typed='True'):
-        if typed:
-            return val1 + int(val2)
-
+    >>> @for_argument(int, str, typed=bool, returns=int)
+    >>> def check(val1, val2, typed='True'):
+    >>>     if typed:
+    >>>         return val1 + int(val2)
     """
     t_ops = [_NOP if op == 'self' else op for op in t_ops]
     returns = t_kwops.pop('returns', _NOP)
diff --git a/satella/coding/fun_static.py b/satella/coding/fun_static.py
index a43cd27b515dcb94a315fd60db0aa09d7025418d..547c0f9e8c19940469fa8bcacfbfd3a4eb6da31e 100644
--- a/satella/coding/fun_static.py
+++ b/satella/coding/fun_static.py
@@ -1,28 +1,21 @@
-import logging
-import typing
-import functools
-
-logger = logging.getLogger(__name__)
-
-
-def static_var(var_name, value):
+def static_var(var_name: str, starting_value):
     """
     Declare a static variable for given function
 
     Use it like:
 
-    @static_var('counter', 2)
-    def count():
-        count.counter += 1
+    >>> @static_var('counter', 2)
+    >>> def count():
+    >>>     count.counter += 1
 
     or:
 
-    class MyClass:
-        @static_var('counter', 2)
-        def count():
-            MyClass.counter += 1
+    >>> class MyClass:
+    >>>     @static_var('counter', 2)
+    >>>     def count():
+    >>>         MyClass.counter += 1
     """
     def decorate(func):
-        setattr(func, var_name, value)
+        setattr(func, var_name, starting_value)
         return func
     return decorate
diff --git a/satella/coding/recast_exceptions.py b/satella/coding/recast_exceptions.py
index e76b6906ce451a5ce0cbc77784760eff928c39bc..2d2386952aabf7b23e6d5aaa7fcaf4750cc9967a 100644
--- a/satella/coding/recast_exceptions.py
+++ b/satella/coding/recast_exceptions.py
@@ -1,8 +1,6 @@
 import functools
-import logging
 import typing as tp
 
-logger = logging.getLogger(__name__)
 
 __all__ = [
     'rethrow_as',
@@ -24,20 +22,20 @@ class rethrow_as:
     Transform some exceptions into others.
 
     Either a decorator or a context manager
-    """
 
-    def __init__(self, *pairs, **kwargs):
-        """
-        Pass tuples of (exception to catch - exception to transform to).
+    New exception will be created by calling exception to transform to with
+    repr of current one.
 
-        New exception will be created by calling exception to transform to with
-        repr of current one.
+    You can also provide just two exceptions, eg.
 
-        You can also provide just two exceptions, eg.
+    >>> rethrow_as(NameError, ValueError)
 
-          rethrow_as(NameError, ValueError)
+    If the second value is a None, exception will be silenced.
+    """
 
-        If the second value is a None, exception will be silenced.
+    def __init__(self, *pairs, **kwargs):
+        """
+        Pass tuples of (exception to catch - exception to transform to).
 
         :param exception_preprocessor: other callable/1 to use instead od repr.
             Should return a text
diff --git a/satella/coding/structures/singleton.py b/satella/coding/structures/singleton.py
index 99225b858ee35625eef2781a6c38b4257afd4502..2a4cea52dae2fee9203bcce1cd9d995a4aeaad43 100644
--- a/satella/coding/structures/singleton.py
+++ b/satella/coding/structures/singleton.py
@@ -1,6 +1,3 @@
-# coding=UTF-8
-from __future__ import print_function, absolute_import, division
-
 import functools
 
 
@@ -8,6 +5,7 @@ __all__ = [
     'Singleton',
 ]
 
+
 # Taken from https://wiki.python.org/moin/PythonDecoratorLibrary
 def Singleton(cls):
     """
@@ -15,9 +13,9 @@ def Singleton(cls):
 
     Usage:
 
-        @Singleton
-        class MyClass(object):
-            ...
+    >>> @Singleton
+    >>> class MyClass(object):
+    >>>     ...
     """
 
     cls.__new_old__ = cls.__new__
diff --git a/satella/coding/structures/structures.py b/satella/coding/structures/structures.py
index c3d0e12a2f542762913d8a66ae42b06fb62435bd..aff8d9eb6cd9c4c7347f2c6be35b0b3b0a712902 100644
--- a/satella/coding/structures/structures.py
+++ b/satella/coding/structures/structures.py
@@ -16,13 +16,31 @@ __all__ = [
 
 
 class OmniHashableMixin:
+    """
+    A mix-in. Provides hashing and equal comparison for your own class using specified fields.
+
+    Example of use:
+
+    class Point2D(OmniHashableMixin):
+        _HASH_FIELDS_TO_USE = ['x', 'y']
+
+        def __init__(self, x, y):
+            ...
+
+    and now class Point2D has defined __hash__ and __eq__ by these fields.
+    Do everything in your power to make specified fields immutable, as mutating them will result
+    in a different hash.
+    """
     _HASH_FIELDS_TO_USE = []
 
     def __hash__(self):
         return functools.reduce(operator.xor, (hash(getattr(self, fname)) \
                                                for fname in self._HASH_FIELDS_TO_USE))
 
-    def __eq__(self, other):
+    def __eq__(self, other: 'OmniHashableMixin') -> bool:
+        """
+        Note that this will only compare _HASH_FIELDS_TO_USE
+        """
         cons = lambda p: [getattr(p, fname) for fname in self._HASH_FIELDS_TO_USE]
         if cons(self) == cons(other):
             return True
@@ -32,7 +50,7 @@ class OmniHashableMixin:
         else:
             return False
 
-    def __ne__(self, other):
+    def __ne__(self, other: 'OmniHashableMixin') -> bool:
         return not self.__eq__(other)
 
 
@@ -93,6 +111,7 @@ class Heap(object):
     def pop(self) -> tp.Any:
         """
         Return smallest element of the heap.
+
         :raises IndexError: on empty heap
         """
         return heapq.heappop(self.heap)
@@ -120,7 +139,6 @@ class Heap(object):
         """
         Return an iterator returning all elements in this heap sorted ascending.
         State of the heap is not changed
-        :return: Iterator
         """
         heap = copy.copy(self.heap)
         while heap:
@@ -130,17 +148,16 @@ class Heap(object):
         """
         Return an iterator returning all elements in this heap sorted descending.
         State of the heap is not changed
-        :return: Iterator
         """
         return reversed(list(self.iter_ascending()))
 
     def __len__(self) -> int:
         return len(self.heap)
 
-    def __str__(self):
+    def __str__(self) -> str:
         return '<satella.coding.Heap: %s elements>' % (len(self, ))
 
-    def __repr__(self):
+    def __repr__(self) -> str:
         return u'<satella.coding.Heap>'
 
     def __contains__(self, item) -> bool:
@@ -204,6 +221,7 @@ class TimeBasedHeap(Heap):
         Return all elements less (sharp inequality) than particular value.
 
         This changes state of the heap
+
         :param less: value to compare against
         :return: Iterator
         """
diff --git a/satella/coding/structures/typednamedtuple.py b/satella/coding/structures/typednamedtuple.py
index a005b03e3c75ef63069cb2e2cbcaecc45f99cd4a..ab8a7615e9bdf827100908e057efc81669eb297c 100644
--- a/satella/coding/structures/typednamedtuple.py
+++ b/satella/coding/structures/typednamedtuple.py
@@ -25,10 +25,10 @@ def typednamedtuple(cls_name, *arg_name_type):
 
     For example:
 
-      tnt = typednamedtuple('tnt', ('x', float), ('y', float))
-      a = tnt('5.0', y=2)
+    >>> tnt = typednamedtuple('tnt', ('x', float), ('y', float))
+    >>> a = tnt('5.0', y=2)
 
-      a.x is float, a.y is float too
+    a.x is float, a.y is float too
     """
 
     fieldnames = []
diff --git a/satella/configuration/schema/descriptors.py b/satella/configuration/schema/descriptors.py
index 6fc817b32152063c8acc465802d4068569dbdaae..8927258822185b64b0055b3574e7111bb23b9deb 100644
--- a/satella/configuration/schema/descriptors.py
+++ b/satella/configuration/schema/descriptors.py
@@ -202,14 +202,14 @@ class Dict(Descriptor):
 
     Use like:
 
-        Dict([
-            create_key(String(), 'key_s'),
-            create_key(Integer(), 'key_i'),
-            create_key(Float(), 'key_f'),
-            create_key(String(), 'key_not_present', optional=True,
-                       default='hello world'),
-            create_key(IPv4(), 'ip_addr')
-        ])
+    >>> Dict([
+    >>>     create_key(String(), 'key_s'),
+    >>>     create_key(Integer(), 'key_i'),
+    >>>     create_key(Float(), 'key_f'),
+    >>>     create_key(String(), 'key_not_present', optional=True,
+    >>>                default='hello world'),
+    >>>     create_key(IPv4(), 'ip_addr')
+    >>>])
     """
     BASIC_MAKER = dict
     CHECKERS = [must_be_type(dict)]
@@ -312,11 +312,11 @@ def register_custom_descriptor(name: str):
 
     Use like:
 
-        @register_custom_descriptor('ipv6')
-        class IPv6(Regexp):
-            REGEXP = '(\A([0-9a-f]{1,4}:)' ...
+    >>> @register_custom_descriptor('ipv6')
+    >>> class IPv6(Regexp):
+    >>>     REGEXP = '(\A([0-9a-f]{1,4}:)' ...
 
-    name -- name under which it is supposed to be invokable
+    :param name: under which it is supposed to be invokable
     """
     def inner(cls):
         BASE_LOOKUP_TABLE[name] = cls
diff --git a/satella/exception_handling/dump_to_file.py b/satella/exception_handling/dump_to_file.py
index 1b7c759342421b12ef89cb2d11337f116b0b8196..1ade023034d7ba06ccbb8795171212447255599e 100644
--- a/satella/exception_handling/dump_to_file.py
+++ b/satella/exception_handling/dump_to_file.py
@@ -27,6 +27,8 @@ class AsStream:
 
     def __init__(self, o: AsStreamTypeAccept, human_readable: bool):
         """
+        A stream to dump to
+
         :param o: stream, or a file name to use, or None to use /dev/null
         :param human_readable: whether the output should be human-readable
             or a pickle (False for pickle)
@@ -84,6 +86,8 @@ class DumpToFileHandler(BaseExceptionHandler):
     def __init__(self, human_readables: tp.Iterable[AsStreamTypeAcceptHR],
                  trace_pickles: tp.Iterable[AsStreamTypeAcceptpIN] = None):
         """
+        Handler that dumps an exception to a file.
+
         :param human_readables: iterable of either a file-like objects, or paths where human-readable files will
             be output
         :param trace_pickles: iterable of either a file-like objects, or paths where pickles with stack status
diff --git a/satella/exception_handling/exception_handlers.py b/satella/exception_handling/exception_handlers.py
index 1c0c01307aa57643502230b1bc9234987539ad0d..cecc9f68ee07162cf4d557c07fd9b2b511a74681 100644
--- a/satella/exception_handling/exception_handlers.py
+++ b/satella/exception_handling/exception_handlers.py
@@ -51,9 +51,9 @@ def exception_handler(priority: int = NORMAL_PRIORITY):
     """
     Convert a callable to an FunctionExceptionHandler. Usage
 
-        @exception_handler(priority=-10)
-        def handle_exc(type, val, traceback):
-            ...
+    >>> @exception_handler(priority=-10)
+    >>> def handle_exc(type, val, traceback):
+    >>>     ...
 
     :return: ExceptionHandler instance
     """
diff --git a/satella/exception_handling/global_eh.py b/satella/exception_handling/global_eh.py
index c452d5b321dc4423e536f4e4fde354dd12efc9ea..f253f11ffa952616ccb1569f7d845d886bbc6e1d 100644
--- a/satella/exception_handling/global_eh.py
+++ b/satella/exception_handling/global_eh.py
@@ -29,6 +29,7 @@ class GlobalExcepthook:
     def remove_hook(self, hook: BaseExceptionHandler):
         """
         Unregister a hook
+
         :param hook: hook to remove
         :raise ValueError: if hook not in list
         """
diff --git a/satella/instrumentation/trace_back.py b/satella/instrumentation/trace_back.py
index bb094b855e2b10371c548b861932ea3aaf7a42b2..611f651042442e1a959c7ceab44a276b10276146 100644
--- a/satella/instrumentation/trace_back.py
+++ b/satella/instrumentation/trace_back.py
@@ -11,12 +11,12 @@ but that may involve an import.
 
 Use in such a way:
 
-    try:
-        ...
-    except WhateverError as e:
-        tp = Traceback()
-        print(tp.pretty_print())
-        # you can now pickle it if you wish to
+>>> try:
+>>>     ...
+>>> except WhateverError as e:
+>>>     tp = Traceback()
+>>>     print(tp.pretty_print())
+>>>     # you can now pickle it if you wish to
 """
 import inspect
 import io
diff --git a/satella/json.py b/satella/json.py
index e2adaa0c5f73989f1bfe55e27ce1d91c32f3bd7e..4881ad3f2afb81ff8ca51acb8eb67d98ea3bb83e 100644
--- a/satella/json.py
+++ b/satella/json.py
@@ -21,6 +21,7 @@ class JSONEncoder(json.JSONEncoder):
 def json_encode(x) -> str:
     """
     Convert an object to JSON. Will properly handle subclasses of JSONAble
+
     :param x: object to convert
     """
     return JSONEncoder().encode(x)