gt:           if (t != null) {
context: /*
   * IdeaVim - Vim emulator for IDEs based on the IntelliJ platform
   * Copyright (C) 2003-2016 The IdeaVim authors
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
   * the Free Software Foundation, either version 2 of the License, or
   * (at your option) any later version.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
   * GNU General Public License for more details.
   *
   * You should have received a copy of the GNU General Public License
   * along with this program. If not, see <http://www.gnu.org/licenses/>.
   */
  
  package com.maddyhome.idea.vim.group;
  
  import com.google.common.collect.ImmutableList;
  import com.intellij.openapi.actionSystem.AnAction;
  import com.intellij.openapi.diagnostic.Logger;
  import com.intellij.openapi.editor.Editor;
  import com.intellij.openapi.util.text.StringUtil;
  import com.intellij.util.Function;
  import com.intellij.util.containers.ContainerUtil;
  import com.maddyhome.idea.vim.VimPlugin;
  import com.maddyhome.idea.vim.action.motion.mark.MotionGotoFileMarkAction;
  import com.maddyhome.idea.vim.action.motion.search.SearchAgainNextAction;
  import com.maddyhome.idea.vim.action.motion.search.SearchAgainPreviousAction;
  import com.maddyhome.idea.vim.action.motion.search.SearchEntryFwdAction;
  import com.maddyhome.idea.vim.action.motion.search.SearchEntryRevAction;
  import com.maddyhome.idea.vim.action.motion.text.*;
  import com.maddyhome.idea.vim.action.motion.updown.MotionPercentOrMatchAction;
  import com.maddyhome.idea.vim.command.Argument;
  import com.maddyhome.idea.vim.command.Command;
  import com.maddyhome.idea.vim.command.CommandState;
  import com.maddyhome.idea.vim.command.SelectionType;
  import com.maddyhome.idea.vim.common.Register;
  import com.maddyhome.idea.vim.common.TextRange;
  import com.maddyhome.idea.vim.helper.EditorHelper;
  import com.maddyhome.idea.vim.helper.StringHelper;
  import com.maddyhome.idea.vim.option.ListOption;
  import com.maddyhome.idea.vim.option.OptionChangeEvent;
  import com.maddyhome.idea.vim.option.OptionChangeListener;
  import com.maddyhome.idea.vim.option.Options;
  import com.maddyhome.idea.vim.ui.ClipboardHandler;
  import org.jdom.Element;
  import org.jetbrains.annotations.NotNull;
  import org.jetbrains.annotations.Nullable;
  
  import javax.swing.*;
  import java.awt.event.KeyEvent;
  import java.util.*;
  
  /**
   * This group works with command associated with copying and pasting text
   */
  public class RegisterGroup {
    private static final String WRITABLE_REGISTERS = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-*+_/\"";
    private static final String READONLY_REGISTERS = ":.%#=/";
    private static final String RECORDABLE_REGISTER = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final String PLAYBACK_REGISTER = RECORDABLE_REGISTER + "\".*+";
    private static final String VALID_REGISTERS = WRITABLE_REGISTERS + READONLY_REGISTERS;
    private static final List<Character> CLIPBOARD_REGISTERS = ImmutableList.of('*', '+');
    private static final Logger logger = Logger.getInstance(RegisterGroup.class.getName());
  
    private char defaultRegister = '"';
    private char lastRegister = defaultRegister;
    @NotNull private final HashMap<Character, Register> registers = new HashMap<Character, Register>();
    private char recordRegister = 0;
    @Nullable private List<KeyStroke> recordList = null;
  
    public RegisterGroup() {
      final ListOption clipboardOption = Options.getInstance().getListOption(Options.CLIPBOARD);
      if (clipboardOption != null) {
        clipboardOption.addOptionChangeListener(new OptionChangeListener() {
          public void valueChange(OptionChangeEvent event) {
            if (clipboardOption.contains("unnamed")) {
              defaultRegister = '*';
            }
            else if (clipboardOption.contains("unnamedplus")) {
              defaultRegister = '+';
            }
            else {
              defaultRegister = '"';
            }
            lastRegister = defaultRegister;
          }
        });
      }
    }
  
    /**
     * Check to see if the last selected register can be written to.
     */
    public boolean isRegisterWritable() {
      return READONLY_REGISTERS.indexOf(lastRegister) < 0;
    }
  
    /**
     * Store which register the user wishes to work with.
     *
     * @param reg The register name
     * @return true if a valid register name, false if not
     */
    public boolean selectRegister(char reg) {
      if (VALID_REGISTERS.indexOf(reg) != -1) {
        lastRegister = reg;
        if (logger.isDebugEnabled()) logger.debug("register selected: " + lastRegister);
  
        return true;
      }
      else {
        return false;
      }
    }
  
    /**
     * Reset the selected register back to the default register.
     */
    public void resetRegister() {
      lastRegister = defaultRegister;
      logger.debug("register reset");
    }
  
    /**
     * Store text into the last register.
     *
     * @param editor   The editor to get the text from
     * @param range    The range of the text to store
     * @param type     The type of copy
     * @param isDelete is from a delete
     * @return true if able to store the text into the register, false if not
     */
    public boolean storeText(@NotNull Editor editor, @NotNull TextRange range, @NotNull SelectionType type,
                             boolean isDelete) {
      if (isRegisterWritable()) {
        String text = EditorHelper.getText(editor, range);
  
        return storeTextInternal(editor, range, text, type, lastRegister, isDelete);
      }
  
      return false;
    }
  
    public boolean storeTextInternal(@NotNull Editor editor, @NotNull TextRange range, @NotNull String text,
                                     @NotNull SelectionType type, char register, boolean isDelete) {
      // Null register doesn't get saved
      if (lastRegister == '_') return true;
  
      int start = range.getStartOffset();
      int end = range.getEndOffset();
      // Normalize the start and end
      if (start > end) {
        int t = start;
        start = end;
        end = t;
      }
  
      if (type == SelectionType.LINE_WISE && text.length() > 0 && text.charAt(text.length() - 1) != '\n') {
        text = text + '\n';
      }
  
      // If this is an uppercase register, we need to append the text to the corresponding lowercase register
      if (Character.isUpperCase(register)) {
        char lreg = Character.toLowerCase(register);
        Register r = registers.get(new Character(lreg));
        // Append the text if the lowercase register existed
        if (r != null) {
          r.addText(text);
        }
        // Set the text if the lowercase register didn't exist yet
        else {
          registers.put(lreg, new Register(lreg, type, text));
          if (logger.isDebugEnabled()) logger.debug("register '" + register + "' contains: \"" + text + "\"");
        }
      }
      else if (CLIPBOARD_REGISTERS.contains(register)) {
        ClipboardHandler.setClipboardText(text);
      }
      // Put the text in the specified register
      else {
        registers.put(register, new Register(register, type, text));
        if (logger.isDebugEnabled()) logger.debug("register '" + register + "' contains: \"" + text + "\"");
      }
  
      // Also add it to the default register if the default wasn't specified
      if (register != defaultRegister && ".:/".indexOf(register) == -1) {
        registers.put(defaultRegister, new Register(defaultRegister, type, text));
        if (logger.isDebugEnabled()) logger.debug("register '" + register + "' contains: \"" + text + "\"");
      }
  
      if (isDelete) {
        boolean smallInlineDeletion = type == SelectionType.CHARACTER_WISE &&
                         editor.offsetToLogicalPosition(start).line == editor.offsetToLogicalPosition(end).line;
  
        // Deletes go into numbered registers only if text is smaller than a line, register is used or it's a special case
        if (!smallInlineDeletion || register != defaultRegister || isSmallDeletionSpecialCase(editor)) {
          // Old 1 goes to 2, etc. Old 8 to 9, old 9 is lost
          for (char d = '8'; d >= '1'; d--) {
            Register t = registers.get(d);
  