diff --git a/asyncmsg/NameService.h b/asyncmsg/NameService.h
index 26fbabba76abdb16374e9cb261b7ea2b8b135600..170abbba6973e85c4fe971105a4431a6e4be5ceb 100644
--- a/asyncmsg/NameService.h
+++ b/asyncmsg/NameService.h
@@ -41,6 +41,13 @@ namespace daq {
                            ((std::string)m_name)
                            )
 
+    ERS_DECLARE_ISSUE_BASE(asyncmsg,
+                           CannotAllocateMulticast,
+                           Issue,
+                           "Cannot allocate multicast address",
+                           ERS_EMPTY,
+                           ERS_EMPTY)
+
     namespace asyncmsg {
 
         
@@ -106,16 +113,42 @@ namespace daq {
 
             /** \brief Resolve a single specific application.
              *
-             * \param[in] Resolves exactly one specific remote applications.
+             * \param[in] name Resolves exactly one specific remote applications with this name.
              *
              * \throws daq::asyncmsg::CannotResolve, IS exceptions
              */
             boost::asio::ip::tcp::endpoint resolve(const std::string& name) const;
 
-            /** \brief A helper method to parse a string of the form network/netmask.
+            /**
+             * \brief Allocate the multicast address for the partition.
+             *
+             * \param[in] addr The string representation of the address; can be a full IP address or '*'.
+             * \param[in] network The string representation of the network to use for multicast.
+             * \returns The allocated multicast address.
+             * \throws daq::asyncmsg::CannotAllocateMulticast, daq::asyncmsg::InvalidISServer
+             *
+             * Only one application per partition should call this. If the 'addr' parameter contains
+             * a '*', the multicast address will be dynamically allocated in such a way that it
+             * is unique per installation and across partitions (e.g. in Point 1).
+             */
+            std::string allocate_multicast_address(const std::string& addr, const std::string& network);
+
+            /** \brief Find the multicast address for the partition.
              * 
+             * \returns A string containing the IP addresses usable by boost::asio.
+             *
+             * \throws daq::asyncmsg::CannotResolve
+             *
+             * Applications who need the multicast address of the partition should call this with the 
+             * 'addr' taken from OKS. If 'addr' is '*' the multicast address will be dynamically looked up.
              */
+            std::string lookup_multicast_address(const std::string& addr) const;
+
+            /** typedef for readability, a 2-tuple of IP addresses representing network/netmask. */
             typedef std::tuple<boost::asio::ip::address,boost::asio::ip::address> Network;
+
+            /** \brief A helper method to parse a string of the form network/netmask.
+             */
             static Network parse_address_network(const std::string& network);
 
             /** \brief A helper method to find the local interface matching netmask.
diff --git a/schema/MsgInfo_is.schema.xml b/schema/MsgInfo_is.schema.xml
index 7876424f70f662c93d9b54b39405e24158002628..a91496c5bddbf85c94f59f97d962baee03ee5cb6 100644
--- a/schema/MsgInfo_is.schema.xml
+++ b/schema/MsgInfo_is.schema.xml
@@ -9,7 +9,6 @@
   <!ATTLIST info
       name CDATA #REQUIRED
       type CDATA #REQUIRED
-      num-of-includes CDATA #REQUIRED
       num-of-items CDATA #REQUIRED
       oks-format CDATA #FIXED "schema"
       oks-version CDATA #REQUIRED
@@ -50,7 +49,6 @@
       range CDATA ""
       format (dec|hex|oct) "dec"
       is-multi-value (yes|no) "no"
-      multi-value-implementation (list|vector) "list"
       init-value CDATA ""
       is-not-null (yes|no) "no"
   >
@@ -64,7 +62,6 @@
       is-composite (yes|no) #REQUIRED
       is-exclusive (yes|no) #REQUIRED
       is-dependent (yes|no) #REQUIRED
-      multi-value-implementation (list|vector) "list"
   >
   <!ELEMENT method (method-implementation*)>
   <!ATTLIST method
@@ -81,7 +78,12 @@
 
 <oks-schema>
 
-<info name="" type="" num-of-includes="0" num-of-items="1" oks-format="schema" oks-version="oks-06-06-07 built &quot;May  2 2013&quot;" created-by="rhauser" created-on="msu-pc7.cern.ch" creation-time="20130502T084342" last-modified-by="rhauser" last-modified-on="msu-pc7.cern.ch" last-modification-time="20130502T084544"/>
+<info name="" type="" num-of-items="2" oks-format="schema" oks-version="oks-06-09-02 built &quot;Nov  2 2015&quot;" created-by="rhauser" created-on="msu-pc7.cern.ch" creation-time="20130502T084342" last-modified-by="rhauser" last-modified-on="msu-pc7.cern.ch" last-modification-time="20151102T125421"/>
+
+<include>
+ <file path="is/is.xml"/>
+</include>
+
 
  <class name="MsgInfo">
   <superclass name="Info"/>
@@ -90,4 +92,11 @@
   <attribute name="Port" description="Port number" type="u16" is-not-null="yes"/>
  </class>
 
+ <class name="MultiCastGroup">
+  <superclass name="Info"/>
+  <attribute name="Partition" description="The name of the partition where this multicast group is used." type="string" is-not-null="yes"/>
+  <attribute name="MulticastAddress" description="The address of the multicast group. It must be in the 224.*.*.* range." type="string" range="224\.[0-9]+\.[0-9]+\.[0-9]+" init-value="224.200.100.100" is-not-null="yes"/>
+  <attribute name="MulticastNetwork" description="The network address where multicast packages are being sent. This determines the outgoing interface and should be the network part of the " type="string" range="[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)?" init-value="10.149.0.0" is-not-null="yes"/>
+ </class>
+
 </oks-schema>
diff --git a/src/MultiCastGroup.h b/src/MultiCastGroup.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea755561c5cd2239a4b263ffdf23f7642a5d4b22
--- /dev/null
+++ b/src/MultiCastGroup.h
@@ -0,0 +1,105 @@
+#ifndef MULTICASTGROUP_H
+#define MULTICASTGROUP_H
+
+#include <is/info.h>
+
+#include <string>
+#include <ostream>
+
+
+// <<BeginUserCode>>
+
+// <<EndUserCode>>
+/**
+ * 
+ * @author  generated by the IS tool
+ * @version 04/11/15
+ */
+
+class MultiCastGroup : public ISInfo {
+public:
+
+    /**
+     * The name of the partition where this multicast group is used.
+     */
+    std::string                   Partition;
+
+    /**
+     * The address of the multicast group. It must be in the 224.*.*.* range.
+     */
+    std::string                   MulticastAddress;
+
+    /**
+     * The network address where multicast packages are being sent. This determines the outgoing interface and should be the network part of the 
+     */
+    std::string                   MulticastNetwork;
+
+
+    static const ISType & type() {
+	static const ISType type_ = MultiCastGroup( ).ISInfo::type();
+	return type_;
+    }
+
+    virtual std::ostream & print( std::ostream & out ) const {
+	ISInfo::print( out );
+	out << std::endl;
+	out << "Partition: " << Partition << "\t// The name of the partition where this multicast group is used." << std::endl;
+	out << "MulticastAddress: " << MulticastAddress << "\t// The address of the multicast group. It must be in the 224.*.*.* range." << std::endl;
+	out << "MulticastNetwork: " << MulticastNetwork << "\t// The network address where multicast packages are being sent. This determines the outgoing interface and should be the network part of the ";
+	return out;
+    }
+
+    MultiCastGroup( )
+      : ISInfo( "MultiCastGroup" )
+    {
+	initialize();
+    }
+
+    ~MultiCastGroup(){
+
+// <<BeginUserCode>>
+
+// <<EndUserCode>>
+    }
+
+protected:
+    MultiCastGroup( const std::string & type )
+      : ISInfo( type )
+    {
+	initialize();
+    }
+
+    void publishGuts( ISostream & out ){
+	out << Partition << MulticastAddress << MulticastNetwork;
+    }
+
+    void refreshGuts( ISistream & in ){
+	in >> Partition >> MulticastAddress >> MulticastNetwork;
+    }
+
+private:
+    void initialize()
+    {
+	MulticastAddress = "224.200.100.100";
+	MulticastNetwork = "10.149.0.0";
+
+// <<BeginUserCode>>
+
+// <<EndUserCode>>
+    }
+
+
+// <<BeginUserCode>>
+
+// <<EndUserCode>>
+};
+
+// <<BeginUserCode>>
+
+// <<EndUserCode>>
+inline std::ostream & operator<<( std::ostream & out, const MultiCastGroup & info ) {
+    info.print( out );
+    return out;
+}
+
+#endif // MULTICASTGROUP_H
diff --git a/src/MultiCastGroupNamed.h b/src/MultiCastGroupNamed.h
new file mode 100644
index 0000000000000000000000000000000000000000..300b23803834a912caf3671257b7c7c6027a5dfc
--- /dev/null
+++ b/src/MultiCastGroupNamed.h
@@ -0,0 +1,105 @@
+#ifndef MULTICASTGROUPNAMED_H
+#define MULTICASTGROUPNAMED_H
+
+#include <is/namedinfo.h>
+
+#include <string>
+#include <ostream>
+
+
+// <<BeginUserCode>>
+
+// <<EndUserCode>>
+/**
+ * 
+ * @author  generated by the IS tool
+ * @version 04/11/15
+ */
+
+class MultiCastGroupNamed : public ISNamedInfo {
+public:
+
+    /**
+     * The name of the partition where this multicast group is used.
+     */
+    std::string                   Partition;
+
+    /**
+     * The address of the multicast group. It must be in the 224.*.*.* range.
+     */
+    std::string                   MulticastAddress;
+
+    /**
+     * The network address where multicast packages are being sent. This determines the outgoing interface and should be the network part of the 
+     */
+    std::string                   MulticastNetwork;
+
+
+    static const ISType & type() {
+	static const ISType type_ = MultiCastGroupNamed( IPCPartition(), "" ).ISInfo::type();
+	return type_;
+    }
+
+    virtual std::ostream & print( std::ostream & out ) const {
+	ISNamedInfo::print( out );
+	out << std::endl;
+	out << "Partition: " << Partition << "\t// The name of the partition where this multicast group is used." << std::endl;
+	out << "MulticastAddress: " << MulticastAddress << "\t// The address of the multicast group. It must be in the 224.*.*.* range." << std::endl;
+	out << "MulticastNetwork: " << MulticastNetwork << "\t// The network address where multicast packages are being sent. This determines the outgoing interface and should be the network part of the ";
+	return out;
+    }
+
+    MultiCastGroupNamed( const IPCPartition & partition, const std::string & name )
+      : ISNamedInfo( partition, name, "MultiCastGroup" )
+    {
+	initialize();
+    }
+
+    ~MultiCastGroupNamed(){
+
+// <<BeginUserCode>>
+
+// <<EndUserCode>>
+    }
+
+protected:
+    MultiCastGroupNamed( const IPCPartition & partition, const std::string & name, const std::string & type )
+      : ISNamedInfo( partition, name, type )
+    {
+	initialize();
+    }
+
+    void publishGuts( ISostream & out ){
+	out << Partition << MulticastAddress << MulticastNetwork;
+    }
+
+    void refreshGuts( ISistream & in ){
+	in >> Partition >> MulticastAddress >> MulticastNetwork;
+    }
+
+private:
+    void initialize()
+    {
+	MulticastAddress = "224.200.100.100";
+	MulticastNetwork = "10.149.0.0";
+
+// <<BeginUserCode>>
+
+// <<EndUserCode>>
+    }
+
+
+// <<BeginUserCode>>
+
+// <<EndUserCode>>
+};
+
+// <<BeginUserCode>>
+
+// <<EndUserCode>>
+inline std::ostream & operator<<( std::ostream & out, const MultiCastGroupNamed & info ) {
+    info.print( out );
+    return out;
+}
+
+#endif // MULTICASTGROUPNAMED_H
diff --git a/src/NameService.cxx b/src/NameService.cxx
index b0763e1a8bdba457e804ab0b0c6e7a8735e0089a..a1c1b3e49d601295ba54a4c21edb72dc2f48b00e 100644
--- a/src/NameService.cxx
+++ b/src/NameService.cxx
@@ -3,10 +3,13 @@
 #include "transport/Interface.h"
 
 #include "MsgInfo.h"
+#include "MultiCastGroup.h"
+#include "MultiCastGroupNamed.h"
 
 #include "is/infostream.h"
 #include "is/infodictionary.h"
 #include "is/serveriterator.h"
+#include "is/infoiterator.h"
 
 #include <algorithm>
 
@@ -346,5 +349,86 @@ namespace daq {
             return boost::asio::ip::address();
         }
 
+        std::string NameService::allocate_multicast_address(const std::string& addr, const std::string& network)
+        {
+            MultiCastGroup group;
+            ISInfoDictionary  dict(m_partition);
+
+            if(addr == "*") {
+
+                // Find potential entry in initial partition
+                ISInfoIterator it(IPCPartition(), "RunParams", MultiCastGroup::type());
+                bool found = false;
+
+                while(it++) {
+                    it.value(group);
+                    if(group.Partition == m_partition.name()) {
+                        // found our partition.
+                        found = true;
+                        break;
+                    }
+                }
+
+                if(!found) {
+                    // allocate a new group.
+
+                    unsigned short    index = 1;
+                    std::string       name_prefix = "RunParams.MultiCast-";
+
+                    group.Partition = m_partition.name();
+                    group.MulticastAddress = std::string("224.100.100.") + boost::lexical_cast<std::string>(index);
+                    group.MulticastNetwork = network;
+
+                    while(!found && index < 256) {
+                        
+                        try {
+                            dict.insert(name_prefix + group.MulticastAddress, group);
+                            found = true;
+                        } catch(...) {
+                            // try next
+                            index++;
+                        }
+                    }
+                }
+                    
+                if(!found) {
+                    // A dynamic address was requested, but we could not allocate one...
+                    throw CannotAllocateMulticast(ERS_HERE);
+                }
+            }    
+
+            ISServerIterator servers(m_partition, m_is_server + ".*");
+            if(servers.entries() == 0) {
+                throw InvalidISServer(ERS_HERE,m_is_server);
+            }
+            while(servers++) {
+                // may throw
+                try {
+                    dict.checkin(std::string(servers.name()) + ".MultiCastAddress", group);
+                } catch(ers::Issue& reason) {
+                    throw InvalidISServer(ERS_HERE, servers.name(), reason);
+                }
+            }
+            
+            return group.MulticastAddress;
+        }
+        
+        std::string NameService::lookup_multicast_address(const std::string& addr) const
+        {
+            if(addr == "*") {
+
+                MultiCastGroupNamed group(m_partition, m_is_server + ".MultiCastAddress");
+                
+                try {
+                    group.checkout();
+                    return group.MulticastAddress;
+                    
+                } catch (ers::Issue& ex) {
+                    throw CannotResolve(ERS_HERE, addr, ex);
+                }
+            }
+
+            return addr;
+        }
     }
 }