gt:         if (vm.getVmInit() != null) {
context: package org.ovirt.engine.core.bll;
  
  import java.lang.reflect.Field;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collection;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Objects;
  import java.util.Set;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  import org.apache.commons.collections.CollectionUtils;
  import org.apache.commons.lang.StringUtils;
  import org.ovirt.engine.core.bll.context.CompensationContext;
  import org.ovirt.engine.core.bll.network.macpoolmanager.MacPoolManagerStrategy;
  import org.ovirt.engine.core.bll.utils.PermissionSubject;
  import org.ovirt.engine.core.bll.utils.VmDeviceUtils;
  import org.ovirt.engine.core.bll.validator.VmValidationUtils;
  import org.ovirt.engine.core.common.AuditLogType;
  import org.ovirt.engine.core.common.FeatureSupported;
  import org.ovirt.engine.core.common.VdcObjectType;
  import org.ovirt.engine.core.common.action.VdcActionType;
  import org.ovirt.engine.core.common.action.VmManagementParametersBase;
  import org.ovirt.engine.core.common.backendinterfaces.BaseHandler;
  import org.ovirt.engine.core.common.businessentities.ActionGroup;
  import org.ovirt.engine.core.common.businessentities.ArchitectureType;
  import org.ovirt.engine.core.common.businessentities.CopyOnNewVersion;
  import org.ovirt.engine.core.common.businessentities.DisplayType;
  import org.ovirt.engine.core.common.businessentities.EditableDeviceOnVmStatusField;
  import org.ovirt.engine.core.common.businessentities.EditableField;
  import org.ovirt.engine.core.common.businessentities.EditableOnVm;
  import org.ovirt.engine.core.common.businessentities.EditableOnVmStatusField;
  import org.ovirt.engine.core.common.businessentities.GraphicsDevice;
  import org.ovirt.engine.core.common.businessentities.GraphicsType;
  import org.ovirt.engine.core.common.businessentities.GuestAgentStatus;
  import org.ovirt.engine.core.common.businessentities.NumaTuneMode;
  import org.ovirt.engine.core.common.businessentities.Snapshot;
  import org.ovirt.engine.core.common.businessentities.Snapshot.SnapshotType;
  import org.ovirt.engine.core.common.businessentities.UsbPolicy;
  import org.ovirt.engine.core.common.businessentities.VDS;
  import org.ovirt.engine.core.common.businessentities.VDSGroup;
  import org.ovirt.engine.core.common.businessentities.VM;
  import org.ovirt.engine.core.common.businessentities.VMStatus;
  import org.ovirt.engine.core.common.businessentities.VmBase;
  import org.ovirt.engine.core.common.businessentities.VmDevice;
  import org.ovirt.engine.core.common.businessentities.VmDeviceGeneralType;
  import org.ovirt.engine.core.common.businessentities.VmDynamic;
  import org.ovirt.engine.core.common.businessentities.VmInit;
  import org.ovirt.engine.core.common.businessentities.VmNumaNode;
  import org.ovirt.engine.core.common.businessentities.VmStatic;
  import org.ovirt.engine.core.common.businessentities.network.VmNetworkInterface;
  import org.ovirt.engine.core.common.businessentities.network.VmNic;
  import org.ovirt.engine.core.common.businessentities.storage.CinderDisk;
  import org.ovirt.engine.core.common.businessentities.storage.Disk;
  import org.ovirt.engine.core.common.businessentities.storage.DiskImage;
  import org.ovirt.engine.core.common.businessentities.storage.DiskInterface;
  import org.ovirt.engine.core.common.config.Config;
  import org.ovirt.engine.core.common.config.ConfigValues;
  import org.ovirt.engine.core.common.errors.EngineError;
  import org.ovirt.engine.core.common.errors.EngineException;
  import org.ovirt.engine.core.common.errors.EngineMessage;
  import org.ovirt.engine.core.common.locks.LockingGroup;
  import org.ovirt.engine.core.common.osinfo.OsRepository;
  import org.ovirt.engine.core.common.queries.NameQueryParameters;
  import org.ovirt.engine.core.common.queries.VdcQueryReturnValue;
  import org.ovirt.engine.core.common.queries.VdcQueryType;
  import org.ovirt.engine.core.common.utils.Pair;
  import org.ovirt.engine.core.common.utils.SimpleDependecyInjector;
  import org.ovirt.engine.core.common.utils.VmDeviceType;
  import org.ovirt.engine.core.common.utils.VmDeviceUpdate;
  import org.ovirt.engine.core.common.vdscommands.SetVmStatusVDSCommandParameters;
  import org.ovirt.engine.core.common.vdscommands.UpdateVmDynamicDataVDSCommandParameters;
  import org.ovirt.engine.core.common.vdscommands.VDSCommandType;
  import org.ovirt.engine.core.compat.Guid;
  import org.ovirt.engine.core.compat.RpmVersion;
  import org.ovirt.engine.core.compat.Version;
  import org.ovirt.engine.core.dal.dbbroker.DbFacade;
  import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogDirector;
  import org.ovirt.engine.core.dal.dbbroker.auditloghandling.AuditLogableBase;
  import org.ovirt.engine.core.dao.VdsDynamicDao;
  import org.ovirt.engine.core.dao.VmInitDao;
  import org.ovirt.engine.core.utils.ObjectIdentityChecker;
  import org.ovirt.engine.core.utils.linq.LinqUtils;
  import org.ovirt.engine.core.utils.linq.Predicate;
  import org.ovirt.engine.core.utils.lock.LockManager;
  import org.ovirt.engine.core.utils.lock.LockManagerFactory;
  import org.ovirt.engine.core.utils.transaction.TransactionMethod;
  import org.ovirt.engine.core.utils.transaction.TransactionSupport;
  import org.ovirt.engine.core.vdsbroker.ResourceManager;
  import org.slf4j.Logger;
  import org.slf4j.LoggerFactory;
  
  public class VmHandler {
  
      private static ObjectIdentityChecker updateVmsStatic;
      private static OsRepository osRepository;
  
      private static final Logger log = LoggerFactory.getLogger(VmHandler.class);
  
      private static Set<VdcActionType> COMMANDS_ALLOWED_ON_EXTERNAL_VMS = new HashSet<>();
      private static Set<VdcActionType> COMMANDS_ALLOWED_ON_HOSTED_ENGINE = new HashSet<>();
      /**
       * Initialize static list containers, for identity and permission check. The initialization should be executed
       * before calling ObjectIdentityChecker.
       *
       * @see Backend#initHandlers
       */
      public static void init() {
          Class<?>[] inspectedClassNames = new Class<?>[] {
                  VmBase.class,
                  VM.class,
                  VmStatic.class,
                  VmDynamic.class,
                  VmManagementParametersBase.class };
  
          osRepository = SimpleDependecyInjector.getInstance().get(OsRepository.class);
  
          updateVmsStatic =
                  new ObjectIdentityChecker(VmHandler.class, Arrays.asList(inspectedClassNames));
  
          for (Pair<EditableField, Field> pair : BaseHandler.extractAnnotatedFields(EditableField.class,
                  (inspectedClassNames))) {
              updateVmsStatic.AddPermittedFields(pair.getSecond().getName());
          }
  
          for (Pair<EditableOnVm, Field> pair : BaseHandler.extractAnnotatedFields(EditableOnVm.class, inspectedClassNames)) {
              updateVmsStatic.AddPermittedFields(pair.getSecond().getName());
          }
  
          for (Pair<EditableOnVmStatusField, Field> pair : BaseHandler.extractAnnotatedFields(EditableOnVmStatusField.class,
                  inspectedClassNames)) {
              updateVmsStatic.AddField(Arrays.asList(pair.getFirst().statuses()), pair.getSecond().getName());
              if (pair.getFirst().isHotsetAllowed()) {
                  updateVmsStatic.AddHotsetFields(pair.getSecond().getName());
              }
          }
  
          for (Pair<EditableDeviceOnVmStatusField, Field> pair : BaseHandler.extractAnnotatedFields(EditableDeviceOnVmStatusField.class,
                  inspectedClassNames)) {
              updateVmsStatic.AddField(Arrays.asList(pair.getFirst().statuses()), pair.getSecond().getName());
          }
  
          COMMANDS_ALLOWED_ON_EXTERNAL_VMS.add(VdcActionType.MigrateVm);
          COMMANDS_ALLOWED_ON_EXTERNAL_VMS.add(VdcActionType.MigrateVmToServer);
          COMMANDS_ALLOWED_ON_EXTERNAL_VMS.add(VdcActionType.InternalMigrateVm);
          COMMANDS_ALLOWED_ON_EXTERNAL_VMS.add(VdcActionType.CancelMigrateVm);
          COMMANDS_ALLOWED_ON_EXTERNAL_VMS.add(VdcActionType.SetVmTicket);
          COMMANDS_ALLOWED_ON_EXTERNAL_VMS.add(VdcActionType.VmLogon);
          COMMANDS_ALLOWED_ON_EXTERNAL_VMS.add(VdcActionType.StopVm);
          COMMANDS_ALLOWED_ON_EXTERNAL_VMS.add(VdcActionType.ShutdownVm);
          COMMANDS_ALLOWED_ON_EXTERNAL_VMS.add(VdcActionType.RemoveVm);
          COMMANDS_ALLOWED_ON_EXTERNAL_VMS.add(VdcActionType.RebootVm);
          COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.MigrateVm);
          COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.MigrateVmToServer);
          COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.InternalMigrateVm);
          COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.CancelMigrateVm);
          COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.SetVmTicket);
          COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.VmLogon);
          COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.UpdateVm);
          COMMANDS_ALLOWED_ON_HOSTED_ENGINE.add(VdcActionType.RemoveVm);
      }
  
      public static boolean isUpdateValid(VmStatic source, VmStatic destination, VMStatus status) {
          return updateVmsStatic.IsUpdateValid(source, destination, status);
      }
  
      public static List<String> getChangedFieldsForStatus(VmStatic source, VmStatic destination, VMStatus status) {
          return updateVmsStatic.getChangedFieldsForStatus(source, destination, status);
      }
  
      public static boolean isUpdateValid(VmStatic source, VmStatic destination, VMStatus status, boolean hotsetEnabled) {
          return updateVmsStatic.IsUpdateValid(source, destination, status, hotsetEnabled);
      }
  
      public static boolean isUpdateValid(VmStatic source, VmStatic destination) {
          return updateVmsStatic.IsUpdateValid(source, destination);
      }
  
      public static boolean isUpdateValidForVmDevice(String fieldName, VMStatus status) {
          return updateVmsStatic.IsFieldUpdatable(status, fieldName, null);
      }
  
      public static boolean copyNonEditableFieldsToDestination(VmStatic source, VmStatic destination, boolean hotSetEnabled) {
          return updateVmsStatic.copyNonEditableFieldsToDestination(source, destination, hotSetEnabled);
      }
  
      /**
       * Verifies the add vm command .
       *
       * @param reasons
       *            The reasons.
       * @param nicsCount
       *            How many vNICs need to be allocated.
       * @return
       */
      public static boolean verifyAddVm(List<String> reasons,
              int nicsCount,
              int vmPriority,
              MacPoolManagerStrategy macPool) {
          boolean returnValue = true;
          if (macPool.getAvailableMacsCount() < nicsCount) {
              if (reasons != null) {
                  reasons.add(EngineMessage.MAC_POOL_NOT_ENOUGH_MAC_ADDRESSES.toString());
              }
              returnValue = false;
          } else if (!VmTemplateCommand.isVmPriorityValueLegal(vmPriority, reasons)) {
              returnValue = false;
          }
          return returnValue;
      }
  
      /**
       * Checks if VM with same name exists in the given DC. If no DC provided, check all VMs in the database.
       */
      public static boolean isVmWithSameNameExistStatic(String vmName, Guid storagePoolId) {
          NameQueryParameters params = new NameQueryParameters(vmName);
          params.setDatacenterId(storagePoolId);
          VdcQueryReturnValue result = Backend.getInstance().runInternalQuery(VdcQueryType.IsVmWithSameNameExist, params);
          return (Boolean) (result.getReturnValue());
      }
  
      /**
       * Lock the VM in a new transaction, saving compensation data of the old status.
       *
       * @param vm
       *            The VM to lock.
       * @param compensationContext
       *            Used to save the old VM status, for compensation purposes.
       */
      public static void lockVm(final VmDynamic vm, final CompensationContext compensationContext) {
          TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() {
  
              @Override
              public Void runInTransaction() {
                  compensationContext.snapshotEntityStatus(vm);
                  lockVm(vm.getId());
                  compensationContext.stateChanged();
                  return null;
              }
          });
      }
  
      /**
       * Check VM status before locking it, If VM status is not down, we throw an exception.
       *
       * @param status
       *            - The status of the VM
       */
      private static void checkStatusBeforeLock(VMStatus status) {
          if (status == VMStatus.ImageLocked) {
              log.error("VM status cannot change to image locked, since it is already locked");
              throw new EngineException(EngineError.IRS_IMAGE_STATUS_ILLEGAL);
          }
      }
  
      /**
       * Lock VM after check its status, If VM status is locked, we throw an exception.
       *
       * @param vmId
       *            - The ID of the VM.
       */
      public static void checkStatusAndLockVm(Guid vmId) {
          VmDynamic vmDynamic = DbFacade.getInstance().getVmDynamicDao().get(vmId);
          checkStatusBeforeLock(vmDynamic.getStatus());
          lockVm(vmId);
      }
  
      /**
       * Lock VM with compensation, after checking its status, If VM status is locked, we throw an exception.
       *
       * @param vmId
       *            - The ID of the VM, which we want to lock.
       * @param compensationContext
       *            - Used to save the old VM status for compensation purposes.
       */
      public static void checkStatusAndLockVm(Guid vmId, CompensationContext compensationContext) {
          VmDynamic vmDynamic = DbFacade.getInstance().getVmDynamicDao().get(vmId);
          checkStatusBeforeLock(vmDynamic.getStatus());
          lockVm(vmDynamic, compensationContext);
      }
  
      public static void lockVm(Guid vmId) {
          Backend.getInstance()
                  .getResourceManager()
                  .RunVdsCommand(VDSCommandType.SetVmStatus,
                          new SetVmStatusVDSCommandParameters(vmId, VMStatus.ImageLocked));
      }
  
      /**
       * Unlock the VM in a new transaction, saving compensation data of the old status.
       *
       * @param vm
       *            The VM to unlock.
       * @param compensationContext
       *            Used to save the old VM status, for compensation purposes.
       */
      public static void unlockVm(final VM vm, final CompensationContext compensationContext) {
          TransactionSupport.executeInNewTransaction(new TransactionMethod<Void>() {
  
              @Override
              public Void runInTransaction() {
                  compensationContext.snapshotEntityStatus(vm.getDynamicData());
                  unLockVm(vm);
                  compensationContext.stateChanged();
                  return null;
              }
          });
      }
  
      public static void unLockVm(VM vm) {
          Backend.getInstance()
                  .getResourceManager()
                  .RunVdsCommand(VDSCommandType.SetVmStatus,
                          new SetVmStatusVDSCommandParameters(vm.getId(), VMStatus.Down));
          vm.setStatus(VMStatus.Down);
      }
  
      public static void updateDisksFromDb(VM vm) {
          List<Disk> imageList = DbFacade.getInstance().getDiskDao().getAllForVm(vm.getId());
          vm.clearDisks();
          updateDisksForVm(vm, imageList);
      }
  
      public static void updateDisksForVm(VM vm, Collection<? extends Disk> disks) {
          for (Disk disk : disks) {
              if (disk.isAllowSnapshot() && !disk.isDiskSnapshot()) {
                  DiskImage image = (DiskImage) disk;
                  vm.getDiskMap().put(image.getId(), image);
                  vm.getDiskList().add(image);
              } else {
                  vm.getDiskMap().put(disk.getId(), disk);
              }
          }
      }
  
      /**
       * Fetch VmInit from Database
       * @param vm VmBase to set the VmInit into
       * @param secure if true don't return any password field
       * We want to set false only when running VM becase the VmInitDao
       * decrypt the password.
       */
      public static void updateVmInitFromDB(VmBase vm, boolean secure) {
          VmInitDao db = DbFacade.getInstance().getVmInitDao();
          vm.setVmInit(db.get(vm.getId()));
          if (vm.getVmInit() != null) {
              if (secure) {
                  vm.getVmInit().setPasswordAlreadyStored(!StringUtils.isEmpty(vm.getVmInit().getRootPassword()));
                  vm.getVmInit().setRootPassword(null);
              } else {
                  vm.getVmInit().setPasswordAlreadyStored(false);
              }
          }
      }
  
      public static void addVmInitToDB(VmBase vm) {
          if (vm.getVmInit() != null) {
              vm.getVmInit().setId(vm.getId());
              VmInitDao db = DbFacade.getInstance().getVmInitDao();
              VmInit oldVmInit = db.get(vm.getId());
              if (oldVmInit == null) {
                  db.save(vm.getVmInit());
              } else {
                  if (vm.getVmInit().isPasswordAlreadyStored()) {
                      // since we are not always returning the password in
                      // updateVmInitFromDB()
                      // method (we don't want to display it in the UI/API) we
                      // don't want to override
                      // the password if the flag is on
                      vm.getVmInit().setRootPassword(oldVmInit.getRootPassword());
                  }
                  db.update(vm.getVmInit());
              }
          }
      }
  
      public static void updateVmInitToDB(VmBase vm) {
  