private void RemapButtonMapping()
    {
      if (mappingsListView.SelectedIndices.Count != 1)
        return;

      ListViewItem item = mappingsListView.SelectedItems[0];

      List<ButtonMapping> currentMappings = GetCurrentButtonMappings();
      if (currentMappings == null)
        return;

      ButtonMapping toModify = null;
      foreach (ButtonMapping test in currentMappings)
      {
        if (test.KeyCode.Equals(item.SubItems[0].Text, StringComparison.Ordinal))
        {
          toModify = test;
          break;
        }
      }

      if (toModify == null)
        return;

      GetKeyCodeForm getKeyCode = new GetKeyCodeForm();
      getKeyCode.ShowDialog(this);

      string keyCode = getKeyCode.KeyCode;
      if (String.IsNullOrEmpty(keyCode))
        return;

      foreach (ButtonMapping test in currentMappings)
      {
        if (test.KeyCode.Equals(keyCode, StringComparison.Ordinal))
        {
          MessageBox.Show(this,
                          String.Format("{0} is already mapped to {1} ({2})", keyCode, test.Description, test.Command),
                          "Cannot remap", MessageBoxButtons.OK, MessageBoxIcon.Warning);
          return;
        }
      }

      item.SubItems[0].Text = keyCode;

      toModify.KeyCode = keyCode;
    }
    private void NewButtonMapping()
    {
      List<ButtonMapping> currentMappings = GetCurrentButtonMappings();
      if (currentMappings == null)
        return;

      GetKeyCodeForm getKeyCode = new GetKeyCodeForm();
      getKeyCode.ShowDialog(this);

      string keyCode = getKeyCode.KeyCode;
      string deviceName = getKeyCode.DeviceName;

      if (String.IsNullOrEmpty(keyCode))
        return;

      ButtonMappingForm map = null;
      ButtonMapping existing = null;

      foreach (ButtonMapping test in currentMappings)
      {
        if (keyCode.Equals(test.KeyCode, StringComparison.Ordinal))
        {
          existing = test;
          map = new ButtonMappingForm(test.KeyCode, test.Description, test.Command);
          break;
        }
      }

      if (map == null)
      {
        string description = String.Empty;

        // TODO: Implement abstract remote button descriptions.
        if (deviceName.Equals("Abstract", StringComparison.OrdinalIgnoreCase))
        {
          switch (keyCode.ToLowerInvariant())
          {
            case "Red":
              description = "Red teletext button";
              break;
          }
        }

        map = new ButtonMappingForm(keyCode, description, String.Empty);
      }

      if (map.ShowDialog(this) == DialogResult.OK)
      {
        if (existing == null) // Create new mapping
        {
          mappingsListView.Items.Add(
            new ListViewItem(
              new string[] { map.KeyCode, map.Description, map.Command }
              ));

          currentMappings.Add(new ButtonMapping(map.KeyCode, map.Description, map.Command));
        }
        else // Replace existing mapping
        {
          for (int index = 0; index < mappingsListView.Items.Count; index++)
          {
            if (mappingsListView.Items[index].SubItems[0].Text.Equals(map.KeyCode, StringComparison.Ordinal))
            {
              mappingsListView.Items[index].SubItems[1].Text = map.Description;
              mappingsListView.Items[index].SubItems[2].Text = map.Command;
            }
          }

          existing.Description = map.Description;
          existing.Command = map.Command;
        }
      }
    }