Source:
<code>protected void executeCommand() { if (!getVm().isDown()) { if (FeatureSupported.liveMerge(getVm().getVdsGroupCompatibilityVersion())) { if (!getVm().isQualifiedForSnapshotMerge()) { log.error("Cannot remove VM snapshot. Vm is not Down, Up or Paused"); throw new VdcBLLException(VdcBllErrors.VM_NOT_QUALIFIED_FOR_SNAPSHOT_MERGE); } else if (getVm().getRunOnVds() == null || !getVdsDAO().get(getVm().getRunOnVds()).getLiveMergeSupport()) { log.error("Cannot remove VM snapshot. The host on which VM is running does not support Live Merge"); throw new VdcBLLException(VdcBllErrors.VM_HOST_CANNOT_LIVE_MERGE); } } else { log.error("Cannot remove VM snapshot. Vm is not Down and cluster version does not support Live Merge"); throw new VdcBLLException(VdcBllErrors.IRS_IMAGE_STATUS_ILLEGAL); } } final Snapshot snapshot = getSnapshotDao().get(getParameters().getSnapshotId()); boolean snapshotHasImages = hasImages(); boolean removeSnapshotMemory = isMemoryVolumeRemoveable(snapshot.getMemoryVolume()); if (!snapshotHasImages && !removeSnapshotMemory) { getSnapshotDao().remove(getParameters().getSnapshotId()); setSucceeded(true); return; } lockSnapshot(snapshot); freeLock(); getParameters().setEntityInfo(new EntityInfo(VdcObjectType.VM, getVmId())); boolean useTaskManagerToRemoveMemory = false; if (snapshotHasImages) { removeImages(); if (getSnapshotActionType() == VdcActionType.RemoveSnapshotSingleDiskLive) { persistCommand(getParameters().getParentCommand(), true); useTaskManagerToRemoveMemory = true; } } if (removeSnapshotMemory) { <START> removeMemory(snapshot, useTaskManagerToRemoveMemory, snapshotHasImages); <END> } setSucceeded(true); }</code><technical_language>check if snapshotHasImages is false, if is false, call endVmCommand, instead of implementing in removeMemory method</technical_language>

Target:
protected void executeCommand() { if (!getVm().isDown()) { if (FeatureSupported.liveMerge(getVm().getVdsGroupCompatibilityVersion())) { if (!getVm().isQualifiedForSnapshotMerge()) { log.error("Cannot remove VM snapshot. Vm is not Down, Up or Paused"); throw new VdcBLLException(VdcBllErrors.VM_NOT_QUALIFIED_FOR_SNAPSHOT_MERGE); } else if (getVm().getRunOnVds() == null || !getVdsDAO().get(getVm().getRunOnVds()).getLiveMergeSupport()) { log.error("Cannot remove VM snapshot. The host on which VM is running does not support Live Merge"); throw new VdcBLLException(VdcBllErrors.VM_HOST_CANNOT_LIVE_MERGE); } } else { log.error("Cannot remove VM snapshot. Vm is not Down and cluster version does not support Live Merge"); throw new VdcBLLException(VdcBllErrors.IRS_IMAGE_STATUS_ILLEGAL); } } final Snapshot snapshot = getSnapshotDao().get(getParameters().getSnapshotId()); boolean snapshotHasImages = hasImages(); boolean removeSnapshotMemory = isMemoryVolumeRemoveable(snapshot.getMemoryVolume()); if (!snapshotHasImages && !removeSnapshotMemory) { getSnapshotDao().remove(getParameters().getSnapshotId()); setSucceeded(true); return; } lockSnapshot(snapshot); freeLock(); getParameters().setEntityInfo(new EntityInfo(VdcObjectType.VM, getVmId())); boolean useTaskManagerToRemoveMemory = false; if (snapshotHasImages) { removeImages(); if (getSnapshotActionType() == VdcActionType.RemoveSnapshotSingleDiskLive) { persistCommand(getParameters().getParentCommand(), true); useTaskManagerToRemoveMemory = true; } } if (removeSnapshotMemory) { removeMemory(snapshot, useTaskManagerToRemoveMemory); if (!snapshotHasImages) { endVmCommand(); } } setSucceeded(true); }