diff --git a/Main.hs b/Main.hs
--- a/Main.hs
+++ b/Main.hs
@@ -72,21 +72,23 @@
     concurrentlyFor_ files $ codeGen options typeMapping $
         [ reflection_h
         , types_cpp
+        , types_comm_cpp
         , types_h header enum_header allocator
         , apply_h applyProto apply_attribute
         , apply_cpp applyProto
+        , comm_h
         ] <>
         [ enum_h | enum_header]
   where
     applyProto = map snd $ filter (enabled apply) protocols
     enabled a p = null a || fst p `elem` a
     protocols =
-        [ (Compact, Protocol "bond::CompactBinaryReader<bond::InputBuffer>"
-                             "bond::CompactBinaryWriter<bond::OutputBuffer>")
-        , (Fast,    Protocol "bond::FastBinaryReader<bond::InputBuffer>"
-                             "bond::FastBinaryWriter<bond::OutputBuffer>")
-        , (Simple,  Protocol "bond::SimpleBinaryReader<bond::InputBuffer>"
-                             "bond::SimpleBinaryWriter<bond::OutputBuffer>")
+        [ (Compact, Protocol " ::bond::CompactBinaryReader< ::bond::InputBuffer>"
+                             " ::bond::CompactBinaryWriter< ::bond::OutputBuffer>")
+        , (Fast,    Protocol " ::bond::FastBinaryReader< ::bond::InputBuffer>"
+                             " ::bond::FastBinaryWriter< ::bond::OutputBuffer>")
+        , (Simple,  Protocol " ::bond::SimpleBinaryReader< ::bond::InputBuffer>"
+                             " ::bond::SimpleBinaryWriter< ::bond::OutputBuffer>")
         ]
 cppCodegen _ = error "cppCodegen: impossible happened."
 
diff --git a/bond.cabal b/bond.cabal
--- a/bond.cabal
+++ b/bond.cabal
@@ -2,7 +2,7 @@
 -- Licensed under the MIT license. See LICENSE file in the project root for full license information.
 
 name:               bond
-version:            0.6.0.0
+version:            0.7.0.0
 cabal-version:      >= 1.8
 tested-with:        GHC>=7.4.1
 synopsis:           Bond schema compiler and code generator
@@ -62,7 +62,9 @@
                     Language.Bond.Codegen.Cpp.Enum_h
                     Language.Bond.Codegen.Cpp.Reflection_h
                     Language.Bond.Codegen.Cpp.Types_cpp
+                    Language.Bond.Codegen.Cpp.Types_Comm_cpp
                     Language.Bond.Codegen.Cpp.Types_h
+                    Language.Bond.Codegen.Cpp.Comm_h
                     Language.Bond.Codegen.Cs.Types_cs
                     Language.Bond.Codegen.Cs.Comm_cs
                     Language.Bond.Codegen.Cpp.ApplyOverloads
diff --git a/src/Language/Bond/Codegen/Cpp/ApplyOverloads.hs b/src/Language/Bond/Codegen/Cpp/ApplyOverloads.hs
--- a/src/Language/Bond/Codegen/Cpp/ApplyOverloads.hs
+++ b/src/Language/Bond/Codegen/Cpp/ApplyOverloads.hs
@@ -28,12 +28,12 @@
     //
     // Overloads of Apply function with common transforms for #{declName}.
     // These overloads will be selected using argument dependent lookup
-    // before bond::Apply function templates.
+    // before ::bond::Apply function templates.
     //
-    #{attr}bool Apply(const bond::To< #{qualifiedName}>& transform,
-               const bond::bonded< #{qualifiedName}>& value)#{body}
+    #{attr}bool Apply(const ::bond::To< #{qualifiedName}>& transform,
+               const ::bond::bonded< #{qualifiedName}>& value)#{body}
 
-    #{attr}bool Apply(const bond::InitSchemaDef& transform,
+    #{attr}bool Apply(const ::bond::InitSchemaDef& transform,
                const #{qualifiedName}& value)#{body}
     #{newlineSep 1 applyOverloads' protocols}|]
   where
@@ -47,22 +47,22 @@
     marshaler = "Marshaler" :: String
 
     deserialization Protocol {..} = [lt|
-    #{attr}bool Apply(const bond::To< #{qualifiedName}>& transform,
-               const bond::bonded< #{qualifiedName}, #{protocolReader}&>& value)#{body}
+    #{attr}bool Apply(const ::bond::To< #{qualifiedName}>& transform,
+               const ::bond::bonded< #{qualifiedName}, #{protocolReader}&>& value)#{body}
 
-    #{attr}bool Apply(const bond::To< #{qualifiedName}>& transform,
-               const bond::bonded<void, #{protocolReader}&>& value)#{body}|]
+    #{attr}bool Apply(const ::bond::To< #{qualifiedName}>& transform,
+               const ::bond::bonded<void, #{protocolReader}&>& value)#{body}|]
 
     serialization transform Protocol {..} = [lt|
-    #{attr}bool Apply(const bond::#{transform}<#{protocolWriter} >& transform,
+    #{attr}bool Apply(const ::bond::#{transform}<#{protocolWriter} >& transform,
                const #{qualifiedName}& value)#{body}
 
-    #{attr}bool Apply(const bond::#{transform}<#{protocolWriter} >& transform,
-               const bond::bonded< #{qualifiedName}>& value)#{body}
+    #{attr}bool Apply(const ::bond::#{transform}<#{protocolWriter} >& transform,
+               const ::bond::bonded< #{qualifiedName}>& value)#{body}
     #{newlineSep 1 (transcoding transform) protocols}|]
       where
         transcoding transform' Protocol {protocolReader = fromReader} = [lt|
-    #{attr}bool Apply(const bond::#{transform'}<#{protocolWriter} >& transform,
-               const bond::bonded< #{qualifiedName}, #{fromReader}&>& value)#{body}|]
+    #{attr}bool Apply(const ::bond::#{transform'}<#{protocolWriter} >& transform,
+               const ::bond::bonded< #{qualifiedName}, #{fromReader}&>& value)#{body}|]
 
 applyOverloads _ _ _ _ _ = mempty
diff --git a/src/Language/Bond/Codegen/Cpp/Apply_cpp.hs b/src/Language/Bond/Codegen/Cpp/Apply_cpp.hs
--- a/src/Language/Bond/Codegen/Cpp/Apply_cpp.hs
+++ b/src/Language/Bond/Codegen/Cpp/Apply_cpp.hs
@@ -28,7 +28,7 @@
   where
     body = [lt|
     {
-        return bond::Apply<>(transform, value);
+        return ::bond::Apply<>(transform, value);
     }|]
 
     attr = [lt||]
diff --git a/src/Language/Bond/Codegen/Cpp/Comm_h.hs b/src/Language/Bond/Codegen/Cpp/Comm_h.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Bond/Codegen/Cpp/Comm_h.hs
@@ -0,0 +1,329 @@
+-- Copyright (c) Microsoft. All rights reserved.
+-- Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+{-# LANGUAGE QuasiQuotes, OverloadedStrings, RecordWildCards #-}
+
+module Language.Bond.Codegen.Cpp.Comm_h (comm_h) where
+
+import System.FilePath
+import Data.Monoid
+import Prelude
+import qualified Data.Text.Lazy as L
+import Data.Text.Lazy.Builder
+import Text.Shakespeare.Text
+import Language.Bond.Syntax.Types
+import Language.Bond.Syntax.Util
+import Language.Bond.Codegen.Util
+import Language.Bond.Codegen.TypeMapping
+import qualified Language.Bond.Codegen.Cpp.Util as CPP
+
+
+-- | Codegen template for generating /base_name/_comm.h containing declarations of
+-- of service interface and proxy.
+comm_h :: MappingContext -> String -> [Import] -> [Declaration] -> (String, L.Text)
+comm_h cpp file imports declarations = ("_comm.h", [lt|
+#pragma once
+
+#include <bond/comm/services.h>
+#include "#{file}_types.h"
+#{newlineSep 0 includeImport imports}
+
+#{CPP.openNamespace cpp}
+    #{doubleLineSep 1 comm declarations}
+
+#{CPP.closeNamespace cpp}
+|])
+  where
+    includeImport (Import path) = [lt|#include "#{dropExtension path}_comm.h"|]
+
+    cppType = getTypeName cpp
+
+    request mt = request' (payload mt)
+      where
+        payload = maybe "void" cppType
+        request' params =  [lt|::bond::comm::payload<#{padLeft}#{params}>|]
+          where
+            paramsText = toLazyText params
+            padLeft = if L.head paramsText == ':' then [lt| |] else mempty
+
+    response mt = response' (payload mt)
+      where
+        payload = maybe "void" cppType
+        response' params =  [lt|::bond::comm::message<#{padLeft}#{params}>|]
+          where
+            paramsText = toLazyText params
+            padLeft = if L.head paramsText == ':' then [lt| |] else mempty
+
+    callback m = [lt|const std::function<void (const #{response m}&)>& callback|]
+
+    comm s@Service {..} = [lt|#{template}class #{declName}
+    {
+    public:
+        virtual ~#{declName}() = default;
+
+        #{doubleLineSep 2 virtualMethod serviceMethods}
+
+        struct Schema;
+        class Proxy;
+
+        template <template <typename> class Promise>
+        class Using;
+    };
+
+    #{template}struct #{className}::Schema
+    {
+        static const ::bond::Metadata metadata;
+
+        #{newlineSep 2 methodMetadata serviceMethods}
+
+        public: struct service
+        {
+            #{doubleLineSep 3 methodTemplate serviceMethods}
+        };
+
+        private: typedef boost::mpl::list<> methods0;
+        #{newlineSep 2 pushMethod indexedMethods}
+
+        public: typedef #{typename}methods#{length serviceMethods}::type methods;
+        #{constructor}
+    };
+    #{onlyTemplate $ CPP.schemaMetadata cpp s}
+
+    #{template}class #{className}::Proxy
+        : public #{className}
+    {
+    public:
+        template <typename ServiceProxy>
+        explicit
+        Proxy(const ServiceProxy& proxy,
+              const std::string& name = #{className}::Schema::metadata.qualified_name)
+            : _impl(boost::make_shared<__Impl<ServiceProxy>>(proxy, name))
+        {}
+
+        explicit
+        Proxy(const boost::shared_ptr<#{className}>& service)
+            : _impl(service)
+        {}
+
+        Proxy() = default;
+
+        #{doubleLineSep 2 proxyMethod serviceMethods}
+
+        template <template <typename> class Promise>
+        class Using;
+
+    protected:
+        boost::shared_ptr<#{className}> _impl;
+
+        template <typename ServiceProxy>
+        class __Impl
+            : public #{className}
+        {
+        public:
+            __Impl(const ServiceProxy& proxy, const std::string& name)
+                : _proxy(proxy),
+                  _name(name)
+            {}
+
+            virtual ~__Impl() = default;
+
+            #{doubleLineSep 3 implMethod serviceMethods}
+
+        private:
+            ServiceProxy _proxy;
+            const std::string _name;
+        };
+    };
+
+    #{template}template <template <typename> class Promise>
+    class #{className}::Using
+        : public #{className}
+    {
+    public:
+        #{doubleLineSep 2 virtualFutureMethod serviceMethods}
+
+        #{doubleLineSep 2 serviceMethod serviceMethods}
+    };
+
+    #{template}template <template <typename> class Promise>
+    class #{className}::Proxy::Using
+        : public #{className}::Proxy
+    {
+    public:
+        template <typename ServiceProxy>
+        explicit
+        Using(const ServiceProxy& proxy,
+              const std::string& name = #{className}::Schema::metadata.qualified_name)
+            : #{className}::Proxy(proxy, name)
+        {}
+
+        explicit
+        Using(const boost::shared_ptr<#{className}>& service)
+            : #{className}::Proxy(service)
+        {}
+
+        Using() = default;
+
+        #{doubleLineSep 2 proxyFutureMethod serviceMethods}
+    };
+    |]
+      where
+        className = CPP.className s
+        template = CPP.template s
+        onlyTemplate x = if null declParams then mempty else x
+        typename = onlyTemplate [lt|typename |]
+
+        methodMetadataVar m = [lt|s_#{methodName m}_metadata|]
+
+        methodMetadata m =
+            [lt|private: static const ::bond::Metadata #{methodMetadataVar m};|]
+
+        -- reversed list of method names zipped with indexes
+        indexedMethods :: [(String, Int)]
+        indexedMethods = zipWith ((,) . methodName) (reverse serviceMethods) [0..]
+
+        pushMethod (method, i) =
+            [lt|private: typedef #{typename}boost::mpl::push_front<methods#{i}, #{typename}service::#{method}>::type methods#{i + 1};|]
+
+        -- constructor, generated only for service templates
+        constructor = onlyTemplate [lt|
+            Schema()
+            {
+                // Force instantiation of template statics
+                (void)metadata;
+                #{newlineSep 4 static serviceMethods}
+            }|]
+          where
+            static m = [lt|(void)#{methodMetadataVar m};|]
+
+        methodTemplate m = [lt|typedef ::bond::reflection::MethodTemplate<
+                #{className},
+                #{request $ methodInput m},
+                #{result m},
+                &#{className}::#{methodName m},
+                &#{methodMetadataVar m}
+            > #{methodName m};|]
+          where
+            result Event{} = "void"
+            result Function{..} = response methodResult
+
+        methodSignature n m =
+            [lt|void #{methodName m}(#{commaLineSep n id $ methodParams m})|]
+          where
+            methodParams Event{..} =
+                [ [lt|const #{request methodInput}& input|]
+                ]
+
+            methodParams Function{..} =
+                [ [lt|const #{request methodInput}& input|]
+                , callback methodResult
+                ]
+
+        resultOf x f = [lt|decltype(std::declval< #{x}>().#{f}())|]
+
+        promiseType result = [lt|Promise< #{response result}>|]
+
+        futureType result = resultOf (promiseType result) get_future
+          where
+            get_future = [lt|get_future|]
+
+        methodFutureSignature Function{..} =
+            [lt|auto #{methodName}(const #{request methodInput}& input)
+            -> #{futureType methodResult}|]
+        methodFutureSignature Event{..} = error "No future-based signature for Event methods"
+
+        virtualMethod m = [lt|virtual #{methodSignature 3 m} = 0;|]
+
+        virtualFutureMethod Event{} = mempty
+        virtualFutureMethod m = [lt|virtual #{methodFutureSignature m} = 0;|]
+
+        serviceMethod Event{} = mempty
+        serviceMethod m@Function{..} = [lt|#{methodSignature 3 m} override
+        {
+            when(#{methodName}(input), ::bond::comm::Continuation(callback));
+        }|]
+
+        proxyMethod m@Event{..} = [lt|#{methodSignature 3 m} override
+        {
+            _impl->#{methodName}(input);
+        }#{proxyMethodOverload methodInput}|]
+          where
+            proxyMethodOverload Nothing = [lt|
+
+        void #{methodName}()
+        {
+            _impl->#{methodName}(::bond::comm::payload<void>());
+        }|]
+            proxyMethodOverload (Just payload) | isStruct payload = [lt|
+
+        void #{methodName}(const #{cppType payload}& input)
+        {
+            _impl->#{methodName}(boost::cref(input));
+        }|]
+            proxyMethodOverload _ = mempty
+
+        proxyMethod m@Function{..} = [lt|#{methodSignature 3 m} override
+        {
+            _impl->#{methodName}(input, callback);
+        }#{proxyMethodOverload methodInput}|]
+          where
+            proxyMethodOverload Nothing = [lt|
+
+        void #{methodName}(
+            #{callback methodResult})
+        {
+            _impl->#{methodName}(::bond::comm::payload<void>(), callback);
+        }|]
+            proxyMethodOverload (Just payload) | isStruct payload = [lt|
+
+        void #{methodName}(const #{cppType payload}& input,
+            #{callback methodResult})
+        {
+            _impl->#{methodName}(boost::cref(input), callback);
+        }|]
+            proxyMethodOverload _ = mempty
+
+        proxyFutureMethod Event{} = mempty
+        proxyFutureMethod m@Function{..} = [lt|using #{className}::Proxy::#{methodName};
+
+        #{methodFutureSignature m}
+        {
+            auto promise = boost::make_shared<#{promiseType methodResult}>();
+
+            _impl->#{methodName}(input,
+                [=](const #{response methodResult}& result) mutable
+                {
+                    promise->set_value(result);
+                });
+
+            return promise->get_future();
+        }#{proxyMethodOverload methodInput}|]
+          where
+            proxyMethodOverload Nothing = [lt|
+
+        auto #{methodName}()
+            -> #{futureType methodResult}
+        {
+            return #{methodName}(::bond::comm::payload<void>());
+        }|]
+            proxyMethodOverload (Just payload) | isStruct payload = [lt|
+
+        auto #{methodName}(const #{cppType payload}& input)
+            -> #{futureType methodResult}
+        {
+            return #{methodName}(#{request methodInput}(boost::cref(input)));
+        }
+        |]
+            proxyMethodOverload _ = mempty
+
+        implMethod m@Event{..} = [lt|#{methodSignature 4 m} override
+            {
+                _proxy.Send(_name, Schema::service::#{methodName}::metadata.name, input);
+            }|]
+
+        implMethod m@Function{..} = [lt|#{methodSignature 4 m} override
+            {
+                _proxy.Send(_name, Schema::service::#{methodName}::metadata.name, input, callback);
+            }|]
+
+    comm _ = mempty
diff --git a/src/Language/Bond/Codegen/Cpp/Reflection_h.hs b/src/Language/Bond/Codegen/Cpp/Reflection_h.hs
--- a/src/Language/Bond/Codegen/Cpp/Reflection_h.hs
+++ b/src/Language/Bond/Codegen/Cpp/Reflection_h.hs
@@ -42,11 +42,11 @@
     schema s@Struct {..} = [lt|//
     // #{declName}
     //
-    #{CPP.template s}struct #{structName}::Schema
+    #{CPP.template s}struct #{className}::Schema
     {
         typedef #{baseType structBase} base;
 
-        static const bond::Metadata metadata;
+        static const ::bond::Metadata metadata;
         #{newlineBeginSep 2 fieldMetadata structFields}
 
         public: struct var
@@ -58,22 +58,22 @@
         public: typedef #{typename}fields#{length structFields}::type fields;
         #{constructor}
         
-        static bond::Metadata GetMetadata()
+        static ::bond::Metadata GetMetadata()
         {
-            return bond::reflection::MetadataInit#{metadataInitArgs}("#{declName}", "#{getDeclTypeName idl s}",
+            return ::bond::reflection::MetadataInit#{metadataInitArgs}("#{declName}", "#{getDeclTypeName idl s}",
                 #{CPP.attributeInit declAttributes}
             );
         }
     };
     #{onlyTemplate $ CPP.schemaMetadata cpp s}|]
       where
-        structParams = CPP.structParams s
+        classParams = CPP.classParams s
 
-        structName = CPP.structName s
+        className = CPP.className s
 
         onlyTemplate x = if null declParams then mempty else x
 
-        metadataInitArgs = onlyTemplate [lt|<boost::mpl::list#{structParams} >|]
+        metadataInitArgs = onlyTemplate [lt|<boost::mpl::list#{classParams} >|]
 
         typename = onlyTemplate [lt|typename |]
 
@@ -93,22 +93,22 @@
         indexedFields = zipWith ((,) . fieldName) (reverse structFields) [0..]
 
         baseType (Just base) = cppType base
-        baseType Nothing = "bond::no_base"
+        baseType Nothing = "::bond::no_base"
 
         pushField (field, i) =
             [lt|private: typedef #{typename}boost::mpl::push_front<fields#{i}, #{typename}var::#{field}>::type fields#{i + 1};|]
 
         fieldMetadata Field {..} =
-            [lt|private: static const bond::Metadata s_#{fieldName}_metadata;|]
+            [lt|private: static const ::bond::Metadata s_#{fieldName}_metadata;|]
 
         fieldTemplates = F.foldMap $ \ f@Field {..} -> [lt|
             // #{fieldName}
-            typedef bond::reflection::FieldTemplate<
+            typedef ::bond::reflection::FieldTemplate<
                 #{fieldOrdinal},
                 #{CPP.modifierTag f},
-                #{structName},
+                #{className},
                 #{cppType fieldType},
-                &#{structName}::#{fieldName},
+                &#{className}::#{fieldName},
                 &s_#{fieldName}_metadata
             > #{fieldName};
         |]
diff --git a/src/Language/Bond/Codegen/Cpp/Types_Comm_cpp.hs b/src/Language/Bond/Codegen/Cpp/Types_Comm_cpp.hs
new file mode 100644
--- /dev/null
+++ b/src/Language/Bond/Codegen/Cpp/Types_Comm_cpp.hs
@@ -0,0 +1,34 @@
+-- Copyright (c) Microsoft. All rights reserved.
+-- Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+{-# LANGUAGE QuasiQuotes, OverloadedStrings, RecordWildCards #-}
+
+module Language.Bond.Codegen.Cpp.Types_Comm_cpp (types_comm_cpp) where
+
+import Data.Monoid
+import Prelude
+import Data.Text.Lazy (Text)
+import Text.Shakespeare.Text
+import Language.Bond.Syntax.Types
+import Language.Bond.Codegen.TypeMapping
+import Language.Bond.Codegen.Util
+import qualified Language.Bond.Codegen.Cpp.Util as CPP
+
+-- | Codegen template for generating /base_name/_comm_types.cpp containing
+-- definitions of helper functions and schema metadata static variables.
+types_comm_cpp :: MappingContext -> String -> [Import] -> [Declaration] -> (String, Text)
+types_comm_cpp cpp file _imports declarations = ("_comm.cpp", [lt|
+#include "#{file}_reflection.h"
+#include "#{file}_comm.h"
+#include <bond/core/exception.h>
+
+#{CPP.openNamespace cpp}
+    #{doubleLineSepEnd 1 statics declarations}
+#{CPP.closeNamespace cpp}
+|])
+  where
+    -- definitions of Schema statics for non-generic services
+    statics s@Service {..} =
+        if null declParams then CPP.schemaMetadata cpp s else mempty
+
+    statics _ = mempty
diff --git a/src/Language/Bond/Codegen/Cpp/Types_cpp.hs b/src/Language/Bond/Codegen/Cpp/Types_cpp.hs
--- a/src/Language/Bond/Codegen/Cpp/Types_cpp.hs
+++ b/src/Language/Bond/Codegen/Cpp/Types_cpp.hs
@@ -14,7 +14,7 @@
 import Language.Bond.Codegen.Util
 import qualified Language.Bond.Codegen.Cpp.Util as CPP
 
--- | Codegen template for generating /base_name/_type.cpp containing
+-- | Codegen template for generating /base_name/_types.cpp containing
 -- definitions of helper functions and schema metadata static variables.
 types_cpp :: MappingContext -> String -> [Import] -> [Declaration] -> (String, Text)
 types_cpp cpp file _imports declarations = ("_types.cpp", [lt|
@@ -47,7 +47,7 @@
 
         const
         std::map<enum #{declName}, std::string> _value_to_name_#{declName} =
-            bond::reverse_map(_name_to_value_#{declName});
+            ::bond::reverse_map(_name_to_value_#{declName});
 
         const std::string& ToString(enum #{declName} value)
         {
@@ -55,7 +55,7 @@
                 GetValueToNameMap(value).find(value);
 
             if (GetValueToNameMap(value).end() == it)
-                bond::InvalidEnumValueException(value, "#{declName}");
+                ::bond::InvalidEnumValueException(value, "#{declName}");
 
             return it->second;
         }
@@ -63,7 +63,7 @@
         void FromString(const std::string& name, enum #{declName}& value)
         {
             if (!ToEnum(value, name))
-                bond::InvalidEnumValueException(name.c_str(), "#{declName}");
+                ::bond::InvalidEnumValueException(name.c_str(), "#{declName}");
         }
     } // namespace #{declName}
     } // namespace _bond_enumerators|]
diff --git a/src/Language/Bond/Codegen/Cpp/Types_h.hs b/src/Language/Bond/Codegen/Cpp/Types_h.hs
--- a/src/Language/Bond/Codegen/Cpp/Types_h.hs
+++ b/src/Language/Bond/Codegen/Cpp/Types_h.hs
@@ -103,7 +103,7 @@
 |]
       where
         usesAllocator s@Struct {..} = [lt|template <typename _Alloc#{sepBeginBy ", typename " paramName declParams}>
-    struct uses_allocator<#{typename} #{getDeclTypeName cpp s}#{CPP.structParams s}, _Alloc>
+    struct uses_allocator<#{typename} #{getDeclTypeName cpp s}#{CPP.classParams s}, _Alloc>
         : is_convertible<_Alloc, #{allocParam}>
     {};|]
           where
@@ -146,13 +146,13 @@
         #{initMetadata}
     };
 
-    #{template}inline void swap(#{qualifiedStructName}& left, #{qualifiedStructName}& right)
+    #{template}inline void swap(#{qualifiedClassName}& left, #{qualifiedClassName}& right)
     {
         left.swap(right);
     }|]
       where
         template = CPP.template s
-        qualifiedStructName = [lt|#{getDeclTypeName cpp s}#{CPP.structParams s}|]
+        qualifiedClassName = CPP.qualifiedClassName cpp s
 
         otherParam = if hasOnlyMetaFields then mempty else [lt| other|]
         hasOnlyMetaFields = not (any (not . getAny . metaField) structFields) && isNothing structBase
@@ -339,7 +339,7 @@
         }
 
         inline
-        const char* GetTypeName(enum #{declName}, const bond::qualified_name_tag&)
+        const char* GetTypeName(enum #{declName}, const ::bond::qualified_name_tag&)
         {
             return "#{getDeclTypeName idl e}";
         }
diff --git a/src/Language/Bond/Codegen/Cpp/Util.hs b/src/Language/Bond/Codegen/Cpp/Util.hs
--- a/src/Language/Bond/Codegen/Cpp/Util.hs
+++ b/src/Language/Bond/Codegen/Cpp/Util.hs
@@ -7,8 +7,9 @@
 module Language.Bond.Codegen.Cpp.Util
     ( openNamespace
     , closeNamespace
-    , structName
-    , structParams
+    , className
+    , classParams
+    , qualifiedClassName
     , template
     , modifierTag
     , defaultValue
@@ -23,7 +24,8 @@
 
 import Data.Monoid
 import Prelude
-import Data.Text.Lazy (Text)
+import Data.Text.Lazy (Text, unpack)
+import Data.Text.Lazy.Builder (toLazyText)
 import Text.Shakespeare.Text
 import Language.Bond.Syntax.Types
 import Language.Bond.Syntax.Util
@@ -44,14 +46,18 @@
   where
     close n = [lt|} // namespace #{n}|]
 
-structName :: Declaration -> String
-structName s@Struct {..} = declName <> structParams s
-structName _ = error "structName: impossible happened."
+className :: Declaration -> String
+className decl = declName decl <> classParams decl
 
-structParams :: Declaration -> String
-structParams Struct {..} = angles $ sepBy ", " paramName declParams
-structParams _ = error "structName: impossible happened."
+classParams :: Declaration -> String
+classParams = angles . sepBy ", " paramName . declParams
 
+qualifiedClassName :: MappingContext -> Declaration -> String
+qualifiedClassName cpp s@Struct {..} = qualifiedName <> classParams s
+  where
+    qualifiedName = unpack $ toLazyText $ getDeclTypeName cpp s
+qualifiedClassName _ _ = error "qualifiedClassName: impossible happened."
+
 template :: Declaration -> Text
 template d = if null $ declParams d then mempty else [lt|template <typename #{params}>
     |]
@@ -60,7 +66,7 @@
 
 -- attribute initializer
 attributeInit :: [Attribute] -> Text
-attributeInit [] = "bond::reflection::Attributes()"
+attributeInit [] = "::bond::reflection::Attributes()"
 attributeInit xs = [lt|boost::assign::map_list_of<std::string, std::string>#{newlineBeginSep 5 attrNameValue xs}|]
   where
     idl = MappingContext idlTypeMapping [] [] []  
@@ -69,7 +75,7 @@
 
 -- modifier tag type for a field
 modifierTag :: Field -> Text
-modifierTag Field {..} = [lt|bond::reflection::#{modifier fieldType fieldModifier}_field_modifier|]
+modifierTag Field {..} = [lt|::bond::reflection::#{modifier fieldType fieldModifier}_field_modifier|]
   where
     modifier BT_MetaName _ = [lt|required_optional|]
     modifier BT_MetaFullName _ = [lt|required_optional|]
@@ -102,26 +108,42 @@
 -- schema metadata static member definitions
 schemaMetadata :: MappingContext -> Declaration -> Text
 schemaMetadata cpp s@Struct {..} = [lt|
-    #{template s}const bond::Metadata #{structName s}::Schema::metadata
-        = #{structName s}::Schema::GetMetadata();#{newlineBeginSep 1 staticDef structFields}|]
+    #{template s}const ::bond::Metadata #{className s}::Schema::metadata
+        = #{className s}::Schema::GetMetadata();#{newlineBeginSep 1 staticDef structFields}|]
   where
     -- static member definition for field metadata
     staticDef f@Field {..}
         | fieldModifier == Optional && null fieldAttributes = [lt|
-    #{template s}const bond::Metadata #{structName s}::Schema::s_#{fieldName}_metadata
-        = bond::reflection::MetadataInit(#{defaultInit f}"#{fieldName}");|]
+    #{template s}const ::bond::Metadata #{className s}::Schema::s_#{fieldName}_metadata
+        = ::bond::reflection::MetadataInit(#{defaultInit f}"#{fieldName}");|]
         | otherwise = [lt|
-    #{template s}const bond::Metadata #{structName s}::Schema::s_#{fieldName}_metadata
-        = bond::reflection::MetadataInit(#{defaultInit f}"#{fieldName}", #{modifierTag f}::value,
-            #{attributeInit fieldAttributes});|]
+    #{template s}const ::bond::Metadata #{className s}::Schema::s_#{fieldName}_metadata
+        = ::bond::reflection::MetadataInit(#{defaultInit f}"#{fieldName}", #{modifierTag f}::value,
+                #{attributeInit fieldAttributes});|]
       where
         defaultInit Field {fieldDefault = (Just def)} = [lt|#{explicitDefault def}, |]
         defaultInit _ = mempty
-        explicitDefault (DefaultNothing) = "bond::nothing"
+        explicitDefault (DefaultNothing) = "::bond::nothing"
         explicitDefault d@(DefaultInteger _) = staticCast d
         explicitDefault d@(DefaultFloat _) = staticCast d
         explicitDefault d = defaultValue cpp fieldType d
         staticCast d = [lt|static_cast<#{getTypeName cpp fieldType}>(#{defaultValue cpp fieldType d})|]
+schemaMetadata _ s@Service {..} = [lt|
+    #{template s}const ::bond::Metadata #{className s}::Schema::metadata
+        = ::bond::reflection::MetadataInit#{metadataInitArgs}("#{declName}", "#{idlNamespace}",
+                #{attributeInit declAttributes});#{newlineBeginSep 1 staticDef serviceMethods}|]
+  where
+    idl = MappingContext idlTypeMapping [] [] []
+    idlNamespace = getDeclTypeName idl s
+    metadataInitArgs = if null declParams then mempty else [lt|<boost::mpl::list#{classParams s} >|]
+    -- static member definition for method metadata
+    staticDef m = [lt|
+    #{template s}const ::bond::Metadata #{className s}::Schema::s_#{methodName m}_metadata
+        = ::bond::reflection::MetadataInit("#{methodName m}"#{attributes $ methodAttributes m}|]
+      where
+        attributes [] = [lt|);|]
+        attributes a = [lt|,
+                #{attributeInit a});|]
 schemaMetadata _ _ = error "schemaMetadata: impossible happened."
 
 defaultedFunctions, defaultedMoveCtors, rvalueReferences :: Text
diff --git a/src/Language/Bond/Codegen/Templates.hs b/src/Language/Bond/Codegen/Templates.hs
--- a/src/Language/Bond/Codegen/Templates.hs
+++ b/src/Language/Bond/Codegen/Templates.hs
@@ -36,11 +36,14 @@
       -- ** C++
       types_h
     , types_cpp
+    , types_comm_cpp
     , reflection_h
     , enum_h
     , apply_h
     , apply_cpp
     ,  Protocol(..)
+      -- ** C++ Comm
+    , comm_h
       -- ** C#
     , FieldMapping(..)
     , StructMapping(..)
@@ -57,7 +60,9 @@
 import Language.Bond.Codegen.Cpp.Enum_h
 import Language.Bond.Codegen.Cpp.Reflection_h
 import Language.Bond.Codegen.Cpp.Types_cpp
+import Language.Bond.Codegen.Cpp.Types_Comm_cpp
 import Language.Bond.Codegen.Cpp.Types_h
+import Language.Bond.Codegen.Cpp.Comm_h
 import Language.Bond.Codegen.Cs.Types_cs
 import Language.Bond.Codegen.Cs.Comm_cs
 -- redundant imports for haddock
diff --git a/src/Language/Bond/Codegen/TypeMapping.hs b/src/Language/Bond/Codegen/TypeMapping.hs
--- a/src/Language/Bond/Codegen/TypeMapping.hs
+++ b/src/Language/Bond/Codegen/TypeMapping.hs
@@ -350,15 +350,15 @@
 cppType BT_WString = pure "std::wstring"
 cppType BT_MetaName = pure "std::string"
 cppType BT_MetaFullName = pure "std::string"
-cppType BT_Blob = pure "bond::blob"
+cppType BT_Blob = pure "::bond::blob"
 cppType (BT_IntTypeArg x) = pureText x
-cppType (BT_Maybe type_) = "bond::maybe<" <>> elementTypeName type_ <<> ">"
+cppType (BT_Maybe type_) = "::bond::maybe<" <>> elementTypeName type_ <<> ">"
 cppType (BT_List element) = "std::list<" <>> elementTypeName element <<> ">"
-cppType (BT_Nullable element) = "bond::nullable<" <>> elementTypeName element <<> ">"
+cppType (BT_Nullable element) = "::bond::nullable<" <>> elementTypeName element <<> ">"
 cppType (BT_Vector element) = "std::vector<" <>> elementTypeName element <<> ">"
 cppType (BT_Set element) = "std::set<" <>> elementTypeName element <<> ">"
 cppType (BT_Map key value) = "std::map<" <>> elementTypeName key <<>> ", " <>> elementTypeName value <<> ">"
-cppType (BT_Bonded type_) = "bond::bonded<" <>> elementTypeName type_ <<> ">"
+cppType (BT_Bonded type_) = "::bond::bonded<" <>> elementTypeName type_ <<> ">"
 cppType (BT_TypeParam param) = pureText $ paramName param
 cppType (BT_UserDefined a@Alias {..} args) = aliasTypeName a args
 cppType (BT_UserDefined decl args) = declQualifiedTypeName decl <<>> (angles <$> commaSepTypeNames args)
@@ -370,8 +370,8 @@
 cppTypeCustomAlloc alloc BT_MetaName = cppTypeCustomAlloc alloc BT_String
 cppTypeCustomAlloc alloc BT_MetaFullName = cppTypeCustomAlloc alloc BT_String
 cppTypeCustomAlloc alloc (BT_List element) = "std::list<" <>> elementTypeName element <<>> ", " <>> allocator alloc element <<> ">"
-cppTypeCustomAlloc alloc (BT_Nullable element) | isStruct element = "bond::nullable<" <>> elementTypeName element <<> ", " <> alloc <> ">"
-cppTypeCustomAlloc _lloc (BT_Nullable element) = "bond::nullable<" <>> elementTypeName element <<> ">"
+cppTypeCustomAlloc alloc (BT_Nullable element) | isStruct element = "::bond::nullable<" <>> elementTypeName element <<> ", " <> alloc <> ">"
+cppTypeCustomAlloc _lloc (BT_Nullable element) = "::bond::nullable<" <>> elementTypeName element <<> ">"
 cppTypeCustomAlloc alloc (BT_Vector element) = "std::vector<" <>> elementTypeName element <<>> ", " <>> allocator alloc element <<> ">"
 cppTypeCustomAlloc alloc (BT_Set element) = "std::set<" <>> elementTypeName element <<>> comparer element <<>> allocator alloc element <<> ">"
 cppTypeCustomAlloc alloc (BT_Map key value) = "std::map<" <>> elementTypeName key <<>> ", " <>> elementTypeName value <<>> comparer key <<>> pairAllocator alloc key value <<> ">"
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -10,7 +10,7 @@
 tests :: TestTree
 tests = testGroup "Compiler tests"
     [ testGroup "AST"
-        [ localOption (QuickCheckMaxSize 15) $
+        [ localOption (QuickCheckMaxSize 6) $
             testProperty "roundtrip" roundtripAST
         , testGroup "Compare .bond and .json"
             [ testCase "attributes" $ compareAST "attributes"
@@ -27,6 +27,7 @@
             , testCase "simple service syntax" $ compareAST "service"
             , testCase "service attributes" $ compareAST "service_attributes"
             , testCase "generic service" $ compareAST "generic_service"
+            , testCase "documentation example" $ compareAST "example"
             ]
         ]
     , testGroup "SchemaDef"
@@ -97,6 +98,20 @@
                 ]
                 "basic_types"
             ]
+            , testGroup "Comm"
+                [ verifyCppCommCodegen
+                    [ "c++"
+                    ]
+                    "service"
+                , verifyCppCommCodegen
+                    [ "c++"
+                    ]
+                    "generic_service"
+                , verifyCppCommCodegen
+                    [ "c++"
+                    ]
+                    "service_attributes"
+                ]
     , testGroup "C#"
             [ verifyCsCodegen "attributes"
             , verifyCsCodegen "basic_types"
diff --git a/tests/Tests/Codegen.hs b/tests/Tests/Codegen.hs
--- a/tests/Tests/Codegen.hs
+++ b/tests/Tests/Codegen.hs
@@ -7,6 +7,7 @@
 module Tests.Codegen
     ( verifyCodegen
     , verifyCppCodegen
+    , verifyCppCommCodegen
     , verifyApplyCodegen
     , verifyCsCodegen
     , verifyCsCommCodegen
@@ -61,6 +62,14 @@
                    "bond::SimpleBinaryWriter<bond::OutputBuffer>"
         ]
 
+verifyCppCommCodegen :: [String] -> FilePath -> TestTree
+verifyCppCommCodegen args baseName =
+    testGroup baseName $
+        map (verifyFile (processOptions args) baseName cppTypeMapping "")
+            [ comm_h
+            , types_cpp
+            , types_comm_cpp
+            ]
 
 verifyCsCommCodegen :: [String] -> FilePath -> TestTree
 verifyCsCommCodegen args baseName =
@@ -95,6 +104,7 @@
     templates Cpp {..} =
         [ reflection_h
         , types_cpp
+        , types_comm_cpp
         , types_h header enum_header allocator
         ]
     templates Cs {..} =
