You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ariatosca.apache.org by mx...@apache.org on 2017/08/03 14:43:43 UTC

[1/2] incubator-ariatosca git commit: review 1 [Forced Update!]

Repository: incubator-ariatosca
Updated Branches:
  refs/heads/ARIA-174-Refactor-instantiation-phase f29602505 -> bbc5a7ed6 (forced update)


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/parser/presentation/fields.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/fields.py b/aria/parser/presentation/fields.py
index 9de2f7b..5c08d4a 100644
--- a/aria/parser/presentation/fields.py
+++ b/aria/parser/presentation/fields.py
@@ -571,7 +571,7 @@ class Field(object):
     def _dump_primitive(self, context, value):
         if hasattr(value, 'as_raw'):
             value = as_raw(value)
-        puts('%s: %s' % (self.name, context.style.literal(value)))
+        puts('%s: %s' % (self.name, context.style.literal_style(value)))
 
     # primitive list
 
@@ -610,7 +610,7 @@ class Field(object):
             for primitive in value:
                 if hasattr(primitive, 'as_raw'):
                     primitive = as_raw(primitive)
-                puts(context.style.literal(primitive))
+                puts(context.style.literal_style(primitive))
 
     # primitive dict
 
@@ -639,7 +639,7 @@ class Field(object):
             for v in value.itervalues():
                 if hasattr(v, 'as_raw'):
                     v = as_raw(v)
-                puts(context.style.literal(v))
+                puts(context.style.literal_style(v))
 
     # object
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/parser/presentation/presentation.py
----------------------------------------------------------------------
diff --git a/aria/parser/presentation/presentation.py b/aria/parser/presentation/presentation.py
index 164d9b2..3f9f86d 100644
--- a/aria/parser/presentation/presentation.py
+++ b/aria/parser/presentation/presentation.py
@@ -37,13 +37,13 @@ class Value(object):
 
     def _dump(self, context):
         if self.type is not None:
-            puts(context.style.type(self.type))
+            puts(context.style.type_style(self.type))
         if self.value is not None:
-            puts(context.style.literal(self.value))
+            puts(context.style.literal_style(self.value))
         if self.description is not None:
-            puts(context.style.meta(self.description))
+            puts(context.style.meta_style(self.description))
         if self.required is not None:
-            puts(context.style.required(self.required))
+            puts(context.style.required_style(self.required))
 
 
 class PresentationBase(HasCachedMethods):
@@ -162,7 +162,7 @@ class PresentationBase(HasCachedMethods):
             for field_name in self._iter_field_names():  # pylint: disable=no-member
                 self._dump_field(context, field_name)
         else:
-            puts(context.style.literal(self._raw))
+            puts(context.style.literal_style(self._raw))
 
     def _dump_field(self, context, field_name):
         """

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/parser/validation/context.py
----------------------------------------------------------------------
diff --git a/aria/parser/validation/context.py b/aria/parser/validation/context.py
index a245518..da9eef6 100644
--- a/aria/parser/validation/context.py
+++ b/aria/parser/validation/context.py
@@ -16,7 +16,7 @@
 from . import issue
 
 
-class ValidationContext(issue.Reporter):
+class ValidationContext(issue.ReporterMixin):
     """
     Validation context.
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/parser/validation/issue.py
----------------------------------------------------------------------
diff --git a/aria/parser/validation/issue.py b/aria/parser/validation/issue.py
index 11ea7f9..42fc580 100644
--- a/aria/parser/validation/issue.py
+++ b/aria/parser/validation/issue.py
@@ -132,12 +132,12 @@ class Issue(object):
         return heading_str
 
 
-class Reporter(object):
+class ReporterMixin(object):
 
     Issue = Issue
 
     def __init__(self, *args, **kwargs):
-        super(Reporter, self).__init__(*args, **kwargs)
+        super(ReporterMixin, self).__init__(*args, **kwargs)
         self._issues = threading.LockedList()
         self.max_level = self.Issue.ALL
 

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/utils/console.py
----------------------------------------------------------------------
diff --git a/aria/utils/console.py b/aria/utils/console.py
index cd5d480..fa9f873 100644
--- a/aria/utils/console.py
+++ b/aria/utils/console.py
@@ -31,51 +31,51 @@ _indent_string = ''
 
 
 class TopologyStylizer(object):
-    def __init__(self, indentation=2):
+    def __init__(self, indentation=0):
         self._str = StringIO()
         self._indentation = indentation
 
-    def write(self, str_):
-        puts(str_, stream=self._str)
+    def write(self, string):
+        self._str.write(self._indentation)
+        self._str.write(formatting.safe_repr(string))
+        self._str.write(os.linesep)
 
     @contextmanager
-    def indent(self, indentation=None):
-        with indent(indentation or self._indentation):
-            yield
+    def indent(self, indentation=2):
+        self._indentation += indentation
+        yield
+        self._indentation -= indentation
 
     @staticmethod
-    def section(value):
+    def section_style(value):
         return Colored.cyan(value, bold=True)
 
     @staticmethod
-    def type(value):
+    def type_style(value):
         return Colored.blue(value, bold=True)
 
     @staticmethod
-    def node(value):
+    def node_style(value):
         return Colored.red(value, bold=True)
 
     @staticmethod
-    def property(value):
+    def property_style(value):
         return Colored.magenta(value, bold=True)
 
     @staticmethod
-    def literal(value):
+    def literal_style(value):
         return Colored.magenta(formatting.safe_repr(value))
 
     @staticmethod
-    def required(value):
+    def required_style(value):
         return Colored.white(value)
 
     @staticmethod
-    def meta(value):
+    def meta_style(value):
         return Colored.green(value)
 
-    def __repr__(self):
-        return self._str.getvalue()
-
     def __str__(self):
-        return repr(self)
+        return self._str.getvalue()
 
 
 def puts(string='', newline=True, stream=sys.stdout):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/extensions/aria_extension_tosca/simple_v1_0/misc.py
----------------------------------------------------------------------
diff --git a/extensions/aria_extension_tosca/simple_v1_0/misc.py b/extensions/aria_extension_tosca/simple_v1_0/misc.py
index 23beb3c..a65ff41 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/misc.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/misc.py
@@ -52,7 +52,7 @@ class Description(AsIsPresentation):
 
     def _dump(self, context):
         value = as_raw(self.value)
-        puts(context.style.meta(value))
+        puts(context.style.meta_style(value))
 
 
 @allow_unknown_fields

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
----------------------------------------------------------------------
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 d84f1c0..1f90d29 100644
--- a/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
+++ b/extensions/aria_extension_tosca/simple_v1_0/modeling/__init__.py
@@ -498,6 +498,9 @@ def create_plugin_specification_model(context, policy):
 
 def create_workflow_operation_template_model(context, service_template, policy):
     model = OperationTemplate(name=policy._name)
+    # since we use backpopulates, these fields are populated upon commit, we get a weird(temporary)
+    # behavior where in previous code service_template.workflow_templates is a dict which has None
+    # as key for the value of model.
     service_template.workflow_templates[model.name] = model
 
     if policy.description:
@@ -606,7 +609,7 @@ def create_parameter_model_from_value(template_parameter, template_parameter_nam
 def create_parameter_models_from_assignments(properties, source_properties, model_cls):
     if source_properties:
         for property_name, prop in source_properties.iteritems():
-            properties[property_name] = model_cls(name=property_name, # pylint: disable=unexpected-keyword-arg
+            properties[property_name] = model_cls(name=property_name,                               # pylint: disable=unexpected-keyword-arg
                                                   type_name=prop.value.type,
                                                   value=prop.value.value,
                                                   description=prop.value.description)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/tests/instantiation/test_configuration.py
----------------------------------------------------------------------
diff --git a/tests/instantiation/test_configuration.py b/tests/instantiation/test_configuration.py
index a41f0a8..6ac0c9c 100644
--- a/tests/instantiation/test_configuration.py
+++ b/tests/instantiation/test_configuration.py
@@ -165,11 +165,8 @@ def test_remote(service):
 
 
 def test_reserved_arguments(broken_service_issues):
-    assert len(broken_service_issues) == 2
-
-    assert any(
-        all([issue.message.startswith('using reserved arguments in operation "operation": '),
-             'ctx' in issue.message,
-             'toolbelt' in issue.message])
-        for issue in broken_service_issues
-    )
+    assert len(broken_service_issues) == 1
+    message = broken_service_issues[0].message
+    assert message.startswith('using reserved arguments in operation "operation":')
+    assert '"ctx"' in message
+    assert '"toolbelt"' in message

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/tests/parser/service_templates.py
----------------------------------------------------------------------
diff --git a/tests/parser/service_templates.py b/tests/parser/service_templates.py
index ec41cd2..9e8fcae 100644
--- a/tests/parser/service_templates.py
+++ b/tests/parser/service_templates.py
@@ -27,7 +27,6 @@ def consume_literal(literal, consumer_class_name='instance', cache=True, no_issu
     context = create_context(LiteralLocation(literal))
     consumer, dumper = create_consumer(context, consumer_class_name)
     consumer.consume()
-    consumer.dump()
     if no_issues:
         context.validation.dump_issues()
         assert not context.validation.has_issues
@@ -48,6 +47,7 @@ def consume_use_case(use_case_name, consumer_class_name='instance', cache=True):
     assert not context.validation.has_issues
     return context, dumper
 
+
 def consume_types_use_case(use_case_name, consumer_class_name='instance', cache=True):
     cachedmethod.ENABLED = cache
     uri = get_service_template_uri('tosca-simple-1.0', 'types', use_case_name,
@@ -62,6 +62,7 @@ def consume_types_use_case(use_case_name, consumer_class_name='instance', cache=
     assert not context.validation.has_issues
     return context, dumper
 
+
 def consume_node_cellar(consumer_class_name='instance', cache=True):
     consume_test_case(
         get_service_template_uri('tosca-simple-1.0', 'node-cellar', 'node-cellar.yaml'),

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/tests/parser/test_reqs_caps.py
----------------------------------------------------------------------
diff --git a/tests/parser/test_reqs_caps.py b/tests/parser/test_reqs_caps.py
index 0af2487..e92aec4 100644
--- a/tests/parser/test_reqs_caps.py
+++ b/tests/parser/test_reqs_caps.py
@@ -18,10 +18,10 @@ from ..helpers import get_service_template_uri
 
 
 def test_satisfy_capability_type():
-    consume_reqs_caps_template('instance')
+    consume_reqs_caps_template1('instance')
 
 
-def consume_reqs_caps_template(consumer_class_name, cache=True):
+def consume_reqs_caps_template1(consumer_class_name, cache=True):
     consume_test_case(
         get_service_template_uri('tosca-simple-1.0', 'reqs_caps', 'reqs_caps1.yaml'),
         consumer_class_name=consumer_class_name,


[2/2] incubator-ariatosca git commit: review 1

Posted by mx...@apache.org.
review 1


Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/bbc5a7ed
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/bbc5a7ed
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/bbc5a7ed

Branch: refs/heads/ARIA-174-Refactor-instantiation-phase
Commit: bbc5a7ed6e1910ebf409b1b6a088c1bc2aa77fcf
Parents: b729f63
Author: max-orlov <ma...@gigaspaces.com>
Authored: Thu Aug 3 15:55:01 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Thu Aug 3 17:43:29 2017 +0300

----------------------------------------------------------------------
 aria/cli/commands/service_templates.py          |   2 +-
 aria/core.py                                    |  17 +-
 aria/modeling/mixins.py                         |   8 -
 aria/modeling/service_template.py               |  37 ++
 aria/modeling/utils.py                          |   4 +-
 aria/orchestrator/topology/common.py            |  50 ++-
 aria/orchestrator/topology/instance_handler.py  | 253 ++++++------
 aria/orchestrator/topology/template_handler.py  | 403 ++++++++++---------
 aria/orchestrator/topology/topology.py          | 106 ++---
 aria/orchestrator/topology/utils.py             |  19 -
 aria/parser/consumption/modeling.py             |  21 +-
 aria/parser/presentation/fields.py              |   6 +-
 aria/parser/presentation/presentation.py        |  10 +-
 aria/parser/validation/context.py               |   2 +-
 aria/parser/validation/issue.py                 |   4 +-
 aria/utils/console.py                           |  34 +-
 .../aria_extension_tosca/simple_v1_0/misc.py    |   2 +-
 .../simple_v1_0/modeling/__init__.py            |   5 +-
 tests/instantiation/test_configuration.py       |  13 +-
 tests/parser/service_templates.py               |   3 +-
 tests/parser/test_reqs_caps.py                  |   4 +-
 21 files changed, 528 insertions(+), 475 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/cli/commands/service_templates.py
----------------------------------------------------------------------
diff --git a/aria/cli/commands/service_templates.py b/aria/cli/commands/service_templates.py
index 89662a9..5a7039c 100644
--- a/aria/cli/commands/service_templates.py
+++ b/aria/cli/commands/service_templates.py
@@ -57,7 +57,7 @@ def service_templates():
 def show(service_template_name, model_storage, mode_full, mode_types, format_json, format_yaml,
          logger):
     """
-    Show information for a stored service templates
+    Show information for a stored service template
 
     SERVICE_TEMPLATE_NAME is the unique name of the stored service template.
     """

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/core.py
----------------------------------------------------------------------
diff --git a/aria/core.py b/aria/core.py
index a81ae13..83d5f7a 100644
--- a/aria/core.py
+++ b/aria/core.py
@@ -74,18 +74,19 @@ class Core(object):
         # setting no autoflush for the duration of instantiation - this helps avoid dependency
         # constraints as they're being set up
         with storage_session.no_autoflush:
-            topology_ = topology.Topology(self.model_storage)
-            service = topology_.instantiate(service_template, inputs=inputs)
-            topology_.coerce(service)
+            topology_ = topology.Topology()
+            service = topology_.instantiate(
+                service_template, inputs=inputs, model_storage=self.model_storage)
+            topology_.coerce(service, report_issues=True)
 
             topology_.validate(service)
             topology_.satisfy_requirements(service)
-            topology_.coerce(service)
+            topology_.coerce(service, report_issues=True)
 
             topology_.validate_capabilities(service)
-            topology_.find_hosts(service)
+            topology_.assign_hosts(service)
             topology_.configure_operations(service)
-            topology_.coerce(service)
+            topology_.coerce(service, report_issues=True)
             if topology_.dump_issues():
                 raise exceptions.InstantiationError('Failed to instantiate service template `{0}`'
                                                     .format(service_template.name))
@@ -117,8 +118,8 @@ class Core(object):
     def _parse_service_template(service_template_path):
         context = consumption.ConsumptionContext()
         context.presentation.location = UriLocation(service_template_path)
-        # TODO: this is the last place which uses the consumer chains (since read is a proper Parser
-        # todo..based consumer, it has no place in the topology package).
+        # Most of the parser uses the topology package in order to manipulate teh models.
+        # However, here we use the ConsumerChain, but this should change in the future.
         consumption.ConsumerChain(
             context,
             (

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/modeling/mixins.py
----------------------------------------------------------------------
diff --git a/aria/modeling/mixins.py b/aria/modeling/mixins.py
index 1a3cb32..d58c25a 100644
--- a/aria/modeling/mixins.py
+++ b/aria/modeling/mixins.py
@@ -296,14 +296,6 @@ class ParameterMixin(TemplateModelMixin, caching.HasCachedMethods):
             ('value', self.value),
             ('description', self.description)))
 
-    def coerce_values(self, report_issues):
-        value = self._value
-        if value is not None:
-            evaluation = functions.evaluate(value, self, report_issues)
-            if (evaluation is not None) and evaluation.final:
-                # A final evaluation can safely replace the existing value
-                self._value = evaluation.value
-
     @property
     def unwrapped(self):
         return self.name, self.value

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/modeling/service_template.py
----------------------------------------------------------------------
diff --git a/aria/modeling/service_template.py b/aria/modeling/service_template.py
index f2e1e78..aaf88db 100644
--- a/aria/modeling/service_template.py
+++ b/aria/modeling/service_template.py
@@ -530,6 +530,43 @@ class NodeTemplateBase(TemplateModelMixin):
 
         return '{name}_{index}'.format(name=self.name, index=self._next_index)
 
+    @property
+    def scaling(self):
+        scaling = {}
+
+        def extract_property(properties, name):
+            if name in scaling:
+                return
+            prop = properties.get(name)
+            if (prop is not None) and (prop.type_name == 'integer') and (prop.value is not None):
+                scaling[name] = prop.value
+
+        def extract_properties(properties):
+            extract_property(properties, 'min_instances')
+            extract_property(properties, 'max_instances')
+            extract_property(properties, 'default_instances')
+
+        def default_property(name, value):
+            if name not in scaling:
+                scaling[name] = value
+
+        # From our scaling capabilities
+        for capability_template in self.capability_templates.itervalues():
+            if capability_template.type.role == 'scaling':
+                extract_properties(capability_template.properties)
+
+        # From service scaling policies
+        for policy_template in self.service_template.policy_templates.itervalues():
+            if policy_template.type.role == 'scaling':
+                if policy_template.is_for_node_template(self.name):
+                    extract_properties(policy_template.properties)
+
+        # Defaults
+        default_property('min_instances', 0)
+        default_property('max_instances', 1)
+        default_property('default_instances', 1)
+
+        return scaling
 
 class GroupTemplateBase(TemplateModelMixin):
     """

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/modeling/utils.py
----------------------------------------------------------------------
diff --git a/aria/modeling/utils.py b/aria/modeling/utils.py
index 5218b81..9b64598 100644
--- a/aria/modeling/utils.py
+++ b/aria/modeling/utils.py
@@ -107,7 +107,7 @@ def merge_parameter_values(provided_values, declared_parameters, model_cls=None)
     provided_values = provided_values or {}
     provided_values_of_wrong_type = OrderedDict()
     model_parameters = OrderedDict()
-    model_cls = model_cls or get_class_from_relationship(declared_parameters)
+    model_cls = model_cls or _get_class_from_sql_relationship(declared_parameters)
 
     for declared_parameter_name, declared_parameter in declared_parameters.iteritems():
         if declared_parameter_name in provided_values:
@@ -175,7 +175,7 @@ def fix_doc(cls):
     return cls
 
 
-def get_class_from_relationship(property):
+def _get_class_from_sql_relationship(property):
     class_ = property._sa_adapter.owner_state.class_
     prop_name = property._sa_adapter.attr.key
     return getattr(class_, prop_name).property.mapper.class_

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/orchestrator/topology/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/common.py b/aria/orchestrator/topology/common.py
index 45e9ab0..02926ab 100644
--- a/aria/orchestrator/topology/common.py
+++ b/aria/orchestrator/topology/common.py
@@ -14,39 +14,53 @@
 # limitations under the License.
 
 
-class _Handler(object):
-    def __init__(self, topology, template):
+class HandlerBase(object):
+    def __init__(self, topology, model):
         self._topology = topology
-        self._model = template
+        self._model = model
 
-    def _coerce(self, *templates, **kwargs):
-        for template in templates:
-            self._topology.coerce(template)
+    def coerce(self, **kwargs):
+        raise NotImplementedError
 
-    def coerce(self):
-        pass
+    def _coerce(self, *models, **kwargs):
+        for template in models:
+            self._topology.coerce(template, **kwargs)
 
     def validate(self, **kwargs):
-        pass
+        raise NotImplementedError
 
-    def _validate(self, *templates, **kwargs):
-        for template in templates:
-            self._topology.validate(template)
+    def _validate(self, *models, **kwargs):
+        for template in models:
+            self._topology.validate(template, **kwargs)
 
     def dump(self, out_stream):
-        pass
+        raise NotImplementedError
 
 
-class _TemplateHandlerMixin(_Handler):
+class TemplateHandlerBase(HandlerBase):
+    """
+    Base handler for template based models
+    """
 
-    def instantiate(self, instance_cls):
+    def instantiate(self, instance_cls, **kwargs):
         raise NotImplementedError
 
 
-class _InstanceHandlerMixin(_Handler):
-    pass
+class InstanceHandlerBase(HandlerBase):
+    """
+    Base handler for instance based models
+
+    """
+    def validate(self, **kwargs):
+        raise NotImplementedError
+
+    def coerce(self, **kwargs):
+        raise NotImplementedError
+
+    def dump(self, out_stream):
+        raise NotImplementedError
 
 
-class _OperatorHolderHandlerMixin(_Handler):
+class ActorHandlerBase(HandlerBase):
     def configure_operations(self):
         raise NotImplementedError

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/orchestrator/topology/instance_handler.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/instance_handler.py b/aria/orchestrator/topology/instance_handler.py
index ea58d88..4e0a974 100644
--- a/aria/orchestrator/topology/instance_handler.py
+++ b/aria/orchestrator/topology/instance_handler.py
@@ -14,111 +14,114 @@
 # limitations under the License.
 
 from ... parser.modeling import context
-from ... modeling import models
+from ... modeling import models, functions
 from ... utils import formatting
 from .. import execution_plugin
 from .. import decorators
 from . import common
 
 
-class Artifact(common._InstanceHandlerMixin):
+class Artifact(common.InstanceHandlerBase):
 
     def coerce(self, **kwargs):
         self._topology.coerce(self._model.properties, **kwargs)
 
     def validate(self, **kwargs):
-        self._topology.validate(self._model.properties)
+        self._topology.validate(self._model.properties, **kwargs)
 
     def dump(self, out_stream):
         with out_stream.indent():
-            out_stream.write(out_stream.node(self._model.name))
-            out_stream.write(out_stream.meta(self._model.description))
+            out_stream.write(out_stream.node_style(self._model.name))
+            out_stream.write(out_stream.meta_style(self._model.description))
             with out_stream.indent():
-                out_stream.write('Artifact type: {0}'.format(out_stream.type(
-                    self._model.type.name)))
+                out_stream.write('Artifact type: {0}'.format(out_stream.type_style(
+                    self._model.type_style.name)))
                 out_stream.write('Source path: {0}'.format(
-                    out_stream.literal(self._model.source_path)))
+                    out_stream.literal_style(self._model.source_path)))
                 if self._model.target_path is not None:
                     out_stream.write('Target path: {0}'.format(
-                        out_stream.literal(self._model.target_path)))
+                        out_stream.literal_style(self._model.target_path)))
                 if self._model.repository_url is not None:
                     out_stream.write('Repository URL: {0}'.format(
-                        out_stream.literal(self._model.repository_url)))
+                        out_stream.literal_style(self._model.repository_url)))
                 if self._model.repository_credential:
                     out_stream.write('Repository credential: {0}'.format(
-                        out_stream.literal(self._model.repository_credential)))
-                self._topology.dump(self._model.properties, out_stream, 'Properties')
+                        out_stream.literal_style(self._model.repository_credential)))
+                self._topology.dump(self._model.properties, out_stream, title='Properties')
 
 
-class Capability(common._InstanceHandlerMixin):
+class Capability(common.InstanceHandlerBase):
     def coerce(self, **kwargs):
         self._topology.coerce(self._model.properties, **kwargs)
 
     def validate(self, **kwargs):
-        self._topology.validate(self._model.properties)
+        self._topology.validate(self._model.properties, **kwargs)
 
     def dump(self, out_stream):
-        out_stream.write(out_stream.node(self._model.name))
+        out_stream.write(out_stream.node_style(self._model.name))
         with out_stream.indent():
-            out_stream.write('Type: {0}'.format(out_stream.type(self._model.type.name)))
+            out_stream.write('Type: {0}'.format(out_stream.type_style(self._model.type_style.name)))
             out_stream.write('Occurrences: {0:d} ({1:d}{2})'.format(
                 self._model.occurrences,
                 self._model.min_occurrences or 0,
                 ' to {0:d}'.format(self._model.max_occurrences)
                 if self._model.max_occurrences is not None
                 else ' or more'))
-            self._topology.dump(self._model.properties, out_stream, 'Properties')
+            self._topology.dump(self._model.properties, out_stream, title='Properties')
 
 
-class Group(common._OperatorHolderHandlerMixin):
+class Group(common.ActorHandlerBase):
 
     def coerce(self, **kwargs):
         self._coerce(self._model.properties, self._model.interfaces, **kwargs)
 
     def validate(self, **kwargs):
         self._validate(self._model.properties,
-                       self._model.interfaces)
+                       self._model.interfaces,
+                       **kwargs)
 
     def dump(self, out_stream):
-        out_stream.write('Group: {0}'.format(out_stream.node(self._model.name)))
+        out_stream.write('Group: {0}'.format(out_stream.node_style(self._model.name)))
         with out_stream.indent():
-            out_stream.write('Type: {0}'.format(out_stream.type(self._model.type.name)))
-            self._topology.dump(self._model.properties, out_stream, 'Properties')
-            self._topology.dump(self._model.interfaces, out_stream, 'Interfaces')
+            out_stream.write('Type: {0}'.format(out_stream.type_style(self._model.type_style.name)))
+            self._topology.dump(self._model.properties, out_stream, title='Properties')
+            self._topology.dump(self._model.interfaces, out_stream, title='Interfaces')
             if self._model.nodes:
                 out_stream.write('Member nodes:')
                 with out_stream.indent():
                     for node in self._model.nodes:
-                        out_stream.write(out_stream.node(node.name))
+                        out_stream.write(out_stream.node_style(node.name))
 
     def configure_operations(self):
         for interface in self._model.interfaces.values():
             self._topology.configure_operations(interface)
 
 
-class Interface(common._OperatorHolderHandlerMixin):
+class Interface(common.ActorHandlerBase):
     def coerce(self, **kwargs):
         self._coerce(self._model.inputs, self._model.operations, **kwargs)
 
     def validate(self, **kwargs):
         self._validate(self._model.inputs,
-                       self._model.operations)
+                       self._model.operations,
+                       **kwargs)
 
     def dump(self, out_stream):
-        out_stream.write(out_stream.node(self._model.name))
+        out_stream.write(out_stream.node_style(self._model.name))
         if self._model.description:
-            out_stream.write(out_stream.meta(self._model.description))
+            out_stream.write(out_stream.meta_style(self._model.description))
         with out_stream.indent():
-            out_stream.write('Interface type: {0}'.format(out_stream.type(self._model.type.name)))
-            self._topology.dump(self._model.inputs, out_stream, 'Inputs')
-            self._topology.dump(self._model.operations, out_stream, 'Operations')
+            out_stream.write('Interface type: {0}'.format(
+                out_stream.type_style(self._model.type.name)))
+            self._topology.dump(self._model.inputs, out_stream, title='Inputs')
+            self._topology.dump(self._model.operations, out_stream, title='Operations')
 
     def configure_operations(self):
         for operation in self._model.operations.values():
             self._topology.configure_operations(operation)
 
 
-class Node(common._OperatorHolderHandlerMixin):
+class Node(common.ActorHandlerBase):
     def coerce(self, **kwargs):
         self._coerce(self._model.properties,
                      self._model.attributes,
@@ -143,17 +146,18 @@ class Node(common._OperatorHolderHandlerMixin):
                        self._model.outbound_relationships)
 
     def dump(self, out_stream):
-        out_stream.write('Node: {0}'.format(out_stream.node(self._model.name)))
+        out_stream.write('Node: {0}'.format(out_stream.node_style(self._model.name)))
         with out_stream.indent():
-            out_stream.write('Type: {0}'.format(out_stream.type(self._model.type.name)))
+            out_stream.write('Type: {0}'.format(out_stream.type_style(self._model.type_style.name)))
             out_stream.write('Template: {0}'.format(
-                out_stream.node(self._model.node_template.name)))
-            self._topology.dump(self._model.properties, out_stream, 'Properties')
-            self._topology.dump(self._model.attributes, out_stream, 'Attributes')
-            self._topology.dump(self._model.interfaces, out_stream, 'Interfaces')
-            self._topology.dump(self._model.artifacts, out_stream, 'Artifacts')
-            self._topology.dump(self._model.capabilities, out_stream, 'Capabilities')
-            self._topology.dump(self._model.outbound_relationships, out_stream, 'Relationships')
+                out_stream.node_style(self._model.node_template.name)))
+            self._topology.dump(self._model.properties, out_stream, title='Properties')
+            self._topology.dump(self._model.attributes, out_stream, title='Attributes')
+            self._topology.dump(self._model.interfaces, out_stream, title='Interfaces')
+            self._topology.dump(self._model.artifacts, out_stream, title='Artifacts')
+            self._topology.dump(self._model.capabilities, out_stream, title='Capabilities')
+            self._topology.dump(self._model.outbound_relationships, out_stream,
+                                title='Relationships')
 
     def configure_operations(self):
         for interface in self._model.interfaces.values():
@@ -183,9 +187,9 @@ class Node(common._OperatorHolderHandlerMixin):
             # information in the creation of the relationship, Some requirements may have been
             # satisfied by a previous run on that node template.
             # The entire mechanism of satisfying requirements needs to be refactored.
-            if any(r.requirement_template == requirement_template
-                   for r in self._model.outbound_relationships):
-                return satisfied
+            if any(rel.requirement_template == requirement_template
+                   for rel in self._model.outbound_relationships):
+                continue
 
             # Find target template
             target_node_template, target_node_capability = self._find_target(requirement_template)
@@ -248,7 +252,8 @@ class Node(common._OperatorHolderHandlerMixin):
             return False
 
     def _find_target(self, requirement_template):
-        # We might already have a specific node template, so we'll just verify it
+        # We might already have a specific node template from the requirement template, so
+        # we'll just verify it
         if requirement_template.target_node_template is not None:
             if not self._model.node_template.is_target_node_template_valid(
                     requirement_template.target_node_template):
@@ -289,6 +294,7 @@ class Node(common._OperatorHolderHandlerMixin):
 
                 return target_node_template, target_node_capability
 
+        # Find the first node which has a capability of the required type
         elif requirement_template.target_capability_type is not None:
             for target_node_template in \
                     self._model.node_template.service_template.node_templates.itervalues():
@@ -334,7 +340,7 @@ class Node(common._OperatorHolderHandlerMixin):
         return True
 
 
-class Operation(common._OperatorHolderHandlerMixin):
+class Operation(common.ActorHandlerBase):
     def coerce(self, **kwargs):
         self._coerce(self._model.inputs,
                      self._model.configurations,
@@ -344,36 +350,39 @@ class Operation(common._OperatorHolderHandlerMixin):
     def validate(self, **kwargs):
         self._validate(self._model.inputs,
                        self._model.configurations,
-                       self._model.arguments)
+                       self._model.arguments,
+                       **kwargs)
 
     def dump(self, out_stream):
-        out_stream.write(out_stream.node(self._model.name))
+        out_stream.write(out_stream.node_style(self._model.name))
         if self._model.description:
-            out_stream.write(out_stream.meta(self._model.description))
+            out_stream.write(out_stream.meta_style(self._model.description))
         with out_stream.indent():
             if self._model.implementation is not None:
                 out_stream.write('Implementation: {0}'.format(
-                    out_stream.literal(self._model.implementation)))
+                    out_stream.literal_style(self._model.implementation)))
             if self._model.dependencies:
                 out_stream.write(
-                    'Dependencies: {0}'.format(
-                        ', '.join((str(out_stream.literal(v)) for v in self._model.dependencies))))
-            self._topology.dump(self._model.inputs, out_stream, 'Inputs')
+                    'Dependencies: {0}'.format(', '.join((str(out_stream.literal_style(v))
+                                                          for v in self._model.dependencies))))
+            self._topology.dump(self._model.inputs, out_stream, title='Inputs')
             if self._model.executor is not None:
-                out_stream.write('Executor: {0}'.format(out_stream.literal(self._model.executor)))
+                out_stream.write('Executor: {0}'.format(out_stream.literal_style(
+                    self._model.executor)))
             if self._model.max_attempts is not None:
-                out_stream.write('Max attempts: {0}'.format(out_stream.literal(
+                out_stream.write('Max attempts: {0}'.format(out_stream.literal_style(
                     self._model.max_attempts)))
             if self._model.retry_interval is not None:
                 out_stream.write('Retry interval: {0}'.format(
-                    out_stream.literal(self._model.retry_interval)))
+                    out_stream.literal_style(self._model.retry_interval)))
             if self._model.plugin is not None:
                 out_stream.write('Plugin: {0}'.format(
-                    out_stream.literal(self._model.plugin.name)))
-            self._topology.dump(self._model.configurations, out_stream, 'Configuration')
+                    out_stream.literal_style(self._model.plugin.name)))
+            self._topology.dump(self._model.configurations, out_stream, title='Configuration')
             if self._model.function is not None:
-                out_stream.write('Function: {0}'.format(out_stream.literal(self._model.function)))
-            self._topology.dump(self._model.arguments, out_stream, 'Arguments')
+                out_stream.write('Function: {0}'.format(out_stream.literal_style(
+                    self._model.function)))
+            self._topology.dump(self._model.arguments, out_stream, title='Arguments')
 
     def configure_operations(self):
         if self._model.implementation is None and self._model.function is None:
@@ -414,31 +423,31 @@ class Operation(common._OperatorHolderHandlerMixin):
                 level=self._topology.Issue.EXTERNAL)
 
 
-class Policy(common._InstanceHandlerMixin):
+class Policy(common.InstanceHandlerBase):
     def coerce(self, **kwargs):
         self._topology.coerce(self._model.properties, **kwargs)
 
     def validate(self, **kwargs):
-        self._topology.validate(self._model.properties)
+        self._topology.validate(self._model.properties, **kwargs)
 
     def dump(self, out_stream):
-        out_stream.write('Policy: {0}'.format(out_stream.node(self._model.name)))
+        out_stream.write('Policy: {0}'.format(out_stream.node_style(self._model.name)))
         with out_stream.indent():
-            out_stream.write('Type: {0}'.format(out_stream.type(self._model.type.name)))
-            self._topology.dump(self._model.properties, out_stream, 'Properties')
+            out_stream.write('Type: {0}'.format(out_stream.type_style(self._model.type_style.name)))
+            self._topology.dump(self._model.properties, out_stream, title='Properties')
             if self._model.nodes:
                 out_stream.write('Target nodes:')
                 with out_stream.indent():
                     for node in self._model.nodes:
-                        out_stream.write(out_stream.node(node.name))
+                        out_stream.write(out_stream.node_style(node.name))
             if self._model.groups:
                 out_stream.write('Target groups:')
                 with out_stream.indent():
                     for group in self._model.groups:
-                        out_stream.write(out_stream.node(group.name))
+                        out_stream.write(out_stream.node_style(group.name))
 
 
-class Relationship(common._OperatorHolderHandlerMixin):
+class Relationship(common.ActorHandlerBase):
     def coerce(self, **kwargs):
         self._coerce(self._model.properties,
                      self._model.interfaces,
@@ -446,34 +455,36 @@ class Relationship(common._OperatorHolderHandlerMixin):
 
     def validate(self, **kwargs):
         self._validate(self._model.properties,
-                       self._model.interfaces)
+                       self._model.interfaces,
+                       **kwargs)
 
     def dump(self, out_stream):
         if self._model.name:
-            out_stream.write('{0} ->'.format(out_stream.node(self._model.name)))
+            out_stream.write('{0} ->'.format(out_stream.node_style(self._model.name)))
         else:
             out_stream.write('->')
         with out_stream.indent():
-            out_stream.write('Node: {0}'.format(out_stream.node(self._model.target_node.name)))
+            out_stream.write('Node: {0}'.format(out_stream.node_style(
+                self._model.target_node.name)))
             if self._model.target_capability:
-                out_stream.write('Capability: {0}'.format(out_stream.node(
+                out_stream.write('Capability: {0}'.format(out_stream.node_style(
                     self._model.target_capability.name)))
-            if self._model.type is not None:
+            if self._model.type_style is not None:
                 out_stream.write('Relationship type: {0}'.format(
-                    out_stream.type(self._model.type.name)))
+                    out_stream.type_style(self._model.type_style.name)))
             if (self._model.relationship_template is not None and
                     self._model.relationship_template.name):
                 out_stream.write('Relationship template: {0}'.format(
-                    out_stream.node(self._model.relationship_template.name)))
-            self._topology.dump(self._model.properties, out_stream, 'Properties')
-            self._topology.dump(self._model.interfaces, out_stream, 'Interfaces')
+                    out_stream.node_style(self._model.relationship_template.name)))
+            self._topology.dump(self._model.properties, out_stream, title='Properties')
+            self._topology.dump(self._model.interfaces, out_stream, title='Interfaces')
 
     def configure_operations(self):
         for interface in self._model.interfaces.values():
             self._topology.configure_operations(interface)
 
 
-class Service(common._OperatorHolderHandlerMixin):
+class Service(common.ActorHandlerBase):
     def coerce(self, **kwargs):
         self._coerce(self._model.meta_data,
                      self._model.nodes,
@@ -493,19 +504,20 @@ class Service(common._OperatorHolderHandlerMixin):
                        self._model.substitution,
                        self._model.inputs,
                        self._model.outputs,
-                       self._model.workflows)
+                       self._model.workflows,
+                       **kwargs)
 
     def dump(self, out_stream):
         if self._model.description is not None:
-            out_stream.write(out_stream.meta(self._model.description))
-        self._topology.dump(self._model.meta_data, out_stream, 'Metadata')
+            out_stream.write(out_stream.meta_style(self._model.description))
+        self._topology.dump(self._model.meta_data, out_stream, title='Metadata')
         self._topology.dump(self._model.nodes, out_stream)
         self._topology.dump(self._model.groups, out_stream)
         self._topology.dump(self._model.policies, out_stream)
         self._topology.dump(self._model.substitution, out_stream)
-        self._topology.dump(self._model.inputs, out_stream, 'Inputs')
-        self._topology.dump(self._model.outputs, out_stream, 'Outputs')
-        self._topology.dump(self._model.workflows, out_stream, 'Workflows')
+        self._topology.dump(self._model.inputs, out_stream, title='Inputs')
+        self._topology.dump(self._model.outputs, out_stream, title='Outputs')
+        self._topology.dump(self._model.workflows, out_stream, title='Workflows')
 
     def configure_operations(self):
         for node in self._model.nodes.itervalues():
@@ -527,78 +539,82 @@ class Service(common._OperatorHolderHandlerMixin):
                    for node in self._model.nodes.values())
 
 
-class Substitution(common._InstanceHandlerMixin):
+class Substitution(common.InstanceHandlerBase):
     def coerce(self, **kwargs):
         self._topology.coerce(self._model.mappings, **kwargs)
 
     def validate(self, **kwargs):
-        self._topology.validate(self._model.mappings)
+        self._topology.validate(self._model.mappings, **kwargs)
 
     def dump(self, out_stream):
         out_stream.write('Substitution:')
         with out_stream.indent():
-            out_stream.write('Node type: {0}'.format(out_stream.type(self._model.node_type.name)))
-            self._topology.dump(self._model.mappings, out_stream, 'Mappings')
+            out_stream.write('Node type: {0}'.format(out_stream.type_style(
+                self._model.node_type.name)))
+            self._topology.dump(self._model.mappings, out_stream, title='Mappings')
 
 
-class SubstitutionMapping(common._InstanceHandlerMixin):
+class SubstitutionMapping(common.InstanceHandlerBase):
 
-    def validate(self, **kwargs):
+    def coerce(self, **kwargs):
+        pass
+
+    def validate(self, **_):
         if (self._model.capability is None) and (self._model.requirement_template is None):
             self._topology.report(
                 'mapping "{0}" refers to neither capability nor a requirement'
                 ' in node: {1}'.format(
-                    self._model.name, formatting.safe_repr(self._model.node.name)),
+                    self._model.name, formatting.safe_repr(self._model.node_style.name)),
                 level=self._topology.Issue.BETWEEN_TYPES)
 
     def dump(self, out_stream):
         if self._model.capability is not None:
             out_stream.write('{0} -> {1}.{2}'.format(
-                out_stream.node(self._model.name),
-                out_stream.node(self._model.capability.node.name),
-                out_stream.node(self._model.capability.name)))
+                out_stream.node_style(self._model.name),
+                out_stream.node_style(self._model.capability.node_style.name),
+                out_stream.node_style(self._model.capability.name)))
         else:
             out_stream.write('{0} -> {1}.{2}'.format(
-                out_stream.node(self._model.name),
-                out_stream.node(self._model.node.name),
-                out_stream.node(self._model.requirement_template.name)))
+                out_stream.node_style(self._model.name),
+                out_stream.node_style(self._model.node_style.name),
+                out_stream.node_style(self._model.requirement_template.name)))
 
 
-class Metadata(common._InstanceHandlerMixin):
+class Metadata(common.InstanceHandlerBase):
 
     def dump(self, out_stream):
         out_stream.write('{0}: {1}'.format(
-            out_stream.property(self._topology.name),
-            out_stream.literal(self._topology.value)))
+            out_stream.property_style(self._model.name),
+            out_stream.literal_style(self._model.value)))
 
-    def coerce(self):
+    def coerce(self, **_):
         pass
 
-    def instantiate(self, instance_cls, **kwargs):
+    def instantiate(self, instance_cls):
         return instance_cls(name=self._model.name, value=self._model.value)
 
     def validate(self):
         pass
 
 
-class _Parameter(common._InstanceHandlerMixin):
+class _Parameter(common.InstanceHandlerBase):
 
     def dump(self, out_stream):
         if self._model.type_name is not None:
             out_stream.write('{0}: {1} ({2})'.format(
-                out_stream.property(self._model.name),
-                out_stream.literal(formatting.as_raw(self._model.value)),
-                out_stream.type(self._model.type_name)))
+                out_stream.property_style(self._model.name),
+                out_stream.literal_style(formatting.as_raw(self._model.value)),
+                out_stream.type_style(self._model.type_name)))
         else:
             out_stream.write('{0}: {1}'.format(
-                out_stream.property(self._model.name),
-                out_stream.literal(formatting.as_raw(self._model.value))))
+                out_stream.property_style(self._model.name),
+                out_stream.literal_style(formatting.as_raw(self._model.value))))
         if self._model.description:
-            out_stream.write(out_stream.meta(self._model.description))
+            out_stream.write(out_stream.meta_style(self._model.description))
 
     def instantiate(self, instance_cls, **kwargs):
         return instance_cls(
-            name=self._model.name,  # pylint: disable=unexpected-keyword-arg
+            name=self._model.name,                                                                  # pylint: disable=unexpected-keyword-arg
             type_name=self._model.type_name,
             _value=self._model._value,
             description=self._model.description
@@ -607,6 +623,14 @@ class _Parameter(common._InstanceHandlerMixin):
     def validate(self):
         pass
 
+    def coerce(self, report_issues):                                                                # pylint: disable=arguments-differ
+        value = self._model._value
+        if value is not None:
+            evaluation = functions.evaluate(value, self._model, report_issues)
+            if (evaluation is not None) and evaluation.final:
+                # A final evaluation can safely replace the existing value
+                self._model._value = evaluation.value
+
 
 class Attribute(_Parameter):
     pass
@@ -632,13 +656,16 @@ class Configuration(_Parameter):
     pass
 
 
-class Type(common._InstanceHandlerMixin):
-    def coerce(self):
+class Type(common.InstanceHandlerBase):
+    def coerce(self, **_):
         pass
 
     def dump(self, out_stream):
         if self._model.name:
-            out_stream.write(out_stream.type(self._model.name))
+            out_stream.write(out_stream.type_style(self._model.name))
         with out_stream.indent():
             for child in self._model.children:
                 self._topology.dump(child, out_stream)
+
+    def validate(self, **kwargs):
+        pass

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/orchestrator/topology/template_handler.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/template_handler.py b/aria/orchestrator/topology/template_handler.py
index d355e6d..274abae 100644
--- a/aria/orchestrator/topology/template_handler.py
+++ b/aria/orchestrator/topology/template_handler.py
@@ -15,23 +15,26 @@
 
 from datetime import datetime
 
-from ...utils import formatting
+from ...utils import (
+    formatting,
+    versions
+)
 from ...modeling import utils as modeling_utils
 from . import utils, common
 
 
-class ServiceTemplate(common._TemplateHandlerMixin):
+class ServiceTemplate(common.TemplateHandlerBase):
     def dump(self, out_stream):
         if self._model.description is not None:
-            out_stream.write(out_stream.meta(self._model.description))
-        self._topology.dump(self._model.meta_data, out_stream, 'Metadata')
+            out_stream.write(out_stream.meta_style(self._model.description))
+        self._topology.dump(self._model.meta_data, out_stream, title='Metadata')
         self._topology.dump(self._model.node_templates, out_stream)
         self._topology.dump(self._model.group_templates, out_stream)
         self._topology.dump(self._model.policy_templates, out_stream)
         self._topology.dump(self._model.substitution_template, out_stream)
-        self._topology.dump(self._model.inputs, out_stream, 'Inputs')
-        self._topology.dump(self._model.outputs, out_stream, 'Outputs')
-        self._topology.dump(self._model.workflow_templates, out_stream, 'Workflow templates')
+        self._topology.dump(self._model.inputs, out_stream, title='Inputs')
+        self._topology.dump(self._model.outputs, out_stream, title='Outputs')
+        self._topology.dump(self._model.workflow_templates, out_stream, title='Workflow templates')
 
     def coerce(self, **kwargs):
         self._coerce(self._model.meta_data,
@@ -44,7 +47,7 @@ class ServiceTemplate(common._TemplateHandlerMixin):
                      self._model.workflow_templates,
                      **kwargs)
 
-    def instantiate(self, instance_cls, inputs=None):                                               # pylint: disable=arguments-differ
+    def instantiate(self, instance_cls, inputs=None, model_storage=None):                           # pylint: disable=arguments-differ
         now = datetime.now()
 
         modeling_utils.validate_no_undeclared_inputs(
@@ -61,9 +64,9 @@ class ServiceTemplate(common._TemplateHandlerMixin):
         )
 
         for plugin_specification in self._model.plugin_specifications.itervalues():
-            if plugin_specification.enabled and self._topology._model_storage:
-                if utils.resolve_plugin_specification(plugin_specification,
-                                                      self._topology.model_storage.plugin.list()):
+            if plugin_specification.enabled and model_storage:
+                if self._resolve_plugin_specification(plugin_specification,
+                                                      model_storage.plugin.list()):
                     plugin = plugin_specification.plugin
                     service.plugins[plugin.name] = plugin
                 else:
@@ -84,45 +87,36 @@ class ServiceTemplate(common._TemplateHandlerMixin):
 
         return service
 
+    @staticmethod
+    def _resolve_plugin_specification(plugin_specification, plugins):
+        matching_plugins = []
+        if plugins:
+            for plugin in plugins:
+                if (plugin.name == plugin_specification.name and
+                        (plugin_specification.version is None or
+                         versions.VersionString(plugin.package_version) >=
+                         plugin_specification.version)
+                   ):
+                    matching_plugins.append(plugin)
+        plugin_specification.plugin = None
+        if matching_plugins:
+            # Return highest version of plugin
+            plugin_specification.plugin = \
+                max(matching_plugins,
+                    key=lambda plugin: versions.VersionString(plugin.package_version).key)
+        return plugin_specification.plugin is not None
+
     def _scaling(self, node_template):
-        scaling = {}
-
-        def extract_property(properties, name):
-            if name in scaling:
-                return
-            prop = properties.get(name)
-            if (prop is not None) and (prop.type_name == 'integer') and (prop.value is not None):
-                scaling[name] = prop.value
-
-        def extract_properties(properties):
-            extract_property(properties, 'min_instances')
-            extract_property(properties, 'max_instances')
-            extract_property(properties, 'default_instances')
-
-        # From our scaling capabilities
-        for capability_template in node_template.capability_templates.itervalues():
-            if capability_template.type.role == 'scaling':
-                extract_properties(capability_template.properties)
-
-        # From service scaling policies
-        for policy_template in node_template.service_template.policy_templates.itervalues():
-            if policy_template.type.role == 'scaling':
-                if policy_template.is_for_node_template(node_template.name):
-                    extract_properties(policy_template.properties)
-
-        # Defaults
-        scaling.setdefault('min_instances', 0)
-        scaling.setdefault('max_instances', 1)
-        scaling.setdefault('default_instances', 1)
-
-        # Validate
-        # pylint: disable=too-many-boolean-expressions
-        if (scaling['min_instances'] < 0 or
-                scaling['max_instances'] < 0 or
-                scaling['default_instances'] < 0 or
-                scaling['max_instances'] < scaling['min_instances'] or
-                scaling['default_instances'] < scaling['min_instances'] or
-                scaling['default_instances'] > scaling['max_instances']):
+        scaling = node_template.scaling
+
+        if any([scaling['min_instances'] < 0,
+                scaling['max_instances'] < scaling['min_instances'],
+                scaling['max_instances'] < 0,
+
+                scaling['default_instances'] < 0,
+                scaling['default_instances'] < scaling['min_instances'],
+                scaling['default_instances'] > scaling['max_instances']
+               ]):
             self._topology.report(
                 'invalid scaling parameters for node template "{0}": min={min_instances}, max='
                 '{max_instances}, default={default_instances}'.format(self._model.name, **scaling),
@@ -130,47 +124,52 @@ class ServiceTemplate(common._TemplateHandlerMixin):
 
         return scaling
 
-    def validate(self):
-        self._topology.validate(self._model.meta_data)
-        self._topology.validate(self._model.node_templates)
-        self._topology.validate(self._model.group_templates)
-        self._topology.validate(self._model.policy_templates)
-        self._topology.validate(self._model.substitution_template)
-        self._topology.validate(self._model.inputs)
-        self._topology.validate(self._model.outputs)
-        self._topology.validate(self._model.workflow_templates)
-        self._topology.validate(self._model.node_types)
-        self._topology.validate(self._model.group_types)
-        self._topology.validate(self._model.policy_types)
-        self._topology.validate(self._model.relationship_types)
-        self._topology.validate(self._model.capability_types)
-        self._topology.validate(self._model.interface_types)
-        self._topology.validate(self._model.artifact_types)
-
-
-class ArtifactTemplate(common._TemplateHandlerMixin):
+    def validate(self, **kwargs):
+        self._validate(
+            self._model.meta_data,
+            self._model.node_templates,
+            self._model.group_templates,
+            self._model.policy_templates,
+            self._model.substitution_template,
+            self._model.inputs,
+            self._model.outputs,
+            self._model.workflow_templates,
+            self._model.node_types,
+            self._model.group_types,
+            self._model.policy_types,
+            self._model.relationship_types,
+            self._model.capability_types,
+            self._model.interface_types,
+            self._model.artifact_types,
+            **kwargs
+        )
+
+
+class ArtifactTemplate(common.TemplateHandlerBase):
     def dump(self, out_stream):
-        out_stream.write(out_stream.node(self._model.name))
+        out_stream.write(out_stream.node_style(self._model.name))
         if self._model.description:
-            out_stream.write(out_stream.meta(self._model.description))
+            out_stream.write(out_stream.meta_style(self._model.description))
         with out_stream.indent():
-            out_stream.write('Artifact type: {0}'.format(out_stream.type(self._model.type.name)))
-            out_stream.write('Source path: {0}'.format(out_stream.literal(self._model.source_path)))
+            out_stream.write('Artifact type: {0}'.format(out_stream.type_style(
+                self._model.type_style.name)))
+            out_stream.write('Source path: {0}'.format(out_stream.literal_style(
+                self._model.source_path)))
             if self._model.target_path is not None:
-                out_stream.write('Target path: {0}'.format(out_stream.literal(
+                out_stream.write('Target path: {0}'.format(out_stream.literal_style(
                     self._model.target_path)))
             if self._model.repository_url is not None:
                 out_stream.write('Repository URL: {0}'.format(
-                    out_stream.literal(self._model.repository_url)))
+                    out_stream.literal_style(self._model.repository_url)))
             if self._model.repository_credential:
                 out_stream.write('Repository credential: {0}'.format(
-                    out_stream.literal(self._model.repository_credential)))
-            self._topology.dump(self._model.properties, out_stream, 'Properties')
+                    out_stream.literal_style(self._model.repository_credential)))
+            self._topology.dump(self._model.properties, out_stream, title='Properties')
 
     def coerce(self, **kwargs):
         self._topology.coerce(self._model.properties, **kwargs)
 
-    def instantiate(self, instance_cls):
+    def instantiate(self, instance_cls, **_):
         return instance_cls(
             name=self._model.name,
             type=self._model.type,
@@ -181,17 +180,17 @@ class ArtifactTemplate(common._TemplateHandlerMixin):
             repository_credential=self._model.repository_credential,
             artifact_template=self._model)
 
-    def validate(self):
-        self._topology.validate(self._model.properties)
+    def validate(self, **kwargs):
+        self._topology.validate(self._model.properties, **kwargs)
 
 
-class CapabilityTemplate(common._TemplateHandlerMixin):
+class CapabilityTemplate(common.TemplateHandlerBase):
     def dump(self, out_stream):
-        out_stream.write(out_stream.node(self._model.name))
+        out_stream.write(out_stream.node_style(self._model.name))
         if self._model.description:
-            out_stream.write(out_stream.meta(self._model.description))
+            out_stream.write(out_stream.meta_style(self._model.description))
         with out_stream.indent():
-            out_stream.write('Type: {0}'.format(out_stream.type(self._model.type.name)))
+            out_stream.write('Type: {0}'.format(out_stream.type_style(self._model.type_style.name)))
             out_stream.write(
                 'Occurrences: {0:d}{1}'.format(
                     self._model.min_occurrences or 0,
@@ -200,14 +199,14 @@ class CapabilityTemplate(common._TemplateHandlerMixin):
                     else ' or more'))
             if self._model.valid_source_node_types:
                 out_stream.write('Valid source node types: {0}'.format(
-                    ', '.join((str(out_stream.type(v.name))
+                    ', '.join((str(out_stream.type_style(v.name))
                                for v in self._model.valid_source_node_types))))
-            self._topology.dump(self._model.properties, out_stream, 'Properties')
+            self._topology.dump(self._model.properties, out_stream, title='Properties')
 
-    def coerce(self):
-        self._topology.coerce(self._model.properties)
+    def coerce(self, **kwargs):
+        self._topology.coerce(self._model.properties, **kwargs)
 
-    def instantiate(self, instance_cls):
+    def instantiate(self, instance_cls, **_):
         return instance_cls(name=self._model.name,
                             type=self._model.type,
                             min_occurrences=self._model.min_occurrences,
@@ -215,34 +214,34 @@ class CapabilityTemplate(common._TemplateHandlerMixin):
                             occurrences=0,
                             capability_template=self._model)
 
-    def validate(self):
-        self._topology.validate(self._model.properties)
+    def validate(self, **kwargs):
+        self._topology.validate(self._model.properties, **kwargs)
 
 
-class RequirementTemplate(common._TemplateHandlerMixin):
+class RequirementTemplate(common.TemplateHandlerBase):
     def dump(self, out_stream):
         if self._model.name:
-            out_stream.write(out_stream.node(self._model.name))
+            out_stream.write(out_stream.node_style(self._model.name))
         else:
             out_stream.write('Requirement:')
         with out_stream.indent():
             if self._model.target_node_type is not None:
                 out_stream.write('Target node type: {0}'.format(
-                    out_stream.type(self._model.target_node_type.name)))
+                    out_stream.type_style(self._model.target_node_type.name)))
             elif self._model.target_node_template is not None:
                 out_stream.write('Target node template: {0}'.format(
-                    out_stream.node(self._model.target_node_template.name)))
+                    out_stream.node_style(self._model.target_node_template.name)))
             if self._model.target_capability_type is not None:
                 out_stream.write('Target capability type: {0}'.format(
-                    out_stream.type(self._model.target_capability_type.name)))
+                    out_stream.type_style(self._model.target_capability_type.name)))
             elif self._model.target_capability_name is not None:
                 out_stream.write('Target capability name: {0}'.format(
-                    out_stream.node(self._model.target_capability_name)))
+                    out_stream.node_style(self._model.target_capability_name)))
             if self._model.target_node_template_constraints:
                 out_stream.write('Target node template constraints:')
                 with out_stream.indent():
                     for constraint in self._model.target_node_template_constraints:
-                        out_stream.write(out_stream.literal(constraint))
+                        out_stream.write(out_stream.literal_style(constraint))
             if self._model.relationship_template:
                 out_stream.write('Relationship:')
                 with out_stream.indent():
@@ -251,37 +250,33 @@ class RequirementTemplate(common._TemplateHandlerMixin):
     def coerce(self, **kwargs):
         self._topology.coerce(self._model.relationship_template, **kwargs)
 
-    def instantiate(self, instance_cls):
-        return instance_cls(name=self._model.name,
-                            type=self._model.type,
-                            min_occurrences=self._model.min_occurrences,
-                            max_occurrences=self._model.max_occurrences,
-                            occurrences=0,
-                            capability_template=self._model)
+    def instantiate(self, instance_cls, **_):
+        pass
 
-    def validate(self):
-        self._topology.validate(self._model.relationship_template)
+    def validate(self, **kwargs):
+        self._topology.validate(self._model.relationship_template, **kwargs)
 
 
-class GroupTemplate(common._TemplateHandlerMixin):
+class GroupTemplate(common.TemplateHandlerBase):
     def dump(self, out_stream):
-        out_stream.write('Group template: {0}'.format(out_stream.node(self._model.name)))
+        out_stream.write('Group template: {0}'.format(out_stream.node_style(self._model.name)))
         if self._model.description:
-            out_stream.write(out_stream.meta(self._model.description))
+            out_stream.write(out_stream.meta_style(self._model.description))
         with out_stream.indent():
-            out_stream.write('Type: {0}'.format(out_stream.type(self._model.type.name)))
-            self._topology.dump(self._model.properties, out_stream, 'Properties')
-            self._topology.dump(self._model.interface_templates, out_stream, 'Interface Templates')
+            out_stream.write('Type: {0}'.format(out_stream.type_style(self._model.type_style.name)))
+            self._topology.dump(self._model.properties, out_stream, title='Properties')
+            self._topology.dump(self._model.interface_templates, out_stream,
+                                title='Interface Templates')
             if self._model.node_templates:
                 out_stream.write('Member node templates: {0}'.format(', '.join(
-                    (str(out_stream.node(v.name)) for v in self._model.node_templates))))
+                    (str(out_stream.node_style(v.name)) for v in self._model.node_templates))))
 
     def coerce(self, **kwargs):
         self._coerce(self._model.properties,
                      self._model.interface_templates,
                      **kwargs)
 
-    def instantiate(self, instance_cls):
+    def instantiate(self, instance_cls, **_):
         group = instance_cls(
             name=self._model.name,
             type=self._model.type,
@@ -294,27 +289,30 @@ class GroupTemplate(common._TemplateHandlerMixin):
                 group.nodes += node_template.nodes
         return group
 
-    def validate(self):
+    def validate(self, **kwargs):
         self._validate(self._model.properties,
-                       self._model.interface_templates)
+                       self._model.interface_templates,
+                       **kwargs)
 
 
-class InterfaceTemplate(common._TemplateHandlerMixin):
+class InterfaceTemplate(common.TemplateHandlerBase):
     def dump(self, out_stream):
-        out_stream.write(out_stream.node(self._model.name))
+        out_stream.write(out_stream.node_style(self._model.name))
         if self._model.description:
-            out_stream.write(out_stream.meta(self._model.description))
+            out_stream.write(out_stream.meta_style(self._model.description))
         with out_stream.indent():
-            out_stream.write('Interface type: {0}'.format(out_stream.type(self._model.type.name)))
-            self._topology.dump(self._model.inputs, out_stream, 'Inputs')
-            self._topology.dump(self._model.operation_templates, out_stream, 'Operation templates')
+            out_stream.write('Interface type: {0}'.format(out_stream.type_style(
+                self._model.type_style.name)))
+            self._topology.dump(self._model.inputs, out_stream, title='Inputs')
+            self._topology.dump(self._model.operation_templates, out_stream,
+                                title='Operation templates')
 
     def coerce(self, **kwargs):
         self._coerce(self._model.inputs,
                      self._model.operation_templates,
                      **kwargs)
 
-    def instantiate(self, instance_cls):
+    def instantiate(self, instance_cls, **_):
         interface = instance_cls(
             name=self._model.name,
             type=self._model.type,
@@ -324,28 +322,29 @@ class InterfaceTemplate(common._TemplateHandlerMixin):
         interface.operations = self._topology.instantiate(self._model.operation_templates)
         return interface
 
-    def validate(self):
+    def validate(self, **kwargs):
         self._validate(self._model.inputs,
-                       self._model.operation_templates)
+                       self._model.operation_templates,
+                       **kwargs)
 
 
-class NodeTemplate(common._TemplateHandlerMixin):
+class NodeTemplate(common.TemplateHandlerBase):
     def dump(self, out_stream):
-        out_stream.write('Node template: {0}'.format(out_stream.node(self._model.name)))
+        out_stream.write('Node template: {0}'.format(out_stream.node_style(self._model.name)))
         with out_stream.indent():
             if self._model.description:
-                out_stream.write(out_stream.meta(self._model.description))
-            out_stream.write('Type: {0}'.format(out_stream.type(self._model.type.name)))
-            self._topology.dump(self._model.properties, out_stream, 'Properties')
-            self._topology.dump(self._model.attributes, out_stream, 'Attributes')
+                out_stream.write(out_stream.meta_style(self._model.description))
+            out_stream.write('Type: {0}'.format(out_stream.type_style(self._model.type_style.name)))
+            self._topology.dump(self._model.properties, out_stream, title='Properties')
+            self._topology.dump(self._model.attributes, out_stream, title='Attributes')
             self._topology.dump(
-                self._model.interface_templates, out_stream, 'Interface Templates')
+                self._model.interface_templates, out_stream, title='Interface Templates')
             self._topology.dump(
-                self._model.artifact_templates, out_stream, 'Artifact Templates')
+                self._model.artifact_templates, out_stream, title='Artifact Templates')
             self._topology.dump(
-                self._model.capability_templates, out_stream, 'Capability Templates')
+                self._model.capability_templates, out_stream, title='Capability Templates')
             self._topology.dump(
-                self._model.requirement_templates, out_stream, 'Requirement Templates')
+                self._model.requirement_templates, out_stream, title='Requirement Templates')
 
     def coerce(self, **kwargs):
         self._coerce(self._model.properties,
@@ -356,7 +355,7 @@ class NodeTemplate(common._TemplateHandlerMixin):
                      self._model.requirement_templates,
                      **kwargs)
 
-    def instantiate(self, instance_cls):
+    def instantiate(self, instance_cls, **_):
         node = instance_cls(
             name=self._model._next_name,
             type=self._model.type,
@@ -378,34 +377,35 @@ class NodeTemplate(common._TemplateHandlerMixin):
 
         return node
 
-    def validate(self):
+    def validate(self, **kwargs):
         self._validate(self._model.properties,
                        self._model.attributes,
                        self._model.interface_templates,
                        self._model.artifact_templates,
                        self._model.capability_templates,
-                       self._model.requirement_templates)
+                       self._model.requirement_templates,
+                       **kwargs)
 
 
-class PolicyTemplate(common._TemplateHandlerMixin):
+class PolicyTemplate(common.TemplateHandlerBase):
     def dump(self, out_stream):
-        out_stream.write('Policy template: {0}'.format(out_stream.node(self._model.name)))
+        out_stream.write('Policy template: {0}'.format(out_stream.node_style(self._model.name)))
         if self._model.description:
-            out_stream.write(out_stream.meta(self._model.description))
+            out_stream.write(out_stream.meta_style(self._model.description))
         with out_stream.indent():
-            out_stream.write('Type: {0}'.format(out_stream.type(self._model.type.name)))
-            self._topology.dump(self._model.properties, out_stream, 'Properties')
+            out_stream.write('Type: {0}'.format(out_stream.type_style(self._model.type_style.name)))
+            self._topology.dump(self._model.properties, out_stream, title='Properties')
             if self._model.node_templates:
                 out_stream.write('Target node templates: {0}'.format(', '.join(
-                    (str(out_stream.node(v.name)) for v in self._model.node_templates))))
+                    (str(out_stream.node_style(v.name)) for v in self._model.node_templates))))
             if self._model.group_templates:
                 out_stream.write('Target group templates: {0}'.format(', '.join(
-                    (str(out_stream.node(v.name)) for v in self._model.group_templates))))
+                    (str(out_stream.node_style(v.name)) for v in self._model.group_templates))))
 
     def coerce(self, **kwargs):
         self._topology.coerce(self._model.properties, **kwargs)
 
-    def instantiate(self, instance_cls):
+    def instantiate(self, instance_cls, **_):
         policy = instance_cls(
             name=self._model.name,
             type=self._model.type,
@@ -421,47 +421,48 @@ class PolicyTemplate(common._TemplateHandlerMixin):
                 policy.groups += group_template.groups
         return policy
 
-    def validate(self):
-        self._topology.validate(self._model.properties)
+    def validate(self, **kwargs):
+        self._topology.validate(self._model.properties, **kwargs)
 
 
-class SubstitutionTemplate(common._TemplateHandlerMixin):
+class SubstitutionTemplate(common.TemplateHandlerBase):
 
     def dump(self, out_stream):
         out_stream.write('Substitution template:')
         with out_stream.indent():
-            out_stream.write('Node type: {0}'.format(out_stream.type(self._model.node_type.name)))
-            self._topology.dump(self._model.mappings, out_stream, 'Mappings')
+            out_stream.write('Node type: {0}'.format(out_stream.type_style(
+                self._model.node_type.name)))
+            self._topology.dump(self._model.mappings, out_stream, title='Mappings')
 
     def coerce(self, **kwargs):
         self._topology.coerce(self._model.mappings, **kwargs)
 
-    def instantiate(self, instance_cls):
+    def instantiate(self, instance_cls, **_):
         return instance_cls(node_type=self._model.node_type,
                             substitution_template=self._model)
 
-    def validate(self):
-        self._topology.validate(self._model.mappings)
+    def validate(self, **kwargs):
+        self._topology.validate(self._model.mappings, **kwargs)
 
 
-class SubstitutionTemplateMapping(common._TemplateHandlerMixin):
+class SubstitutionTemplateMapping(common.TemplateHandlerBase):
 
     def dump(self, out_stream):
         if self._topology.capability_template is not None:
-            node_template = self._topology.capability_template.node_template
+            node_template = self._model.capability_template.node_template
         else:
-            node_template = self._topology.requirement_template.node_template
+            node_template = self._model.requirement_template.node_template
         out_stream.write('{0} -> {1}.{2}'.format(
-            out_stream.node(self._topology.name),
-            out_stream.node(node_template.name),
-            out_stream.node(self._topology.capability_template.name
-                            if self._topology.capability_template
-                            else self._topology.requirement_template.name)))
+            out_stream.node_style(self._model.name),
+            out_stream.node_style(node_template.name),
+            out_stream.node_style(self._model.capability_template.name
+                                  if self._model.capability_template
+                                  else self._model.requirement_template.name)))
 
-    def coerce(self):
+    def coerce(self, **_):
         pass
 
-    def instantiate(self, instance_cls):
+    def instantiate(self, instance_cls, **_):
         substitution_mapping = instance_cls(
             name=self._model.name,
             requirement_template=self._model.requirement_template)
@@ -479,16 +480,16 @@ class SubstitutionTemplateMapping(common._TemplateHandlerMixin):
             return None
         # The TOSCA spec does not provide a way to choose the node,
         # so we will just pick the first one
-        substitution_mapping.node = nodes[0]
+        substitution_mapping.node_style = nodes[0]
         if self._model.capability_template:
-            for a_capability in substitution_mapping.node.capabilities.itervalues():
+            for a_capability in substitution_mapping.node_style.capabilities.itervalues():
                 if a_capability.capability_template.name == \
                         self._model.capability_template.name:
                     substitution_mapping.capability = a_capability
 
         return substitution_mapping
 
-    def validate(self):
+    def validate(self, **_):
         if self._model.capability_template is None and self._model.requirement_template is None:
             self._topology.report(
                 'mapping "{0}" refers to neither capability nor a requirement '
@@ -497,24 +498,25 @@ class SubstitutionTemplateMapping(common._TemplateHandlerMixin):
                 level=self._topology.Issue.BETWEEN_TYPES)
 
 
-class RelationshipTemplate(common._TemplateHandlerMixin):
+class RelationshipTemplate(common.TemplateHandlerBase):
     def dump(self, out_stream):
-        if self._model.type is not None:
-            out_stream.write('Relationship type: {0}'.format(out_stream.type(
-                self._model.type.name)))
+        if self._model.type_style is not None:
+            out_stream.write('Relationship type: {0}'.format(out_stream.type_style(
+                self._model.type_style.name)))
         else:
             out_stream.write('Relationship template: {0}'.format(
-                out_stream.node(self._model.name)))
+                out_stream.node_style(self._model.name)))
         if self._model.description:
-            out_stream.write(out_stream.meta(self._model.description))
+            out_stream.write(out_stream.meta_style(self._model.description))
         with out_stream.indent():
-            self._topology.dump(self._model.properties, out_stream, 'Properties')
-            self._topology.dump(self._model.interface_templates, out_stream, 'Interface Templates')
+            self._topology.dump(self._model.properties, out_stream, title='Properties')
+            self._topology.dump(self._model.interface_templates, out_stream,
+                                title='Interface Templates')
 
     def coerce(self, **kwargs):
         self._coerce(self._model.properties, self._model.interface_templates, **kwargs)
 
-    def instantiate(self, instance_cls):
+    def instantiate(self, instance_cls, **_):
         relationship = instance_cls(
             name=self._model.name,
             type=self._model.type,
@@ -524,45 +526,47 @@ class RelationshipTemplate(common._TemplateHandlerMixin):
         relationship.interfaces = self._topology.instantiate(self._model.interface_templates)
         return relationship
 
-    def validate(self):
-        self._validate(self._model.properties, self._model.interface_templates)
+    def validate(self, **kwargs):
+        self._validate(self._model.properties, self._model.interface_templates, **kwargs)
 
 
-class OperationTemplate(common._TemplateHandlerMixin):
+class OperationTemplate(common.TemplateHandlerBase):
 
     def dump(self, out_stream):
-        out_stream.write(out_stream.node(self._model.name))
+        out_stream.write(out_stream.node_style(self._model.name))
         if self._model.description:
-            out_stream.write(out_stream.meta(self._model.description))
+            out_stream.write(out_stream.meta_style(self._model.description))
         with out_stream.indent():
             if self._model.implementation is not None:
                 out_stream.write('Implementation: {0}'.format(
-                    out_stream.literal(self._model.implementation)))
+                    out_stream.literal_style(self._model.implementation)))
             if self._model.dependencies:
-                out_stream.write('Dependencies: {0}'.format(
-                    ', '.join((str(out_stream.literal(v)) for v in self._model.dependencies))))
-            self._topology.dump(self._model.inputs, out_stream, 'Inputs')
+                out_stream.write('Dependencies: {0}'.format(', '.join(
+                    (str(out_stream.literal_style(v)) for v in self._model.dependencies))))
+            self._topology.dump(self._model.inputs, out_stream, title='Inputs')
             if self._model.executor is not None:
-                out_stream.write('Executor: {0}'.format(out_stream.literal(self._model.executor)))
+                out_stream.write('Executor: {0}'.format(
+                    out_stream.literal_style(self._model.executor)))
             if self._model.max_attempts is not None:
-                out_stream.write('Max attempts: {0}'.format(out_stream.literal(
+                out_stream.write('Max attempts: {0}'.format(out_stream.literal_style(
                     self._model.max_attempts)))
             if self._model.retry_interval is not None:
                 out_stream.write('Retry interval: {0}'.format(
-                    out_stream.literal(self._model.retry_interval)))
+                    out_stream.literal_style(self._model.retry_interval)))
             if self._model.plugin_specification is not None:
                 out_stream.write('Plugin specification: {0}'.format(
-                    out_stream.literal(self._model.plugin_specification.name)))
-            self._topology.dump(self._model.configurations, out_stream, 'Configuration')
+                    out_stream.literal_style(self._model.plugin_specification.name)))
+            self._topology.dump(self._model.configurations, out_stream, title='Configuration')
             if self._model.function is not None:
-                out_stream.write('Function: {0}'.format(out_stream.literal(self._model.function)))
+                out_stream.write('Function: {0}'.format(out_stream.literal_style(
+                    self._model.function)))
 
     def coerce(self, **kwargs):
         self._coerce(self._model.inputs,
                      self._model.configurations,
                      **kwargs)
 
-    def instantiate(self, instance_cls):
+    def instantiate(self, instance_cls, **_):
         operation = instance_cls(
             name=self._model.name,
             description=utils.deepcopy_with_locators(self._model.description),
@@ -584,13 +588,20 @@ class OperationTemplate(common._TemplateHandlerMixin):
 
         return operation
 
-    def validate(self):
+    def validate(self, **kwargs):
         self._validate(self._model.inputs,
-                       self._model.configurations)
+                       self._model.configurations,
+                       **kwargs)
 
 
-class PluginSpecification(common._TemplateHandlerMixin):
-    def instantiate(self, **kwargs):
+class PluginSpecification(common.TemplateHandlerBase):
+    def validate(self, **kwargs):
+        pass
+
+    def coerce(self, **kwargs):
+        pass
+
+    def instantiate(self, **_):
         pass
 
     def dump(self, out_stream):

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/orchestrator/topology/topology.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/topology.py b/aria/orchestrator/topology/topology.py
index 6164a10..b2b689d 100644
--- a/aria/orchestrator/topology/topology.py
+++ b/aria/orchestrator/topology/topology.py
@@ -23,7 +23,7 @@ from . import (
 )
 
 
-class Topology(issue.Reporter):
+class Topology(issue.ReporterMixin):
 
     _init_map = {
         models.ServiceTemplate: models.Service,
@@ -36,7 +36,6 @@ class Topology(issue.Reporter):
         models.SubstitutionTemplate: models.Substitution,
         models.RelationshipTemplate: models.Relationship,
         models.OperationTemplate: models.Operation,
-        models.RequirementTemplate: None,
         models.SubstitutionTemplateMapping: models.SubstitutionMapping,
 
         # Common
@@ -50,28 +49,33 @@ class Topology(issue.Reporter):
         models.Type: models.Type
     }
 
-    def __init__(self, model_storage=None, *args, **kwargs):
-        # TODO: model storage is required only for the list of plugins, can we get it
-        # somewhere else?
+    def __init__(self, *args, **kwargs):
         super(Topology, self).__init__(*args, **kwargs)
-        self._model_storage = model_storage
-        self._handlers = dict(self._init_handlers(instance_handler),
-                              **self._init_handlers(template_handler))
+        self._models_to_handlers = dict(self._init_handlers(instance_handler),
+                                        **self._init_handlers(template_handler))
 
     @staticmethod
     def _init_handlers(module_):
+        """
+        Register handlers from a module to the models
+
+        :param module_: The module to look for handlers
+        :return: a dict where key is the models class, and the value is the handler class
+        associated with it from the provided modukle
+        """
         handlers = {}
         for attribute_name in dir(module_):
             if attribute_name.startswith('_'):
                 continue
             attribute = getattr(module_, attribute_name)
-            if isinstance(attribute, type) and issubclass(attribute, common._Handler):
+            if isinstance(attribute, type) and issubclass(attribute, common.HandlerBase):
                 handlers[getattr(models, attribute_name)] = attribute
         return handlers
 
     def instantiate(self, model, **kwargs):
         """
-        all handlers used by instantiate should hold a tuple as value (handler, instnace_cls)
+        instantiate the provided model
+
         :param model:
         :param kwargs:
         :return:
@@ -82,25 +86,25 @@ class Topology(issue.Reporter):
         elif isinstance(model, list):
             return list(self.instantiate(value, **kwargs) for value in model)
         elif model is not None:
-            _handler = self._handlers.get(model.__class__)
-            instance_cls = self._init_map.get(model.__class__)
-            return _handler(self, model).instantiate(instance_cls, **kwargs)
+            _handler = self._models_to_handlers[model.__class__]
+            model_instance_cls = self._init_map[model.__class__]
+            return _handler(self, model).instantiate(model_instance_cls, **kwargs)
 
     def validate(self, model, **kwargs):
         if isinstance(model, dict):
-            return self.validate(model.values())
+            return self.validate(model.values(), **kwargs)
         elif isinstance(model, list):
-            return all(self.validate(value) for value in model)
+            return all(self.validate(value, **kwargs) for value in model)
         elif model is not None:
-            _handler = self._handlers.get(model.__class__)
+            _handler = self._models_to_handlers[model.__class__]
             return _handler(self, model).validate(**kwargs)
 
-    def dump(self, model, out_stream=None, section_name=None, **kwargs):
+    def dump(self, model, out_stream=None, title=None, **kwargs):
         out_stream = out_stream or console.TopologyStylizer()
 
         # if model is empty, no need to print out the section name
-        if model and section_name:
-            out_stream.write('{0}:'.format(section_name))
+        if model and title:
+            out_stream.write('{0}:'.format(title))
 
         if isinstance(model, dict):
             if str(out_stream):
@@ -114,12 +118,12 @@ class Topology(issue.Reporter):
                 self.dump(value, out_stream=out_stream, **kwargs)
 
         elif model is not None:
-            _handler = self._handlers.get(model.__class__)
+            _handler = self._models_to_handlers[model.__class__]
             _handler(self, model).dump(out_stream=out_stream, **kwargs)
 
         return out_stream
 
-    def dump_graph(self, service, **kwargs):
+    def dump_graph(self, service):
         out_stream = console.TopologyStylizer()
         for node in service.nodes.itervalues():
             if not node.inbound_relationships:
@@ -127,19 +131,20 @@ class Topology(issue.Reporter):
         return out_stream
 
     def _dump_graph_node(self, out_stream, node, capability=None):
-        out_stream.write(out_stream.node(node.name))
+        out_stream.write(out_stream.node_style(node.name))
         if capability is not None:
-            out_stream.write('{0} ({1})'.format(out_stream.property(capability.name),
-                                                out_stream.type(capability.type.name)))
+            out_stream.write('{0} ({1})'.format(out_stream.property_style(capability.name),
+                                                out_stream.type_style(capability.type_style.name)))
         if node.outbound_relationships:
             with out_stream.indent():
                 for relationship_model in node.outbound_relationships:
-                    relationship_name = out_stream.property(relationship_model.name)
-                    if relationship_model.type is not None:
+                    styled_relationship_name = out_stream.property_style(relationship_model.name)
+                    if relationship_model.type_style is not None:
                         out_stream.write('-> {0} ({1})'.format(
-                            relationship_name, out_stream.type(relationship_model.type.name)))
+                            styled_relationship_name,
+                            out_stream.type_style(relationship_model.type_style.name)))
                     else:
-                        out_stream.write('-> {0}'.format(relationship_name))
+                        out_stream.write('-> {0}'.format(styled_relationship_name))
                     with out_stream.indent(3):
                         self._dump_graph_node(out_stream,
                                               relationship_model.target_node,
@@ -147,11 +152,11 @@ class Topology(issue.Reporter):
 
     def coerce(self, model, **kwargs):
         if isinstance(model, dict):
-            return self.validate(model.values())
+            return self.coerce(model.values(), **kwargs)
         elif isinstance(model, list):
-            return all(self.validate(value) for value in model)
+            return all(self.coerce(value, **kwargs) for value in model)
         elif model is not None:
-            _handler = self._handlers.get(model.__class__)
+            _handler = self._models_to_handlers[model.__class__]
             return _handler(self, model).coerce(**kwargs)
 
     def dump_types(self, service_template, out_stream=None):
@@ -164,54 +169,55 @@ class Topology(issue.Reporter):
         self.dump(service_template.artifact_types, out_stream, 'Artifact types')
         self.dump(service_template.interface_types, out_stream, 'Interface types')
 
-        return str(out_stream)
+        return out_stream
 
     def satisfy_requirements(self, model, **kwargs):
         if isinstance(model, dict):
-            return self.satisfy_requirements(model.values())
+            return self.satisfy_requirements(model.values(), **kwargs)
         elif isinstance(model, list):
-            return all(self.satisfy_requirements(value) for value in model)
+            return all(self.satisfy_requirements(value, **kwargs) for value in model)
         elif model is not None:
-            _handler = self._handlers.get(model.__class__)
+            _handler = self._models_to_handlers[model.__class__]
             return _handler(self, model).satisfy_requirements(**kwargs)
 
     def validate_capabilities(self, model, **kwargs):
         if isinstance(model, dict):
-            return self.validate_capabilities(model.values())
+            return self.validate_capabilities(model.values(), **kwargs)
         elif isinstance(model, list):
-            return all(self.validate_capabilities(value) for value in model)
+            return all(self.validate_capabilities(value, **kwargs) for value in model)
         elif model is not None:
-            _handler = self._handlers.get(model.__class__)
+            _handler = self._models_to_handlers[model.__class__]
             return _handler(self, model).validate_capabilities(**kwargs)
 
     def _find_host(self, node):
         if node.type.role == 'host':
             return node
 
-        has_role = lambda rel, role: \
-            rel.target_capability is not None and rel.target_capability.type.role == role
+        def target_has_role(rel, role):
+            return (rel.target_capability is not None and
+                    rel.target_capability.type.role == role)
 
-        for relationship in node.outbound_relationships:
-            if has_role(relationship, 'host'):
-                host = self._find_host(relationship.target_node)
+        for outbound_relationship in node.outbound_relationships:
+            if target_has_role(outbound_relationship, 'host'):
+                host = self._find_host(outbound_relationship.target_node)
                 if host is not None:
                     return host
-        for relationship in node.inbound_relationships:
-            if has_role(relationship, 'feature'):
-                host = self._find_host(relationship.source_node)
+        for inbound_relationship in node.inbound_relationships:
+            if target_has_role(inbound_relationship, 'feature'):
+                host = self._find_host(inbound_relationship.source_node)
                 if host is not None:
                     return host
         return None
 
-    def find_hosts(self, service):
+    def assign_hosts(self, service):
         for node in service.nodes.values():
             node.host = self._find_host(node)
 
     def configure_operations(self, model, **kwargs):
         if isinstance(model, dict):
-            return self.configure_operations(model.values())
+            return self.configure_operations(model.values(), **kwargs)
         elif isinstance(model, list):
-            return all(self.configure_operations(value) for value in model)
+            return all(self.configure_operations(value, **kwargs) for value in model)
         elif model is not None:
-            _handler = self._handlers.get(model.__class__)
+            _handler = self._models_to_handlers[model.__class__]
             return _handler(self, model).configure_operations(**kwargs)

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/orchestrator/topology/utils.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/topology/utils.py b/aria/orchestrator/topology/utils.py
index 47396a5..ec74391 100644
--- a/aria/orchestrator/topology/utils.py
+++ b/aria/orchestrator/topology/utils.py
@@ -15,8 +15,6 @@
 
 from copy import deepcopy
 
-from ...utils.versions import VersionString
-
 
 def deepcopy_with_locators(value):
     """
@@ -48,20 +46,3 @@ def copy_locators(target, source):
     elif isinstance(target, dict) and isinstance(source, dict):
         for k, v in target.items():
             copy_locators(v, source[k])
-
-
-def resolve_plugin_specification(plugin_specification, plugins):
-    matching_plugins = []
-    if plugins:
-        for plugin in plugins:
-            if (plugin.name == plugin_specification.name and
-                    (plugin_specification.version is None or
-                     VersionString(plugin.package_version) >= plugin_specification.version)
-               ):
-                matching_plugins.append(plugin)
-    plugin_specification.plugin = None
-    if matching_plugins:
-        # Return highest version of plugin
-        plugin_specification.plugin = \
-            max(matching_plugins, key=lambda plugin: VersionString(plugin.package_version).key)
-    return plugin_specification.plugin is not None

http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/bbc5a7ed/aria/parser/consumption/modeling.py
----------------------------------------------------------------------
diff --git a/aria/parser/consumption/modeling.py b/aria/parser/consumption/modeling.py
index 0afd555..221b308 100644
--- a/aria/parser/consumption/modeling.py
+++ b/aria/parser/consumption/modeling.py
@@ -15,7 +15,6 @@
 
 from .consumer import Consumer, ConsumerChain
 from ...utils.formatting import json_dumps, yaml_dumps
-from ... import exceptions
 
 
 class DeriveServiceTemplate(Consumer):
@@ -75,7 +74,7 @@ class ServiceTemplate(ConsumerChain):
             raw = self.context.modeling.template_as_raw
             self.context.write(json_dumps(raw, indent=indent))
         else:
-            self.topology.dump(self.context.modeling.template)
+            self.context.write(self.topology.dump(self.context.modeling.template))
 
 
 class Types(Consumer):
@@ -110,22 +109,6 @@ class InstantiateServiceInstance(Consumer):
             self.context.modeling.template,
             inputs=dict(self.context.modeling.inputs)
         )
-        ConsumerChain(
-            self.context,
-            (
-                CoerceServiceInstanceValues,
-                ValidateServiceInstance,
-                SatisfyRequirements,
-                CoerceServiceInstanceValues,
-                ValidateCapabilities,
-                FindHosts,
-                ConfigureOperations,
-                CoerceServiceInstanceValues
-            )).consume()
-
-        if self.context.validation.dump_issues():
-            raise exceptions.InstantiationError('Failed to instantiate service template `{0}`'
-                                                .format(self.context.modeling.template.name))
 
 
 class CoerceServiceInstanceValues(Consumer):
@@ -170,7 +153,7 @@ class FindHosts(Consumer):
     """
 
     def consume(self):
-        self.topology.find_hosts(self.context.modeling.instance)
+        self.topology.assign_hosts(self.context.modeling.instance)
 
 
 class ConfigureOperations(Consumer):