diff --git a/source/ChromeDevTools/MasterDevs.ChromeDevTools.csproj b/source/ChromeDevTools/MasterDevs.ChromeDevTools.csproj
index 5c08970b191b5e4cd62f325fcaa6eb4934e51827..c8c40e0002b9fbb8417172315a19559d640a0dcc 100644
--- a/source/ChromeDevTools/MasterDevs.ChromeDevTools.csproj
+++ b/source/ChromeDevTools/MasterDevs.ChromeDevTools.csproj
@@ -880,6 +880,7 @@
     <Compile Include="Protocol\Worker\WorkerCreatedEvent.cs" />
     <Compile Include="Protocol\Worker\WorkerTerminatedEvent.cs" />
     <Compile Include="Serialization\MessageContractResolver.cs" />
+    <Compile Include="SupportedByAttribute.cs" />
   </ItemGroup>
   <ItemGroup>
     <Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
diff --git a/source/ChromeDevTools/SupportedByAttribute.cs b/source/ChromeDevTools/SupportedByAttribute.cs
new file mode 100644
index 0000000000000000000000000000000000000000..73fb8cf2744063a1d1a39c0a33821cbfd0826d7a
--- /dev/null
+++ b/source/ChromeDevTools/SupportedByAttribute.cs
@@ -0,0 +1,24 @@
+using System;
+
+namespace MasterDevs.ChromeDevTools
+{
+    [AttributeUsage(AttributeTargets.Class)]
+    public class SupportedByAttribute : Attribute
+    {
+        public SupportedByAttribute(string browser)
+        {
+            if (browser == null)
+            {
+                throw new ArgumentNullException(nameof(browser));
+            }
+
+            this.Browser = browser;
+        }
+
+        public string Browser
+        {
+            get;
+            set;
+        }
+    }
+}
diff --git a/source/ProtocolGenerator/NameEqualityComparer.cs b/source/ProtocolGenerator/NameEqualityComparer.cs
index 75287f9b470f9188e6efe7a6baeb0d8e4caa38d6..e79082f11b98ea3af39ef7f0f200fea1e197c693 100644
--- a/source/ProtocolGenerator/NameEqualityComparer.cs
+++ b/source/ProtocolGenerator/NameEqualityComparer.cs
@@ -6,12 +6,13 @@ using System.Threading.Tasks;
 
 namespace MasterDevs.ChromeDevTools.ProtocolGenerator
 {
-    class NameEqualityComparer : EqualityComparer<ProtocolItem>
+    class NameEqualityComparer<T> : EqualityComparer<T>
+        where T : ProtocolItem
     {
-        public static NameEqualityComparer Instance
-        { get; } = new NameEqualityComparer();
+        public static NameEqualityComparer<T> Instance
+        { get; } = new NameEqualityComparer<T>();
 
-        public override bool Equals(ProtocolItem x, ProtocolItem y)
+        public override bool Equals(T x, T y)
         {
             if (x == null || y == null)
             {
@@ -21,7 +22,7 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
             return string.Equals(x.Name, y.Name, StringComparison.OrdinalIgnoreCase);
         }
 
-        public override int GetHashCode(ProtocolItem obj)
+        public override int GetHashCode(T obj)
         {
             if (obj == null)
             {
diff --git a/source/ProtocolGenerator/Program.cs b/source/ProtocolGenerator/Program.cs
index a375f348ed37b2d110695d0c72129ea79f820b1b..3a577f4c716d3d391cb3eccfb9c037a40cc4dfdf 100644
--- a/source/ProtocolGenerator/Program.cs
+++ b/source/ProtocolGenerator/Program.cs
@@ -24,7 +24,6 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
         private static Dictionary<string, List<string>> _DomainEvents = new Dictionary<string, List<string>>();
         private static Dictionary<string, string> _SimpleTypes = new Dictionary<string, string>();
 
-
         private static void Main(string[] args)
         {
             // At this point in time, we only process the most recent Chrome
@@ -208,10 +207,10 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
             var parameters = evnt.Parameters;
             // ignoreing "handlers" ... i'm not sure what they are for yet
             _DomainEvents[domainDirectoryInfo.Name].Add(eventName);
-            WriteEvent(domainDirectoryInfo, eventName, description, parameters);
+            WriteEvent(domainDirectoryInfo, eventName, description, parameters, evnt.SupportedBy);
         }
 
-        private static void WriteEvent(DirectoryInfo domainDirectoryInfo, string eventName, string description, IEnumerable<Property> parameters)
+        private static void WriteEvent(DirectoryInfo domainDirectoryInfo, string eventName, string description, IEnumerable<Property> parameters, IEnumerable<string> supportedBy)
         {
             var className = ToCamelCase(eventName) + EventSubclass;
             var sb = new StringBuilder();
@@ -230,6 +229,7 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
             }
             sb.AppendFormat("\t[{0}({1}.{2}.{3})]", EventAttribute, ProtocolNameClass, domainDirectoryInfo.Name, ToCamelCase(eventName));
             sb.AppendLine();
+            WriteSupportedBy(sb, supportedBy);
             sb.AppendFormat("\tpublic class {0}", className);
             sb.AppendLine();
             sb.AppendLine("\t{");
@@ -250,11 +250,11 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
             var parameters = command.Parameters;
             var returnObject = command.Returns;
             _DomainCommands[domainDirectoryInfo.Name].Add(commandName);
-            WriteCommand(domainDirectoryInfo, commandName, description, parameters);
-            WriteCommandResponse(domainDirectoryInfo, commandName, description, returnObject);
+            WriteCommand(domainDirectoryInfo, commandName, description, parameters, command.SupportedBy);
+            WriteCommandResponse(domainDirectoryInfo, commandName, description, returnObject, command.SupportedBy);
         }
 
-        private static void WriteCommandResponse(DirectoryInfo domainDirectoryInfo, string commandName, string description, IEnumerable<Property> returnObject)
+        private static void WriteCommandResponse(DirectoryInfo domainDirectoryInfo, string commandName, string description, IEnumerable<Property> returnObject, IEnumerable<string> supportedBy)
         {
             var className = ToCamelCase(commandName) + CommandResponseSubclass;
             var sb = new StringBuilder();
@@ -274,6 +274,7 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
             }
             sb.AppendFormat("\t[{0}({1}.{2}.{3})]", CommandResponseAttribute, ProtocolNameClass, domainDirectoryInfo.Name, ToCamelCase(commandName));
             sb.AppendLine();
+            WriteSupportedBy(sb, supportedBy);
             sb.AppendFormat("\tpublic class {0}", className);
             sb.AppendLine();
             sb.AppendLine("\t{");
@@ -286,7 +287,7 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
             WriteToFile(domainDirectoryInfo, className, sb.ToString());
         }
 
-        private static void WriteCommand(DirectoryInfo domainDirectoryInfo, string commandName, string description, IEnumerable<Property> parameters)
+        private static void WriteCommand(DirectoryInfo domainDirectoryInfo, string commandName, string description, IEnumerable<Property> parameters, IEnumerable<string> supportedBy)
         {
             var className = ToCamelCase(commandName) + CommandSubclass;
             var sb = new StringBuilder();
@@ -307,6 +308,7 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
             }
             sb.AppendFormat("\t[{0}({1}.{2}.{3})]", CommandAttribute, ProtocolNameClass, domainDirectoryInfo.Name, ToCamelCase(commandName));
             sb.AppendLine();
+            WriteSupportedBy(sb, supportedBy);
             sb.AppendFormat("\tpublic class {0}", className);
             sb.AppendLine();
             sb.AppendLine("\t{");
@@ -349,6 +351,7 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
             sb.AppendFormat("\t/// {0}", type.Description);
             sb.AppendLine();
             sb.AppendLine("\t/// </summary>");
+            WriteSupportedBy(sb, type);
             sb.AppendFormat("\tpublic class {0}", className);
             sb.AppendLine();
             sb.AppendLine("\t{");
@@ -479,6 +482,7 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
             sb.AppendFormat("\t/// {0}", type.Description);
             sb.AppendLine();
             sb.AppendLine("\t/// </summary>");
+            WriteSupportedBy(sb, type);
             sb.AppendFormat("\tpublic enum {0}", enumName);
             sb.AppendLine();
             sb.AppendLine("\t{");
@@ -492,6 +496,19 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
             WriteToFile(domainDirectoryInfo, enumName, sb.ToString());
         }
 
+        private static void WriteSupportedBy(StringBuilder sb, ProtocolItem type)
+        {
+            WriteSupportedBy(sb, type.SupportedBy);
+        }
+
+        private static void WriteSupportedBy(StringBuilder sb, IEnumerable<string> supportedBy)
+        {
+            foreach(var browser in supportedBy)
+            {
+                sb.AppendLine($"\t[SupportedBy(\"{browser}\")");
+            }
+        }
+
         private static void WriteToFile(DirectoryInfo domainDirectoryInfo, string fileName, string fileContents)
         {
             var fullPath = Path.Combine(domainDirectoryInfo.FullName, fileName + ".cs");
diff --git a/source/ProtocolGenerator/ProtocolMerger.cs b/source/ProtocolGenerator/ProtocolMerger.cs
index cbdd168240d1c77187ff915a637d9ad0665c0391..b28270c05d19f0a34272a8ea4ebf22e55a4eec19 100644
--- a/source/ProtocolGenerator/ProtocolMerger.cs
+++ b/source/ProtocolGenerator/ProtocolMerger.cs
@@ -1,5 +1,6 @@
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
@@ -12,64 +13,50 @@ namespace MasterDevs.ChromeDevTools.ProtocolGenerator
         {
             foreach (var domain in source.Domains)
             {
-                if (!target.Domains.Contains(domain, NameEqualityComparer.Instance))
+                if (!target.Domains.Contains(domain, NameEqualityComparer<Domain>.Instance))
                 {
                     target.Domains.Add(domain);
                 }
                 else
                 {
-                    Merge(source, domain, target.Domains.Single(t => NameEqualityComparer.Instance.Equals(domain, t)));
+                    Merge(source, domain, target.Domains.Single(t => NameEqualityComparer<Domain>.Instance.Equals(domain, t)));
                 }
             }
         }
 
         static void Merge(Protocol protocol, Domain source, Domain target)
         {
-            foreach (var command in source.Commands)
+            Merge(protocol, source, source.Commands, target.Commands);
+            Merge(protocol, source, source.Events, target.Events);
+            Merge(protocol, source, source.Types, target.Types);
+        }
+
+        static void Merge<T>(Protocol protocol, Domain domain, Collection<T> source, Collection<T> target)
+            where T : ProtocolItem
+        {
+            foreach (var item in source)
             {
-                if (!target.Commands.Contains(command, NameEqualityComparer.Instance))
+                if (!target.Contains(item, NameEqualityComparer<T>.Instance))
                 {
-                    target.Commands.Add(command);
+                    target.Add(item);
                 }
                 else
                 {
-                    var targetCommand = target.Commands.Single(t => NameEqualityComparer.Instance.Equals(command, t));
+                    var targetItem = target.Single(t => NameEqualityComparer<T>.Instance.Equals(item, t));
 
-                    if(!targetCommand.Equals(command))
+                    if (!targetItem.Equals(item))
                     {
-                        Console.WriteLine($"{protocol.Alias};{source.Name};{command.Name};{command};{targetCommand}");
+                        Console.WriteLine($"{protocol.Alias};{domain.Name};{item.Name};{item};{targetItem};{typeof(T).Name}");
                     }
                     else
                     {
-                        foreach (var v in command.SupportedBy)
+                        foreach (var v in item.SupportedBy)
                         {
-                            targetCommand.SupportedBy.Add(v);
+                            targetItem.SupportedBy.Add(v);
                         }
                     }
                 }
             }
-
-            foreach (var @event in source.Events)
-            {
-                if (!target.Events.Contains(@event, NameEqualityComparer.Instance))
-                {
-                    target.Events.Add(@event);
-                }
-                else
-                {
-                }
-            }
-
-            foreach (var type in source.Types)
-            {
-                if (!target.Types.Contains(type, NameEqualityComparer.Instance))
-                {
-                    target.Types.Add(type);
-                }
-                else
-                {
-                }
-            }
         }
     }
 }