--- a/net/minecraft/client/settings/KeyBinding.java
+++ b/net/minecraft/client/settings/KeyBinding.java
@@ -15,9 +15,9 @@
 import net.minecraftforge.api.distmarker.OnlyIn;
 
 @OnlyIn(Dist.CLIENT)
-public class KeyBinding implements Comparable<KeyBinding> {
+public class KeyBinding implements Comparable<KeyBinding>, net.minecraftforge.client.extensions.IForgeKeybinding {
    private static final Map<String, KeyBinding> field_74516_a = Maps.newHashMap();
-   private static final Map<InputMappings.Input, KeyBinding> field_74514_b = Maps.newHashMap();
+   private static final net.minecraftforge.client.settings.KeyBindingMap field_74514_b = new net.minecraftforge.client.settings.KeyBindingMap();
    private static final Set<String> field_151473_c = Sets.newHashSet();
    private static final Map<String, Integer> field_193627_d = Util.func_200696_a(Maps.newHashMap(), (p_205215_0_) -> {
       p_205215_0_.put("key.categories.movement", 1);
@@ -36,7 +36,7 @@
    private int field_151474_i;
 
    public static void func_197981_a(InputMappings.Input p_197981_0_) {
-      KeyBinding keybinding = field_74514_b.get(p_197981_0_);
+      KeyBinding keybinding = field_74514_b.lookupActive(p_197981_0_);
       if (keybinding != null) {
          ++keybinding.field_151474_i;
       }
@@ -44,7 +44,7 @@
    }
 
    public static void func_197980_a(InputMappings.Input p_197980_0_, boolean p_197980_1_) {
-      KeyBinding keybinding = field_74514_b.get(p_197980_0_);
+      for (KeyBinding keybinding : field_74514_b.lookupAll(p_197980_0_))
       if (keybinding != null) {
          keybinding.func_225593_a_(p_197980_1_);
       }
@@ -68,10 +68,10 @@
    }
 
    public static void func_74508_b() {
-      field_74514_b.clear();
+      field_74514_b.clearMap();
 
       for(KeyBinding keybinding : field_74516_a.values()) {
-         field_74514_b.put(keybinding.field_74512_d, keybinding);
+         field_74514_b.addKey(keybinding.field_74512_d, keybinding);
       }
 
    }
@@ -86,12 +86,12 @@
       this.field_151472_e = this.field_74512_d;
       this.field_151471_f = p_i47675_4_;
       field_74516_a.put(p_i47675_1_, this);
-      field_74514_b.put(this.field_74512_d, this);
+      field_74514_b.addKey(this.field_74512_d, this);
       field_151473_c.add(p_i47675_4_);
    }
 
    public boolean func_151470_d() {
-      return this.field_74513_e;
+      return this.field_74513_e && getKeyConflictContext().isActive() && getKeyModifier().isActive(getKeyConflictContext());
    }
 
    public String func_151466_e() {
@@ -125,7 +125,13 @@
    }
 
    public int compareTo(KeyBinding p_compareTo_1_) {
-      return this.field_151471_f.equals(p_compareTo_1_.field_151471_f) ? I18n.func_135052_a(this.field_74515_c).compareTo(I18n.func_135052_a(p_compareTo_1_.field_74515_c)) : field_193627_d.get(this.field_151471_f).compareTo(field_193627_d.get(p_compareTo_1_.field_151471_f));
+      if (this.field_151471_f.equals(p_compareTo_1_.field_151471_f)) return I18n.func_135052_a(this.field_74515_c).compareTo(I18n.func_135052_a(p_compareTo_1_.field_74515_c));
+      Integer tCat = field_193627_d.get(this.field_151471_f);
+      Integer oCat = field_193627_d.get(p_compareTo_1_.field_151471_f);
+      if (tCat == null && oCat != null) return 1;
+      if (tCat != null && oCat == null) return -1;
+      if (tCat == null && oCat == null) return I18n.func_135052_a(this.field_151471_f).compareTo(I18n.func_135052_a(p_compareTo_1_.field_151471_f));
+      return  tCat.compareTo(oCat);
    }
 
    public static Supplier<ITextComponent> func_193626_b(String p_193626_0_) {
@@ -136,6 +142,20 @@
    }
 
    public boolean func_197983_b(KeyBinding p_197983_1_) {
+      if (getKeyConflictContext().conflicts(p_197983_1_.getKeyConflictContext()) || p_197983_1_.getKeyConflictContext().conflicts(getKeyConflictContext())) {
+         net.minecraftforge.client.settings.KeyModifier keyModifier = getKeyModifier();
+         net.minecraftforge.client.settings.KeyModifier otherKeyModifier = p_197983_1_.getKeyModifier();
+         if (keyModifier.matches(p_197983_1_.getKey()) || otherKeyModifier.matches(getKey())) {
+            return true;
+         } else if (getKey().equals(p_197983_1_.getKey())) {
+            // IN_GAME key contexts have a conflict when at least one modifier is NONE.
+            // For example: If you hold shift to crouch, you can still press E to open your inventory. This means that a Shift+E hotkey is in conflict with E.
+            // GUI and other key contexts do not have this limitation.
+            return keyModifier == otherKeyModifier ||
+               (getKeyConflictContext().conflicts(net.minecraftforge.client.settings.KeyConflictContext.IN_GAME) &&
+               (keyModifier == net.minecraftforge.client.settings.KeyModifier.NONE || otherKeyModifier == net.minecraftforge.client.settings.KeyModifier.NONE));
+         }
+      }
       return this.field_74512_d.equals(p_197983_1_.field_74512_d);
    }
 
@@ -156,11 +176,13 @@
    }
 
    public ITextComponent func_238171_j_() {
+      return getKeyModifier().getCombinedName(field_74512_d, () -> {
       return this.field_74512_d.func_237520_d_();
+      });
    }
 
    public boolean func_197985_l() {
-      return this.field_74512_d.equals(this.field_151472_e);
+      return this.field_74512_d.equals(this.field_151472_e) && getKeyModifier() == getKeyModifierDefault();
    }
 
    public String func_197982_m() {
@@ -170,4 +192,84 @@
    public void func_225593_a_(boolean p_225593_1_) {
       this.field_74513_e = p_225593_1_;
    }
+
+   /****************** Forge Start *****************************/
+   private net.minecraftforge.client.settings.KeyModifier keyModifierDefault = net.minecraftforge.client.settings.KeyModifier.NONE;
+   private net.minecraftforge.client.settings.KeyModifier keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE;
+   private net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext = net.minecraftforge.client.settings.KeyConflictContext.UNIVERSAL;
+
+   /**
+    * Convenience constructor for creating KeyBindings with keyConflictContext set.
+    */
+   public KeyBinding(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, final InputMappings.Type inputType, final int keyCode, String category) {
+       this(description, keyConflictContext, inputType.func_197944_a(keyCode), category);
+   }
+
+   /**
+    * Convenience constructor for creating KeyBindings with keyConflictContext set.
+    */
+   public KeyBinding(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, InputMappings.Input keyCode, String category) {
+       this(description, keyConflictContext, net.minecraftforge.client.settings.KeyModifier.NONE, keyCode, category);
+   }
+
+   /**
+    * Convenience constructor for creating KeyBindings with keyConflictContext and keyModifier set.
+    */
+   public KeyBinding(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, net.minecraftforge.client.settings.KeyModifier keyModifier, final InputMappings.Type inputType, final int keyCode, String category) {
+       this(description, keyConflictContext, keyModifier, inputType.func_197944_a(keyCode), category);
+   }
+
+   /**
+    * Convenience constructor for creating KeyBindings with keyConflictContext and keyModifier set.
+    */
+   public KeyBinding(String description, net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext, net.minecraftforge.client.settings.KeyModifier keyModifier, InputMappings.Input keyCode, String category) {
+      this.field_74515_c = description;
+      this.field_74512_d = keyCode;
+      this.field_151472_e = keyCode;
+      this.field_151471_f = category;
+      this.keyConflictContext = keyConflictContext;
+      this.keyModifier = keyModifier;
+      this.keyModifierDefault = keyModifier;
+      if (this.keyModifier.matches(keyCode))
+         this.keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE;
+      field_74516_a.put(description, this);
+      field_74514_b.addKey(keyCode, this);
+      field_151473_c.add(category);
+   }
+
+   @Override
+   public InputMappings.Input getKey() {
+       return this.field_74512_d;
+   }
+
+   @Override
+   public void setKeyConflictContext(net.minecraftforge.client.settings.IKeyConflictContext keyConflictContext) {
+       this.keyConflictContext = keyConflictContext;
+   }
+
+   @Override
+   public net.minecraftforge.client.settings.IKeyConflictContext getKeyConflictContext() {
+       return keyConflictContext;
+   }
+
+   @Override
+   public net.minecraftforge.client.settings.KeyModifier getKeyModifierDefault() {
+       return keyModifierDefault;
+   }
+
+   @Override
+   public net.minecraftforge.client.settings.KeyModifier getKeyModifier() {
+       return keyModifier;
+   }
+
+   @Override
+   public void setKeyModifierAndCode(net.minecraftforge.client.settings.KeyModifier keyModifier, InputMappings.Input keyCode) {
+       this.field_74512_d = keyCode;
+       if (keyModifier.matches(keyCode))
+           keyModifier = net.minecraftforge.client.settings.KeyModifier.NONE;
+       field_74514_b.removeKey(this);
+       this.keyModifier = keyModifier;
+       field_74514_b.addKey(keyCode, this);
+   }
+   /****************** Forge End *****************************/
 }
