ARIA-286 Sphinx documentation for code and CLI
diff --git a/aria/__init__.py b/aria/__init__.py
index bed1dc6..76a62ce 100644
--- a/aria/__init__.py
+++ b/aria/__init__.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-ARIA top level package
+The ARIA root package provides entry points for extension and storage initialization.
 """
 
 import sys
@@ -45,13 +45,17 @@
     '__version__',
     'workflow',
     'operation',
+    'install_aria_extensions',
+    'application_model_storage',
+    'application_resource_storage'
 )
 
 
 def install_aria_extensions():
     """
-    Iterates all Python packages with names beginning with :code:`aria_extension_` and all
-    :code:`aria_extension` entry points and loads them.
+    Iterates all Python packages with names beginning with ``aria_extension_`` and all
+    ``aria_extension`` entry points and loads them.
+
     It then invokes all registered extension functions.
     """
     for loader, module_name, _ in iter_modules():
@@ -64,7 +68,7 @@
 
 def application_model_storage(api, api_kwargs=None, initiator=None, initiator_kwargs=None):
     """
-    Initiate model storage
+    Initiate model storage.
     """
     return storage.ModelStorage(api_cls=api,
                                 api_kwargs=api_kwargs,
@@ -75,7 +79,7 @@
 
 def application_resource_storage(api, api_kwargs=None, initiator=None, initiator_kwargs=None):
     """
-    Initiate resource storage
+    Initiate resource storage.
     """
 
     return storage.ResourceStorage(api_cls=api,
diff --git a/aria/cli/__init__.py b/aria/cli/__init__.py
index ae1e83e..c0ef46f 100644
--- a/aria/cli/__init__.py
+++ b/aria/cli/__init__.py
@@ -12,3 +12,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+"""
+CLI package.
+"""
diff --git a/aria/cli/color.py b/aria/cli/color.py
index 5e0355a..03381ba 100644
--- a/aria/cli/color.py
+++ b/aria/cli/color.py
@@ -12,6 +12,11 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+"""
+Terminal colorization utilities.
+"""
+
 from StringIO import StringIO
 import re
 
@@ -75,8 +80,7 @@
     def __init__(self, fore=None, back=None, style=None):
         """
         It is possible to provide fore, back and style arguments. each could be either
-        the color is lower case letter, or the actual color from colorama.
-
+        the color is lower case letter, or the actual color from Colorama.
         """
         self._kwargs = dict(fore=fore, back=back, style=style)
         self._str = StringIO()
diff --git a/aria/cli/commands/__init__.py b/aria/cli/commands/__init__.py
index a01a029..ba34a43 100644
--- a/aria/cli/commands/__init__.py
+++ b/aria/cli/commands/__init__.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+CLI commands package.
+"""
+
 from . import (
     executions,
     logs,
diff --git a/aria/cli/commands/executions.py b/aria/cli/commands/executions.py
index 9f56ccd..ea70af5 100644
--- a/aria/cli/commands/executions.py
+++ b/aria/cli/commands/executions.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+CLI ``executions`` sub-commands.
+"""
+
 import os
 
 from .. import helptexts
@@ -27,28 +31,30 @@
 from ...utils import formatting
 from ...utils import threading
 
-EXECUTION_COLUMNS = ['id', 'workflow_name', 'status', 'service_name',
-                     'created_at', 'error']
+EXECUTION_COLUMNS = ('id', 'workflow_name', 'status', 'service_name',
+                     'created_at', 'error')
 
 
 @aria.group(name='executions')
 @aria.options.verbose()
 def executions():
-    """Handle workflow executions
+    """
+    Manage executions
     """
     pass
 
 
 @executions.command(name='show',
-                    short_help='Show execution information')
+                    short_help='Show information for an execution')
 @aria.argument('execution-id')
 @aria.options.verbose()
 @aria.pass_model_storage
 @aria.pass_logger
 def show(execution_id, model_storage, logger):
-    """Show information for a specific execution
+    """
+    Show information for an execution
 
-    `EXECUTION_ID` is the execution to get information on.
+    EXECUTION_ID is the unique ID of the execution.
     """
     logger.info('Showing execution {0}'.format(execution_id))
     execution = model_storage.execution.get(execution_id)
@@ -68,7 +74,7 @@
 
 
 @executions.command(name='list',
-                    short_help='List service executions')
+                    short_help='List executions')
 @aria.options.service_name(required=False)
 @aria.options.sort_by()
 @aria.options.descending
@@ -80,10 +86,11 @@
          descending,
          model_storage,
          logger):
-    """List executions
+    """
+    List executions
 
-    If `SERVICE_NAME` is provided, list executions for that service.
-    Otherwise, list executions for all services.
+    If SERVICE_NAME is provided, list executions on that service. Otherwise, list executions on all
+    services.
     """
     if service_name:
         logger.info('Listing executions for service {0}...'.format(
@@ -102,7 +109,7 @@
 
 
 @executions.command(name='start',
-                    short_help='Execute a workflow')
+                    short_help='Start a workflow on a service')
 @aria.argument('workflow-name')
 @aria.options.service_name(required=True)
 @aria.options.inputs(help=helptexts.EXECUTION_INPUTS)
@@ -126,9 +133,12 @@
           resource_storage,
           plugin_manager,
           logger):
-    """Execute a workflow
+    """
+    Start a workflow on a service
 
-    `WORKFLOW_NAME` is the name of the workflow to execute (e.g. `uninstall`)
+    SERVICE_NAME is the unique name of the service.
+
+    WORKFLOW_NAME is the unique name of the workflow within the service (e.g. "uninstall").
     """
     service = model_storage.service.get_by_name(service_name)
     executor = DryExecutor() if dry else None  # use WorkflowRunner's default executor
@@ -145,7 +155,7 @@
 
 
 @executions.command(name='resume',
-                    short_help='Resume a workflow')
+                    short_help='Resume a stopped execution')
 @aria.argument('execution-id')
 @aria.options.inputs(help=helptexts.EXECUTION_INPUTS)
 @aria.options.dry_execution
@@ -166,6 +176,11 @@
            resource_storage,
            plugin_manager,
            logger):
+    """
+    Resume a stopped execution
+
+    EXECUTION_ID is the unique ID of the execution.
+    """
     executor = DryExecutor() if dry else None  # use WorkflowRunner's default executor
 
     execution = model_storage.execution.get(execution_id)
@@ -225,7 +240,7 @@
 
 
 def _cancel_execution(workflow_runner, execution_thread, logger, log_iterator):
-    logger.info('Cancelling execution. Press Ctrl+C again to force-cancel')
+    logger.info('Cancelling execution. Press Ctrl+C again to force-cancel.')
     workflow_runner.cancel()
     while execution_thread.is_alive():
         try:
diff --git a/aria/cli/commands/logs.py b/aria/cli/commands/logs.py
index 2f7f361..b751b97 100644
--- a/aria/cli/commands/logs.py
+++ b/aria/cli/commands/logs.py
@@ -12,6 +12,11 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+"""
+CLI ``logs`` sub-commands.
+"""
+
 from .. import execution_logging
 from ..logger import ModelLogIterator
 from ..core import aria
@@ -20,20 +25,24 @@
 @aria.group(name='logs')
 @aria.options.verbose()
 def logs():
-    """Show logs from workflow executions
+    """
+    Manage logs of workflow executions
     """
     pass
 
 
 @logs.command(name='list',
-              short_help='List execution logs')
+              short_help='List logs for an execution')
 @aria.argument('execution-id')
 @aria.options.verbose()
 @aria.options.mark_pattern()
 @aria.pass_model_storage
 @aria.pass_logger
 def list(execution_id, mark_pattern, model_storage, logger):
-    """Display logs for an execution
+    """
+    List logs for an execution
+
+    EXECUTION_ID is the unique ID of the execution.
     """
     logger.info('Listing logs for execution id {0}'.format(execution_id))
     log_iterator = ModelLogIterator(model_storage, execution_id)
@@ -45,15 +54,16 @@
 
 
 @logs.command(name='delete',
-              short_help='Delete execution logs')
+              short_help='Delete logs of an execution')
 @aria.argument('execution-id')
 @aria.options.verbose()
 @aria.pass_model_storage
 @aria.pass_logger
 def delete(execution_id, model_storage, logger):
-    """Delete logs of an execution
+    """
+    Delete logs of an execution
 
-    `EXECUTION_ID` is the execution logs to delete.
+    EXECUTION_ID is the unique ID of the execution.
     """
     logger.info('Deleting logs for execution id {0}'.format(execution_id))
     logs_list = model_storage.log.list(filters=dict(execution_fk=execution_id))
diff --git a/aria/cli/commands/node_templates.py b/aria/cli/commands/node_templates.py
index 50c755e..ec160d2 100644
--- a/aria/cli/commands/node_templates.py
+++ b/aria/cli/commands/node_templates.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+CLI ``node-templates`` sub-commands.
+"""
+
 from .. import table
 from .. import utils
 from ..core import aria
@@ -24,22 +28,24 @@
 @aria.group(name='node-templates')
 @aria.options.verbose()
 def node_templates():
-    """Handle a service template's node templates
+    """
+    Manages stored service templates' node templates
     """
     pass
 
 
 @node_templates.command(name='show',
-                        short_help='Show node information')
+                        short_help='Show information for a stored node template')
 @aria.argument('node-template-id')
 # @aria.options.service_template_name(required=True)
 @aria.options.verbose()
 @aria.pass_model_storage
 @aria.pass_logger
 def show(node_template_id, model_storage, logger):
-    """Show information for a specific node of a specific service template
+    """
+    Show information for a stored node template
 
-    `NODE_TEMPLATE_ID` is the node id to get information on.
+    NODE_TEMPLATE_ID is the unique node template ID.
     """
     logger.info('Showing node template {0}'.format(node_template_id))
     node_template = model_storage.node_template.get(node_template_id)
@@ -64,7 +70,7 @@
 
 
 @node_templates.command(name='list',
-                        short_help='List node templates for a service template')
+                        short_help='List stored node templates')
 @aria.options.service_template_name()
 @aria.options.sort_by('service_template_name')
 @aria.options.descending
@@ -72,9 +78,10 @@
 @aria.pass_model_storage
 @aria.pass_logger
 def list(service_template_name, sort_by, descending, model_storage, logger):
-    """List node templates
+    """
+    List stored node templates
 
-    If `SERVICE_TEMPLATE_NAME` is provided, list nodes for that service template.
+    If SERVICE_TEMPLATE_NAME is provided, list node templates for that stored service template.
     Otherwise, list node templates for all service templates.
     """
     if service_template_name:
diff --git a/aria/cli/commands/nodes.py b/aria/cli/commands/nodes.py
index 1bbefe6..30f1dd4 100644
--- a/aria/cli/commands/nodes.py
+++ b/aria/cli/commands/nodes.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+CLI ``nodes`` sub-commands.
+"""
+
 from .. import table
 from .. import utils
 from ..core import aria
@@ -24,21 +28,23 @@
 @aria.group(name='nodes')
 @aria.options.verbose()
 def nodes():
-    """Handle a service's nodes
+    """
+    Manage services' nodes
     """
     pass
 
 
 @nodes.command(name='show',
-               short_help='Show node information')
+               short_help='Show information for a node')
 @aria.argument('node_id')
 @aria.options.verbose()
 @aria.pass_model_storage
 @aria.pass_logger
 def show(node_id, model_storage, logger):
-    """Showing information for a specific node
+    """
+    Show information for a node
 
-    `NODE_ID` is the id of the node to get information on.
+    NODE_ID is the unique node ID.
     """
     logger.info('Showing node {0}'.format(node_id))
     node = model_storage.node.get(node_id)
@@ -55,7 +61,7 @@
 
 
 @nodes.command(name='list',
-               short_help='List node for a service')
+               short_help='List node')
 @aria.options.service_name(required=False)
 @aria.options.sort_by('service_name')
 @aria.options.descending
@@ -67,10 +73,11 @@
          descending,
          model_storage,
          logger):
-    """List nodes
+    """
+    List nodes
 
-    If `SERVICE_NAME` is provided, list nodes for that service.
-    Otherwise, list nodes for all services.
+    If SERVICE_NAME is provided, list nodes for that service. Otherwise, list nodes for all
+    services.
     """
     if service_name:
         logger.info('Listing nodes for service {0}...'.format(service_name))
diff --git a/aria/cli/commands/plugins.py b/aria/cli/commands/plugins.py
index 670288e..b5d68a2 100644
--- a/aria/cli/commands/plugins.py
+++ b/aria/cli/commands/plugins.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+CLI ``plugins`` sub-commands.
+"""
+
 from .. import table
 from .. import utils
 from ..core import aria
@@ -25,24 +29,26 @@
 @aria.group(name='plugins')
 @aria.options.verbose()
 def plugins():
-    """Handle plugins
+    """
+    Manage plugins
     """
     pass
 
 
 @plugins.command(name='validate',
-                 short_help='Validate a plugin')
+                 short_help='Validate a plugin archive')
 @aria.argument('plugin-path')
 @aria.options.verbose()
 @aria.pass_plugin_manager
 @aria.pass_logger
 def validate(plugin_path, plugin_manager, logger):
-    """Validate a plugin archive
+    """
+    Validate a plugin archive
 
-    A valid plugin is a wagon (http://github.com/cloudify-cosmo/wagon)
-    in the zip format (suffix may also be .wgn).
+    A valid plugin is a wagon (`http://github.com/cloudify-cosmo/wagon`) in the ZIP format (suffix
+    may also be `.wgn`).
 
-    `PLUGIN_PATH` is the path to wagon archive to validate.
+    PLUGIN_PATH is the path to the wagon archive.
     """
     logger.info('Validating plugin {0}...'.format(plugin_path))
     plugin_manager.validate_plugin(plugin_path)
@@ -57,9 +63,13 @@
 @aria.pass_plugin_manager
 @aria.pass_logger
 def install(ctx, plugin_path, plugin_manager, logger):
-    """Install a plugin
+    """
+    Install a plugin
 
-    `PLUGIN_PATH` is the path to wagon archive to install.
+    A valid plugin is a wagon (`http://github.com/cloudify-cosmo/wagon`) in the ZIP format (suffix
+    may also be `.wgn`).
+
+    PLUGIN_PATH is the path to the wagon archive.
     """
     ctx.invoke(validate, plugin_path=plugin_path)
     logger.info('Installing plugin {0}...'.format(plugin_path))
@@ -68,15 +78,16 @@
 
 
 @plugins.command(name='show',
-                 short_help='show plugin information')
+                 short_help='Show information for an installed plugin')
 @aria.argument('plugin-id')
 @aria.options.verbose()
 @aria.pass_model_storage
 @aria.pass_logger
 def show(plugin_id, model_storage, logger):
-    """Show information for a specific plugin
+    """
+    Show information for an installed plugin
 
-    `PLUGIN_ID` is the id of the plugin to show information on.
+    PLUGIN_ID is the unique installed plugin ID in this ARIA instance.
     """
     logger.info('Showing plugin {0}...'.format(plugin_id))
     plugin = model_storage.plugin.get(plugin_id)
@@ -84,14 +95,15 @@
 
 
 @plugins.command(name='list',
-                 short_help='List plugins')
+                 short_help='List all installed plugins')
 @aria.options.sort_by('uploaded_at')
 @aria.options.descending
 @aria.options.verbose()
 @aria.pass_model_storage
 @aria.pass_logger
 def list(sort_by, descending, model_storage, logger):
-    """List all plugins on the manager
+    """
+    List all installed plugins
     """
     logger.info('Listing all plugins...')
     plugins_list = model_storage.plugin.list(
diff --git a/aria/cli/commands/reset.py b/aria/cli/commands/reset.py
index 1fe0714..c82c707 100644
--- a/aria/cli/commands/reset.py
+++ b/aria/cli/commands/reset.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+CLI ``reset`` command.
+"""
+
 from .. import helptexts
 from ..core import aria
 from ..env import env
@@ -20,7 +24,7 @@
 
 
 @aria.command(name='reset',
-              short_help="Reset ARIA's working directory")
+              short_help="Reset ARIA working directory")
 @aria.options.force(help=helptexts.FORCE_RESET)
 @aria.options.reset_config
 @aria.pass_logger
@@ -28,9 +32,10 @@
 def reset(force, reset_config, logger):
     """
     Reset ARIA working directory
-    Resetting the working directory will result in the deletion of all state in ARIA; The user
-     configuration will remain intact, unless the `reset_config` flag has been set as well, in
-     which case the entire ARIA working directory shall be removed.
+
+    Deletes installed plugins, service templates, services, executions, and logs. The user
+    configuration will remain intact unless the `--reset_config` flag has been set as well, in
+    which case the entire ARIA working directory shall be removed.
     """
     if not force:
         raise AriaCliError("To reset the ARIA's working directory, you must also provide the force"
diff --git a/aria/cli/commands/service_templates.py b/aria/cli/commands/service_templates.py
index d139195..f567aa8 100644
--- a/aria/cli/commands/service_templates.py
+++ b/aria/cli/commands/service_templates.py
@@ -13,6 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+CLI ``service-templates`` sub-commands.
+"""
 
 import os
 
@@ -35,13 +38,14 @@
 @aria.group(name='service-templates')
 @aria.options.verbose()
 def service_templates():
-    """Handle service templates on the manager
+    """
+    Manage service templates
     """
     pass
 
 
 @service_templates.command(name='show',
-                           short_help='Show service template information')
+                           short_help='Show information for a stored service template')
 @aria.argument('service-template-name')
 @aria.options.verbose()
 @aria.pass_model_storage
@@ -52,9 +56,10 @@
 @aria.pass_logger
 def show(service_template_name, model_storage, mode_full, mode_types, format_json, format_yaml,
          logger):
-    """Show information for a specific service template
+    """
+    Show information for a stored service template
 
-    `SERVICE_TEMPLATE_NAME` is the name of the service template to show information on.
+    SERVICE_TEMPLATE_NAME is the unique name of the stored service template.
     """
     service_template = model_storage.service_template.get_by_name(service_template_name)
 
@@ -94,14 +99,15 @@
 
 
 @service_templates.command(name='list',
-                           short_help='List service templates')
+                           short_help='List all stored service templates')
 @aria.options.sort_by()
 @aria.options.descending
 @aria.options.verbose()
 @aria.pass_model_storage
 @aria.pass_logger
 def list(sort_by, descending, model_storage, logger):
-    """List all service templates
+    """
+    List all stored service templates
     """
 
     logger.info('Listing all service templates...')
@@ -115,7 +121,7 @@
 
 
 @service_templates.command(name='store',
-                           short_help='Store a service template')
+                           short_help='Parse and store a service template archive')
 @aria.argument('service-template-path')
 @aria.argument('service-template-name')
 @aria.options.service_template_filename
@@ -126,11 +132,12 @@
 @aria.pass_logger
 def store(service_template_path, service_template_name, service_template_filename,
           model_storage, resource_storage, plugin_manager, logger):
-    """Store a service template
+    """
+    Parse and store a service template archive
 
-    `SERVICE_TEMPLATE_PATH` is the path of the service template to store.
+    SERVICE_TEMPLATE_PATH is the path to the service template archive.
 
-    `SERVICE_TEMPLATE_NAME` is the name of the service template to store.
+    SERVICE_TEMPLATE_NAME is the unique name to give to the service template in storage.
     """
     logger.info('Storing service template {0}...'.format(service_template_name))
 
@@ -148,7 +155,7 @@
 
 
 @service_templates.command(name='delete',
-                           short_help='Delete a service template')
+                           short_help='Delete a stored service template')
 @aria.argument('service-template-name')
 @aria.options.verbose()
 @aria.pass_model_storage
@@ -156,9 +163,10 @@
 @aria.pass_plugin_manager
 @aria.pass_logger
 def delete(service_template_name, model_storage, resource_storage, plugin_manager, logger):
-    """Delete a service template
+    """
+    Delete a stored service template
 
-    `SERVICE_TEMPLATE_NAME` is the name of the service template to delete.
+    SERVICE_TEMPLATE_NAME is the unique name of the stored service template.
     """
     logger.info('Deleting service template {0}...'.format(service_template_name))
     service_template = model_storage.service_template.get_by_name(service_template_name)
@@ -168,22 +176,23 @@
 
 
 @service_templates.command(name='inputs',
-                           short_help='Show service template inputs')
+                           short_help='Show stored service template inputs')
 @aria.argument('service-template-name')
 @aria.options.verbose()
 @aria.pass_model_storage
 @aria.pass_logger
 def inputs(service_template_name, model_storage, logger):
-    """Show inputs for a specific service template
+    """
+    Show stored service template inputs
 
-    `SERVICE_TEMPLATE_NAME` is the name of the service template to show inputs for.
+    SERVICE_TEMPLATE_NAME is the unique name of the stored service template.
     """
     logger.info('Showing inputs for service template {0}...'.format(service_template_name))
     print_service_template_inputs(model_storage, service_template_name, logger)
 
 
 @service_templates.command(name='validate',
-                           short_help='Validate a service template')
+                           short_help='Validate a service template archive')
 @aria.argument('service-template')
 @aria.options.service_template_filename
 @aria.options.verbose()
@@ -193,9 +202,10 @@
 @aria.pass_logger
 def validate(service_template, service_template_filename,
              model_storage, resource_storage, plugin_manager, logger):
-    """Validate a service template
+    """
+    Validate a service template archive
 
-    `SERVICE_TEMPLATE` is the path or URL of the service template or archive to validate.
+    SERVICE_TEMPLATE_PATH is the path to the service template archive.
     """
     logger.info('Validating service template: {0}'.format(service_template))
     service_template_path = service_template_utils.get(service_template, service_template_filename)
@@ -205,16 +215,18 @@
 
 
 @service_templates.command(name='create-archive',
-                           short_help='Create a CSAR archive')
+                           short_help='Create a CSAR archive from a service template source')
 @aria.argument('service-template-path')
 @aria.argument('destination')
 @aria.options.verbose()
 @aria.pass_logger
 def create_archive(service_template_path, destination, logger):
-    """Create a CSAR archive
+    """
+    Create a CSAR archive from a service template source
 
-    `service_template_path` is the path of the service template to create the archive from
-    `destination` is the path of the output CSAR archive
+    SERVICE_TEMPLATE_PATH is the path to the service template source.
+
+    DESTINATION is the path to the created CSAR archive.
     """
     logger.info('Creating a CSAR archive')
     if not destination.endswith(csar.CSAR_FILE_EXTENSION):
diff --git a/aria/cli/commands/services.py b/aria/cli/commands/services.py
index ae5895a..a99f5b3 100644
--- a/aria/cli/commands/services.py
+++ b/aria/cli/commands/services.py
@@ -13,6 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+CLI ``services`` sub-commands.
+"""
 
 import os
 from StringIO import StringIO
@@ -36,13 +39,14 @@
 @aria.group(name='services')
 @aria.options.verbose()
 def services():
-    """Handle services
+    """
+    Manage services
     """
     pass
 
 
 @services.command(name='show',
-                  short_help='Display service information')
+                  short_help='Show information for a service')
 @aria.argument('service-name')
 @aria.options.verbose()
 @aria.options.service_mode_full
@@ -52,9 +56,10 @@
 @aria.pass_model_storage
 @aria.pass_logger
 def show(service_name, model_storage, mode_full, mode_graph, format_json, format_yaml, logger):
-    """Show information for a specific service template
+    """
+    Show information for a service
 
-    `SERVICE_NAME` is the name of the service to display information on.
+    SERVICE_NAME is the unique name of the service.
     """
     service = model_storage.service.get_by_name(service_name)
 
@@ -99,10 +104,11 @@
          descending,
          model_storage,
          logger):
-    """List services
+    """
+    List services
 
-    If `--service-template-name` is provided, list services for that service template.
-    Otherwise, list services for all service templates.
+    If `--service-template-name` is provided, list services based on that service template.
+    Otherwise, list all services.
     """
     if service_template_name:
         logger.info('Listing services for service template {0}...'.format(
@@ -120,7 +126,7 @@
 
 
 @services.command(name='create',
-                  short_help='Create a services')
+                  short_help='Create a service')
 @aria.argument('service-name', required=False)
 @aria.options.service_template_name(required=True)
 @aria.options.inputs(help=helptexts.SERVICE_INPUTS)
@@ -136,10 +142,10 @@
            resource_storage,
            plugin_manager,
            logger):
-    """Create a service
+    """
+    Create a service
 
-    `SERVICE_NAME` is the name of the service you'd like to create.
-
+    SERVICE_NAME is the unique name to give to the service.
     """
     logger.info('Creating new service from service template {0}...'.format(
         service_template_name))
@@ -168,9 +174,10 @@
 @aria.pass_plugin_manager
 @aria.pass_logger
 def delete(service_name, force, model_storage, resource_storage, plugin_manager, logger):
-    """Delete a service
+    """
+    Delete a service
 
-    `SERVICE_NAME` is the name of the service to delete.
+    SERVICE_NAME is the unique name of the service.
     """
     logger.info('Deleting service {0}...'.format(service_name))
     service = model_storage.service.get_by_name(service_name)
@@ -186,9 +193,10 @@
 @aria.pass_model_storage
 @aria.pass_logger
 def outputs(service_name, model_storage, logger):
-    """Show outputs for a specific service
+    """
+    Show service outputs
 
-    `SERVICE_NAME` is the name of the service to print outputs for.
+    SERVICE_NAME is the unique name of the service.
     """
     logger.info('Showing outputs for service {0}...'.format(service_name))
     service = model_storage.service.get_by_name(service_name)
@@ -211,9 +219,10 @@
 @aria.pass_model_storage
 @aria.pass_logger
 def inputs(service_name, model_storage, logger):
-    """Show inputs for a specific service
+    """
+    Show service inputs
 
-    `SERVICE_NAME` is the id of the service to print inputs for.
+    SERVICE_NAME is the unique name of the service.
     """
     logger.info('Showing inputs for service {0}...'.format(service_name))
     service = model_storage.service.get_by_name(service_name)
diff --git a/aria/cli/commands/workflows.py b/aria/cli/commands/workflows.py
index 221dbc4..03cf00e 100644
--- a/aria/cli/commands/workflows.py
+++ b/aria/cli/commands/workflows.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+CLI ``worfklows`` sub-commands.
+"""
+
 from .. import table
 from ..core import aria
 from ..exceptions import AriaCliError
@@ -22,22 +26,26 @@
 
 @aria.group(name='workflows')
 def workflows():
-    """Handle service workflows
+    """
+    Manage service workflows
     """
     pass
 
 
 @workflows.command(name='show',
-                   short_help='Show workflow information')
+                   short_help='Show information for a service workflow')
 @aria.argument('workflow-name')
 @aria.options.service_name(required=True)
 @aria.options.verbose()
 @aria.pass_model_storage
 @aria.pass_logger
 def show(workflow_name, service_name, model_storage, logger):
-    """Show information for a specific workflow of a specific service
+    """
+    Show information for a service workflow
 
-    `WORKFLOW_NAME` is the name of the workflow to get information on.
+    SERVICE_NAME is the unique name of the service.
+
+    WORKFLOW_NAME is the unique name of the workflow within the service (e.g. "uninstall").
     """
     logger.info('Retrieving workflow {0} for service {1}'.format(
         workflow_name, service_name))
@@ -81,13 +89,16 @@
 
 
 @workflows.command(name='list',
-                   short_help='List workflows for a service')
+                   short_help='List service workflows')
 @aria.options.service_name(required=True)
 @aria.options.verbose()
 @aria.pass_model_storage
 @aria.pass_logger
 def list(service_name, model_storage, logger):
-    """List all workflows of a specific service
+    """
+    List service workflows
+
+    SERVICE_NAME is the unique name of the service.
     """
     logger.info('Listing workflows for service {0}...'.format(service_name))
     service = model_storage.service.get_by_name(service_name)
diff --git a/aria/cli/config/__init__.py b/aria/cli/config/__init__.py
index ae1e83e..738e8ed 100644
--- a/aria/cli/config/__init__.py
+++ b/aria/cli/config/__init__.py
@@ -12,3 +12,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+"""
+CLI configuration package.
+"""
diff --git a/aria/cli/config/config.py b/aria/cli/config/config.py
index d584fad..bbece80 100644
--- a/aria/cli/config/config.py
+++ b/aria/cli/config/config.py
@@ -13,6 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+CLI configuration mechanism.
+"""
 
 import os
 import pkg_resources
diff --git a/aria/cli/core/__init__.py b/aria/cli/core/__init__.py
index ae1e83e..88a9801 100644
--- a/aria/cli/core/__init__.py
+++ b/aria/cli/core/__init__.py
@@ -12,3 +12,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+"""
+CLI core package.
+"""
diff --git a/aria/cli/core/aria.py b/aria/cli/core/aria.py
index e5b3eb2..515c06a 100644
--- a/aria/cli/core/aria.py
+++ b/aria/cli/core/aria.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Enhancements and ARIA-specific conveniences for `Click <http://click.pocoo.org>`__.
+"""
+
 import os
 import sys
 import difflib
@@ -227,9 +231,8 @@
 
     def resolve_command(self, ctx, args):
         """
-        Override clicks ``resolve_command`` method
-        and appends *Did you mean ...* suggestions
-        to the raised exception message.
+        Override clicks ``resolve_command`` method and appends *Did you mean ...* suggestions to the
+        raised exception message.
         """
         try:
             return super(AliasedGroup, self).resolve_command(ctx, args)
@@ -250,7 +253,7 @@
 
 def group(name):
     """
-    Allow to create a group with a default click context and a cls for click's ``didyoueamn``
+    Allow to create a group with a default click context and a class for Click's ``didyoueamn``
     without having to repeat it for every group.
     """
     return click.group(
@@ -271,7 +274,7 @@
 
 def argument(*args, **kwargs):
     """
-    Make Click arguments ARIA specific.
+    Make Click arguments specific to ARIA.
 
     This exists purely for aesthetic reasons, otherwise some decorators are called
     ``@click.something`` instead of ``@aria.something``
diff --git a/aria/cli/csar.py b/aria/cli/csar.py
index 8f44557..40b1699 100644
--- a/aria/cli/csar.py
+++ b/aria/cli/csar.py
@@ -13,6 +13,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Support for the CSAR (Cloud Service ARchive) packaging specification.
+
+See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
+/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html#_Toc461787381>`__
+"""
+
 import os
 import logging
 import pprint
diff --git a/aria/cli/defaults.py b/aria/cli/defaults.py
index 5c16938..e84abc0 100644
--- a/aria/cli/defaults.py
+++ b/aria/cli/defaults.py
@@ -13,8 +13,18 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Various CLI default values.
+"""
 
+#: Default service template filename
 SERVICE_TEMPLATE_FILENAME = 'service_template.yaml'
+
+#: Default task max attempts
 TASK_MAX_ATTEMPTS = 30
+
+#: Default task retry interval
 TASK_RETRY_INTERVAL = 30
+
+#: Default sort descending
 SORT_DESCENDING = False
diff --git a/aria/cli/env.py b/aria/cli/env.py
index 52a4ec6..84bdebe 100644
--- a/aria/cli/env.py
+++ b/aria/cli/env.py
@@ -13,6 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Environment (private)
+"""
 
 import os
 import shutil
diff --git a/aria/cli/exceptions.py b/aria/cli/exceptions.py
index 89cfacd..7da9836 100644
--- a/aria/cli/exceptions.py
+++ b/aria/cli/exceptions.py
@@ -13,6 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+CLI exceptions.
+"""
 
 from ..exceptions import AriaError
 
diff --git a/aria/cli/execution_logging.py b/aria/cli/execution_logging.py
index 248ff7c..af40e01 100644
--- a/aria/cli/execution_logging.py
+++ b/aria/cli/execution_logging.py
@@ -12,6 +12,11 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+"""
+Formatting for ``executions`` sub-commands.
+"""
+
 import os
 import re
 from StringIO import StringIO
diff --git a/aria/cli/helptexts.py b/aria/cli/helptexts.py
index 74934db..a5d41e8 100644
--- a/aria/cli/helptexts.py
+++ b/aria/cli/helptexts.py
@@ -13,10 +13,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Gathers all CLI command help texts in one place.
+"""
 
 DEFAULT_MUTUALITY_ERROR_MESSAGE = 'mutually exclusive'
 VERBOSE = \
-    "Show verbose output. You can supply this up to three times (i.e. -vvv)"
+    "Show verbose output; you can supply this up to three times (i.e. -vvv)"
 
 VERSION = "Display the version and exit"
 FORCE_RESET = "Confirmation for resetting ARIA's working directory"
@@ -28,12 +31,12 @@
 
 SERVICE_TEMPLATE_PATH = "The path to the application's service template file"
 SERVICE_TEMPLATE_FILENAME = (
-    "The name of the archive's main service template file. "
-    "This is only relevant if uploading a (non-CSAR) archive")
+    "The name of the archive's main service template file "
+    "(only relevant if uploading a non-CSAR archive)")
 INPUTS_PARAMS_USAGE = (
-    '(Can be provided as wildcard based paths '
-    '(*.yaml, /my_inputs/, etc..) to YAML files, a JSON string or as '
-    'key1=value1;key2=value2). This argument can be used multiple times')
+    '(can be provided as wildcard based paths '
+    '("inp?.yaml", "/my_inputs/", etc.) to YAML files, a JSON string or as '
+    '"key1=value1;key2=value2"); this argument can be used multiple times')
 SERVICE_INPUTS = "Inputs for the service {0}".format(INPUTS_PARAMS_USAGE)
 EXECUTION_INPUTS = "Inputs for the execution {0}".format(INPUTS_PARAMS_USAGE)
 
@@ -46,8 +49,8 @@
 IGNORE_AVAILABLE_NODES = "Delete the service even if it has available nodes"
 SORT_BY = "Key for sorting the list"
 DESCENDING = "Sort list in descending order [default: False]"
-JSON_OUTPUT = "Output logs in a consumable JSON format"
-MARK_PATTERN = "Mark a regex pattern in the logs"
+JSON_OUTPUT = "Output logs in JSON format"
+MARK_PATTERN = "Mark a regular expression pattern in the logs"
 
 SHOW_FULL = "Show full information"
 SHOW_JSON = "Show in JSON format (implies --full)"
diff --git a/aria/cli/inputs.py b/aria/cli/inputs.py
index 4d46ebb..bea3e1a 100644
--- a/aria/cli/inputs.py
+++ b/aria/cli/inputs.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Helpers for validating and coercing service template inputs.
+"""
+
 import os
 import glob
 from ruamel import yaml
@@ -22,15 +26,17 @@
 
 
 def inputs_to_dict(resources):
-    """Returns a dictionary of inputs
+    """
+    Returns a dictionary of inputs
 
-    `resources` can be:
-    - A list of files.
-    - A single file
-    - A directory containing multiple input files
-    - A key1=value1;key2=value2 pairs string.
-    - A string formatted as JSON/YAML.
-    - Wildcard based string (e.g. *-inputs.yaml)
+    :param resources: can be:
+
+     * list of files
+     * single file
+     * directory containing multiple input files
+     * ``key1=value1;key2=value2`` pairs string.
+     * string formatted as JSON/YAML
+     * wildcard based string (e.g. ``*-inputs.yaml``)
     """
     if not resources:
         return dict()
diff --git a/aria/cli/logger.py b/aria/cli/logger.py
index 96f3fb3..14baae0 100644
--- a/aria/cli/logger.py
+++ b/aria/cli/logger.py
@@ -13,6 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Centralized logging configuration and formatting.
+"""
 
 import os
 import copy
diff --git a/aria/cli/main.py b/aria/cli/main.py
index 02cf095..640360b 100644
--- a/aria/cli/main.py
+++ b/aria/cli/main.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Executable entry point into the CLI.
+"""
+
 from aria import install_aria_extensions
 from aria.cli import commands
 from aria.cli.core import aria
@@ -22,12 +26,15 @@
 @aria.options.verbose()
 @aria.options.version
 def _aria():
-    """ARIA's Command Line Interface
+    """
+    ARIA's Command Line Interface.
 
-    To activate bash-completion. Run: `eval "$(_ARIA_COMPLETE=source aria)"`
+    To activate bash-completion run::
 
-    ARIA's working directory resides by default in ~/.aria. To change it, set
-    the environment variable `ARIA_WORKDIR` to something else (e.g. /tmp/).
+        eval "$(_ARIA_COMPLETE=source aria)"
+
+    ARIA's working directory resides by default in "~/.aria". To change it, set the environment
+    variable ARIA_WORKDIR to something else (e.g. "/tmp/").
     """
     aria.set_cli_except_hook()
 
diff --git a/aria/cli/service_template_utils.py b/aria/cli/service_template_utils.py
index c953c02..5312522 100644
--- a/aria/cli/service_template_utils.py
+++ b/aria/cli/service_template_utils.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Loading mechanism for service templates.
+"""
+
 import os
 from urlparse import urlparse
 
@@ -23,26 +27,24 @@
 
 
 def get(source, service_template_filename):
-    """Get a source and return a path to the main service template file
+    """
+    Get a source and return a path to the main service template file
 
     The behavior based on then source argument content is:
-        - local yaml file: return the file
-        - local archive:
-            extract it locally and return path service template file
-        - URL:
-            - download and get service template from downloaded archive
-        - github repo:
-            - download and get service template from downloaded archive
 
-    Supported archive types are: csar, zip, tar, tar.gz and tar.bz2
+    * local ``.yaml`` file: return the file
+    * local archive (``.csar``, ``.zip``, ``.tar``, ``.tar.gz``, and ``.tar.bz2``): extract it
+      locally and return path service template file
+    * URL: download and get service template from downloaded archive
+    * GitHub repo: download and get service template from downloaded archive
 
-    :param source: Path/URL/github repo to archive/service-template file
-    :type source: str
-    :param service_template_filename: Path to service template (if source is an archive [but
-     not a csar archive - with csars archives, this is read from the metadata file])
-    :type service_template_filename: str
-    :return: Path to main service template file
-    :rtype: str
+    :param source: path/URL/GitHub repo to archive/service-template file
+    :type source: basestring
+    :param service_template_filename: path to service template if source is a non-CSAR archive
+     with CSAR archives, this is read from the metadata file)
+    :type service_template_filename: basestring
+    :return: path to main service template file
+    :rtype: basestring
     """
     if urlparse(source).scheme:
         downloaded_file = utils.download_file(source)
@@ -66,14 +68,15 @@
 
 
 def _get_service_template_file_from_archive(archive, service_template_filename):
-    """Extract archive to temporary location and get path to service template file.
+    """
+    Extract archive to temporary location and get path to service template file.
 
-    :param archive: Path to archive file
-    :type archive: str
-    :param service_template_filename: Path to service template file relative to archive
-    :type service_template_filename: str
-    :return: Absolute path to service template file
-    :rtype: str
+    :param archive: path to archive file
+    :type archive: basestring
+    :param service_template_filename: path to service template file relative to archive
+    :type service_template_filename: basestring
+    :return: absolute path to service template file
+    :rtype: basestring
 
     """
     if csar.is_csar_archive(archive):
@@ -95,12 +98,13 @@
 
 
 def _map_to_github_url(source):
-    """Returns a path to a downloaded github archive.
+    """
+    Returns a path to a downloaded GitHub archive.
 
-    :param source: github repo in the format of `org/repo[:tag/branch]`.
-    :type source: str
-    :return: URL to the archive file for the given repo in github
-    :rtype: str
+    :param source: GitHub repo: ``org/repo[:tag/branch]``
+    :type source: basestring
+    :return: URL to the archive file for the given repo in GitHub
+    :rtype: basestring
 
     """
     source_parts = source.split(':', 1)
diff --git a/aria/cli/table.py b/aria/cli/table.py
index d984c87..74487ae 100644
--- a/aria/cli/table.py
+++ b/aria/cli/table.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Tabular formatting utilities.
+"""
+
 import os
 from datetime import datetime
 
@@ -23,6 +27,23 @@
 
 def print_data(columns, items, header_text,
                column_formatters=None, col_max_width=None, defaults=None):
+    """
+    Prints data in a tabular form.
+
+    :param columns: columns of the table, e.g. ``['id','name']``
+    :type columns: iterable of basestring
+    :param items: each element must have keys or attributes corresponding to the ``columns`` items,
+     e.g. ``[{'id':'123', 'name':'Pete'}]``
+    :type data: [{:obj:`basestring`: :obj:`basestring`}]
+    :param column_formatters: maps column name to formatter, a function that may manipulate the
+     string values printed for this column, e.g. ``{'created_at': timestamp_formatter}``
+    :type column_formatters: {:obj:`basestring`: :obj:`function`}
+    :param col_max_width: maximum width of table
+    :type col_max_width: int
+    :param defaults: default values for keys that don't exist in the data itself, e.g.
+     ``{'serviceId':'123'}``
+    :type defaults: {:obj:`basestring`: :obj:`basestring`}
+    """
     if items is None:
         items = []
     elif not isinstance(items, list):
@@ -43,30 +64,17 @@
     """
     Return a new PrettyTable instance representing the list.
 
-    Arguments:
-
-        cols - An iterable of strings that specify what
-               are the columns of the table.
-
-               for example: ['id','name']
-
-        data - An iterable of dictionaries or objects, each element must
-               have keys or attributes corresponding to the cols items.
-
-               for example: [{'id':'123', 'name':'Pete'}]
-
-        column_formatters - A dictionary from a column name to a formatter - a function that
-                            may manipulate the string values printed for this column.
-                            (See below for a few built-in formatter examples)
-
-                            for example: {'created_at': timestamp_formatter}
-
-        defaults - A dictionary specifying default values for
-                   key's that don't exist in the data itself.
-
-                   for example: {'serviceId':'123'} will set the
-                   serviceId value for all rows to '123'.
-
+    :param cols: columns of the table, e.g. ``['id','name']``
+    :type cols: iterable of :obj:`basestring`
+    :param data: each element must have keys or attributes corresponding to the ``cols`` items,
+     e.g. ``[{'id':'123', 'name':'Pete'}]``
+    :type data: [{:obj:`basestring`: :obj:`basestring`}]
+    :param column_formatters: maps column name to formatter, a function that may manipulate the
+     string values printed for this column, e.g. ``{'created_at': timestamp_formatter}``
+    :type column_formatters: {:obj:`basestring`: :obj:`function`}
+    :param defaults: default values for keys that don't exist in the data itself, e.g.
+     ``{'serviceId':'123'}``
+    :type defaults: {:obj:`basestring`: :obj:`basestring`}
     """
     def get_values_per_column(column, row_data):
         if hasattr(row_data, column) or (isinstance(row_data, dict) and column in row_data):
diff --git a/aria/cli/utils.py b/aria/cli/utils.py
index 852f24d..697ff37 100644
--- a/aria/cli/utils.py
+++ b/aria/cli/utils.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Miscellaneous CLI utilities.
+"""
+
 import os
 import sys
 from StringIO import StringIO
@@ -44,8 +48,8 @@
 
 def check_overriding_storage_exceptions(e, model_class, name):
     """
-    This method checks whether the storage exception is a known type where we'd like to override
-     the exception message; If so, it raises a new error. Otherwise it simply returns.
+    Checks whether the storage exception is a known type where we'd like to override the exception
+    message; If so, it raises a new error. Otherwise it simply returns.
     """
     assert isinstance(e, BaseException)
     if 'UNIQUE constraint failed' in e.message:
@@ -68,15 +72,16 @@
 
 
 def generate_progress_handler(file_path, action='', max_bar_length=80):
-    """Returns a function that prints a progress bar in the terminal
-
-    :param file_path: The name of the file being transferred
-    :param action: Uploading/Downloading
-    :param max_bar_length: Maximum allowed length of the bar. Default: 80
-    :return: The configured print_progress function
     """
-    # We want to limit the maximum line length to 80, but allow for a smaller
-    # terminal size. We also include the action string, and some extra chars
+    Returns a function that prints a progress bar in the terminal.
+
+    :param file_path: the name of the file being transferred
+    :param action: uploading/downloading
+    :param max_bar_length: maximum allowed length of the bar
+    :return: configured ``print_progress`` function
+    """
+    # We want to limit the maximum line length to 80, but allow for a smaller terminal size. We also
+    # include the action string, and some extra chars
     terminal_width = get_terminal_size().columns
 
     # This takes care of the case where there is no terminal (e.g. unittest)
@@ -91,24 +96,21 @@
     bar_length -= len(file_name)
 
     def print_progress(read_bytes, total_bytes):
-        """Print upload/download progress on a single line
+        """
+        Print upload/download progress on a single line.
 
-        Call this function in a loop to create a progress bar in the terminal
+        Call this function in a loop to create a progress bar in the terminal.
 
-        :param read_bytes: Number of bytes already processed
-        :param total_bytes: Total number of bytes in the file
+        :param read_bytes: number of bytes already processed
+        :param total_bytes: total number of bytes in the file
         """
 
-        filled_length = min(bar_length, int(round(bar_length * read_bytes /
-                                                  float(total_bytes))))
-        percents = min(100.00, round(
-            100.00 * (read_bytes / float(total_bytes)), 2))
+        filled_length = min(bar_length, int(round(bar_length * read_bytes / float(total_bytes))))
+        percents = min(100.00, round(100.00 * (read_bytes / float(total_bytes)), 2))
         bar = '#' * filled_length + '-' * (bar_length - filled_length)  # pylint: disable=blacklisted-name
 
-        # The \r caret makes sure the cursor moves back to the beginning of
-        # the line
-        sys.stdout.write('\r{0} {1} |{2}| {3}%'.format(
-            action, file_name, bar, percents))
+        # The \r caret makes sure the cursor moves back to the beginning of the line
+        sys.stdout.write('\r{0} {1} |{2}| {3}%'.format(action, file_name, bar, percents))
         if read_bytes >= total_bytes:
             sys.stdout.write(os.linesep)
 
diff --git a/aria/core.py b/aria/core.py
index f660167..a8d5245 100644
--- a/aria/core.py
+++ b/aria/core.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+ARIA core module.
+"""
+
 from . import exceptions
 from .parser import consumption
 from .parser.loading.location import UriLocation
diff --git a/aria/exceptions.py b/aria/exceptions.py
index 93987dc..5d3e21d 100644
--- a/aria/exceptions.py
+++ b/aria/exceptions.py
@@ -14,9 +14,7 @@
 # limitations under the License.
 
 """
-ARIA exceptions module
-Every sub-package in ARIA has a module with its exceptions.
-aria.exceptions module conveniently collects all these exceptions for easier imports.
+Base exception classes and other common exceptions used throughout ARIA.
 """
 
 import sys
@@ -48,21 +46,21 @@
 
 class DependentServicesError(AriaError):
     """
-    Raised when attempting to delete a service template which has existing services
+    Raised when attempting to delete a service template which has existing services.
     """
     pass
 
 
 class DependentActiveExecutionsError(AriaError):
     """
-    Raised when attempting to delete a service which has active executions
+    Raised when attempting to delete a service which has active executions.
     """
     pass
 
 
 class DependentAvailableNodesError(AriaError):
     """
-    Raised when attempting to delete a service which has available nodes
+    Raised when attempting to delete a service which has available nodes.
     """
     pass
 
diff --git a/aria/extension.py b/aria/extension.py
index 4dba74f..e90750d 100644
--- a/aria/extension.py
+++ b/aria/extension.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Mechanism for registering and loading ARIA extensions.
+"""
+
 # pylint: disable=no-self-use
 
 from .utils import collections
@@ -49,7 +53,9 @@
 
 
 class _ExtensionRegistration(object):
-    """Base class for extension class decorators"""
+    """
+    Base class for extension class decorators.
+    """
 
     def __init__(self):
         self._registrars = {}
@@ -70,7 +76,7 @@
 
     def init(self):
         """
-        Initialize all registrars by calling all registered functions
+        Initialize all registrars by calling all registered functions.
         """
         registered_instances = [cls() for cls in self._registered_classes]
         for name, registrar in self._registrars.items():
@@ -81,13 +87,16 @@
 
 
 class _ParserExtensionRegistration(_ExtensionRegistration):
-    """Parser extensions class decorator"""
+    """
+    Parser extensions class decorator.
+    """
 
     @_registrar
     def presenter_class(self):
         """
         Presentation class registration.
-        Implementing functions can return a single class or a list/tuple of classes
+
+        Implementing functions can return a single class or a list/tuple of classes.
         """
         return []
 
@@ -95,7 +104,8 @@
     def specification_package(self):
         """
         Specification package registration.
-        Implementing functions can return a package name or a list/tuple of names
+
+        Implementing functions can return a package name or a list/tuple of names.
         """
         return []
 
@@ -103,7 +113,8 @@
     def specification_url(self):
         """
         Specification URL registration.
-        Implementing functions should return a dictionary from names to URLs
+
+        Implementing functions should return a dictionary from names to URLs.
         """
         return {}
 
@@ -111,7 +122,8 @@
     def uri_loader_prefix(self):
         """
         URI loader prefix registration.
-        Implementing functions can return a single prefix or a list/tuple of prefixes
+
+        Implementing functions can return a single prefix or a list/tuple of prefixes.
         """
         return collections.StrictList(value_class=basestring)
 
@@ -119,13 +131,15 @@
 
 
 class _ProcessExecutorExtensionRegistration(_ExtensionRegistration):
-    """Process executor extension class decorator"""
+    """
+    Process executor extension class decorator.
+    """
 
     @_registrar
     def decorate(self):
         """
         The operation function executed by the process executor will be decorated with the function
-        returned from decorate().
+        returned from ``decorate()``.
         """
         return []
 
@@ -134,7 +148,7 @@
 
 def init():
     """
-    Initialize all registrars by calling all registered functions
+    Initialize all registrars by calling all registered functions.
     """
     parser.init()
     process_executor.init()
diff --git a/aria/logger.py b/aria/logger.py
index bd7ed4e..f4f6ec9 100644
--- a/aria/logger.py
+++ b/aria/logger.py
@@ -14,7 +14,8 @@
 # limitations under the License.
 
 """
-Logging related mixins and functions
+Mix-ins and functions for logging, supporting multiple backends (such as SQL) and consistent
+formatting.
 """
 
 import logging
@@ -38,12 +39,11 @@
 
 class LoggerMixin(object):
     """
-    Mixin Logger Class
-    configuration (class members):
-        logger_name: logger name [default: <class_name>]
-        logger_level: logger level [default: logging.DEBUG]
-        base_logger: This Mixing will create child logger from this base_logger
-                    [default: root logger]
+    Provides logging functionality to a class.
+
+    :ivar logger_name: logger name; default to the class name
+    :ivar logger_level: logger level; defaults to ``logging.DEBUG``
+    :ivar base_logger: child loggers are created from this; defaults to the root logger
     """
     logger_name = None
     logger_level = logging.DEBUG
@@ -66,7 +66,7 @@
             base_logger=logging.getLogger(),
             **kwargs):
         """
-        Set the logger used by the consuming class
+        Set the logger used by the consuming class.
         """
         cls.logger_name = logger_name
         cls.logger_level = logger_level
@@ -86,10 +86,12 @@
 
 def create_logger(logger=_base_logger, handlers=(), **configs):
     """
-
-    :param logging.Logger logger: The logger name [default: aria logger]
-    :param list handlers: The logger handlers
-    :param configs: The logger configurations
+    :param logger: logger name; defaults to ARIA logger
+    :type logger: logging.Logger
+    :param handlers: logger handlers
+    :type handlers: []
+    :param configs: logger configurations
+    :type configs: []
     :return: logger
     """
     logger.handlers = []
@@ -103,10 +105,8 @@
 
 def create_console_log_handler(level=logging.DEBUG, formatter=None):
     """
-
     :param level:
     :param formatter:
-    :return:
     """
     console = logging.StreamHandler()
     console.setLevel(level)
@@ -123,10 +123,9 @@
 
 class _DefaultConsoleFormat(logging.Formatter):
     """
-    _DefaultConsoleFormat class
-    Console logger formatter
-     info level logs format: '%(message)s'
-     every other log level are formatted: '%(levelname)s: %(message)s'
+    Info level log format: ``%(message)s``.
+
+    Every other log level is formatted: ``%(levelname)s: %(message)s``.
     """
     def format(self, record):
         try:
@@ -147,7 +146,7 @@
         backup_count=10,
         formatter=None):
     """
-    Create a logging.handlers.RotatingFileHandler
+    Create a :class:`logging.handlers.RotatingFileHandler`.
     """
     rotating_file = logging_handlers.RotatingFileHandler(
         filename=file_path,
@@ -161,7 +160,6 @@
 
 
 class _SQLAlchemyHandler(logging.Handler):
-
     def __init__(self, model, log_cls, execution_id, **kwargs):
         logging.Handler.__init__(self, **kwargs)
         self._model = model
diff --git a/aria/modeling/__init__.py b/aria/modeling/__init__.py
index 4ac79e7..57bc188 100644
--- a/aria/modeling/__init__.py
+++ b/aria/modeling/__init__.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+This package provides an API for modeling ARIA's state and serializing it to storage.
+"""
+
 from collections import namedtuple
 
 from . import (
diff --git a/aria/modeling/constraints.py b/aria/modeling/constraints.py
index 107b010..8ed33d5 100644
--- a/aria/modeling/constraints.py
+++ b/aria/modeling/constraints.py
@@ -13,6 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Constraints for the requirements-and-capabilities matching mechanism.
+"""
 
 class NodeTemplateConstraint(object):
     """
@@ -23,6 +26,6 @@
 
     def matches(self, source_node_template, target_node_template):
         """
-        Returns true is the target matches the constraint for the source.
+        Returns ``True`` if the target matches the constraint for the source.
         """
         raise NotImplementedError
diff --git a/aria/modeling/exceptions.py b/aria/modeling/exceptions.py
index d0e3e22..573efaf 100644
--- a/aria/modeling/exceptions.py
+++ b/aria/modeling/exceptions.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Modeling exceptions.
+"""
+
 from ..exceptions import AriaException
 
 
diff --git a/aria/modeling/functions.py b/aria/modeling/functions.py
index 06fd19f..6544adf 100644
--- a/aria/modeling/functions.py
+++ b/aria/modeling/functions.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Mechanism for evaluating intrinsic functions.
+"""
+
 from ..parser.consumption import ConsumptionContext
 from ..parser.exceptions import InvalidValueError
 from ..utils.collections import OrderedDict
@@ -34,10 +38,11 @@
 
     def __evaluate__(self, container_holder):
         """
-        Evaluates the function if possible. If impossible, raises
-        :class:`CannotEvaluateFunctionException` (do not just return None).
+        Evaluates the function if possible.
 
-        :rtype: Evaluation (or any object with ``value`` and ``final`` properties)
+        :rtype: :class:`Evaluation` (or any object with ``value`` and ``final`` properties)
+        :raises CannotEvaluateFunctionException: if cannot be evaluated at this time (do *not* just
+         return ``None``)
         """
 
         raise NotImplementedError
@@ -50,6 +55,10 @@
 class Evaluation(object):
     """
     An evaluated :class:`Function` return value.
+
+    :ivar value: evaluated value
+    :ivar final: whether the value is final
+    :vartype final: boolean
     """
 
     def __init__(self, value, final=False):
@@ -60,13 +69,13 @@
 def evaluate(value, container_holder, report_issues=False): # pylint: disable=too-many-branches
     """
     Recursively attempts to call ``__evaluate__``. If an evaluation occurred will return an
-    :class:`Evaluation`, otherwise it will be None. If any evaluation is non-final, then the entire
-    evaluation will also be non-final.
+    :class:`Evaluation`, otherwise it will be ``None``. If any evaluation is non-final, then the
+    entire evaluation will also be non-final.
 
     The ``container_holder`` argument should have three properties: ``container`` should return
     the model that contains the value, ``service`` should return the containing
-    :class:`aria.modeling.models.Service` model or None, and ``service_template`` should return the
-    containing :class:`aria.modeling.models.ServiceTemplate` model or None.
+    :class:`~aria.modeling.models.Service` model or None, and ``service_template`` should return the
+    containing :class:`~aria.modeling.models.ServiceTemplate` model or ``None``.
     """
 
     evaluated = False
diff --git a/aria/modeling/mixins.py b/aria/modeling/mixins.py
index c98a866..883ff4a 100644
--- a/aria/modeling/mixins.py
+++ b/aria/modeling/mixins.py
@@ -14,9 +14,7 @@
 # limitations under the License.
 
 """
-classes:
-    * ModelMixin - abstract model implementation.
-    * ModelIDMixin - abstract model implementation with IDs.
+ARIA modeling mix-ins module
 """
 
 from sqlalchemy.ext import associationproxy
@@ -49,11 +47,11 @@
 
     def to_dict(self, fields=None, suppress_error=False):
         """
-        Return a dict representation of the model
+        Create a dict representation of the model.
 
-        :param suppress_error: If set to True, sets ``None`` to attributes that it's unable to
-                               retrieve (e.g., if a relationship wasn't established yet, and so it's
-                               impossible to access a property through it)
+        :param suppress_error: if set to ``True``, sets ``None`` to attributes that it's unable to
+         retrieve (e.g., if a relationship wasn't established yet, and so it's impossible to access
+         a property through it)
         """
 
         res = dict()
@@ -79,14 +77,14 @@
     @classmethod
     def fields(cls):
         """
-        Return the list of field names for this table
+        List of field names for this table.
 
-        Mostly for backwards compatibility in the code (that uses ``fields``)
+        Mostly for backwards compatibility in the code (that uses ``fields``).
         """
 
         fields = set(cls._iter_association_proxies())
         fields.update(cls.__table__.columns.keys())
-        return fields - set(getattr(cls, '__private_fields__', []))
+        return fields - set(getattr(cls, '__private_fields__', ()))
 
     @classmethod
     def _iter_association_proxies(cls):
@@ -101,8 +99,17 @@
 
 
 class ModelIDMixin(object):
-    id = Column(Integer, primary_key=True, autoincrement=True)
-    name = Column(Text, index=True)
+    id = Column(Integer, primary_key=True, autoincrement=True, doc="""
+    Unique ID.
+    
+    :type: :obj:`int`
+    """)
+
+    name = Column(Text, index=True, doc="""
+    Model name.
+    
+    :type: :obj:`basestring`
+    """)
 
     @classmethod
     def id_column_name(cls):
@@ -115,10 +122,10 @@
 
 class InstanceModelMixin(ModelMixin):
     """
-    Mixin for :class:`ServiceInstance` models.
+    Mix-in for service instance models.
 
-    All models support validation, diagnostic dumping, and representation as
-    raw data (which can be translated into JSON or YAML) via ``as_raw``.
+    All models support validation, diagnostic dumping, and representation as raw data (which can be
+    translated into JSON or YAML) via :meth:`as_raw`.
     """
 
     @property
@@ -137,9 +144,9 @@
 
 class TemplateModelMixin(InstanceModelMixin):
     """
-    Mixin for :class:`ServiceTemplate` models.
+    Mix-in for service template models.
 
-    All model models can be instantiated into :class:`ServiceInstance` models.
+    All model models can be instantiated into service instance models.
     """
 
     def instantiate(self, container):
@@ -148,24 +155,26 @@
 
 class ParameterMixin(TemplateModelMixin, caching.HasCachedMethods):                                 #pylint: disable=abstract-method
     """
-    Represents a typed value. The value can contain nested intrinsic functions.
+    Mix-in for typed values. The value can contain nested intrinsic functions.
 
-    This model can be used as the ``container_holder`` argument for :func:`functions.evaluate`.
-
-    :ivar name: Name
-    :vartype name: basestring
-    :ivar type_name: Type name
-    :vartype type_name: basestring
-    :ivar value: Value
-    :ivar description: Description
-    :vartype description: basestring
+    This model can be used as the ``container_holder`` argument for
+    :func:`~aria.modeling.functions.evaluate`.
     """
 
     __tablename__ = 'parameter'
 
-    name = Column(Text)
-    type_name = Column(Text)
-    description = Column(Text)
+    type_name = Column(Text, doc="""
+    Type name.
+    
+    :type: :obj:`basestring`
+    """)
+
+    description = Column(Text, doc="""
+    Human-readable description.
+    
+    :type: :obj:`basestring`
+    """)
+
     _value = Column(PickleType)
 
     @property
@@ -187,8 +196,10 @@
         """
         The sole owner of this parameter, which is another model that relates to it.
 
-        *All* parameters should have an owner model. In case this property method fails to find
-        it, it will raise a ValueError, which should signify an abnormal, orphaned parameter.
+        *All* parameters should have an owner model.
+
+        :raises ~exceptions.ValueError: if failed to find an owner, which signifies an abnormal,
+         orphaned parameter
         """
 
         # Find first non-null relationship
@@ -210,8 +221,10 @@
         The logical container is equivalent to the ``SELF`` keyword used by intrinsic functions in
         TOSCA.
 
-        *All* parameters should have a container model. In case this property method fails to find
-        it, it will raise a ValueError, which should signify an abnormal, orphaned parameter.
+        *All* parameters should have a container model.
+
+        :raises ~exceptions.ValueError: if failed to find a container model, which signifies an
+         abnormal, orphaned parameter
         """
 
         from . import models
@@ -253,7 +266,11 @@
     @caching.cachedmethod
     def service(self):
         """
-        The :class:`Service` containing this parameter, or None if not contained in a service.
+        The :class:`~aria.modeling.models.Service` model containing this parameter, or ``None`` if
+        not contained in a service.
+
+        :raises ~exceptions.ValueError: if failed to find a container model, which signifies an
+         abnormal, orphaned parameter
         """
 
         from . import models
@@ -268,8 +285,11 @@
     @caching.cachedmethod
     def service_template(self):
         """
-        The :class:`ServiceTemplate` containing this parameter, or None if not contained in a
-        service template.
+        The :class:`~aria.modeling.models.ServiceTemplate` model containing this parameter, or
+        ``None`` if not contained in a service template.
+
+        :raises ~exceptions.ValueError: if failed to find a container model, which signifies an
+         abnormal, orphaned parameter
         """
 
         from . import models
@@ -329,10 +349,10 @@
         cos01 specification <http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01
         /TOSCA-Simple-Profile-YAML-v1.0-cos01.html#_Toc373867862>`__
 
-        :param name: Parameter name
+        :param name: parameter name
         :type name: basestring
-        :param value: Parameter value
-        :param description: Description (optional)
+        :param value: parameter value
+        :param description: human-readable description (optional)
         :type description: basestring
         """
 
@@ -345,7 +365,6 @@
                    description=description)
 
     def as_other_parameter_model(self, other_model_cls):
-
         name, value = self.unwrapped
         return other_model_cls.wrap(name, value)
 
diff --git a/aria/modeling/models.py b/aria/modeling/models.py
index f30b86f..cf84fdb 100644
--- a/aria/modeling/models.py
+++ b/aria/modeling/models.py
@@ -13,6 +13,74 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Data models.
+
+Service template models
+-----------------------
+
+.. autosummary::
+   :nosignatures:
+
+   aria.modeling.models.ServiceTemplate
+   aria.modeling.models.NodeTemplate
+   aria.modeling.models.GroupTemplate
+   aria.modeling.models.PolicyTemplate
+   aria.modeling.models.SubstitutionTemplate
+   aria.modeling.models.SubstitutionTemplateMapping
+   aria.modeling.models.RequirementTemplate
+   aria.modeling.models.RelationshipTemplate
+   aria.modeling.models.CapabilityTemplate
+   aria.modeling.models.InterfaceTemplate
+   aria.modeling.models.OperationTemplate
+   aria.modeling.models.ArtifactTemplate
+   aria.modeling.models.PluginSpecification
+
+Service instance models
+-----------------------
+
+.. autosummary::
+   :nosignatures:
+
+   aria.modeling.models.Service
+   aria.modeling.models.Node
+   aria.modeling.models.Group
+   aria.modeling.models.Policy
+   aria.modeling.models.Substitution
+   aria.modeling.models.SubstitutionMapping
+   aria.modeling.models.Relationship
+   aria.modeling.models.Capability
+   aria.modeling.models.Interface
+   aria.modeling.models.Operation
+   aria.modeling.models.Artifact
+
+Common models
+-------------
+
+.. autosummary::
+   :nosignatures:
+
+   aria.modeling.models.Output
+   aria.modeling.models.Input
+   aria.modeling.models.Configuration
+   aria.modeling.models.Property
+   aria.modeling.models.Attribute
+   aria.modeling.models.Type
+   aria.modeling.models.Metadata
+
+Orchestration models
+--------------------
+
+.. autosummary::
+   :nosignatures:
+
+   aria.modeling.models.Execution
+   aria.modeling.models.Task
+   aria.modeling.models.Log
+   aria.modeling.models.Plugin
+   aria.modeling.models.Argument
+"""
+
 # pylint: disable=abstract-method
 
 from sqlalchemy.ext.declarative import declarative_base
@@ -28,14 +96,15 @@
     service_common,
     orchestration,
     mixins,
+    utils
 )
 
+
 aria_declarative_base = declarative_base(cls=mixins.ModelIDMixin)
 
 
 # See also models_to_register at the bottom of this file
 __all__ = (
-    'aria_declarative_base',
     'models_to_register',
 
     # Service template models
@@ -91,54 +160,68 @@
 
 # region service template models
 
+@utils.fix_doc
 class ServiceTemplate(aria_declarative_base, service_template.ServiceTemplateBase):
     name = Column(Text, index=True, unique=True)
 
 
+@utils.fix_doc
 class NodeTemplate(aria_declarative_base, service_template.NodeTemplateBase):
     pass
 
 
+@utils.fix_doc
 class GroupTemplate(aria_declarative_base, service_template.GroupTemplateBase):
     pass
 
 
+@utils.fix_doc
 class PolicyTemplate(aria_declarative_base, service_template.PolicyTemplateBase):
     pass
 
 
+@utils.fix_doc
 class SubstitutionTemplate(aria_declarative_base, service_template.SubstitutionTemplateBase):
     pass
 
 
+@utils.fix_doc
 class SubstitutionTemplateMapping(aria_declarative_base,
                                   service_template.SubstitutionTemplateMappingBase):
     pass
 
 
+@utils.fix_doc
 class RequirementTemplate(aria_declarative_base, service_template.RequirementTemplateBase):
     pass
 
 
+@utils.fix_doc
 class RelationshipTemplate(aria_declarative_base, service_template.RelationshipTemplateBase):
     pass
 
 
+@utils.fix_doc
 class CapabilityTemplate(aria_declarative_base, service_template.CapabilityTemplateBase):
     pass
 
 
+@utils.fix_doc
 class InterfaceTemplate(aria_declarative_base, service_template.InterfaceTemplateBase):
     pass
 
 
+@utils.fix_doc
 class OperationTemplate(aria_declarative_base, service_template.OperationTemplateBase):
     pass
 
 
+@utils.fix_doc
 class ArtifactTemplate(aria_declarative_base, service_template.ArtifactTemplateBase):
     pass
 
+
+@utils.fix_doc
 class PluginSpecification(aria_declarative_base, service_template.PluginSpecificationBase):
     pass
 
@@ -147,46 +230,57 @@
 
 # region service instance models
 
+@utils.fix_doc
 class Service(aria_declarative_base, service_instance.ServiceBase):
     name = Column(Text, index=True, unique=True)
 
 
+@utils.fix_doc
 class Node(aria_declarative_base, service_instance.NodeBase):
     pass
 
 
+@utils.fix_doc
 class Group(aria_declarative_base, service_instance.GroupBase):
     pass
 
 
+@utils.fix_doc
 class Policy(aria_declarative_base, service_instance.PolicyBase):
     pass
 
 
+@utils.fix_doc
 class Substitution(aria_declarative_base, service_instance.SubstitutionBase):
     pass
 
 
+@utils.fix_doc
 class SubstitutionMapping(aria_declarative_base, service_instance.SubstitutionMappingBase):
     pass
 
 
+@utils.fix_doc
 class Relationship(aria_declarative_base, service_instance.RelationshipBase):
     pass
 
 
+@utils.fix_doc
 class Capability(aria_declarative_base, service_instance.CapabilityBase):
     pass
 
 
+@utils.fix_doc
 class Interface(aria_declarative_base, service_instance.InterfaceBase):
     pass
 
 
+@utils.fix_doc
 class Operation(aria_declarative_base, service_instance.OperationBase):
     pass
 
 
+@utils.fix_doc
 class Artifact(aria_declarative_base, service_instance.ArtifactBase):
     pass
 
@@ -195,14 +289,17 @@
 
 # region service changes models
 
+@utils.fix_doc
 class ServiceUpdate(aria_declarative_base, service_changes.ServiceUpdateBase):
     pass
 
 
+@utils.fix_doc
 class ServiceUpdateStep(aria_declarative_base, service_changes.ServiceUpdateStepBase):
     pass
 
 
+@utils.fix_doc
 class ServiceModification(aria_declarative_base, service_changes.ServiceModificationBase):
     pass
 
@@ -211,31 +308,37 @@
 
 # region common service models
 
-
+@utils.fix_doc
 class Input(aria_declarative_base, service_common.InputBase):
     pass
 
 
+@utils.fix_doc
 class Configuration(aria_declarative_base, service_common.ConfigurationBase):
     pass
 
 
+@utils.fix_doc
 class Output(aria_declarative_base, service_common.OutputBase):
     pass
 
 
+@utils.fix_doc
 class Property(aria_declarative_base, service_common.PropertyBase):
     pass
 
 
+@utils.fix_doc
 class Attribute(aria_declarative_base, service_common.AttributeBase):
     pass
 
 
+@utils.fix_doc
 class Type(aria_declarative_base, service_common.TypeBase):
     pass
 
 
+@utils.fix_doc
 class Metadata(aria_declarative_base, service_common.MetadataBase):
     pass
 
@@ -244,26 +347,30 @@
 
 # region orchestration models
 
+@utils.fix_doc
 class Execution(aria_declarative_base, orchestration.ExecutionBase):
     pass
 
 
+@utils.fix_doc
 class Plugin(aria_declarative_base, orchestration.PluginBase):
     pass
 
 
+@utils.fix_doc
 class Task(aria_declarative_base, orchestration.TaskBase):
     pass
 
 
+@utils.fix_doc
 class Log(aria_declarative_base, orchestration.LogBase):
     pass
 
 
+@utils.fix_doc
 class Argument(aria_declarative_base, orchestration.ArgumentBase):
     pass
 
-
 # endregion
 
 
diff --git a/aria/modeling/orchestration.py b/aria/modeling/orchestration.py
index 829c305..7068557 100644
--- a/aria/modeling/orchestration.py
+++ b/aria/modeling/orchestration.py
@@ -14,10 +14,7 @@
 # limitations under the License.
 
 """
-classes:
-    * Execution - execution implementation model.
-    * Plugin - plugin implementation model.
-    * Task - a task
+ARIA modeling orchestration module
 """
 
 # pylint: disable=no-self-argument, no-member, abstract-method
@@ -34,7 +31,6 @@
     Float,
     orm,
     PickleType)
-from sqlalchemy.ext.associationproxy import association_proxy
 from sqlalchemy.ext.declarative import declared_attr
 
 from ..orchestrator.exceptions import (TaskAbortException, TaskRetryException)
@@ -47,13 +43,13 @@
 
 class ExecutionBase(mixins.ModelMixin):
     """
-    Execution model representation.
+    Workflow execution.
     """
 
     __tablename__ = 'execution'
 
-    __private_fields__ = ['service_fk',
-                          'service_template']
+    __private_fields__ = ('service_fk',
+                          'service_template')
 
     SUCCEEDED = 'succeeded'
     FAILED = 'failed'
@@ -72,6 +68,110 @@
         CANCELLED: PENDING
     }
 
+    # region one_to_many relationships
+
+    @declared_attr
+    def inputs(cls):
+        """
+        Execution parameters.
+
+        :type: {:obj:`basestring`: :class:`Input`}
+        """
+        return relationship.one_to_many(cls, 'input', dict_key='name')
+
+    @declared_attr
+    def tasks(cls):
+        """
+        Tasks.
+
+        :type: [:class:`Task`]
+        """
+        return relationship.one_to_many(cls, 'task')
+
+    @declared_attr
+    def logs(cls):
+        """
+        Log messages for the execution (including log messages for its tasks).
+
+        :type: [:class:`Log`]
+        """
+        return relationship.one_to_many(cls, 'log')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def service(cls):
+        """
+        Associated service.
+
+        :type: :class:`Service`
+        """
+        return relationship.many_to_one(cls, 'service')
+
+    # endregion
+
+    # region association proxies
+
+    @declared_attr
+    def service_name(cls):
+        return relationship.association_proxy('service', cls.name_column_name())
+
+    @declared_attr
+    def service_template(cls):
+        return relationship.association_proxy('service', 'service_template')
+
+    @declared_attr
+    def service_template_name(cls):
+        return relationship.association_proxy('service', 'service_template_name')
+
+    # endregion
+
+    # region foreign keys
+
+    @declared_attr
+    def service_fk(cls):
+        return relationship.foreign_key('service')
+
+    # endregion
+
+    created_at = Column(DateTime, index=True, doc="""
+    Creation timestamp.
+
+    :type: :class:`~datetime.datetime`
+    """)
+
+    started_at = Column(DateTime, nullable=True, index=True, doc="""
+    Started timestamp.
+
+    :type: :class:`~datetime.datetime`
+    """)
+
+    ended_at = Column(DateTime, nullable=True, index=True, doc="""
+    Ended timestamp.
+
+    :type: :class:`~datetime.datetime`
+    """)
+
+    error = Column(Text, nullable=True, doc="""
+    Error message.
+
+    :type: :obj:`basestring`
+    """)
+
+    status = Column(Enum(*STATES, name='execution_status'), default=PENDING, doc="""
+    Status.
+
+    :type: :obj:`basestring`
+    """)
+
+    workflow_name = Column(Text, doc="""
+    Workflow name.
+
+    :type: :obj:`basestring`
+    """)
+
     @orm.validates('status')
     def validate_status(self, key, value):
         """Validation function that verifies execution status transitions are OK"""
@@ -88,62 +188,12 @@
                 new=value))
         return value
 
-    created_at = Column(DateTime, index=True)
-    started_at = Column(DateTime, nullable=True, index=True)
-    ended_at = Column(DateTime, nullable=True, index=True)
-    error = Column(Text, nullable=True)
-    status = Column(Enum(*STATES, name='execution_status'), default=PENDING)
-    workflow_name = Column(Text)
-
     def has_ended(self):
         return self.status in self.END_STATES
 
     def is_active(self):
         return not self.has_ended() and self.status != self.PENDING
 
-    @declared_attr
-    def logs(cls):
-        return relationship.one_to_many(cls, 'log')
-
-    @declared_attr
-    def service(cls):
-        return relationship.many_to_one(cls, 'service')
-
-    @declared_attr
-    def tasks(cls):
-        return relationship.one_to_many(cls, 'task')
-
-    @declared_attr
-    def inputs(cls):
-        return relationship.one_to_many(cls, 'input', dict_key='name')
-
-    # region foreign keys
-
-    @declared_attr
-    def service_fk(cls):
-        return relationship.foreign_key('service')
-
-    # endregion
-
-    # region association proxies
-
-    @declared_attr
-    def service_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('service', cls.name_column_name())
-
-    @declared_attr
-    def service_template(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('service', 'service_template')
-
-    @declared_attr
-    def service_template_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('service', 'service_template_name')
-
-    # endregion
-
     def __str__(self):
         return '<{0} id=`{1}` (status={2})>'.format(
             self.__class__.__name__,
@@ -152,113 +202,26 @@
         )
 
 
-class PluginBase(mixins.ModelMixin):
-    """
-    An installed plugin.
-
-    Plugins are usually packaged as `wagons <https://github.com/cloudify-cosmo/wagon>`__, which
-    are archives of one or more `wheels <https://packaging.python.org/distributing/#wheels>`__.
-    Most of these fields are indeed extracted from the installed wagon's metadata.
-
-    :ivar archive_name: Filename (not the full path) of the wagon's archive, often with a ".wgn"
-                        extension
-    :vartype archive_name: basestring
-    :ivar distribution: The name of the operating system on which the wagon was installed (e.g.
-                        "ubuntu")
-    :vartype distribution: basestring
-    :ivar distribution_release: The release of the operating system on which the wagon was installed
-                                (e.g. "trusty")
-    :vartype distribution_release: basestring
-    :ivar distribution_version: The version of the operating system on which the wagon was installed
-                                (e.g. "14.04")
-    :vartype distribution_version: basestring
-    :ivar package_name: The primary Python package name used when the wagon was installed, which is
-                        one of the wheels in the wagon (e.g. "cloudify-script-plugin")
-    :vartype package_name: basestring
-    :ivar package_source: The full install string for the primary Python package name used when the
-                          wagon was installed (e.g. "cloudify-script-plugin==1.2")
-    :vartype package_source: basestring
-    :ivar package_version: The version for the primary Python package name used when the wagon was
-                           installed (e.g. "1.2")
-    :vartype package_version: basestring
-    :ivar supported_platform: If the wheels are *all* pure Python then this would be "any",
-                              otherwise it would be the installed platform name (e.g.
-                              "linux_x86_64")
-    :vartype supported_platform: basestring
-    :ivar supported_py_versions: The Python versions supported by all the wheels (e.g. ["py26",
-                                 "py27"])
-    :vartype supported_py_versions: [basestring]
-    :ivar wheels: The filenames of the wheels archived in the wagon, often with a ".whl" extension
-    :vartype wheels: [basestring]
-    :ivar uploaded_at: Timestamp for when the wagon was installed
-    :vartype uploaded_at: basestring
-    """
-
-    __tablename__ = 'plugin'
-
-    @declared_attr
-    def tasks(cls):
-        return relationship.one_to_many(cls, 'task')
-
-    archive_name = Column(Text, nullable=False, index=True)
-    distribution = Column(Text)
-    distribution_release = Column(Text)
-    distribution_version = Column(Text)
-    package_name = Column(Text, nullable=False, index=True)
-    package_source = Column(Text)
-    package_version = Column(Text)
-    supported_platform = Column(Text)
-    supported_py_versions = Column(modeling_types.StrictList(basestring))
-    wheels = Column(modeling_types.StrictList(basestring), nullable=False)
-    uploaded_at = Column(DateTime, nullable=False, index=True)
-
-
 class TaskBase(mixins.ModelMixin):
     """
     Represents the smallest unit of stateful execution in ARIA. The task state includes inputs,
     outputs, as well as an atomic status, ensuring that the task can only be running once at any
     given time.
 
+    The Python :attr:`function` is usually provided by an associated :class:`Plugin`. The
+    :attr:`arguments` of the function should be set according to the specific signature of the
+    function.
+
     Tasks may be "one shot" or may be configured to run repeatedly in the case of failure.
 
     Tasks are often based on :class:`Operation`, and thus act on either a :class:`Node` or a
     :class:`Relationship`, however this is not required.
-
-    :ivar node: The node actor (optional)
-    :vartype node: :class:`Node`
-    :ivar relationship: The relationship actor (optional)
-    :vartype relationship: :class:`Relationship`
-    :ivar plugin: The implementing plugin (set to None for default execution plugin)
-    :vartype plugin: :class:`Plugin`
-    :ivar function: Python path to an ``@operation`` function
-    :vartype function: basestring
-    :ivar arguments: Arguments that can be used by this task
-    :vartype arguments: {basestring: :class:`Argument`}
-    :ivar max_attempts: Maximum number of retries allowed in case of failure
-    :vartype max_attempts: int
-    :ivar retry_interval: Interval between retries (in seconds)
-    :vartype retry_interval: int
-    :ivar ignore_failure: Set to True to ignore failures
-    :vartype ignore_failure: bool
-    :ivar due_at: Timestamp to start the task
-    :vartype due_at: datetime
-    :ivar execution: Assigned execution
-    :vartype execution: :class:`Execution`
-    :ivar status: Current atomic status ('pending', 'retrying', 'sent', 'started', 'success',
-                  'failed')
-    :vartype status: basestring
-    :ivar started_at: Timestamp for when task started
-    :vartype started_at: datetime
-    :ivar ended_at: Timestamp for when task ended
-    :vartype ended_at: datetime
-    :ivar attempts_count: How many attempts occurred
-    :vartype attempts_count: int
     """
 
     __tablename__ = 'task'
 
-    __private_fields__ = ['dependency_operation_task_fk', 'dependency_stub_task_fk', 'node_fk',
-                          'relationship_fk', 'plugin_fk', 'execution_fk']
+    __private_fields__ = ('dependency_operation_task_fk', 'dependency_stub_task_fk', 'node_fk',
+                          'relationship_fk', 'plugin_fk', 'execution_fk')
 
     START_WORKFLOW = 'start_workflow'
     END_WORKFLOW = 'end_workflow'
@@ -292,70 +255,91 @@
     )
     INFINITE_RETRIES = -1
 
-    @declared_attr
-    def execution(cls):
-        return relationship.many_to_one(cls, 'execution')
-
-    @declared_attr
-    def execution_fk(cls):
-        return relationship.foreign_key('execution', nullable=True)
-
-    status = Column(Enum(*STATES, name='status'), default=PENDING)
-    due_at = Column(DateTime, nullable=False, index=True, default=datetime.utcnow())
-    started_at = Column(DateTime, default=None)
-    ended_at = Column(DateTime, default=None)
-    attempts_count = Column(Integer, default=1)
-
-    _executor = Column(PickleType)
-    _context_cls = Column(PickleType)
-    _stub_type = Column(Enum(*STUB_TYPES))
+    # region one_to_many relationships
 
     @declared_attr
     def logs(cls):
+        """
+        Log messages.
+
+        :type: [:class:`Log`]
+        """
         return relationship.one_to_many(cls, 'log')
 
     @declared_attr
+    def arguments(cls):
+        """
+        Arguments sent to the Python :attr:`function``.
+
+        :type: {:obj:`basestring`: :class:`Argument`}
+        """
+        return relationship.one_to_many(cls, 'argument', dict_key='name')
+
+    # endregion
+
+    # region many_one relationships
+
+    @declared_attr
+    def execution(cls):
+        """
+        Containing execution.
+
+        :type: :class:`Execution`
+        """
+        return relationship.many_to_one(cls, 'execution')
+
+    @declared_attr
     def node(cls):
+        """
+        Node actor (can be ``None``).
+
+        :type: :class:`Node`
+        """
         return relationship.many_to_one(cls, 'node')
 
     @declared_attr
     def relationship(cls):
+        """
+        Relationship actor (can be ``None``).
+
+        :type: :class:`Relationship`
+        """
         return relationship.many_to_one(cls, 'relationship')
 
     @declared_attr
     def plugin(cls):
+        """
+        Associated plugin.
+
+        :type: :class:`Plugin`
+        """
         return relationship.many_to_one(cls, 'plugin')
 
+    # endregion
+
+    # region association proxies
+
     @declared_attr
-    def arguments(cls):
-        return relationship.one_to_many(cls, 'argument', dict_key='name')
+    def node_name(cls):
+        return relationship.association_proxy('node', cls.name_column_name())
 
-    function = Column(String)
-    max_attempts = Column(Integer, default=1)
-    retry_interval = Column(Float, default=0)
-    ignore_failure = Column(Boolean, default=False)
-    interface_name = Column(String)
-    operation_name = Column(String)
+    @declared_attr
+    def relationship_name(cls):
+        return relationship.association_proxy('relationship', cls.name_column_name())
 
-    @property
-    def actor(self):
-        """
-        Return the actor of the task
-        :return:
-        """
-        return self.node or self.relationship
+    @declared_attr
+    def execution_name(cls):
+        return relationship.association_proxy('execution', cls.name_column_name())
 
-    @orm.validates('max_attempts')
-    def validate_max_attempts(self, _, value):                                  # pylint: disable=no-self-use
-        """Validates that max attempts is either -1 or a positive number"""
-        if value < 1 and value != TaskBase.INFINITE_RETRIES:
-            raise ValueError('Max attempts can be either -1 (infinite) or any positive number. '
-                             'Got {value}'.format(value=value))
-        return value
+    # endregion
 
     # region foreign keys
 
     @declared_attr
+    def execution_fk(cls):
+        return relationship.foreign_key('execution', nullable=True)
+
+    @declared_attr
     def node_fk(cls):
         return relationship.foreign_key('node', nullable=True)
 
@@ -369,24 +353,93 @@
 
     # endregion
 
-    # region association proxies
+    status = Column(Enum(*STATES, name='status'), default=PENDING, doc="""
+    Current atomic status ('pending', 'retrying', 'sent', 'started', 'success', 'failed').
 
-    @declared_attr
-    def node_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('node', cls.name_column_name())
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def relationship_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('relationship', cls.name_column_name())
+    due_at = Column(DateTime, nullable=False, index=True, default=datetime.utcnow(), doc="""
+    Timestamp to start the task.
 
-    @declared_attr
-    def execution_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('execution', cls.name_column_name())
+    :type: :class:`~datetime.datetime`
+    """)
 
-    # endregion
+    started_at = Column(DateTime, default=None, doc="""
+    Started timestamp.
+
+    :type: :class:`~datetime.datetime`
+    """)
+
+    ended_at = Column(DateTime, default=None, doc="""
+    Ended timestamp.
+
+    :type: :class:`~datetime.datetime`
+    """)
+
+    attempts_count = Column(Integer, default=1, doc="""
+    How many attempts occurred.
+
+    :type: :class:`~datetime.datetime`
+    """)
+
+    function = Column(String, doc="""
+    Full path to Python function.
+
+    :type: :obj:`basestring`
+    """)
+
+    max_attempts = Column(Integer, default=1, doc="""
+    Maximum number of attempts allowed in case of task failure.
+
+    :type: :obj:`int`
+    """)
+
+    retry_interval = Column(Float, default=0, doc="""
+    Interval between task retry attemps (in seconds).
+
+    :type: :obj:`float`
+    """)
+
+    ignore_failure = Column(Boolean, default=False, doc="""
+    Set to ``True`` to ignore failures.
+
+    :type: :obj:`bool`
+    """)
+
+    interface_name = Column(String, doc="""
+    Name of interface on node or relationship.
+
+    :type: :obj:`basestring`
+    """)
+
+    operation_name = Column(String, doc="""
+    Name of operation in interface on node or relationship.
+
+    :type: :obj:`basestring`
+    """)
+
+    _api_id = Column(String)
+    _executor = Column(PickleType)
+    _context_cls = Column(PickleType)
+    _stub_type = Column(Enum(*STUB_TYPES))
+
+    @property
+    def actor(self):
+        """
+        Actor of the task (node or relationship).
+        """
+        return self.node or self.relationship
+
+    @orm.validates('max_attempts')
+    def validate_max_attempts(self, _, value):                                  # pylint: disable=no-self-use
+        """
+        Validates that max attempts is either -1 or a positive number.
+        """
+        if value < 1 and value != TaskBase.INFINITE_RETRIES:
+            raise ValueError('Max attempts can be either -1 (infinite) or any positive number. '
+                             'Got {value}'.format(value=value))
+        return value
 
     @staticmethod
     def abort(message=None):
@@ -447,26 +500,36 @@
 
 
 class LogBase(mixins.ModelMixin):
+    """
+    Single log message.
+    """
 
     __tablename__ = 'log'
 
-    __private_fields__ = ['execution_fk',
-                          'task_fk']
+    __private_fields__ = ('execution_fk',
+                          'task_fk')
+
+    # region many_to_one relationships
 
     @declared_attr
     def execution(cls):
+        """
+        Containing execution.
+
+        :type: :class:`Execution`
+        """
         return relationship.many_to_one(cls, 'execution')
 
     @declared_attr
     def task(cls):
+        """
+        Containing task (can be ``None``).
+
+        :type: :class:`Task`
+        """
         return relationship.many_to_one(cls, 'task')
 
-    level = Column(String)
-    msg = Column(String)
-    created_at = Column(DateTime, index=True)
-
-    # In case of failed execution
-    traceback = Column(Text)
+    # endregion
 
     # region foreign keys
 
@@ -480,6 +543,30 @@
 
     # endregion
 
+    level = Column(String, doc="""
+    Log level.
+
+    :type: :obj:`basestring`
+    """)
+
+    msg = Column(String, doc="""
+    Log message.
+
+    :type: :obj:`basestring`
+    """)
+
+    created_at = Column(DateTime, index=True, doc="""
+    Creation timestamp.
+
+    :type: :class:`~datetime.datetime`
+    """)
+
+    traceback = Column(Text, doc="""
+    Error traceback in case of failure.
+
+    :type: :class:`~datetime.datetime`
+    """)
+
     def __str__(self):
         return self.msg
 
@@ -488,10 +575,129 @@
         return '{name}: {self.msg}'.format(name=name, self=self)
 
 
+class PluginBase(mixins.ModelMixin):
+    """
+    Installed plugin.
+
+    Plugins are usually packaged as `wagons <https://github.com/cloudify-cosmo/wagon>`__, which
+    are archives of one or more `wheels <https://packaging.python.org/distributing/#wheels>`__.
+    Most of these fields are indeed extracted from the installed wagon's metadata.
+    """
+
+    __tablename__ = 'plugin'
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def tasks(cls):
+        """
+        Associated Tasks.
+
+        :type: [:class:`Task`]
+        """
+        return relationship.one_to_many(cls, 'task')
+
+    # endregion
+
+    archive_name = Column(Text, nullable=False, index=True, doc="""
+    Filename (not the full path) of the wagon's archive, often with a ``.wgn`` extension.
+
+    :type: :obj:`basestring`
+    """)
+
+    distribution = Column(Text, doc="""
+    Name of the operating system on which the wagon was installed (e.g. ``ubuntu``).
+
+    :type: :obj:`basestring`
+    """)
+
+    distribution_release = Column(Text, doc="""
+    Release of the operating system on which the wagon was installed (e.g. ``trusty``).
+
+    :type: :obj:`basestring`
+    """)
+
+    distribution_version = Column(Text, doc="""
+    Version of the operating system on which the wagon was installed (e.g. ``14.04``).
+
+    :type: :obj:`basestring`
+    """)
+
+    package_name = Column(Text, nullable=False, index=True, doc="""
+    Primary Python package name used when the wagon was installed, which is one of the wheels in the
+    wagon (e.g. ``cloudify-script-plugin``).
+
+    :type: :obj:`basestring`
+    """)
+
+    package_source = Column(Text, doc="""
+    Full install string for the primary Python package name used when the wagon was installed (e.g.
+    ``cloudify-script-plugin==1.2``).
+
+    :type: :obj:`basestring`
+    """)
+
+    package_version = Column(Text, doc="""
+    Version for the primary Python package name used when the wagon was installed (e.g. ``1.2``).
+
+    :type: :obj:`basestring`
+    """)
+
+    supported_platform = Column(Text, doc="""
+    If the wheels are *all* pure Python then this would be "any", otherwise it would be the
+    installed platform name (e.g. ``linux_x86_64``).
+
+    :type: :obj:`basestring`
+    """)
+
+    supported_py_versions = Column(modeling_types.StrictList(basestring), doc="""
+    Python versions supported by all the wheels (e.g. ``["py26", "py27"]``)
+
+    :type: [:obj:`basestring`]
+    """)
+
+    wheels = Column(modeling_types.StrictList(basestring), nullable=False, doc="""
+    Filenames of the wheels archived in the wagon, often with a ``.whl`` extension.
+
+    :type: [:obj:`basestring`]
+    """)
+
+    uploaded_at = Column(DateTime, nullable=False, index=True, doc="""
+    Timestamp for when the wagon was installed.
+
+    :type: :class:`~datetime.datetime`
+    """)
+
+
 class ArgumentBase(mixins.ParameterMixin):
+    """
+    Python function argument parameter.
+    """
 
     __tablename__ = 'argument'
 
+    # region many_to_one relationships
+
+    @declared_attr
+    def task(cls):
+        """
+        Containing task (can be ``None``);
+
+        :type: :class:`Task`
+        """
+        return relationship.many_to_one(cls, 'task')
+
+    @declared_attr
+    def operation(cls):
+        """
+        Containing operation (can be ``None``);
+
+        :type: :class:`Operation`
+        """
+        return relationship.many_to_one(cls, 'operation')
+
+    # endregion
+
     # region foreign keys
 
     @declared_attr
@@ -503,15 +709,3 @@
         return relationship.foreign_key('operation', nullable=True)
 
     # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def task(cls):
-        return relationship.many_to_one(cls, 'task')
-
-    @declared_attr
-    def operation(cls):
-        return relationship.many_to_one(cls, 'operation')
-
-    # endregion
diff --git a/aria/modeling/relationship.py b/aria/modeling/relationship.py
index 76ac316..8b6028f 100644
--- a/aria/modeling/relationship.py
+++ b/aria/modeling/relationship.py
@@ -13,9 +13,15 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+ARIA modeling relationship module
+"""
+
 # pylint: disable=invalid-name, redefined-outer-name
+
 from sqlalchemy.orm import relationship, backref
 from sqlalchemy.orm.collections import attribute_mapped_collection
+from sqlalchemy.ext.associationproxy import association_proxy as original_association_proxy
 from sqlalchemy import (
     Column,
     ForeignKey,
@@ -43,9 +49,9 @@
 
     *This utility method should only be used during class creation.*
 
-    :param other_table: Other table name
+    :param other_table: other table name
     :type other_table: basestring
-    :param nullable: True to allow null values (meaning that there is no relationship)
+    :param nullable: ``True`` to allow null values (meaning that there is no relationship)
     :type nullable: bool
     """
 
@@ -63,9 +69,9 @@
 
     *This utility method should only be used during class creation.*
 
-    :param model_class: The class in which this relationship will be declared
+    :param model_class: class in which this relationship will be declared
     :type model_class: type
-    :param fk: Foreign key name
+    :param fk: foreign key name
     :type fk: basestring
     """
 
@@ -105,17 +111,17 @@
 
     *This utility method should only be used during class creation.*
 
-    :param model_class: The class in which this relationship will be declared
+    :param model_class: class in which this relationship will be declared
     :type model_class: type
-    :param other_table: Other table name
+    :param other_table: other table name
     :type other_table: basestring
-    :param fk: Foreign key name at our table (no need specify if there's no ambiguity)
+    :param fk: foreign key name at our table (no need specify if there's no ambiguity)
     :type fk: basestring
-    :param other_fk: Foreign key name at the other table (no need specify if there's no ambiguity)
+    :param other_fk: foreign key name at the other table (no need specify if there's no ambiguity)
     :type other_fk: basestring
-    :param back_populates: Override name of matching many-to-many property at other table; set to
-                       false to disable
-    :type back_populates: basestring|bool
+    :param back_populates: override name of matching many-to-many property at other table; set to
+     ``False`` to disable
+    :type back_populates: basestring or bool
     """
     backref_kwargs = None
     if back_populates is not NO_BACK_POP:
@@ -150,18 +156,23 @@
 
     *This utility method should only be used during class creation.*
 
-    :param model_class: The class in which this relationship will be declared
+    :param model_class: class in which this relationship will be declared
     :type model_class: type
-    :param child_table: Child table name
+    :param other_table: other table name
     :type other_table: basestring
-    :param other_fk: Foreign key name at the child table (no need specify if there's no ambiguity)
+    :param other_fk: foreign key name at the other table (no need specify if there's no ambiguity)
     :type other_fk: basestring
-    :param dict_key: If set the value will be a dict with this key as the dict key; otherwise will
-                     be a list
+    :param dict_key: if set the value will be a dict with this key as the dict key; otherwise will
+     be a list
     :type dict_key: basestring
-    :param back_populates: Override name of matching many-to-one property at child table; set to
-                           false to disable
-    :type back_populates: basestring|bool
+    :param back_populates: override name of matching many-to-one property at other table; set to
+     ``False`` to disable
+    :type back_populates: basestring or bool
+    :param rel_kwargs: additional relationship kwargs to be used by SQLAlchemy
+    :type rel_kwargs: dict
+    :param self: used for relationships between a table and itself. if set, other_table will
+     become the same as the source table.
+    :type self: bool
     """
     relationship_kwargs = rel_kwargs or {}
     if self:
@@ -201,19 +212,19 @@
     The declaration will automatically create a matching one-to-many property at the child model,
     named after the plural form of our table name. Use the ``parent_property`` argument to override
     this name. Note: the automatic property will always be a SQLAlchemy query object; if you need a
-    Python collection then use :meth:`one_to_many` at that model.
+    Python collection then use :func:`one_to_many` at that model.
 
     *This utility method should only be used during class creation.*
 
-    :param model_class: The class in which this relationship will be declared
+    :param model_class: class in which this relationship will be declared
     :type model_class: type
-    :param parent_table: Parent table name
+    :param parent_table: parent table name
     :type parent_table: basestring
-    :param fk: Foreign key name at our table (no need specify if there's no ambiguity)
+    :param fk: foreign key name at our table (no need specify if there's no ambiguity)
     :type fk: basestring
-    :param back_populates: Override name of matching one-to-many property at parent table; set to
-                            false to disable
-    :type back_populates: basestring|bool
+    :param back_populates: override name of matching one-to-many property at parent table; set to
+     ``False`` to disable
+    :type back_populates: basestring or bool
     """
     if back_populates is None:
         back_populates = formatting.pluralize(model_class.__tablename__)
@@ -241,22 +252,25 @@
     The declaration will automatically create a matching many-to-many property at the other model,
     named after the plural form of our table name. Use the ``other_property`` argument to override
     this name. Note: the automatic property will always be a SQLAlchemy query object; if you need a
-    Python collection then use :meth:`many_to_many` again at that model.
+    Python collection then use :func:`many_to_many` again at that model.
 
     *This utility method should only be used during class creation.*
 
-    :param model_class: The class in which this relationship will be declared
+    :param model_class: class in which this relationship will be declared
     :type model_class: type
-    :param other_table: Parent table name
+    :param other_table: parent table name
     :type other_table: basestring
-    :param prefix: Optional prefix for extra table name as well as for ``other_property``
+    :param prefix: optional prefix for extra table name as well as for ``other_property``
     :type prefix: basestring
-    :param dict_key: If set the value will be a dict with this key as the dict key; otherwise will
-                     be a list
+    :param dict_key: if set the value will be a dict with this key as the dict key; otherwise will
+     be a list
     :type dict_key: basestring
-    :param other_property: Override name of matching many-to-many property at other table; set to
-                           false to disable
-    :type other_property: basestring|bool
+    :param other_property: override name of matching many-to-many property at other table; set to
+     ``False`` to disable
+    :type other_property: basestring or bool
+    :param self: used for relationships between a table and itself. if set, other_table will
+     become the same as the source table.
+    :type self: bool
     """
 
     this_table = model_class.__tablename__
@@ -301,6 +315,21 @@
     return _relationship(model_class, other_table, **kwargs)
 
 
+def association_proxy(*args, **kwargs):
+    if 'type' in kwargs:
+        type_ = kwargs.get('type')
+        del kwargs['type']
+    else:
+        type_ = ':obj:`basestring`'
+    proxy = original_association_proxy(*args, **kwargs)
+    proxy.__doc__ = """
+    Internal. For use in SQLAlchemy queries.
+
+    :type: {0}
+    """.format(type_)
+    return proxy
+
+
 def _relationship(model_class,
                   other_table_name,
                   back_populates=None,
diff --git a/aria/modeling/service_changes.py b/aria/modeling/service_changes.py
index f632fef..061262a 100644
--- a/aria/modeling/service_changes.py
+++ b/aria/modeling/service_changes.py
@@ -14,10 +14,7 @@
 # limitations under the License.
 
 """
-classes:
-    * ServiceUpdate - service update implementation model.
-    * ServiceUpdateStep - service update step implementation model.
-    * ServiceModification - service modification implementation model.
+ARIA modeling service changes module
 """
 
 # pylint: disable=no-self-argument, no-member, abstract-method
@@ -30,7 +27,6 @@
     DateTime,
     Enum,
 )
-from sqlalchemy.ext.associationproxy import association_proxy
 from sqlalchemy.ext.declarative import declared_attr
 
 from .types import (List, Dict)
@@ -44,8 +40,8 @@
     """
     __tablename__ = 'service_update'
 
-    __private_fields__ = ['service_fk',
-                          'execution_fk']
+    __private_fields__ = ('service_fk',
+                          'execution_fk')
 
     created_at = Column(DateTime, nullable=False, index=True)
     service_plan = Column(Dict, nullable=False)
@@ -55,29 +51,15 @@
     modified_entity_ids = Column(Dict)
     state = Column(Text)
 
-    # region foreign keys
-
-    @declared_attr
-    def execution_fk(cls):
-        return relationship.foreign_key('execution', nullable=True)
-
-    @declared_attr
-    def service_fk(cls):
-        return relationship.foreign_key('service')
-
-    # endregion
-
     # region association proxies
 
     @declared_attr
     def execution_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('execution', cls.name_column_name())
+        return relationship.association_proxy('execution', cls.name_column_name())
 
     @declared_attr
     def service_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('service', cls.name_column_name())
+        return relationship.association_proxy('service', cls.name_column_name())
 
     # endregion
 
@@ -105,6 +87,18 @@
 
     # endregion
 
+    # region foreign keys
+
+    @declared_attr
+    def execution_fk(cls):
+        return relationship.foreign_key('execution', nullable=True)
+
+    @declared_attr
+    def service_fk(cls):
+        return relationship.foreign_key('service')
+
+    # endregion
+
     def to_dict(self, suppress_error=False, **kwargs):
         dep_update_dict = super(ServiceUpdateBase, self).to_dict(suppress_error)     #pylint: disable=no-member
         # Taking care of the fact the DeploymentSteps are _BaseModels
@@ -119,7 +113,7 @@
 
     __tablename__ = 'service_update_step'
 
-    __private_fields__ = ['service_update_fk']
+    __private_fields__ = ('service_update_fk',)
 
     _action_types = namedtuple('ACTION_TYPES', 'ADD, REMOVE, MODIFY')
     ACTION_TYPES = _action_types(ADD='add', REMOVE='remove', MODIFY='modify')
@@ -143,20 +137,11 @@
     entity_id = Column(Text, nullable=False)
     entity_type = Column(Enum(*ENTITY_TYPES, name='entity_type'), nullable=False)
 
-    # region foreign keys
-
-    @declared_attr
-    def service_update_fk(cls):
-        return relationship.foreign_key('service_update')
-
-    # endregion
-
     # region association proxies
 
     @declared_attr
     def service_update_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('service_update', cls.name_column_name())
+        return relationship.association_proxy('service_update', cls.name_column_name())
 
     # endregion
 
@@ -176,6 +161,14 @@
 
     # endregion
 
+    # region foreign keys
+
+    @declared_attr
+    def service_update_fk(cls):
+        return relationship.foreign_key('service_update')
+
+    # endregion
+
     def __hash__(self):
         return hash((getattr(self, self.id_column_name()), self.entity_id))
 
@@ -211,7 +204,7 @@
 
     __tablename__ = 'service_modification'
 
-    __private_fields__ = ['service_fk']
+    __private_fields__ = ('service_fk',)
 
     STARTED = 'started'
     FINISHED = 'finished'
@@ -227,20 +220,11 @@
     nodes = Column(Dict)
     status = Column(Enum(*STATES, name='service_modification_status'))
 
-    # region foreign keys
-
-    @declared_attr
-    def service_fk(cls):
-        return relationship.foreign_key('service')
-
-    # endregion
-
     # region association proxies
 
     @declared_attr
     def service_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('service', cls.name_column_name())
+        return relationship.association_proxy('service', cls.name_column_name())
 
     # endregion
 
@@ -253,8 +237,17 @@
     # endregion
 
     # region many_to_one relationships
+
     @declared_attr
     def service(cls):
         return relationship.many_to_one(cls, 'service', back_populates='modifications')
 
     # endregion
+
+    # region foreign keys
+
+    @declared_attr
+    def service_fk(cls):
+        return relationship.foreign_key('service')
+
+    # endregion
diff --git a/aria/modeling/service_common.py b/aria/modeling/service_common.py
index 0bb861f..b533a88 100644
--- a/aria/modeling/service_common.py
+++ b/aria/modeling/service_common.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+ARIA modeling service common module
+"""
+
 # pylint: disable=no-self-argument, no-member, abstract-method
 
 from sqlalchemy import (
@@ -32,9 +36,34 @@
 
 
 class OutputBase(ParameterMixin):
+    """
+    Output parameter or declaration for an output parameter.
+    """
 
     __tablename__ = 'output'
 
+    # region many_to_one relationships
+
+    @declared_attr
+    def service_template(cls):
+        """
+        Containing service template (can be ``None``).
+
+        :type: :class:`ServiceTemplate`
+        """
+        return relationship.many_to_one(cls, 'service_template')
+
+    @declared_attr
+    def service(cls):
+        """
+        Containing service (can be ``None``).
+
+        :type: :class:`ServiceTemplate`
+        """
+        return relationship.many_to_one(cls, 'service')
+
+    # endregion
+
     # region foreign keys
 
     @declared_attr
@@ -47,23 +76,81 @@
 
     # endregion
 
+
+class InputBase(ParameterMixin):
+    """
+    Input parameter or declaration for an input parameter.
+    """
+
+    __tablename__ = 'input'
+
     # region many_to_one relationships
 
     @declared_attr
     def service_template(cls):
+        """
+        Containing service template (can be ``None``).
+
+        :type: :class:`ServiceTemplate`
+        """
         return relationship.many_to_one(cls, 'service_template')
 
     @declared_attr
     def service(cls):
+        """
+        Containing service (can be ``None``).
+
+        :type: :class:`Service`
+        """
         return relationship.many_to_one(cls, 'service')
 
+    @declared_attr
+    def interface(cls):
+        """
+        Containing interface (can be ``None``).
+
+        :type: :class:`Interface`
+        """
+        return relationship.many_to_one(cls, 'interface')
+
+    @declared_attr
+    def operation(cls):
+        """
+        Containing operation (can be ``None``).
+
+        :type: :class:`Operation`
+        """
+        return relationship.many_to_one(cls, 'operation')
+
+    @declared_attr
+    def interface_template(cls):
+        """
+        Containing interface template (can be ``None``).
+
+        :type: :class:`InterfaceTemplate`
+        """
+        return relationship.many_to_one(cls, 'interface_template')
+
+    @declared_attr
+    def operation_template(cls):
+        """
+        Containing operation template (can be ``None``).
+
+        :type: :class:`OperationTemplate`
+        """
+        return relationship.many_to_one(cls, 'operation_template')
+
+    @declared_attr
+    def execution(cls):
+        """
+        Containing execution (can be ``None``).
+
+        :type: :class:`Execution`
+        """
+        return relationship.many_to_one(cls, 'execution')
+
     # endregion
 
-
-class InputBase(ParameterMixin):
-
-    __tablename__ = 'input'
-
     # region foreign keys
 
     @declared_attr
@@ -100,43 +187,36 @@
 
     # endregion
 
+
+class ConfigurationBase(ParameterMixin):
+    """
+    Configuration parameter.
+    """
+
+    __tablename__ = 'configuration'
+
     # region many_to_one relationships
 
     @declared_attr
-    def service_template(cls):
-        return relationship.many_to_one(cls, 'service_template')
-
-    @declared_attr
-    def service(cls):
-        return relationship.many_to_one(cls, 'service')
-
-    @declared_attr
-    def interface(cls):
-        return relationship.many_to_one(cls, 'interface')
-
-    @declared_attr
-    def operation(cls):
-        return relationship.many_to_one(cls, 'operation')
-
-    @declared_attr
-    def interface_template(cls):
-        return relationship.many_to_one(cls, 'interface_template')
-
-    @declared_attr
     def operation_template(cls):
+        """
+        Containing operation template (can be ``None``).
+
+        :type: :class:`OperationTemplate`
+        """
         return relationship.many_to_one(cls, 'operation_template')
 
     @declared_attr
-    def execution(cls):
-        return relationship.many_to_one(cls, 'execution')
+    def operation(cls):
+        """
+        Containing operation (can be ``None``).
+
+        :type: :class:`Operation`
+        """
+        return relationship.many_to_one(cls, 'operation')
 
     # endregion
 
-
-class ConfigurationBase(ParameterMixin):
-
-    __tablename__ = 'configuration'
-
     # region foreign keys
 
     @declared_attr
@@ -149,23 +229,126 @@
 
     # endregion
 
+
+class PropertyBase(ParameterMixin):
+    """
+    Property parameter or declaration for a property parameter.
+    """
+
+    __tablename__ = 'property'
+
     # region many_to_one relationships
 
     @declared_attr
-    def operation_template(cls):
-        return relationship.many_to_one(cls, 'operation_template')
+    def node_template(cls):
+        """
+        Containing node template (can be ``None``).
+
+        :type: :class:`NodeTemplate`
+        """
+        return relationship.many_to_one(cls, 'node_template')
 
     @declared_attr
-    def operation(cls):
-        return relationship.many_to_one(cls, 'operation')
+    def group_template(cls):
+        """
+        Containing group template (can be ``None``).
+
+        :type: :class:`GroupTemplate`
+        """
+        return relationship.many_to_one(cls, 'group_template')
+
+    @declared_attr
+    def policy_template(cls):
+        """
+        Containing policy template (can be ``None``).
+
+        :type: :class:`PolicyTemplate`
+        """
+        return relationship.many_to_one(cls, 'policy_template')
+
+    @declared_attr
+    def relationship_template(cls):
+        """
+        Containing relationship template (can be ``None``).
+
+        :type: :class:`RelationshipTemplate`
+        """
+        return relationship.many_to_one(cls, 'relationship_template')
+
+    @declared_attr
+    def capability_template(cls):
+        """
+        Containing capability template (can be ``None``).
+
+        :type: :class:`CapabilityTemplate`
+        """
+        return relationship.many_to_one(cls, 'capability_template')
+
+    @declared_attr
+    def artifact_template(cls):
+        """
+        Containing artifact template (can be ``None``).
+
+        :type: :class:`ArtifactTemplate`
+        """
+        return relationship.many_to_one(cls, 'artifact_template')
+
+    @declared_attr
+    def node(cls):
+        """
+        Containing node (can be ``None``).
+
+        :type: :class:`Node`
+        """
+        return relationship.many_to_one(cls, 'node')
+
+    @declared_attr
+    def group(cls):
+        """
+        Containing group (can be ``None``).
+
+        :type: :class:`Group`
+        """
+        return relationship.many_to_one(cls, 'group')
+
+    @declared_attr
+    def policy(cls):
+        """
+        Containing policy (can be ``None``).
+
+        :type: :class:`Policy`
+        """
+        return relationship.many_to_one(cls, 'policy')
+
+    @declared_attr
+    def relationship(cls):
+        """
+        Containing relationship (can be ``None``).
+
+        :type: :class:`Relationship`
+        """
+        return relationship.many_to_one(cls, 'relationship')
+
+    @declared_attr
+    def capability(cls):
+        """
+        Containing capability (can be ``None``).
+
+        :type: :class:`Capability`
+        """
+        return relationship.many_to_one(cls, 'capability')
+
+    @declared_attr
+    def artifact(cls):
+        """
+        Containing artifact (can be ``None``).
+
+        :type: :class:`Artifact`
+        """
+        return relationship.many_to_one(cls, 'artifact')
 
     # endregion
 
-
-class PropertyBase(ParameterMixin):
-
-    __tablename__ = 'property'
-
     # region foreign keys
 
     @declared_attr
@@ -215,65 +398,39 @@
     @declared_attr
     def artifact_fk(cls):
         return relationship.foreign_key('artifact', nullable=True)
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def node_template(cls):
-        return relationship.many_to_one(cls, 'node_template')
-
-    @declared_attr
-    def group_template(cls):
-        return relationship.many_to_one(cls, 'group_template')
-
-    @declared_attr
-    def policy_template(cls):
-        return relationship.many_to_one(cls, 'policy_template')
-
-    @declared_attr
-    def relationship_template(cls):
-        return relationship.many_to_one(cls, 'relationship_template')
-
-    @declared_attr
-    def capability_template(cls):
-        return relationship.many_to_one(cls, 'capability_template')
-
-    @declared_attr
-    def artifact_template(cls):
-        return relationship.many_to_one(cls, 'artifact_template')
-
-    @declared_attr
-    def node(cls):
-        return relationship.many_to_one(cls, 'node')
-
-    @declared_attr
-    def group(cls):
-        return relationship.many_to_one(cls, 'group')
-
-    @declared_attr
-    def policy(cls):
-        return relationship.many_to_one(cls, 'policy')
-
-    @declared_attr
-    def relationship(cls):
-        return relationship.many_to_one(cls, 'relationship')
-
-    @declared_attr
-    def capability(cls):
-        return relationship.many_to_one(cls, 'capability')
-
-    @declared_attr
-    def artifact(cls):
-        return relationship.many_to_one(cls, 'artifact')
 
     # endregion
 
 
 class AttributeBase(ParameterMixin):
+    """
+    Attribute parameter or declaration for an attribute parameter.
+    """
 
     __tablename__ = 'attribute'
 
+    # region many_to_one relationships
+
+    @declared_attr
+    def node_template(cls):
+        """
+        Containing node template (can be ``None``).
+
+        :type: :class:`NodeTemplate`
+        """
+        return relationship.many_to_one(cls, 'node_template')
+
+    @declared_attr
+    def node(cls):
+        """
+        Containing node (can be ``None``).
+
+        :type: :class:`Node`
+        """
+        return relationship.many_to_one(cls, 'node')
+
+    # endregion
+
     # region foreign keys
 
     @declared_attr
@@ -288,40 +445,52 @@
 
     # endregion
 
-    # region many_to_one relationships
-
-    @declared_attr
-    def node_template(cls):
-        return relationship.many_to_one(cls, 'node_template')
-
-    @declared_attr
-    def node(cls):
-        return relationship.many_to_one(cls, 'node')
-
-    # endregion
-
 
 class TypeBase(InstanceModelMixin):
     """
-    Represents a type and its children.
+    Type and its children. Can serve as the root for a type hierarchy.
     """
 
     __tablename__ = 'type'
 
-    __private_fields__ = ['parent_type_fk']
+    __private_fields__ = ('parent_type_fk',)
 
     variant = Column(Text, nullable=False)
-    description = Column(Text)
+
+    description = Column(Text, doc="""
+    Human-readable description.
+
+    :type: :obj:`basestring`
+    """)
+
     _role = Column(Text, name='role')
 
+    # region one_to_one relationships
+
     @declared_attr
     def parent(cls):
+        """
+        Parent type (will be ``None`` for the root of a type hierarchy).
+
+        :type: :class:`Type`
+        """
         return relationship.one_to_one_self(cls, 'parent_type_fk')
 
+    # endregion
+
+    # region one_to_many relationships
+
     @declared_attr
     def children(cls):
+        """
+        Children.
+
+        :type: [:class:`Type`]
+        """
         return relationship.one_to_many(cls, other_fk='parent_type_fk', self=True)
 
+    # endregion
+
     # region foreign keys
 
     @declared_attr
@@ -402,8 +571,9 @@
     @property
     def hierarchy(self):
         """
-        Return the type hierarchy.
-        :return:
+        Type hierarchy as a list beginning with this type and ending in the root.
+
+        :type: [:class:`Type`]
         """
         return [self] + (self.parent.hierarchy if self.parent else [])
 
@@ -414,9 +584,9 @@
 
     This model is used by both service template and service instance elements.
 
-    :ivar name: Name
+    :ivar name: name
     :vartype name: basestring
-    :ivar value: Value
+    :ivar value: value
     :vartype value: basestring
     """
 
diff --git a/aria/modeling/service_instance.py b/aria/modeling/service_instance.py
index b451889..002a87c 100644
--- a/aria/modeling/service_instance.py
+++ b/aria/modeling/service_instance.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+ARIA modeling service instance module
+"""
+
 # pylint: disable=too-many-lines, no-self-argument, no-member, abstract-method
 
 from sqlalchemy import (
@@ -23,7 +27,6 @@
     Boolean
 )
 from sqlalchemy import DateTime
-from sqlalchemy.ext.associationproxy import association_proxy
 from sqlalchemy.ext.declarative import declared_attr
 from sqlalchemy.ext.orderinglist import ordering_list
 
@@ -45,51 +48,157 @@
 
 class ServiceBase(InstanceModelMixin):
     """
-    A service is usually an instance of a :class:`ServiceTemplate`.
-
-    You will usually not create it programmatically, but instead instantiate it from a service
-    template.
-
-    :ivar name: Name (unique for this ARIA installation)
-    :vartype name: basestring
-    :ivar service_template: Template from which this service was instantiated (optional)
-    :vartype service_template: :class:`ServiceTemplate`
-    :ivar description: Human-readable description
-    :vartype description: string
-    :ivar meta_data: Custom annotations
-    :vartype meta_data: {basestring: :class:`Metadata`}
-    :ivar node: Nodes
-    :vartype node: {basestring: :class:`Node`}
-    :ivar groups: Groups of nodes
-    :vartype groups: {basestring: :class:`Group`}
-    :ivar policies: Policies
-    :vartype policies: {basestring: :class:`Policy`]}
-    :ivar substitution: The entire service can appear as a node
-    :vartype substitution: :class:`Substitution`
-    :ivar inputs: Externally provided parameters
-    :vartype inputs: {basestring: :class:`Input`}
-    :ivar outputs: These parameters are filled in after service installation
-    :vartype outputs: {basestring: :class:`Output`}
-    :ivar workflows: Custom workflows that can be performed on the service
-    :vartype workflows: {basestring: :class:`Operation`}
-    :ivar plugins: Plugins used by the service
-    :vartype plugins: {basestring: :class:`Plugin`}
-    :ivar created_at: Creation timestamp
-    :vartype created_at: :class:`datetime.datetime`
-    :ivar updated_at: Update timestamp
-    :vartype updated_at: :class:`datetime.datetime`
-    :ivar modifications: Modifications of this service
-    :vartype modifications: [:class:`ServiceModification`]
-    :ivar updates: Updates of this service
-    :vartype updates: [:class:`ServiceUpdate`]
-    :ivar executions: Executions on this service
-    :vartype executions: [:class:`Execution`]
+    Usually an instance of a :class:`ServiceTemplate` and its many associated templates (node
+    templates, group templates, policy templates, etc.). However, it can also be created
+    programmatically.
     """
 
     __tablename__ = 'service'
 
-    __private_fields__ = ['substitution_fk',
-                          'service_template_fk']
+    __private_fields__ = ('substitution_fk',
+                          'service_template_fk')
+
+    # region association proxies
+
+    @declared_attr
+    def service_template_name(cls):
+        return relationship.association_proxy('service_template', 'name', type=':obj:`basestring`')
+
+    # endregion
+
+    # region one_to_one relationships
+
+    @declared_attr
+    def substitution(cls):
+        """
+        Exposes the entire service as a single node.
+
+        :type: :class:`Substitution`
+        """
+        return relationship.one_to_one(cls, 'substitution', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def outputs(cls):
+        """
+        Output parameters.
+
+        :type: {:obj:`basestring`: :class:`Output`}
+        """
+        return relationship.one_to_many(cls, 'output', dict_key='name')
+
+    @declared_attr
+    def inputs(cls):
+        """
+        Externally provided parameters.
+
+        :type: {:obj:`basestring`: :class:`Input`}
+        """
+        return relationship.one_to_many(cls, 'input', dict_key='name')
+
+    @declared_attr
+    def updates(cls):
+        """
+        Service updates.
+
+        :type: [:class:`ServiceUpdate`]
+        """
+        return relationship.one_to_many(cls, 'service_update')
+
+    @declared_attr
+    def modifications(cls):
+        """
+        Service modifications.
+
+        :type: [:class:`ServiceModification`]
+        """
+        return relationship.one_to_many(cls, 'service_modification')
+
+    @declared_attr
+    def executions(cls):
+        """
+        Executions.
+
+        :type: [:class:`Execution`]
+        """
+        return relationship.one_to_many(cls, 'execution')
+
+    @declared_attr
+    def nodes(cls):
+        """
+        Nodes.
+
+        :type: {:obj:`basestring`, :class:`Node`}
+        """
+        return relationship.one_to_many(cls, 'node', dict_key='name')
+
+    @declared_attr
+    def groups(cls):
+        """
+        Groups.
+
+        :type: {:obj:`basestring`, :class:`Group`}
+        """
+        return relationship.one_to_many(cls, 'group', dict_key='name')
+
+    @declared_attr
+    def policies(cls):
+        """
+        Policies.
+
+        :type: {:obj:`basestring`, :class:`Policy`}
+        """
+        return relationship.one_to_many(cls, 'policy', dict_key='name')
+
+    @declared_attr
+    def workflows(cls):
+        """
+        Workflows.
+
+        :type: {:obj:`basestring`, :class:`Operation`}
+        """
+        return relationship.one_to_many(cls, 'operation', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def service_template(cls):
+        """
+        Source service template (can be ``None``).
+
+        :type: :class:`ServiceTemplate`
+        """
+        return relationship.many_to_one(cls, 'service_template')
+
+    # endregion
+
+    # region many_to_many relationships
+
+    @declared_attr
+    def meta_data(cls):
+        """
+        Associated metadata.
+
+        :type: {:obj:`basestring`, :class:`Metadata`}
+        """
+        # Warning! We cannot use the attr name "metadata" because it's used by SQLAlchemy!
+        return relationship.many_to_many(cls, 'metadata', dict_key='name')
+
+    @declared_attr
+    def plugins(cls):
+        """
+        Associated plugins.
+
+        :type: {:obj:`basestring`, :class:`Plugin`}
+        """
+        return relationship.many_to_many(cls, 'plugin', dict_key='name')
+
+    # endregion
 
     # region foreign keys
 
@@ -105,87 +214,23 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    @declared_attr
-    def service_template_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('service_template', 'name')
+    :type: :obj:`basestring`
+    """)
 
-    # endregion
+    created_at = Column(DateTime, nullable=False, index=True, doc="""
+    Creation timestamp.
 
-    # region one_to_one relationships
+    :type: :class:`~datetime.datetime`
+    """)
 
-    @declared_attr
-    def substitution(cls):
-        return relationship.one_to_one(cls, 'substitution', back_populates=relationship.NO_BACK_POP)
+    updated_at = Column(DateTime, doc="""
+    Update timestamp.
 
-    # endregion
-
-    # region one_to_many relationships
-
-    @declared_attr
-    def outputs(cls):
-        return relationship.one_to_many(cls, 'output', dict_key='name')
-
-    @declared_attr
-    def inputs(cls):
-        return relationship.one_to_many(cls, 'input', dict_key='name')
-
-    @declared_attr
-    def updates(cls):
-        return relationship.one_to_many(cls, 'service_update')
-
-    @declared_attr
-    def modifications(cls):
-        return relationship.one_to_many(cls, 'service_modification')
-
-    @declared_attr
-    def executions(cls):
-        return relationship.one_to_many(cls, 'execution')
-
-    @declared_attr
-    def nodes(cls):
-        return relationship.one_to_many(cls, 'node', dict_key='name')
-
-    @declared_attr
-    def groups(cls):
-        return relationship.one_to_many(cls, 'group', dict_key='name')
-
-    @declared_attr
-    def policies(cls):
-        return relationship.one_to_many(cls, 'policy', dict_key='name')
-
-    @declared_attr
-    def workflows(cls):
-        return relationship.one_to_many(cls, 'operation', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def service_template(cls):
-        return relationship.many_to_one(cls, 'service_template')
-
-    # endregion
-
-    # region many_to_many relationships
-
-    @declared_attr
-    def meta_data(cls):
-        # Warning! We cannot use the attr name "metadata" because it's used by SQLAlchemy!
-        return relationship.many_to_many(cls, 'metadata', dict_key='name')
-
-    @declared_attr
-    def plugins(cls):
-        return relationship.many_to_many(cls, 'plugin', dict_key='name')
-
-    # endregion
-
-    description = Column(Text)
-    created_at = Column(DateTime, nullable=False, index=True)
-    updated_at = Column(DateTime)
+    :type: :class:`~datetime.datetime`
+    """)
 
     def satisfy_requirements(self):
         satisfied = True
@@ -311,56 +356,20 @@
 
 class NodeBase(InstanceModelMixin):
     """
+    Typed vertex in the service topology.
+
+    Nodes may have zero or more :class:`Relationship` instances to other nodes, together forming
+    a many-to-many node graph.
+
     Usually an instance of a :class:`NodeTemplate`.
-
-    Nodes may have zero or more :class:`Relationship` instances to other nodes.
-
-    :ivar name: Name (unique for this service)
-    :vartype name: basestring
-    :ivar node_template: Template from which this node was instantiated (optional)
-    :vartype node_template: :class:`NodeTemplate`
-    :ivar type: Node type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: string
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar interfaces: Bundles of operations
-    :vartype interfaces: {basestring: :class:`Interface`}
-    :ivar artifacts: Associated files
-    :vartype artifacts: {basestring: :class:`Artifact`}
-    :ivar capabilities: Exposed capabilities
-    :vartype capabilities: {basestring: :class:`Capability`}
-    :ivar outbound_relationships: Relationships to other nodes
-    :vartype outbound_relationships: [:class:`Relationship`]
-    :ivar inbound_relationships: Relationships from other nodes
-    :vartype inbound_relationships: [:class:`Relationship`]
-    :ivar host: Host node (can be self)
-    :vartype host: :class:`Node`
-    :ivar state: The state of the node, according to to the TOSCA-defined node states
-    :vartype state: string
-    :ivar version: Used by `aria.storage.instrumentation`
-    :vartype version: int
-    :ivar service: Containing service
-    :vartype service: :class:`Service`
-    :ivar groups: We are a member of these groups
-    :vartype groups: [:class:`Group`]
-    :ivar policies: Policies enacted on this node
-    :vartype policies: [:class:`Policy`]
-    :ivar substitution_mapping: Our contribution to service substitution
-    :vartype substitution_mapping: :class:`SubstitutionMapping`
-    :ivar tasks: Tasks for this node
-    :vartype tasks: [:class:`Task`]
-    :ivar hosted_tasks: Tasks on this node
-    :vartype hosted_tasks: [:class:`Task`]
     """
 
     __tablename__ = 'node'
 
-    __private_fields__ = ['type_fk',
+    __private_fields__ = ('type_fk',
                           'host_fk',
                           'service_fk',
-                          'node_template_fk']
+                          'node_template_fk')
 
     INITIAL = 'initial'
     CREATING = 'creating'
@@ -371,42 +380,170 @@
     STARTED = 'started'
     STOPPING = 'stopping'
     DELETING = 'deleting'
-    # 'deleted' isn't actually part of the tosca spec, since according the description of the
-    # 'deleting' state: "Node is transitioning from its current state to one where it is deleted and
-    #  its state is no longer tracked by the instance model."
-    # However, we prefer to be able to retrieve information about deleted nodes, so we chose to add
-    # this 'deleted' state to enable us to do so.
     DELETED = 'deleted'
     ERROR = 'error'
 
-    STATES = [INITIAL, CREATING, CREATED, CONFIGURING, CONFIGURED, STARTING, STARTED, STOPPING,
-              DELETING, DELETED, ERROR]
+    # 'deleted' isn't actually part of the TOSCA spec, since according the description of the
+    # 'deleting' state: "Node is transitioning from its current state to one where it is deleted and
+    # its state is no longer tracked by the instance model." However, we prefer to be able to
+    # retrieve information about deleted nodes, so we chose to add this 'deleted' state to enable us
+    # to do so.
 
-    _op_to_state = {'create': {'transitional': CREATING, 'finished': CREATED},
+    STATES = (INITIAL, CREATING, CREATED, CONFIGURING, CONFIGURED, STARTING, STARTED, STOPPING,
+              DELETING, DELETED, ERROR)
+
+    _OP_TO_STATE = {'create': {'transitional': CREATING, 'finished': CREATED},
                     'configure': {'transitional': CONFIGURING, 'finished': CONFIGURED},
                     'start': {'transitional': STARTING, 'finished': STARTED},
                     'stop': {'transitional': STOPPING, 'finished': CONFIGURED},
                     'delete': {'transitional': DELETING, 'finished': DELETED}}
 
-    @classmethod
-    def determine_state(cls, op_name, is_transitional):
-        """ :returns the state the node should be in as a result of running the
-            operation on this node.
+    # region association proxies
 
-            e.g. if we are running tosca.interfaces.node.lifecycle.Standard.create, then
-            the resulting state should either 'creating' (if the task just started) or 'created'
-            (if the task ended).
+    @declared_attr
+    def service_name(cls):
+        return relationship.association_proxy('service', 'name', type=':obj:`basestring`')
 
-            If the operation is not a standard tosca lifecycle operation, then we return None"""
+    @declared_attr
+    def node_template_name(cls):
+        return relationship.association_proxy('node_template', 'name', type=':obj:`basestring`')
 
-        state_type = 'transitional' if is_transitional else 'finished'
-        try:
-            return cls._op_to_state[op_name][state_type]
-        except KeyError:
-            return None
+    # endregion
 
-    def is_available(self):
-        return self.state not in (self.INITIAL, self.DELETED, self.ERROR)
+    # region one_to_one relationships
+
+    @declared_attr
+    def host(cls): # pylint: disable=method-hidden
+        """
+        Node in which we are hosted (can be ``None``).
+
+        Normally the host node is found by following the relationship graph (relationships with
+        ``host`` roles) to final nodes (with ``host`` roles).
+
+        :type: :class:`Node`
+        """
+        return relationship.one_to_one_self(cls, 'host_fk')
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def tasks(cls):
+        """
+        Associated tasks.
+
+        :type: [:class:`Task`]
+        """
+        return relationship.one_to_many(cls, 'task')
+
+    @declared_attr
+    def interfaces(cls):
+        """
+        Associated interfaces.
+
+        :type: {:obj:`basestring`: :class:`Interface`}
+        """
+        return relationship.one_to_many(cls, 'interface', dict_key='name')
+
+    @declared_attr
+    def properties(cls):
+        """
+        Associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
+        return relationship.one_to_many(cls, 'property', dict_key='name')
+
+    @declared_attr
+    def attributes(cls):
+        """
+        Associated mutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Attribute`}
+        """
+        return relationship.one_to_many(cls, 'attribute', dict_key='name')
+
+    @declared_attr
+    def artifacts(cls):
+        """
+        Associated artifacts.
+
+        :type: {:obj:`basestring`: :class:`Artifact`}
+        """
+        return relationship.one_to_many(cls, 'artifact', dict_key='name')
+
+    @declared_attr
+    def capabilities(cls):
+        """
+        Associated exposed capabilities.
+
+        :type: {:obj:`basestring`: :class:`Capability`}
+        """
+        return relationship.one_to_many(cls, 'capability', dict_key='name')
+
+    @declared_attr
+    def outbound_relationships(cls):
+        """
+        Relationships to other nodes.
+
+        :type: [:class:`Relationship`]
+        """
+        return relationship.one_to_many(
+            cls, 'relationship', other_fk='source_node_fk', back_populates='source_node',
+            rel_kwargs=dict(
+                order_by='Relationship.source_position',
+                collection_class=ordering_list('source_position', count_from=0)
+            )
+        )
+
+    @declared_attr
+    def inbound_relationships(cls):
+        """
+        Relationships from other nodes.
+
+        :type: [:class:`Relationship`]
+        """
+        return relationship.one_to_many(
+            cls, 'relationship', other_fk='target_node_fk', back_populates='target_node',
+            rel_kwargs=dict(
+                order_by='Relationship.target_position',
+                collection_class=ordering_list('target_position', count_from=0)
+            )
+        )
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def service(cls):
+        """
+        Containing service.
+
+        :type: :class:`Service`
+        """
+        return relationship.many_to_one(cls, 'service')
+
+    @declared_attr
+    def node_template(cls):
+        """
+        Source node template (can be ``None``).
+
+        :type: :class:`NodeTemplate`
+        """
+        return relationship.many_to_one(cls, 'node_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Node type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
 
     # region foreign_keys
 
@@ -432,98 +569,46 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    @declared_attr
-    def service_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('service', 'name')
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def node_template_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('node_template', 'name')
+    state = Column(Enum(*STATES, name='node_state'), nullable=False, default=INITIAL, doc="""
+    TOSCA state.
 
-    # endregion
+    :type: :obj:`basestring`
+    """)
 
-    # region one_to_one relationships
+    version = Column(Integer, default=1, doc="""
+    Used by :mod:`aria.storage.instrumentation`.
 
-    @declared_attr
-    def host(cls): # pylint: disable=method-hidden
-        return relationship.one_to_one_self(cls, 'host_fk')
-
-    # endregion
-
-    # region one_to_many relationships
-
-    @declared_attr
-    def tasks(cls):
-        return relationship.one_to_many(cls, 'task')
-
-    @declared_attr
-    def interfaces(cls):
-        return relationship.one_to_many(cls, 'interface', dict_key='name')
-
-    @declared_attr
-    def properties(cls):
-        return relationship.one_to_many(cls, 'property', dict_key='name')
-
-    @declared_attr
-    def attributes(cls):
-        return relationship.one_to_many(cls, 'attribute', dict_key='name')
-
-    @declared_attr
-    def artifacts(cls):
-        return relationship.one_to_many(cls, 'artifact', dict_key='name')
-
-    @declared_attr
-    def capabilities(cls):
-        return relationship.one_to_many(cls, 'capability', dict_key='name')
-
-    @declared_attr
-    def outbound_relationships(cls):
-        return relationship.one_to_many(
-            cls, 'relationship', other_fk='source_node_fk', back_populates='source_node',
-            rel_kwargs=dict(
-                order_by='Relationship.source_position',
-                collection_class=ordering_list('source_position', count_from=0)
-            )
-        )
-
-    @declared_attr
-    def inbound_relationships(cls):
-        return relationship.one_to_many(
-            cls, 'relationship', other_fk='target_node_fk', back_populates='target_node',
-            rel_kwargs=dict(
-                order_by='Relationship.target_position',
-                collection_class=ordering_list('target_position', count_from=0)
-            )
-        )
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def service(cls):
-        return relationship.many_to_one(cls, 'service')
-
-    @declared_attr
-    def node_template(cls):
-        return relationship.many_to_one(cls, 'node_template')
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    description = Column(Text)
-    state = Column(Enum(*STATES, name='node_state'), nullable=False, default=INITIAL)
-    version = Column(Integer, default=1)
+    :type: :obj:`int`
+    """)
 
     __mapper_args__ = {'version_id_col': version} # Enable SQLAlchemy automatic version counting
 
+    @classmethod
+    def determine_state(cls, op_name, is_transitional):
+        """ :returns the state the node should be in as a result of running the
+            operation on this node.
+
+            e.g. if we are running tosca.interfaces.node.lifecycle.Standard.create, then
+            the resulting state should either 'creating' (if the task just started) or 'created'
+            (if the task ended).
+
+            If the operation is not a standard tosca lifecycle operation, then we return None"""
+
+        state_type = 'transitional' if is_transitional else 'finished'
+        try:
+            return cls._OP_TO_STATE[op_name][state_type]
+        except KeyError:
+            return None
+
+    def is_available(self):
+        return self.state not in (self.INITIAL, self.DELETED, self.ERROR)
+
     @property
     def host_address(self):
         if self.host and self.host.attributes:
@@ -698,31 +783,90 @@
 
 class GroupBase(InstanceModelMixin):
     """
-    Usually an instance of a :class:`GroupTemplate`.
+    Typed logical container for zero or more :class:`Node` instances.
 
-    :ivar name: Name (unique for this service)
-    :vartype name: basestring
-    :ivar group_template: Template from which this group was instantiated (optional)
-    :vartype group_template: :class:`GroupTemplate`
-    :ivar type: Group type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: string
-    :ivar nodes: Members of this group
-    :vartype nodes: [:class:`Node`]
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar interfaces: Bundles of operations
-    :vartype interfaces: {basestring: :class:`Interface`}
-    :ivar service: Containing service
-    :vartype service: :class:`Service`
-    :ivar policies: Policies enacted on this group
-    :vartype policies: [:class:`Policy`]
+    Usually an instance of a :class:`GroupTemplate`.
     """
 
     __tablename__ = 'group'
 
-    __private_fields__ = ['type_fk', 'service_fk', 'group_template_fk']
+    __private_fields__ = ('type_fk',
+                          'service_fk',
+                          'group_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def properties(cls):
+        """
+        Associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
+        return relationship.one_to_many(cls, 'property', dict_key='name')
+
+    @declared_attr
+    def interfaces(cls):
+        """
+        Associated interfaces.
+
+        :type: {:obj:`basestring`: :class:`Interface`}
+        """
+        return relationship.one_to_many(cls, 'interface', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def service(cls):
+        """
+        Containing service.
+
+        :type: :class:`Service`
+        """
+        return relationship.many_to_one(cls, 'service')
+
+    @declared_attr
+    def group_template(cls):
+        """
+        Source group template (can be ``None``).
+
+        :type: :class:`GroupTemplate`
+        """
+        return relationship.many_to_one(cls, 'group_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Group type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
+
+    # region many_to_many relationships
+
+    @declared_attr
+    def nodes(cls):
+        """
+        Member nodes.
+
+        :type: [:class:`Node`]
+        """
+        return relationship.many_to_many(cls, 'node')
+
+    # endregion
 
     # region foreign_keys
 
@@ -743,51 +887,11 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    # endregion
-
-    # region one_to_one relationships
-
-    # endregion
-
-    # region one_to_many relationships
-
-    @declared_attr
-    def properties(cls):
-        return relationship.one_to_many(cls, 'property', dict_key='name')
-
-    @declared_attr
-    def interfaces(cls):
-        return relationship.one_to_many(cls, 'interface', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def service(cls):
-        return relationship.many_to_one(cls, 'service')
-
-    @declared_attr
-    def group_template(cls):
-        return relationship.many_to_one(cls, 'group_template')
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    # region many_to_many relationships
-
-    @declared_attr
-    def nodes(cls):
-        return relationship.many_to_many(cls, 'node')
-
-    # endregion
-
-    description = Column(Text)
+    :type: :obj:`basestring`
+    """)
 
     def configure_operations(self):
         for interface in self.interfaces.itervalues():
@@ -824,29 +928,91 @@
 
 class PolicyBase(InstanceModelMixin):
     """
-    Usually an instance of a :class:`PolicyTemplate`.
+    Typed set of orchestration hints applied to zero or more :class:`Node` or :class:`Group`
+    instances.
 
-    :ivar name: Name (unique for this service)
-    :vartype name: basestring
-    :ivar policy_template: Template from which this policy was instantiated (optional)
-    :vartype policy_template: :class:`PolicyTemplate`
-    :ivar type: Policy type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: string
-    :ivar nodes: Policy will be enacted on all these nodes
-    :vartype nodes: [:class:`Node`]
-    :ivar groups: Policy will be enacted on all nodes in these groups
-    :vartype groups: [:class:`Group`]
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar service: Containing service
-    :vartype service: :class:`Service`
+    Usually an instance of a :class:`PolicyTemplate`.
     """
 
     __tablename__ = 'policy'
 
-    __private_fields__ = ['type_fk', 'service_fk', 'policy_template_fk']
+    __private_fields__ = ('type_fk',
+                          'service_fk',
+                          'policy_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def properties(cls):
+        """
+        Associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
+        return relationship.one_to_many(cls, 'property', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def service(cls):
+        """
+        Containing service.
+
+        :type: :class:`Service`
+        """
+        return relationship.many_to_one(cls, 'service')
+
+    @declared_attr
+    def policy_template(cls):
+        """
+        Source policy template (can be ``None``).
+
+        :type: :class:`PolicyTemplate`
+        """
+        return relationship.many_to_one(cls, 'policy_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Group type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
+
+    # region many_to_many relationships
+
+    @declared_attr
+    def nodes(cls):
+        """
+        Policy is enacted on these nodes.
+
+        :type: {:obj:`basestring`: :class:`Node`}
+        """
+        return relationship.many_to_many(cls, 'node')
+
+    @declared_attr
+    def groups(cls):
+        """
+        Policy is enacted on nodes in these groups.
+
+        :type: {:obj:`basestring`: :class:`Group`}
+        """
+        return relationship.many_to_many(cls, 'group')
+
+    # endregion
 
     # region foreign_keys
 
@@ -867,51 +1033,11 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    # endregion
-
-    # region one_to_one relationships
-
-    # endregion
-
-    # region one_to_many relationships
-
-    @declared_attr
-    def properties(cls):
-        return relationship.one_to_many(cls, 'property', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def service(cls):
-        return relationship.many_to_one(cls, 'service')
-
-    @declared_attr
-    def policy_template(cls):
-        return relationship.many_to_one(cls, 'policy_template')
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    # region many_to_many relationships
-
-    @declared_attr
-    def nodes(cls):
-        return relationship.many_to_many(cls, 'node')
-
-    @declared_attr
-    def groups(cls):
-        return relationship.many_to_many(cls, 'group')
-
-    # endregion
-
-    description = Column(Text)
+    :type: :obj:`basestring`
+    """)
 
     @property
     def as_raw(self):
@@ -946,38 +1072,15 @@
 
 class SubstitutionBase(InstanceModelMixin):
     """
-    Used to substitute a single node for the entire deployment.
+    Exposes the entire service as a single node.
 
     Usually an instance of a :class:`SubstitutionTemplate`.
-
-    :ivar substitution_template: Template from which this substitution was instantiated (optional)
-    :vartype substitution_template: :class:`SubstitutionTemplate`
-    :ivar node_type: Exposed node type
-    :vartype node_type: :class:`Type`
-    :ivar mappings: Requirement and capability mappings
-    :vartype mappings: {basestring: :class:`SubstitutionTemplate`}
-    :ivar service: Containing service
-    :vartype service: :class:`Service`
     """
 
     __tablename__ = 'substitution'
 
-    __private_fields__ = ['node_type_fk',
-                          'substitution_template_fk']
-
-    # region foreign_keys
-
-    @declared_attr
-    def node_type_fk(cls):
-        """For Substitution many-to-one to Type"""
-        return relationship.foreign_key('type')
-
-    @declared_attr
-    def substitution_template_fk(cls):
-        """For Substitution many-to-one to SubstitutionTemplate"""
-        return relationship.foreign_key('substitution_template', nullable=True)
-
-    # endregion
+    __private_fields__ = ('node_type_fk',
+                          'substitution_template_fk')
 
     # region association proxies
 
@@ -991,6 +1094,11 @@
 
     @declared_attr
     def mappings(cls):
+        """
+        Map requirement and capabilities to exposed node.
+
+        :type: {:obj:`basestring`: :class:`SubstitutionMapping`}
+        """
         return relationship.one_to_many(cls, 'substitution_mapping', dict_key='name')
 
     # endregion
@@ -999,18 +1107,47 @@
 
     @declared_attr
     def service(cls):
+        """
+        Containing service.
+
+        :type: :class:`Service`
+        """
         return relationship.one_to_one(cls, 'service', back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def substitution_template(cls):
+        """
+        Source substitution template (can be ``None``).
+
+        :type: :class:`SubstitutionTemplate`
+        """
         return relationship.many_to_one(cls, 'substitution_template')
 
     @declared_attr
     def node_type(cls):
+        """
+        Exposed node type.
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
 
     # endregion
 
+    # region foreign_keys
+
+    @declared_attr
+    def node_type_fk(cls):
+        """For Substitution many-to-one to Type"""
+        return relationship.foreign_key('type')
+
+    @declared_attr
+    def substitution_template_fk(cls):
+        """For Substitution many-to-one to SubstitutionTemplate"""
+        return relationship.foreign_key('substitution_template', nullable=True)
+
+    # endregion
+
     @property
     def as_raw(self):
         return collections.OrderedDict((
@@ -1033,30 +1170,76 @@
 
 class SubstitutionMappingBase(InstanceModelMixin):
     """
-    Used by :class:`Substitution` to map a capability or a requirement to a node.
+    Used by :class:`Substitution` to map a capability or a requirement to the exposed node.
 
-    Only one of `capability_template` and `requirement_template` can be set.
+    The :attr:`name` field should match the capability or requirement template name on the exposed
+    node's type.
 
-    Usually an instance of a :class:`SubstitutionTemplate`.
+    Only one of :attr:`capability` and :attr:`requirement_template` can be set. If the latter is
+    set, then :attr:`node` must also be set.
 
-    :ivar name: Exposed capability or requirement name
-    :vartype name: basestring
-    :ivar node: Node
-    :vartype node: :class:`Node`
-    :ivar capability: Capability in the node
-    :vartype capability: :class:`Capability`
-    :ivar requirement_template: Requirement template in the node template
-    :vartype requirement_template: :class:`RequirementTemplate`
-    :ivar substitution: Containing substitution
-    :vartype substitution: :class:`Substitution`
+    Usually an instance of a :class:`SubstitutionMappingTemplate`.
     """
 
     __tablename__ = 'substitution_mapping'
 
-    __private_fields__ = ['substitution_fk',
-                          'node_fk',
+    __private_fields__ = ('substitution_fk',
                           'capability_fk',
-                          'requirement_template_fk']
+                          'requirement_template_fk',
+                          'node_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    @declared_attr
+    def capability(cls):
+        """
+        Capability to expose (can be ``None``).
+
+        :type: :class:`Capability`
+        """
+        return relationship.one_to_one(cls, 'capability', back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def requirement_template(cls):
+        """
+        Requirement template to expose (can be ``None``).
+
+        :type: :class:`RequirementTemplate`
+        """
+        return relationship.one_to_one(cls, 'requirement_template',
+                                       back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def node(cls):
+        """
+        Node for which to expose :attr:`requirement_template` (can be ``None``).
+
+        :type: :class:`Node`
+        """
+        return relationship.one_to_one(cls, 'node', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
+
+    # region one_to_many relationships
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def substitution(cls):
+        """
+        Containing substitution.
+
+        :type: :class:`Substitution`
+        """
+        return relationship.many_to_one(cls, 'substitution', back_populates='mappings')
+
+    # endregion
 
     # region foreign keys
 
@@ -1066,55 +1249,22 @@
         return relationship.foreign_key('substitution')
 
     @declared_attr
-    def node_fk(cls):
-        """For Substitution one-to-one to NodeTemplate"""
-        return relationship.foreign_key('node')
-
-    @declared_attr
     def capability_fk(cls):
         """For Substitution one-to-one to Capability"""
         return relationship.foreign_key('capability', nullable=True)
 
     @declared_attr
+    def node_fk(cls):
+        """For Substitution one-to-one to Node"""
+        return relationship.foreign_key('node', nullable=True)
+
+    @declared_attr
     def requirement_template_fk(cls):
         """For Substitution one-to-one to RequirementTemplate"""
         return relationship.foreign_key('requirement_template', nullable=True)
 
     # endregion
 
-    # region association proxies
-
-    # endregion
-
-    # region one_to_one relationships
-
-    @declared_attr
-    def substitution(cls):
-        return relationship.many_to_one(cls, 'substitution', back_populates='mappings')
-
-    @declared_attr
-    def node(cls):
-        return relationship.one_to_one(cls, 'node', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def capability(cls):
-        return relationship.one_to_one(cls, 'capability', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def requirement_template(cls):
-        return relationship.one_to_one(
-            cls, 'requirement_template', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    # region one_to_many relationships
-
-    # endregion
-
-    # region many_to_one relationships
-
-    # endregion
-
     @property
     def as_raw(self):
         return collections.OrderedDict((
@@ -1134,56 +1284,143 @@
 
     def dump(self):
         context = ConsumptionContext.get_thread_local()
-        console.puts('{0} -> {1}.{2}'.format(
-            context.style.node(self.name),
-            context.style.node(self.node.name),
-            context.style.node(self.capability.name
-                               if self.capability
-                               else self.requirement_template.name)))
+        if self.capability is not None:
+            console.puts('{0} -> {1}.{2}'.format(
+                context.style.node(self.name),
+                context.style.node(self.capability.node.name),
+                context.style.node(self.capability.name)))
+        else:
+            console.puts('{0} -> {1}.{2}'.format(
+                context.style.node(self.name),
+                context.style.node(self.node.name),
+                context.style.node(self.requirement_template.name)))
 
 
 class RelationshipBase(InstanceModelMixin):
     """
-    Connects :class:`Node` to a capability in another node.
+    Optionally-typed edge in the service topology, connecting a :class:`Node` to a
+    :class:`Capability` of another node.
 
-    Might be an instance of a :class:`RelationshipTemplate`.
-
-    :ivar name: Name (usually the name of the requirement at the source node template)
-    :vartype name: basestring
-    :ivar relationship_template: Template from which this relationship was instantiated (optional)
-    :vartype relationship_template: :class:`RelationshipTemplate`
-    :ivar requirement_template: Template from which this relationship was instantiated (optional)
-    :vartype requirement_template: :class:`RequirementTemplate`
-    :ivar type: Relationship type
-    :vartype type: :class:`Type`
-    :ivar target_capability: Capability at the target node (optional)
-    :vartype target_capability: :class:`Capability`
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar interfaces: Bundles of operations
-    :vartype interfaces: {basestring: :class:`Interfaces`}
-    :ivar source_position: The position of the relationship in the outbound relationships.
-    :vartype source_position: int
-    :ivar target_position: The position of the relationship in the inbound relationships.
-    :vartype target_position: int
-    :ivar source_node: Source node
-    :vartype source_node: :class:`Node`
-    :ivar target_node: Target node
-    :vartype target_node: :class:`Node`
-    :ivar tasks: Tasks for this relationship
-    :vartype tasks: [:class:`Task`]
+    Might be an instance of :class:`RelationshipTemplate` and/or :class:`RequirementTemplate`.
     """
 
     __tablename__ = 'relationship'
 
-    __private_fields__ = ['type_fk',
+    __private_fields__ = ('type_fk',
                           'source_node_fk',
                           'target_node_fk',
                           'target_capability_fk',
                           'requirement_template_fk',
                           'relationship_template_fk',
                           'target_position',
-                          'source_position']
+                          'source_position')
+
+    # region association proxies
+
+    @declared_attr
+    def source_node_name(cls):
+        return relationship.association_proxy('source_node', 'name')
+
+    @declared_attr
+    def target_node_name(cls):
+        return relationship.association_proxy('target_node', 'name')
+
+    # endregion
+
+    # region one_to_one relationships
+
+    @declared_attr
+    def target_capability(cls):
+        """
+        Target capability.
+
+        :type: :class:`Capability`
+        """
+        return relationship.one_to_one(cls, 'capability', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def tasks(cls):
+        """
+        Associated tasks.
+
+        :type: [:class:`Task`]
+        """
+        return relationship.one_to_many(cls, 'task')
+
+    @declared_attr
+    def interfaces(cls):
+        """
+        Associated interfaces.
+
+        :type: {:obj:`basestring`: :class:`Interface`}
+        """
+        return relationship.one_to_many(cls, 'interface', dict_key='name')
+
+    @declared_attr
+    def properties(cls):
+        """
+        Associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
+        return relationship.one_to_many(cls, 'property', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def source_node(cls):
+        """
+        Source node.
+
+        :type: :class:`Node`
+        """
+        return relationship.many_to_one(
+            cls, 'node', fk='source_node_fk', back_populates='outbound_relationships')
+
+    @declared_attr
+    def target_node(cls):
+        """
+        Target node.
+
+        :type: :class:`Node`
+        """
+        return relationship.many_to_one(
+            cls, 'node', fk='target_node_fk', back_populates='inbound_relationships')
+
+    @declared_attr
+    def relationship_template(cls):
+        """
+        Source relationship template (can be ``None``).
+
+        :type: :class:`RelationshipTemplate`
+        """
+        return relationship.many_to_one(cls, 'relationship_template')
+
+    @declared_attr
+    def requirement_template(cls):
+        """
+        Source requirement template (can be ``None``).
+
+        :type: :class:`RequirementTemplate`
+        """
+        return relationship.many_to_one(cls, 'requirement_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Relationship type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
 
     # region foreign keys
 
@@ -1219,72 +1456,17 @@
 
     # endregion
 
-    # region association proxies
+    source_position = Column(Integer, doc="""
+    Position at source.
 
-    @declared_attr
-    def source_node_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('source_node', 'name')
+    :type: :obj:`int`
+    """)
 
-    @declared_attr
-    def target_node_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('target_node', 'name')
+    target_position = Column(Integer, doc="""
+    Position at target.
 
-    # endregion
-
-    # region one_to_one relationships
-
-    @declared_attr
-    def target_capability(cls):
-        return relationship.one_to_one(cls, 'capability', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    # region one_to_many relationships
-
-    @declared_attr
-    def tasks(cls):
-        return relationship.one_to_many(cls, 'task')
-
-    @declared_attr
-    def interfaces(cls):
-        return relationship.one_to_many(cls, 'interface', dict_key='name')
-
-    @declared_attr
-    def properties(cls):
-        return relationship.one_to_many(cls, 'property', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def source_node(cls):
-        return relationship.many_to_one(
-            cls, 'node', fk='source_node_fk', back_populates='outbound_relationships')
-
-    @declared_attr
-    def target_node(cls):
-        return relationship.many_to_one(
-            cls, 'node', fk='target_node_fk', back_populates='inbound_relationships')
-
-    @declared_attr
-    def relationship_template(cls):
-        return relationship.many_to_one(cls, 'relationship_template')
-
-    @declared_attr
-    def requirement_template(cls):
-        return relationship.many_to_one(cls, 'requirement_template')
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    source_position = Column(Integer)
-    target_position = Column(Integer)
+    :type: :obj:`int`
+    """)
 
     def configure_operations(self):
         for interface in self.interfaces.itervalues():
@@ -1332,37 +1514,69 @@
 
 class CapabilityBase(InstanceModelMixin):
     """
-    A capability of a :class:`Node`.
+    Typed attachment serving two purposes: to provide extra properties and attributes to a
+    :class:`Node`, and to expose targets for :class:`Relationship` instances from other nodes.
 
     Usually an instance of a :class:`CapabilityTemplate`.
-
-    :ivar name: Name (unique for the node)
-    :vartype name: basestring
-    :ivar capability_template: Template from which this capability was instantiated (optional)
-    :vartype capability_template: :class:`capabilityTemplate`
-    :ivar type: Capability type
-    :vartype type: :class:`Type`
-    :ivar min_occurrences: Minimum number of requirement matches required
-    :vartype min_occurrences: int
-    :ivar max_occurrences: Maximum number of requirement matches allowed
-    :vartype min_occurrences: int
-    :ivar occurrences: Actual number of requirement matches
-    :vartype occurrences: int
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar node: Containing node
-    :vartype node: :class:`Node`
-    :ivar relationship: Available when we are the target of a relationship
-    :vartype relationship: :class:`Relationship`
-    :ivar substitution_mapping: Our contribution to service substitution
-    :vartype substitution_mapping: :class:`SubstitutionMapping`
     """
 
     __tablename__ = 'capability'
 
-    __private_fields__ = ['capability_fk',
+    __private_fields__ = ('capability_fk',
                           'node_fk',
-                          'capability_template_fk']
+                          'capability_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def properties(cls):
+        """
+        Associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
+        return relationship.one_to_many(cls, 'property', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def node(cls):
+        """
+        Containing node.
+
+        :type: :class:`Node`
+        """
+        return relationship.many_to_one(cls, 'node')
+
+    @declared_attr
+    def capability_template(cls):
+        """
+        Source capability template (can be ``None``).
+
+        :type: :class:`CapabilityTemplate`
+        """
+        return relationship.many_to_one(cls, 'capability_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Capability type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
 
     # region foreign_keys
 
@@ -1383,41 +1597,23 @@
 
     # endregion
 
-    # region association proxies
+    min_occurrences = Column(Integer, default=None, doc="""
+    Minimum number of requirement matches required.
 
-    # endregion
+    :type: :obj:`int`
+    """)
 
-    # region one_to_one relationships
+    max_occurrences = Column(Integer, default=None, doc="""
+    Maximum number of requirement matches allowed.
 
-    # endregion
+    :type: :obj:`int`
+    """)
 
-    # region one_to_many relationships
+    occurrences = Column(Integer, default=0, doc="""
+    Number of requirement matches.
 
-    @declared_attr
-    def properties(cls):
-        return relationship.one_to_many(cls, 'property', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def node(cls):
-        return relationship.many_to_one(cls, 'node')
-
-    @declared_attr
-    def capability_template(cls):
-        return relationship.many_to_one(cls, 'capability_template')
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    min_occurrences = Column(Integer, default=None)
-    max_occurrences = Column(Integer, default=None)
-    occurrences = Column(Integer, default=0)
+    :type: :obj:`int`
+    """)
 
     @property
     def has_enough_relationships(self):
@@ -1461,37 +1657,99 @@
 
 class InterfaceBase(InstanceModelMixin):
     """
-    A typed set of :class:`Operation`.
+    Typed bundle of :class:`Operation` instances.
 
-    Usually an instance of :class:`InterfaceTemplate`.
+    Can be associated with a :class:`Node`, a :class:`Group`, or a :class:`Relationship`.
 
-    :ivar name: Name (unique for the node, group, or relationship)
-    :vartype name: basestring
-    :ivar interface_template: Template from which this interface was instantiated (optional)
-    :vartype interface_template: :class:`InterfaceTemplate`
-    :ivar type: Interface type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: string
-    :ivar inputs: Inputs that can be used by all operations in the interface
-    :vartype inputs: {basestring: :class:`Input`}
-    :ivar operations: Operations
-    :vartype operations: {basestring: :class:`Operation`}
-    :ivar node: Containing node
-    :vartype node: :class:`Node`
-    :ivar group: Containing group
-    :vartype group: :class:`Group`
-    :ivar relationship: Containing relationship
-    :vartype relationship: :class:`Relationship`
+    Usually an instance of a :class:`InterfaceTemplate`.
     """
 
     __tablename__ = 'interface'
 
-    __private_fields__ = ['type_fk',
+    __private_fields__ = ('type_fk',
                           'node_fk',
                           'group_fk',
                           'relationship_fk',
-                          'interface_template_fk']
+                          'interface_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def inputs(cls):
+        """
+        Parameters for all operations of the interface.
+
+        :type: {:obj:`basestring`: :class:`Input`}
+        """
+        return relationship.one_to_many(cls, 'input', dict_key='name')
+
+    @declared_attr
+    def operations(cls):
+        """
+        Associated operations.
+
+        :type: {:obj:`basestring`: :class:`Operation`}
+        """
+        return relationship.one_to_many(cls, 'operation', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def node(cls):
+        """
+        Containing node (can be ``None``).
+
+        :type: :class:`Node`
+        """
+        return relationship.many_to_one(cls, 'node')
+
+    @declared_attr
+    def group(cls):
+        """
+        Containing group (can be ``None``).
+
+        :type: :class:`Group`
+        """
+        return relationship.many_to_one(cls, 'group')
+
+    @declared_attr
+    def relationship(cls):
+        """
+        Containing relationship (can be ``None``).
+
+        :type: :class:`Relationship`
+        """
+        return relationship.many_to_one(cls, 'relationship')
+
+    @declared_attr
+    def interface_template(cls):
+        """
+        Source interface template (can be ``None``).
+
+        :type: :class:`InterfaceTemplate`
+        """
+        return relationship.many_to_one(cls, 'interface_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Interface type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
 
     # region foreign_keys
 
@@ -1522,51 +1780,11 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    # endregion
-
-    # region one_to_one relationships
-
-    # endregion
-
-    # region one_to_many relationships
-
-    @declared_attr
-    def inputs(cls):
-        return relationship.one_to_many(cls, 'input', dict_key='name')
-
-    @declared_attr
-    def operations(cls):
-        return relationship.one_to_many(cls, 'operation', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def node(cls):
-        return relationship.many_to_one(cls, 'node')
-
-    @declared_attr
-    def relationship(cls):
-        return relationship.many_to_one(cls, 'relationship')
-
-    @declared_attr
-    def group(cls):
-        return relationship.many_to_one(cls, 'group')
-
-    @declared_attr
-    def interface_template(cls):
-        return relationship.many_to_one(cls, 'interface_template')
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    description = Column(Text)
+    :type: :obj:`basestring`
+    """)
 
     def configure_operations(self):
         for operation in self.operations.itervalues():
@@ -1602,52 +1820,112 @@
 
 class OperationBase(InstanceModelMixin):
     """
-    An operation in a :class:`Interface`.
+    Entry points to Python functions called as part of a workflow execution.
+
+    The operation signature (its :attr:`name` and its :attr:`inputs`'s names and types) is declared
+    by the type of the :class:`Interface`, however each operation can provide its own
+    :attr:`implementation` as well as additional inputs.
+
+    The Python :attr:`function` is usually provided by an associated :class:`Plugin`. Its purpose is
+    to execute the implementation, providing it with both the operation's and interface's inputs.
+    The :attr:`arguments` of the function should be set according to the specific signature of the
+    function.
+
+    Additionally, :attr:`configuration` parameters can be provided as hints to configure the
+    function's behavior. For example, they can be used to configure remote execution credentials.
 
     Might be an instance of :class:`OperationTemplate`.
-
-    :ivar name: Name (unique for the interface or service)
-    :vartype name: basestring
-    :ivar operation_template: Template from which this operation was instantiated (optional)
-    :vartype operation_template: :class:`OperationTemplate`
-    :ivar description: Human-readable description
-    :vartype description: string
-    :ivar relationship_edge: When true specified that the operation is on the relationship's
-                             target edge instead of its source (only used by relationship
-                             operations)
-    :vartype relationship_edge: bool
-    :ivar implementation: Implementation (interpreted by the plugin)
-    :vartype implementation: basestring
-    :ivar dependencies: Dependency strings (interpreted by the plugin)
-    :vartype dependencies: [basestring]
-    :ivar inputs: Input that can be used by this operation
-    :vartype inputs: {basestring: :class:`Input`}
-    :ivar plugin: Associated plugin
-    :vartype plugin: :class:`Plugin`
-    :ivar configurations: Configuration (interpreted by the plugin)
-    :vartype configurations: {basestring, :class:`Configuration`}
-    :ivar function: Name of the operation function
-    :vartype function: basestring
-    :ivar arguments: Arguments to send to the operation function
-    :vartype arguments: {basestring: :class:`Argument`}
-    :ivar executor: Name of executor to run the operation with
-    :vartype executor: basestring
-    :ivar max_attempts: Maximum number of attempts allowed in case of failure
-    :vartype max_attempts: int
-    :ivar retry_interval: Interval between retries (in seconds)
-    :vartype retry_interval: int
-    :ivar interface: Containing interface
-    :vartype interface: :class:`Interface`
-    :ivar service: Containing service
-    :vartype service: :class:`Service`
     """
 
     __tablename__ = 'operation'
 
-    __private_fields__ = ['service_fk',
+    __private_fields__ = ('service_fk',
                           'interface_fk',
                           'plugin_fk',
-                          'operation_template_fk']
+                          'operation_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    @declared_attr
+    def plugin(cls):
+        """
+        Associated plugin.
+
+        :type: :class:`Plugin`
+        """
+        return relationship.one_to_one(cls, 'plugin', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def inputs(cls):
+        """
+        Parameters provided to the :attr:`implementation`.
+
+        :type: {:obj:`basestring`: :class:`Input`}
+        """
+        return relationship.one_to_many(cls, 'input', dict_key='name')
+
+    @declared_attr
+    def arguments(cls):
+        """
+        Arguments sent to the Python :attr:`function`.
+
+        :type: {:obj:`basestring`: :class:`Argument`}
+        """
+        return relationship.one_to_many(cls, 'argument', dict_key='name')
+
+    @declared_attr
+    def configurations(cls):
+        """
+        Configuration parameters for the Python :attr:`function`.
+
+        :type: {:obj:`basestring`: :class:`Configuration`}
+        """
+        return relationship.one_to_many(cls, 'configuration', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def service(cls):
+        """
+        Containing service (can be ``None``). For workflow operations.
+
+        :type: :class:`Service`
+        """
+        return relationship.many_to_one(cls, 'service', back_populates='workflows')
+
+    @declared_attr
+    def interface(cls):
+        """
+        Containing interface (can be ``None``).
+
+        :type: :class:`Interface`
+        """
+        return relationship.many_to_one(cls, 'interface')
+
+    @declared_attr
+    def operation_template(cls):
+        """
+        Source operation template (can be ``None``).
+
+        :type: :class:`OperationTemplate`
+        """
+        return relationship.many_to_one(cls, 'operation_template')
+
+    # endregion
+
+    # region many_to_many relationships
+
+    # endregion
 
     # region foreign_keys
 
@@ -1673,62 +1951,54 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    # endregion
+    :type: :obj:`basestring`
+    """)
 
-    # region one_to_one relationships
+    relationship_edge = Column(Boolean, doc="""
+    When ``True`` specifies that the operation is on the relationship's target edge; ``False`` is
+    the source edge (only used by operations on relationships)
 
-    @declared_attr
-    def plugin(cls):
-        return relationship.one_to_one(cls, 'plugin', back_populates=relationship.NO_BACK_POP)
+    :type: :obj:`bool`
+    """)
 
-    # endregion
+    implementation = Column(Text, doc="""
+    Implementation (usually the name of an artifact).
 
-    # region one_to_many relationships
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def inputs(cls):
-        return relationship.one_to_many(cls, 'input', dict_key='name')
+    dependencies = Column(modeling_types.StrictList(item_cls=basestring), doc="""
+    Dependencies (usually names of artifacts).
 
-    @declared_attr
-    def configurations(cls):
-        return relationship.one_to_many(cls, 'configuration', dict_key='name')
+    :type: [:obj:`basestring`]
+    """)
 
-    @declared_attr
-    def arguments(cls):
-        return relationship.one_to_many(cls, 'argument', dict_key='name')
+    function = Column(Text, doc="""
+    Full path to Python function.
 
-    # endregion
+    :type: :obj:`basestring`
+    """)
 
-    # region many_to_one relationships
+    executor = Column(Text, doc="""
+    Name of executor.
 
-    @declared_attr
-    def service(cls):
-        return relationship.many_to_one(cls, 'service', back_populates='workflows')
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def interface(cls):
-        return relationship.many_to_one(cls, 'interface')
+    max_attempts = Column(Integer, doc="""
+    Maximum number of attempts allowed in case of task failure.
 
-    @declared_attr
-    def operation_template(cls):
-        return relationship.many_to_one(cls, 'operation_template')
+    :type: :obj:`int`
+    """)
 
-    # endregion
+    retry_interval = Column(Integer, doc="""
+    Interval between task retry attemps (in seconds).
 
-    # region many_to_many relationships
-
-    # endregion
-
-    description = Column(Text)
-    relationship_edge = Column(Boolean)
-    implementation = Column(Text)
-    dependencies = Column(modeling_types.StrictList(item_cls=basestring))
-    function = Column(Text)
-    executor = Column(Text)
-    max_attempts = Column(Integer)
-    retry_interval = Column(Integer)
+    :type: :obj:`float`
+    """)
 
     def configure(self):
         if (self.implementation is None) and (self.function is None):
@@ -1821,37 +2091,68 @@
 
 class ArtifactBase(InstanceModelMixin):
     """
-    A file associated with a :class:`Node`.
+    Typed file, either provided in a CSAR or downloaded from a repository.
 
     Usually an instance of :class:`ArtifactTemplate`.
-
-    :ivar name: Name (unique for the node)
-    :vartype name: basestring
-    :ivar artifact_template: Template from which this artifact was instantiated (optional)
-    :vartype artifact_template: :class:`ArtifactTemplate`
-    :ivar type: Artifact type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: string
-    :ivar source_path: Source path (CSAR or repository)
-    :vartype source_path: basestring
-    :ivar target_path: Path at destination machine
-    :vartype target_path: basestring
-    :ivar repository_url: Repository URL
-    :vartype repository_path: basestring
-    :ivar repository_credential: Credentials for accessing the repository
-    :vartype repository_credential: {basestring: basestring}
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar node: Containing node
-    :vartype node: :class:`Node`
     """
 
     __tablename__ = 'artifact'
 
-    __private_fields__ = ['type_fk',
+    __private_fields__ = ('type_fk',
                           'node_fk',
-                          'artifact_template_fk']
+                          'artifact_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def properties(cls):
+        """
+        Associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
+        return relationship.one_to_many(cls, 'property', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def node(cls):
+        """
+        Containing node.
+
+        :type: :class:`Node`
+        """
+        return relationship.many_to_one(cls, 'node')
+
+    @declared_attr
+    def artifact_template(cls):
+        """
+        Source artifact template (can be ``None``).
+
+        :type: :class:`ArtifactTemplate`
+        """
+        return relationship.many_to_one(cls, 'artifact_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Artifact type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
 
     # region foreign_keys
 
@@ -1872,41 +2173,35 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    # endregion
+    :type: :obj:`basestring`
+    """)
 
-    # region one_to_one relationships
+    source_path = Column(Text, doc="""
+    Source path (in CSAR or repository).
 
-    # endregion
+    :type: :obj:`basestring`
+    """)
 
-    # region one_to_many relationships
+    target_path = Column(Text, doc="""
+    Path at which to install at destination.
 
-    @declared_attr
-    def properties(cls):
-        return relationship.one_to_many(cls, 'property', dict_key='name')
+    :type: :obj:`basestring`
+    """)
 
-    # endregion
+    repository_url = Column(Text, doc="""
+    Repository URL.
 
-    # region many_to_one relationships
-    @declared_attr
-    def node(cls):
-        return relationship.many_to_one(cls, 'node')
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def artifact_template(cls):
-        return relationship.many_to_one(cls, 'artifact_template')
+    repository_credential = Column(modeling_types.StrictDict(basestring, basestring), doc="""
+    Credentials for accessing the repository.
 
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-    # endregion
-
-    description = Column(Text)
-    source_path = Column(Text)
-    target_path = Column(Text)
-    repository_url = Column(Text)
-    repository_credential = Column(modeling_types.StrictDict(basestring, basestring))
+    :type: {:obj:`basestring`, :obj:`basestring`}
+    """)
 
     @property
     def as_raw(self):
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index 344da6d..57fd672 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+ARIA modeling service template module
+"""
+
 # pylint: disable=too-many-lines, no-self-argument, no-member, abstract-method
 
 from __future__ import absolute_import  # so we can import standard 'types'
@@ -28,7 +32,6 @@
     PickleType
 )
 from sqlalchemy.ext.declarative import declared_attr
-from sqlalchemy.ext.associationproxy import association_proxy
 
 from ..parser import validation
 from ..parser.consumption import ConsumptionContext
@@ -45,72 +48,228 @@
 
 class ServiceTemplateBase(TemplateModelMixin):
     """
-    A service template is a source for creating :class:`Service` instances.
+    Template for creating :class:`Service` instances.
 
-    It is usually created by various DSL parsers, such as ARIA's TOSCA extension. However, it can
-    also be created programmatically.
-
-    :ivar name: Name (unique for this ARIA installation)
-    :vartype name: basestring
-    :ivar description: Human-readable description
-    :vartype description: basestring
-    :ivar main_file_name: Filename of CSAR or YAML file from which this service template was parsed
-    :vartype main_file_name: basestring
-    :ivar meta_data: Custom annotations
-    :vartype meta_data: {basestring: :class:`Metadata`}
-    :ivar node_templates: Templates for creating nodes
-    :vartype node_templates: {basestring: :class:`NodeTemplate`}
-    :ivar group_templates: Templates for creating groups
-    :vartype group_templates: {basestring: :class:`GroupTemplate`}
-    :ivar policy_templates: Templates for creating policies
-    :vartype policy_templates: {basestring: :class:`PolicyTemplate`}
-    :ivar substitution_template: The entire service can appear as a node
-    :vartype substitution_template: :class:`SubstitutionTemplate`
-    :ivar inputs: Externally provided parameters
-    :vartype inputs: {basestring: :class:`Input`}
-    :ivar outputs: These parameters are filled in after service installation
-    :vartype outputs: {basestring: :class:`Output`}
-    :ivar workflow_templates: Custom workflows that can be performed on the service
-    :vartype workflow_templates: {basestring: :class:`OperationTemplate`}
-    :ivar plugin_specifications: Plugins used by the service
-    :vartype plugin_specifications: {basestring: :class:`PluginSpecification`}
-    :ivar node_types: Base for the node type hierarchy
-    :vartype node_types: :class:`Type`
-    :ivar group_types: Base for the group type hierarchy
-    :vartype group_types: :class:`Type`
-    :ivar policy_types: Base for the policy type hierarchy
-    :vartype policy_types: :class:`Type`
-    :ivar relationship_types: Base for the relationship type hierarchy
-    :vartype relationship_types: :class:`Type`
-    :ivar capability_types: Base for the capability type hierarchy
-    :vartype capability_types: :class:`Type`
-    :ivar interface_types: Base for the interface type hierarchy
-    :vartype interface_types: :class:`Type`
-    :ivar artifact_types: Base for the artifact type hierarchy
-    :vartype artifact_types: :class:`Type`
-    :ivar created_at: Creation timestamp
-    :vartype created_at: :class:`datetime.datetime`
-    :ivar updated_at: Update timestamp
-    :vartype updated_at: :class:`datetime.datetime`
-    :ivar services: Instantiated services
-    :vartype services: [:class:`Service`]
+    Usually created by various DSL parsers, such as ARIA's TOSCA extension. However, it can also be
+    created programmatically.
     """
 
     __tablename__ = 'service_template'
 
-    __private_fields__ = ['substitution_template_fk',
+    __private_fields__ = ('substitution_template_fk',
                           'node_type_fk',
                           'group_type_fk',
                           'policy_type_fk',
                           'relationship_type_fk',
                           'capability_type_fk',
                           'interface_type_fk',
-                          'artifact_type_fk']
+                          'artifact_type_fk')
 
-    description = Column(Text)
-    main_file_name = Column(Text)
-    created_at = Column(DateTime, nullable=False, index=True)
-    updated_at = Column(DateTime)
+    description = Column(Text, doc="""
+    Human-readable description.
+
+    :type: :obj:`basestring`
+    """)
+
+    main_file_name = Column(Text, doc="""
+    Filename of CSAR or YAML file from which this service template was parsed.
+    
+    :type: :obj:`basestring`
+    """)
+
+    created_at = Column(DateTime, nullable=False, index=True, doc="""
+    Creation timestamp.
+
+    :type: :class:`~datetime.datetime`
+    """)
+
+    updated_at = Column(DateTime, doc="""
+    Update timestamp.
+
+    :type: :class:`~datetime.datetime`
+    """)
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    @declared_attr
+    def substitution_template(cls):
+        """
+        Exposes an entire service as a single node.
+
+        :type: :class:`SubstitutionTemplate`
+        """
+        return relationship.one_to_one(
+            cls, 'substitution_template', back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def node_types(cls):
+        """
+        Base for the node type hierarchy,
+
+        :type: :class:`Type`
+        """
+        return relationship.one_to_one(
+            cls, 'type', fk='node_type_fk', back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def group_types(cls):
+        """
+        Base for the group type hierarchy,
+
+        :type: :class:`Type`
+        """
+        return relationship.one_to_one(
+            cls, 'type', fk='group_type_fk', back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def policy_types(cls):
+        """
+        Base for the policy type hierarchy,
+
+        :type: :class:`Type`
+        """
+        return relationship.one_to_one(
+            cls, 'type', fk='policy_type_fk', back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def relationship_types(cls):
+        """
+        Base for the relationship type hierarchy,
+
+        :type: :class:`Type`
+        """
+        return relationship.one_to_one(
+            cls, 'type', fk='relationship_type_fk', back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def capability_types(cls):
+        """
+        Base for the capability type hierarchy,
+
+        :type: :class:`Type`
+        """
+        return relationship.one_to_one(
+            cls, 'type', fk='capability_type_fk', back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def interface_types(cls):
+        """
+        Base for the interface type hierarchy,
+
+        :type: :class:`Type`
+        """
+        return relationship.one_to_one(
+            cls, 'type', fk='interface_type_fk', back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def artifact_types(cls):
+        """
+        Base for the artifact type hierarchy,
+
+        :type: :class:`Type`
+        """
+        return relationship.one_to_one(
+            cls, 'type', fk='artifact_type_fk', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def services(cls):
+        """
+        Instantiated services.
+
+        :type: [:class:`Service`]
+        """
+        return relationship.one_to_many(cls, 'service', dict_key='name')
+
+    @declared_attr
+    def node_templates(cls):
+        """
+        Templates for creating nodes.
+
+        :type: {:obj:`basestring`, :class:`NodeTemplate`}
+        """
+        return relationship.one_to_many(cls, 'node_template', dict_key='name')
+
+    @declared_attr
+    def group_templates(cls):
+        """
+        Templates for creating groups.
+
+        :type: {:obj:`basestring`, :class:`GroupTemplate`}
+        """
+        return relationship.one_to_many(cls, 'group_template', dict_key='name')
+
+    @declared_attr
+    def policy_templates(cls):
+        """
+        Templates for creating policies.
+
+        :type: {:obj:`basestring`, :class:`PolicyTemplate`}
+        """
+        return relationship.one_to_many(cls, 'policy_template', dict_key='name')
+
+    @declared_attr
+    def workflow_templates(cls):
+        """
+        Templates for creating workflows.
+
+        :type: {:obj:`basestring`, :class:`OperationTemplate`}
+        """
+        return relationship.one_to_many(cls, 'operation_template', dict_key='name')
+
+    @declared_attr
+    def outputs(cls):
+        """
+        Declarations for output parameters are filled in after service installation.
+
+        :type: {:obj:`basestring`: :class:`Output`}
+        """
+        return relationship.one_to_many(cls, 'output', dict_key='name')
+
+    @declared_attr
+    def inputs(cls):
+        """
+        Declarations for externally provided parameters.
+
+        :type: {:obj:`basestring`: :class:`Input`}
+        """
+        return relationship.one_to_many(cls, 'input', dict_key='name')
+
+    @declared_attr
+    def plugin_specifications(cls):
+        """
+        Required plugins for instantiated services.
+
+        :type: {:obj:`basestring`: :class:`PluginSpecification`}
+        """
+        return relationship.one_to_many(cls, 'plugin_specification', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    # endregion
+
+    # region many_to_many relationships
+
+    @declared_attr
+    def meta_data(cls):
+        """
+        Associated metadata.
+
+        :type: {:obj:`basestring`: :class:`Metadata`}
+        """
+        # Warning! We cannot use the attr name "metadata" because it's used by SQLAlchemy!
+        return relationship.many_to_many(cls, 'metadata', dict_key='name')
+
+    # endregion
 
     # region foreign keys
 
@@ -156,103 +315,6 @@
 
     # endregion
 
-    # region association proxies
-
-    # endregion
-
-    # region one_to_one relationships
-
-    @declared_attr
-    def substitution_template(cls):
-        return relationship.one_to_one(
-            cls, 'substitution_template', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def node_types(cls):
-        return relationship.one_to_one(
-            cls, 'type', fk='node_type_fk', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def group_types(cls):
-        return relationship.one_to_one(
-            cls, 'type', fk='group_type_fk', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def policy_types(cls):
-        return relationship.one_to_one(
-            cls, 'type', fk='policy_type_fk', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def relationship_types(cls):
-        return relationship.one_to_one(
-            cls, 'type', fk='relationship_type_fk', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def capability_types(cls):
-        return relationship.one_to_one(
-            cls, 'type', fk='capability_type_fk', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def interface_types(cls):
-        return relationship.one_to_one(
-            cls, 'type', fk='interface_type_fk', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def artifact_types(cls):
-        return relationship.one_to_one(
-            cls, 'type', fk='artifact_type_fk', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    # region one_to_many relationships
-
-    @declared_attr
-    def services(cls):
-        return relationship.one_to_many(cls, 'service', dict_key='name')
-
-    @declared_attr
-    def node_templates(cls):
-        return relationship.one_to_many(cls, 'node_template', dict_key='name')
-
-    @declared_attr
-    def outputs(cls):
-        return relationship.one_to_many(cls, 'output', dict_key='name')
-
-    @declared_attr
-    def inputs(cls):
-        return relationship.one_to_many(cls, 'input', dict_key='name')
-
-    @declared_attr
-    def group_templates(cls):
-        return relationship.one_to_many(cls, 'group_template', dict_key='name')
-
-    @declared_attr
-    def policy_templates(cls):
-        return relationship.one_to_many(cls, 'policy_template', dict_key='name')
-
-    @declared_attr
-    def workflow_templates(cls):
-        return relationship.one_to_many(cls, 'operation_template', dict_key='name')
-
-    @declared_attr
-    def plugin_specifications(cls):
-        return relationship.one_to_many(cls, 'plugin_specification', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    # endregion
-
-    # region many_to_many relationships
-
-    @declared_attr
-    def meta_data(cls):
-        # Warning! We cannot use the attr name "metadata" because it's used by SQLAlchemy!
-        return relationship.many_to_many(cls, 'metadata', dict_key='name')
-
-    # endregion
-
     @property
     def as_raw(self):
         return collections.OrderedDict((
@@ -397,49 +459,119 @@
 
 class NodeTemplateBase(TemplateModelMixin):
     """
-    A template for creating zero or more :class:`Node` instances.
-
-    :ivar name: Name (unique for this service template; will usually be used as a prefix for node
-                names)
-    :vartype name: basestring
-    :ivar type: Node type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: basestring
-    :ivar default_instances: Default number nodes that will appear in the service
-    :vartype default_instances: int
-    :ivar min_instances: Minimum number nodes that will appear in the service
-    :vartype min_instances: int
-    :ivar max_instances: Maximum number nodes that will appear in the service
-    :vartype max_instances: int
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar interface_templates: Bundles of operations
-    :vartype interface_templates: {basestring: :class:`InterfaceTemplate`}
-    :ivar artifact_templates: Associated files
-    :vartype artifact_templates: {basestring: :class:`ArtifactTemplate`}
-    :ivar capability_templates: Exposed capabilities
-    :vartype capability_templates: {basestring: :class:`CapabilityTemplate`}
-    :ivar requirement_templates: Potential relationships with other nodes
-    :vartype requirement_templates: [:class:`RequirementTemplate`]
-    :ivar target_node_template_constraints: Constraints for filtering relationship targets
-    :vartype target_node_template_constraints: [:class:`NodeTemplateConstraint`]
-    :ivar service_template: Containing service template
-    :vartype service_template: :class:`ServiceTemplate`
-    :ivar group_templates: We are a member of these groups
-    :vartype group_templates: [:class:`GroupTemplate`]
-    :ivar policy_templates: Policy templates enacted on this node
-    :vartype policy_templates: [:class:`PolicyTemplate`]
-    :ivar substitution_template_mapping: Our contribution to service substitution
-    :vartype substitution_template_mapping: :class:`SubstitutionTemplateMapping`
-    :ivar nodes: Instantiated nodes
-    :vartype nodes: [:class:`Node`]
+    Template for creating zero or more :class:`Node` instances, which are typed vertices in the
+    service topology.
     """
 
     __tablename__ = 'node_template'
 
-    __private_fields__ = ['type_fk',
-                          'service_template_fk']
+    __private_fields__ = ('type_fk',
+                          'service_template_fk')
+
+    # region association proxies
+
+    @declared_attr
+    def service_template_name(cls):
+        return relationship.association_proxy('service_template', 'name')
+
+    @declared_attr
+    def type_name(cls):
+        return relationship.association_proxy('type', 'name')
+
+    # endregion
+
+    # region one_to_one relationships
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def nodes(cls):
+        """
+        Instantiated nodes.
+
+        :type: [:class:`Node`]
+        """
+        return relationship.one_to_many(cls, 'node')
+
+    @declared_attr
+    def interface_templates(cls):
+        """
+        Associated interface templates.
+
+        :type: {:obj:`basestring`: :class:`InterfaceTemplate`}
+        """
+        return relationship.one_to_many(cls, 'interface_template', dict_key='name')
+
+    @declared_attr
+    def artifact_templates(cls):
+        """
+        Associated artifacts.
+
+        :type: {:obj:`basestring`: :class:`ArtifactTemplate`}
+        """
+        return relationship.one_to_many(cls, 'artifact_template', dict_key='name')
+
+    @declared_attr
+    def capability_templates(cls):
+        """
+        Associated exposed capability templates.
+
+        :type: {:obj:`basestring`: :class:`CapabilityTemplate`}
+        """
+        return relationship.one_to_many(cls, 'capability_template', dict_key='name')
+
+    @declared_attr
+    def requirement_templates(cls):
+        """
+        Associated potential relationships with other nodes.
+
+        :type: [:class:`RequirementTemplate`]
+        """
+        return relationship.one_to_many(cls, 'requirement_template', other_fk='node_template_fk')
+
+    @declared_attr
+    def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
+        return relationship.one_to_many(cls, 'property', dict_key='name')
+
+    @declared_attr
+    def attributes(cls):
+        """
+        Declarations for associated mutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Attribute`}
+        """
+        return relationship.one_to_many(cls, 'attribute', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def type(cls):
+        """
+        Node type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def service_template(cls):
+        """
+        Containing service template.
+
+        :type: :class:`ServiceTemplate`
+        """
+        return relationship.many_to_one(cls, 'service_template')
+
+    # endregion
 
     # region foreign_keys
 
@@ -455,73 +587,35 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    @declared_attr
-    def service_template_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('service_template', 'name')
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def type_name(cls):
-        """Required for use by SQLAlchemy queries"""
-        return association_proxy('type', 'name')
+    default_instances = Column(Integer, default=1, doc="""
+    Default number nodes that will appear in the service.
 
-    # endregion
+    :type: :obj:`int`
+    """)
 
-    # region one_to_one relationships
+    min_instances = Column(Integer, default=0, doc="""
+    Minimum number nodes that will appear in the service.
 
-    # endregion
+    :type: :obj:`int`
+    """)
 
-    # region one_to_many relationships
+    max_instances = Column(Integer, default=None, doc="""
+    Maximum number nodes that will appear in the service.
 
-    @declared_attr
-    def nodes(cls):
-        return relationship.one_to_many(cls, 'node')
+    :type: :obj:`int`
+    """)
 
-    @declared_attr
-    def interface_templates(cls):
-        return relationship.one_to_many(cls, 'interface_template', dict_key='name')
+    target_node_template_constraints = Column(PickleType, doc="""
+    Constraints for filtering relationship targets.
 
-    @declared_attr
-    def artifact_templates(cls):
-        return relationship.one_to_many(cls, 'artifact_template', dict_key='name')
-
-    @declared_attr
-    def capability_templates(cls):
-        return relationship.one_to_many(cls, 'capability_template', dict_key='name')
-
-    @declared_attr
-    def requirement_templates(cls):
-        return relationship.one_to_many(cls, 'requirement_template', other_fk='node_template_fk')
-
-    @declared_attr
-    def properties(cls):
-        return relationship.one_to_many(cls, 'property', dict_key='name')
-
-    @declared_attr
-    def attributes(cls):
-        return relationship.one_to_many(cls, 'attribute', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def service_template(cls):
-        return relationship.many_to_one(cls, 'service_template')
-
-    # endregion
-
-    description = Column(Text)
-    default_instances = Column(Integer, default=1)
-    min_instances = Column(Integer, default=0)
-    max_instances = Column(Integer, default=None)
-    target_node_template_constraints = Column(PickleType)
+    :type: [:class:`NodeTemplateConstraint`]
+    """)
 
     def is_target_node_template_valid(self, target_node_template):
         if self.target_node_template_constraints:
@@ -612,34 +706,88 @@
 
 class GroupTemplateBase(TemplateModelMixin):
     """
-    A template for creating a :class:`Group` instance.
-
-    Groups are logical containers for zero or more nodes.
-
-    :ivar name: Name (unique for this service template)
-    :vartype name: basestring
-    :ivar type: Group type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: basestring
-    :ivar node_templates: All nodes instantiated by these templates will be members of the group
-    :vartype node_templates: [:class:`NodeTemplate`]
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar interface_templates: Bundles of operations
-    :vartype interface_templates: {basestring: :class:`InterfaceTemplate`}
-    :ivar service_template: Containing service template
-    :vartype service_template: :class:`ServiceTemplate`
-    :ivar policy_templates: Policy templates enacted on this group
-    :vartype policy_templates: [:class:`PolicyTemplate`]
-    :ivar groups: Instantiated groups
-    :vartype groups: [:class:`Group`]
+    Template for creating a :class:`Group` instance, which is a typed logical container for zero or
+    more :class:`Node` instances.
     """
 
     __tablename__ = 'group_template'
 
-    __private_fields__ = ['type_fk',
-                          'service_template_fk']
+    __private_fields__ = ('type_fk',
+                          'service_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def groups(cls):
+        """
+        Instantiated groups.
+
+        :type: [:class:`Group`]
+        """
+        return relationship.one_to_many(cls, 'group')
+
+    @declared_attr
+    def interface_templates(cls):
+        """
+        Associated interface templates.
+
+        :type: {:obj:`basestring`: :class:`InterfaceTemplate`}
+        """
+        return relationship.one_to_many(cls, 'interface_template', dict_key='name')
+
+    @declared_attr
+    def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
+        return relationship.one_to_many(cls, 'property', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def service_template(cls):
+        """
+        Containing service template.
+
+        :type: :class:`ServiceTemplate`
+        """
+        return relationship.many_to_one(cls, 'service_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Group type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
+
+    # region many_to_many relationships
+
+    @declared_attr
+    def node_templates(cls):
+        """
+        Nodes instantiated by these templates will be members of the group.
+
+        :type: [:class:`NodeTemplate`]
+        """
+        return relationship.many_to_many(cls, 'node_template')
+
+    # endregion
 
     # region foreign keys
 
@@ -655,51 +803,11 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    # endregion
-
-    # region one_to_one relationships
-
-    # endregion
-
-    # region one_to_many relationships
-
-    @declared_attr
-    def groups(cls):
-        return relationship.one_to_many(cls, 'group')
-
-    @declared_attr
-    def interface_templates(cls):
-        return relationship.one_to_many(cls, 'interface_template', dict_key='name')
-
-    @declared_attr
-    def properties(cls):
-        return relationship.one_to_many(cls, 'property', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def service_template(cls):
-        return relationship.many_to_one(cls, 'service_template')
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    # region many_to_many relationships
-
-    @declared_attr
-    def node_templates(cls):
-        return relationship.many_to_many(cls, 'node_template')
-
-    # endregion
-
-    description = Column(Text)
+    :type: :obj:`basestring`
+    """)
 
     @property
     def as_raw(self):
@@ -747,30 +855,88 @@
 
 class PolicyTemplateBase(TemplateModelMixin):
     """
-    Policies can be applied to zero or more :class:`NodeTemplate` or :class:`GroupTemplate`
-    instances.
-
-    :ivar name: Name (unique for this service template)
-    :vartype name: basestring
-    :ivar type: Policy type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: basestring
-    :ivar node_templates: Policy will be enacted on all nodes instantiated by these templates
-    :vartype node_templates: [:class:`NodeTemplate`]
-    :ivar group_templates: Policy will be enacted on all nodes in these groups
-    :vartype group_templates: [:class:`GroupTemplate`]
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar service_template: Containing service template
-    :vartype service_template: :class:`ServiceTemplate`
-    :ivar policies: Instantiated policies
-    :vartype policies: [:class:`Policy`]
+    Template for creating a :class:`Policy` instance, which is a typed set of orchestration hints
+    applied to zero or more :class:`Node` or :class:`Group` instances.
     """
 
     __tablename__ = 'policy_template'
 
-    __private_fields__ = ['type_fk', 'service_template_fk']
+    __private_fields__ = ('type_fk',
+                          'service_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def policies(cls):
+        """
+        Instantiated policies.
+
+        :type: [:class:`Policy`]
+        """
+        return relationship.one_to_many(cls, 'policy')
+
+    @declared_attr
+    def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
+        return relationship.one_to_many(cls, 'property', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def service_template(cls):
+        """
+        Containing service template.
+
+        :type: :class:`ServiceTemplate`
+        """
+        return relationship.many_to_one(cls, 'service_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Policy type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
+
+    # region many_to_many relationships
+
+    @declared_attr
+    def node_templates(cls):
+        """
+        Policy will be enacted on all nodes instantiated by these templates.
+
+        :type: {:obj:`basestring`: :class:`NodeTemplate`}
+        """
+        return relationship.many_to_many(cls, 'node_template')
+
+    @declared_attr
+    def group_templates(cls):
+        """
+        Policy will be enacted on all nodes in all groups instantiated by these templates.
+
+        :type: {:obj:`basestring`: :class:`GroupTemplate`}
+        """
+        return relationship.many_to_many(cls, 'group_template')
+
+    # endregion
 
     # region foreign keys
 
@@ -786,51 +952,11 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    # endregion
-
-    # region one_to_one relationships
-
-    # endregion
-
-    # region one_to_many relationships
-
-    @declared_attr
-    def policies(cls):
-        return relationship.one_to_many(cls, 'policy')
-
-    @declared_attr
-    def properties(cls):
-        return relationship.one_to_many(cls, 'property', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def service_template(cls):
-        return relationship.many_to_one(cls, 'service_template')
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    # region many_to_many relationships
-
-    @declared_attr
-    def node_templates(cls):
-        return relationship.many_to_many(cls, 'node_template')
-
-    @declared_attr
-    def group_templates(cls):
-        return relationship.many_to_many(cls, 'group_template')
-
-    # endregion
-
-    description = Column(Text)
+    :type: :obj:`basestring`
+    """)
 
     @property
     def as_raw(self):
@@ -879,30 +1005,13 @@
 
 class SubstitutionTemplateBase(TemplateModelMixin):
     """
-    Used to substitute a single node for the entire deployment.
-
-    :ivar node_type: Exposed node type
-    :vartype node_type: :class:`Type`
-    :ivar mappings: Requirement and capability mappings
-    :vartype mappings: {basestring: :class:`SubstitutionTemplateMapping`}
-    :ivar service_template: Containing service template
-    :vartype service_template: :class:`ServiceTemplate`
-    :ivar substitutions: Instantiated substitutions
-    :vartype substitutions: [:class:`Substitution`]
+    Template for creating a :class:`Substitution` instance, which exposes an entire instantiated
+    service as a single node.
     """
 
     __tablename__ = 'substitution_template'
 
-    __private_fields__ = ['node_type_fk']
-
-    # region foreign keys
-
-    @declared_attr
-    def node_type_fk(cls):
-        """For SubstitutionTemplate many-to-one to Type"""
-        return relationship.foreign_key('type')
-
-    # endregion
+    __private_fields__ = ('node_type_fk',)
 
     # region association proxies
 
@@ -916,10 +1025,20 @@
 
     @declared_attr
     def substitutions(cls):
+        """
+        Instantiated substitutions.
+
+        :type: [:class:`Substitution`]
+        """
         return relationship.one_to_many(cls, 'substitution')
 
     @declared_attr
     def mappings(cls):
+        """
+        Map requirement and capabilities to exposed node.
+
+        :type: {:obj:`basestring`: :class:`SubstitutionTemplateMapping`}
+        """
         return relationship.one_to_many(cls, 'substitution_template_mapping', dict_key='name')
 
     # endregion
@@ -928,10 +1047,24 @@
 
     @declared_attr
     def node_type(cls):
+        """
+        Exposed node type.
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
 
     # endregion
 
+    # region foreign keys
+
+    @declared_attr
+    def node_type_fk(cls):
+        """For SubstitutionTemplate many-to-one to Type"""
+        return relationship.foreign_key('type')
+
+    # endregion
+
     @property
     def as_raw(self):
         return collections.OrderedDict((
@@ -961,52 +1094,20 @@
 
 class SubstitutionTemplateMappingBase(TemplateModelMixin):
     """
-    Used by :class:`SubstitutionTemplate` to map a capability or a requirement to a node.
+    Used by :class:`SubstitutionTemplate` to map a capability template or a requirement template to
+    the exposed node.
 
-    Only one of `capability_template` and `requirement_template` can be set.
+    The :attr:`name` field should match the capability or requirement name on the exposed node's
+    type.
 
-    :ivar name: Exposed capability or requirement name
-    :vartype name: basestring
-    :ivar node_template: Node template
-    :vartype node_template: :class:`NodeTemplate`
-    :ivar capability_template: Capability template in the node template
-    :vartype capability_template: :class:`CapabilityTemplate`
-    :ivar requirement_template: Requirement template in the node template
-    :vartype requirement_template: :class:`RequirementTemplate`
-    :ivar substitution_template: Containing substitution template
-    :vartype substitution_template: :class:`SubstitutionTemplate`
+    Only one of :attr:`capability_template` and :attr:`requirement_template` can be set.
     """
 
     __tablename__ = 'substitution_template_mapping'
 
-    __private_fields__ = ['substitution_template_fk',
-                          'node_template_fk',
+    __private_fields__ = ('substitution_template_fk',
                           'capability_template_fk',
-                          'requirement_template_fk']
-
-    # region foreign keys
-
-    @declared_attr
-    def substitution_template_fk(cls):
-        """For SubstitutionTemplate one-to-many to SubstitutionTemplateMapping"""
-        return relationship.foreign_key('substitution_template')
-
-    @declared_attr
-    def node_template_fk(cls):
-        """For SubstitutionTemplate one-to-one to NodeTemplate"""
-        return relationship.foreign_key('node_template')
-
-    @declared_attr
-    def capability_template_fk(cls):
-        """For SubstitutionTemplate one-to-one to CapabilityTemplate"""
-        return relationship.foreign_key('capability_template', nullable=True)
-
-    @declared_attr
-    def requirement_template_fk(cls):
-        """For SubstitutionTemplate one-to-one to RequirementTemplate"""
-        return relationship.foreign_key('requirement_template', nullable=True)
-
-    # endregion
+                          'requirement_template_fk')
 
     # region association proxies
 
@@ -1015,17 +1116,22 @@
     # region one_to_one relationships
 
     @declared_attr
-    def node_template(cls):
-        return relationship.one_to_one(
-            cls, 'node_template', back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
     def capability_template(cls):
+        """
+        Capability template to expose (can be ``None``).
+
+        :type: :class:`CapabilityTemplate`
+        """
         return relationship.one_to_one(
             cls, 'capability_template', back_populates=relationship.NO_BACK_POP)
 
     @declared_attr
     def requirement_template(cls):
+        """
+        Requirement template to expose (can be ``None``).
+
+        :type: :class:`RequirementTemplate`
+        """
         return relationship.one_to_one(
             cls, 'requirement_template', back_populates=relationship.NO_BACK_POP)
 
@@ -1039,10 +1145,34 @@
 
     @declared_attr
     def substitution_template(cls):
+        """
+        Containing substitution template.
+
+        :type: :class:`SubstitutionTemplate`
+        """
         return relationship.many_to_one(cls, 'substitution_template', back_populates='mappings')
 
     # endregion
 
+    # region foreign keys
+
+    @declared_attr
+    def substitution_template_fk(cls):
+        """For SubstitutionTemplate one-to-many to SubstitutionTemplateMapping"""
+        return relationship.foreign_key('substitution_template')
+
+    @declared_attr
+    def capability_template_fk(cls):
+        """For SubstitutionTemplate one-to-one to CapabilityTemplate"""
+        return relationship.foreign_key('capability_template', nullable=True)
+
+    @declared_attr
+    def requirement_template_fk(cls):
+        """For SubstitutionTemplate one-to-one to RequirementTemplate"""
+        return relationship.foreign_key('requirement_template', nullable=True)
+
+    # endregion
+
     @property
     def as_raw(self):
         return collections.OrderedDict((
@@ -1054,7 +1184,11 @@
     def instantiate(self, container):
         from . import models
         context = ConsumptionContext.get_thread_local()
-        nodes = self.node_template.nodes
+        if self.capability_template is not None:
+            node_template = self.capability_template.node_template
+        else:
+            node_template = self.requirement_template.node_template
+        nodes = node_template.nodes
         if len(nodes) == 0:
             context.validation.report(
                 'mapping "{0}" refers to node template "{1}" but there are no '
@@ -1070,9 +1204,10 @@
                 if a_capability.capability_template.name == self.capability_template.name:
                     capability = a_capability
         return models.SubstitutionMapping(name=self.name,
-                                          node=node,
                                           capability=capability,
-                                          requirement_template=self.requirement_template)
+                                          requirement_template=self.requirement_template,
+                                          node=node)
+
 
     def validate(self):
         context = ConsumptionContext.get_thread_local()
@@ -1085,9 +1220,13 @@
 
     def dump(self):
         context = ConsumptionContext.get_thread_local()
+        if self.capability_template is not None:
+            node_template = self.capability_template.node_template
+        else:
+            node_template = self.requirement_template.node_template
         console.puts('{0} -> {1}.{2}'.format(
             context.style.node(self.name),
-            context.style.node(self.node_template.name),
+            context.style.node(node_template.name),
             context.style.node(self.capability_template.name
                                if self.capability_template
                                else self.requirement_template.name)))
@@ -1095,41 +1234,103 @@
 
 class RequirementTemplateBase(TemplateModelMixin):
     """
-    A requirement for a :class:`NodeTemplate`. During instantiation will be matched with a
-    capability of another node.
+    Template for creating :class:`Relationship` instances, which are optionally-typed edges in the
+    service topology, connecting a :class:`Node` to a :class:`Capability` of another node.
 
-    Requirements may optionally contain a :class:`RelationshipTemplate` that will be created between
-    the nodes.
+    Note that there is no equivalent "Requirement" instance model. Instead, during instantiation a
+    requirement template is matched with a capability and a :class:`Relationship` is instantiated.
 
-    :ivar name: Name (a node template can have multiple requirements with the same name)
-    :vartype name: basestring
-    :ivar target_node_type: Required node type (optional)
-    :vartype target_node_type: :class:`Type`
-    :ivar target_node_template: Required node template (optional)
-    :vartype target_node_template: :class:`NodeTemplate`
-    :ivar target_capability_type: Required capability type (optional)
-    :vartype target_capability_type: :class:`Type`
-    :ivar target_capability_name: Name of capability in target node (optional)
-    :vartype target_capability_name: basestring
-    :ivar target_node_template_constraints: Constraints for filtering relationship targets
-    :vartype target_node_template_constraints: [:class:`NodeTemplateConstraint`]
-    :ivar relationship_template: Template for relationships (optional)
-    :vartype relationship_template: :class:`RelationshipTemplate`
-    :ivar node_template: Containing node template
-    :vartype node_template: :class:`NodeTemplate`
-    :ivar substitution_template_mapping: Our contribution to service substitution
-    :vartype substitution_template_mapping: :class:`SubstitutionTemplateMapping`
-    :ivar substitution_mapping: Our contribution to service substitution
-    :vartype substitution_mapping: :class:`SubstitutionMapping`
+    A requirement template *must* target a :class:`CapabilityType` or a capability name. It can
+    optionally target a specific :class:`NodeType` or :class:`NodeTemplate`.
+
+    Requirement templates may optionally contain a :class:`RelationshipTemplate`. If they do not,
+    a :class:`Relationship` will be instantiated with default values.
     """
 
     __tablename__ = 'requirement_template'
 
-    __private_fields__ = ['target_node_type_fk',
+    __private_fields__ = ('target_capability_type_fk',
                           'target_node_template_fk',
-                          'target_capability_type_fk'
-                          'node_template_fk',
-                          'relationship_template_fk']
+                          'target_node_type_fk',
+                          'relationship_template_fk',
+                          'node_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    @declared_attr
+    def target_capability_type(cls):
+        """
+        Target capability type.
+
+        :type: :class:`CapabilityType`
+        """
+        return relationship.one_to_one(cls,
+                                       'type',
+                                       fk='target_capability_type_fk',
+                                       back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def target_node_template(cls):
+        """
+        Target node template (can be ``None``).
+
+        :type: :class:`NodeTemplate`
+        """
+        return relationship.one_to_one(cls,
+                                       'node_template',
+                                       fk='target_node_template_fk',
+                                       back_populates=relationship.NO_BACK_POP)
+
+    @declared_attr
+    def relationship_template(cls):
+        """
+        Associated relationship template (can be ``None``).
+
+        :type: :class:`RelationshipTemplate`
+        """
+        return relationship.one_to_one(cls, 'relationship_template')
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def relationships(cls):
+        """
+        Instantiated relationships.
+
+        :type: [:class:`Relationship`]
+        """
+        return relationship.one_to_many(cls, 'relationship')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def node_template(cls):
+        """
+        Containing node template.
+
+        :type: :class:`NodeTemplate`
+        """
+        return relationship.many_to_one(cls, 'node_template', fk='node_template_fk')
+
+    @declared_attr
+    def target_node_type(cls):
+        """
+        Target node type (can be ``None``).
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(
+            cls, 'type', fk='target_node_type_fk', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
 
     # region foreign keys
 
@@ -1145,7 +1346,7 @@
 
     @declared_attr
     def target_capability_type_fk(cls):
-        """For RequirementTemplate one-to-one to NodeTemplate"""
+        """For RequirementTemplate one-to-one to Type"""
         return relationship.foreign_key('type', nullable=True)
 
     @declared_attr
@@ -1160,55 +1361,17 @@
 
     # endregion
 
-    # region association proxies
+    target_capability_name = Column(Text, doc="""
+    Target capability name in node template or node type (can be ``None``).
 
-    # endregion
+    :type: :obj:`basestring`
+    """)
 
-    # region one_to_one relationships
+    target_node_template_constraints = Column(PickleType, doc="""
+    Constraints for filtering relationship targets.
 
-    @declared_attr
-    def target_node_template(cls):
-        return relationship.one_to_one(cls,
-                                       'node_template',
-                                       fk='target_node_template_fk',
-                                       back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def target_capability_type(cls):
-        return relationship.one_to_one(cls,
-                                       'type',
-                                       fk='target_capability_type_fk',
-                                       back_populates=relationship.NO_BACK_POP)
-
-    @declared_attr
-    def relationship_template(cls):
-        return relationship.one_to_one(cls, 'relationship_template')
-
-    # endregion
-
-    # region one_to_many relationships
-
-    @declared_attr
-    def relationships(cls):
-        return relationship.one_to_many(cls, 'relationship')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def node_template(cls):
-        return relationship.many_to_one(cls, 'node_template', fk='node_template_fk')
-
-    @declared_attr
-    def target_node_type(cls):
-        return relationship.many_to_one(
-            cls, 'type', fk='target_node_type_fk', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    target_capability_name = Column(Text)
-    target_node_template_constraints = Column(PickleType)
+    :type: [:class:`NodeTemplateConstraint`]
+    """)
 
     def find_target(self, source_node_template):
         context = ConsumptionContext.get_thread_local()
@@ -1313,41 +1476,16 @@
 
 class RelationshipTemplateBase(TemplateModelMixin):
     """
-    Optional addition to a :class:`RequirementTemplate` in :class:`NodeTemplate` that can be applied
-    when the requirement is matched with a capability.
+    Optional addition to a :class:`RequirementTemplate`.
 
-    Note that a relationship template here is not equivalent to a relationship template entity in
-    TOSCA. For example, a TOSCA requirement specifying a relationship type instead of a template
-    would still be represented here as a relationship template.
-
-    :ivar name: Name (optional; if present is unique for this service template)
-    :vartype name: basestring
-    :ivar type: Relationship type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: basestring
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar interface_templates: Bundles of operations
-    :vartype interface_templates: {basestring: :class:`InterfaceTemplate`}
-    :ivar requirement_template: Containing requirement template
-    :vartype requirement_template: :class:`RequirementTemplate`
-    :ivar relationships: Instantiated relationships
-    :vartype relationships: [:class:`Relationship`]
+    Note that a relationship template here is not exactly equivalent to a relationship template
+    entity in TOSCA. For example, a TOSCA requirement specifying a relationship type rather than a
+    relationship template would still be represented here as a relationship template.
     """
 
     __tablename__ = 'relationship_template'
 
-    __private_fields__ = ['type_fk']
-
-    # region foreign keys
-
-    @declared_attr
-    def type_fk(cls):
-        """For RelationshipTemplate many-to-one to Type"""
-        return relationship.foreign_key('type', nullable=True)
-
-    # endregion
+    __private_fields__ = ('type_fk',)
 
     # region association proxies
 
@@ -1361,14 +1499,29 @@
 
     @declared_attr
     def relationships(cls):
+        """
+        Instantiated relationships.
+
+        :type: [:class:`Relationship`]
+        """
         return relationship.one_to_many(cls, 'relationship')
 
     @declared_attr
     def interface_templates(cls):
+        """
+        Associated interface templates.
+
+        :type: {:obj:`basestring`: :class:`InterfaceTemplate`}
+        """
         return relationship.one_to_many(cls, 'interface_template', dict_key='name')
 
     @declared_attr
     def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
         return relationship.one_to_many(cls, 'property', dict_key='name')
 
     # endregion
@@ -1377,11 +1530,29 @@
 
     @declared_attr
     def type(cls):
+        """
+        Relationship type.
+
+        :type: :class:`Type`
+        """
         return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
 
     # endregion
 
-    description = Column(Text)
+    # region foreign keys
+
+    @declared_attr
+    def type_fk(cls):
+        """For RelationshipTemplate many-to-one to Type"""
+        return relationship.foreign_key('type', nullable=True)
+
+    # endregion
+
+    description = Column(Text, doc="""
+    Human-readable description.
+
+    :type: :obj:`basestring`
+    """)
 
     @property
     def as_raw(self):
@@ -1426,35 +1597,80 @@
 
 class CapabilityTemplateBase(TemplateModelMixin):
     """
-    A capability of a :class:`NodeTemplate`. Nodes expose zero or more capabilities that can be
-    matched with :class:`Requirement` instances of other nodes.
-
-    :ivar name: Name (unique for the node template)
-    :vartype name: basestring
-    :ivar type: Capability type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: basestring
-    :ivar valid_source_node_types: Reject requirements that are not from these node types (optional)
-    :vartype valid_source_node_types: [:class:`Type`]
-    :ivar min_occurrences: Minimum number of requirement matches required
-    :vartype min_occurrences: int
-    :ivar max_occurrences: Maximum number of requirement matches allowed
-    :vartype min_occurrences: int
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar node_template: Containing node template
-    :vartype node_template: :class:`NodeTemplate`
-    :ivar substitution_template_mapping: Our contribution to service substitution
-    :vartype substitution_template_mapping: :class:`SubstitutionTemplateMapping`
-    :ivar capabilities: Instantiated capabilities
-    :vartype capabilities: [:class:`Capability`]
+    Template for creating :class:`Capability` instances, typed attachments which serve two purposes:
+    to provide extra properties and attributes to :class:`Node` instances, and to expose targets for
+    :class:`Relationship` instances from other nodes.
     """
 
     __tablename__ = 'capability_template'
 
-    __private_fields__ = ['type_fk',
-                          'node_template_fk']
+    __private_fields__ = ('type_fk',
+                          'node_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def capabilities(cls):
+        """
+        Instantiated capabilities.
+
+        :type: [:class:`Capability`]
+        """
+        return relationship.one_to_many(cls, 'capability')
+
+    @declared_attr
+    def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
+        return relationship.one_to_many(cls, 'property', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def node_template(cls):
+        """
+        Containing node template.
+
+        :type: :class:`NodeTemplate`
+        """
+        return relationship.many_to_one(cls, 'node_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Capability type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
+
+    # region many_to_many relationships
+
+    @declared_attr
+    def valid_source_node_types(cls):
+        """
+        Reject requirements that are not from these node types.
+
+        :type: [:class:`Type`]
+        """
+        return relationship.many_to_many(cls, 'type', prefix='valid_sources')
+
+    # endregion
 
     # region foreign keys
 
@@ -1470,50 +1686,23 @@
 
     # endregion
 
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    # region association proxies
+    :type: :obj:`basestring`
+    """)
 
-    # endregion
+    min_occurrences = Column(Integer, default=None, doc="""
+    Minimum number of requirement matches required.
 
-    # region one_to_one relationships
+    :type: :obj:`int`
+    """)
 
-    # endregion
+    max_occurrences = Column(Integer, default=None, doc="""
+    Maximum number of requirement matches allowed.
 
-    # region one_to_many relationships
-
-    @declared_attr
-    def capabilities(cls):
-        return relationship.one_to_many(cls, 'capability')
-
-    @declared_attr
-    def properties(cls):
-        return relationship.one_to_many(cls, 'property', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def node_template(cls):
-        return relationship.many_to_one(cls, 'node_template')
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    # region many_to_many relationships
-
-    @declared_attr
-    def valid_source_node_types(cls):
-        return relationship.many_to_many(cls, 'type', prefix='valid_sources')
-
-    # endregion
-
-    description = Column(Text)
-    min_occurrences = Column(Integer, default=None)  # optional
-    max_occurrences = Column(Integer, default=None)  # optional
+    :type: :obj:`int`
+    """)
 
     def satisfies_requirement(self,
                               source_node_template,
@@ -1588,34 +1777,99 @@
 
 class InterfaceTemplateBase(TemplateModelMixin):
     """
-    A typed set of :class:`OperationTemplate`.
+    Template for creating :class:`Interface` instances, which are typed bundles of
+    :class:`Operation` instances.
 
-    :ivar name: Name (unique for the node, group, or relationship template)
-    :vartype name: basestring
-    :ivar type: Interface type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: basestring
-    :ivar inputs: Inputs that can be used by all operations in the interface
-    :vartype inputs: {basestring: :class:`Input`}
-    :ivar operation_templates: Operations
-    :vartype operation_templates: {basestring: :class:`OperationTemplate`}
-    :ivar node_template: Containing node template
-    :vartype node_template: :class:`NodeTemplate`
-    :ivar group_template: Containing group template
-    :vartype group_template: :class:`GroupTemplate`
-    :ivar relationship_template: Containing relationship template
-    :vartype relationship_template: :class:`RelationshipTemplate`
-    :ivar interfaces: Instantiated interfaces
-    :vartype interfaces: [:class:`Interface`]
+    Can be associated with a :class:`NodeTemplate`, a :class:`GroupTemplate`, or a
+    :class:`RelationshipTemplate`.
     """
 
     __tablename__ = 'interface_template'
 
-    __private_fields__ = ['type_fk',
+    __private_fields__ = ('type_fk',
                           'node_template_fk',
                           'group_template_fk',
-                          'relationship_template_fk']
+                          'relationship_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def inputs(cls):
+        """
+        Declarations for externally provided parameters that can be used by all operations of the
+        interface.
+
+        :type: {:obj:`basestring`: :class:`Input`}
+        """
+        return relationship.one_to_many(cls, 'input', dict_key='name')
+
+    @declared_attr
+    def interfaces(cls):
+        """
+        Instantiated interfaces.
+
+        :type: [:class:`Interface`]
+        """
+        return relationship.one_to_many(cls, 'interface')
+
+    @declared_attr
+    def operation_templates(cls):
+        """
+        Associated operation templates.
+
+        :type: {:obj:`basestring`: :class:`OperationTemplate`}
+        """
+        return relationship.one_to_many(cls, 'operation_template', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def node_template(cls):
+        """
+        Containing node template (can be ``None``).
+
+        :type: :class:`NodeTemplate`
+        """
+        return relationship.many_to_one(cls, 'node_template')
+
+    @declared_attr
+    def group_template(cls):
+        """
+        Containing group template (can be ``None``).
+
+        :type: :class:`GroupTemplate`
+        """
+        return relationship.many_to_one(cls, 'group_template')
+
+    @declared_attr
+    def relationship_template(cls):
+        """
+        Containing relationship template (can be ``None``).
+
+        :type: :class:`RelationshipTemplate`
+        """
+        return relationship.many_to_one(cls, 'relationship_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Interface type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
 
     # region foreign keys
 
@@ -1641,51 +1895,11 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    # endregion
-
-    # region one_to_one relationships
-
-    # endregion
-
-    # region one_to_many relationships
-
-    @declared_attr
-    def inputs(cls):
-        return relationship.one_to_many(cls, 'input', dict_key='name')
-
-    @declared_attr
-    def interfaces(cls):
-        return relationship.one_to_many(cls, 'interface')
-
-    @declared_attr
-    def operation_templates(cls):
-        return relationship.one_to_many(cls, 'operation_template', dict_key='name')
-
-    # endregion
-
-    # region many_to_one relationships
-
-    @declared_attr
-    def relationship_template(cls):
-        return relationship.many_to_one(cls, 'relationship_template')
-
-    @declared_attr
-    def group_template(cls):
-        return relationship.many_to_one(cls, 'group_template')
-
-    @declared_attr
-    def node_template(cls):
-        return relationship.many_to_one(cls, 'node_template')
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    description = Column(Text)
+    :type: :obj:`basestring`
+    """)
 
     @property
     def as_raw(self):
@@ -1728,49 +1942,91 @@
 
 class OperationTemplateBase(TemplateModelMixin):
     """
-    An operation in a :class:`InterfaceTemplate`.
-
-    Operations are executed by an associated :class:`PluginSpecification` via an executor.
-
-    :ivar name: Name (unique for the interface or service template)
-    :vartype name: basestring
-    :ivar description: Human-readable description
-    :vartype description: basestring
-    :ivar relationship_edge: When true specified that the operation is on the relationship's
-                             target edge instead of its source (only used by relationship
-                             operations)
-    :vartype relationship_edge: bool
-    :ivar implementation: Implementation (interpreted by the plugin)
-    :vartype implementation: basestring
-    :ivar dependencies: Dependency strings (interpreted by the plugin)
-    :vartype dependencies: [basestring]
-    :ivar inputs: Inputs that can be used by this operation
-    :vartype inputs: {basestring: :class:`Input`}
-    :ivar plugin_specification: Associated plugin
-    :vartype plugin_specification: :class:`PluginSpecification`
-    :ivar configurations: Configuration (interpreted by the plugin)
-    :vartype configurations: {basestring, :class:`Configuration`}
-    :ivar function: Name of the operation function
-    :vartype function: basestring
-    :ivar executor: Name of executor to run the operation with
-    :vartype executor: basestring
-    :ivar max_attempts: Maximum number of attempts allowed in case of failure
-    :vartype max_attempts: int
-    :ivar retry_interval: Interval between retries (in seconds)
-    :vartype retry_interval: int
-    :ivar interface_template: Containing interface template
-    :vartype interface_template: :class:`InterfaceTemplate`
-    :ivar service_template: Containing service template
-    :vartype service_template: :class:`ServiceTemplate`
-    :ivar operations: Instantiated operations
-    :vartype operations: [:class:`Operation`]
+    Template for creating :class:`Operation` instances, which are entry points to Python functions
+    called as part of a workflow execution.
     """
 
     __tablename__ = 'operation_template'
 
-    __private_fields__ = ['service_template_fk',
+    __private_fields__ = ('service_template_fk',
                           'interface_template_fk',
-                          'plugin_fk']
+                          'plugin_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    @declared_attr
+    def plugin_specification(cls):
+        """
+        Associated plugin specification.
+
+        :type: :class:`PluginSpecification`
+        """
+        return relationship.one_to_one(
+            cls, 'plugin_specification', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def operations(cls):
+        """
+        Instantiated operations.
+
+        :type: [:class:`Operation`]
+        """
+        return relationship.one_to_many(cls, 'operation')
+
+    @declared_attr
+    def inputs(cls):
+        """
+        Declarations for parameters provided to the :attr:`implementation`.
+
+        :type: {:obj:`basestring`: :class:`Input`}
+        """
+        return relationship.one_to_many(cls, 'input', dict_key='name')
+
+    @declared_attr
+    def configurations(cls):
+        """
+        Configuration parameters for the operation instance Python :attr:`function`.
+
+        :type: {:obj:`basestring`: :class:`Configuration`}
+        """
+        return relationship.one_to_many(cls, 'configuration', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def service_template(cls):
+        """
+        Containing service template (can be ``None``). For workflow operation templates.
+
+        :type: :class:`ServiceTemplate`
+        """
+        return relationship.many_to_one(cls, 'service_template',
+                                        back_populates='workflow_templates')
+
+    @declared_attr
+    def interface_template(cls):
+        """
+        Containing interface template (can be ``None``).
+
+        :type: :class:`InterfaceTemplate`
+        """
+        return relationship.many_to_one(cls, 'interface_template')
+
+    # endregion
+
+    # region many_to_many relationships
+
+    # endregion
 
     # region foreign keys
 
@@ -1791,60 +2047,54 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    # endregion
+    :type: :obj:`basestring`
+    """)
 
-    # region one_to_one relationships
+    relationship_edge = Column(Boolean, doc="""
+    When ``True`` specifies that the operation is on the relationship's target edge; ``False`` is
+    the source edge (only used by operations on relationships)
 
-    @declared_attr
-    def plugin_specification(cls):
-        return relationship.one_to_one(
-            cls, 'plugin_specification', back_populates=relationship.NO_BACK_POP)
+    :type: :obj:`bool`
+    """)
 
-    # endregion
+    implementation = Column(Text, doc="""
+    Implementation (usually the name of an artifact).
 
-    # region one_to_many relationships
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def inputs(cls):
-        return relationship.one_to_many(cls, 'input', dict_key='name')
+    dependencies = Column(modeling_types.StrictList(item_cls=basestring), doc="""
+    Dependencies (usually names of artifacts).
 
-    @declared_attr
-    def operations(cls):
-        return relationship.one_to_many(cls, 'operation')
+    :type: [:obj:`basestring`]
+    """)
 
-    @declared_attr
-    def configurations(cls):
-        return relationship.one_to_many(cls, 'configuration', dict_key='name')
+    function = Column(Text, doc="""
+    Full path to Python function.
 
-    # endregion
+    :type: :obj:`basestring`
+    """)
 
-    # region many_to_one relationships
+    executor = Column(Text, doc="""
+    Name of executor.
 
-    @declared_attr
-    def service_template(cls):
-        return relationship.many_to_one(cls, 'service_template',
-                                        back_populates='workflow_templates')
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def interface_template(cls):
-        return relationship.many_to_one(cls, 'interface_template')
+    max_attempts = Column(Integer, doc="""
+    Maximum number of attempts allowed in case of task failure.
 
-    # endregion
+    :type: :obj:`int`
+    """)
 
-    # region many_to_many relationships
+    retry_interval = Column(Integer, doc="""
+    Interval between task retry attemps (in seconds).
 
-    # endregion
-
-    description = Column(Text)
-    relationship_edge = Column(Boolean)
-    implementation = Column(Text)
-    dependencies = Column(modeling_types.StrictList(item_cls=basestring))
-    function = Column(Text)
-    executor = Column(Text)
-    max_attempts = Column(Integer)
-    retry_interval = Column(Integer)
+    :type: :obj:`float`
+    """)
 
     @property
     def as_raw(self):
@@ -1917,34 +2167,66 @@
 
 class ArtifactTemplateBase(TemplateModelMixin):
     """
-    A file associated with a :class:`NodeTemplate`.
-
-    :ivar name: Name (unique for the node template)
-    :vartype name: basestring
-    :ivar type: Artifact type
-    :vartype type: :class:`Type`
-    :ivar description: Human-readable description
-    :vartype description: basestring
-    :ivar source_path: Source path (CSAR or repository)
-    :vartype source_path: basestring
-    :ivar target_path: Path at destination machine
-    :vartype target_path: basestring
-    :ivar repository_url: Repository URL
-    :vartype repository_path: basestring
-    :ivar repository_credential: Credentials for accessing the repository
-    :vartype repository_credential: {basestring: basestring}
-    :ivar properties: Associated parameters
-    :vartype properties: {basestring: :class:`Property`}
-    :ivar node_template: Containing node template
-    :vartype node_template: :class:`NodeTemplate`
-    :ivar artifacts: Instantiated artifacts
-    :vartype artifacts: [:class:`Artifact`]
+    Template for creating an :class:`Artifact` instance, which is a typed file, either provided in a
+    CSAR or downloaded from a repository.
     """
 
     __tablename__ = 'artifact_template'
 
-    __private_fields__ = ['type_fk',
-                          'node_template_fk']
+    __private_fields__ = ('type_fk',
+                          'node_template_fk')
+
+    # region association proxies
+
+    # endregion
+
+    # region one_to_one relationships
+
+    # endregion
+
+    # region one_to_many relationships
+
+    @declared_attr
+    def artifacts(cls):
+        """
+        Instantiated artifacts.
+
+        :type: [:class:`Artifact`]
+        """
+        return relationship.one_to_many(cls, 'artifact')
+
+    @declared_attr
+    def properties(cls):
+        """
+        Declarations for associated immutable parameters.
+
+        :type: {:obj:`basestring`: :class:`Property`}
+        """
+        return relationship.one_to_many(cls, 'property', dict_key='name')
+
+    # endregion
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def node_template(cls):
+        """
+        Containing node template.
+
+        :type: :class:`NodeTemplate`
+        """
+        return relationship.many_to_one(cls, 'node_template')
+
+    @declared_attr
+    def type(cls):
+        """
+        Artifact type.
+
+        :type: :class:`Type`
+        """
+        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
 
     # region foreign keys
 
@@ -1960,43 +2242,35 @@
 
     # endregion
 
-    # region association proxies
+    description = Column(Text, doc="""
+    Human-readable description.
 
-    # endregion
+    :type: :obj:`basestring`
+    """)
 
-    # region one_to_one relationships
+    source_path = Column(Text, doc="""
+    Source path (in CSAR or repository).
 
-    # endregion
+    :type: :obj:`basestring`
+    """)
 
-    # region one_to_many relationships
+    target_path = Column(Text, doc="""
+    Path at which to install at destination.
 
-    @declared_attr
-    def artifacts(cls):
-        return relationship.one_to_many(cls, 'artifact')
+    :type: :obj:`basestring`
+    """)
 
-    @declared_attr
-    def properties(cls):
-        return relationship.one_to_many(cls, 'property', dict_key='name')
+    repository_url = Column(Text, doc="""
+    Repository URL.
 
-    # endregion
+    :type: :obj:`basestring`
+    """)
 
-    # region many_to_one relationships
+    repository_credential = Column(modeling_types.StrictDict(basestring, basestring), doc="""
+    Credentials for accessing the repository.
 
-    @declared_attr
-    def node_template(cls):
-        return relationship.many_to_one(cls, 'node_template')
-
-    @declared_attr
-    def type(cls):
-        return relationship.many_to_one(cls, 'type', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
-    description = Column(Text)
-    source_path = Column(Text)
-    target_path = Column(Text)
-    repository_url = Column(Text)
-    repository_credential = Column(modeling_types.StrictDict(basestring, basestring))
+    :type: {:obj:`basestring`, :obj:`basestring`}
+    """)
 
     @property
     def as_raw(self):
@@ -2050,25 +2324,49 @@
 
 class PluginSpecificationBase(TemplateModelMixin):
     """
-    Plugin specification.
+    Requirement for a :class:`Plugin`.
 
-    :ivar name: Required plugin name
-    :vartype name: basestring
-    :ivar version: Minimum plugin version
-    :vartype version: basestring
-    :ivar enabled: Whether the plugin is enabled
-    :vartype enabled: bool
-    :ivar plugin: The matching plugin (or None if not matched)
-    :vartype plugin: :class:`Plugin`
+    The actual plugin to be selected depends on those currently installed in ARIA.
     """
 
     __tablename__ = 'plugin_specification'
 
-    __private_fields__ = ['service_template_fk',
-                          'plugin_fk']
+    __private_fields__ = ('service_template_fk',
+                          'plugin_fk')
 
-    version = Column(Text)
-    enabled = Column(Boolean, nullable=False, default=True)
+    version = Column(Text, doc="""
+    Minimum plugin version.
+
+    :type: :obj:`basestring`
+    """)
+
+    enabled = Column(Boolean, nullable=False, default=True, doc="""
+    Whether the plugin is enabled.
+
+    :type: :obj:`bool`
+    """)
+
+    # region many_to_one relationships
+
+    @declared_attr
+    def service_template(cls):
+        """
+        Containing service template.
+
+        :type: :class:`ServiceTemplate`
+        """
+        return relationship.many_to_one(cls, 'service_template')
+
+    @declared_attr
+    def plugin(cls): # pylint: disable=method-hidden
+        """
+        Matched plugin.
+
+        :type: :class:`Plugin`
+        """
+        return relationship.many_to_one(cls, 'plugin', back_populates=relationship.NO_BACK_POP)
+
+    # endregion
 
     # region foreign keys
 
@@ -2084,18 +2382,6 @@
 
     # endregion
 
-    # region many_to_one relationships
-
-    @declared_attr
-    def service_template(cls):
-        return relationship.many_to_one(cls, 'service_template')
-
-    @declared_attr
-    def plugin(cls): # pylint: disable=method-hidden
-        return relationship.many_to_one(cls, 'plugin', back_populates=relationship.NO_BACK_POP)
-
-    # endregion
-
     @property
     def as_raw(self):
         return collections.OrderedDict((
diff --git a/aria/modeling/types.py b/aria/modeling/types.py
index 920a0c2..c34326e 100644
--- a/aria/modeling/types.py
+++ b/aria/modeling/types.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Allows JSON-serializable collections to be used as SQLAlchemy column types.
+"""
+
 import json
 from collections import namedtuple
 
@@ -52,12 +56,18 @@
 
 
 class Dict(_MutableType):
+    """
+    JSON-serializable dict type for SQLAlchemy columns.
+    """
     @property
     def python_type(self):
         return dict
 
 
 class List(_MutableType):
+    """
+    JSON-serializable list type for SQLAlchemy columns.
+    """
     @property
     def python_type(self):
         return list
@@ -67,7 +77,9 @@
 
     @classmethod
     def coerce(cls, key, value):
-        "Convert plain dictionaries to MutableDict."
+        """
+        Convert plain dictionaries to MutableDict.
+        """
         try:
             if not isinstance(value, cls):
                 if isinstance(value, dict):
@@ -117,7 +129,9 @@
 
     @classmethod
     def coerce(cls, key, value):
-        "Convert plain dictionaries to MutableDict."
+        """
+        Convert plain dictionaries to MutableDict.
+        """
         try:
             return mutable.MutableDict.coerce(key, value)
         except ValueError as e:
@@ -142,7 +156,9 @@
             raise exceptions.ValueFormatException('could not coerce to MutableDict', cause=e)
 
     def __setitem__(self, index, value):
-        """Detect list set events and emit change events."""
+        """
+        Detect list set events and emit change events.
+        """
         self._assert_item(value)
         super(_StrictListMixin, self).__setitem__(index, value)
 
@@ -169,7 +185,9 @@
 
     @classmethod
     def coerce(cls, key, value):
-        "Convert plain dictionaries to MutableDict."
+        """
+        Convert plain dictionaries to MutableDict.
+        """
         try:
             return mutable.MutableList.coerce(key, value)
         except ValueError as e:
@@ -181,9 +199,9 @@
 
 class _StrictDict(object):
     """
-    This entire class functions as a factory for strict dicts and their listeners.
-    No type class, and no listener type class is created more than once. If a relevant type class
-    exists it is returned.
+    This entire class functions as a factory for strict dicts and their listeners. No type class,
+    and no listener type class is created more than once. If a relevant type class exists it is
+    returned.
     """
     _strict_map = {}
 
@@ -216,13 +234,19 @@
 
 
 StrictDict = _StrictDict()
+"""
+JSON-serializable strict dict type for SQLAlchemy columns.
+
+:param key_cls:
+:param value_cls:
+"""
 
 
 class _StrictList(object):
     """
-    This entire class functions as a factory for strict lists and their listeners.
-    No type class, and no listener type class is created more than once. If a relevant type class
-    exists it is returned.
+    This entire class functions as a factory for strict lists and their listeners. No type class,
+    and no listener type class is created more than once. If a relevant type class exists it is
+    returned.
     """
     _strict_map = {}
 
@@ -254,6 +278,11 @@
 
 
 StrictList = _StrictList()
+"""
+JSON-serializable strict list type for SQLAlchemy columns.
+
+:param item_cls:
+"""
 
 
 def _mutable_association_listener(mapper, cls):
diff --git a/aria/modeling/utils.py b/aria/modeling/utils.py
index 43be410..5193cd9 100644
--- a/aria/modeling/utils.py
+++ b/aria/modeling/utils.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Miscellaneous modeling utilities.
+"""
+
 import os
 from json import JSONEncoder
 from StringIO import StringIO
@@ -26,6 +30,13 @@
 
 
 class ModelJSONEncoder(JSONEncoder):
+    """
+    JSON encoder that automatically unwraps ``value`` attributes.
+    """
+    def __init__(self, *args, **kwargs):
+        # Just here to make sure Sphinx doesn't grab the base constructor's docstring
+        super(ModelJSONEncoder, self).__init__(*args, **kwargs)
+
     def default(self, o):  # pylint: disable=method-hidden
         from .mixins import ModelMixin
         if isinstance(o, ModelMixin):
@@ -40,8 +51,8 @@
 
 class NodeTemplateContainerHolder(object):
     """
-    Wrapper that allows using a :class:`aria.modeling.models.NodeTemplate` model directly as the
-    ``container_holder`` input for :func:`aria.modeling.functions.evaluate`.
+    Wrapper that allows using a :class:`~aria.modeling.models.NodeTemplate` model directly as the
+    ``container_holder`` input for :func:`~aria.modeling.functions.evaluate`.
     """
 
     def __init__(self, node_template):
@@ -60,18 +71,17 @@
     Exceptions will be raised for validation errors.
 
     :param parameter_values: provided parameter values or None
-    :type parameter_values: {basestring, object}
+    :type parameter_values: {:obj:`basestring`: object}
     :param declared_parameters: declared parameters
-    :type declared_parameters: {basestring, :class:`aria.modeling.models.Parameter`}
+    :type declared_parameters: {:obj:`basestring`: :class:`~aria.modeling.models.Parameter`}
     :return: the merged parameters
-    :rtype: {basestring, :class:`aria.modeling.models.Parameter`}
-    :raises aria.modeling.exceptions.UndeclaredParametersException: if a key in ``parameter_values``
-            does not exist in ``declared_parameters``
-    :raises aria.modeling.exceptions.MissingRequiredParametersException: if a key in
-            ``declared_parameters`` does not exist in ``parameter_values`` and also has no default
-            value
-    :raises aria.modeling.exceptions.ParametersOfWrongTypeException: if a value in
-            ``parameter_values`` does not match its type in ``declared_parameters``
+    :rtype: {:obj:`basestring`: :class:`~aria.modeling.models.Parameter`}
+    :raises ~aria.modeling.exceptions.UndeclaredParametersException: if a key in
+     ``parameter_values`` does not exist in ``declared_parameters``
+    :raises ~aria.modeling.exceptions.MissingRequiredParametersException: if a key in
+     ``declared_parameters`` does not exist in ``parameter_values`` and also has no default value
+    :raises ~aria.modeling.exceptions.ParametersOfWrongTypeException: if a value in
+      ``parameter_values`` does not match its type in ``declared_parameters``
     """
 
     parameter_values = parameter_values or {}
@@ -204,6 +214,22 @@
 class classproperty(object):                                                                        # pylint: disable=invalid-name
     def __init__(self, f):
         self._func = f
+        self.__doct__ = f.__doc__
 
     def __get__(self, instance, owner):
         return self._func(owner)
+
+
+def fix_doc(cls):
+    """
+    Class decorator to use the last base class's docstring and make sure Sphinx doesn't grab the
+    base constructor's docstring.
+    """
+    original_init = cls.__init__
+    def init(*args, **kwargs):
+        original_init(*args, **kwargs)
+
+    cls.__init__ = init
+    cls.__doc__ = cls.__bases__[-1].__doc__
+
+    return cls
diff --git a/aria/orchestrator/__init__.py b/aria/orchestrator/__init__.py
index b855aed..24fee9e 100644
--- a/aria/orchestrator/__init__.py
+++ b/aria/orchestrator/__init__.py
@@ -12,9 +12,11 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
 """
-ARIA orchestrator
+Orchestrator package.
 """
+
 from .decorators import (
     workflow,
     operation,
diff --git a/aria/orchestrator/context/__init__.py b/aria/orchestrator/context/__init__.py
index ad89b13..a87828d 100644
--- a/aria/orchestrator/context/__init__.py
+++ b/aria/orchestrator/context/__init__.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Provides contexts to workflow and operation
+Contexts for workflows and operations.
 """
 
 from . import workflow, operation
diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py
index f4df317..f400142 100644
--- a/aria/orchestrator/context/common.py
+++ b/aria/orchestrator/context/common.py
@@ -14,8 +14,9 @@
 # limitations under the License.
 
 """
-A common context for both workflow and operation
+Common code for contexts.
 """
+
 import logging
 from contextlib import contextmanager
 from functools import partial
@@ -33,7 +34,7 @@
 
 class BaseContext(object):
     """
-    Base context object for workflow and operation
+    Base class for contexts.
     """
 
     INSTRUMENTATION_FIELDS = (
@@ -109,52 +110,48 @@
     @property
     def model(self):
         """
-        Access to the model storage
-        :return:
+        Storage model API ("MAPI").
         """
         return self._model
 
     @property
     def resource(self):
         """
-        Access to the resource storage
-        :return:
+        Storage resource API ("RAPI").
         """
         return self._resource
 
     @property
     def service_template(self):
         """
-        The blueprint model
+        Service template model.
         """
         return self.service.service_template
 
     @property
     def service(self):
         """
-        The deployment model
+        Service instance model.
         """
         return self.model.service.get(self._service_id)
 
     @property
     def name(self):
         """
-        The operation name
-        :return:
+        Operation name.
         """
         return self._name
 
     @property
     def id(self):
         """
-        The operation id
-        :return:
+        Operation ID.
         """
         return self._id
 
     def download_resource(self, destination, path=None):
         """
-        Download a blueprint resource from the resource storage
+        Download a service template resource from the storage resource API ("RAPI").
         """
         try:
             self.resource.service.download(entry_id=str(self.service.id),
@@ -167,9 +164,9 @@
 
     def download_resource_and_render(self, destination, path=None, variables=None):
         """
-        Download a blueprint resource from the resource storage render its content as a jinja
-        template using the provided variables. ctx is available to the template without providing it
-        explicitly.
+        Downloads a service template resource from the resource storage and renders its content as a
+        Jinja template using the provided variables. ``ctx`` is available to the template without
+        providing it explicitly.
         """
         resource_content = self.get_resource(path=path)
         resource_content = self._render_resource(resource_content=resource_content,
@@ -179,7 +176,7 @@
 
     def get_resource(self, path=None):
         """
-        Read a deployment resource as string from the resource storage
+        Reads a service instance resource as string from the resource storage.
         """
         try:
             return self.resource.service.read(entry_id=str(self.service.id), path=path)
@@ -189,9 +186,9 @@
 
     def get_resource_and_render(self, path=None, variables=None):
         """
-        Read a deployment resource as string from the resource storage and render it as a jinja
-        template using the provided variables. ctx is available to the template without providing it
-        explicitly.
+        Reads a service instance resource as string from the resource storage and renders it as a
+        Jinja template using the provided variables. ``ctx`` is available to the template without
+        providing it explicitly.
         """
         resource_content = self.get_resource(path=path)
         return self._render_resource(resource_content=resource_content, variables=variables)
diff --git a/aria/orchestrator/context/exceptions.py b/aria/orchestrator/context/exceptions.py
index fe762e1..e46e2b1 100644
--- a/aria/orchestrator/context/exceptions.py
+++ b/aria/orchestrator/context/exceptions.py
@@ -12,9 +12,11 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
 """
-Context based exceptions
+Context exceptions.
 """
+
 from ..exceptions import OrchestratorError
 
 
diff --git a/aria/orchestrator/context/operation.py b/aria/orchestrator/context/operation.py
index d43b847..7d5f40c 100644
--- a/aria/orchestrator/context/operation.py
+++ b/aria/orchestrator/context/operation.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Workflow and operation contexts
+Operation contexts.
 """
 
 import threading
@@ -27,7 +27,7 @@
 
 class BaseOperationContext(common.BaseContext):
     """
-    Context object used during operation creation and execution
+    Base class for contexts used during operation creation and execution.
     """
 
     def __init__(self, task_id, actor_id, **kwargs):
@@ -116,7 +116,7 @@
 
 class NodeOperationContext(BaseOperationContext):
     """
-    Context for node based operations.
+    Context for node operations.
     """
 
     @property
@@ -138,7 +138,7 @@
 
 class RelationshipOperationContext(BaseOperationContext):
     """
-    Context for relationship based operations.
+    Context for relationship operations.
     """
 
     @property
diff --git a/aria/orchestrator/context/toolbelt.py b/aria/orchestrator/context/toolbelt.py
index b5a54a9..a2e1122 100644
--- a/aria/orchestrator/context/toolbelt.py
+++ b/aria/orchestrator/context/toolbelt.py
@@ -12,8 +12,9 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
 """
-Provides with different tools for operations.
+Tools for operations.
 """
 
 from . import operation
@@ -21,7 +22,7 @@
 
 class NodeToolBelt(object):
     """
-    Node operation related tool belt
+    Node operation tool belt.
     """
     def __init__(self, operation_context):
         self._op_context = operation_context
@@ -38,7 +39,7 @@
 
 class RelationshipToolBelt(object):
     """
-    Relationship operation related tool belt
+    Relationship operation tool belt.
     """
     def __init__(self, operation_context):
         self._op_context = operation_context
@@ -46,9 +47,9 @@
 
 def toolbelt(operation_context):
     """
-    Get a toolbelt according to the current operation executor
+    Get a toolbelt from to the current operation executor.
+
     :param operation_context:
-    :return:
     """
     if isinstance(operation_context, operation.NodeOperationContext):
         return NodeToolBelt(operation_context)
diff --git a/aria/orchestrator/context/workflow.py b/aria/orchestrator/context/workflow.py
index 18334f3..738d2fd 100644
--- a/aria/orchestrator/context/workflow.py
+++ b/aria/orchestrator/context/workflow.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Workflow and operation contexts
+Workflow context.
 """
 
 import threading
@@ -26,7 +26,7 @@
 
 class WorkflowContext(BaseContext):
     """
-    Context object used during workflow creation and execution
+    Context used during workflow creation and execution.
     """
     def __init__(self,
                  workflow_name,
@@ -57,21 +57,21 @@
     @property
     def execution(self):
         """
-        The execution model
+        Execution model.
         """
         return self.model.execution.get(self._execution_id)
 
     @execution.setter
     def execution(self, value):
         """
-        Store the execution in the model storage
+        Stores the execution in the storage model API ("MAPI").
         """
         self.model.execution.put(value)
 
     @property
     def node_templates(self):
         """
-        Iterator over nodes
+        Iterates over nodes templates.
         """
         key = 'service_{0}'.format(self.model.node_template.model_cls.name_column_name())
 
@@ -84,7 +84,7 @@
     @property
     def nodes(self):
         """
-        Iterator over node instances
+        Iterates over nodes.
         """
         key = 'service_{0}'.format(self.model.node.model_cls.name_column_name())
         return self.model.node.iter(
@@ -102,7 +102,7 @@
 
 class _CurrentContext(threading.local):
     """
-    Provides thread-level context, which sugarcoats the task mapi.
+    Provides a thread-level context, with sugar for the task MAPI.
     """
 
     def __init__(self):
@@ -114,9 +114,7 @@
 
     def get(self):
         """
-        Retrieves the current workflow context
-        :return: the workflow context
-        :rtype: WorkflowContext
+        Retrieves the current workflow context.
         """
         if self._workflow_context is not None:
             return self._workflow_context
@@ -125,9 +123,7 @@
     @contextmanager
     def push(self, workflow_context):
         """
-        Switches the current context to the provided context
-        :param workflow_context: the context to switch to.
-        :yields: the current context
+        Switches the current context to the provided context.
         """
         prev_workflow_context = self._workflow_context
         self._set(workflow_context)
diff --git a/aria/orchestrator/decorators.py b/aria/orchestrator/decorators.py
index 389bfb8..4b163d6 100644
--- a/aria/orchestrator/decorators.py
+++ b/aria/orchestrator/decorators.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Workflow and operation decorators
+Workflow and operation decorators.
 """
 
 from functools import partial, wraps
@@ -32,7 +32,7 @@
 
 def workflow(func=None, suffix_template=''):
     """
-    Workflow decorator
+    Workflow decorator.
     """
     if func is None:
         return partial(workflow, suffix_template=suffix_template)
@@ -58,7 +58,7 @@
 
 def operation(func=None, toolbelt=False, suffix_template='', logging_handlers=None):
     """
-    Operation decorator
+    Operation decorator.
     """
 
     if func is None:
diff --git a/aria/orchestrator/events.py b/aria/orchestrator/events.py
index aa1b5bc..ef84e5d 100644
--- a/aria/orchestrator/events.py
+++ b/aria/orchestrator/events.py
@@ -14,10 +14,7 @@
 # limitations under the License.
 
 """
-ARIA's events Sub-Package
-Path: aria.events
-
-Events package provides events mechanism for different executions in aria.
+Orchestrator events.
 """
 
 from blinker import signal
diff --git a/aria/orchestrator/exceptions.py b/aria/orchestrator/exceptions.py
index 71b6401..384458f 100644
--- a/aria/orchestrator/exceptions.py
+++ b/aria/orchestrator/exceptions.py
@@ -12,9 +12,11 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
 """
-Orchestrator based exceptions
+Orchestrator exceptions.
 """
+
 from aria.exceptions import AriaError
 
 
diff --git a/aria/orchestrator/execution_plugin/__init__.py b/aria/orchestrator/execution_plugin/__init__.py
index 3624264..d15de99 100644
--- a/aria/orchestrator/execution_plugin/__init__.py
+++ b/aria/orchestrator/execution_plugin/__init__.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Execution plugin package.
+"""
+
 from contextlib import contextmanager
 from . import instantiation
 
diff --git a/aria/orchestrator/execution_plugin/common.py b/aria/orchestrator/execution_plugin/common.py
index 32e4575..ce6746c 100644
--- a/aria/orchestrator/execution_plugin/common.py
+++ b/aria/orchestrator/execution_plugin/common.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Execution plugin utilities.
+"""
+
 import json
 import os
 import tempfile
@@ -52,21 +56,23 @@
 
 def create_process_config(script_path, process, operation_kwargs, quote_json_env_vars=False):
     """
-    update a process with it's environment variables, and return it.
+    Updates a process with its environment variables, and return it.
 
-    Get a dict representing a process and a dict representing the environment
-    variables. Convert each environment variable to a format of
-    <string representing the name of the variable> :
-    <json formatted string representing the value of the variable>.
-    Finally, update the process with the newly formatted environment variables,
-    and return the process.
+    Gets a dict representing a process and a dict representing the environment variables. Converts
+    each environment variable to a format of::
 
-    :param process: a dict representing a process
+        <string representing the name of the variable>:
+        <json formatted string representing the value of the variable>.
+
+    Finally, updates the process with the newly formatted environment variables, and return the
+    process.
+
+    :param process: dict representing a process
     :type process: dict
-    :param operation_kwargs: a dict representing environment variables that
-    should exist in the process' running environment.
+    :param operation_kwargs: dict representing environment variables that should exist in the
+     process's running environment.
     :type operation_kwargs: dict
-    :return: the process updated with its environment variables.
+    :return: process updated with its environment variables
     :rtype: dict
     """
     process = process or {}
diff --git a/aria/orchestrator/execution_plugin/constants.py b/aria/orchestrator/execution_plugin/constants.py
index 0b54dbe..8082e95 100644
--- a/aria/orchestrator/execution_plugin/constants.py
+++ b/aria/orchestrator/execution_plugin/constants.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Execution plugin constants.
+"""
+
 from . import exceptions
 
 # related to local
diff --git a/aria/orchestrator/execution_plugin/ctx_proxy/__init__.py b/aria/orchestrator/execution_plugin/ctx_proxy/__init__.py
index 7571c15..46c8cf1 100644
--- a/aria/orchestrator/execution_plugin/ctx_proxy/__init__.py
+++ b/aria/orchestrator/execution_plugin/ctx_proxy/__init__.py
@@ -13,4 +13,8 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+``ctx`` proxy.
+"""
+
 from . import server, client
diff --git a/aria/orchestrator/execution_plugin/ctx_proxy/client.py b/aria/orchestrator/execution_plugin/ctx_proxy/client.py
index f7f56aa..1310c21 100644
--- a/aria/orchestrator/execution_plugin/ctx_proxy/client.py
+++ b/aria/orchestrator/execution_plugin/ctx_proxy/client.py
@@ -14,6 +14,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+``ctx`` proxy client implementation.
+"""
+
 import argparse
 import json
 import os
diff --git a/aria/orchestrator/execution_plugin/ctx_proxy/server.py b/aria/orchestrator/execution_plugin/ctx_proxy/server.py
index 50d4c3a..0a2a606 100644
--- a/aria/orchestrator/execution_plugin/ctx_proxy/server.py
+++ b/aria/orchestrator/execution_plugin/ctx_proxy/server.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+``ctx`` proxy server implementation.
+"""
+
 import collections
 import json
 import re
diff --git a/aria/orchestrator/execution_plugin/environment_globals.py b/aria/orchestrator/execution_plugin/environment_globals.py
index 27311f0..6dec293 100644
--- a/aria/orchestrator/execution_plugin/environment_globals.py
+++ b/aria/orchestrator/execution_plugin/environment_globals.py
@@ -13,41 +13,38 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Utilities for managing globals for the environment.
+"""
 
 def create_initial_globals(path):
-    """ emulates a `globals()` call in a freshly loaded module
+    """
+    Emulates a ``globals()`` call in a freshly loaded module.
 
-    The implementation of this function is likely to raise a couple of
-    questions. If you read the implementation and nothing bothered you, feel
-    free to skip the rest of this docstring.
+    The implementation of this function is likely to raise a couple of questions. If you read the
+    implementation and nothing bothered you, feel free to skip the rest of this docstring.
 
-    First, why is this function in its own module and not, say, in the same
-    module of the other environment-related functions?
-    Second, why is it implemented in such a way that copies the globals, then
-    deletes the item that represents this function, and then changes some
-    other entries?
+    First, why is this function in its own module and not, say, in the same module of the other
+    environment-related functions? Second, why is it implemented in such a way that copies the
+    globals, then deletes the item that represents this function, and then changes some other
+    entries?
 
-    Well, these two questions can be answered with one (elaborate) explanation.
-    If this function was in the same module with the other environment-related
-    functions, then we would have had to delete more items in globals than just
-    `create_initial_globals`. That is because all of the other function names
-    would also be in globals, and since there is no built-in mechanism that
-    return the name of the user-defined objects, this approach is quite an
-    overkill.
+    Well, these two questions can be answered with one (elaborate) explanation. If this function was
+    in the same module with the other environment-related functions, then we would have had to
+    delete more items in globals than just ``create_initial_globals``. That is because all of the
+    other function names would also be in globals, and since there is no built-in mechanism that
+    return the name of the user-defined objects, this approach is quite an overkill.
 
-    - But why do we rely on the copy-existing-globals-and-delete-entries
-    method, when it seems to force us to put `create_initial_globals` in its
-    own file?
+    *But why do we rely on the copy-existing-globals-and-delete-entries method, when it seems to
+    force us to put ``create_initial_globals`` in its own file?*
 
-    Well, because there is no easier method of creating globals of a newly
-    loaded module.
+    Well, because there is no easier method of creating globals of a newly loaded module.
 
-    - How about hard coding a 'global' dict? It seems that there are very few
-    entries: __doc__, __file__, __name__, __package__ (but don't forget
-    __builtins__).
+    *How about hard coding a ``globals`` dict? It seems that there are very few entries:
+    ``__doc__``, ``__file__``, ``__name__``, ``__package__`` (but don't forget ``__builtins__``).*
 
-    That would be coupling our implementation to a specific `globals`
-    implementation. What if `globals` were to change?
+    That would be coupling our implementation to a specific ``globals`` implementation. What if
+    ``globals`` were to change?
     """
     copied_globals = globals().copy()
     copied_globals.update({
diff --git a/aria/orchestrator/execution_plugin/exceptions.py b/aria/orchestrator/execution_plugin/exceptions.py
index 4641c80..f201fae 100644
--- a/aria/orchestrator/execution_plugin/exceptions.py
+++ b/aria/orchestrator/execution_plugin/exceptions.py
@@ -13,9 +13,14 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Execution plugin exceptions.
+"""
 
 class ProcessException(Exception):
-    """Raised when local scripts and remote ssh commands fail"""
+    """
+    Raised when local scripts and remote SSH commands fail.
+    """
 
     def __init__(self, stderr=None, stdout=None, command=None, exit_code=None):
         super(ProcessException, self).__init__(stderr)
@@ -26,11 +31,15 @@
 
 
 class TaskException(Exception):
-    """Raised when remote ssh scripts fail"""
+    """
+    Raised when remote ssh scripts fail.
+    """
 
 
 class ScriptException(Exception):
-    """Used by the ctx proxy server when task.retry or task.abort are called by scripts"""
+    """
+    Used by the ``ctx`` proxy server when task.retry or task.abort are called by scripts.
+    """
 
     def __init__(self, message=None, retry=None, retry_interval=None):
         super(ScriptException, self).__init__(message)
diff --git a/aria/orchestrator/execution_plugin/instantiation.py b/aria/orchestrator/execution_plugin/instantiation.py
index b067e8c..f55aa50 100644
--- a/aria/orchestrator/execution_plugin/instantiation.py
+++ b/aria/orchestrator/execution_plugin/instantiation.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Instantiation of :class:`~aria.modeling.models.Operation` models.
+"""
+
 # TODO: this module will eventually be moved to a new "aria.instantiation" package
 
 from ...utils.type import full_type_name
diff --git a/aria/orchestrator/execution_plugin/local.py b/aria/orchestrator/execution_plugin/local.py
index 121e582..04b9ecd 100644
--- a/aria/orchestrator/execution_plugin/local.py
+++ b/aria/orchestrator/execution_plugin/local.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Local execution of operations.
+"""
+
 import os
 import subprocess
 import threading
diff --git a/aria/orchestrator/execution_plugin/operations.py b/aria/orchestrator/execution_plugin/operations.py
index 0bc8083..e8de545 100644
--- a/aria/orchestrator/execution_plugin/operations.py
+++ b/aria/orchestrator/execution_plugin/operations.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Entry point functions.
+"""
+
 from aria.orchestrator import operation
 from . import local as local_operations
 
diff --git a/aria/orchestrator/execution_plugin/ssh/__init__.py b/aria/orchestrator/execution_plugin/ssh/__init__.py
index ae1e83e..474deef 100644
--- a/aria/orchestrator/execution_plugin/ssh/__init__.py
+++ b/aria/orchestrator/execution_plugin/ssh/__init__.py
@@ -12,3 +12,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+"""
+Remote execution of operations over SSH.
+"""
diff --git a/aria/orchestrator/execution_plugin/ssh/operations.py b/aria/orchestrator/execution_plugin/ssh/operations.py
index 7147a30..c40e783 100644
--- a/aria/orchestrator/execution_plugin/ssh/operations.py
+++ b/aria/orchestrator/execution_plugin/ssh/operations.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Utilities for running commands remotely over SSH.
+"""
+
 import os
 import random
 import string
diff --git a/aria/orchestrator/plugin.py b/aria/orchestrator/plugin.py
index 8fbcf5a..756a28e 100644
--- a/aria/orchestrator/plugin.py
+++ b/aria/orchestrator/plugin.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Plugin management.
+"""
+
 import os
 import tempfile
 import subprocess
@@ -32,7 +36,7 @@
 
     def __init__(self, model, plugins_dir):
         """
-        :param plugins_dir: Root directory to install plugins in.
+        :param plugins_dir: root directory in which to install plugins
         """
         self._model = model
         self._plugins_dir = plugins_dir
@@ -72,10 +76,13 @@
     def load_plugin(self, plugin, env=None):
         """
         Load the plugin into an environment.
+
         Loading the plugin means the plugin's code and binaries paths will be appended to the
-        environment's PATH and PYTHONPATH, thereby allowing usage of the plugin.
-        :param plugin: The plugin to load
-        :param env: The environment to load the plugin into; If `None`, os.environ will be used.
+        environment's ``PATH`` and ``PYTHONPATH``, thereby allowing usage of the plugin.
+
+        :param plugin: plugin to load
+        :param env: environment to load the plugin into; If ``None``, :obj:`os.environ` will be
+         used
         """
         env = env or os.environ
         plugin_dir = self.get_plugin_dir(plugin)
@@ -106,9 +113,10 @@
     @staticmethod
     def validate_plugin(source):
         """
-        validate a plugin archive.
-        A valid plugin is a wagon (http://github.com/cloudify-cosmo/wagon)
-        in the zip format (suffix may also be .wgn).
+        Validate a plugin archive.
+
+        A valid plugin is a `wagon <http://github.com/cloudify-cosmo/wagon>`__ in the zip format
+        (suffix may also be ``.wgn``).
         """
         if not zipfile.is_zipfile(source):
             raise exceptions.InvalidPluginError(
diff --git a/aria/orchestrator/workflow_runner.py b/aria/orchestrator/workflow_runner.py
index 3d58386..df1725f 100644
--- a/aria/orchestrator/workflow_runner.py
+++ b/aria/orchestrator/workflow_runner.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Workflow runner
+Running workflows.
 """
 
 import os
@@ -44,15 +44,16 @@
         """
         Manages a single workflow execution on a given service.
 
-        :param workflow_name: Workflow name
-        :param service_id: Service ID
-        :param inputs: A key-value dict of inputs for the execution
-        :param model_storage: Model storage
-        :param resource_storage: Resource storage
-        :param plugin_manager: Plugin manager
-        :param executor: Executor for tasks. Defaults to a ProcessExecutor instance.
-        :param task_max_attempts: Maximum attempts of repeating each failing task
-        :param task_retry_interval: Retry interval in between retry attempts of a failing task
+        :param workflow_name: workflow name
+        :param service_id: service ID
+        :param inputs: key-value dict of inputs for the execution
+        :param model_storage: model storage API ("MAPI")
+        :param resource_storage: resource storage API ("RAPI")
+        :param plugin_manager: plugin manager
+        :param executor: executor for tasks; defaults to a
+         :class:`~aria.orchestrator.workflows.executor.process.ProcessExecutor` instance
+        :param task_max_attempts: maximum attempts of repeating each failing task
+        :param task_retry_interval: retry interval between retry attempts of a failing task
         """
 
         if not (execution_id or (workflow_name and service_id)):
diff --git a/aria/orchestrator/workflows/__init__.py b/aria/orchestrator/workflows/__init__.py
index e0c979a..1f6c368 100644
--- a/aria/orchestrator/workflows/__init__.py
+++ b/aria/orchestrator/workflows/__init__.py
@@ -13,5 +13,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Workflows package.
+"""
+
 # Import required so that logging signals are registered
 from . import events_logging
diff --git a/aria/orchestrator/workflows/api/__init__.py b/aria/orchestrator/workflows/api/__init__.py
index a3a17ee..587eee3 100644
--- a/aria/orchestrator/workflows/api/__init__.py
+++ b/aria/orchestrator/workflows/api/__init__.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Provides API for building tasks
+Workflow API.
 """
 
 from . import task, task_graph
diff --git a/aria/orchestrator/workflows/api/task.py b/aria/orchestrator/workflows/api/task.py
index f7d2c66..4c518fc 100644
--- a/aria/orchestrator/workflows/api/task.py
+++ b/aria/orchestrator/workflows/api/task.py
@@ -26,7 +26,7 @@
 
 class BaseTask(object):
     """
-    Abstract task graph task
+    Base class for tasks.
     """
 
     def __init__(self, ctx=None, **kwargs):
@@ -39,44 +39,43 @@
     @property
     def id(self):
         """
-        uuid4 generated id
-        :return:
+        UUID4 ID.
         """
         return self._id
 
     @property
     def workflow_context(self):
         """
-        the context of the current workflow
-        :return:
+        Context of the current workflow.
         """
         return self._workflow_context
 
 
 class OperationTask(BaseTask):
     """
-    Represents an operation task in the task graph.
+    Executes an operation.
 
     :ivar name: formatted name (includes actor type, actor name, and interface/operation names)
     :vartype name: basestring
     :ivar actor: node or relationship
-    :vartype actor: :class:`aria.modeling.models.Node`|:class:`aria.modeling.models.Relationship`
+    :vartype actor: :class:`~aria.modeling.models.Node` or
+     :class:`~aria.modeling.models.Relationship`
     :ivar interface_name: interface name on actor
     :vartype interface_name: basestring
     :ivar operation_name: operation name on interface
     :vartype operation_name: basestring
     :ivar plugin: plugin (or None for default plugin)
-    :vartype plugin: :class:`aria.modeling.models.Plugin`
+    :vartype plugin: :class:`~aria.modeling.models.Plugin`
     :ivar function: path to Python function
     :vartype function: basestring
     :ivar arguments: arguments to send to Python function
-    :vartype arguments: {basestring, :class:`aria.modeling.models.Argument`}
+    :vartype arguments: {:obj:`basestring`: :class:`~aria.modeling.models.Argument`}
     :ivar ignore_failure: whether to ignore failures
     :vartype ignore_failure: bool
     :ivar max_attempts: maximum number of attempts allowed in case of failure
     :vartype max_attempts: int
     :ivar retry_interval: interval between retries (in seconds)
-    :vartype retry_interval: int
+    :vartype retry_interval: float
     """
 
     NAME_FORMAT = '{interface}:{operation}@{type}:{name}'
@@ -91,21 +90,22 @@
                  retry_interval=None):
         """
         :param actor: node or relationship
-        :type actor: :class:`aria.modeling.models.Node`|:class:`aria.modeling.models.Relationship`
+        :type actor: :class:`~aria.modeling.models.Node` or
+         :class:`~aria.modeling.models.Relationship`
         :param interface_name: interface name on actor
         :type interface_name: basestring
         :param operation_name: operation name on interface
         :type operation_name: basestring
         :param arguments: override argument values
-        :type arguments: {basestring, object}
+        :type arguments: {:obj:`basestring`: object}
         :param ignore_failure: override whether to ignore failures
         :type ignore_failure: bool
         :param max_attempts: override maximum number of attempts allowed in case of failure
         :type max_attempts: int
         :param retry_interval: override interval between retries (in seconds)
-        :type retry_interval: int
-        :raises aria.orchestrator.workflows.exceptions.OperationNotFoundException: if
-                ``interface_name`` and ``operation_name`` to not refer to an operation on the actor
+        :type retry_interval: float
+        :raises ~aria.orchestrator.workflows.exceptions.OperationNotFoundException: if
+         ``interface_name`` and ``operation_name`` do not refer to an operation on the actor
         """
 
         # Creating OperationTask directly should raise an error when there is no
@@ -160,14 +160,13 @@
 
 class WorkflowTask(BaseTask):
     """
-    Represents a workflow task in the task graph
+    Executes a complete workflow.
     """
 
     def __init__(self, workflow_func, **kwargs):
         """
-        Creates a workflow based task using the workflow_func provided, and its kwargs
-        :param workflow_func: the function to run
-        :param kwargs: the kwargs that would be passed to the workflow_func
+        :param workflow_func: function to run
+        :param kwargs: kwargs that would be passed to the workflow_func
         """
         super(WorkflowTask, self).__init__(**kwargs)
         kwargs['ctx'] = self.workflow_context
@@ -176,8 +175,7 @@
     @property
     def graph(self):
         """
-        The graph constructed by the sub workflow
-        :return:
+        Graph constructed by the sub workflow.
         """
         return self._graph
 
@@ -190,13 +188,14 @@
 
 def create_task(actor, interface_name, operation_name, **kwargs):
     """
-    This helper function enables safe creation of OperationTask, if the supplied interface or
-    operation do not exist, None is returned.
-    :param actor: the actor for this task
-    :param interface_name: the name of the interface
-    :param operation_name: the name of the operation
-    :param kwargs: any additional kwargs to be passed to the task OperationTask
-    :return: and OperationTask or None (if the interface/operation does not exists)
+    Helper function that enables safe creation of :class:`OperationTask`. If the supplied interface
+    or operation do not exist, ``None`` is returned.
+
+    :param actor: actor for this task
+    :param interface_name: name of the interface
+    :param operation_name: name of the operation
+    :param kwargs: any additional kwargs to be passed to the OperationTask
+    :return: OperationTask or None (if the interface/operation does not exists)
     """
     try:
         return OperationTask(
@@ -212,13 +211,13 @@
 def create_relationships_tasks(
         node, interface_name, source_operation_name=None, target_operation_name=None, **kwargs):
     """
-    Creates a relationship task (source and target) for all of a node_instance relationships.
-    :param basestring source_operation_name: the relationship operation name.
-    :param basestring interface_name: the name of the interface.
+    Creates a relationship task (source and target) for all of a node relationships.
+
+    :param basestring source_operation_name: relationship operation name
+    :param basestring interface_name: name of the interface
     :param source_operation_name:
     :param target_operation_name:
-    :param NodeInstance node: the source_node
-    :return:
+    :param node: source node
     """
     sub_tasks = []
     for relationship in node.outbound_relationships:
@@ -235,12 +234,11 @@
 def create_relationship_tasks(relationship, interface_name, source_operation_name=None,
                               target_operation_name=None, **kwargs):
     """
-    Creates a relationship task source and target.
-    :param Relationship relationship: the relationship instance itself
+    Creates a relationship task (source and target).
+
+    :param relationship: relationship instance itself
     :param source_operation_name:
     :param target_operation_name:
-
-    :return:
     """
     operations = []
     if source_operation_name:
diff --git a/aria/orchestrator/workflows/api/task_graph.py b/aria/orchestrator/workflows/api/task_graph.py
index 9f0d13b..900a0d1 100644
--- a/aria/orchestrator/workflows/api/task_graph.py
+++ b/aria/orchestrator/workflows/api/task_graph.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Task graph. Used by users to build workflows
+Task graph.
 """
 
 from collections import Iterable
@@ -27,7 +27,7 @@
 
 class TaskNotInGraphError(Exception):
     """
-    An error representing a scenario where a given task is not in the graph as expected
+    An error representing a scenario where a given task is not in the graph as expected.
     """
     pass
 
@@ -43,8 +43,7 @@
 
 class TaskGraph(object):
     """
-    A tasks graph builder.
-    Build an operations flow graph
+    Task graph builder.
     """
 
     def __init__(self, name):
@@ -59,8 +58,7 @@
     @property
     def id(self):
         """
-        Represents the id of the graph
-        :return: graph id
+        ID of the graph
         """
         return self._id
 
@@ -69,27 +67,28 @@
     @property
     def tasks(self):
         """
-        An iterator on tasks added to the graph
-        :yields: Iterator over all tasks in the graph
+        Iterator over tasks in the graph.
         """
         for _, data in self._graph.nodes_iter(data=True):
             yield data['task']
 
     def topological_order(self, reverse=False):
         """
-        Returns topological sort on the graph
+        Topological sort of the graph.
+
         :param reverse: whether to reverse the sort
-        :return: a list which represents the topological sort
+        :return: list which represents the topological sort
         """
         for task_id in topological_sort(self._graph, reverse=reverse):
             yield self.get_task(task_id)
 
     def get_dependencies(self, dependent_task):
         """
-        Iterates over the task's dependencies
-        :param BaseTask dependent_task: The task whose dependencies are requested
-        :yields: Iterator over all tasks which dependency_task depends on
-        :raise: TaskNotInGraphError if dependent_task is not in the graph
+        Iterates over the task's dependencies.
+
+        :param dependent_task: task whose dependencies are requested
+        :raises ~aria.orchestrator.workflows.api.task_graph.TaskNotInGraphError: if
+         ``dependent_task`` is not in the graph
         """
         if not self.has_tasks(dependent_task):
             raise TaskNotInGraphError('Task id: {0}'.format(dependent_task.id))
@@ -98,10 +97,11 @@
 
     def get_dependents(self, dependency_task):
         """
-        Iterates over the task's dependents
-        :param BaseTask dependency_task: The task whose dependents are requested
-        :yields: Iterator over all tasks which depend on dependency_task
-        :raise: TaskNotInGraphError if dependency_task is not in the graph
+        Iterates over the task's dependents.
+
+        :param dependency_task: task whose dependents are requested
+        :raises ~aria.orchestrator.workflows.api.task_graph.TaskNotInGraphError: if
+         ``dependency_task`` is not in the graph
         """
         if not self.has_tasks(dependency_task):
             raise TaskNotInGraphError('Task id: {0}'.format(dependency_task.id))
@@ -112,11 +112,11 @@
 
     def get_task(self, task_id):
         """
-        Get a task instance that's been inserted to the graph by the task's id
-        :param basestring task_id: The task's id
-        :return: Requested task
-        :rtype: BaseTask
-        :raise: TaskNotInGraphError if no task found in the graph with the given id
+        Get a task instance that's been inserted to the graph by the task's ID.
+
+        :param basestring task_id: task ID
+        :raises ~aria.orchestrator.workflows.api.task_graph.TaskNotInGraphError: if no task found in
+         the graph with the given ID
         """
         if not self._graph.has_node(task_id):
             raise TaskNotInGraphError('Task id: {0}'.format(task_id))
@@ -126,9 +126,10 @@
     @_filter_out_empty_tasks
     def add_tasks(self, *tasks):
         """
-        Add a task to the graph
-        :param BaseTask task: The task
-        :return: A list of added tasks
+        Adds a task to the graph.
+
+        :param task: task
+        :return: list of added tasks
         :rtype: list
         """
         assert all([isinstance(task, (api_task.BaseTask, Iterable)) for task in tasks])
@@ -146,9 +147,10 @@
     @_filter_out_empty_tasks
     def remove_tasks(self, *tasks):
         """
-        Remove the provided task from the graph
-        :param BaseTask task: The task
-        :return: A list of removed tasks
+        Removes the provided task from the graph.
+
+        :param task: task
+        :return: list of removed tasks
         :rtype: list
         """
         return_tasks = []
@@ -165,9 +167,10 @@
     @_filter_out_empty_tasks
     def has_tasks(self, *tasks):
         """
-        Check whether a task is in the graph or not
-        :param BaseTask task: The task
-        :return: True if all tasks are in the graph, otherwise True
+        Checks whether a task is in the graph.
+
+        :param task: task
+        :return: ``True`` if all tasks are in the graph, otherwise ``False``
         :rtype: list
         """
         assert all(isinstance(t, (api_task.BaseTask, Iterable)) for t in tasks)
@@ -183,16 +186,18 @@
 
     def add_dependency(self, dependent, dependency):
         """
-        Add a dependency for one item (task, sequence or parallel) on another
-        The dependent will only be executed after the dependency terminates
-        If either of the items is either a sequence or a parallel,
-         multiple dependencies may be added
-        :param BaseTask|_TasksArrangement dependent: The dependent (task, sequence or parallel)
-        :param BaseTask|_TasksArrangement dependency: The dependency (task, sequence or parallel)
-        :return: True if the dependency between the two hadn't already existed, otherwise False
+        Adds a dependency for one item (task, sequence or parallel) on another.
+
+        The dependent will only be executed after the dependency terminates. If either of the items
+        is either a sequence or a parallel, multiple dependencies may be added.
+
+        :param dependent: dependent (task, sequence or parallel)
+        :param dependency: dependency (task, sequence or parallel)
+        :return: ``True`` if the dependency between the two hadn't already existed, otherwise
+         ``False``
         :rtype: bool
-        :raise TaskNotInGraphError if either the dependent or dependency are tasks which
-         are not in the graph
+        :raises ~aria.orchestrator.workflows.api.task_graph.TaskNotInGraphError: if either the
+         dependent or dependency are tasks which are not in the graph
         """
         if not (self.has_tasks(dependent) and self.has_tasks(dependency)):
             raise TaskNotInGraphError()
@@ -212,18 +217,17 @@
 
     def has_dependency(self, dependent, dependency):
         """
-        Check whether one item (task, sequence or parallel) depends on another
+        Checks whether one item (task, sequence or parallel) depends on another.
 
-        Note that if either of the items is either a sequence or a parallel,
-        and some of the dependencies exist in the graph but not all of them,
-        this method will return False
+        Note that if either of the items is either a sequence or a parallel, and some of the
+        dependencies exist in the graph but not all of them, this method will return ``False``.
 
-        :param BaseTask|_TasksArrangement dependent: The dependent (task, sequence or parallel)
-        :param BaseTask|_TasksArrangement dependency: The dependency (task, sequence or parallel)
-        :return: True if the dependency between the two exists, otherwise False
+        :param dependent: dependent (task, sequence or parallel)
+        :param dependency: dependency (task, sequence or parallel)
+        :return: ``True`` if the dependency between the two exists, otherwise ``False``
         :rtype: bool
-        :raise TaskNotInGraphError if either the dependent or dependency are tasks
-         which are not in the graph
+        :raises ~aria.orchestrator.workflows.api.task_graph.TaskNotInGraphError: if either the
+         dependent or dependency are tasks which are not in the graph
         """
         if not (dependent and dependency):
             return False
@@ -246,18 +250,18 @@
 
     def remove_dependency(self, dependent, dependency):
         """
-        Remove a dependency for one item (task, sequence or parallel) on another
+        Removes a dependency for one item (task, sequence or parallel) on another.
 
-        Note that if either of the items is either a sequence or a parallel, and some of
-        the dependencies exist in the graph but not all of them, this method will not remove
-        any of the dependencies and return False
+        Note that if either of the items is either a sequence or a parallel, and some of the
+        dependencies exist in the graph but not all of them, this method will not remove any of the
+        dependencies and return ``False``.
 
-        :param BaseTask|_TasksArrangement dependent: The dependent (task, sequence or parallel)
-        :param BaseTask|_TasksArrangement dependency: The dependency (task, sequence or parallel)
-        :return: False if the dependency between the two hadn't existed, otherwise True
+        :param dependent: dependent (task, sequence or parallel)
+        :param dependency: dependency (task, sequence or parallel)
+        :return: ``False`` if the dependency between the two hadn't existed, otherwise ``True``
         :rtype: bool
-        :raise TaskNotInGraphError if either the dependent or dependency are tasks
-         which are not in the graph
+        :raises ~aria.orchestrator.workflows.api.task_graph.TaskNotInGraphError: if either the
+         dependent or dependency are tasks which are not in the graph
         """
         if not (self.has_tasks(dependent) and self.has_tasks(dependency)):
             raise TaskNotInGraphError()
@@ -277,9 +281,10 @@
     @_filter_out_empty_tasks
     def sequence(self, *tasks):
         """
-        Create and insert a sequence into the graph, effectively each task i depends on i-1
-        :param tasks: an iterable of dependencies
-        :return: the provided tasks
+        Creates and inserts a sequence into the graph, effectively each task i depends on i-1.
+
+        :param tasks: iterable of dependencies
+        :return: provided tasks
         """
         if tasks:
             self.add_tasks(*tasks)
diff --git a/aria/orchestrator/workflows/builtin/__init__.py b/aria/orchestrator/workflows/builtin/__init__.py
index 8b13c62..1b2f390 100644
--- a/aria/orchestrator/workflows/builtin/__init__.py
+++ b/aria/orchestrator/workflows/builtin/__init__.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-A set of builtin workflows
+Built-in workflows.
 """
 
 from .install import install
diff --git a/aria/orchestrator/workflows/builtin/execute_operation.py b/aria/orchestrator/workflows/builtin/execute_operation.py
index 437e584..949f864 100644
--- a/aria/orchestrator/workflows/builtin/execute_operation.py
+++ b/aria/orchestrator/workflows/builtin/execute_operation.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Builtin execute_operation workflow
+Built-in operation execution Workflow.
 """
 
 from ... import workflow
@@ -34,13 +34,13 @@
         node_ids,
         **kwargs):
     """
-    The execute_operation workflow
+    Built-in operation execution Workflow.
 
-    :param WorkflowContext workflow_context: the workflow context
-    :param TaskGraph graph: the graph which will describe the workflow.
-    :param basestring operation: the operation name to execute
-    :param dict operation_kwargs:
-    :param bool run_by_dependency_order:
+    :param workflow_context: workflow context
+    :param graph: graph which will describe the workflow
+    :param operation: operation name to execute
+    :param operation_kwargs:
+    :param run_by_dependency_order:
     :param type_names:
     :param node_template_ids:
     :param node_ids:
diff --git a/aria/orchestrator/workflows/builtin/heal.py b/aria/orchestrator/workflows/builtin/heal.py
index ca382e8..07e27b1 100644
--- a/aria/orchestrator/workflows/builtin/heal.py
+++ b/aria/orchestrator/workflows/builtin/heal.py
@@ -16,7 +16,7 @@
 # pylint: skip-file
 
 """
-Builtin heal workflow
+Built-in heal workflow.
 """
 
 from aria import workflow
@@ -28,11 +28,11 @@
 @workflow
 def heal(ctx, graph, node_id):
     """
-    The heal workflow
+    Built-in heal workflow..
 
-    :param WorkflowContext ctx: the workflow context
-    :param TaskGraph graph: the graph which will describe the workflow.
-    :param node_id: the id of the node to heal
+    :param ctx: workflow context
+    :param graph: graph which will describe the workflow.
+    :param node_id: ID of the node to heal
     :return:
     """
     failing_node = ctx.model.node.get(node_id)
@@ -60,13 +60,12 @@
 @workflow(suffix_template='{failing_nodes}')
 def heal_uninstall(ctx, graph, failing_nodes, targeted_nodes):
     """
-    the uninstall part of the heal mechanism
-    :param WorkflowContext ctx: the workflow context
-    :param TaskGraph graph: the task graph to edit.
-    :param failing_nodes: the failing nodes to heal.
-    :param targeted_nodes: the targets of the relationships where the failing node are
-    source
-    :return:
+    Uninstall phase of the heal mechanism.
+
+    :param ctx: workflow context
+    :param graph: task graph to edit
+    :param failing_nodes: failing nodes to heal
+    :param targeted_nodes: targets of the relationships where the failing node are
     """
     node_sub_workflows = {}
 
@@ -113,13 +112,12 @@
 @workflow(suffix_template='{failing_nodes}')
 def heal_install(ctx, graph, failing_nodes, targeted_nodes):
     """
-    the install part of the heal mechanism
-    :param WorkflowContext ctx: the workflow context
-    :param TaskGraph graph: the task graph to edit.
-    :param failing_nodes: the failing nodes to heal.
-    :param targeted_nodes: the targets of the relationships where the failing node are
-    source
-    :return:
+    Install phase of the heal mechanism.
+
+    :param ctx: workflow context
+    :param graph: task graph to edit.
+    :param failing_nodes: failing nodes to heal
+    :param targeted_nodes: targets of the relationships where the failing node are
     """
     node_sub_workflows = {}
 
diff --git a/aria/orchestrator/workflows/builtin/install.py b/aria/orchestrator/workflows/builtin/install.py
index 821b190..1e7c531 100644
--- a/aria/orchestrator/workflows/builtin/install.py
+++ b/aria/orchestrator/workflows/builtin/install.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Builtin install workflow
+Built-in install workflow.
 """
 
 from ... import workflow
@@ -24,6 +24,9 @@
 
 @workflow
 def install(ctx, graph):
+    """
+    Built-in install workflow.
+    """
     tasks_and_nodes = []
     for node in ctx.nodes:
         tasks_and_nodes.append((api_task.WorkflowTask(workflows.install_node, node=node), node))
diff --git a/aria/orchestrator/workflows/builtin/start.py b/aria/orchestrator/workflows/builtin/start.py
index 1946143..c02a26d 100644
--- a/aria/orchestrator/workflows/builtin/start.py
+++ b/aria/orchestrator/workflows/builtin/start.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Builtin start workflow
+Built-in start workflow.
 """
 
 from .workflows import start_node
@@ -24,5 +24,8 @@
 
 @workflow
 def start(ctx, graph):
+    """
+    Built-in start workflow.
+    """
     for node in ctx.model.node.iter():
         graph.add_tasks(api_task.WorkflowTask(start_node, node=node))
diff --git a/aria/orchestrator/workflows/builtin/stop.py b/aria/orchestrator/workflows/builtin/stop.py
index c1b60ae..6f9930b 100644
--- a/aria/orchestrator/workflows/builtin/stop.py
+++ b/aria/orchestrator/workflows/builtin/stop.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Builtin stop workflow
+Built-in stop workflow.
 """
 
 from .workflows import stop_node
@@ -24,5 +24,8 @@
 
 @workflow
 def stop(ctx, graph):
+    """
+    Built-in stop workflow.
+    """
     for node in ctx.model.node.iter():
         graph.add_tasks(api_task.WorkflowTask(stop_node, node=node))
diff --git a/aria/orchestrator/workflows/builtin/uninstall.py b/aria/orchestrator/workflows/builtin/uninstall.py
index c35117e..7925f4b 100644
--- a/aria/orchestrator/workflows/builtin/uninstall.py
+++ b/aria/orchestrator/workflows/builtin/uninstall.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Builtin uninstall workflow
+Built-in uninstall workflow.
 """
 
 from ... import workflow
@@ -24,6 +24,9 @@
 
 @workflow
 def uninstall(ctx, graph):
+    """
+    Built-in uninstall workflow.
+    """
     tasks_and_nodes = []
     for node in ctx.nodes:
         tasks_and_nodes.append((api_task.WorkflowTask(workflows.uninstall_node, node=node), node))
diff --git a/aria/orchestrator/workflows/core/__init__.py b/aria/orchestrator/workflows/core/__init__.py
index 81db43f..3f28136 100644
--- a/aria/orchestrator/workflows/core/__init__.py
+++ b/aria/orchestrator/workflows/core/__init__.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Core for the workflow execution mechanism
+Workflow core.
 """
 
 from . import engine
diff --git a/aria/orchestrator/workflows/core/engine.py b/aria/orchestrator/workflows/core/engine.py
index 5a94df8..d9c77e9 100644
--- a/aria/orchestrator/workflows/core/engine.py
+++ b/aria/orchestrator/workflows/core/engine.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-The workflow engine. Executes workflows
+Workflow execution.
 """
 
 import time
@@ -33,7 +33,7 @@
 
 class Engine(logger.LoggerMixin):
     """
-    The workflow engine. Executes workflows
+    Executes workflows.
     """
 
     def __init__(self, executors, **kwargs):
@@ -43,7 +43,7 @@
 
     def execute(self, ctx, resuming=False):
         """
-        execute the workflow
+        Executes the workflow.
         """
         if resuming:
             events.on_resume_workflow_signal.send(ctx)
@@ -87,8 +87,8 @@
     def cancel_execution(ctx):
         """
         Send a cancel request to the engine. If execution already started, execution status
-        will be modified to 'cancelling' status. If execution is in pending mode, execution status
-        will be modified to 'cancelled' directly.
+        will be modified to ``cancelling`` status. If execution is in pending mode, execution status
+        will be modified to ``cancelled`` directly.
         """
         events.on_cancelling_workflow_signal.send(ctx)
 
diff --git a/aria/orchestrator/workflows/core/events_handler.py b/aria/orchestrator/workflows/core/events_handler.py
index 7380db8..769c1a8 100644
--- a/aria/orchestrator/workflows/core/events_handler.py
+++ b/aria/orchestrator/workflows/core/events_handler.py
@@ -14,10 +14,7 @@
 # limitations under the License.
 
 """
-ARIA's events Sub-Package
-Path: aria.events.storage_event_handler
-
-Implementation of storage handlers for workflow and operation events.
+Workflow event handling.
 """
 
 from datetime import (
diff --git a/aria/orchestrator/workflows/events_logging.py b/aria/orchestrator/workflows/events_logging.py
index 4cee867..9eee1e1 100644
--- a/aria/orchestrator/workflows/events_logging.py
+++ b/aria/orchestrator/workflows/events_logging.py
@@ -15,10 +15,7 @@
 
 
 """
-ARIA's events Sub-Package
-Path: aria.events.storage_event_handler
-
-Implementation of logger handlers for workflow and operation events.
+Workflow event logging.
 """
 
 from .. import events
diff --git a/aria/orchestrator/workflows/exceptions.py b/aria/orchestrator/workflows/exceptions.py
index b5ae496..2a1d6b1 100644
--- a/aria/orchestrator/workflows/exceptions.py
+++ b/aria/orchestrator/workflows/exceptions.py
@@ -14,8 +14,9 @@
 # limitations under the License.
 
 """
-Workflow related Exception classes
+Workflow exceptions.
 """
+
 import os
 
 from .. import exceptions
@@ -23,14 +24,14 @@
 
 class ExecutorException(exceptions.AriaError):
     """
-    General executor exception
+    General executor exception.
     """
     pass
 
 
 class ProcessException(ExecutorException):
     """
-    Raised when subprocess execution fails
+    Raised when subprocess execution fails.
     """
 
     def __init__(self, command, stderr=None, stdout=None, return_code=None):
@@ -62,13 +63,13 @@
 
 class AriaEngineError(exceptions.AriaError):
     """
-    Raised by the workflow engine
+    Raised by the workflow engine.
     """
 
 
 class TaskException(exceptions.AriaError):
     """
-    Raised by the task
+    Raised by the task.
     """
 
 
diff --git a/aria/orchestrator/workflows/executor/__init__.py b/aria/orchestrator/workflows/executor/__init__.py
index 414a740..cafab74 100644
--- a/aria/orchestrator/workflows/executor/__init__.py
+++ b/aria/orchestrator/workflows/executor/__init__.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Executors for task execution
+Task executors.
 """
 
 
diff --git a/aria/orchestrator/workflows/executor/base.py b/aria/orchestrator/workflows/executor/base.py
index 4cc4503..ec1a0c7 100644
--- a/aria/orchestrator/workflows/executor/base.py
+++ b/aria/orchestrator/workflows/executor/base.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Base executor module
+Base class for task executors.
 """
 
 from aria import logger
@@ -23,14 +23,15 @@
 
 class BaseExecutor(logger.LoggerMixin):
     """
-    Base class for executors for running tasks
+    Base class for task executors.
     """
     def _execute(self, ctx):
         raise NotImplementedError
 
     def execute(self, ctx):
         """
-        Execute a task
+        Executes a task.
+
         :param task: task to execute
         """
         if ctx.task.function:
@@ -44,7 +45,7 @@
 
     def close(self):
         """
-        Close the executor
+        Closes the executor.
         """
         pass
 
diff --git a/aria/orchestrator/workflows/executor/celery.py b/aria/orchestrator/workflows/executor/celery.py
index 46b15fd..0716e5b 100644
--- a/aria/orchestrator/workflows/executor/celery.py
+++ b/aria/orchestrator/workflows/executor/celery.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Celery based executor
+Celery task executor.
 """
 
 import threading
@@ -25,7 +25,7 @@
 
 class CeleryExecutor(BaseExecutor):
     """
-    Executor which runs tasks using aria_celery
+    Celery task executor.
     """
 
     def __init__(self, app, *args, **kwargs):
diff --git a/aria/orchestrator/workflows/executor/dry.py b/aria/orchestrator/workflows/executor/dry.py
index 9d86125..9314e5d 100644
--- a/aria/orchestrator/workflows/executor/dry.py
+++ b/aria/orchestrator/workflows/executor/dry.py
@@ -14,8 +14,9 @@
 # limitations under the License.
 
 """
-Dry executor
+Dry task executor.
 """
+
 from datetime import datetime
 
 from . import base
@@ -23,7 +24,7 @@
 
 class DryExecutor(base.BaseExecutor):                                                                    # pylint: disable=abstract-method
     """
-    Executor which dry runs tasks - prints task information without causing any side effects
+    Dry task executor: prints task information without causing any side effects.
     """
     def execute(self, ctx):
         with ctx.persist_changes:
diff --git a/aria/orchestrator/workflows/executor/process.py b/aria/orchestrator/workflows/executor/process.py
index 11e3cfd..69288ea 100644
--- a/aria/orchestrator/workflows/executor/process.py
+++ b/aria/orchestrator/workflows/executor/process.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Subprocess based executor
+Sub-process task executor.
 """
 
 # pylint: disable=wrong-import-position
@@ -67,7 +67,7 @@
 
 class ProcessExecutor(base.BaseExecutor):
     """
-    Executor which runs tasks in a subprocess environment
+    Sub-process task executor.
     """
 
     def __init__(self, plugin_manager=None, python_path=None, *args, **kwargs):
diff --git a/aria/orchestrator/workflows/executor/thread.py b/aria/orchestrator/workflows/executor/thread.py
index 8c447b6..d9dcdf8 100644
--- a/aria/orchestrator/workflows/executor/thread.py
+++ b/aria/orchestrator/workflows/executor/thread.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Thread based executor
+Thread task executor.
 """
 
 import Queue
@@ -29,9 +29,11 @@
 
 class ThreadExecutor(BaseExecutor):
     """
-    Executor which runs tasks in a separate thread. It's easier writing tests
-    using this executor rather than the full blown subprocess executor.
-    Note: This executor is not capable of running plugin operations.
+    Thread task executor.
+
+    It's easier writing tests using this executor rather than the full-blown sub-process executor.
+
+    Note: This executor is incapable of running plugin operations.
     """
 
     def __init__(self, pool_size=1, *args, **kwargs):
diff --git a/aria/parser/__init__.py b/aria/parser/__init__.py
index 64df88a..7903b52 100644
--- a/aria/parser/__init__.py
+++ b/aria/parser/__init__.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Parser package.
+"""
+
 from .specification import implements_specification, iter_specifications
 
 
diff --git a/aria/parser/consumption/__init__.py b/aria/parser/consumption/__init__.py
index 76e73be..bd4b29c 100644
--- a/aria/parser/consumption/__init__.py
+++ b/aria/parser/consumption/__init__.py
@@ -13,6 +13,37 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Consumption package.
+
+.. autosummary::
+   :nosignatures:
+
+   aria.parser.consumption.ConsumptionContext
+   aria.parser.consumption.Style
+
+Consumers
+---------
+
+.. autosummary::
+   :nosignatures:
+
+   aria.parser.consumption.Consumer
+   aria.parser.consumption.ConsumerChain
+   aria.parser.consumption.ConsumerException
+   aria.parser.consumption.Inputs
+   aria.parser.consumption.ServiceTemplate
+   aria.parser.consumption.Types
+   aria.parser.consumption.CoerceServiceInstanceValues
+   aria.parser.consumption.ValidateServiceInstance
+   aria.parser.consumption.SatisfyRequirements
+   aria.parser.consumption.ValidateCapabilities
+   aria.parser.consumption.FindHosts
+   aria.parser.consumption.ConfigureOperations
+   aria.parser.consumption.ServiceInstance
+   aria.parser.consumption.Read
+   aria.parser.consumption.Validate
+"""
 
 from .exceptions import ConsumerException
 from .context import ConsumptionContext
diff --git a/aria/parser/consumption/consumer.py b/aria/parser/consumption/consumer.py
index f9c2f2e..4f4c614 100644
--- a/aria/parser/consumption/consumer.py
+++ b/aria/parser/consumption/consumer.py
@@ -48,8 +48,8 @@
     """
     ARIA consumer chain.
 
-    Calls consumers in order, handling exception by calling `_handle_exception` on them,
-    and stops the chain if there are any validation issues.
+    Calls consumers in order, handling exception by calling ``_handle_exception`` on them, and stops
+    the chain if there are any validation issues.
     """
 
     def __init__(self, context, consumer_classes=None, handle_exceptions=True):
diff --git a/aria/parser/consumption/context.py b/aria/parser/consumption/context.py
index a8b75df..6fa61f4 100644
--- a/aria/parser/consumption/context.py
+++ b/aria/parser/consumption/context.py
@@ -29,16 +29,22 @@
 
 class ConsumptionContext(object):
     """
-    Properties:
+    Consumption context.
 
-    * :code:`args`: The runtime arguments (usually provided on the command line)
-    * :code:`out`: Message output stream (defaults to stdout)
-    * :code:`style`: Message output style
-    * :code:`validation`: :class:`aria.validation.ValidationContext`
-    * :code:`loading`: :class:`aria.loading.LoadingContext`
-    * :code:`reading`: :class:`aria.reading.ReadingContext`
-    * :code:`presentation`: :class:`aria.presentation.PresentationContext`
-    * :code:`modeling`: :class:`aria.service.ModelingContext`
+    :ivar args: runtime arguments (usually provided on the command line)
+    :ivar out: message output stream (defaults to stdout)
+    :ivar style: message output style
+    :vartype style: Style
+    :ivar validation: validation context
+    :vartype validation: :class:`ValidationContext`
+    :ivar loading: loading context
+    :vartype loading: :class:`LoadingContext`
+    :ivar reading: reading context
+    :vartype reading: :class:`ReadingContext`
+    :ivar presentation: presentation context
+    :vartype presentation: :class:`PresentationContext`
+    :ivar modeling: modeling context
+    :vartype modeling: :class:`ModelingContext`
     """
 
     @staticmethod
@@ -71,7 +77,7 @@
 
     def write(self, string):
         """
-        Writes to our :code:`out`, making sure to encode UTF-8 if required.
+        Writes to our ``out``, making sure to encode UTF-8 if required.
         """
 
         try:
diff --git a/aria/parser/consumption/presentation.py b/aria/parser/consumption/presentation.py
index 7766473..542b3f0 100644
--- a/aria/parser/consumption/presentation.py
+++ b/aria/parser/consumption/presentation.py
@@ -26,11 +26,12 @@
     """
     Reads the presentation, handling imports recursively.
 
-    It works by consuming a data source via appropriate :class:`aria.loader.Loader`,
-    :class:`aria.reader.Reader`, and :class:`aria.presenter.Presenter` instances.
+    It works by consuming a data source via appropriate :class:`~aria.parser.loading.Loader`,
+    :class:`~aria.parser.reading.Reader`, and :class:`~aria.parser.presentation.Presenter`
+    instances.
 
     It supports agnostic raw data composition for presenters that have
-    :code:`_get_import_locations` and :code:`_merge_import`.
+    ``_get_import_locations`` and ``_merge_import``.
 
     To improve performance, loaders are called asynchronously on separate threads.
 
diff --git a/aria/parser/exceptions.py b/aria/parser/exceptions.py
index 5d1a55c..a1f7012 100644
--- a/aria/parser/exceptions.py
+++ b/aria/parser/exceptions.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Parser exceptions.
+"""
+
 from ..exceptions import AriaException
 from .validation import Issue
 
diff --git a/aria/parser/loading/__init__.py b/aria/parser/loading/__init__.py
index 006f164..834675e 100644
--- a/aria/parser/loading/__init__.py
+++ b/aria/parser/loading/__init__.py
@@ -13,6 +13,41 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Loading package.
+
+.. autosummary::
+   :nosignatures:
+
+   aria.parser.loading.LoadingContext
+   aria.parser.loading.LoaderException
+   aria.parser.loading.LoaderNotFoundError
+   aria.parser.loading.DocumentNotFoundException
+   aria.parser.loading.LoaderSource
+   aria.parser.loading.DefaultLoaderSource
+
+Loaders
+-------
+
+.. autosummary::
+   :nosignatures:
+
+   aria.parser.loading.Loader
+   aria.parser.loading.FileTextLoader
+   aria.parser.loading.LiteralLoader
+   aria.parser.loading.RequestLoader
+   aria.parser.loading.RequestTextLoader
+   aria.parser.loading.UriTextLoader
+
+Locations
+---------
+
+.. autosummary::
+   :nosignatures:
+
+   aria.parser.loading.Location
+   aria.parser.loading.UriLocation
+"""
 
 from .exceptions import LoaderException, LoaderNotFoundError, DocumentNotFoundException
 from .context import LoadingContext
diff --git a/aria/parser/loading/context.py b/aria/parser/loading/context.py
index 44e3fd1..59727c9 100644
--- a/aria/parser/loading/context.py
+++ b/aria/parser/loading/context.py
@@ -20,10 +20,12 @@
 
 class LoadingContext(object):
     """
-    Properties:
+    Loading context.
 
-    * :code:`loader_source`: For finding loader instances
-    * :code:`prefixes`: List of additional prefixes for :class:`UriTextLoader`
+    :ivar loader_source: for finding loader instances
+    :vartype loader_source: ~aria.parser.loading.LoaderSource
+    :ivar prefixes: additional prefixes for :class:`UriTextLoader`
+    :vartype prefixes: [:obj:`basestring`]
     """
 
     def __init__(self):
diff --git a/aria/parser/loading/literal.py b/aria/parser/loading/literal.py
index 1b99fd8..7865008 100644
--- a/aria/parser/loading/literal.py
+++ b/aria/parser/loading/literal.py
@@ -21,7 +21,7 @@
     """
     ARIA literal loader.
 
-    See :class:`aria.loading.LiteralLocation`.
+    See :class:`~aria.parser.loading.LiteralLocation`.
     """
 
     def __init__(self, location):
diff --git a/aria/parser/loading/location.py b/aria/parser/loading/location.py
index 5bc6fab..902e856 100644
--- a/aria/parser/loading/location.py
+++ b/aria/parser/loading/location.py
@@ -23,8 +23,8 @@
     """
     Base class for ARIA locations.
 
-    Locations are used by :class:`aria.loading.LoaderSource` to delegate to
-    an appropriate :class:`aria.loading.Loader`.
+    Locations are used by :class:`~aria.parser.loading.LoaderSource` to delegate to
+    an appropriate :class:`~aria.parser.loading.Loader`.
     """
 
     def is_equivalent(self, location):
@@ -41,7 +41,7 @@
 
     If no scheme is included, it should be treated as a filesystem path.
 
-    See :class:`aria.loading.UriTextLoader`.
+    See :class:`~aria.parser.loading.UriTextLoader`.
     """
 
     def __init__(self, uri):
@@ -68,7 +68,7 @@
     """
     A location that embeds content.
 
-    See :class:`aria.loading.LiteralLoader`.
+    See :class:`~aria.parser.loading.LiteralLoader`.
     """
 
     def __init__(self, content, name='literal'):
diff --git a/aria/parser/loading/source.py b/aria/parser/loading/source.py
index 7acf813..bcd6dd1 100644
--- a/aria/parser/loading/source.py
+++ b/aria/parser/loading/source.py
@@ -32,7 +32,7 @@
 class DefaultLoaderSource(LoaderSource):
     """
     The default ARIA loader source will generate a :class:`UriTextLoader` for
-    :class:`UriLocation' and a :class:`LiteralLoader` for a :class:`LiteralLocation`.
+    :class:`UriLocation` and a :class:`LiteralLoader` for a :class:`LiteralLocation`.
     """
 
     def get_loader(self, context, location, origin_location):
diff --git a/aria/parser/loading/uri.py b/aria/parser/loading/uri.py
index 1b23bf6..a5a18e6 100644
--- a/aria/parser/loading/uri.py
+++ b/aria/parser/loading/uri.py
@@ -29,14 +29,14 @@
     """
     Base class for ARIA URI loaders.
 
-    See :class:`aria.loading.UriLocation`.
+    See :class:`~aria.parser.loading.UriLocation`.
 
     Supports a list of search prefixes that are tried in order if the URI cannot be found.
     They will be:
 
-    * If :code:`origin_location` is provided its prefix will come first.
+    * If ``origin_location`` is provided its prefix will come first.
     * Then the prefixes in the :class:`LoadingContext` will be added.
-    * Finally, the global prefixes specified in :code:`URI_LOADER_PREFIXES` will be added.
+    * Finally, the parser can supply a ``uri_loader_prefix`` function with extra prefixes.
     """
 
     def __init__(self, context, location, origin_location=None):
diff --git a/aria/parser/modeling/__init__.py b/aria/parser/modeling/__init__.py
index df127cd..4b1c995 100644
--- a/aria/parser/modeling/__init__.py
+++ b/aria/parser/modeling/__init__.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Modeling package.
+"""
+
 from .context import IdType, ModelingContext
 
 
diff --git a/aria/parser/modeling/context.py b/aria/parser/modeling/context.py
index 4a53641..3d75617 100644
--- a/aria/parser/modeling/context.py
+++ b/aria/parser/modeling/context.py
@@ -38,14 +38,20 @@
 
 class ModelingContext(object):
     """
-    Properties:
+    Modeling context.
 
-    * :code:`template`: The generated service template
-    * :code:`instance`: The generated service instance
-    * :code:`node_id_format`: Format for node instance IDs
-    * :code:`id_type`: Type of IDs to use for instances
-    * :code:`id_max_length`: Maximum allowed instance ID length
-    * :code:`inputs`: Dict of inputs values
+    :ivar template: generated service template
+    :vartype template: aria.modeling.models.ServiceTemplate
+    :ivar instance: generated service instance
+    :vartype instance: aria.modeling.models.Service
+    :ivar node_id_format: format for node instance IDs
+    :vartype node_id_format: basestring
+    :ivar id_type: type of IDs to use for instances
+    :vartype id_type: basestring
+    :ivar id_max_length: maximum allowed instance ID length
+    :vartype id_max_length: int
+    :ivar inputs: inputs values
+    :vartype inputs: {:obj:`basestring`, object}
     """
 
     def __init__(self):
diff --git a/aria/parser/presentation/__init__.py b/aria/parser/presentation/__init__.py
index a681695..5633e7b 100644
--- a/aria/parser/presentation/__init__.py
+++ b/aria/parser/presentation/__init__.py
@@ -13,6 +13,85 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Presentation package.
+
+.. autosummary::
+   :nosignatures:
+
+   aria.parser.presentation.PresentationContext
+   aria.parser.presentation.PresenterException
+   aria.parser.presentation.PresenterNotFoundError
+   aria.parser.presentation.Field
+   aria.parser.presentation.NULL
+   aria.parser.presentation.none_to_null
+   aria.parser.presentation.null_to_none
+   aria.parser.presentation.Value
+   aria.parser.presentation.Presenter
+   aria.parser.presentation.PresenterSource
+   aria.parser.presentation.DefaultPresenterSource
+
+Presentations
+-------------
+
+.. autosummary::
+   :nosignatures:
+
+   aria.parser.presentation.PresentationBase
+   aria.parser.presentation.Presentation
+   aria.parser.presentation.AsIsPresentation
+
+Field decorators
+----------------
+
+.. autosummary::
+   :nosignatures:
+
+   aria.parser.presentation.has_fields
+   aria.parser.presentation.short_form_field
+   aria.parser.presentation.allow_unknown_fields
+   aria.parser.presentation.primitive_field
+   aria.parser.presentation.primitive_list_field
+   aria.parser.presentation.primitive_dict_field
+   aria.parser.presentation.primitive_dict_unknown_fields
+   aria.parser.presentation.object_field
+   aria.parser.presentation.object_list_field
+   aria.parser.presentation.object_dict_field
+   aria.parser.presentation.object_sequenced_list_field
+   aria.parser.presentation.object_dict_unknown_fields
+   aria.parser.presentation.field_getter
+   aria.parser.presentation.field_setter
+   aria.parser.presentation.field_validator
+
+Field validators
+----------------
+
+.. autosummary::
+   :nosignatures:
+
+   aria.parser.presentation.type_validator
+   aria.parser.presentation.list_type_validator
+   aria.parser.presentation.list_length_validator
+   aria.parser.presentation.derived_from_validator
+
+Utilities
+---------
+
+.. autosummary::
+   :nosignatures:
+
+   aria.parser.presentation.get_locator
+   aria.parser.presentation.parse_types_dict_names
+   aria.parser.presentation.validate_primitive
+   aria.parser.presentation.validate_no_short_form
+   aria.parser.presentation.validate_no_unknown_fields
+   aria.parser.presentation.validate_known_fields
+   aria.parser.presentation.get_parent_presentation
+   aria.parser.presentation.report_issue_for_unknown_type
+   aria.parser.presentation.report_issue_for_parent_is_self
+   aria.parser.presentation.report_issue_for_unknown_parent_type
+   aria.parser.presentation.report_issue_for_circular_type_hierarchy
+"""
 
 from .exceptions import PresenterException, PresenterNotFoundError
 from .context import PresentationContext
@@ -29,8 +108,8 @@
                                derived_from_validator)
 from .utils import (get_locator, parse_types_dict_names, validate_primitive, validate_no_short_form,
                     validate_no_unknown_fields, validate_known_fields, get_parent_presentation,
-                    report_issue_for_unknown_type, report_issue_for_parent_is_self,
-                    report_issue_for_circular_type_hierarchy)
+                    report_issue_for_unknown_type, report_issue_for_unknown_parent_type,
+                    report_issue_for_parent_is_self, report_issue_for_circular_type_hierarchy)
 
 __all__ = (
     'PresenterException',
@@ -74,5 +153,6 @@
     'validate_known_fields',
     'get_parent_presentation',
     'report_issue_for_unknown_type',
+    'report_issue_for_unknown_parent_type',
     'report_issue_for_parent_is_self',
     'report_issue_for_circular_type_hierarchy')
diff --git a/aria/parser/presentation/context.py b/aria/parser/presentation/context.py
index 26dcb39..44a6f82 100644
--- a/aria/parser/presentation/context.py
+++ b/aria/parser/presentation/context.py
@@ -19,16 +19,24 @@
 
 class PresentationContext(object):
     """
-    Properties:
+    Presentation context.
 
-    * :code:`presenter`: The generated presenter instance
-    * :code:`location`: From where we will generate the presenter
-    * :code:`presenter_source`: For finding presenter classes
-    * :code:`presenter_class`: Overrides :code:`presenter_source` with a specific class
-    * :code:`import_profile`: Whether to import the profile by default (defaults to true)
-    * :code:`threads`: Number of threads to use when reading data
-    * :code:`timeout`: Timeout in seconds for loading data
-    * :code:`print_exceptions`: Whether to print exceptions while reading data
+    :ivar presenter: the generated presenter instance
+    :vartype presenter: ~aria.parser.presentation.Presenter
+    :ivar location: from where we will generate the presenter
+    :vartype location: ~aria.parser.loading.Location
+    :ivar presenter_source: for finding presenter classes
+    :vartype presenter_source: ~aria.parser.presentation.PresenterSource
+    :ivar presenter_class: overrides ``presenter_source`` with a specific class
+    :vartype presenter_class: type
+    :ivar import_profile: whether to import the profile by default (defaults to ``True``)
+    :vartype import_profile: bool
+    :ivar threads: number of threads to use when reading data
+    :vartype threads: int
+    :ivar timeout: timeout in seconds for loading data
+    :vartype timeout: float
+    :ivar print_exceptions: whether to print exceptions while reading data
+    :vartype print_exceptions: bool
     """
 
     def __init__(self):
diff --git a/aria/parser/presentation/field_validators.py b/aria/parser/presentation/field_validators.py
index 9903a1b..aa04913 100644
--- a/aria/parser/presentation/field_validators.py
+++ b/aria/parser/presentation/field_validators.py
@@ -25,9 +25,9 @@
     Makes sure that the field refers to an existing type defined in the root presenter.
 
     The arguments from the second onwards are used to locate a nested field under
-    :code:`service_template` under the root presenter. The first of these can optionally
-    be a function, in which case it will be called to convert type names. This can be used
-    to support shorthand type names, aliases, etc.
+    ``service_template`` under the root presenter. The first of these can optionally be a function,
+    in which case it will be called to convert type names. This can be used to support shorthand
+    type names, aliases, etc.
 
     Can be used with the :func:`field_validator` decorator.
     """
@@ -58,9 +58,9 @@
     Assumes that the field is a list.
 
     The arguments from the second onwards are used to locate a nested field under
-    :code:`service_template` under the root presenter. The first of these can optionally
-    be a function, in which case it will be called to convert type names. This can be used
-    to support shorthand type names, aliases, etc.
+    ``service_template`` under the root presenter. The first of these can optionally be a function,
+    in which case it will be called to convert type names. This can be used to support shorthand
+    type names, aliases, etc.
 
     Can be used with the :func:`field_validator` decorator.
     """
@@ -115,10 +115,9 @@
 
     Checks that we do not derive from ourselves and that we do not cause a circular hierarchy.
 
-    The arguments are used to locate a nested field under
-    :code:`service_template` under the root presenter.
-    The first of these can optionally be a function, in which case it will be called to convert type
-    names. This can be used to support shorthand type names, aliases, etc.
+    The arguments are used to locate a nested field under ``service_template`` under the root
+    presenter. The first of these can optionally be a function, in which case it will be called to
+    convert type names. This can be used to support shorthand type names, aliases, etc.
 
     Can be used with the :func:`field_validator` decorator.
     """
diff --git a/aria/parser/presentation/fields.py b/aria/parser/presentation/fields.py
index 7f85723..959bad1 100644
--- a/aria/parser/presentation/fields.py
+++ b/aria/parser/presentation/fields.py
@@ -39,19 +39,16 @@
     """
     Class decorator for validated field support.
 
-    1. Adds a :code:`FIELDS` class property that is a dict of all the fields.
-       Will inherit and merge :code:`FIELDS` properties from base classes if
-       they have them.
+    1. Adds a ``FIELDS`` class property that is a dict of all the fields. Will inherit and merge
+       ``FIELDS`` properties from base classes if they have them.
 
-    2. Generates automatic :code:`@property` implementations for the fields
-       with the help of a set of special function decorators.
+    2. Generates automatic ``@property`` implementations for the fields with the help of a set of
+       special function decorators.
 
-    The class also works with the Python dict protocol, so that
-    fields can be accessed via dict semantics. The functionality is
-    identical to that of using attribute access.
+    The class also works with the Python dict protocol, so that fields can be accessed via dict
+    semantics. The functionality is identical to that of using attribute access.
 
-    The class will also gain two utility methods, :code:`_iter_field_names`
-    and :code:`_iter_fields`.
+    The class will also gain two utility methods, ``_iter_field_names`` and ``_iter_fields``.
     """
 
     # Make sure we have FIELDS
@@ -267,8 +264,8 @@
     """
     Method decorator for overriding the getter function of a field.
 
-    The signature of the getter function must be: :code:`f(field, presentation, context)`.
-    The default getter can be accessed as :code:`field.default_get(presentation, context)`.
+    The signature of the getter function must be: ``f(field, presentation, context)``.
+    The default getter can be accessed as ```field.default_get(presentation, context)``.
 
     The function must already be decorated with a field decorator.
     """
@@ -286,8 +283,8 @@
     """
     Method decorator for overriding the setter function of a field.
 
-    The signature of the setter function must be: :code:`f(field, presentation, context, value)`.
-    The default setter can be accessed as :code:`field.default_set(presentation, context, value)`.
+    The signature of the setter function must be: ``f(field, presentation, context, value)``.
+    The default setter can be accessed as ``field.default_set(presentation, context, value)``.
 
     The function must already be decorated with a field decorator.
     """
@@ -305,8 +302,8 @@
     """
     Method decorator for overriding the validator function of a field.
 
-    The signature of the validator function must be: :code:f(field, presentation, context)`.
-    The default validator can be accessed as :code:`field.default_validate(presentation, context)`.
+    The signature of the validator function must be: ``f(field, presentation, context)``.
+    The default validator can be accessed as ``field.default_validate(presentation, context)``.
 
     The function must already be decorated with a field decorator.
     """
@@ -373,7 +370,7 @@
 
 class Field(object):
     """
-    Field handler used by :code:`@has_fields` decorator.
+    Field handler used by ``@has_fields`` decorator.
     """
 
     def __init__(self, field_variant, func, cls=None, default=None, allowed=None, required=False):
diff --git a/aria/parser/presentation/null.py b/aria/parser/presentation/null.py
index a018df4..287d2ba 100644
--- a/aria/parser/presentation/null.py
+++ b/aria/parser/presentation/null.py
@@ -33,7 +33,7 @@
 
 def none_to_null(value):
     """
-    Convert :code:`None` to :code:`NULL`, recursively.
+    Convert ``None`` to ``NULL``, recursively.
     """
 
     if value is None:
@@ -51,7 +51,7 @@
 
 def null_to_none(value):
     """
-    Convert :code:`NULL` to :code:`None`, recursively.
+    Convert ``NULL`` to ``None``, recursively.
     """
 
     if value is NULL:
diff --git a/aria/parser/presentation/presentation.py b/aria/parser/presentation/presentation.py
index 644d880..7292562 100644
--- a/aria/parser/presentation/presentation.py
+++ b/aria/parser/presentation/presentation.py
@@ -52,18 +52,17 @@
 
     def _validate(self, context):
         """
-        Validates the presentation while reporting errors in the validation context but
-        *not* raising exceptions.
+        Validates the presentation while reporting errors in the validation context but *not*
+        raising exceptions.
 
-        The base class does not thing, but subclasses may override this for specialized
-        validation.
+        The base class does not thing, but subclasses may override this for specialized validation.
         """
 
     @property
     def _fullname(self):
         """
-        Always returns a usable full name of the presentation, whether it itself is named,
-        or recursing to its container, and finally defaulting to the class name.
+        Always returns a usable full name of the presentation, whether it itself is named, or
+        recursing to its container, and finally defaulting to the class name.
         """
 
         if self._name is not None:
@@ -75,10 +74,10 @@
     @property
     def _locator(self):
         """
-        Attempts to return the most relevant locator, whether we have one, or recursing
-        to our container.
+        Attempts to return the most relevant locator, whether we have one, or recursing to our
+        container.
 
-        :rtype: :class:`aria.reading.Locator`
+        :rtype: :class:`aria.parser.reading.Locator`
         """
 
         return get_locator(self._raw, self._container)
@@ -98,8 +97,8 @@
 
     def _get_from_dict(self, *names):
         """
-        Gets attributes recursively, except for the last name which is used
-        to get a value from the last dict.
+        Gets attributes recursively, except for the last name which is used to get a value from the
+        last dict.
         """
 
         if names:
@@ -110,10 +109,10 @@
 
     def _get_child_locator(self, *names):
         """
-        Attempts to return the locator of one our children. Will default to our locator
-        if not found.
+        Attempts to return the locator of one our children. Will default to our locator if not
+        found.
 
-        :rtype: :class:`aria.reading.Locator`
+        :rtype: :class:`aria.parser.reading.Locator`
         """
 
         if hasattr(self._raw, '_locator'):
@@ -126,9 +125,8 @@
         """
         Emits a colorized representation.
 
-        The base class will emit a sensible default representation of the fields,
-        (by calling :code:`_dump_content`), but subclasses may override this for specialized
-        dumping.
+        The base class will emit a sensible default representation of the fields, (by calling
+        ``_dump_content``), but subclasses may override this for specialized dumping.
         """
 
         if self._name:
@@ -142,8 +140,8 @@
         """
         Emits a colorized representation of the contents.
 
-        The base class will call :code:`_dump_field` on all the fields, but subclasses may
-        override this for specialized dumping.
+        The base class will call ``_dump_field`` on all the fields, but subclasses may override
+        this for specialized dumping.
         """
 
         if field_names:
@@ -159,8 +157,8 @@
         """
         Emits a colorized representation of the field.
 
-        According to the field type, this may trigger nested recursion. The nested
-        types will delegate to their :code:`_dump` methods.
+        According to the field type, this may trigger nested recursion. The nested types will
+        delegate to their ``_dump`` methods.
         """
 
         field = self.FIELDS[field_name]  # pylint: disable=no-member
@@ -179,16 +177,14 @@
 
 class Presentation(PresentationBase):
     """
-    Base class for ARIA presentations. A presentation is a Pythonic wrapper around
-    agnostic raw data, adding the ability to read and modify the data with proper
-    validation.
+    Base class for ARIA presentations. A presentation is a Pythonic wrapper around agnostic raw
+    data, adding the ability to read and modify the data with proper validation.
 
-    ARIA presentation classes will often be decorated with @has_fields, as that
-    mechanism automates a lot of field-specific validation. However, that is not a
-    requirement.
+    ARIA presentation classes will often be decorated with :func:`has_fields`, as that mechanism
+    automates a lot of field-specific validation. However, that is not a requirement.
 
-    Make sure that your utility property and method names begin with a "_", because
-    those names without a "_" prefix are normally reserved for fields.
+    Make sure that your utility property and method names begin with a ``_``, because those names
+    without a ``_`` prefix are normally reserved for fields.
     """
 
     def _validate(self, context):
diff --git a/aria/parser/presentation/source.py b/aria/parser/presentation/source.py
index 7198b07..4bfb8e1 100644
--- a/aria/parser/presentation/source.py
+++ b/aria/parser/presentation/source.py
@@ -32,7 +32,7 @@
 
 class DefaultPresenterSource(PresenterSource):
     """
-    The default ARIA presenter source supports TOSCA Simple Profile.
+    The default ARIA presenter source.
     """
 
     def __init__(self, classes=None):
diff --git a/aria/parser/presentation/utils.py b/aria/parser/presentation/utils.py
index fbe971b..f0fd390 100644
--- a/aria/parser/presentation/utils.py
+++ b/aria/parser/presentation/utils.py
@@ -25,7 +25,7 @@
     """
     Gets the first available locator.
 
-    :rtype: :class:`aria.reading.Locator`
+    :rtype: :class:`aria.parser.reading.Locator`
     """
 
     for v in values:
@@ -53,7 +53,7 @@
     Checks if the value is of the primitive type, optionally attempting to coerce it
     if it is not.
 
-    Raises a :code:`ValueError` if it isn't or if coercion failed.
+    :raises ValueError: if not a primitive type or if coercion failed.
     """
 
     if (cls is not None) and (value is not None) and (value is not NULL):
@@ -112,14 +112,14 @@
 
 def get_parent_presentation(context, presentation, *types_dict_names):
     """
-    Returns the parent presentation according to the :code:`derived_from` field, or None if invalid.
+    Returns the parent presentation according to the ``derived_from`` field, or ``None`` if invalid.
 
     Checks that we do not derive from ourselves and that we do not cause a circular hierarchy.
 
     The arguments from the third onwards are used to locate a nested field under
-    :code:`service_template` under the root presenter. The first of these can optionally
-    be a function, in which case it will be called to convert type names. This can be used
-    to support shorthand type names, aliases, etc.
+    ``service_template`` under the root presenter. The first of these can optionally be a function,
+    in which case it will be called to convert type names. This can be used to support shorthand
+    type names, aliases, etc.
     """
 
     type_name = presentation.derived_from
diff --git a/aria/parser/reading/__init__.py b/aria/parser/reading/__init__.py
index b5c0709..065ca56 100644
--- a/aria/parser/reading/__init__.py
+++ b/aria/parser/reading/__init__.py
@@ -10,6 +10,29 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Reading package.
+
+.. autosummary::
+   :nosignatures:
+
+   aria.parser.reading.ReadingContext
+   ReaderException
+   ReaderNotFoundError
+   ReaderSyntaxError
+   AlreadyReadException
+   JinjaReader
+   JsonReader
+   Locator
+   deepcopy_with_locators
+   copy_locators
+   RawReader
+   Reader
+   ReaderSource
+   DefaultReaderSource
+   YamlReader
+"""
+
 from .raw import RawReader
 from .reader import Reader
 from .yaml import YamlReader
diff --git a/aria/parser/reading/context.py b/aria/parser/reading/context.py
index 02d4de9..233e407 100644
--- a/aria/parser/reading/context.py
+++ b/aria/parser/reading/context.py
@@ -16,10 +16,12 @@
 
 class ReadingContext(object):
     """
-    Properties:
+    Reading context.
 
-    * :code:`reader_source`: For finding reader instances
-    * :code:`reader`: Overrides :code:`reader_source` with a specific class
+    :ivar reader_source: for finding reader instances
+    :vartype reader_source: ReaderSource
+    :ivar reader: overrides ``reader_source`` with a specific class
+    :vartype reader: type
     """
 
     def __init__(self):
diff --git a/aria/parser/reading/locator.py b/aria/parser/reading/locator.py
index 4142ee7..965164d 100644
--- a/aria/parser/reading/locator.py
+++ b/aria/parser/reading/locator.py
@@ -124,7 +124,7 @@
 
 def deepcopy_with_locators(value):
     """
-    Like :code:`deepcopy`, but also copies over locators.
+    Like :func:`deepcopy`, but also copies over locators.
     """
 
     res = deepcopy(value)
@@ -134,7 +134,7 @@
 
 def copy_locators(target, source):
     """
-    Copies over :code:`_locator` for all elements, recursively.
+    Copies over ``_locator`` for all elements, recursively.
 
     Assumes that target and source have exactly the same list/dict structure.
     """
diff --git a/aria/parser/reading/reader.py b/aria/parser/reading/reader.py
index fe64697..1a29f11 100644
--- a/aria/parser/reading/reader.py
+++ b/aria/parser/reading/reader.py
@@ -18,7 +18,7 @@
     """
     Base class for ARIA readers.
 
-    Readers provide agnostic raw data by consuming :class:`aria.loading.Loader` instances.
+    Readers provide agnostic raw data by consuming :class:`aria.parser.loading.Loader` instances.
     """
 
     def __init__(self, context, location, loader):
diff --git a/aria/parser/specification.py b/aria/parser/specification.py
index 714bed1..4f452b8 100644
--- a/aria/parser/specification.py
+++ b/aria/parser/specification.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Utilities for cross-referencing code with specification documents.
+"""
+
 import re
 
 from ..extension import parser
diff --git a/aria/parser/validation/__init__.py b/aria/parser/validation/__init__.py
index fead43b..21632ba 100644
--- a/aria/parser/validation/__init__.py
+++ b/aria/parser/validation/__init__.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Validation package.
+"""
+
 from .issue import Issue
 from .context import ValidationContext
 
diff --git a/aria/parser/validation/context.py b/aria/parser/validation/context.py
index d81f1cd..ef641bd 100644
--- a/aria/parser/validation/context.py
+++ b/aria/parser/validation/context.py
@@ -23,13 +23,16 @@
 
 class ValidationContext(object):
     """
-    Properties:
+    Validation context.
 
-    * :code:`allow_unknown_fields`: When False (the default) will report an issue
-            if an unknown field is used
-    * :code:`allow_primitive_coersion`: When False (the default) will not attempt to
-            coerce primitive field types
-    * :code:`max_level`: Maximum validation level to report (default is all)
+    :ivar allow_unknown_fields: when ``False`` (the default) will report an issue if an unknown
+     field is used
+    :vartype allow_unknown_fields: bool
+    :ivar allow_primitive_coersion`: when ``False`` (the default) will not attempt to coerce
+     primitive field types
+    :vartype allow_primitive_coersion: bool
+    :ivar max_level: maximum validation level to report (default is all)
+    :vartype max_level: int
     """
 
     def __init__(self):
diff --git a/aria/storage/__init__.py b/aria/storage/__init__.py
index bd7c8c1..a553ca7 100644
--- a/aria/storage/__init__.py
+++ b/aria/storage/__init__.py
@@ -14,29 +14,9 @@
 # limitations under the License.
 
 """
-ARIA's storage Sub-Package
-Path: aria.storage
-
-Storage package is a generic abstraction over different storage types.
-We define this abstraction with the following components:
-
-1. storage: simple mapi to use
-2. driver: implementation of the database client mapi.
-3. model: defines the structure of the table/document.
-4. field: defines a field/item in the model.
-
-API:
-    * application_storage_factory - function, default ARIA storage factory.
-    * Storage - class, simple storage mapi.
-    * models - module, default ARIA standard models.
-    * structures - module, default ARIA structures - holds the base model,
-                   and different fields types.
-    * Model - class, abstract model implementation.
-    * Field - class, base field implementation.
-    * IterField - class, base iterable field implementation.
-    * drivers - module, a pool of ARIA standard drivers.
-    * StorageDriver - class, abstract model implementation.
+Storage package.
 """
+
 from .core import (
     Storage,
     ModelStorage,
diff --git a/aria/storage/api.py b/aria/storage/api.py
index 3304721..a337743 100644
--- a/aria/storage/api.py
+++ b/aria/storage/api.py
@@ -12,15 +12,17 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
 """
-General storage API
+Storage APIs.
 """
+
 import threading
 
 
 class StorageAPI(object):
     """
-    General storage Base API
+    Base class for storage APIs.
     """
     def create(self, **kwargs):
         """
@@ -33,15 +35,12 @@
 
 class ModelAPI(StorageAPI):
     """
-    A Base object for the model.
+    Base class for model APIs ("MAPI").
     """
     def __init__(self, model_cls, name=None, **kwargs):
         """
-        Base model API
-
-        :param model_cls: the representing class of the model
-        :param str name: the name of the model
-        :param kwargs:
+        :param model_cls: representing class of the model
+        :param name: name of the model
         """
         super(ModelAPI, self).__init__(**kwargs)
         self._model_cls = model_cls
@@ -59,46 +58,42 @@
     @property
     def name(self):
         """
-        The name of the class
-        :return: name of the class
+        Name of the class.
+
+        :type: :obj:`basestring`
         """
         return self._name
 
     @property
     def model_cls(self):
         """
-        The class represting the model
-        :return:
+        Class representing the model
+
+        :type: :obj:`Type`
         """
         return self._model_cls
 
     def get(self, entry_id, filters=None, **kwargs):
         """
-        Get entry from storage.
+        Gets a model from storage.
 
         :param entry_id:
-        :param kwargs:
-        :return:
         """
         raise NotImplementedError('Subclass must implement abstract get method')
 
     def put(self, entry, **kwargs):
         """
-        Store entry in storage
+        Puts a model in storage.
 
         :param entry:
-        :param kwargs:
-        :return:
         """
         raise NotImplementedError('Subclass must implement abstract store method')
 
     def delete(self, entry_id, **kwargs):
         """
-        Delete entry from storage.
+        Deletes a model from storage.
 
         :param entry_id:
-        :param kwargs:
-        :return:
         """
         raise NotImplementedError('Subclass must implement abstract delete method')
 
@@ -107,32 +102,27 @@
 
     def iter(self, **kwargs):
         """
-        Iter over the entries in storage.
-
-        :param kwargs:
-        :return:
+        Iterate over all models in storage.
         """
         raise NotImplementedError('Subclass must implement abstract iter method')
 
     def update(self, entry, **kwargs):
         """
-        Update entry in storage.
+        Update a model in storage.
 
         :param entry:
         :param kwargs:
-        :return:
         """
         raise NotImplementedError('Subclass must implement abstract update method')
 
 
 class ResourceAPI(StorageAPI):
     """
-    A Base object for the resource.
+    Base class for resource APIs ("RAPI").
     """
     def __init__(self, name, **kwargs):
         """
-        Base resource API
-        :param str name: the resource type
+        :param name: resource type
         """
         super(ResourceAPI, self).__init__(**kwargs)
         self._name = name
@@ -140,63 +130,57 @@
     @property
     def name(self):
         """
-        The name of the resource
-        :return:
+        Name of resource.
+
+        :type: :obj:`basestring`
         """
         return self._name
 
     def read(self, entry_id, path, **kwargs):
         """
-        Get a bytesteam from the storage.
+        Get a bytesteam for a resource from storage.
 
         :param entry_id:
         :param path:
-        :param kwargs:
-        :return:
         """
         raise NotImplementedError('Subclass must implement abstract read method')
 
     def delete(self, entry_id, path, **kwargs):
         """
-        Delete a resource from the storage.
+        Delete a resource from storage.
 
         :param entry_id:
         :param path:
-        :param kwargs:
-        :return:
         """
         raise NotImplementedError('Subclass must implement abstract delete method')
 
     def download(self, entry_id, destination, path=None, **kwargs):
         """
-        Download a resource from the storage.
+        Download a resource from storage.
 
         :param entry_id:
         :param destination:
         :param path:
-        :param kwargs:
-        :return:
         """
         raise NotImplementedError('Subclass must implement abstract download method')
 
     def upload(self, entry_id, source, path=None, **kwargs):
         """
-        Upload a resource to the storage.
+        Upload a resource to storage.
 
         :param entry_id:
         :param source:
         :param path:
-        :param kwargs:
-        :return:
         """
         raise NotImplementedError('Subclass must implement abstract upload method')
 
 
 def generate_lower_name(model_cls):
     """
-    Generates the name of the class from the class object. e.g. SomeClass -> some_class
-    :param model_cls: the class to evaluate.
-    :return: lower name
+    Generates the name of the class from the class object, e.g. ``SomeClass`` -> ``some_class``
+
+    :param model_cls: class to evaluate
+    :return: lowercase name
     :rtype: basestring
     """
     return getattr(model_cls, '__mapiname__', model_cls.__tablename__)
diff --git a/aria/storage/collection_instrumentation.py b/aria/storage/collection_instrumentation.py
index 454f97a..c90cb18 100644
--- a/aria/storage/collection_instrumentation.py
+++ b/aria/storage/collection_instrumentation.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Utilities for instrumenting collections of models in storage.
+"""
+
 from . import exceptions
 
 
@@ -42,17 +46,15 @@
         Instantiates the object from existing seq.
 
         :param seq: the original sequence to load from
-        :return:
         """
         raise NotImplementedError
 
     def _set(self, key, value):
         """
-        set the changes for the current object (not in the db)
+        Sets the changes for the current object (not in the database).
 
         :param key:
         :param value:
-        :return:
         """
         raise NotImplementedError
 
@@ -61,10 +63,10 @@
 
     def _instrument(self, key, value):
         """
-        Instruments any collection to track changes (and ease of access)
+        Instruments any collection to track changes (and ease of access).
+
         :param key:
         :param value:
-        :return:
         """
         if isinstance(value, _InstrumentedCollection):
             return value
@@ -79,9 +81,9 @@
 
     def _raw_value(self, value):
         """
-        Get the raw value.
+        Gets the raw value.
+
         :param value:
-        :return:
         """
         if isinstance(value, self._field_cls):
             return value.value
@@ -89,10 +91,10 @@
 
     def _encapsulate_value(self, key, value):
         """
-        Create a new item cls if needed.
+        Creates a new item class if needed.
+
         :param key:
         :param value:
-        :return:
         """
         if isinstance(value, self._field_cls):
             return value
@@ -101,10 +103,10 @@
 
     def __setitem__(self, key, value):
         """
-        Update the values in both the local and the db locations.
+        Updates the values in both the local and the database locations.
+
         :param key:
         :param value:
-        :return:
         """
         self._set(key, value)
         if self._is_top_level:
@@ -119,11 +121,11 @@
 
     def _set_field(self, collection, key, value):
         """
-        enables updating the current change in the ancestors
-        :param collection: the collection to change
-        :param key: the key for the specific field
-        :param value: the new value
-        :return:
+        Enables updating the current change in the ancestors.
+
+        :param collection: collection to change
+        :param key: key for the specific field
+        :param value: new value
         """
         if isinstance(value, _InstrumentedCollection):
             value = value._raw
@@ -209,9 +211,10 @@
 
     def __init__(self, mapi, *args, **kwargs):
         """
-        The original model
-        :param wrapped: the model to be instrumented
-        :param mapi: the mapi for that model
+        The original model.
+
+        :param wrapped: model to be instrumented
+        :param mapi: MAPI for the wrapped model
         """
         super(_InstrumentedModel, self).__init__(*args, **kwargs)
         self._mapi = mapi
@@ -261,11 +264,10 @@
 
     def __init__(self, instrumentation_kwargs, *args, **kwargs):
         """
-
-        :param instrumented_cls: The class to be instrumented
-        :param instrumentation_cls: the instrumentation cls
-        :param wrapped: the currently wrapped instance
-        :param kwargs: and kwargs to the passed to the instrumented class.
+        :param instrumented_cls: class to be instrumented
+        :param instrumentation_cls: instrumentation cls
+        :param wrapped: currently wrapped instance
+        :param kwargs: passed to the instrumented class
         """
         super(_WrappedModel, self).__init__(*args, **kwargs)
         self._kwargs = instrumentation_kwargs
diff --git a/aria/storage/core.py b/aria/storage/core.py
index 06c29e8..74b1147 100644
--- a/aria/storage/core.py
+++ b/aria/storage/core.py
@@ -14,29 +14,9 @@
 # limitations under the License.
 
 """
-ARIA's storage Sub-Package
-Path: aria.storage
-
-Storage package is a generic abstraction over different storage types.
-We define this abstraction with the following components:
-
-1. storage: simple mapi to use
-2. driver: implementation of the database client mapi.
-3. model: defines the structure of the table/document.
-4. field: defines a field/item in the model.
-
-API:
-    * application_storage_factory - function, default ARIA storage factory.
-    * Storage - class, simple storage mapi.
-    * models - module, default ARIA standard models.
-    * structures - module, default ARIA structures - holds the base model,
-                   and different fields types.
-    * Model - class, abstract model implementation.
-    * Field - class, base field implementation.
-    * IterField - class, base iterable field implementation.
-    * drivers - module, a pool of ARIA standard drivers.
-    * StorageDriver - class, abstract model implementation.
+Storage API management.
 """
+
 import copy
 from contextlib import contextmanager
 
@@ -52,7 +32,7 @@
 
 class Storage(LoggerMixin):
     """
-    Represents the storage
+    Base class for storage managers.
     """
     def __init__(self,
                  api_cls,
@@ -62,13 +42,12 @@
                  initiator_kwargs=None,
                  **kwargs):
         """
-
-        :param api_cls: API cls for each model.
+        :param api_cls: API class for each entry
         :param api_kwargs:
-        :param items: the items to register
-        :param initiator: a func which initializes the storage before the first use.
-        This function should return a dict, this dict would be passed in addition to the api kwargs.
-        This enables the creation of any unpickable objects across process.
+        :param items: items to register
+        :param initiator: function which initializes the storage before the first use; this function
+         should return a dict, this dict would be passed in addition to the API kwargs; this enables
+         the creation of non-serializable objects
         :param initiator_kwargs:
         :param kwargs:
         """
@@ -112,22 +91,22 @@
 
     def register(self, entry):
         """
-        Register the entry to the storage
-        :param name:
-        :return:
+        Register an API.
+
+        :param entry:
         """
         raise NotImplementedError('Subclass must implement abstract register method')
 
 
 class ResourceStorage(Storage):
     """
-    Represents resource storage.
+    Manages storage resource APIs ("RAPIs").
     """
     def register(self, name):
         """
-        Register the resource type to resource storage.
-        :param name:
-        :return:
+        Register a storage resource API ("RAPI").
+
+        :param name: name
         """
         self.registered[name] = self.api(name=name, **self._all_api_kwargs)
         self.registered[name].create()
@@ -136,7 +115,7 @@
 
 class ModelStorage(Storage):
     """
-    Represents model storage.
+    Manages storage model APIs ("MAPIs").
     """
     def __init__(self, *args, **kwargs):
         if kwargs.get('initiator', None) is None:
@@ -145,9 +124,9 @@
 
     def register(self, model_cls):
         """
-        Register the model into the model storage.
-        :param model_cls: the model to register.
-        :return:
+        Register a storage model API ("MAPI").
+
+        :param model_cls: model API to register
         """
         model_name = model_cls.__modelname__
         if model_name in self.registered:
@@ -162,8 +141,7 @@
 
     def drop(self):
         """
-        Drop all the tables from the model.
-        :return:
+        Drop all the tables.
         """
         for mapi in self.registered.values():
             mapi.drop()
diff --git a/aria/storage/exceptions.py b/aria/storage/exceptions.py
index 3f0ecec..c538876 100644
--- a/aria/storage/exceptions.py
+++ b/aria/storage/exceptions.py
@@ -12,9 +12,11 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
 """
-Storage based exceptions
+Storage exceptions.
 """
+
 from .. import exceptions
 
 
diff --git a/aria/storage/filesystem_rapi.py b/aria/storage/filesystem_rapi.py
index 3ddc520..b425fa2 100644
--- a/aria/storage/filesystem_rapi.py
+++ b/aria/storage/filesystem_rapi.py
@@ -12,9 +12,11 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
 """
-File system based RAPI
+File system implementation of the storage resource API ("RAPI").
 """
+
 import os
 import shutil
 from multiprocessing import RLock
@@ -30,13 +32,12 @@
 
 class FileSystemResourceAPI(api.ResourceAPI):
     """
-    File system resource storage.
+    File system implementation of the storage resource API ("RAPI").
     """
 
     def __init__(self, directory, **kwargs):
         """
-        File system implementation for storage api.
-        :param str directory: root dir for storage.
+        :param directory: root dir for storage
         """
         super(FileSystemResourceAPI, self).__init__(**kwargs)
         self.directory = directory
@@ -47,8 +48,7 @@
     @contextmanager
     def connect(self):
         """
-        Established a connection and destroys it after use.
-        :return:
+        Establishes a connection and destroys it after use.
         """
         try:
             self._establish_connection()
@@ -60,16 +60,13 @@
 
     def _establish_connection(self):
         """
-        Establish a conenction. used in the 'connect' contextmanager.
-        :return:
+        Establishes a connection. Used in the ``connect`` context manager.
         """
         self._lock.acquire()
 
-
     def _destroy_connection(self):
         """
-        Destroy a connection. used in the 'connect' contextmanager.
-        :return:
+        Destroys a connection. Used in the ``connect`` context manager.
         """
         self._lock.release()
 
@@ -79,9 +76,9 @@
 
     def create(self, **kwargs):
         """
-        Create directory in storage by path.
-        tries to create the root directory as well.
-        :param str name: path of file in storage.
+        Creates a directory in by path. Tries to create the root directory as well.
+
+        :param name: path of directory
         """
         try:
             os.makedirs(self.directory)
@@ -94,11 +91,11 @@
 
     def read(self, entry_id, path, **_):
         """
-        Retrieve the content of a file system storage resource.
+        Retrieves the contents of a file.
 
-        :param str entry_id: the id of the entry.
-        :param str path: a path to the specific resource to read.
-        :return: the content of the file.
+        :param entry_id: entry ID
+        :param path: path to resource
+        :return: contents of the file
         :rtype: bytes
         """
         resource_relative_path = os.path.join(self.name, entry_id, path or '')
@@ -118,11 +115,11 @@
 
     def download(self, entry_id, destination, path=None, **_):
         """
-        Download a specific file or dir from the file system resource storage.
+        Downloads a file or directory.
 
-        :param str entry_id: the id of the entry.
-        :param str destination: the destination to download to
-        :param str path: the path to download relative to the root of the entry (otherwise all).
+        :param entry_id: entry ID
+        :param destination: download destination
+        :param path: path to download relative to the root of the entry (otherwise all)
         """
         resource_relative_path = os.path.join(self.name, entry_id, path or '')
         resource = os.path.join(self.directory, resource_relative_path)
@@ -136,10 +133,10 @@
 
     def upload(self, entry_id, source, path=None, **_):
         """
-        Uploads a specific file or dir to the file system resource storage.
+        Uploads a file or directory.
 
-        :param str entry_id: the id of the entry.
-        :param source: the source of the files to upload.
+        :param entry_id: entry ID
+        :param source: source of the files to upload
         :param path: the destination of the file/s relative to the entry root dir.
         """
         resource_directory = os.path.join(self.directory, self.name, entry_id)
@@ -153,10 +150,10 @@
 
     def delete(self, entry_id, path=None, **_):
         """
-        Deletes a file system storage resource.
+        Deletes a file or directory.
 
-        :param str entry_id: the id of the entry.
-        :param str path: a path to delete relative to the root of the entry (otherwise all).
+        :param entry_id: entry ID
+        :param path: path to delete relative to the root of the entry (otherwise all)
         """
         destination = os.path.join(self.directory, self.name, entry_id, path or '')
         if os.path.exists(destination):
diff --git a/aria/storage/sql_mapi.py b/aria/storage/sql_mapi.py
index bb6223a..975ada7 100644
--- a/aria/storage/sql_mapi.py
+++ b/aria/storage/sql_mapi.py
@@ -12,9 +12,11 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
 """
-SQLAlchemy based MAPI
+SQLAlchemy implementation of the storage model API ("MAPI").
 """
+
 import os
 import platform
 
@@ -42,7 +44,7 @@
 
 class SQLAlchemyModelAPI(api.ModelAPI):
     """
-    SQL based MAPI.
+    SQLAlchemy implementation of the storage model API ("MAPI").
     """
 
     def __init__(self,
@@ -54,7 +56,8 @@
         self._session = session
 
     def get(self, entry_id, include=None, **kwargs):
-        """Return a single result based on the model class and element ID
+        """
+        Returns a single result based on the model class and element ID
         """
         query = self._get_query(include, {'id': entry_id})
         result = query.first()
@@ -102,25 +105,28 @@
              filters=None,
              sort=None,
              **kwargs):
-        """Return a (possibly empty) list of `model_class` results
+        """
+        Returns a (possibly empty) list of ``model_class`` results.
         """
         for result in self._get_query(include, filters, sort):
             yield self._instrument(result)
 
     def put(self, entry, **kwargs):
-        """Create a `model_class` instance from a serializable `model` object
+        """
+        Creatse a ``model_class`` instance from a serializable ``model`` object.
 
-        :param entry: A dict with relevant kwargs, or an instance of a class
-        that has a `to_dict` method, and whose attributes match the columns
-        of `model_class` (might also my just an instance of `model_class`)
-        :return: An instance of `model_class`
+        :param entry: dict with relevant kwargs, or an instance of a class that has a ``to_dict``
+         method, and whose attributes match the columns of ``model_class`` (might also be just an
+         instance of ``model_class``)
+        :return: an instance of ``model_class``
         """
         self._session.add(entry)
         self._safe_commit()
         return entry
 
     def delete(self, entry, **kwargs):
-        """Delete a single result based on the model class and element ID
+        """
+        Deletes a single result based on the model class and element ID.
         """
         self._load_relationships(entry)
         self._session.delete(entry)
@@ -128,17 +134,19 @@
         return entry
 
     def update(self, entry, **kwargs):
-        """Add `instance` to the DB session, and attempt to commit
+        """
+        Adds ``instance`` to the database session, and attempts to commit.
 
-        :return: The updated instance
+        :return: updated instance
         """
         return self.put(entry)
 
     def refresh(self, entry):
-        """Reload the instance with fresh information from the DB
+        """
+        Reloads the instance with fresh information from the database.
 
-        :param entry: Instance to be re-loaded from the DB
-        :return: The refreshed instance
+        :param entry: instance to be re-loaded from the database
+        :return: refreshed instance
         """
         self._session.refresh(entry)
         self._load_relationships(entry)
@@ -160,14 +168,14 @@
 
     def drop(self):
         """
-        Drop the table from the storage.
-        :return:
+        Drops the table.
         """
         self.model_cls.__table__.drop(self._engine)
 
     def _safe_commit(self):
-        """Try to commit changes in the session. Roll back if exception raised
-        Excepts SQLAlchemy errors and rollbacks if they're caught
+        """
+        Try to commit changes in the session. Roll back if exception raised SQLAlchemy errors and
+        rolls back if they're caught.
         """
         try:
             self._session.commit()
@@ -179,11 +187,11 @@
             raise exceptions.StorageError('SQL Storage error: {0}'.format(str(e)))
 
     def _get_base_query(self, include, joins):
-        """Create the initial query from the model class and included columns
+        """
+        Create the initial query from the model class and included columns.
 
-        :param include: A (possibly empty) list of columns to include in
-        the query
-        :return: An SQLAlchemy AppenderQuery object
+        :param include: (possibly empty) list of columns to include in the query
+        :return: SQLAlchemy AppenderQuery object
         """
         # If only some columns are included, query through the session object
         if include:
@@ -199,9 +207,10 @@
 
     @staticmethod
     def _get_joins(model_class, columns):
-        """Get a list of all the tables on which we need to join
+        """
+        Gets a list of all the tables on which we need to join.
 
-        :param columns: A set of all attributes involved in the query
+        :param columns: set of all attributes involved in the query
         """
 
         # Using a list instead of a set because order is important
@@ -222,12 +231,13 @@
 
     @staticmethod
     def _sort_query(query, sort=None):
-        """Add sorting clauses to the query
+        """
+        Adds sorting clauses to the query.
 
-        :param query: Base SQL query
-        :param sort: An optional dictionary where keys are column names to
-        sort by, and values are the order (asc/desc)
-        :return: An SQLAlchemy AppenderQuery object
+        :param query: base SQL query
+        :param sort: optional dictionary where keys are column names to sort by, and values are
+         the order (asc/desc)
+        :return: SQLAlchemy AppenderQuery object
         """
         if sort:
             for column, order in sort.items():
@@ -237,13 +247,13 @@
         return query
 
     def _filter_query(self, query, filters):
-        """Add filter clauses to the query
+        """
+        Adds filter clauses to the query.
 
-        :param query: Base SQL query
-        :param filters: An optional dictionary where keys are column names to
-        filter by, and values are values applicable for those columns (or lists
-        of such values)
-        :return: An SQLAlchemy AppenderQuery object
+        :param query: base SQL query
+        :param filters: optional dictionary where keys are column names to filter by, and values
+         are values applicable for those columns (or lists of such values)
+        :return: SQLAlchemy AppenderQuery object
         """
         return self._add_value_filter(query, filters)
 
@@ -264,17 +274,16 @@
                    include=None,
                    filters=None,
                    sort=None):
-        """Get an SQL query object based on the params passed
+        """
+        Gets a SQL query object based on the params passed.
 
-        :param model_class: SQL DB table class
-        :param include: An optional list of columns to include in the query
-        :param filters: An optional dictionary where keys are column names to
-        filter by, and values are values applicable for those columns (or lists
-        of such values)
-        :param sort: An optional dictionary where keys are column names to
-        sort by, and values are the order (asc/desc)
-        :return: A sorted and filtered query with only the relevant
-        columns
+        :param model_class: SQL database table class
+        :param include: optional list of columns to include in the query
+        :param filters: optional dictionary where keys are column names to filter by, and values
+         are values applicable for those columns (or lists of such values)
+        :param sort: optional dictionary where keys are column names to sort by, and values are the
+         order (asc/desc)
+        :return: sorted and filtered query with only the relevant columns
         """
         include, filters, sort, joins = self._get_joins_and_converted_columns(
             include, filters, sort
@@ -305,9 +314,10 @@
                                          include,
                                          filters,
                                          sort):
-        """Get a list of tables on which we need to join and the converted
-        `include`, `filters` and `sort` arguments (converted to actual SQLA
-        column/label objects instead of column names)
+        """
+        Gets a list of tables on which we need to join and the converted ``include``, ``filters``
+        and ```sort`` arguments (converted to actual SQLAlchemy column/label objects instead of
+        column names).
         """
         include = include or []
         filters = filters or dict()
@@ -325,8 +335,9 @@
                                       include,
                                       filters,
                                       sort):
-        """Go over the optional parameters (include, filters, sort), and
-        replace column names with actual SQLA column objects
+        """
+        Gooes over the optional parameters (include, filters, sort), and replace column names with
+        actual SQLAlechmy column objects.
         """
         include = [self._get_column(c) for c in include]
         filters = dict((self._get_column(c), filters[c]) for c in filters)
@@ -335,9 +346,10 @@
         return include, filters, sort
 
     def _get_column(self, column_name):
-        """Return the column on which an action (filtering, sorting, etc.)
-        would need to be performed. Can be either an attribute of the class,
-        or an association proxy linked to a relationship the class has
+        """
+        Returns the column on which an action (filtering, sorting, etc.) would need to be performed.
+        Can be either an attribute of the class, or an association proxy linked to a relationship
+        in the class.
         """
         column = getattr(self.model_cls, column_name)
         if column.is_attribute:
@@ -352,15 +364,16 @@
 
     @staticmethod
     def _paginate(query, pagination):
-        """Paginate the query by size and offset
+        """
+        Paginates the query by size and offset.
 
-        :param query: Current SQLAlchemy query object
-        :param pagination: An optional dict with size and offset keys
-        :return: A tuple with four elements:
-        - res ults: `size` items starting from `offset`
-        - the total count of items
-        - `size` [default: 0]
-        - `offset` [default: 0]
+        :param query: current SQLAlchemy query object
+        :param pagination: optional dict with size and offset keys
+        :return: tuple with four elements:
+         * results: ``size`` items starting from ``offset``
+         * the total count of items
+         * ``size`` [default: 0]
+         * ``offset`` [default: 0]
         """
         if pagination:
             size = pagination.get('size', 0)
@@ -374,8 +387,9 @@
 
     @staticmethod
     def _load_relationships(instance):
-        """A helper method used to overcome a problem where the relationships
-        that rely on joins aren't being loaded automatically
+        """
+        Helper method used to overcome a problem where the relationships that rely on joins aren't
+        being loaded automatically.
         """
         for rel in instance.__mapper__.relationships:
             getattr(instance, rel.key)
@@ -389,13 +403,15 @@
 
 def init_storage(base_dir, filename='db.sqlite'):
     """
-    A builtin ModelStorage initiator.
-    Creates a sqlalchemy engine and a session to be passed to the mapi.
+    Built-in ModelStorage initiator.
 
-    Initiator_kwargs must be passed to the ModelStorage which must hold the base_dir for the
-    location of the db file, and an option filename. This would create an sqlite db.
-    :param base_dir: the dir of the db
-    :param filename: the db file name.
+    Creates a SQLAlchemy engine and a session to be passed to the MAPI.
+
+    ``initiator_kwargs`` must be passed to the ModelStorage which must hold the ``base_dir`` for the
+    location of the database file, and an option filename. This would create an SQLite database.
+
+    :param base_dir: directory of the database
+    :param filename: database file name.
     :return:
     """
     uri = 'sqlite:///{platform_char}{path}'.format(
@@ -415,7 +431,7 @@
 
 class ListResult(list):
     """
-    a ListResult contains results about the requested items.
+    Contains results about the requested items.
     """
     def __init__(self, metadata, *args, **qwargs):
         super(ListResult, self).__init__(*args, **qwargs)
diff --git a/aria/utils/__init__.py b/aria/utils/__init__.py
index ae1e83e..2a957a9 100644
--- a/aria/utils/__init__.py
+++ b/aria/utils/__init__.py
@@ -12,3 +12,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+"""
+General-purpose utilities package.
+"""
diff --git a/aria/utils/archive.py b/aria/utils/archive.py
index 63d9004..29efcb1 100644
--- a/aria/utils/archive.py
+++ b/aria/utils/archive.py
@@ -10,6 +10,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Archive utilities.
+"""
 
 import os
 import tarfile
diff --git a/aria/utils/argparse.py b/aria/utils/argparse.py
index 365c148..a05a841 100644
--- a/aria/utils/argparse.py
+++ b/aria/utils/argparse.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Enhancements to Python's ``argparse`` module.
+"""
+
 from __future__ import absolute_import  # so we can import standard 'argparse'
 
 from argparse import ArgumentParser as BaseArgumentParser
@@ -27,7 +31,7 @@
 
     def add_flag_argument(self, name, help_true=None, help_false=None, default=False):
         """
-        Adds a flag argument as two arguments: :code:`--my-flag` and :code:`--no-my-flag`.
+        Adds a flag argument as two arguments: ``--my-flag`` and ``--no-my-flag``.
         """
 
         dest = name.replace('-', '_')
diff --git a/aria/utils/caching.py b/aria/utils/caching.py
index c9e475a..5f8cd88 100644
--- a/aria/utils/caching.py
+++ b/aria/utils/caching.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Caching utilities.
+"""
+
 from __future__ import absolute_import  # so we can import standard 'collections' and 'threading'
 
 from threading import Lock
@@ -27,8 +31,8 @@
 
     The implementation is thread-safe.
 
-    Supports :code:`cache_info` to be compatible with Python 3's :code:`functools.lru_cache`.
-    Note that the statistics are combined for all instances of the class.
+    Supports ``cache_info`` to be compatible with Python 3's ``functools.lru_cache``. Note that the
+    statistics are combined for all instances of the class.
 
     Won't use the cache if not called when bound to an object, allowing you to override the cache.
 
@@ -39,6 +43,7 @@
     ENABLED = True
 
     def __init__(self, func):
+        self.__doc__ = func.__doc__
         self.func = func
         self.hits = 0
         self.misses = 0
diff --git a/aria/utils/collections.py b/aria/utils/collections.py
index 1e732aa..ccc37a1 100644
--- a/aria/utils/collections.py
+++ b/aria/utils/collections.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Additional collection classes and collection utilities.
+"""
+
 from __future__ import absolute_import  # so we can import standard 'collections'
 
 from copy import deepcopy
@@ -32,8 +36,8 @@
     """
     An immutable list.
 
-    After initialization it will raise :class:`TypeError` exceptions if modification
-    is attempted.
+    After initialization it will raise :class:`~exceptions.TypeError` exceptions if modification is
+    attempted.
 
     Note that objects stored in the list may not be immutable.
     """
@@ -78,12 +82,13 @@
 
 EMPTY_READ_ONLY_LIST = FrozenList()
 
+
 class FrozenDict(OrderedDict):
     """
     An immutable ordered dict.
 
-    After initialization it will raise :class:`TypeError` exceptions if modification
-    is attempted.
+    After initialization it will raise :class:`~exceptions.TypeError` exceptions if modification is
+    attempted.
 
     Note that objects stored in the dict may not be immutable.
     """
@@ -109,9 +114,11 @@
 
 EMPTY_READ_ONLY_DICT = FrozenDict()
 
+
 class StrictList(list):
     """
-    A list that raises :class:`TypeError` exceptions when objects of the wrong type are inserted.
+    A list that raises :class:`~exceptions.TypeError` exceptions when objects of the wrong type are
+    inserted.
     """
 
     def __init__(self,
@@ -168,10 +175,11 @@
         value = self._wrap(value)
         return super(StrictList, self).insert(index, value)
 
+
 class StrictDict(OrderedDict):
     """
-    An ordered dict that raises :class:`TypeError` exceptions
-    when keys or values of the wrong type are used.
+    An ordered dict that raises :class:`~exceptions.TypeError` exceptions when keys or values of the
+    wrong type are used.
     """
 
     def __init__(self,
@@ -211,6 +219,7 @@
             value = self.wrapper_function(value)
         return super(StrictDict, self).__setitem__(key, value)
 
+
 def merge(dict_a, dict_b, path=None, strict=False):
     """
     Merges dicts, recursively.
@@ -234,12 +243,14 @@
             dict_a[key] = value_b
     return dict_a
 
+
 def is_removable(_container, _key, v):
     return (v is None) or ((isinstance(v, dict) or isinstance(v, list)) and (len(v) == 0))
 
+
 def prune(value, is_removable_function=is_removable):
     """
-    Deletes :code:`None` and empty lists and dicts, recursively.
+    Deletes ``None`` and empty lists and dicts, recursively.
     """
 
     if isinstance(value, list):
@@ -258,10 +269,11 @@
     return value
 
 
-# TODO (left for tal): Move following two methods to some place parser specific
+# TODO: Move following two methods to some place parser specific
+
 def deepcopy_with_locators(value):
     """
-    Like :code:`deepcopy`, but also copies over locators.
+    Like :func:`~copy.deepcopy`, but also copies over locators.
     """
 
     res = deepcopy(value)
@@ -271,7 +283,7 @@
 
 def copy_locators(target, source):
     """
-    Copies over :code:`_locator` for all elements, recursively.
+    Copies over ``_locator`` for all elements, recursively.
 
     Assumes that target and source have exactly the same list/dict structure.
     """
diff --git a/aria/utils/console.py b/aria/utils/console.py
index 55d2529..642cbb1 100644
--- a/aria/utils/console.py
+++ b/aria/utils/console.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Abstraction API above terminal color libraries.
+"""
+
 from clint.textui.core import STDOUT
 from clint.textui import puts as _puts
 from clint.textui.colored import ColoredString as _ColoredString
diff --git a/aria/utils/exceptions.py b/aria/utils/exceptions.py
index b60cee4..5bb0e6d 100644
--- a/aria/utils/exceptions.py
+++ b/aria/utils/exceptions.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Utilities for extracting and formatting Python exceptions.
+"""
+
 import sys
 import linecache
 import StringIO
diff --git a/aria/utils/file.py b/aria/utils/file.py
index 6d1aa16..75f2859 100644
--- a/aria/utils/file.py
+++ b/aria/utils/file.py
@@ -13,13 +13,19 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+File utilities.
+"""
+
 import errno
 import os
 import shutil
 
 
 def makedirs(path):
-    """An extension of os.makedirs that doesn't fail if the directory already exists"""
+    """
+    Enhancement of :func:`os.makedirs` that doesn't fail if the directory already exists.
+    """
     if os.path.isdir(path):
         return
     try:
@@ -29,7 +35,6 @@
             raise
 
 def remove_if_exists(path):
-
     try:
         if os.path.isfile(path):
             os.remove(path)
diff --git a/aria/utils/formatting.py b/aria/utils/formatting.py
index b8d24cd..fa34b7d 100644
--- a/aria/utils/formatting.py
+++ b/aria/utils/formatting.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+String formatting and string-based format utilities.
+"""
+
 import json
 from types import MethodType
 
@@ -42,8 +46,7 @@
 
 class JsonAsRawEncoder(json.JSONEncoder):
     """
-    A :class:`JSONEncoder` that will use the :code:`as_raw` property of objects
-    if available.
+    A :class:`JSONEncoder` that will use the ``as_raw`` property of objects if available.
     """
     def raw_encoder_default(self, obj):
         try:
@@ -61,8 +64,7 @@
 
 class YamlAsRawDumper(yaml.dumper.RoundTripDumper):  # pylint: disable=too-many-ancestors
     """
-    A :class:`RoundTripDumper` that will use the :code:`as_raw` property of objects
-    if available.
+    A :class:`RoundTripDumper` that will use the ``as_raw`` property of objects if available.
     """
 
     def represent_data(self, data):
@@ -101,8 +103,8 @@
 
 def safe_str(value):
     """
-    Like :code:`str` coercion, but makes sure that Unicode strings are properly
-    encoded, and will never return None.
+    Like :class:`str` coercion, but makes sure that Unicode strings are properly encoded, and will
+    never return ``None``.
     """
 
     try:
@@ -113,7 +115,7 @@
 
 def safe_repr(value):
     """
-    Like :code:`repr`, but calls :code:`as_raw` and :code:`as_agnostic` first.
+    Like :func:`repr`, but calls :func:`as_raw` and :func:`as_agnostic` first.
     """
 
     return repr(as_agnostic(as_raw(value)))
@@ -143,7 +145,7 @@
 
 def as_raw(value):
     """
-    Converts values using their :code:`as_raw` property, if it exists, recursively.
+    Converts values using their ``as_raw`` property, if it exists, recursively.
     """
 
     if hasattr(value, 'as_raw'):
@@ -164,7 +166,7 @@
 
 def as_raw_list(value):
     """
-    Assuming value is a list, converts its values using :code:`as_raw`.
+    Assuming value is a list, converts its values using :func:`as_raw`.
     """
 
     if value is None:
@@ -176,8 +178,7 @@
 
 def as_raw_dict(value):
     """
-    Assuming value is a dict, converts its values using :code:`as_raw`.
-    The keys are left as is.
+    Assuming value is a dict, converts its values using :func:`as_raw`. The keys are left as is.
     """
 
     if value is None:
@@ -188,8 +189,8 @@
 
 def as_agnostic(value):
     """
-    Converts subclasses of list and dict to standard lists and dicts, and Unicode strings
-    to non-Unicode if possible, recursively.
+    Converts subclasses of list and dict to standard lists and dicts, and Unicode strings to
+    non-Unicode if possible, recursively.
 
     Useful for creating human-readable output of structures.
     """
@@ -216,8 +217,7 @@
 
 def json_dumps(value, indent=2):
     """
-    JSON dumps that supports Unicode and the :code:`as_raw` property of objects
-    if available.
+    JSON dumps that supports Unicode and the ``as_raw`` property of objects if available.
     """
 
     return json.dumps(value, indent=indent, ensure_ascii=False, cls=JsonAsRawEncoder)
@@ -225,8 +225,7 @@
 
 def yaml_dumps(value, indent=2):
     """
-    YAML dumps that supports Unicode and the :code:`as_raw` property of objects
-    if available.
+    YAML dumps that supports Unicode and the ``as_raw`` property of objects if available.
     """
 
     return yaml.dump(value, indent=indent, allow_unicode=True, Dumper=YamlAsRawDumper)
diff --git a/aria/utils/http.py b/aria/utils/http.py
index 7bdfd79..c8357e9 100644
--- a/aria/utils/http.py
+++ b/aria/utils/http.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+HTTP utilities.
+"""
+
 import os
 import tempfile
 
@@ -20,17 +24,17 @@
 
 
 def download_file(url, destination=None, logger=None, progress_handler=None):
-    """Download file.
+    """
+    Download file.
 
-    May raise IOError as well as requests.exceptions.RequestException
-    :param url: Location of the file to download
-    :type url: str
-    :param destination:
-        Location where the file should be saved (autogenerated by default)
-    :type destination: str | None
-    :returns: Location where the file was saved
-    :rtype: str
-
+    :param url: URL from which to download
+    :type url: basestring
+    :param destination: path where the file should be saved or ``None`` to auto-generate
+    :type destination: basestring
+    :returns: path where the file was saved
+    :rtype: basestring
+    :raises exceptions.IOError:
+    :raises requests.exceptions.RequestException:
     """
     chunk_size = 1024
 
diff --git a/aria/utils/imports.py b/aria/utils/imports.py
index 35aa0fc..14ad09e 100644
--- a/aria/utils/imports.py
+++ b/aria/utils/imports.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Utility methods for dynamically loading python code
+Utilities for dynamically loading Python code.
 """
 
 import pkgutil
@@ -50,8 +50,8 @@
 
 def import_modules(name):
     """
-    Imports a module and all its sub-modules, recursively.
-    Relies on modules defining a 'MODULES' attribute listing their sub-module names.
+    Imports a module and all its sub-modules, recursively. Relies on modules defining a ``MODULES``
+    attribute listing their sub-module names.
     """
 
     module = __import__(name, fromlist=['MODULES'], level=0)
@@ -63,9 +63,9 @@
 # TODO merge with import_fullname
 def load_attribute(attribute_path):
     """
-    Dynamically load an attribute based on the path to it.
-    e.g. some_package.some_module.some_attribute, will load the some_attribute from the
-    some_package.some_module module
+    Dynamically load an attribute based on the path to it. E.g.
+    ``some_package.some_module.some_attribute``, will load ``some_attribute`` from the
+    ``some_package.some_module`` module.
     """
     module_name, attribute_name = attribute_path.rsplit('.', 1)
     try:
diff --git a/aria/utils/openclose.py b/aria/utils/openclose.py
index 19740eb..722885c 100644
--- a/aria/utils/openclose.py
+++ b/aria/utils/openclose.py
@@ -13,9 +13,13 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Utilities for working with open/close patterns.
+"""
+
 class OpenClose(object):
     """
-    Wraps an object that has open() and close() methods to support the "with" keyword.
+    Wraps an object that has ``open()`` and ``close()`` methods to support the ``with`` keyword.
     """
 
     def __init__(self, wrapped):
diff --git a/aria/utils/plugin.py b/aria/utils/plugin.py
index b7f94a1..4fb6a8e 100644
--- a/aria/utils/plugin.py
+++ b/aria/utils/plugin.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Plugin utilities.
+"""
+
 import wagon
 
 
diff --git a/aria/utils/process.py b/aria/utils/process.py
index 9aeae67..ec4a72d 100644
--- a/aria/utils/process.py
+++ b/aria/utils/process.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Process utilities.
+"""
+
 import os
 
 
diff --git a/aria/utils/specification.py b/aria/utils/specification.py
index e74c103..8c51134 100644
--- a/aria/utils/specification.py
+++ b/aria/utils/specification.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Utilities for cross-referencing code with specification documents.
+"""
+
 from .collections import OrderedDict
 
 
diff --git a/aria/utils/threading.py b/aria/utils/threading.py
index bfd30f5..b9d627a 100644
--- a/aria/utils/threading.py
+++ b/aria/utils/threading.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Threading utilities.
+"""
+
 from __future__ import absolute_import  # so we can import standard 'threading'
 
 import sys
@@ -26,6 +30,7 @@
 class ExecutorException(Exception):
     pass
 
+
 class DaemonThread(Thread):
     def __init__(self, *args, **kwargs):
         super(DaemonThread, self).__init__(*args, **kwargs)
@@ -33,16 +38,15 @@
 
     def run(self):
         """
-        We're overriding `Thread.run` in order to avoid annoying (but harmless) error
-        messages during shutdown. The problem is that CPython nullifies the
-        global state _before_ shutting down daemon threads, so that exceptions
-        might happen, and then `Thread.__bootstrap_inner` prints them out.
+        We're overriding ``Thread.run`` in order to avoid annoying (but harmless) error messages
+        during shutdown. The problem is that CPython nullifies the global state _before_ shutting
+        down daemon threads, so that exceptions might happen, and then ``Thread.__bootstrap_inner``
+        prints them out.
 
         Our solution is to swallow these exceptions here.
 
-        The side effect is that uncaught exceptions in our own thread code will _not_
-        be printed out as usual, so it's our responsibility to catch them in our
-        code.
+        The side effect is that uncaught exceptions in our own thread code will _not_ be printed out
+        as usual, so it's our responsibility to catch them in our code.
         """
 
         try:
@@ -54,6 +58,7 @@
             # Exceptions might occur in daemon threads during interpreter shutdown
             pass
 
+
 # https://gist.github.com/tliron/81dd915166b0bfc64be08b4f8e22c835
 class FixedThreadPoolExecutor(object):
     """
@@ -77,8 +82,8 @@
         executor.raise_first()
         print executor.returns
 
-    You can also use it with the Python "with" keyword, in which case you don't need to call "close"
-    explicitly::
+    You can also use it with the Python ``with`` keyword, in which case you don't need to call
+    ``close`` explicitly::
 
         with FixedThreadPoolExecutor(10) as executor:
             for value in range(100):
@@ -95,11 +100,10 @@
                  timeout=None,
                  print_exceptions=False):
         """
-        :param size: Number of threads in the pool (fixed).
-        :param timeout: Timeout in seconds for all
-               blocking operations. (Defaults to none, meaning no timeout)
-        :param print_exceptions: Set to true in order to
-               print exceptions from tasks. (Defaults to false)
+        :param size: number of threads in the pool; if ``None`` will use an optimal number for the
+         platform
+        :param timeout: timeout in seconds for all blocking operations (``None`` means no timeout)
+        :param print_exceptions: set to ``True`` in order to print exceptions from tasks
         """
         if not size:
             try:
@@ -131,7 +135,7 @@
 
         The task will be called ASAP on the next available worker thread in the pool.
 
-        Will raise an :class:`ExecutorException` exception if cannot be submitted.
+        :raises ExecutorException: if cannot be submitted
         """
 
         try:
@@ -145,7 +149,7 @@
 
         You cannot submit tasks anymore after calling this.
 
-        This is called automatically upon exit if you are using the "with" keyword.
+        This is called automatically upon exit if you are using the ``with`` keyword.
         """
 
         self.drain()
@@ -194,9 +198,9 @@
         """
         If exceptions were thrown by any task, then the first one will be raised.
 
-        This is rather arbitrary: proper handling would involve iterating all the
-        exceptions. However, if you want to use the "raise" mechanism, you are
-        limited to raising only one of them.
+        This is rather arbitrary: proper handling would involve iterating all the exceptions.
+        However, if you want to use the "raise" mechanism, you are limited to raising only one of
+        them.
         """
 
         exceptions = self.exceptions
@@ -238,13 +242,13 @@
         self.close()
         return False
 
+
 class LockedList(list):
     """
-    A list that supports the "with" keyword with a built-in lock.
+    A list that supports the ``with`` keyword with a built-in lock.
 
-    Though Python lists are thread-safe in that they will not raise exceptions
-    during concurrent access, they do not guarantee atomicity. This class will
-    let you gain atomicity when needed.
+    Though Python lists are thread-safe in that they will not raise exceptions during concurrent
+    access, they do not guarantee atomicity. This class will let you gain atomicity when needed.
     """
 
     def __init__(self, *args, **kwargs):
@@ -260,7 +264,7 @@
 
 class ExceptionThread(Thread):
     """
-    A thread from which top level exceptions can be retrieved or reraised
+    A thread from which top level exceptions can be retrieved or re-raised.
     """
     def __init__(self, *args, **kwargs):
         Thread.__init__(self, *args, **kwargs)
diff --git a/aria/utils/type.py b/aria/utils/type.py
index f08159a..fe88a62 100644
--- a/aria/utils/type.py
+++ b/aria/utils/type.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Type utilities.
+"""
+
 import datetime
 
 from .specification import implements_specification
@@ -79,7 +83,7 @@
 @implements_specification('3.2.1-1', 'tosca-simple-1.0')
 def canonical_type_name(value):
     """
-    Returns the canonical TOSCA type name of a primitive value, or None if unknown.
+    Returns the canonical TOSCA type name of a primitive value, or ``None`` if unknown.
 
     For a list of TOSCA type names, see the `TOSCA Simple Profile v1.0
     cos01 specification <http://docs.oasis-open.org/tosca/TOSCA-Simple-Profile-YAML/v1.0/cos01
@@ -95,7 +99,7 @@
 @implements_specification('3.2.1-2', 'tosca-simple-1.0')
 def canonical_type(type_name):
     """
-    Return the canonical type for any Python, YAML, or TOSCA type name or alias, or None if
+    Return the canonical type for any Python, YAML, or TOSCA type name or alias, or ``None`` if
     unsupported.
 
     :param type_name: Type name (case insensitive)
@@ -109,9 +113,8 @@
     Validate that a value is of a specific type. Supports Python, YAML, and TOSCA type names and
     aliases.
 
-    A ValueError will be raised on type mismatch.
-
-    :param type_name: Type name (case insensitive)
+    :param type_name: type name (case insensitive)
+    :raises ~exceptions.ValueError: on type mismatch
     """
 
     the_type = canonical_type(type_name)
@@ -132,9 +135,8 @@
     """
     Converts a value to a specific Python primitive type.
 
-    A ValueError will be raised for unsupported types or conversion failure.
-
     :param python_type_name: Python primitive type name (case insensitive)
+    :raises ~exceptions.ValueError: for unsupported types or conversion failure
     """
 
     python_type_name = python_type_name.lower()
diff --git a/aria/utils/uris.py b/aria/utils/uris.py
index 5f7bcf5..49881f2 100644
--- a/aria/utils/uris.py
+++ b/aria/utils/uris.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+URI utilities.
+"""
+
 import os
 import urlparse
 
@@ -22,8 +26,8 @@
 
 def as_file(uri):
     """
-    If the URI is a file (either the :code:`file` scheme or no scheme), then returns the normalized
-    path. Otherwise, returns None.
+    If the URI is a file (either the ``file`` scheme or no scheme), then returns the normalized
+    path. Otherwise, returns ``None``.
     """
 
     if _IS_WINDOWS:
diff --git a/aria/utils/uuid.py b/aria/utils/uuid.py
index 1f340c6..d6c9ced 100644
--- a/aria/utils/uuid.py
+++ b/aria/utils/uuid.py
@@ -13,6 +13,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+UUID generation utilities.
+"""
+
 from __future__ import absolute_import  # so we can import standard 'uuid'
 
 from random import randrange
@@ -32,14 +36,14 @@
     """
     A random string with varying degrees of guarantee of universal uniqueness.
 
-    :param variant: options are:
-                    * 'base57' (the default) uses a mix of upper and lowercase alphanumerics
-                      ensuring no visually ambiguous characters; default length 22
-                    * 'alphanumeric' uses lowercase alphanumeric; default length 25
-                    * 'uuid' user lowercase hexadecimal in the classic UUID format, including
-                      dashes; length is always 36
-                    * 'hex' uses lowercase hexadecimal characters but has no guarantee of
-                      uniqueness; default length of 5
+    :param variant:
+     * ``base57`` (the default) uses a mix of upper and lowercase alphanumerics ensuring no visually
+       ambiguous characters; default length 22
+     * ``alphanumeric`` uses lowercase alphanumeric; default length 25
+     * ``uuid`` uses lowercase hexadecimal in the classic UUID format, including dashes; length is
+       always 36
+     * ``hex`` uses lowercase hexadecimal characters but has no guarantee of uniqueness; default
+       length of 5
     """
 
     if variant == 'base57':
diff --git a/aria/utils/validation.py b/aria/utils/validation.py
index 193cb33..3452dcc 100644
--- a/aria/utils/validation.py
+++ b/aria/utils/validation.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-Contains validation related utilities
+Validation utilities.
 """
 
 from .formatting import string_list_as_string
@@ -22,7 +22,7 @@
 
 class ValidatorMixin(object):
     """
-    A mixin that should be added to classes that require validating user input
+    A mix0in that should be added to classes that require validating user input.
     """
 
     _ARGUMENT_TYPE_MESSAGE = '{name} argument must be {type} based, got {arg!r}'
@@ -68,7 +68,7 @@
 def validate_function_arguments(func, func_kwargs):
     """
     Validates all required arguments are supplied to ``func`` and that no additional arguments are
-    supplied
+    supplied.
     """
 
     _kwargs_flags = 8
diff --git a/aria/utils/versions.py b/aria/utils/versions.py
index 925f59e..521004c 100644
--- a/aria/utils/versions.py
+++ b/aria/utils/versions.py
@@ -14,7 +14,7 @@
 # limitations under the License.
 
 """
-General-purpose version string handling
+Verion string utilities.
 """
 
 import re
@@ -55,8 +55,9 @@
     Any value that does not conform to this format will be treated as a zero version, which would
     be lesser than any non-zero version.
 
-    For efficient list sorts use the ``key`` property, e.g.:
-    ``sorted(versions, key=lambda x: x.key)``
+    For efficient list sorts use the ``key`` property, e.g.::
+
+        sorted(versions, key=lambda x: x.key)
     """
 
     NULL = None # initialized below
@@ -84,9 +85,9 @@
     """
     Parses a version string.
 
-    :param version: The version string
-    :returns: The primary tuple and qualifier float
-    :rtype: ((int), float)
+    :param version: version string
+    :returns: primary tuple and qualifier float
+    :rtype: ((:obj:`int`), :obj:`float`)
     """
 
     if version is None:
diff --git a/docs/aria.cli.rst b/docs/aria.cli.rst
new file mode 100644
index 0000000..c325cf0
--- /dev/null
+++ b/docs/aria.cli.rst
@@ -0,0 +1,100 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+:mod:`aria.cli`
+===============
+
+.. automodule:: aria.cli
+
+:mod:`aria.cli.color`
+---------------------
+
+.. automodule:: aria.cli.color
+
+:mod:`aria.cli.csar`
+--------------------
+
+.. automodule:: aria.cli.csar
+
+:mod:`aria.cli.defaults`
+------------------------
+
+.. automodule:: aria.cli.defaults
+
+:mod:`aria.cli.exceptions`
+--------------------------
+
+.. automodule:: aria.cli.exceptions
+
+:mod:`aria.cli.execution_logging`
+---------------------------------
+
+.. automodule:: aria.cli.execution_logging
+
+:mod:`aria.cli.helptexts`
+-------------------------
+
+.. automodule:: aria.cli.helptexts
+
+:mod:`aria.cli.inputs`
+----------------------
+
+.. automodule:: aria.cli.inputs
+
+:mod:`aria.cli.logger`
+----------------------
+
+.. automodule:: aria.cli.logger
+
+:mod:`aria.cli.main`
+--------------------
+
+.. automodule:: aria.cli.main
+
+:mod:`aria.cli.service_template_utils`
+--------------------------------------
+
+.. automodule:: aria.cli.service_template_utils
+
+:mod:`aria.cli.table`
+---------------------
+
+.. automodule:: aria.cli.table
+
+:mod:`aria.cli.utils`
+---------------------
+
+.. automodule:: aria.cli.utils
+
+:mod:`aria.cli.config`
+----------------------
+
+.. automodule:: aria.cli.config
+
+:mod:`aria.cli.config.config`
+-----------------------------
+
+.. automodule:: aria.cli.config.config
+
+:mod:`aria.cli.core`
+--------------------
+
+.. automodule:: aria.cli.core
+
+:mod:`aria.cli.core.aria`
+-------------------------
+
+.. automodule:: aria.cli.core.aria
diff --git a/docs/tosca.rst b/docs/aria.modeling.models.rst
similarity index 63%
copy from docs/tosca.rst
copy to docs/aria.modeling.models.rst
index c98a4a9..6431780 100644
--- a/docs/tosca.rst
+++ b/docs/aria.modeling.models.rst
@@ -14,23 +14,8 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 
+:mod:`aria.modeling.models`
+===========================
 
-`aria_extension_tosca` Package
-##############################
-
-This is the ARIA TOSCA extension.
-
-:mod:`aria_extension_tosca`
-***************************
-
-.. automodule:: aria_extension_tosca
-
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
-
-.. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+.. automodule:: aria.modeling.models
+   :no-show-inheritance:
diff --git a/docs/aria.modeling.rst b/docs/aria.modeling.rst
new file mode 100644
index 0000000..b85e22c
--- /dev/null
+++ b/docs/aria.modeling.rst
@@ -0,0 +1,56 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+:mod:`aria.modeling`
+====================
+
+.. automodule:: aria.modeling
+
+:mod:`aria.modeling.constraints`
+--------------------------------
+
+.. automodule:: aria.modeling.constraints
+
+:mod:`aria.modeling.exceptions`
+-------------------------------
+
+.. automodule:: aria.modeling.exceptions
+
+:mod:`aria.modeling.functions`
+------------------------------
+
+.. automodule:: aria.modeling.functions
+
+:mod:`aria.modeling.mixins`
+---------------------------
+
+.. automodule:: aria.modeling.mixins
+
+:mod:`aria.modeling.relationship`
+---------------------------------
+
+.. automodule:: aria.modeling.relationship
+
+:mod:`aria.modeling.types`
+--------------------------
+
+.. automodule:: aria.modeling.types
+
+:mod:`aria.modeling.utils`
+--------------------------
+
+.. automodule:: aria.modeling.utils
diff --git a/docs/aria.orchestrator.context.rst b/docs/aria.orchestrator.context.rst
new file mode 100644
index 0000000..395befc
--- /dev/null
+++ b/docs/aria.orchestrator.context.rst
@@ -0,0 +1,46 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+:mod:`aria.orchestrator.context`
+================================
+
+.. automodule:: aria.orchestrator.context
+
+:mod:`aria.orchestrator.context.common`
+---------------------------------------
+
+.. automodule:: aria.orchestrator.context.common
+
+:mod:`aria.orchestrator.context.exceptions`
+-------------------------------------------
+
+.. automodule:: aria.orchestrator.context.exceptions
+
+:mod:`aria.orchestrator.context.operation`
+------------------------------------------
+
+.. automodule:: aria.orchestrator.context.operation
+
+:mod:`aria.orchestrator.context.toolbelt`
+-----------------------------------------
+
+.. automodule:: aria.orchestrator.context.toolbelt
+
+:mod:`aria.orchestrator.context.workflow`
+-----------------------------------------
+
+.. automodule:: aria.orchestrator.context.workflow
diff --git a/docs/aria.orchestrator.execution_plugin.ctx_proxy.rst b/docs/aria.orchestrator.execution_plugin.ctx_proxy.rst
new file mode 100644
index 0000000..47ed598
--- /dev/null
+++ b/docs/aria.orchestrator.execution_plugin.ctx_proxy.rst
@@ -0,0 +1,31 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+:mod:`aria.orchestrator.execution_plugin.ctx_proxy`
+===================================================
+
+.. automodule:: aria.orchestrator.execution_plugin.ctx_proxy
+
+:mod:`aria.orchestrator.execution_plugin.ctx_proxy.client`
+----------------------------------------------------------
+
+.. automodule:: aria.orchestrator.execution_plugin.ctx_proxy.client
+
+:mod:`aria.orchestrator.execution_plugin.ctx_proxy.server`
+----------------------------------------------------------
+
+.. automodule:: aria.orchestrator.execution_plugin.ctx_proxy.server
diff --git a/docs/aria.orchestrator.execution_plugin.rst b/docs/aria.orchestrator.execution_plugin.rst
new file mode 100644
index 0000000..177a316
--- /dev/null
+++ b/docs/aria.orchestrator.execution_plugin.rst
@@ -0,0 +1,56 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+:mod:`aria.orchestrator.execution_plugin`
+=========================================
+
+.. automodule:: aria.orchestrator.execution_plugin
+
+:mod:`aria.orchestrator.execution_plugin.common`
+------------------------------------------------
+
+.. automodule:: aria.orchestrator.execution_plugin.common
+
+:mod:`aria.orchestrator.execution_plugin.constants`
+---------------------------------------------------
+
+.. automodule:: aria.orchestrator.execution_plugin.constants
+
+:mod:`aria.orchestrator.execution_plugin.environment_globals`
+-------------------------------------------------------------
+
+.. automodule:: aria.orchestrator.execution_plugin.environment_globals
+
+:mod:`aria.orchestrator.execution_plugin.exceptions`
+----------------------------------------------------
+
+.. automodule:: aria.orchestrator.execution_plugin.exceptions
+
+:mod:`aria.orchestrator.execution_plugin.instantiation`
+-------------------------------------------------------
+
+.. automodule:: aria.orchestrator.execution_plugin.instantiation
+
+:mod:`aria.orchestrator.execution_plugin.local`
+-----------------------------------------------
+
+.. automodule:: aria.orchestrator.execution_plugin.local
+
+:mod:`aria.orchestrator.execution_plugin.operations`
+----------------------------------------------------
+
+.. automodule:: aria.orchestrator.execution_plugin.operations
diff --git a/docs/tosca.rst b/docs/aria.orchestrator.execution_plugin.ssh.rst
similarity index 61%
copy from docs/tosca.rst
copy to docs/aria.orchestrator.execution_plugin.ssh.rst
index c98a4a9..8bbaa57 100644
--- a/docs/tosca.rst
+++ b/docs/aria.orchestrator.execution_plugin.ssh.rst
@@ -15,22 +15,17 @@
    limitations under the License.
 
 
-`aria_extension_tosca` Package
-##############################
+:mod:`aria.orchestrator.execution_plugin.ssh`
+=============================================
 
-This is the ARIA TOSCA extension.
+.. automodule:: aria.orchestrator.execution_plugin.ssh
 
-:mod:`aria_extension_tosca`
-***************************
+:mod:`aria.orchestrator.execution_plugin.ssh.operations`
+--------------------------------------------------------
 
-.. automodule:: aria_extension_tosca
+.. automodule:: aria.orchestrator.execution_plugin.ssh.operations
 
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
+:mod:`aria.orchestrator.execution_plugin.ssh.tunnel`
+----------------------------------------------------
 
-.. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+.. automodule:: aria.orchestrator.execution_plugin.ssh.tunnel
diff --git a/docs/aria.orchestrator.rst b/docs/aria.orchestrator.rst
new file mode 100644
index 0000000..33454e6
--- /dev/null
+++ b/docs/aria.orchestrator.rst
@@ -0,0 +1,46 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+:mod:`aria.orchestrator`
+========================
+
+.. automodule:: aria.orchestrator
+
+:mod:`aria.orchestrator.decorators`
+-----------------------------------
+
+.. automodule:: aria.orchestrator.decorators
+
+:mod:`aria.orchestrator.events`
+-------------------------------
+
+.. automodule:: aria.orchestrator.events
+
+:mod:`aria.orchestrator.exceptions`
+-----------------------------------
+
+.. automodule:: aria.orchestrator.exceptions
+
+:mod:`aria.orchestrator.plugin`
+-------------------------------
+
+.. automodule:: aria.orchestrator.plugin
+
+:mod:`aria.orchestrator.workflow_runner`
+----------------------------------------
+
+.. automodule:: aria.orchestrator.workflow_runner
diff --git a/docs/tosca.rst b/docs/aria.orchestrator.workflows.api.rst
similarity index 63%
copy from docs/tosca.rst
copy to docs/aria.orchestrator.workflows.api.rst
index c98a4a9..7ecac75 100644
--- a/docs/tosca.rst
+++ b/docs/aria.orchestrator.workflows.api.rst
@@ -15,22 +15,17 @@
    limitations under the License.
 
 
-`aria_extension_tosca` Package
-##############################
+:mod:`aria.orchestrator.workflows.api`
+======================================
 
-This is the ARIA TOSCA extension.
+.. automodule:: aria.orchestrator.workflows.api
 
-:mod:`aria_extension_tosca`
-***************************
+:mod:`aria.orchestrator.workflows.api.task_graph`
+-------------------------------------------------
 
-.. automodule:: aria_extension_tosca
+.. automodule:: aria.orchestrator.workflows.api.task_graph
 
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
+:mod:`aria.orchestrator.workflows.api.task`
+-------------------------------------------
 
-.. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+.. automodule:: aria.orchestrator.workflows.api.task
diff --git a/docs/aria.orchestrator.workflows.builtin.rst b/docs/aria.orchestrator.workflows.builtin.rst
new file mode 100644
index 0000000..de1a8f9
--- /dev/null
+++ b/docs/aria.orchestrator.workflows.builtin.rst
@@ -0,0 +1,57 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+
+:mod:`aria.orchestrator.workflows.builtin`
+==========================================
+
+.. automodule:: aria.orchestrator.workflows.builtin
+
+:mod:`aria.orchestrator.workflows.builtin.execute_operation`
+------------------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.builtin.execute_operation
+
+:mod:`aria.orchestrator.workflows.builtin.heal`
+-----------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.builtin.heal
+
+:mod:`aria.orchestrator.workflows.builtin.install`
+--------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.builtin.install
+
+:mod:`aria.orchestrator.workflows.builtin.start`
+------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.builtin.start
+
+:mod:`aria.orchestrator.workflows.builtin.stop`
+-----------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.builtin.stop
+
+:mod:`aria.orchestrator.workflows.builtin.uninstall`
+----------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.builtin.uninstall
+
+:mod:`aria.orchestrator.workflows.builtin.workflows`
+----------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.builtin.workflows
diff --git a/docs/aria.orchestrator.workflows.executor.rst b/docs/aria.orchestrator.workflows.executor.rst
new file mode 100644
index 0000000..cde0a77
--- /dev/null
+++ b/docs/aria.orchestrator.workflows.executor.rst
@@ -0,0 +1,46 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+:mod:`aria.orchestrator.workflows.executor`
+===========================================
+
+.. automodule:: aria.orchestrator.workflows.executor
+
+:mod:`aria.orchestrator.workflows.executor.base`
+------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.executor.base
+
+:mod:`aria.orchestrator.workflows.executor.celery`
+--------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.executor.celery
+
+:mod:`aria.orchestrator.workflows.executor.dry`
+-----------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.executor.dry
+
+:mod:`aria.orchestrator.workflows.executor.process`
+---------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.executor.process
+
+:mod:`aria.orchestrator.workflows.executor.thread`
+--------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.executor.thread
diff --git a/docs/aria.orchestrator.workflows.rst b/docs/aria.orchestrator.workflows.rst
new file mode 100644
index 0000000..c0bc1c1
--- /dev/null
+++ b/docs/aria.orchestrator.workflows.rst
@@ -0,0 +1,51 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+:mod:`aria.orchestrator.workflows`
+==================================
+
+.. automodule:: aria.orchestrator.workflows
+
+:mod:`aria.orchestrator.workflows.events_logging`
+-------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.events_logging
+
+:mod:`aria.orchestrator.workflows.exceptions`
+---------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.exceptions
+
+:mod:`aria.orchestrator.workflows.core`
+---------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.core
+
+:mod:`aria.orchestrator.workflows.core.graph_compiler`
+------------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.core.graph_compiler
+
+:mod:`aria.orchestrator.workflows.core.engine`
+----------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.core.engine
+
+:mod:`aria.orchestrator.workflows.core.events_handler`
+------------------------------------------------------
+
+.. automodule:: aria.orchestrator.workflows.core.events_handler
diff --git a/docs/tosca.rst b/docs/aria.parser.consumption.rst
similarity index 63%
copy from docs/tosca.rst
copy to docs/aria.parser.consumption.rst
index c98a4a9..3d9fc6e 100644
--- a/docs/tosca.rst
+++ b/docs/aria.parser.consumption.rst
@@ -15,22 +15,7 @@
    limitations under the License.
 
 
-`aria_extension_tosca` Package
-##############################
+:mod:`aria.parser.consumption`
+==============================
 
-This is the ARIA TOSCA extension.
-
-:mod:`aria_extension_tosca`
-***************************
-
-.. automodule:: aria_extension_tosca
-
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
-
-.. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+.. automodule:: aria.parser.consumption
diff --git a/docs/tosca.rst b/docs/aria.parser.loading.rst
similarity index 63%
copy from docs/tosca.rst
copy to docs/aria.parser.loading.rst
index c98a4a9..0ae7565 100644
--- a/docs/tosca.rst
+++ b/docs/aria.parser.loading.rst
@@ -15,22 +15,7 @@
    limitations under the License.
 
 
-`aria_extension_tosca` Package
-##############################
+:mod:`aria.parser.loading`
+==========================
 
-This is the ARIA TOSCA extension.
-
-:mod:`aria_extension_tosca`
-***************************
-
-.. automodule:: aria_extension_tosca
-
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
-
-.. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+.. automodule:: aria.parser.loading
diff --git a/docs/tosca.rst b/docs/aria.parser.modeling.rst
similarity index 63%
copy from docs/tosca.rst
copy to docs/aria.parser.modeling.rst
index c98a4a9..16c359c 100644
--- a/docs/tosca.rst
+++ b/docs/aria.parser.modeling.rst
@@ -15,22 +15,7 @@
    limitations under the License.
 
 
-`aria_extension_tosca` Package
-##############################
+:mod:`aria.parser.modeling`
+===========================
 
-This is the ARIA TOSCA extension.
-
-:mod:`aria_extension_tosca`
-***************************
-
-.. automodule:: aria_extension_tosca
-
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
-
-.. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+.. automodule:: aria.parser.modeling
diff --git a/docs/tosca.rst b/docs/aria.parser.presentation.rst
similarity index 63%
copy from docs/tosca.rst
copy to docs/aria.parser.presentation.rst
index c98a4a9..6c63b2e 100644
--- a/docs/tosca.rst
+++ b/docs/aria.parser.presentation.rst
@@ -15,22 +15,7 @@
    limitations under the License.
 
 
-`aria_extension_tosca` Package
-##############################
+:mod:`aria.parser.presentation`
+===============================
 
-This is the ARIA TOSCA extension.
-
-:mod:`aria_extension_tosca`
-***************************
-
-.. automodule:: aria_extension_tosca
-
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
-
-.. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+.. automodule:: aria.parser.presentation
diff --git a/docs/tosca.rst b/docs/aria.parser.reading.rst
similarity index 63%
copy from docs/tosca.rst
copy to docs/aria.parser.reading.rst
index c98a4a9..b1d4f6c 100644
--- a/docs/tosca.rst
+++ b/docs/aria.parser.reading.rst
@@ -15,22 +15,7 @@
    limitations under the License.
 
 
-`aria_extension_tosca` Package
-##############################
+:mod:`aria.parser.reading`
+==========================
 
-This is the ARIA TOSCA extension.
-
-:mod:`aria_extension_tosca`
-***************************
-
-.. automodule:: aria_extension_tosca
-
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
-
-.. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+.. automodule:: aria.parser.reading
diff --git a/docs/tosca.rst b/docs/aria.parser.rst
similarity index 63%
copy from docs/tosca.rst
copy to docs/aria.parser.rst
index c98a4a9..700f03d 100644
--- a/docs/tosca.rst
+++ b/docs/aria.parser.rst
@@ -15,22 +15,17 @@
    limitations under the License.
 
 
-`aria_extension_tosca` Package
-##############################
+:mod:`aria.parser`
+==================
 
-This is the ARIA TOSCA extension.
+.. automodule:: aria.parser
 
-:mod:`aria_extension_tosca`
-***************************
+:mod:`aria.parser.exceptions`
+-----------------------------
 
-.. automodule:: aria_extension_tosca
+.. automodule:: aria.parser.exceptions
 
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
+:mod:`aria.parser.specification`
+--------------------------------
 
-.. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+.. automodule:: aria.parser.specification
diff --git a/docs/tosca.rst b/docs/aria.parser.validation.rst
similarity index 63%
copy from docs/tosca.rst
copy to docs/aria.parser.validation.rst
index c98a4a9..621898b 100644
--- a/docs/tosca.rst
+++ b/docs/aria.parser.validation.rst
@@ -15,22 +15,7 @@
    limitations under the License.
 
 
-`aria_extension_tosca` Package
-##############################
+:mod:`aria.parser.validation`
+=============================
 
-This is the ARIA TOSCA extension.
-
-:mod:`aria_extension_tosca`
-***************************
-
-.. automodule:: aria_extension_tosca
-
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
-
-.. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+.. automodule:: aria.parser.validation
diff --git a/docs/tosca.rst b/docs/aria.rst
similarity index 63%
copy from docs/tosca.rst
copy to docs/aria.rst
index c98a4a9..1a0dae5 100644
--- a/docs/tosca.rst
+++ b/docs/aria.rst
@@ -14,23 +14,27 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 
+:mod:`aria`
+===========
 
-`aria_extension_tosca` Package
-##############################
+.. automodule:: aria
 
-This is the ARIA TOSCA extension.
+:mod:`aria.core`
+----------------
 
-:mod:`aria_extension_tosca`
-***************************
+.. automodule:: aria.core
 
-.. automodule:: aria_extension_tosca
+:mod:`aria.exceptions`
+----------------------
 
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
+.. automodule:: aria.exceptions
 
-.. automodule:: aria_extension_tosca.simple_v1_0
+:mod:`aria.extension`
+---------------------
 
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
+.. automodule:: aria.extension
 
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+:mod:`aria.logger`
+------------------
+
+.. automodule:: aria.logger
diff --git a/docs/aria.storage.rst b/docs/aria.storage.rst
new file mode 100644
index 0000000..7c51c2f
--- /dev/null
+++ b/docs/aria.storage.rst
@@ -0,0 +1,51 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+:mod:`aria.storage`
+===================
+
+.. automodule:: aria.storage
+
+:mod:`aria.storage.api`
+-----------------------
+
+.. automodule:: aria.storage.api
+
+:mod:`aria.storage.collection_instrumentation`
+----------------------------------------------
+
+.. automodule:: aria.storage.collection_instrumentation
+
+:mod:`aria.storage.core`
+------------------------
+
+.. automodule:: aria.storage.core
+
+:mod:`aria.storage.exceptions`
+------------------------------
+
+.. automodule:: aria.storage.exceptions
+
+:mod:`aria.storage.filesystem_rapi`
+-----------------------------------
+
+.. automodule:: aria.storage.filesystem_rapi
+
+:mod:`aria.storage.sql_mapi`
+----------------------------
+
+.. automodule:: aria.storage.sql_mapi
diff --git a/docs/aria.utils.rst b/docs/aria.utils.rst
new file mode 100644
index 0000000..220c0cd
--- /dev/null
+++ b/docs/aria.utils.rst
@@ -0,0 +1,121 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+
+:mod:`aria.utils`
+=================
+
+.. automodule:: aria.utils
+
+:mod:`aria.utils.archive`
+-------------------------
+
+.. automodule:: aria.utils.archive
+
+:mod:`aria.utils.argparse`
+--------------------------
+
+.. automodule:: aria.utils.argparse
+
+:mod:`aria.utils.caching`
+-------------------------
+
+.. automodule:: aria.utils.caching
+
+:mod:`aria.utils.collections`
+-----------------------------
+
+.. automodule:: aria.utils.collections
+
+:mod:`aria.utils.console`
+-------------------------
+
+.. automodule:: aria.utils.console
+
+:mod:`aria.utils.exceptions`
+----------------------------
+
+.. automodule:: aria.utils.exceptions
+
+:mod:`aria.utils.file`
+----------------------
+
+.. automodule:: aria.utils.file
+
+:mod:`aria.utils.formatting`
+----------------------------
+
+.. automodule:: aria.utils.formatting
+
+:mod:`aria.utils.http`
+----------------------
+
+.. automodule:: aria.utils.http
+
+:mod:`aria.utils.imports`
+-------------------------
+
+.. automodule:: aria.utils.imports
+
+:mod:`aria.utils.openclose`
+---------------------------
+
+.. automodule:: aria.utils.openclose
+
+:mod:`aria.utils.plugin`
+------------------------
+
+.. automodule:: aria.utils.plugin
+
+:mod:`aria.utils.process`
+-------------------------
+
+.. automodule:: aria.utils.process
+
+:mod:`aria.utils.specification`
+-------------------------------
+
+.. automodule:: aria.utils.specification
+
+:mod:`aria.utils.threading`
+---------------------------
+
+.. automodule:: aria.utils.threading
+
+:mod:`aria.utils.type`
+----------------------
+
+.. automodule:: aria.utils.type
+
+:mod:`aria.utils.uris`
+----------------------
+
+.. automodule:: aria.utils.uris
+
+:mod:`aria.utils.uuid`
+----------------------
+
+.. automodule:: aria.utils.uuid
+
+:mod:`aria.utils.validation`
+----------------------------
+
+.. automodule:: aria.utils.validation
+
+:mod:`aria.utils.versions`
+--------------------------
+
+.. automodule:: aria.utils.versions
diff --git a/docs/tosca.rst b/docs/aria_extension_tosca.simple_nfv_v1_0.rst
similarity index 70%
copy from docs/tosca.rst
copy to docs/aria_extension_tosca.simple_nfv_v1_0.rst
index c98a4a9..6e7b6cd 100644
--- a/docs/tosca.rst
+++ b/docs/aria_extension_tosca.simple_nfv_v1_0.rst
@@ -14,23 +14,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 
-
-`aria_extension_tosca` Package
-##############################
-
-This is the ARIA TOSCA extension.
-
-:mod:`aria_extension_tosca`
-***************************
-
-.. automodule:: aria_extension_tosca
-
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
-
-.. automodule:: aria_extension_tosca.simple_v1_0
-
 :mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
+===========================================
 
 .. automodule:: aria_extension_tosca.simple_nfv_v1_0
diff --git a/docs/aria_extension_tosca.simple_v1_0.modeling.rst b/docs/aria_extension_tosca.simple_v1_0.modeling.rst
new file mode 100644
index 0000000..8bc5499
--- /dev/null
+++ b/docs/aria_extension_tosca.simple_v1_0.modeling.rst
@@ -0,0 +1,75 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling`
+================================================
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling.artifacts`
+----------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling.artifacts
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling.capabilities`
+-------------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling.capabilities
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling.constraints`
+------------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling.constraints
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling.copy`
+-----------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling.copy
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling.data_types`
+-----------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling.data_types
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling.functions`
+----------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling.functions
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling.interfaces`
+-----------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling.interfaces
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling.parameters`
+-----------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling.parameters
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling.policies`
+---------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling.policies
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling.requirements`
+-------------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling.requirements
+
+:mod:`aria_extension_tosca.simple_v1_0.modeling.substitution_mappings`
+----------------------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.modeling.substitution_mappings
diff --git a/docs/aria_extension_tosca.simple_v1_0.presentation.rst b/docs/aria_extension_tosca.simple_v1_0.presentation.rst
new file mode 100644
index 0000000..964c029
--- /dev/null
+++ b/docs/aria_extension_tosca.simple_v1_0.presentation.rst
@@ -0,0 +1,40 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+:mod:`aria_extension_tosca.simple_v1_0.presentation`
+====================================================
+
+.. automodule:: aria_extension_tosca.simple_v1_0.presentation
+
+:mod:`aria_extension_tosca.simple_v1_0.presentation.extensible`
+---------------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.presentation.extensible
+
+:mod:`aria_extension_tosca.simple_v1_0.presentation.field_getters`
+------------------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.presentation.field_getters
+
+:mod:`aria_extension_tosca.simple_v1_0.presentation.field_validators`
+---------------------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.presentation.field_validators
+
+:mod:`aria_extension_tosca.simple_v1_0.presentation.types`
+----------------------------------------------------------
+
+.. automodule:: aria_extension_tosca.simple_v1_0.presentation.types
diff --git a/docs/tosca.rst b/docs/aria_extension_tosca.simple_v1_0.rst
similarity index 70%
rename from docs/tosca.rst
rename to docs/aria_extension_tosca.simple_v1_0.rst
index c98a4a9..bdae6ab 100644
--- a/docs/tosca.rst
+++ b/docs/aria_extension_tosca.simple_v1_0.rst
@@ -14,23 +14,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 
-
-`aria_extension_tosca` Package
-##############################
-
-This is the ARIA TOSCA extension.
-
-:mod:`aria_extension_tosca`
-***************************
-
-.. automodule:: aria_extension_tosca
-
 :mod:`aria_extension_tosca.simple_v1_0`
-***************************************
+=======================================
 
 .. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
diff --git a/docs/cli.rst b/docs/cli.rst
new file mode 100644
index 0000000..ee51545
--- /dev/null
+++ b/docs/cli.rst
@@ -0,0 +1,57 @@
+..
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+   
+       http://www.apache.org/licenses/LICENSE-2.0
+   
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+CLI
+===
+
+.. click:: aria.cli.main:_aria
+   :prog: aria
+
+.. click:: aria.cli.commands.reset:reset
+   :prog: aria reset
+   :show-nested:
+
+.. click:: aria.cli.commands.plugins:plugins
+   :prog: aria plugins
+   :show-nested:
+
+.. click:: aria.cli.commands.service_templates:service_templates
+   :prog: aria service_templates
+   :show-nested:
+
+.. click:: aria.cli.commands.node_templates:node_templates
+   :prog: aria node_templates
+   :show-nested:
+
+.. click:: aria.cli.commands.services:services
+   :prog: aria services
+   :show-nested:
+
+.. click:: aria.cli.commands.nodes:nodes
+   :prog: aria nodes
+   :show-nested:
+
+.. click:: aria.cli.commands.workflows:workflows
+   :prog: aria workflows
+   :show-nested:
+
+.. click:: aria.cli.commands.executions:executions
+   :prog: aria executions
+   :show-nested:
+
+.. click:: aria.cli.commands.logs:logs
+   :prog: aria logs
+   :show-nested:
diff --git a/docs/conf.py b/docs/conf.py
index e557f02..6361621 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -15,7 +15,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-# ARIA documentation build configuration file.
+# ARIA TOSCA documentation build configuration file.
 #
 # This file is execfile()d with the current directory set to its
 # containing dir.
@@ -48,7 +48,12 @@
 # Add any Sphinx extension module names here, as strings. They can be
 # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
 # ones.
-extensions = ['sphinx.ext.autodoc']
+extensions = [
+    'sphinx.ext.autodoc',
+    'sphinx.ext.autosummary',
+    'sphinx.ext.intersphinx',
+    'sphinx_click.ext'
+]
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
@@ -67,9 +72,9 @@
 master_doc = 'index'
 
 # General information about the project.
-project = u'ARIA'
-copyright = u'2016, Apache Software Foundation' # @ReservedAssignment
-author = u'ARIA'
+project = u'ARIA TOSCA'
+copyright = u'2016-2017, Apache Software Foundation' # @ReservedAssignment
+author = u'Apache Software Foundation'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
@@ -152,7 +157,7 @@
 # The name for this set of Sphinx documents.
 # "<project> v<release> documentation" by default.
 #
-# html_title = u'ARIA v0.1.0'
+# html_title = u'ARIA TOSCA v0.1.0'
 
 # A shorter title for the navigation bar.  Default is the same as html_title.
 #
@@ -252,7 +257,7 @@
 # html_search_scorer = 'scorer.js'
 
 # Output file base name for HTML help builder.
-htmlhelp_basename = 'ARIAdoc'
+htmlhelp_basename = 'ARIATOSCAdoc'
 
 # -- Options for LaTeX output ---------------------------------------------
 
@@ -278,7 +283,7 @@
 # (source start file, target name, title,
 #  author, documentclass [howto, manual, or own class]).
 latex_documents = [
-    (master_doc, 'ARIA.tex', u'ARIA',
+    (master_doc, 'ARIATOSCA.tex', u'ARIA TOSCA',
      u'Apache Software Foundation', 'manual'),
 ]
 
@@ -314,7 +319,7 @@
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
 man_pages = [
-    (master_doc, 'aria', u'ARIA',
+    (master_doc, 'aria', u'ARIA TOSCA',
      [author], 1)
 ]
 
@@ -329,8 +334,9 @@
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-    (master_doc, 'ARIA', u'ARIA',
-     author, 'ARIA', 'Toolkit for parsing TOSCA.',
+    (master_doc, 'ARIATOSCA', u'ARIA TOSCA',
+     author, 'ARIA TOSCA', 'an open, light, CLI-driven library of orchestration tools that other '
+     'open projects can consume to easily build TOSCA-based orchestration solutions.',
      'Miscellaneous'),
 ]
 
@@ -350,19 +356,61 @@
 #
 # texinfo_no_detailmenu = False
 
+
+# -- Options for InterSphinx
+
+intersphinx_mapping = {
+    'python': ('https://docs.python.org/2.7', None)
+}
+
 # -- Options for Python domain
 
-# Include __init__ docstring into class docstring
+# Append __init__ docstring into class docstring
 autoclass_content = 'both'
 
 # Default to everything important
-autodoc_default_flags = ['members', 'undoc-members', 'show-inheritance']
+autodoc_default_flags = [
+    'members',
+    'undoc-members',
+    'show-inheritance'
+]
 
-def on_skip_members(app, what, name, obj, skip, options):
-    if not skip:
-        if name in ('FIELDS', 'ALLOW_UNKNOWN_FIELDS', 'SHORT_FORM_FIELD'):
-            skip = True
+SKIP_MEMBERS = (
+    'FIELDS',
+    'ALLOW_UNKNOWN_FIELDS',
+    'SHORT_FORM_FIELD',
+    'INSTRUMENTATION_FIELDS'
+)
+
+SKIP_MEMBER_SUFFIXES = (
+    '_fk',
+)
+
+NEVER_SKIP_MEMBERS = (
+    '__evaluate__',
+)
+
+# 'autodoc-skip-member' event
+def on_skip_member(app, what, name, obj, skip, options):
+    if name in NEVER_SKIP_MEMBERS:
+        return False
+    if name in SKIP_MEMBERS: 
+        return True
+    for suffix in SKIP_MEMBER_SUFFIXES:
+        if name.endswith(suffix):
+            return True
     return skip
-    
+
+from sphinx.domains.python import PythonDomain
+
+class PatchedPythonDomain(PythonDomain):
+    # See: https://github.com/sphinx-doc/sphinx/issues/3866
+    def resolve_xref(self, env, fromdocname, builder, typ, target, node, contnode):
+        if 'refspecific' in node:
+            del node['refspecific']
+        return super(PatchedPythonDomain, self).resolve_xref(
+            env, fromdocname, builder, typ, target, node, contnode)
+
 def setup(app):
-    app.connect('autodoc-skip-member', on_skip_members)
+    app.connect('autodoc-skip-member', on_skip_member)
+    app.override_domain(PatchedPythonDomain)
diff --git a/docs/index.rst b/docs/index.rst
index d915ae6..f68769b 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -14,24 +14,68 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 
+User Manual for ARIA TOSCA
+==========================
 
-ARIA API
-========
+`ARIA TOSCA <http://ariatosca.incubator.apache.org/>`__ is an open, light, CLI-driven library of
+orchestration tools that other open projects can consume to easily build
+`TOSCA <https://www.oasis-open.org/committees/tosca/>`__-based orchestration solutions. ARIA is now
+an incubation project at the Apache Software Foundation.  
 
-`ARIA (Agile Reference Implementation of Automation) <http://ariatosca.org/>`__  is a an open,
-light, CLI-driven library of orchestration tools that other open projects can consume to easily
-build `TOSCA <https://www.oasis-open.org/committees/tosca/>`__-based orchestration solutions. It
-supports NFV and hybrid cloud scenarios.
-
-
-Packages
---------
+Interfaces
+----------
 
 .. toctree::
-   :maxdepth: 2
+   :maxdepth: 1
+   :includehidden:
 
-   parser
-   tosca
+   cli
+   rest
+
+SDK
+---
+
+Core
+####
+
+.. toctree::
+   :maxdepth: 1
+   :includehidden:
+
+   aria
+   aria.cli
+   aria.modeling
+   aria.modeling.models
+   aria.orchestrator
+   aria.orchestrator.context
+   aria.orchestrator.execution_plugin
+   aria.orchestrator.execution_plugin.ctx_proxy
+   aria.orchestrator.execution_plugin.ssh
+   aria.orchestrator.workflows
+   aria.orchestrator.workflows.api
+   aria.orchestrator.workflows.builtin
+   aria.orchestrator.workflows.executor
+   aria.parser
+   aria.parser.consumption
+   aria.parser.loading
+   aria.parser.modeling
+   aria.parser.presentation
+   aria.parser.reading
+   aria.parser.validation
+   aria.storage
+   aria.utils
+
+Extensions
+##########
+
+.. toctree::
+   :maxdepth: 1
+   :includehidden:
+
+   aria_extension_tosca.simple_v1_0
+   aria_extension_tosca.simple_v1_0.modeling
+   aria_extension_tosca.simple_v1_0.presentation
+   aria_extension_tosca.simple_nfv_v1_0
 
 
 Indices and Tables
diff --git a/docs/parser.rst b/docs/parser.rst
deleted file mode 100644
index 5db02e2..0000000
--- a/docs/parser.rst
+++ /dev/null
@@ -1,56 +0,0 @@
-..
-   Licensed to the Apache Software Foundation (ASF) under one or more
-   contributor license agreements.  See the NOTICE file distributed with
-   this work for additional information regarding copyright ownership.
-   The ASF licenses this file to You under the Apache License, Version 2.0
-   (the "License"); you may not use this file except in compliance with
-   the License.  You may obtain a copy of the License at
-   
-       http://www.apache.org/licenses/LICENSE-2.0
-   
-   Unless required by applicable law or agreed to in writing, software
-   distributed under the License is distributed on an "AS IS" BASIS,
-   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-   See the License for the specific language governing permissions and
-   limitations under the License.
-
-
-`aria.parser` Package
-#####################
-
-This is the core parser API.
-
-:mod:`aria.parser`
-******************
-
-.. automodule:: aria
-
-:mod:`aria.parser.consumption`
-******************************
-
-.. automodule:: aria.parser.consumption
-
-:mod:`aria.parser.modeling`
-***************************
-
-.. automodule:: aria.parser.modeling
-
-:mod:`aria.parser.loading`
-**************************
-
-.. automodule:: aria.parser.loading
-
-:mod:`aria.parser.presentation`
-*******************************
-
-.. automodule:: aria.parser.presentation
-
-:mod:`aria.parser.reading`
-**************************
-
-.. automodule:: aria.parser.reading
-
-:mod:`aria.parser.validation`
-*****************************
-
-.. automodule:: aria.parser.validation
diff --git a/docs/requirements.txt b/docs/requirements.txt
index 976c5b6..a49bb26 100644
--- a/docs/requirements.txt
+++ b/docs/requirements.txt
@@ -11,4 +11,5 @@
 # limitations under the License.
 
 Sphinx>=1.6.2, <2.0.0
-sphinx_rtd_theme>=0.2.4, <1.0.0
+sphinx_rtd_theme>=0.2.4, <2.0.0
+sphinx-click>=1.0.2, <1.1.0
diff --git a/docs/tosca.rst b/docs/rest.rst
similarity index 63%
copy from docs/tosca.rst
copy to docs/rest.rst
index c98a4a9..185837e 100644
--- a/docs/tosca.rst
+++ b/docs/rest.rst
@@ -14,23 +14,7 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 
+REST
+====
 
-`aria_extension_tosca` Package
-##############################
-
-This is the ARIA TOSCA extension.
-
-:mod:`aria_extension_tosca`
-***************************
-
-.. automodule:: aria_extension_tosca
-
-:mod:`aria_extension_tosca.simple_v1_0`
-***************************************
-
-.. automodule:: aria_extension_tosca.simple_v1_0
-
-:mod:`aria_extension_tosca.simple_nfv_v1_0`
-*******************************************
-
-.. automodule:: aria_extension_tosca.simple_nfv_v1_0
+TODO
diff --git a/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py b/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py
index cd07f42..64178aa 100644
--- a/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py
+++ b/extensions/aria_extension_tosca/simple_nfv_v1_0/presenter.py
@@ -21,12 +21,12 @@
 
 class ToscaSimpleNfvPresenter1_0(ToscaSimplePresenter1_0): # pylint: disable=invalid-name,abstract-method
     """
-    ARIA presenter for the `TOSCA Simple Profile for NFV v1.0 csd03 <http://docs.oasis-open.org
-    /tosca/tosca-nfv/v1.0/csd03/tosca-nfv-v1.0-csd03.html>`__.
+    ARIA presenter for the `TOSCA Simple Profile for NFV v1.0 csd04 <http://docs.oasis-open.org
+    /tosca/tosca-nfv/v1.0/csd04/tosca-nfv-v1.0-csd04.html>`__.
 
-    Supported :code:`tosca_definitions_version` values:
+    Supported ``tosca_definitions_version`` values:
 
-    * :code:`tosca_simple_profile_for_nfv_1_0`
+    * ``tosca_simple_profile_for_nfv_1_0``
     """
 
     DSL_VERSIONS = ('tosca_simple_profile_for_nfv_1_0',)
diff --git a/extensions/aria_extension_tosca/simple_v1_0/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/__init__.py
index 7dcc60a..61995db 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/__init__.py
@@ -13,6 +13,115 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+"""
+Parser implementation of `TOSCA Simple Profile v1.0 cos01 <http://docs.oasis-open.org/tosca
+/TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html>`__.
+
+.. autosummary::
+   :nosignatures:
+
+   aria_extension_tosca.simple_v1_0.ToscaSimplePresenter1_0
+
+Assignments
+-----------
+
+.. autosummary::
+   :nosignatures:
+
+   aria_extension_tosca.simple_v1_0.PropertyAssignment
+   aria_extension_tosca.simple_v1_0.OperationAssignment
+   aria_extension_tosca.simple_v1_0.InterfaceAssignment
+   aria_extension_tosca.simple_v1_0.RelationshipAssignment
+   aria_extension_tosca.simple_v1_0.RequirementAssignment
+   aria_extension_tosca.simple_v1_0.AttributeAssignment
+   aria_extension_tosca.simple_v1_0.CapabilityAssignment
+   aria_extension_tosca.simple_v1_0.ArtifactAssignment
+
+Definitions
+-----------
+
+.. autosummary::
+   :nosignatures:
+
+   aria_extension_tosca.simple_v1_0.PropertyDefinition
+   aria_extension_tosca.simple_v1_0.AttributeDefinition
+   aria_extension_tosca.simple_v1_0.ParameterDefinition
+   aria_extension_tosca.simple_v1_0.OperationDefinition
+   aria_extension_tosca.simple_v1_0.InterfaceDefinition
+   aria_extension_tosca.simple_v1_0.RelationshipDefinition
+   aria_extension_tosca.simple_v1_0.RequirementDefinition
+   aria_extension_tosca.simple_v1_0.CapabilityDefinition
+
+Filters
+-------
+
+.. autosummary::
+   :nosignatures:
+
+   aria_extension_tosca.simple_v1_0.CapabilityFilter
+   aria_extension_tosca.simple_v1_0.NodeFilter
+
+Miscellaneous
+-------------
+
+.. autosummary::
+   :nosignatures:
+
+   aria_extension_tosca.simple_v1_0.Description
+   aria_extension_tosca.simple_v1_0.MetaData
+   aria_extension_tosca.simple_v1_0.Repository
+   aria_extension_tosca.simple_v1_0.Import
+   aria_extension_tosca.simple_v1_0.ConstraintClause
+   aria_extension_tosca.simple_v1_0.EntrySchema
+   aria_extension_tosca.simple_v1_0.OperationImplementation
+   aria_extension_tosca.simple_v1_0.SubstitutionMappingsRequirement
+   aria_extension_tosca.simple_v1_0.SubstitutionMappingsCapability
+   aria_extension_tosca.simple_v1_0.SubstitutionMappings
+
+Templates
+---------
+
+.. autosummary::
+   :nosignatures:
+
+   aria_extension_tosca.simple_v1_0.NodeTemplate
+   aria_extension_tosca.simple_v1_0.RelationshipTemplate
+   aria_extension_tosca.simple_v1_0.GroupTemplate
+   aria_extension_tosca.simple_v1_0.PolicyTemplate
+   aria_extension_tosca.simple_v1_0.TopologyTemplate
+   aria_extension_tosca.simple_v1_0.ServiceTemplate
+
+Types
+-----
+
+.. autosummary::
+   :nosignatures:
+
+   aria_extension_tosca.simple_v1_0.ArtifactType
+   aria_extension_tosca.simple_v1_0.DataType
+   aria_extension_tosca.simple_v1_0.CapabilityType
+   aria_extension_tosca.simple_v1_0.InterfaceType
+   aria_extension_tosca.simple_v1_0.RelationshipType
+   aria_extension_tosca.simple_v1_0.NodeType
+   aria_extension_tosca.simple_v1_0.GroupType
+   aria_extension_tosca.simple_v1_0.PolicyType
+
+Data types
+----------
+
+.. autosummary::
+   :nosignatures:
+
+   aria_extension_tosca.simple_v1_0.Timestamp
+   aria_extension_tosca.simple_v1_0.Version
+   aria_extension_tosca.simple_v1_0.Range
+   aria_extension_tosca.simple_v1_0.List
+   aria_extension_tosca.simple_v1_0.Map
+   aria_extension_tosca.simple_v1_0.ScalarSize
+   aria_extension_tosca.simple_v1_0.ScalarTime
+   aria_extension_tosca.simple_v1_0.ScalarFrequency
+"""
+
 from .presenter import ToscaSimplePresenter1_0
 from .assignments import (PropertyAssignment, OperationAssignment, InterfaceAssignment,
                           RelationshipAssignment, RequirementAssignment, AttributeAssignment,
diff --git a/extensions/aria_extension_tosca/simple_v1_0/assignments.py b/extensions/aria_extension_tosca/simple_v1_0/assignments.py
index 79f6377..0590527 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/assignments.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/assignments.py
@@ -61,7 +61,7 @@
         """
         The optional description string for the associated named operation.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_field(OperationImplementation)
@@ -70,7 +70,7 @@
         The optional implementation artifact name (e.g., a script file name within a TOSCA CSAR
         file).
 
-        :rtype: :class:`OperationImplementation`
+        :type: :class:`OperationImplementation`
         """
 
     @object_dict_field(PropertyAssignment)
@@ -81,7 +81,7 @@
         when operation definitions are included as part of a Requirement assignment in a Node
         Template.
 
-        :rtype: dict of str, :class:`PropertyAssignment`
+        :type: {:obj:`basestring`: :class:`PropertyAssignment`}
         """
 
     @cachedmethod
@@ -124,13 +124,13 @@
         when interface definitions are referenced as part of a Requirement assignment in a Node
         Template.
 
-        :rtype: dict of str, :class:`PropertyAssignment`
+        :type: {:obj:`basestring`: :class:`PropertyAssignment`}
         """
 
     @object_dict_unknown_fields(OperationAssignment)
     def operations(self):
         """
-        :rtype: dict of str, :class:`OperationAssignment`
+        :type: {:obj:`basestring`: :class:`OperationAssignment`}
         """
 
     @cachedmethod
@@ -157,6 +157,10 @@
 @short_form_field('type')
 @has_fields
 class RelationshipAssignment(ExtensiblePresentation):
+    """
+    Relationship assignment.
+    """
+
     @field_validator(relationship_template_or_type_validator)
     @primitive_field(str)
     def type(self):
@@ -164,7 +168,7 @@
         The optional reserved keyname used to provide the name of the Relationship Type for the
         requirement assignment's relationship keyname.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_dict_field(PropertyAssignment)
@@ -172,7 +176,7 @@
         """
         ARIA NOTE: This field is not mentioned in the spec, but is implied.
 
-        :rtype: dict of str, :class:`PropertyAssignment`
+        :type: {:obj:`basestring`: :class:`PropertyAssignment`}
         """
 
     @object_dict_field(InterfaceAssignment)
@@ -182,7 +186,7 @@
         the corresponding Relationship Type in order to provide Property assignments for these
         interfaces or operations of these interfaces.
 
-        :rtype: dict of str, :class:`InterfaceAssignment`
+        :type: {:obj:`basestring`: :class:`InterfaceAssignment`}
         """
 
     @cachedmethod
@@ -224,7 +228,7 @@
         * Capability Type that the provider will use to select a type-compatible target node
           template to fulfill the requirement at runtime.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @field_validator(node_template_or_type_validator)
@@ -238,7 +242,7 @@
         * Node Type name that the provider will use to select a type-compatible node template to
           fulfill the requirement at runtime.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(RelationshipAssignment)
@@ -251,7 +255,7 @@
         * Relationship Type that the provider will use to select a type-compatible relationship
           template to relate the source node to the target node at runtime.
 
-        :rtype: :class:`RelationshipAssignment`
+        :type: :class:`RelationshipAssignment`
         """
 
     @field_validator(node_filter_validator)
@@ -261,7 +265,7 @@
         The optional filter definition that TOSCA orchestrators or providers would use to select a
         type-compatible target node that can fulfill the associated abstract requirement at runtime.
 
-        :rtype: :class:`NodeFilter`
+        :type: :class:`NodeFilter`
         """
 
     @cachedmethod
@@ -325,7 +329,7 @@
         """
         An optional list of property definitions for the Capability definition.
 
-        :rtype: dict of str, :class:`PropertyAssignment`
+        :type: {:obj:`basestring`: :class:`PropertyAssignment`}
         """
 
     @object_dict_field(AttributeAssignment)
@@ -333,7 +337,7 @@
         """
         An optional list of attribute definitions for the Capability definition.
 
-        :rtype: dict of str, :class:`AttributeAssignment`
+        :type: {:obj:`basestring`: :class:`AttributeAssignment`}
         """
 
     @cachedmethod
@@ -370,7 +374,7 @@
         """
         The required artifact type for the artifact definition.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @primitive_field(str, required=True)
@@ -379,7 +383,7 @@
         The required URI string (relative or absolute) which can be used to locate the artifact's
         file.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @field_validator(type_validator('repository', 'repositories'))
@@ -390,7 +394,7 @@
         repository that contains the artifact. The artifact is expected to be referenceable by its
         file URI within the repository.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Description)
@@ -398,7 +402,7 @@
         """
         The optional description for the artifact definition.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @primitive_field(str)
@@ -406,7 +410,7 @@
         """
         The file path the associated file would be deployed into within the target node's container.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_dict_field(PropertyAssignment)
@@ -414,7 +418,7 @@
         """
         ARIA NOTE: This field is not mentioned in the spec, but is implied.
 
-        :rtype: dict of str, :class:`PropertyAssignment`
+        :type: {:obj:`basestring`: :class:`PropertyAssignment`}
         """
 
     @cachedmethod
diff --git a/extensions/aria_extension_tosca/simple_v1_0/definitions.py b/extensions/aria_extension_tosca/simple_v1_0/definitions.py
index 8564249..1bd0366 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/definitions.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/definitions.py
@@ -42,7 +42,7 @@
     an entity defined in this specification (e.g., Node Types, Relationship Types, Capability Types,
     etc.). Properties are used by template authors to provide input values to TOSCA entities which
     indicate their "desired state" when they are instantiated. The value of a property can be
-    retrieved using the :code:`get_property` function within TOSCA Service Templates.
+    retrieved using the ``get_property`` function within TOSCA Service Templates.
 
     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
@@ -55,7 +55,7 @@
         """
         The required data type for the property.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Description)
@@ -63,7 +63,7 @@
         """
         The optional description for the property.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @primitive_field(bool, default=True)
@@ -71,7 +71,7 @@
         """
         An optional key that declares a property as required (true) or not (false).
 
-        :rtype: bool
+        :type: bool
         """
 
     @field_validator(data_value_validator)
@@ -81,7 +81,7 @@
         An optional key that may provide a value to be used as a default if not provided by another
         means.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @primitive_field(str, default='supported', allowed=('supported', 'unsupported', 'experimental',
@@ -91,7 +91,7 @@
         """
         The optional status of the property relative to the specification or implementation.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_list_field(ConstraintClause)
@@ -99,7 +99,7 @@
         """
         The optional list of sequenced constraint clauses for the property.
 
-        :rtype: list of (str, :class:`ConstraintClause`)
+        :type: list of (str, :class:`ConstraintClause`)
         """
 
     @field_validator(entry_schema_validator)
@@ -109,7 +109,7 @@
         The optional key that is used to declare the name of the Datatype definition for entries of
         set types such as the TOSCA list or map.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @cachedmethod
@@ -128,7 +128,7 @@
     defined in this specification (e.g., a Node, Relationship or Capability Type). Specifically, it
     is used to expose the "actual state" of some property of a TOSCA entity after it has been
     deployed and instantiated (as set by the TOSCA orchestrator). Attribute values can be retrieved
-    via the :code:`get_attribute` function from the instance model and used as values to other
+    via the ``get_attribute`` function from the instance model and used as values to other
     entities within TOSCA Service Templates.
 
     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
@@ -142,7 +142,7 @@
         """
         The required data type for the attribute.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Description)
@@ -150,7 +150,7 @@
         """
         The optional description for the attribute.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @field_validator(data_value_validator)
@@ -163,7 +163,7 @@
         This value SHALL be type compatible with the type declared by the property definition's type
         keyname.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @primitive_field(str, default='supported', allowed=('supported', 'unsupported', 'experimental',
@@ -172,7 +172,7 @@
         """
         The optional status of the attribute relative to the specification or implementation.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @field_validator(entry_schema_validator)
@@ -182,7 +182,7 @@
         The optional key that is used to declare the name of the Datatype definition for entries of
         set types such as the TOSCA list or map.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @cachedmethod
@@ -212,7 +212,7 @@
         Note: This keyname is required for a TOSCA Property definition, but is not for a TOSCA
         Parameter definition.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @field_validator(data_value_validator)
@@ -241,7 +241,7 @@
         """
         The optional description string for the associated named operation.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_field(OperationImplementation)
@@ -250,7 +250,7 @@
         The optional implementation artifact name (e.g., a script file name within a TOSCA CSAR
         file).
 
-        :rtype: :class:`OperationImplementation`
+        :type: :class:`OperationImplementation`
         """
 
     @object_dict_field(PropertyDefinition)
@@ -261,7 +261,7 @@
         includes when interface definitions are included as part of a Requirement definition in a
         Node Type.
 
-        :rtype: dict of str, :class:`PropertyDefinition`
+        :type: {:obj:`basestring`: :class:`PropertyDefinition`}
         """
 
 @allow_unknown_fields
@@ -284,7 +284,7 @@
         """
         ARIA NOTE: This field is not mentioned in the spec, but is implied.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_dict_field(PropertyDefinition)
@@ -295,13 +295,13 @@
         includes when interface definitions are included as part of a Requirement definition in a
         Node Type.
 
-        :rtype: dict of str, :class:`PropertyDefinition`
+        :type: {:obj:`basestring`: :class:`PropertyDefinition`}
         """
 
     @object_dict_unknown_fields(OperationDefinition)
     def operations(self):
         """
-        :rtype: dict of str, :class:`OperationDefinition`
+        :type: {:obj:`basestring`: :class:`OperationDefinition`}
         """
 
     @cachedmethod
@@ -325,6 +325,10 @@
 @short_form_field('type')
 @has_fields
 class RelationshipDefinition(ExtensiblePresentation):
+    """
+    Relationship definition.
+    """
+
     @field_validator(type_validator('relationship type', convert_shorthand_to_full_type_name,
                                     'relationship_types'))
     @primitive_field(str, required=True)
@@ -333,7 +337,7 @@
         The optional reserved keyname used to provide the name of the Relationship Type for the
         requirement definition's relationship keyname.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_dict_field(InterfaceDefinition)
@@ -343,7 +347,7 @@
         the corresponding Relationship Type in order to declare additional Property definitions for
         these interfaces or operations of these interfaces.
 
-        :rtype: list of :class:`InterfaceDefinition`
+        :type: list of :class:`InterfaceDefinition`
         """
 
     @cachedmethod
@@ -375,7 +379,7 @@
         The required reserved keyname used that can be used to provide the name of a valid
         Capability Type that can fulfill the requirement.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @field_validator(type_validator('node type', convert_shorthand_to_full_type_name, 'node_types'))
@@ -385,7 +389,7 @@
         The optional reserved keyname used to provide the name of a valid Node Type that contains
         the capability definition that can be used to fulfill the requirement.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(RelationshipDefinition)
@@ -394,7 +398,7 @@
         The optional reserved keyname used to provide the name of a valid Relationship Type to
         construct when fulfilling the requirement.
 
-        :rtype: :class:`RelationshipDefinition`
+        :type: :class:`RelationshipDefinition`
         """
 
     @field_getter(data_type_class_getter(Range))
@@ -405,7 +409,7 @@
 
         Note: the keyword UNBOUNDED is also supported to represent any positive integer.
 
-        :rtype: :class:`Range`
+        :type: :class:`Range`
         """
 
     @cachedmethod
@@ -437,7 +441,7 @@
         """
         The required name of the Capability Type the capability definition is based upon.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Description)
@@ -445,7 +449,7 @@
         """
         The optional description of the Capability definition.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_dict_field(PropertyDefinition)
@@ -453,7 +457,7 @@
         """
         An optional list of property definitions for the Capability definition.
 
-        :rtype: dict of str, :class:`PropertyDefinition`
+        :type: {:obj:`basestring`: :class:`PropertyDefinition`}
         """
 
     @object_dict_field(AttributeDefinition)
@@ -461,7 +465,7 @@
         """
         An optional list of attribute definitions for the Capability definition.
 
-        :rtype: dict of str, :class:`AttributeDefinition`
+        :type: {:obj:`basestring`: :class:`AttributeDefinition`}
         """
 
     @field_validator(list_type_validator('node type', convert_shorthand_to_full_type_name,
@@ -472,7 +476,7 @@
         An optional list of one or more valid names of Node Types that are supported as valid
         sources of any relationship established to the declared Capability Type.
 
-        :rtype: list of str
+        :type: [:obj:`basestring`]
         """
 
     @field_getter(data_type_class_getter(Range))
@@ -481,14 +485,15 @@
         """
         The optional minimum and maximum occurrences for the capability. By default, an exported
         Capability should allow at least one relationship to be formed with it with a maximum of
-        :code:`UNBOUNDED` relationships.
+        ``UNBOUNDED`` relationships.
 
-        Note: the keyword :code:`UNBOUNDED` is also supported to represent any positive integer.
+        Note: the keyword ``UNBOUNDED`` is also supported to represent any positive integer.
 
-        ARIA NOTE: The spec seems wrong here: the implied default should be [0,UNBOUNDED], not
-        [1,UNBOUNDED], otherwise it would imply that at 1 least one relationship *must* be formed.
+        ARIA NOTE: The spec seems wrong here: the implied default should be ``[0,UNBOUNDED]``, not
+        ``[1,UNBOUNDED]``, otherwise it would imply that at 1 least one relationship *must* be
+        formed.
 
-        :rtype: :class:`Range`
+        :type: :class:`Range`
         """
 
     @cachedmethod
diff --git a/extensions/aria_extension_tosca/simple_v1_0/filters.py b/extensions/aria_extension_tosca/simple_v1_0/filters.py
index 838b505..6db140d 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/filters.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/filters.py
@@ -24,6 +24,10 @@
 
 @has_fields
 class CapabilityFilter(ExtensiblePresentation):
+    """
+    Capability filter.
+    """
+
     @object_sequenced_list_field(ConstraintClause)
     def properties(self):
         pass
@@ -69,7 +73,7 @@
         /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
         #DEFN_ELEMENT_PROPERTY_FILTER_DEFN>`__
 
-        :rtype: list of (str, :class:`ConstraintClause`)
+        :type: list of (str, :class:`ConstraintClause`)
         """
 
     @field_validator(node_filter_capabilities_validator)
@@ -80,7 +84,7 @@
         matching TOSCA entities (e.g., Node Template, Node Type, Capability Types, etc.) based upon
         their capabilities' property definitions' values.
 
-        :rtype: list of (str, :class:`CapabilityDefinition`)
+        :type: list of (str, :class:`CapabilityDefinition`)
         """
 
     @cachedmethod
diff --git a/extensions/aria_extension_tosca/simple_v1_0/misc.py b/extensions/aria_extension_tosca/simple_v1_0/misc.py
index 74eba18..f4d43ac 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/misc.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/misc.py
@@ -39,6 +39,8 @@
 @implements_specification('3.5.1', 'tosca-simple-1.0')
 class Description(AsIsPresentation):
     """
+    Human-readable description.
+
     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
     #DEFN_ELEMENT_DESCRIPTION>`__
@@ -55,6 +57,10 @@
 @has_fields
 @implements_specification('3.9.3.2', 'tosca-simple-1.0')
 class MetaData(ExtensiblePresentation):
+    """
+    Meta data.
+    """
+
     @primitive_field(str)
     @implements_specification('3.9.3.3', 'tosca-simple-1.0')
     def template_name(self):
@@ -82,7 +88,7 @@
     @primitive_dict_unknown_fields()
     def custom(self):
         """
-        :rtype: dict
+        :type: dict
         """
 
 @short_form_field('url')
@@ -103,7 +109,7 @@
         """
         The optional description for the repository.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @primitive_field(str, required=True)
@@ -111,7 +117,7 @@
         """
         The required URL or network address used to access the repository.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @primitive_field()
@@ -119,7 +125,7 @@
         """
         The optional Credential used to authorize access to the repository.
 
-        :rtype: tosca.datatypes.Credential
+        :type: tosca.datatypes.Credential
         """
 
     @cachedmethod
@@ -145,7 +151,7 @@
         """
         The required symbolic name for the imported file.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @primitive_field(str)
@@ -154,7 +160,7 @@
         The optional symbolic name of the repository definition where the imported file can be found
         as a string.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @primitive_field(str)
@@ -163,7 +169,7 @@
         The optional namespace URI to that will be applied to type definitions found within the
         imported file as a string.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @primitive_field(str)
@@ -173,7 +179,7 @@
         forming a qualified name (i.e., qname) when referencing type definitions from the imported
         file.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
 @has_fields
@@ -233,7 +239,7 @@
         Constrains a property or parameter to a value in range of (inclusive) the two values
         declared.
 
-        Note: subclasses or templates of types that declare a property with the :code:`in_range`
+        Note: subclasses or templates of types that declare a property with the ``in_range``
         constraint MAY only further restrict the range specified by the parent type.
         """
 
@@ -300,19 +306,19 @@
     @primitive_field(str, required=True)
     def type(self):
         """
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Description)
     def description(self):
         """
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_list_field(ConstraintClause)
     def constraints(self):
         """
-        :rtype: list of (str, :class:`ConstraintClause`)
+        :type: list of (str, :class:`ConstraintClause`)
         """
 
     @cachedmethod
@@ -326,13 +332,17 @@
 @short_form_field('primary')
 @has_fields
 class OperationImplementation(ExtensiblePresentation):
+    """
+    Operation implementation.
+    """
+
     @primitive_field(str)
     def primary(self):
         """
         The optional implementation artifact name (i.e., the primary script file name within a
         TOSCA CSAR file).
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @primitive_list_field(str)
@@ -342,10 +352,14 @@
         which are referenced by the primary implementation artifact (e.g., a library the script
         installs or a secondary script).
 
-        :rtype: list of str
+        :type: [:obj:`basestring`]
         """
 
 class SubstitutionMappingsRequirement(AsIsPresentation):
+    """
+    Substitution mapping for requirement.
+    """
+
     @property
     @cachedmethod
     def node_template(self):
@@ -361,6 +375,10 @@
         validate_subtitution_mappings_requirement(context, self)
 
 class SubstitutionMappingsCapability(AsIsPresentation):
+    """
+    Substitution mapping for capability.
+    """
+
     @property
     @cachedmethod
     def node_template(self):
@@ -378,23 +396,27 @@
 @has_fields
 @implements_specification('2.10', 'tosca-simple-1.0')
 class SubstitutionMappings(ExtensiblePresentation):
+    """
+    Substitution mappings.
+    """
+
     @field_validator(type_validator('node type', convert_shorthand_to_full_type_name, 'node_types'))
     @primitive_field(str, required=True)
     def node_type(self):
         """
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_dict_field(SubstitutionMappingsRequirement)
     def requirements(self):
         """
-        :rtype: dict of str, :class:`SubstitutionMappingsRequirement`
+        :type: {:obj:`basestring`: :class:`SubstitutionMappingsRequirement`}
         """
 
     @object_dict_field(SubstitutionMappingsCapability)
     def capabilities(self):
         """
-        :rtype: dict of str, :class:`SubstitutionMappingsCapability`
+        :type: {:obj:`basestring`: :class:`SubstitutionMappingsCapability`}
         """
 
     @cachedmethod
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
index 5813ccf..957dc7b 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -484,7 +484,6 @@
                 node_template_model.capability_templates[capability.capability]
             model.mappings[name] = \
                 SubstitutionTemplateMapping(name=name,
-                                            node_template=node_template_model,
                                             capability_template=capability_template_model)
 
     requirements = substitution_mappings.requirements
@@ -499,7 +498,6 @@
                     break
             model.mappings[name] = \
                 SubstitutionTemplateMapping(name=name,
-                                            node_template=node_template_model,
                                             requirement_template=requirement_template_model)
 
     return model
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
index a90a9fc..d75e723 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/capabilities.py
@@ -26,8 +26,8 @@
 
 def get_inherited_valid_source_types(context, presentation):
     """
-    If we haven't set the :code:`valid_source_types` fields, uses that value from our parent, if
-    we have one (recursively).
+    If we haven't set the ``valid_source_types`` fields, uses that value from our parent, if we have
+    one (recursively).
     """
 
     valid_source_types = presentation.valid_source_types
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/copy.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/copy.py
index b86e8eb..bd9037f 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/copy.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/copy.py
@@ -19,7 +19,7 @@
 
 def get_default_raw_from_copy(presentation, field_name):
     """
-    Used for the :code:`_get_default_raw` field hook.
+    Used for the ``_get_default_raw`` field hook.
     """
 
     copy = presentation._raw.get('copy')
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
index c0d79e5..ba94c70 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/data_types.py
@@ -55,7 +55,7 @@
 def coerce_data_type_value(context, presentation, data_type, entry_schema, constraints, value, # pylint: disable=unused-argument
                            aspect):
     """
-    Handles the :code:`_coerce_data()` hook for complex data types.
+    Handles the ``_coerce_data()`` hook for complex data types.
 
     There are two kinds of handling:
 
@@ -383,7 +383,7 @@
 
     Supports both complex data types and primitives.
 
-    Data types can use the :code:`coerce_value` extension to hook their own specialized function.
+    Data types can use the ``coerce_value`` extension to hook their own specialized function.
     If the extension is present, we will delegate to that hook.
     """
 
@@ -454,10 +454,10 @@
     Returns the value after it's coerced to a data type class, reporting validation errors if it
     cannot be coerced. Constraints will be applied after coersion.
 
-    Will either call a :code:`_create` static function in the class, or instantiate it using a
-    constructor if :code:`_create` is not available.
+    Will either call a ``_create`` static function in the class, or instantiate it using a
+    constructor if ``_create`` is not available.
 
-    This will usually be called by a :code:`coerce_value` extension hook in a :class:`DataType`.
+    This will usually be called by a ``coerce_value`` extension hook in a :class:`DataType`.
     """
 
     try:
diff --git a/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py b/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
index 7025213..590c6a0 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/functions.py
@@ -34,7 +34,7 @@
 @implements_specification('4.3.1', 'tosca-simple-1.0')
 class Concat(Function):
     """
-    The :code:`concat` function is used to concatenate two or more string values within a TOSCA
+    The ``concat`` function is used to concatenate two or more string values within a TOSCA
     service template.
     """
 
@@ -76,7 +76,7 @@
 @implements_specification('4.3.2', 'tosca-simple-1.0')
 class Token(Function):
     """
-    The :code:`token` function is used within a TOSCA service template on a string to parse out
+    The ``token`` function is used within a TOSCA service template on a string to parse out
     (tokenize) substrings separated by one or more token characters within a larger string.
     """
 
@@ -127,7 +127,7 @@
 @implements_specification('4.4.1', 'tosca-simple-1.0')
 class GetInput(Function):
     """
-    The :code:`get_input` function is used to retrieve the values of properties declared within the
+    The ``get_input`` function is used to retrieve the values of properties declared within the
     inputs section of a TOSCA Service Template.
     """
 
@@ -170,7 +170,7 @@
 @implements_specification('4.4.2', 'tosca-simple-1.0')
 class GetProperty(Function):
     """
-    The :code:`get_property` function is used to retrieve property values between modelable entities
+    The ``get_property`` function is used to retrieve property values between modelable entities
     defined in the same service template.
     """
 
@@ -238,7 +238,7 @@
 @implements_specification('4.5.1', 'tosca-simple-1.0')
 class GetAttribute(Function):
     """
-    The :code:`get_attribute` function is used to retrieve the values of named attributes declared
+    The ``get_attribute`` function is used to retrieve the values of named attributes declared
     by the referenced node or relationship template name.
     """
 
@@ -285,7 +285,7 @@
 @implements_specification('4.6.1', 'tosca-simple-1.0') # pylint: disable=abstract-method
 class GetOperationOutput(Function):
     """
-    The :code:`get_operation_output` function is used to retrieve the values of variables exposed /
+    The ``get_operation_output`` function is used to retrieve the values of variables exposed /
     exported from an interface operation.
     """
 
@@ -331,7 +331,7 @@
 @implements_specification('4.7.1', 'tosca-simple-1.0')
 class GetNodesOfType(Function):
     """
-    The :code:`get_nodes_of_type` function can be used to retrieve a list of all known instances of
+    The ``get_nodes_of_type`` function can be used to retrieve a list of all known instances of
     nodes of the declared Node Type.
     """
 
@@ -367,7 +367,7 @@
 @implements_specification('4.8.1', 'tosca-simple-1.0') # pylint: disable=abstract-method
 class GetArtifact(Function):
     """
-    The :code:`get_artifact` function is used to retrieve artifact location between modelable
+    The ``get_artifact`` function is used to retrieve artifact location between modelable
     entities defined in the same service template.
     """
 
@@ -574,7 +574,7 @@
     using this reference (i.e., as identified by its HostedOn relationship).
 
     Specifically, TOSCA orchestrators that encounter this keyword when evaluating the get_attribute
-    or :code:`get_property` functions SHALL search each node along the "HostedOn" relationship chain
+    or ``get_property`` functions SHALL search each node along the "HostedOn" relationship chain
     starting at the immediate node that hosts the node where the function was evaluated (and then
     that node's host node, and so forth) until a match is found or the "HostedOn" relationship chain
     ends.
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
index a2fd6ee..63bc02f 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/extensible.py
@@ -19,7 +19,7 @@
 @has_fields
 class ExtensiblePresentation(Presentation):
     """
-    A presentation that supports an optional :code:`_extensions` dict field.
+    A presentation that supports an optional ``_extensions`` dict field.
     """
 
     @primitive_dict_field()
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
index d7b03ae..be80702 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/field_validators.py
@@ -33,7 +33,7 @@
     """
     Makes sure that the field refers to an existing template defined in the root presenter.
 
-    Use with the :func:`field_validator` decorator for the :code:`copy` field in
+    Use with the :func:`field_validator` decorator for the ``copy`` field in
     :class:`NodeTemplate` and :class:`RelationshipTemplate`.
     """
 
@@ -64,7 +64,7 @@
     """
     Makes sure that the field refers to a valid data type, whether complex or primitive.
 
-    Used with the :func:`field_validator` decorator for the :code:`type` fields in
+    Used with the :func:`field_validator` decorator for the ``type`` fields in
     :class:`PropertyDefinition`, :class:`AttributeDefinition`, :class:`ParameterDefinition`,
     and :class:`EntrySchema`.
 
@@ -103,10 +103,10 @@
 
 def entry_schema_validator(field, presentation, context):
     """
-    According to whether the data type supports :code:`entry_schema` (e.g., it is or inherits from
+    According to whether the data type supports ``entry_schema`` (e.g., it is or inherits from
     list or map), make sure that we either have or don't have a valid data type value.
 
-    Used with the :func:`field_validator` decorator for the :code:`entry_schema` field in
+    Used with the :func:`field_validator` decorator for the ``entry_schema`` field in
     :class:`PropertyDefinition` and :class:`AttributeDefinition`.
     """
 
@@ -145,7 +145,7 @@
     """
     Makes sure that the field contains a valid value according to data type and constraints.
 
-    Used with the :func:`field_validator` decorator for the :code:`default` field in
+    Used with the :func:`field_validator` decorator for the ``default`` field in
     :class:`PropertyDefinition` and :class:`AttributeDefinition`.
     """
 
@@ -172,7 +172,7 @@
     """
     Makes sure that the field refers to a valid parent data type (complex or primitive).
 
-    Used with the :func:`field_validator` decorator for the :code:`derived_from` field in
+    Used with the :func:`field_validator` decorator for the ``derived_from`` field in
     :class:`DataType`.
     """
 
@@ -201,7 +201,7 @@
     """
     Makes sure that we do not have properties if we have a primitive ancestor.
 
-    Used with the :func:`field_validator` decorator for the :code:`properties` field in
+    Used with the :func:`field_validator` decorator for the ``properties`` field in
     :class:`DataType`.
     """
 
@@ -241,7 +241,7 @@
     valid value for the container type, and that the upper bound is either "UNBOUNDED" or a valid
     value for the container type.
 
-    Used with the :func:`field_validator` decorator for the :code:`in_range` field in
+    Used with the :func:`field_validator` decorator for the ``in_range`` field in
     :class:`ConstraintClause`.
     """
 
@@ -278,7 +278,7 @@
     """
     Makes sure that the value is a list of valid values for the container type.
 
-    Used with the :func:`field_validator` decorator for the :code:`valid_values` field in
+    Used with the :func:`field_validator` decorator for the ``valid_values`` field in
     :class:`ConstraintClause`.
     """
 
@@ -294,7 +294,7 @@
     """
     Makes sure that the value is a valid regular expression.
 
-    Used with the :func:`field_validator` decorator for the :code:`pattern` field in
+    Used with the :func:`field_validator` decorator for the ``pattern`` field in
     :class:`ConstraintClause`.
     """
 
@@ -324,7 +324,7 @@
     """
     Makes sure that the field refers to either a node template or a node type.
 
-    Used with the :func:`field_validator` decorator for the :code:`node` field in
+    Used with the :func:`field_validator` decorator for the ``node`` field in
     :class:`RequirementAssignment`.
     """
 
@@ -343,11 +343,11 @@
 def capability_definition_or_type_validator(field, presentation, context):
     """
     Makes sure refers to either a capability assignment name in the node template referred to by the
-    :code:`node` field or a general capability type.
+    ``node`` field or a general capability type.
 
-    If the value refers to a capability type, make sure the :code:`node` field was not assigned.
+    If the value refers to a capability type, make sure the ``node`` field was not assigned.
 
-    Used with the :func:`field_validator` decorator for the :code:`capability` field in
+    Used with the :func:`field_validator` decorator for the ``capability`` field in
     :class:`RequirementAssignment`.
     """
 
@@ -385,7 +385,7 @@
     """
     Makes sure that the field has a value only if "node" refers to a node type.
 
-    Used with the :func:`field_validator` decorator for the :code:`node_filter` field in
+    Used with the :func:`field_validator` decorator for the ``node_filter`` field in
     :class:`RequirementAssignment`.
     """
 
@@ -409,7 +409,7 @@
     """
     Makes sure that the field refers to either a relationship template or a relationship type.
 
-    Used with the :func:`field_validator` decorator for the :code:`type` field in
+    Used with the :func:`field_validator` decorator for the ``type`` field in
     :class:`RelationshipAssignment`.
     """
 
@@ -434,7 +434,7 @@
     """
     Makes sure that the field's elements refer to either node types or a group types.
 
-    Used with the :func:`field_validator` decorator for the :code:`targets` field in
+    Used with the :func:`field_validator` decorator for the ``targets`` field in
     :class:`PolicyType`.
     """
 
@@ -458,7 +458,7 @@
     Makes sure that the field's elements refer to either node templates or groups, and that
     they match the node types and group types declared in the policy type.
 
-    Used with the :func:`field_validator` decorator for the :code:`targets` field in
+    Used with the :func:`field_validator` decorator for the ``targets`` field in
     :class:`PolicyTemplate`.
     """
 
@@ -514,7 +514,7 @@
     """
     Makes sure that the field's elements refer to defined properties in the target node type.
 
-    Used with the :func:`field_validator` decorator for the :code:`properties` field in
+    Used with the :func:`field_validator` decorator for the ``properties`` field in
     :class:`NodeFilter`.
     """
 
@@ -537,7 +537,7 @@
     Makes sure that the field's elements refer to defined capabilities and properties in the target
     node type.
 
-    Used with the :func:`field_validator` decorator for the :code:`capabilities` field in
+    Used with the :func:`field_validator` decorator for the ``capabilities`` field in
     :class:`NodeFilter`.
     """
 
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
index 088a246..610e4a0 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presentation/types.py
@@ -17,11 +17,11 @@
     """
     Converts a shorthand type name to its full type name, or else returns it unchanged.
 
-    Works by checking for :code:`shorthand_name` in the types' :code:`_extensions` field. See also
+    Works by checking for ``shorthand_name`` in the types' ``_extensions`` field. See also
     :class:`aria_extension_tosca.v1_0.presentation.extensible.ExtensiblePresentation`.
 
-    Can be used as the conversion function argument in :code:`type_validator` and
-    :code:`derived_from_validator`.
+    Can be used as the conversion function argument in ``type_validator`` and
+    ``derived_from_validator``.
     """
 
     if (name is not None) and types_dict and (name not in types_dict):
@@ -35,11 +35,11 @@
     """
     Gets a type either by its full name or its shorthand name.
 
-    Works by checking for :code:`shorthand_name` in the types' :code:`_extensions` field. See also
-    :class:`aria_extension_tosca.v1_0.presentation.extensible.ExtensiblePresentation`.
+    Works by checking for ``shorthand_name`` in the types' ``_extensions`` field. See also
+    :class:`~aria_extension_tosca.v1_0.presentation.extensible.ExtensiblePresentation`.
 
     The arguments from the third onwards are used to locate a nested field under
-    :code:`service_template` under the root presenter.
+    ``service_template`` under the root presenter.
     """
 
     if name is not None:
diff --git a/extensions/aria_extension_tosca/simple_v1_0/presenter.py b/extensions/aria_extension_tosca/simple_v1_0/presenter.py
index f64078f..394e303 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/presenter.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/presenter.py
@@ -27,9 +27,9 @@
     ARIA presenter for the `TOSCA Simple Profile v1.0 cos01 <http://docs.oasis-open.org/tosca
     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html>`__.
 
-    Supported :code:`tosca_definitions_version` values:
+    Supported ``tosca_definitions_version`` values:
 
-    * :code:`tosca_simple_yaml_1_0`
+    * ``tosca_simple_yaml_1_0``
     """
 
     DSL_VERSIONS = ('tosca_simple_yaml_1_0',)
diff --git a/extensions/aria_extension_tosca/simple_v1_0/templates.py b/extensions/aria_extension_tosca/simple_v1_0/templates.py
index 123a00e..285e496 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/templates.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/templates.py
@@ -60,7 +60,7 @@
         """
         The required name of the Node Type the Node Template is based upon.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Description)
@@ -68,7 +68,7 @@
         """
         An optional description for the Node Template.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @primitive_list_field(str)
@@ -77,7 +77,7 @@
         An optional list of directive values to provide processing instructions to orchestrators and
         tooling.
 
-        :rtype: list of str
+        :type: [:obj:`basestring`]
         """
 
     @object_dict_field(PropertyAssignment)
@@ -85,7 +85,7 @@
         """
         An optional list of property value assignments for the Node Template.
 
-        :rtype: dict of str, :class:`PropertyAssignment`
+        :type: {:obj:`basestring`: :class:`PropertyAssignment`}
         """
 
     @object_dict_field(AttributeAssignment)
@@ -93,7 +93,7 @@
         """
         An optional list of attribute value assignments for the Node Template.
 
-        :rtype: dict of str, :class:`AttributeAssignment`
+        :type: {:obj:`basestring`: :class:`AttributeAssignment`}
         """
 
     @object_sequenced_list_field(RequirementAssignment)
@@ -101,7 +101,7 @@
         """
         An optional sequenced list of requirement assignments for the Node Template.
 
-        :rtype: list of (str, :class:`RequirementAssignment`)
+        :type: list of (str, :class:`RequirementAssignment`)
         """
 
     @object_dict_field(CapabilityAssignment)
@@ -109,7 +109,7 @@
         """
         An optional list of capability assignments for the Node Template.
 
-        :rtype: dict of str, :class:`CapabilityAssignment`
+        :type: {:obj:`basestring`: :class:`CapabilityAssignment`}
         """
 
     @object_dict_field(InterfaceAssignment)
@@ -117,7 +117,7 @@
         """
         An optional list of named interface definitions for the Node Template.
 
-        :rtype: dict of str, :class:`InterfaceAssignment`
+        :type: {:obj:`basestring`: :class:`InterfaceAssignment`}
         """
 
     @object_dict_field(ArtifactAssignment)
@@ -125,7 +125,7 @@
         """
         An optional list of named artifact definitions for the Node Template.
 
-        :rtype: dict of str, :class:`ArtifactAssignment`
+        :type: {:obj:`basestring`: :class:`ArtifactAssignment`}
         """
 
     @object_field(NodeFilter)
@@ -134,7 +134,7 @@
         The optional filter definition that TOSCA orchestrators would use to select the correct
         target node. This keyname is only valid if the directive has the value of "selectable" set.
 
-        :rtype: :class:`NodeFilter`
+        :type: :class:`NodeFilter`
         """
 
     @field_validator(copy_validator('node template', 'node_templates'))
@@ -144,7 +144,7 @@
         The optional (symbolic) name of another node template to copy into (all keynames and values)
         and use as a basis for this node template.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @cachedmethod
@@ -223,7 +223,7 @@
         """
         The required name of the Relationship Type the Relationship Template is based upon.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Description)
@@ -231,7 +231,7 @@
         """
         An optional description for the Relationship Template.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_dict_field(PropertyAssignment)
@@ -239,7 +239,7 @@
         """
         An optional list of property assignments for the Relationship Template.
 
-        :rtype: dict of str, :class:`PropertyAssignment`
+        :type: {:obj:`basestring`: :class:`PropertyAssignment`}
         """
 
     @object_dict_field(AttributeAssignment)
@@ -247,7 +247,7 @@
         """
         An optional list of attribute assignments for the Relationship Template.
 
-        :rtype: dict of str, :class:`AttributeAssignment`
+        :type: {:obj:`basestring`: :class:`AttributeAssignment`}
         """
 
     @object_dict_field(InterfaceAssignment)
@@ -257,7 +257,7 @@
 
         ARIA NOTE: Spec is wrong here, should be Relationship Template.
 
-        :rtype: dict of str, :class:`InterfaceAssignment`
+        :type: {:obj:`basestring`: :class:`InterfaceAssignment`}
         """
 
     @field_validator(copy_validator('relationship template', 'relationship_templates'))
@@ -267,7 +267,7 @@
         The optional (symbolic) name of another relationship template to copy into (all keynames and
         values) and use as a basis for this relationship template.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @cachedmethod
@@ -319,7 +319,7 @@
         """
         The required name of the group type the group definition is based upon.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Description)
@@ -327,7 +327,7 @@
         """
         The optional description for the group definition.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_dict_field(PropertyAssignment)
@@ -335,7 +335,7 @@
         """
         An optional list of property value assignments for the group definition.
 
-        :rtype: dict of str, :class:`PropertyAssignment`
+        :type: {:obj:`basestring`: :class:`PropertyAssignment`}
         """
 
     @field_validator(list_type_validator('node template', 'topology_template', 'node_templates'))
@@ -345,7 +345,7 @@
         The optional list of one or more node template names that are members of this group
         definition.
 
-        :rtype: list of str
+        :type: [:obj:`basestring`]
         """
 
     @object_dict_field(InterfaceAssignment)
@@ -353,7 +353,7 @@
         """
         An optional list of named interface definitions for the group definition.
 
-        :rtype: dict of str, :class:`InterfaceDefinition`
+        :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
         """
 
     @cachedmethod
@@ -392,7 +392,7 @@
         """
         The required name of the policy type the policy definition is based upon.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Description)
@@ -400,7 +400,7 @@
         """
         The optional description for the policy definition.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_dict_field(PropertyAssignment)
@@ -408,7 +408,7 @@
         """
         An optional list of property value assignments for the policy definition.
 
-        :rtype: dict of str, :class:`PropertyAssignment`
+        :type: {:obj:`basestring`: :class:`PropertyAssignment`
         """
 
     @field_validator(policy_targets_validator)
@@ -417,7 +417,7 @@
         """
         An optional list of valid Node Templates or Groups the Policy can be applied to.
 
-        :rtype: list of str
+        :type: [:obj:`basestring`]
         """
 
     @cachedmethod
@@ -444,7 +444,7 @@
     This section defines the topology template of a cloud application. The main ingredients of the
     topology template are node templates representing components of the application and relationship
     templates representing links between the components. These elements are defined in the nested
-    :code:`node_templates` section and the nested relationship_templates sections, respectively.
+    ``node_templates`` section and the nested relationship_templates sections, respectively.
     Furthermore, a topology template allows for defining input parameters, output parameters as well
     as grouping of node templates.
 
@@ -458,7 +458,7 @@
         """
         The optional description for the Topology Template.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_dict_field(ParameterDefinition)
@@ -467,7 +467,7 @@
         An optional list of input parameters (i.e., as parameter definitions) for the Topology
         Template.
 
-        :rtype: dict of str, :class:`ParameterDefinition`
+        :type: {:obj:`basestring`: :class:`ParameterDefinition`}
         """
 
     @object_dict_field(NodeTemplate)
@@ -475,7 +475,7 @@
         """
         An optional list of node template definitions for the Topology Template.
 
-        :rtype: dict of str, :class:`NodeTemplate`
+        :type: {:obj:`basestring`: :class:`NodeTemplate`}
         """
 
     @object_dict_field(RelationshipTemplate)
@@ -483,7 +483,7 @@
         """
         An optional list of relationship templates for the Topology Template.
 
-        :rtype: dict of str, :class:`RelationshipTemplate`
+        :type: {:obj:`basestring`: :class:`RelationshipTemplate`}
         """
 
     @object_dict_field(GroupTemplate)
@@ -500,7 +500,7 @@
         """
         An optional list of Policy definitions for the Topology Template.
 
-        :rtype: dict of str, :class:`PolicyTemplate`
+        :type: {:obj:`basestring`: :class:`PolicyTemplate`}
         """
 
     @object_dict_field(ParameterDefinition)
@@ -509,7 +509,7 @@
         An optional list of output parameters (i.e., as parameter definitions) for the Topology
         Template.
 
-        :rtype: dict of str, :class:`ParameterDefinition`
+        :type: {:obj:`basestring`: :class:`ParameterDefinition`}
         """
 
     @object_field(SubstitutionMappings)
@@ -551,6 +551,8 @@
 @implements_specification('3.9', 'tosca-simple-1.0')
 class ServiceTemplate(ExtensiblePresentation):
     """
+    Servicate template.
+
     See the `TOSCA Simple Profile v1.0 cos01 specification <http://docs.oasis-open.org/tosca
     /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
     #DEFN_ELEMENT_SERVICE_TEMPLATE>`__.
@@ -567,7 +569,7 @@
         /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
         #_Toc379455047>`__
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(MetaData)
@@ -580,7 +582,7 @@
         /TOSCA-Simple-Profile-YAML/v1.0/cos01/TOSCA-Simple-Profile-YAML-v1.0-cos01.html
         #_Toc379455048>`__
 
-        :rtype: :class:`MetaData`
+        :type: :class:`MetaData`
         """
 
     @object_field(Description)
@@ -589,7 +591,7 @@
         """
         Declares a description for this Service Template and its contents.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @primitive_field()
@@ -613,7 +615,7 @@
         the service template along with their addresses and necessary credential information used to
         connect to them in order to retrieve the artifacts.
 
-        :rtype: dict of str, :class:`Repository`
+        :type: {:obj:`basestring`: :class:`Repository`}
         """
 
     @object_list_field(Import)
@@ -623,7 +625,7 @@
         Declares import statements external TOSCA Definitions documents. For example, these may be
         file location or URIs relative to the service template file within the same TOSCA CSAR file.
 
-        :rtype: list of :class:`Import`
+        :type: list of :class:`Import`
         """
 
     @object_dict_field(ArtifactType)
@@ -633,7 +635,7 @@
         This section contains an optional list of artifact type definitions for use in the service
         template.
 
-        :rtype: dict of str, :class:`ArtifactType`
+        :type: {:obj:`basestring`: :class:`ArtifactType`}
         """
 
     @object_dict_field(DataType)
@@ -642,7 +644,7 @@
         """
         Declares a list of optional TOSCA Data Type definitions.
 
-        :rtype: dict of str, :class:`DataType`
+        :type: {:obj:`basestring`: :class:`DataType`}
         """
 
     @object_dict_field(CapabilityType)
@@ -652,7 +654,7 @@
         This section contains an optional list of capability type definitions for use in the service
         template.
 
-        :rtype: dict of str, :class:`CapabilityType`
+        :type: {:obj:`basestring`: :class:`CapabilityType`}
         """
 
     @object_dict_field(InterfaceType)
@@ -662,7 +664,7 @@
         This section contains an optional list of interface type definitions for use in the service
         template.
 
-        :rtype: dict of str, :class:`InterfaceType`
+        :type: {:obj:`basestring`: :class:`InterfaceType`}
         """
 
     @object_dict_field(RelationshipType)
@@ -672,7 +674,7 @@
         This section contains a set of relationship type definitions for use in the service
         template.
 
-        :rtype: dict of str, :class:`RelationshipType`
+        :type: {:obj:`basestring`: :class:`RelationshipType`}
         """
 
     @object_dict_field(NodeType)
@@ -681,7 +683,7 @@
         """
         This section contains a set of node type definitions for use in the service template.
 
-        :rtype: dict of str, :class:`NodeType`
+        :type: {:obj:`basestring`: :class:`NodeType`}
         """
 
     @object_dict_field(GroupType)
@@ -690,7 +692,7 @@
         """
         This section contains a list of group type definitions for use in the service template.
 
-        :rtype: dict of str, :class:`GroupType`
+        :type: {:obj:`basestring`: :class:`GroupType`}
         """
 
     @object_dict_field(PolicyType)
@@ -699,7 +701,7 @@
         """
         This section contains a list of policy type definitions for use in the service template.
 
-        :rtype: dict of str, :class:`PolicyType`
+        :type: {:obj:`basestring`: :class:`PolicyType`}
         """
 
     @object_field(TopologyTemplate)
@@ -709,7 +711,7 @@
         that represent the application's or service's components, as well as relationship templates
         representing relations between the components.
 
-        :rtype: :class:`TopologyTemplate`
+        :type: :class:`TopologyTemplate`
         """
 
     def _dump(self, context):
diff --git a/extensions/aria_extension_tosca/simple_v1_0/types.py b/extensions/aria_extension_tosca/simple_v1_0/types.py
index d97b89c..570b89f 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/types.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/types.py
@@ -64,7 +64,7 @@
         """
         An optional parent Artifact Type name the Artifact Type derives from.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @field_getter(data_type_class_getter(Version))
@@ -73,7 +73,7 @@
         """
         An optional version for the Artifact Type definition.
 
-        :rtype: :class:`Version`
+        :type: :class:`Version`
         """
 
     @object_field(Description)
@@ -81,7 +81,7 @@
         """
         An optional description for the Artifact Type.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @primitive_field(str)
@@ -89,7 +89,7 @@
         """
         The required mime type property for the Artifact Type.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @primitive_list_field(str)
@@ -97,7 +97,7 @@
         """
         The required file extension property for the Artifact Type.
 
-        :rtype: list of str
+        :type: [:obj:`basestring`]
         """
 
     @object_dict_field(PropertyDefinition)
@@ -105,7 +105,7 @@
         """
         An optional list of property definitions for the Artifact Type.
 
-        :rtype: dict of str, :class:`PropertyDefinition`
+        :type: {:obj:`basestring`: :class:`PropertyDefinition`}
         """
 
     @cachedmethod
@@ -147,7 +147,7 @@
         """
         The optional key used when a datatype is derived from an existing TOSCA Data Type.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Version)
@@ -155,7 +155,7 @@
         """
         An optional version for the Data Type definition.
 
-        :rtype: :class:`Version`
+        :type: :class:`Version`
         """
 
     @object_field(Description)
@@ -163,7 +163,7 @@
         """
         The optional description for the Data Type.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @field_validator(data_type_constraints_validator)
@@ -172,7 +172,7 @@
         """
         The optional list of sequenced constraint clauses for the Data Type.
 
-        :rtype: list of (str, :class:`ConstraintClause`)
+        :type: list of (str, :class:`ConstraintClause`)
         """
 
     @field_validator(data_type_properties_validator)
@@ -182,7 +182,7 @@
         The optional list property definitions that comprise the schema for a complex Data Type in
         TOSCA.
 
-        :rtype: dict of str, :class:`PropertyDefinition`
+        :type: {:obj:`basestring`: :class:`PropertyDefinition`}
         """
 
     @cachedmethod
@@ -244,7 +244,7 @@
         """
         An optional parent capability type name this new Capability Type derives from.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Version)
@@ -252,7 +252,7 @@
         """
         An optional version for the Capability Type definition.
 
-        :rtype: :class:`Version`
+        :type: :class:`Version`
         """
 
     @object_field(Description)
@@ -260,7 +260,7 @@
         """
         An optional description for the Capability Type.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_dict_field(PropertyDefinition)
@@ -270,7 +270,7 @@
 
         ARIA NOTE: The spec says 'list', but the examples are all of dicts.
 
-        :rtype: dict of str, :class:`PropertyDefinition`
+        :type: {:obj:`basestring`: :class:`PropertyDefinition`}
         """
 
     @object_dict_field(AttributeDefinition)
@@ -278,7 +278,7 @@
         """
         An optional list of attribute definitions for the Capability Type.
 
-        :rtype: dict of str, :class:`AttributeDefinition`
+        :type: {:obj:`basestring`: :class:`AttributeDefinition`}
         """
 
     @field_validator(list_type_validator('node type', convert_shorthand_to_full_type_name,
@@ -289,7 +289,7 @@
         An optional list of one or more valid names of Node Types that are supported as valid
         sources of any relationship established to the declared Capability Type.
 
-        :rtype: list of str
+        :type: [:obj:`basestring`]
         """
 
     @cachedmethod
@@ -345,7 +345,7 @@
         """
         An optional parent Interface Type name this new Interface Type derives from.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Version)
@@ -353,7 +353,7 @@
         """
         An optional version for the Interface Type definition.
 
-        :rtype: :class:`Version`
+        :type: :class:`Version`
         """
 
     @object_field(Description)
@@ -361,7 +361,7 @@
         """
         An optional description for the Interface Type.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_dict_field(PropertyDefinition)
@@ -369,13 +369,13 @@
         """
         The optional list of input parameter definitions.
 
-        :rtype: dict of str, :class:`PropertyDefinition`
+        :type: {:obj:`basestring`: :class:`PropertyDefinition`}
         """
 
     @object_dict_unknown_fields(OperationDefinition)
     def operations(self):
         """
-        :rtype: dict of str, :class:`OperationDefinition`
+        :type: {:obj:`basestring`: :class:`OperationDefinition`}
         """
 
     @cachedmethod
@@ -424,7 +424,7 @@
         """
         An optional parent Relationship Type name the Relationship Type derives from.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Version)
@@ -432,7 +432,7 @@
         """
         An optional version for the Relationship Type definition.
 
-        :rtype: :class:`Version`
+        :type: :class:`Version`
         """
 
     @object_field(Description)
@@ -440,7 +440,7 @@
         """
         An optional description for the Relationship Type.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_dict_field(PropertyDefinition)
@@ -448,7 +448,7 @@
         """
         An optional list of property definitions for the Relationship Type.
 
-        :rtype: dict of str, :class:`PropertyDefinition`
+        :type: {:obj:`basestring`: :class:`PropertyDefinition`}
         """
 
     @object_dict_field(AttributeDefinition)
@@ -456,7 +456,7 @@
         """
         An optional list of attribute definitions for the Relationship Type.
 
-        :rtype: dict of str, :class:`AttributeDefinition`
+        :type: {:obj:`basestring`: :class:`AttributeDefinition`}
         """
 
     @object_dict_field(InterfaceDefinition)
@@ -464,7 +464,7 @@
         """
         An optional list of interface definitions interfaces supported by the Relationship Type.
 
-        :rtype: dict of str, :class:`InterfaceDefinition`
+        :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
         """
 
     @field_validator(list_type_validator('capability type', convert_shorthand_to_full_type_name,
@@ -475,7 +475,7 @@
         An optional list of one or more names of Capability Types that are valid targets for this
         relationship.
 
-        :rtype: list of str
+        :type: [:obj:`basestring`]
         """
 
     @cachedmethod
@@ -538,7 +538,7 @@
         """
         An optional parent Node Type name this new Node Type derives from.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Version)
@@ -546,7 +546,7 @@
         """
         An optional version for the Node Type definition.
 
-        :rtype: :class:`Version`
+        :type: :class:`Version`
         """
 
     @object_field(Description)
@@ -554,7 +554,7 @@
         """
         An optional description for the Node Type.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_dict_field(PropertyDefinition)
@@ -562,7 +562,7 @@
         """
         An optional list of property definitions for the Node Type.
 
-        :rtype: dict of str, :class:`PropertyDefinition`
+        :type: {:obj:`basestring`: :class:`PropertyDefinition`}
         """
 
     @object_dict_field(AttributeDefinition)
@@ -570,7 +570,7 @@
         """
         An optional list of attribute definitions for the Node Type.
 
-        :rtype: dict of str, :class:`AttributeDefinition`
+        :type: {:obj:`basestring`: :class:`AttributeDefinition`}
         """
 
     @object_sequenced_list_field(RequirementDefinition)
@@ -582,7 +582,7 @@
         more than one requirement of the same name, behavior is undefined. The idea is to use the
         "occurrences" field if you need to limit the number of requirement assignments.
 
-        :rtype: list of (str, :class:`RequirementDefinition`)
+        :type: list of (str, :class:`RequirementDefinition`)
         """
 
     @object_dict_field(CapabilityDefinition)
@@ -590,7 +590,7 @@
         """
         An optional list of capability definitions for the Node Type.
 
-        :rtype: list of :class:`CapabilityDefinition`
+        :type: list of :class:`CapabilityDefinition`
         """
 
     @object_dict_field(InterfaceDefinition)
@@ -598,7 +598,7 @@
         """
         An optional list of interface definitions supported by the Node Type.
 
-        :rtype: dict of str, :class:`InterfaceDefinition`
+        :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
         """
 
     @object_dict_field(ArtifactAssignment)
@@ -606,7 +606,7 @@
         """
         An optional list of named artifact definitions for the Node Type.
 
-        :rtype: dict of str, :class:`ArtifactAssignment`
+        :type: {:obj:`basestring`: :class:`ArtifactAssignment`}
         """
 
     @cachedmethod
@@ -694,7 +694,7 @@
         """
         An optional parent Group Type name the Group Type derives from.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Version)
@@ -702,7 +702,7 @@
         """
         An optional version for the Group Type definition.
 
-        :rtype: :class:`Version`
+        :type: :class:`Version`
         """
 
     @object_field(Description)
@@ -710,7 +710,7 @@
         """
         The optional description for the Group Type.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_dict_field(PropertyDefinition)
@@ -718,7 +718,7 @@
         """
         An optional list of property definitions for the Group Type.
 
-        :rtype: dict of str, :class:`PropertyDefinition`
+        :type: {:obj:`basestring`: :class:`PropertyDefinition`}
         """
 
     @field_validator(list_type_validator('node type', convert_shorthand_to_full_type_name,
@@ -734,7 +734,7 @@
         For example, if we were to name this as an explicit Relationship Type we might call this
         "MemberOf" (group).
 
-        :rtype: list of str
+        :type: [:obj:`basestring`]
         """
 
     @object_dict_field(InterfaceDefinition)
@@ -742,7 +742,7 @@
         """
         An optional list of interface definitions supported by the Group Type.
 
-        :rtype: dict of str, :class:`InterfaceDefinition`
+        :type: {:obj:`basestring`: :class:`InterfaceDefinition`}
         """
 
     @cachedmethod
@@ -800,7 +800,7 @@
         """
         An optional parent Policy Type name the Policy Type derives from.
 
-        :rtype: str
+        :type: :obj:`basestring`
         """
 
     @object_field(Version)
@@ -808,7 +808,7 @@
         """
         An optional version for the Policy Type definition.
 
-        :rtype: :class:`Version`
+        :type: :class:`Version`
         """
 
     @object_field(Description)
@@ -816,7 +816,7 @@
         """
         The optional description for the Policy Type.
 
-        :rtype: :class:`Description`
+        :type: :class:`Description`
         """
 
     @object_dict_field(PropertyDefinition)
@@ -824,7 +824,7 @@
         """
         An optional list of property definitions for the Policy Type.
 
-        :rtype: :class:`PropertyDefinition`
+        :type: :class:`PropertyDefinition`
         """
 
     @field_validator(list_node_type_or_group_type_validator)
@@ -838,7 +838,7 @@
         were to name this as an explicit Relationship Type we might call this "AppliesTo" (node or
         group).
 
-        :rtype: list of str
+        :type: [:obj:`basestring`]
         """
 
     @cachedmethod
diff --git a/tests/orchestrator/workflows/core/test_events.py b/tests/orchestrator/workflows/core/test_events.py
index 30cc8ee..ff50eab 100644
--- a/tests/orchestrator/workflows/core/test_events.py
+++ b/tests/orchestrator/workflows/core/test_events.py
@@ -128,8 +128,8 @@
 
 
 def _assert_node_state_changed_as_a_result_of_standard_lifecycle_operation(node, op_name):
-    assert global_test_dict['transitional_state'] == NodeBase._op_to_state[op_name]['transitional']
-    assert node.state == NodeBase._op_to_state[op_name]['finished']
+    assert global_test_dict['transitional_state'] == NodeBase._OP_TO_STATE[op_name]['transitional']
+    assert node.state == NodeBase._OP_TO_STATE[op_name]['finished']
 
 
 @workflow