commit 4bc8021fb3142123ca424b38dcdcf02c222343c4
Author: Shikhar Bhushan <shikhar@schmizz.net>
Date:   Thu Oct 29 22:11:58 2009 +0100

    documentation in progress

diff --git a/docs/source/_templates/layout.html b/docs/source/_templates/layout.html
index f8b8756..db70786 100644
--- a/docs/source/_templates/layout.html
+++ b/docs/source/_templates/layout.html
@@ -1,7 +1,7 @@
 {% extends "!layout.html" %}
 {% block sidebarlogo %}
 <p align="center">
-  <a href="http://code.google.com/p/ncclient">
+  <a href="http://schmizz.net/ncclient">
     <img src="_static/logo.png" width="125" height="125"/>
   </a>
 </p>
diff --git a/docs/source/api.rst b/docs/source/api.rst
index 511ebfb..3a3fb19 100644
--- a/docs/source/api.rst
+++ b/docs/source/api.rst
@@ -1,8 +1,6 @@
 Complete API documentation
 ==========================
 
-**TODO**
-
 .. toctree::
     
     capabilities
diff --git a/docs/source/capabilities.rst b/docs/source/capabilities.rst
new file mode 100644
index 0000000..f38a26c
--- /dev/null
+++ b/docs/source/capabilities.rst
@@ -0,0 +1,9 @@
+:mod:`~ncclient.capabilities` -- NETCONF Capabilities
+=====================================================
+
+.. module:: ncclient.capabilities
+
+.. autofunction:: schemes
+
+.. autoclass:: Capabilities
+    :members:
\ No newline at end of file
diff --git a/docs/source/manager.rst b/docs/source/manager.rst
index 2ff31e9..0d01d24 100644
--- a/docs/source/manager.rst
+++ b/docs/source/manager.rst
@@ -1,84 +1,27 @@
 :mod:`~ncclient.manager` -- High-level API
 ==========================================
 
-.. module:: ncclient.manager
+.. automodule:: ncclient.manager
     :synopsis: High-level API
 
-.. data:: CAPABILITIES
+Module data
+-----------
 
-    List of URI strings representing the client's capabilities. This is used during the initial
-    capability exchange. Modify this if you need to announce some capability not already included.
+These attributes control what capabilties are exchanged with the NETCONF server and what operations
+are available through the `Manager` API.
 
-.. data:: OPERATIONS
-    
-    Dictionary of method names and corresponding `~ncclient.operations.RPC` classes. `Manager` uses
-    this to lookup operations, e.g. "get_config" is mapped to `ncclient.operations.GetConfig`. It
-    is thus possible to add additional operations to the `Manager` API.
+.. autodata:: CAPABILITIES
+
+.. autodata:: OPERATIONS
 
 Factory functions
 -----------------
 
 A `Manager` instance is created using a factory function.
 
-.. function:: connect_ssh(host[, port=830, timeout=None, unknown_host_cb=default_unknown_host_cb, username=None, password, key_filename=None, allow_agent=True, look_for_keys=True])
-    
-    Initializes a NETCONF session over SSH, and creates a connected `Manager` instance. *host* must
-    be specified, all the other arguments are optional and depend on the kind of host key
-    verification and user authentication you want to complete.
-    
-    For the purpose of host key verification, on -NIX systems a user's :file:`~/.ssh/known_hosts`
-    file is automatically considered. The *unknown_host_cb* argument specifies a callback that will
-    be invoked when the server's host key cannot be verified. See
-    :func:`~ncclient.transport.ssh.default_known_host_cb` for function signature.
-    
-    First, ``publickey`` authentication is attempted. If a specific *key_filename* is specified, it
-    will be loaded and authentication attempted using it. If *allow_agent* is :const:`True` and an
-    SSH agent is running, the keys provided by the agent will be tried. If *look_for_keys* is
-    :const:`True`, keys in the :file:`~/.ssh/id_rsa` and :file:`~.ssh/id_dsa` will be tried. In case
-    an encrypted key file is encountered, the *password* argument will be used as a decryption
-    passphrase.
-    
-    If ``publickey`` authentication fails and the *password* argument has been supplied,
-    ``password`` / ``keyboard-interactive`` SSH authentication will be attempted.
-    
-    :param host: hostname or address on which to connect
-    :type host: `string`
-    
-    :param port: port on which to connect
-    :type port: `int`
-    
-    :param timeout: timeout for socket connect
-    :type timeout: `int`
-    
-    :param unknown_host_cb: optional; callback that is invoked when host key verification fails
-    :type unknown_host_cb: `function`
-    
-    :param username: username to authenticate with, if not specified the username of the logged-in
-                       user is used
-    :type username: `string`
-    
-    :param password: password for ``password`` authentication or passphrase for decrypting
-                       private key files
-    :type password: `string`
-    
-    :param key_filename: location of a private key file on the file system
-    :type key_filename: `string`
-    
-    :param allow_agent: whether to try connecting to SSH agent for keys
-    :type allow_agent: `bool`
-    
-    :param look_for_keys: whether to look in usual locations for keys
-    :type look_for_keys: `bool`
-    
-    :raises: :exc:`~ncclient.transport.SSHUnknownHostError`
-    :raises: :exc:`~ncclient.transport.AuthenticationError`
-    
-    :rtype: `Manager`
-    
-.. function:: connect()
+.. autofunction:: connect_ssh(host[, port=830, timeout=None, unknown_host_cb=default_unknown_host_cb, username=None, password, key_filename=None, allow_agent=True, look_for_keys=True])
 
-    Same as :func:`connect_ssh`, since SSH is the default (and currently, the
-    only) transport.
+.. autodata:: connect
 
 Manager
 -------
@@ -263,7 +206,7 @@ errors, e.g. unexpected session close, :exc:`~ncclient.transport.TransportError`
         Valid values:
         
         * ``"all"`` -- any kind of *rpc-error* (error or warning)
-        * ``"errors"`` -- where the *error-type* attribute says it is an error
+        * ``"errors"`` -- where the *error-type* element says it is an error
         * ``"none"`` -- neither
         
     .. attribute:: client_capabilities
diff --git a/docs/source/operations.rst b/docs/source/operations.rst
new file mode 100644
index 0000000..3a904dc
--- /dev/null
+++ b/docs/source/operations.rst
@@ -0,0 +1,44 @@
+:mod:`~ncclient.operations` -- Everything RPC
+=============================================
+
+Base classes
+------------
+
+.. module:: ncclient.operations
+    :synopsis: Everything RPC
+
+.. autoclass:: RPC(session[, async=False, timeout=None, raise_mode="none"])
+    :members: DEPENDS, REPLY_CLS, _assert, _request, request, event, error, reply, raise_mode, is_async, timeout
+
+.. autoclass:: RPCReply
+    :members: xml, ok, error, errors
+
+.. autoexception:: RPCError
+    :show-inheritance:
+    :members: type, severity, tag, path, message, info
+
+Operations
+----------
+
+*TODO* The operation classes are currently undocumented. See documentation of
+`~ncclient.manager.Manager` for methods that utilize the operation classes. The parameters accepted
+by :meth:`~RPC.request` for these classes are the same.
+
+Replies with data
+-----------------
+
+.. autoclass:: GetReply
+    :show-inheritance:
+    :members: data, data_ele, data_xml
+
+Exceptions
+----------
+
+.. autoexception:: OperationError
+    :show-inheritance:
+
+.. autoexception:: MissingCapabilityError
+    :show-inheritance:
+
+.. autoexception:: TimeoutExpiredError
+    :show-inheritance:
\ No newline at end of file
diff --git a/docs/source/transport.rst b/docs/source/transport.rst
new file mode 100644
index 0000000..f08716b
--- /dev/null
+++ b/docs/source/transport.rst
@@ -0,0 +1,44 @@
+:mod:`~ncclient.transport` -- Transport / Session layer
+=======================================================
+
+.. module:: ncclient.transport
+    :synopsis: Transport / Session layer
+
+Base types
+-----------
+
+.. autoclass:: Session
+    :members: add_listener, remove_listener, get_listener_instance, client_capabilities, server_capabilities, connected, id
+
+.. autoclass:: SessionListener
+    :members: callback, errback
+
+SSH session implementation
+--------------------------
+
+.. automethod:: ssh.default_unknown_host_cb
+
+.. autoclass:: SSHSession
+    :show-inheritance:
+    :members: load_known_hosts, close, transport
+
+    .. automethod:: connect(host[, port=830, timeout=None, username=None, password=None, key_filename=None, allow_agent=True, look_for_keys=True])
+
+Errors
+------
+
+.. autoexception:: TransportError
+    :show-inheritance:
+
+.. autoexception:: SessionCloseError
+    :show-inheritance:
+
+.. autoexception:: SSHError
+    :show-inheritance:
+
+.. autoexception:: AuthenticationError
+    :show-inheritance:
+
+.. autoexception:: SSHUnknownHostError
+    :show-inheritance:
+
diff --git a/docs/source/xml_.rst b/docs/source/xml_.rst
new file mode 100644
index 0000000..423d7fa
--- /dev/null
+++ b/docs/source/xml_.rst
@@ -0,0 +1,4 @@
+:mod:`~ncclient.xml_` -- XML Handling
+=====================================
+
+*TODO*
\ No newline at end of file
diff --git a/ncclient/capabilities.py b/ncclient/capabilities.py
index 3b9fcda..2087336 100644
--- a/ncclient/capabilities.py
+++ b/ncclient/capabilities.py
@@ -29,26 +29,23 @@ def _abbreviate(uri):
     return []
 
 def schemes(url_uri):
-    """Given a URI that has a *scheme* query string (i.e. *:url* capability
-    URI), will return a list of supported schemes.
+    """Given a URI that has a *scheme* query string (i.e. *:url* capability URI), will return a list
+    of supported schemes.
     """
     return url_uri.partition("?scheme=")[2].split(",")
 
 class Capabilities:
 
-    """Represents the set of capabilities available to a NETCONF client or
-    server.
+    """Represents the set of capabilities available to a NETCONF client or server. It is initialized
+    with a list of capability URI's. These can be iterated over.
     
-    Presence of a capability can be checked with the *in* operation. In addition
-    to the URI, for capabilities of the form
-    *urn:ietf:params:netconf:capability:$name:$version* their shorthand can be
-    used as a key. For example, for
-    *urn:ietf:params:netconf:capability:candidate:1.0* the shorthand would be
-    *:candidate*. If version is significant, use *:candidate:1.0* as key.
+    Presence of a capability can be checked with the *in* operation. In addition to the URI, for
+    capabilities of the form *urn:ietf:params:netconf:capability:$name:$version* their shorthand can
+    be used as a key. For example, for *urn:ietf:params:netconf:capability:candidate:1.0* the
+    shorthand would be *:candidate*. If version is significant, use *:candidate:1.0* as key.
     """
     
     def __init__(self, capabilities):
-        "Initializes with a list of capability URI's"
         self._dict = {}
         for uri in capabilities:
             self._dict[uri] = _abbreviate(uri)
@@ -74,15 +71,16 @@ class Capabilities:
         return self._dict.keys()
 
     def add(self, uri):
-        "Add a capability"
+        "Add a capability."
         self._dict[uri] = _abbreviate(uri)
 
     def remove(self, uri):
-        "Remove a capability"
+        "Remove a capability."
         if key in self._dict:
             del self._dict[key]
     
-    def get_uri(self, shorthand):
-        for uri, abbrs in self._dict.items():
-            if shorthand in abbrs:
-                return uri
+    #def get_uri(self, shorthand):
+    #    "Returns the URI that is inferred for a given shorthand."
+    #    for uri, abbrs in self._dict.items():
+    #        if shorthand in abbrs:
+    #            return uri
diff --git a/ncclient/manager.py b/ncclient/manager.py
index 3ab9317..d305c02 100644
--- a/ncclient/manager.py
+++ b/ncclient/manager.py
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-"Thin layer of abstraction around NCClient"
+"This module is a thin layer of abstraction around the library. It exposes all core functionality."
 
 import capabilities
 import operations
@@ -22,7 +22,6 @@ import logging
 logger = logging.getLogger('ncclient.manager')
 
 
-#: :class:`Capabilities` object representing the capabilities currently supported by NCClient
 CAPABILITIES = capabilities.Capabilities([
     "urn:ietf:params:netconf:base:1.0",
     "urn:ietf:params:netconf:capability:writable-running:1.0",
@@ -37,7 +36,10 @@ CAPABILITIES = capabilities.Capabilities([
     "urn:ietf:params:netconf:capability:interleave:1.0"
     #'urn:ietf:params:netconf:capability:notification:1.0', # TODO    
 ])
-
+"""`~ncclient.capabilities.Capabilities` object representing the client's capabilities. This is used
+during the initial capability exchange. Modify this if you need to announce some capability not
+already included.
+"""
 
 OPERATIONS = {
     "get": operations.Get,
@@ -55,17 +57,70 @@ OPERATIONS = {
     "poweroff_machine": operations.PoweroffMachine,
     "reboot_machine": operations.RebootMachine
 }
-
+"""Dictionary of method names and corresponding `~ncclient.operations.RPC` subclasses. `Manager`
+uses this to lookup operations, e.g. "get_config" is mapped to `~ncclient.operations.GetConfig`. It
+is thus possible to add additional operations to the `Manager` API.
+"""
 
 def connect_ssh(*args, **kwds):
+    """Initializes a NETCONF session over SSH, and creates a connected `Manager` instance. *host*
+    must be specified, all the other arguments are optional and depend on the kind of host key
+    verification and user authentication you want to complete.
+        
+    For the purpose of host key verification, on -NIX systems a user's :file:`~/.ssh/known_hosts`
+    file is automatically considered. The *unknown_host_cb* argument specifies a callback that will
+    be invoked when the server's host key cannot be verified. See
+    :func:`~ncclient.transport.ssh.default_unknown_host_cb` for function signature.
+    
+    First, ``publickey`` authentication is attempted. If a specific *key_filename* is specified, it
+    will be loaded and authentication attempted using it. If *allow_agent* is :const:`True` and an
+    SSH agent is running, the keys provided by the agent will be tried. If *look_for_keys* is
+    :const:`True`, keys in the :file:`~/.ssh/id_rsa` and :file:`~.ssh/id_dsa` will be tried. In case
+    an encrypted key file is encountered, the *password* argument will be used as a decryption
+    passphrase.
+    
+    If ``publickey`` authentication fails and the *password* argument has been supplied,
+    ``password`` / ``keyboard-interactive`` SSH authentication will be attempted.
+    
+    :param host: hostname or address on which to connect
+    :type host: `string`
+    
+    :param port: port on which to connect
+    :type port: `int`
+    
+    :param timeout: timeout for socket connect
+    :type timeout: `int`
+    
+    :param unknown_host_cb: optional; callback that is invoked when host key verification fails
+    :type unknown_host_cb: `function`
+    
+    :param username: username to authenticate with, if not specified the username of the logged-in user is used
+    :type username: `string`
+    
+    :param password: password for ``password`` authentication or passphrase for decrypting private key files
+    :type password: `string`
+    
+    :param key_filename: location of a private key file on the file system
+    :type key_filename: `string`
+    
+    :param allow_agent: whether to try connecting to SSH agent for keys
+    :type allow_agent: `bool`
+    
+    :param look_for_keys: whether to look in usual locations for keys
+    :type look_for_keys: `bool`
+    
+    :raises: :exc:`~ncclient.transport.SSHUnknownHostError`
+    :raises: :exc:`~ncclient.transport.AuthenticationError`
+    
+    :rtype: `Manager`
+    """    
     session = transport.SSHSession(CAPABILITIES)
     session.load_known_hosts()
     session.connect(*args, **kwds)
     return Manager(session)
 
-#: Same as :meth:`connect_ssh`
 connect = connect_ssh
-
+"Same as :func:`connect_ssh`, since SSH is the default (and currently, the only) transport."
 
 class Manager(object):
 
diff --git a/ncclient/operations/retrieve.py b/ncclient/operations/retrieve.py
index 3c847b3..90a0f9c 100644
--- a/ncclient/operations/retrieve.py
+++ b/ncclient/operations/retrieve.py
@@ -20,38 +20,35 @@ import util
 
 class GetReply(RPCReply):
 
-    """Adds attributes for the *<data>* element to :class:`RPCReply`, which
-    pertains to the :class:`Get` and :class:`GetConfig` operations."""
+    """Adds attributes for the *data* element to `RPCReply`. This pertains to the `Get` and
+    `GetConfig` operations."""
 
     def _parsing_hook(self, root):
         self._data = None
         if not self._errors:
             self._data = root.find(qualify("data"))
-
+    
     @property
     def data_ele(self):
-        "*<data>* element as an :class:`~xml.etree.ElementTree.Element`"
+        "*data* element as an `~xml.etree.ElementTree.Element`"
         if not self._parsed:
             self.parse()
         return self._data
 
     @property
     def data_xml(self):
-        "*<data>* element as an XML string"
+        "*data* element as an XML string"
         if not self._parsed:
             self.parse()
         return to_xml(self._data)
     
-    #: Same as :attr:`data_ele`
     data = data_ele
-    
-    #def __repr__(self):
-    #    return self.data_xml
+    "Same as :attr:`data_ele`"
 
 
 class Get(RPC):
 
-    "The *<get>* RPC"
+    "The *get* RPC."
 
     REPLY_CLS = GetReply
 
@@ -64,7 +61,7 @@ class Get(RPC):
 
 class GetConfig(RPC):
 
-    "The *<get-config>* RPC"
+    "The *get-config* RPC."
 
     REPLY_CLS = GetReply
 
diff --git a/ncclient/operations/rpc.py b/ncclient/operations/rpc.py
index a11cfa2..3fd7f2d 100644
--- a/ncclient/operations/rpc.py
+++ b/ncclient/operations/rpc.py
@@ -24,87 +24,10 @@ import logging
 logger = logging.getLogger("ncclient.operations.rpc")
 
 
-class RPCReply:
-
-    """Represents an *<rpc-reply>*. Only concerns itself with whether the
-    operation was successful.
-
-    .. note::
-        If the reply has not yet been parsed there is an implicit, one-time
-        parsing overhead to accessing the attributes defined by this class and
-        any subclasses.
-    """
-
-    def __init__(self, raw):
-        self._raw = raw
-        self._parsed = False
-        self._root = None
-        self._errors = []
-
-    def __repr__(self):
-        return self._raw
-
-    def _parsing_hook(self, root):
-        """Subclass can implement.
-
-        :type root: :class:`~xml.etree.ElementTree.Element`
-        """
-        pass
-
-    def parse(self):
-        """Parse the *<rpc-reply>*"""
-        if self._parsed:
-            return
-        root = self._root = to_ele(self._raw) # The <rpc-reply> element
-        # Per RFC 4741 an <ok/> tag is sent when there are no errors or warnings
-        ok = root.find(qualify("ok"))
-        if ok is None:
-            # Create RPCError objects from <rpc-error> elements
-            error = root.find(qualify("rpc-error"))
-            if error is not None:
-                for err in root.getiterator(error.tag):
-                    # Process a particular <rpc-error>
-                    self._errors.append(RPCError(err))
-        self._parsing_hook(root)
-        self._parsed = True
-
-    @property
-    def xml(self):
-        "*<rpc-reply>* as returned"
-        return self._raw
-
-    @property
-    def ok(self):
-        "Boolean value indicating if there were no errors."
-        if not self._parsed:
-            self.parse()
-        return not self._errors # empty list => false
-
-    @property
-    def error(self):
-        """Short for :attr:`errors` [0]; :const:`None` if there were no errors.
-        """
-        if not self._parsed:
-            self.parse()
-        if self._errors:
-            return self._errors[0]
-        else:
-            return None
-
-    @property
-    def errors(self):
-        """`list` of :class:`RPCError` objects. Will be empty if there were no
-        *<rpc-error>* elements in reply.
-        """
-        if not self._parsed:
-            self.parse()
-        return self._errors
-
-
 class RPCError(OperationError):
 
-    """Represents an *<rpc-error>*. It is a type of :exc:`OperationError`
-    and can be raised like any other exception."""
+    """Represents an *rpc-error*. It is a type of :exc:`OperationError` and can be raised like any
+    other exception."""
     
     tag_to_attr = {
         qualify("error-type"): "_type",
@@ -115,10 +38,11 @@ class RPCError(OperationError):
         qualify("error-message"): "_message"
     }
     
-    def __init__(self, err):
+    def __init__(self, raw):
+        self._raw = raw
         for attr in RPCError.tag_to_attr.values():
             setattr(self, attr, None)
-        for subele in err:
+        for subele in raw:
             attr = RPCError.tag_to_attr.get(subele.tag, None)
             if attr is not None:
                 setattr(self, attr, subele.text if attr != "_info" else to_xml(subele) )
@@ -130,37 +54,105 @@ class RPCError(OperationError):
     def to_dict(self):
         return dict([ (attr[1:], getattr(self, attr)) for attr in RPCError.tag_to_attr.values() ])
     
+    "*rpc-error* element as returned."
+    @property
+    def xml(self):
+        return self._raw
+    
     @property
     def type(self):
-        "`string` representing text of *error-type* element"
+        "`string` representing text of *error-type* element."
         return self._type
     
     @property
     def tag(self):
-        "`string` representing text of *error-tag* element"
+        "`string` representing text of *error-tag* element."
         return self._tag
     
     @property
     def severity(self):
-        "`string` representing text of *error-severity* element"
+        "`string` representing text of *error-severity* element."
         return self._severity
     
     @property
     def path(self):
-        "`string` or :const:`None`; representing text of *error-path* element"
+        "`string` or :const:`None`; representing text of *error-path* element."
         return self._path
     
     @property
     def message(self):
-        "`string` or :const:`None`; representing text of *error-message* element"
+        "`string` or :const:`None`; representing text of *error-message* element."
         return self._message
     
     @property
     def info(self):
-        "`string` (XML) or :const:`None`, representing *error-info* element"
+        "`string` (XML) or :const:`None`; representing *error-info* element."
         return self._info
 
 
+class RPCReply:
+
+    """Represents an *rpc-reply*. Only concerns itself with whether the operation was successful.
+
+    .. note::
+        If the reply has not yet been parsed there is an implicit, one-time parsing overhead to
+        accessing the attributes defined by this class and any subclasses.
+    """
+    
+    ERROR_CLS = RPCError
+    "Subclasses can specify a different error class, but it should be a subclass of `RPCError`."
+    
+    def __init__(self, raw):
+        self._raw = raw
+        self._parsed = False
+        self._root = None
+        self._errors = []
+
+    def __repr__(self):
+        return self._raw
+    
+    def parse(self):
+        "Parses the *rpc-reply*."
+        if self._parsed: return
+        root = self._root = to_ele(self._raw) # The <rpc-reply> element
+        # Per RFC 4741 an <ok/> tag is sent when there are no errors or warnings
+        ok = root.find(qualify("ok"))
+        if ok is None:
+            # Create RPCError objects from <rpc-error> elements
+            error = root.find(qualify("rpc-error"))
+            if error is not None:
+                for err in root.getiterator(error.tag):
+                    # Process a particular <rpc-error>
+                    self._errors.append(ERROR_CLS(err))
+        self._parsed = True
+    
+    @property
+    def xml(self):
+        "*rpc-reply* element as returned."
+        return self._raw
+    
+    @property
+    def ok(self):
+        "Boolean value indicating if there were no errors."
+        return not self.errors # empty list => false
+    
+    @property
+    def error(self):
+        "Returns the first `RPCError` and :const:`None` if there were no errors."
+        self.parse()
+        if self._errors:
+            return self._errors[0]
+        else:
+            return None
+    
+    @property
+    def errors(self):
+        """`list` of `RPCError` objects. Will be empty if there were no *rpc-error* elements in
+        reply."""
+        self.parse()
+        return self._errors
+
+
 class RPCReplyListener(SessionListener): # internal use
     
     creation_lock = Lock()
@@ -212,23 +204,19 @@ class RPCReplyListener(SessionListener): # internal use
 
 
 class RPC(object):
-
-    """Base class for all operations.
-
-    Directly corresponds to *<rpc>* requests. Handles making the request, and
-    taking delivery of the reply.
-    """
-
-    #: Subclasses can specify their dependencies on capabilities. List of URI's
-    # or abbreviated names, e.g. ':writable-running'. These are verified at the
-    # time of object creation. If the capability is not available, a
-    # :exc:`MissingCapabilityError` is raised.
+    
+    """Base class for all operations, directly corresponding to *rpc* requests. Handles making the
+    request, and taking delivery of the reply."""
+    
     DEPENDS = []
-
-    #: Subclasses can specify a different reply class, but it must be a
-    # subclass of :class:`RPCReply`.
+    """Subclasses can specify their dependencies on capabilities. List of URI's or abbreviated
+    names, e.g. ':writable-running'. These are verified at the time of instantiation. If the
+    capability is not available, a :exc:`MissingCapabilityError` is raised.
+    """
+    
     REPLY_CLS = RPCReply
-
+    "Subclasses can specify a different reply class, but it should be a subclass of `RPCReply`."
+    
     def __init__(self, session, async=False, timeout=None, raise_mode="none"):
         self._session = session
         try:
@@ -239,34 +227,38 @@ class RPC(object):
         self._async = async
         self._timeout = timeout
         self._raise_mode = raise_mode
-        self._id = uuid1().urn # Keeps things simple instead of having a class attr that has to be locked
+        self._id = uuid1().urn # Keeps things simple instead of having a class attr with running ID that has to be locked
         self._listener = RPCReplyListener(session)
         self._listener.register(self._id, self)
         self._reply = None
         self._error = None
         self._event = Event()
-
-    def _build(self, subele):
-        # internal
+    
+    def _wrap(self, subele):
+        # internal use
         ele = new_ele("rpc", {"message-id": self._id}, xmlns=BASE_NS_1_0)
         ele.append(subele)
         return to_xml(ele)
 
     def _request(self, op):
-        """Subclasses call this method to make the RPC request.
+        """Implementations of :meth:`request` call this method to send the request and process the
+        reply.
         
-        In synchronous mode, waits until the reply is received and returns
-        :class:`RPCReply`.
+        In synchronous mode, blocks until the reply is received and returns `RPCReply`. Depending on
+        the :attr:`raise_mode` a *rpc-error* element in the reply may lead to an :exc:`RPCError`
+        exception.
         
-        In asynchronous mode, returns immediately, returning a reference to this
-        object. The :attr:`event` attribute will be set when the reply has been
-        received (see :attr:`reply`) or an error occured (see :attr:`error`).
+        In asynchronous mode, returns immediately, returning *self*. The :attr:`event` attribute
+        will be set when the reply has been received (see :attr:`reply`) or an error occured (see
+        :attr:`error`).
         
-        :type opspec: :obj:`dict` or :obj:`string` or :class:`~xml.etree.ElementTree.Element`
-        :rtype: :class:`RPCReply` (sync) or :class:`RPC` (async)
+        :param op: operation to be requested
+        :type ops: `~xml.etree.ElementTree.Element`
+        
+        :rtype: `RPCReply` (sync) or `RPC` (async)
         """
         logger.info('Requesting %r' % self.__class__.__name__)
-        req = self._build(op)
+        req = self._wrap(op)
         self._session.send(req)
         if self._async:
             logger.debug('Async request, returning %r', self)
@@ -292,14 +284,15 @@ class RPC(object):
                 raise TimeoutExpiredError
 
     def request(self, *args, **kwds):
-        "Subclasses implement this method."
-        return self._request(self.SPEC)
+        """Subclasses must implement this method. Typically only the request needs to be built as an
+        `~xml.etree.ElementTree.Element` and everything else can be handed off to
+        :meth:`_request`."""
+        pass
     
     def _assert(self, capability):
-        """Subclasses can use this method to verify that a capability is available
-        with the NETCONF server, before making a request that requires it. A
-        :exc:`MissingCapabilityError` will be raised if the capability is not
-        available."""
+        """Subclasses can use this method to verify that a capability is available with the NETCONF
+        server, before making a request that requires it. A :exc:`MissingCapabilityError` will be
+        raised if the capability is not available."""
         if capability not in self._session.server_capabilities:
             raise MissingCapabilityError('Server does not support [%s]' %
                                          capability)
@@ -313,42 +306,40 @@ class RPC(object):
         # internal use
         self._error = err
         self._event.set()
-
+    
     @property
     def reply(self):
-        ":class:`RPCReply` element if reply has been received or :const:`None`"
+        "`RPCReply` element if reply has been received or :const:`None`"
         return self._reply
-
+    
     @property
     def error(self):
         """:exc:`Exception` type if an error occured or :const:`None`.
         
         .. note::
-            This represents an error which prevented a reply from being
-            received. An *<rpc-error>* does not fall in that category -- see
-            :class:`RPCReply` for that.
+            This represents an error which prevented a reply from being received. An *rpc-error*
+            does not fall in that category -- see `RPCReply` for that.
         """
         return self._error
-
+    
     @property
     def id(self):
-        "The *message-id* for this RPC"
+        "The *message-id* for this RPC."
         return self._id
-
+    
     @property
     def session(self):
-        """The :class:`~ncclient.transport.Session` object associated with this
-        RPC"""
+        "The `~ncclient.transport.Session` object associated with this RPC."
         return self._session
 
     @property
     def event(self):
-        """:class:`~threading.Event` that is set when reply has been received or
-        error occured."""
+        """`~threading.Event` that is set when reply has been received or when an error preventing
+        delivery of the reply occurs.
+        """
         return self._event
 
     def set_async(self, async=True):
-        """Set asynchronous mode for this RPC."""
         self._async = async
         if async and not session.can_pipeline:
             raise UserWarning('Asynchronous mode not supported for this device/session')
@@ -358,13 +349,26 @@ class RPC(object):
         self._raise_mode = mode
 
     def set_timeout(self, timeout):
-        """Set the timeout for synchronous waiting; defining how long the RPC
-        request will block on a reply before raising an error. Irrelevant for
-        asynchronous usage."""
         self._timeout = timeout
 
-    #: Whether this RPC is asynchronous
+    raise_mode = property(fget=lambda self: self._raise_mode, fset=set_raise_mode)
+    """Depending on this exception raising mode, an *rpc-error* in the reply may be raised as
+    :exc:`RPCError` exceptions. Valid values:
+    
+    * ``"all"`` -- any kind of *rpc-error* (error or warning)
+    * ``"errors"`` -- when the *error-type* element says it is an error
+    * ``"none"`` -- neither
+    """
+    
     is_async = property(fget=lambda self: self._async, fset=set_async)
-
-    #: Timeout for synchronous waiting
+    """Specifies whether this RPC will be / was requested asynchronously. By default RPC's are
+    synchronous.
+    """
+    
     timeout = property(fget=lambda self: self._timeout, fset=set_timeout)
+    """Timeout in seconds for synchronous waiting defining how long the RPC request will block on a
+    reply before raising :exc:`TimeoutExpiredError`. By default there is no timeout, represented by
+    :const:`None`.
+    
+    Irrelevant for asynchronous usage.
+    """
diff --git a/ncclient/transport/ssh.py b/ncclient/transport/ssh.py
index 7b373d0..2a69c86 100644
--- a/ncclient/transport/ssh.py
+++ b/ncclient/transport/ssh.py
@@ -25,27 +25,26 @@ from errors import AuthenticationError, SessionCloseError, SSHError, SSHUnknownH
 from session import Session
 
 import logging
-logger = logging.getLogger('ncclient.transport.ssh')
+logger = logging.getLogger("ncclient.transport.ssh")
 
 BUF_SIZE = 4096
 MSG_DELIM = "]]>]]>"
 TICK = 0.1
 
 def default_unknown_host_cb(host, fingerprint):
-    """An `unknown host callback` returns :const:`True` if it finds the key
-    acceptable, and :const:`False` if not.
+    """An `unknown host callback` returns :const:`True` if it finds the key acceptable, and
+    :const:`False` if not.
 
-    This default callback always returns :const:`False`, which would lead to
-    :meth:`connect` raising a :exc:`SSHUnknownHost` exception.
-
-    Supply another valid callback if you need to verify the host key
-    programatically.
+    This default callback always returns :const:`False`, which would lead to :meth:`connect` raising
+    a :exc:`SSHUnknownHost` exception.
+    
+    Supply another valid callback if you need to verify the host key programatically.
 
     :arg host: the hostname that needs to be verified
-    :type host: string
+    :type host: `string`
 
-    :arg fingerprint: a hex string representing the host key fingerprint
-    :type fingerprint: string
+    :arg fingerprint: a hex string representing the host key fingerprint, colon-delimited e.g. *4b:69:6c:72:6f:79:20:77:61:73:20:68:65:72:65:21*
+    :type fingerprint: `string`
     """
     return False
 
@@ -71,10 +70,11 @@ class SSHSession(Session):
         self._parsing_pos = 0
     
     def _parse(self):
-        '''Messages ae delimited by MSG_DELIM. The buffer could have grown by a
+        """Messages ae delimited by MSG_DELIM. The buffer could have grown by a
         maximum of BUF_SIZE bytes everytime this method is called. Retains state
         across method calls and if a byte has been read it will not be
-        considered again. '''
+        considered again.
+        """
         delim = MSG_DELIM
         n = len(delim) - 1
         expect = self._parsing_state
@@ -115,8 +115,7 @@ class SSHSession(Session):
         self._parsing_pos = self._buffer.tell()
 
     def load_known_hosts(self, filename=None):
-        """Load host keys from a :file:`known_hosts`-style file. Can be called multiple
-        times.
+        """Load host keys from a :file:`known_hosts`-style file. Can be called multiple times.
 
         If *filename* is not specified, looks in the default locations i.e.
         :file:`~/.ssh/known_hosts` and :file:`~/ssh/known_hosts` for Windows.
@@ -144,11 +143,11 @@ class SSHSession(Session):
                 unknown_host_cb=default_unknown_host_cb,
                 username=None, password=None,
                 key_filename=None, allow_agent=True, look_for_keys=True):
-        """Connect via SSH and initialize the NETCONF session. First attempts
-        the publickey authentication method and then password authentication.
+        """Connect via SSH and initialize the NETCONF session. First attempts the publickey
+        authentication method and then password authentication.
 
-        To disable attemting publickey authentication altogether, call with
-        *allow_agent* and *look_for_keys* as :const:`False`.
+        To disable attemting publickey authentication altogether, call with *allow_agent* and
+        *look_for_keys* as :const:`False`.
 
         :arg host: the hostname or IP address to connect to
         :type host: `string`
@@ -156,10 +155,10 @@ class SSHSession(Session):
         :arg port: by default 830, but some devices use the default SSH port of 22 so this may need to be specified
         :type port: `int`
 
-        :arg timeout: an optional timeout for the TCP handshake
+        :arg timeout: an optional timeout for socket connect
         :type timeout: `int`
 
-        :arg unknown_host_cb: called when a host key is not recognized
+        :arg unknown_host_cb: called when the server host key is not recognized
         :type unknown_host_cb: see :meth:`signature <ssh.default_unknown_host_cb>`
 
         :arg username: the username to use for SSH authentication
