@nmittler - FYI :)

https://github.com/netty/netty/pull/3984#discussion_r34911766

PrimitiveCollections should apply for all "scripted" types
Currently the PrimitiveCollections class has an implementation of `EmptyMap` and `UnmodifiableMap` only for the `int` variant of the primitive map.  These objects should be templatized like the other primitive map types.

codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2FrameWriter.java common/src/main/java/io/netty/util/collection/package-info.java common/src/main/java/io/netty/util/collection/PrimitiveCollections.java
codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2FrameWriter.java common/src/main/templates/io/netty/util/collection/KCollections.template
diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java
index c437282f62e..51b38c8b7eb 100644
--- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java
+++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2Connection.java
@@ -34,9 +34,9 @@
 import static io.netty.util.internal.ObjectUtil.checkNotNull;
 import io.netty.buffer.ByteBuf;
 import io.netty.handler.codec.http2.Http2Stream.State;
+import io.netty.util.collection.IntCollections;
 import io.netty.util.collection.IntObjectHashMap;
 import io.netty.util.collection.IntObjectMap;
-import io.netty.util.collection.PrimitiveCollections;
 import io.netty.util.internal.EmptyArrays;
 import io.netty.util.internal.PlatformDependent;
 import io.netty.util.internal.SystemPropertyUtil;
@@ -292,7 +292,7 @@ private class DefaultStream implements Http2Stream {
         private State state;
         private short weight = DEFAULT_PRIORITY_WEIGHT;
         private DefaultStream parent;
-        private IntObjectMap<DefaultStream> children = PrimitiveCollections.emptyIntObjectMap();
+        private IntObjectMap<DefaultStream> children = IntCollections.emptyMap();
         private int totalChildWeights;
         private int prioritizableForTree = 1;
         private boolean resetSent;
@@ -539,7 +539,7 @@ private boolean isPrioritizable() {
         }
 
         private void initChildrenIfEmpty() {
-            if (children == PrimitiveCollections.<DefaultStream>emptyIntObjectMap()) {
+            if (children == IntCollections.<DefaultStream>emptyMap()) {
                 initChildren();
             }
         }
diff --git a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2FrameWriter.java b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2FrameWriter.java
index 20fc26baa29..628703b571f 100644
--- a/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2FrameWriter.java
+++ b/codec-http2/src/main/java/io/netty/handler/codec/http2/DefaultHttp2FrameWriter.java
@@ -59,7 +59,6 @@
 import io.netty.channel.ChannelPromise;
 import io.netty.handler.codec.http2.Http2CodecUtil.SimpleChannelPromiseAggregator;
 import io.netty.handler.codec.http2.Http2FrameWriter.Configuration;
-import io.netty.util.collection.CharObjectMap;
 
 /**
  * A {@link Http2FrameWriter} that supports all frame types defined by the HTTP/2 specification.
@@ -213,7 +212,7 @@ public ChannelFuture writeSettings(ChannelHandlerContext ctx, Http2Settings sett
             int payloadLength = SETTING_ENTRY_LENGTH * settings.size();
             ByteBuf buf = ctx.alloc().buffer(FRAME_HEADER_LENGTH + settings.size() * SETTING_ENTRY_LENGTH);
             writeFrameHeaderInternal(buf, payloadLength, SETTINGS, new Http2Flags(), 0);
-            for (CharObjectMap.PrimitiveEntry<Long> entry : settings.entries()) {
+            for (Http2Settings.PrimitiveEntry<Long> entry : settings.entries()) {
                 writeUnsignedShort(entry.key(), buf);
                 writeUnsignedInt(entry.value(), buf);
             }
diff --git a/common/src/main/java/io/netty/util/collection/package-info.java b/common/src/main/java/io/netty/util/collection/package-info.java
deleted file mode 100644
index b5f6029edb4..00000000000
--- a/common/src/main/java/io/netty/util/collection/package-info.java
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * Copyright 2014 The Netty Project
- *
- * The Netty Project licenses this file to you under the Apache License,
- * version 2.0 (the "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at:
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
- * License for the specific language governing permissions and limitations
- * under the License.
- */
-
-/**
- * Utility classes for commonly used collections.
- */
-package io.netty.util.collection;
diff --git a/common/src/main/java/io/netty/util/collection/PrimitiveCollections.java b/common/src/main/templates/io/netty/util/collection/KCollections.template
similarity index 78%
rename from common/src/main/java/io/netty/util/collection/PrimitiveCollections.java
rename to common/src/main/templates/io/netty/util/collection/KCollections.template
index 4cf1f53623b..a5a5534e412 100644
--- a/common/src/main/java/io/netty/util/collection/PrimitiveCollections.java
+++ b/common/src/main/templates/io/netty/util/collection/KCollections.template
@@ -22,47 +22,46 @@
 import java.util.Set;
 
 /**
- * Utility methods for primitive collections.
+ * Utilities for @k@-based primitive collections.
  */
-public final class PrimitiveCollections {
+public final class @K@Collections {
 
-    private static final IntObjectMap<Object> EMPTY_INT_OBJECT_MAP = new EmptyIntObjectMap();
+    private static final @K@ObjectMap<Object> EMPTY_MAP = new EmptyMap();
 
-    private PrimitiveCollections() {
+    private @K@Collections() {
     }
 
     /**
-     * Returns an unmodifiable empty {@link IntObjectMap}.
+     * Returns an unmodifiable empty {@link @K@ObjectMap}.
      */
     @SuppressWarnings("unchecked")
-    public static <V> IntObjectMap<V> emptyIntObjectMap() {
-        return (IntObjectMap<V>) EMPTY_INT_OBJECT_MAP;
+    public static <V> @K@ObjectMap<V> emptyMap() {
+        return (@K@ObjectMap<V>) EMPTY_MAP;
     }
 
     /**
      * Creates an unmodifiable wrapper around the given map.
      */
-    public static <V> IntObjectMap<V> unmodifiableIntObjectMap(final IntObjectMap<V> map) {
-        return new UnmodifiableIntObjectMap<V>(map);
+    public static <V> @K@ObjectMap<V> unmodifiableMap(final @K@ObjectMap<V> map) {
+        return new UnmodifiableMap<V>(map);
     }
 
     /**
      * An empty map. All operations that attempt to modify the map are unsupported.
      */
-    private static final class EmptyIntObjectMap implements IntObjectMap<Object> {
-
+    private static final class EmptyMap implements @K@ObjectMap<Object> {
         @Override
-        public Object get(int key) {
+        public Object get(@k@ key) {
             return null;
         }
 
         @Override
-        public Object put(int key, Object value) {
+        public Object put(@k@ key, Object value) {
             throw new UnsupportedOperationException("put");
         }
 
         @Override
-        public Object remove(int key) {
+        public Object remove(@k@ key) {
             return null;
         }
 
@@ -87,12 +86,12 @@ public void clear() {
         }
 
         @Override
-        public Set<Integer> keySet() {
+        public Set<@O@> keySet() {
             return Collections.emptySet();
         }
 
         @Override
-        public boolean containsKey(int key) {
+        public boolean containsKey(@k@ key) {
             return false;
         }
 
@@ -112,7 +111,7 @@ public Object get(Object key) {
         }
 
         @Override
-        public Object put(Integer key, Object value) {
+        public Object put(@O@ key, Object value) {
             throw new UnsupportedOperationException();
         }
 
@@ -122,7 +121,7 @@ public Object remove(Object key) {
         }
 
         @Override
-        public void putAll(Map<? extends Integer, ?> m) {
+        public void putAll(Map<? extends @O@, ?> m) {
             throw new UnsupportedOperationException();
         }
 
@@ -132,39 +131,39 @@ public Collection<Object> values() {
         }
 
         @Override
-        public Set<Entry<Integer, Object>> entrySet() {
+        public Set<Entry<@O@, Object>> entrySet() {
             return Collections.emptySet();
         }
     }
 
     /**
-     * An unmodifiable wrapper around a {@link IntObjectMap}.
+     * An unmodifiable wrapper around a {@link @K@ObjectMap}.
      *
      * @param <V> the value type stored in the map.
      */
-    private static final class UnmodifiableIntObjectMap<V> implements IntObjectMap<V> {
-        private final IntObjectMap<V> map;
-        private Set<Integer> keySet;
-        private Set<Entry<Integer, V>> entrySet;
+    private static final class UnmodifiableMap<V> implements @K@ObjectMap<V> {
+        private final @K@ObjectMap<V> map;
+        private Set<@O@> keySet;
+        private Set<Entry<@O@, V>> entrySet;
         private Collection<V> values;
         private Iterable<PrimitiveEntry<V>> entries;
 
-        UnmodifiableIntObjectMap(IntObjectMap<V> map) {
+        UnmodifiableMap(@K@ObjectMap<V> map) {
             this.map = map;
         }
 
         @Override
-        public V get(int key) {
+        public V get(@k@ key) {
             return map.get(key);
         }
 
         @Override
-        public V put(int key, V value) {
+        public V put(@k@ key, V value) {
             throw new UnsupportedOperationException("put");
         }
 
         @Override
-        public V remove(int key) {
+        public V remove(@k@ key) {
             throw new UnsupportedOperationException("remove");
         }
 
@@ -184,7 +183,7 @@ public void clear() {
         }
 
         @Override
-        public boolean containsKey(int key) {
+        public boolean containsKey(@k@ key) {
             return map.containsKey(key);
         }
 
@@ -204,7 +203,7 @@ public V get(Object key) {
         }
 
         @Override
-        public V put(Integer key, V value) {
+        public V put(@O@ key, V value) {
             throw new UnsupportedOperationException("put");
         }
 
@@ -214,7 +213,7 @@ public V remove(Object key) {
         }
 
         @Override
-        public void putAll(Map<? extends Integer, ? extends V> m) {
+        public void putAll(Map<? extends @O@, ? extends V> m) {
             throw new UnsupportedOperationException("putAll");
         }
 
@@ -233,7 +232,7 @@ public Iterator<PrimitiveEntry<V>> iterator() {
         }
 
         @Override
-        public Set<Integer> keySet() {
+        public Set<@O@> keySet() {
             if (keySet == null) {
                 keySet = Collections.unmodifiableSet(map.keySet());
             }
@@ -241,7 +240,7 @@ public Set<Integer> keySet() {
         }
 
         @Override
-        public Set<Entry<Integer, V>> entrySet() {
+        public Set<Entry<@O@, V>> entrySet() {
             if (entrySet == null) {
                 entrySet = Collections.unmodifiableSet(map.entrySet());
             }
@@ -289,14 +288,14 @@ public void remove() {
          * Unmodifiable wrapper for an entry.
          */
         private class EntryImpl implements PrimitiveEntry<V> {
-            final PrimitiveEntry<V> entry;
+            private final PrimitiveEntry<V> entry;
 
             EntryImpl(PrimitiveEntry<V> entry) {
                 this.entry = entry;
             }
 
             @Override
-            public int key() {
+            public @k@ key() {
                 return entry.key();
             }
 
