Jakub Niedermertl has uploaded a new change for review.

Change subject: userportal, webadmin: Base-template and template-version 
comboboxes merged
......................................................................

userportal, webadmin: Base-template and template-version comboboxes merged

This patch merges Base-template and template-version comboboxes in VM
related dialogs into one combobox - 'Template' - in order to save space
in dialogs. Resulting combobox has one entry for each combination of
template and its version.

The change relates to following dialogs:
  * New and Edit VM
  * Edit Template
  * New and Edit Pool
  * Clone VM from Snapshot

A new field in UnitVmModel of type TemplateWithVersion was introduced
as model of new combobox. Template-version combobox was completely
removed. Base-template combobox is still used in 'New Template' dialog.

Bug-Url: https://bugzilla.redhat.com/1165630
Change-Id: Iec2b522adc72ed0040e79059c1cd514ae3f5ad34
Signed-off-by: Jakub Niedermertl <[email protected]>
---
M 
backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmTemplate.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.ui.xml
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/instancetypes/InstanceTypesPopupWidget.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/pool/PoolEditPopupWidget.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/pool/PoolNewPopupWidget.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/template/TemplateNewPopupWidget.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/vm/VmClonePopupWidget.java
M 
frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/vm/VmPopupWidget.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/VmSpecificUnitToVmBuilder.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolListModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/templates/LatestVmTemplate.java
A 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/templates/TemplateWithVersion.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalListModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/CloneVmFromSnapshotModelBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingPoolModelBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewPoolModelBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewTemplateVmModelBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewVmModelBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/PoolModelBehaviorBase.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/TemplateVmModelBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UserPortalNewTemplateVmModelBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UserPortalNewVmModelBehavior.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmListModel.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/InstanceTypeManager.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/InstanceTypeModelBehaviorBase.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/NewPoolInstanceTypeManager.java
M 
frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/NewVmInstanceTypeManager.java
M 
frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/models/vms/BaseVmListModelTest.java
34 files changed, 604 insertions(+), 446 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-engine refs/changes/78/36278/1

diff --git 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmTemplate.java
 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmTemplate.java
index eb1b160..82a510d 100644
--- 
a/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmTemplate.java
+++ 
b/backend/manager/modules/common/src/main/java/org/ovirt/engine/core/common/businessentities/VmTemplate.java
@@ -16,6 +16,10 @@
 import org.ovirt.engine.core.common.validation.group.UpdateEntity;
 import org.ovirt.engine.core.compat.Guid;
 
+/**
+ * Template
+ * <p>Blank template has id {@link org.ovirt.engine.core.compat.Guid#Empty}</p>
+ */
 public class VmTemplate extends VmBase implements 
BusinessEntityWithStatus<Guid, VmTemplateStatus>, InstanceType, ImageType {
     private static final long serialVersionUID = -5238366659716600486L;
     public static final int BASE_VERSION_NUMBER = 1;
@@ -342,4 +346,13 @@
     public boolean isBaseTemplate() {
         return getId().equals(getBaseTemplateId());
     }
+
+    /**
+     * Check if template is special 'Blank' template or its version.
+     * <p>Blank template is recognized by id being {@link 
org.ovirt.engine.core.compat.Guid#Empty}</p>
+     * @return true if this is Blank template, false otherwise
+     */
+    public boolean isBlank() {
+        return Guid.Empty.equals(getBaseTemplateId());
+    }
 }
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
index 95916ae..f9de547 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/CommonApplicationConstants.java
@@ -71,8 +71,8 @@
     @DefaultStringValue("Sub Version Name")
     String templateVersionName();
 
-    @DefaultStringValue("Template Sub Version")
-    String templateSubVersion();
+    @DefaultStringValue("Template")
+    String template();
 
     @DefaultStringValue("latest")
     String latest();
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java
index ff0c715..018fa1d 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.java
@@ -52,7 +52,6 @@
 import org.ovirt.engine.core.common.businessentities.VmWatchdogType;
 import org.ovirt.engine.core.common.businessentities.profiles.CpuProfile;
 import org.ovirt.engine.core.common.queries.ConfigurationValues;
-import org.ovirt.engine.core.compat.StringFormat;
 import org.ovirt.engine.core.compat.StringHelper;
 import org.ovirt.engine.core.compat.Version;
 import org.ovirt.engine.ui.common.CommonApplicationConstants;
@@ -107,7 +106,7 @@
 import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
 import org.ovirt.engine.ui.uicommonweb.models.ListModel;
 import org.ovirt.engine.ui.uicommonweb.models.TabName;
-import org.ovirt.engine.ui.uicommonweb.models.templates.LatestVmTemplate;
+import org.ovirt.engine.ui.uicommonweb.models.templates.TemplateWithVersion;
 import org.ovirt.engine.ui.uicommonweb.models.vms.DataCenterWithCluster;
 import org.ovirt.engine.ui.uicommonweb.models.vms.DiskModel;
 import org.ovirt.engine.ui.uicommonweb.models.vms.TimeZoneModel;
@@ -212,9 +211,9 @@
     public ListModelTypeAheadListBoxEditor<VmTemplate> baseTemplateEditor;
 
     @UiField(provided = true)
-    @Path(value = "template.selectedItem")
-    @WithElementId("template")
-    public ListModelTypeAheadListBoxEditor<VmTemplate> templateEditor;
+    @Path(value = "templateWithVersion.selectedItem")
+    @WithElementId("templateWithVersion")
+    public ListModelTypeAheadListBoxEditor<TemplateWithVersion> 
templateWithVersionEditor;
 
     @UiField(provided = true)
     @Path(value = "OSType.selectedItem")
@@ -1153,32 +1152,32 @@
                 },
                 new ModeSwitchingVisibilityRenderer());
 
-        templateEditor = new ListModelTypeAheadListBoxEditor<VmTemplate>(
-                new 
ListModelTypeAheadListBoxEditor.NullSafeSuggestBoxRenderer<VmTemplate>() {
-
+        templateWithVersionEditor = new ListModelTypeAheadListBoxEditor<>(
+                new 
ListModelTypeAheadListBoxEditor.NullSafeSuggestBoxRenderer<TemplateWithVersion>(){
                     @Override
-                    public String getReplacementStringNullSafe(VmTemplate 
data) {
-                        return getDisplayableTemplateVersionName(data);
+                    public String 
getReplacementStringNullSafe(TemplateWithVersion templateWithVersion) {
+                        return getFirstColumn(templateWithVersion)
+                                + " | " //$NON-NLS-1$
+                                + getSecondColumn(templateWithVersion);
                     }
 
                     @Override
-                    public String getDisplayStringNullSafe(VmTemplate data) {
+                    public String getDisplayStringNullSafe(TemplateWithVersion 
templateWithVersion) {
                         return typeAheadNameDescriptionTemplateNullSafe(
-                                getDisplayableTemplateVersionName(data),
-                                data.getDescription()
-                        );
+                                getFirstColumn(templateWithVersion),
+                                getSecondColumn(templateWithVersion));
                     }
 
-                    private String 
getDisplayableTemplateVersionName(VmTemplate template) {
-                        if (template instanceof LatestVmTemplate) {
-                            return constants.latest();
-                        }
+                    private String getFirstColumn(TemplateWithVersion 
templateWithVersion) {
+                        return templateWithVersion.getBaseTemplate().getName();
+                    }
 
-                        String versionName = 
template.getId().equals(template.getBaseTemplateId()) ?
-                                constants.baseTemplate() : 
template.getTemplateVersionName();
-
-                        return (versionName == null ? "" : versionName) 
//$NON-NLS-1$
-                                + StringFormat.format(" (%d)", 
template.getTemplateVersionNumber()); //$NON-NLS-1$
+                    private String getSecondColumn(TemplateWithVersion 
templateWithVersion) {
+                        final VmTemplate versionTemplate = 
templateWithVersion.getTemplateVersion();
+                        return templateWithVersion.isLatest()
+                                ? constants.latest()
+                                : versionTemplate.getTemplateVersionName() + " 
(" //$NON-NLS-1$
+                                        + 
versionTemplate.getTemplateVersionNumber() + ")"; //$NON-NLS-1$
                     }
                 },
                 new ModeSwitchingVisibilityRenderer());
@@ -1371,6 +1370,7 @@
         }
     }
 
+
     protected void localize(CommonApplicationConstants constants) {
         // Tabs
         highAvailabilityTab.setLabel(constants.highAvailVmPopup());
@@ -1391,7 +1391,7 @@
         commentEditor.setLabel(constants.commentLabel());
 
         baseTemplateEditor.setLabel(constants.basedOnTemplateVmPopup());
-        templateEditor.setLabel(constants.templateSubVersion());
+        templateWithVersionEditor.setLabel(constants.template());
         instanceTypesEditor.setLabel(constants.instanceType());
 
         oSTypeEditor.setLabel(constants.osVmPopup());
@@ -1873,7 +1873,7 @@
         oSTypeEditor.setTabIndex(nextTabIndex++);
         baseTemplateEditor.setTabIndex(nextTabIndex++);
         instanceTypesEditor.setTabIndexes(nextTabIndex++);
-        templateEditor.setTabIndex(nextTabIndex++);
+        templateWithVersionEditor.setTabIndexes(nextTabIndex++);
 
         nameEditor.setTabIndex(nextTabIndex++);
         templateVersionNameEditor.setTabIndex(nextTabIndex++);
@@ -2114,8 +2114,8 @@
         oSTypeEditor.setEnabled(false);
         quotaEditor.setEnabled(false);
         dataCenterWithClusterEditor.setEnabled(false);
-        templateEditor.setEnabled(false);
         baseTemplateEditor.setEnabled(false);
+        templateWithVersionEditor.setEnabled(false);
         vmTypeEditor.setEnabled(false);
         instanceTypesEditor.setEnabled(false);
         emulatedMachine.setEnabled(false);
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.ui.xml
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.ui.xml
index 767eeaf..26d1a50 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.ui.xml
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/AbstractVmPopupWidget.ui.xml
@@ -422,7 +422,7 @@
                 <e:ListModelTypeAheadListBoxEditor 
ui:field="dataCenterWithClusterEditor" />
                 <e:ListModelTypeAheadListBoxEditor ui:field="quotaEditor" />
                 <e:ListModelTypeAheadListBoxEditor 
ui:field="baseTemplateEditor"/>
-                <e:ListModelTypeAheadListBoxEditor ui:field="templateEditor" />
+                <e:ListModelTypeAheadListBoxEditor 
ui:field="templateWithVersionEditor" />
                 <e:ListModelListBoxEditor ui:field="oSTypeEditor" />
                 <e:ListModelTypeAheadListBoxEditor 
ui:field="instanceTypesEditor" />
                 <e:ListModelListBoxEditor ui:field="vmTypeEditor" />
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/instancetypes/InstanceTypesPopupWidget.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/instancetypes/InstanceTypesPopupWidget.java
index 3d05f4c..8b7beea 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/instancetypes/InstanceTypesPopupWidget.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/instancetypes/InstanceTypesPopupWidget.java
@@ -47,7 +47,6 @@
                 putOne(commentEditor, hiddenField()).
                 putOne(vmTypeEditor, hiddenField()).
                 putOne(oSTypeEditor, hiddenField()).
-                putOne(templateEditor, hiddenField()).
                 putOne(initialRunTab, hiddenField()).
                 putOne(expander, hiddenField()).
                 putOne(allowConsoleReconnectEditor, hiddenField()).
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/pool/PoolEditPopupWidget.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/pool/PoolEditPopupWidget.java
index 1541139..0b2aaef 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/pool/PoolEditPopupWidget.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/pool/PoolEditPopupWidget.java
@@ -98,8 +98,8 @@
         
quotaEditor.addContentWidgetStyleName(style.generalTabExtendedRightWidgetWidth());
         
instanceTypesEditor.addContentWidgetStyleName(style.generalTabExtendedRightWidgetWidth());
         
descriptionEditor.addContentWidgetStyleName(style.generalTabExtendedRightWidgetWidth());
-        
templateEditor.addContentWidgetStyleName(style.generalTabExtendedRightWidgetWidth());
         
memSizeEditor.addContentWidgetStyleName(style.generalTabExtendedRightWidgetWidth());
+        
templateWithVersionEditor.addContentWidgetStyleName(style.generalTabExtendedRightWidgetWidth());
         
detachableMemSizeEditor.addContentWrapperStypeName(style.generalTabExtendedRightWidgetWrapperWidth());
         
totalvCPUsEditor.addContentWidgetStyleName(style.generalTabExtendedRightWidgetWidth());
         
totalvCPUsEditorWithInfoIcon.getContentWidget().addContentWrapperStypeName(style.generalTabExtendedRightWidgetWrapperWidth());
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/pool/PoolNewPopupWidget.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/pool/PoolNewPopupWidget.java
index dd0c46c..86c06b3 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/pool/PoolNewPopupWidget.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/pool/PoolNewPopupWidget.java
@@ -78,7 +78,7 @@
                 putOne(editPoolIncraseNumOfVmsPanel, hiddenField()).
                 putOne(logicalNetworksEditorPanel, hiddenField()).
                 putOne(editPoolEditMaxAssignedVmsPerUserPanel, hiddenField()).
-                update(templateVersionNameEditor, hiddenField()).
+                putOne(baseTemplateEditor, hiddenField()).
                 putAll(detachableWidgets(), 
simpleField().detachable().visibleInAdvancedModeOnly());
 
         updateOrAddToWidgetConfiguration(widgetConfiguration, 
detachableWidgets(), UpdateToDetachable.INSTANCE);
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/template/TemplateNewPopupWidget.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/template/TemplateNewPopupWidget.java
index 897dc42..4c991aa 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/template/TemplateNewPopupWidget.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/template/TemplateNewPopupWidget.java
@@ -37,9 +37,10 @@
         return super.createWidgetConfiguration().
                 putOne(logicalNetworksEditorPanel, hiddenField()).
                 putAll(poolSpecificFields(), hiddenField()).
-                putOne(templateEditor, hiddenField()).
                 putOne(instanceTypesEditor, hiddenField()).
+                putOne(templateWithVersionEditor, hiddenField()).
                 update(resourceAllocationTab, hiddenField());
+
     }
 
 }
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/vm/VmClonePopupWidget.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/vm/VmClonePopupWidget.java
index 68e0666..508000e 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/vm/VmClonePopupWidget.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/vm/VmClonePopupWidget.java
@@ -38,6 +38,6 @@
                 putAll(poolSpecificFields(), hiddenField()).
                 putOne(logicalNetworksEditorPanel, hiddenField()).
                 update(consoleTab, simpleField().visibleInAdvancedModeOnly()).
-                update(templateVersionNameEditor, hiddenField());
+                putOne(baseTemplateEditor, hiddenField());
     }
 }
diff --git 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/vm/VmPopupWidget.java
 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/vm/VmPopupWidget.java
index 3372f61..fcbfc9b 100644
--- 
a/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/vm/VmPopupWidget.java
+++ 
b/frontend/webadmin/modules/gwt-common/src/main/java/org/ovirt/engine/ui/common/widget/uicommon/popup/vm/VmPopupWidget.java
@@ -47,7 +47,7 @@
     protected PopupWidgetConfigMap createWidgetConfiguration() {
         PopupWidgetConfigMap widgetConfiguration = 
super.createWidgetConfiguration().
                 putAll(poolSpecificFields(), hiddenField()).
-                update(templateVersionNameEditor, hiddenField());
+                putOne(baseTemplateEditor, hiddenField());
 
         updateOrAddToWidgetConfiguration(widgetConfiguration, 
detachableWidgets(), UpdateToDetachable.INSTANCE);
         updateOrAddToWidgetConfiguration(widgetConfiguration, 
adminOnlyWidgets(), UpdateToAdminOnly.INSTANCE);
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java
index 07cf87f..33614df 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/Linq.java
@@ -65,6 +65,7 @@
 import org.ovirt.engine.ui.uicommonweb.models.storage.LunModel;
 import org.ovirt.engine.ui.uicommonweb.models.storage.SanTargetModel;
 import org.ovirt.engine.ui.uicommonweb.models.storage.StorageDomainModel;
+import org.ovirt.engine.ui.uicommonweb.models.templates.TemplateWithVersion;
 import org.ovirt.engine.ui.uicommonweb.models.vms.DataCenterWithCluster;
 import org.ovirt.engine.ui.uicommonweb.models.vms.DiskModel;
 import org.ovirt.engine.ui.uicommonweb.models.vms.ImportEntityData;
@@ -1101,6 +1102,19 @@
         }
     }
 
+    public final static class TemplateWithVersionPredicate implements 
IPredicate<TemplateWithVersion> {
+        private final Guid id;
+
+        public TemplateWithVersionPredicate(Guid id) {
+            this.id = id;
+        }
+
+        @Override
+        public boolean match(TemplateWithVersion templateWithVersion) {
+            return id.equals(templateWithVersion.getTemplateVersion().getId());
+        }
+    }
+
     public final static class StoragePredicate implements 
IPredicate<StorageDomain>
     {
         private Guid id = Guid.Empty;
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/VmSpecificUnitToVmBuilder.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/VmSpecificUnitToVmBuilder.java
index 99949b4..152f92b 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/VmSpecificUnitToVmBuilder.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/builders/vm/VmSpecificUnitToVmBuilder.java
@@ -11,7 +11,7 @@
 public class VmSpecificUnitToVmBuilder extends BaseSyncBuilder<UnitVmModel, 
VM> {
     @Override
     protected void build(UnitVmModel model, VM vm) {
-        vm.setVmtGuid(model.getTemplate().getSelectedItem().getId());
+        
vm.setVmtGuid(model.getTemplateWithVersion().getSelectedItem().getTemplateVersion().getId());
         
vm.setInstanceTypeId(model.getInstanceTypes().getSelectedItem().getId());
     }
 }
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolListModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolListModel.java
index 6aec026..ef2cb9f 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolListModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/pools/PoolListModel.java
@@ -27,7 +27,6 @@
 import org.ovirt.engine.ui.frontend.Frontend;
 import org.ovirt.engine.ui.frontend.INewAsyncCallback;
 import org.ovirt.engine.ui.uicommonweb.Cloner;
-import org.ovirt.engine.ui.uicommonweb.models.templates.LatestVmTemplate;
 import org.ovirt.engine.ui.uicommonweb.Linq;
 import org.ovirt.engine.ui.uicommonweb.UICommand;
 import org.ovirt.engine.ui.uicommonweb.builders.BuilderExecutor;
@@ -263,7 +262,7 @@
                                             .getItems(),
                                             new 
Linq.DataCenterWithClusterPredicate(vm.getStoragePoolId(), 
vm.getVdsGroupId())));
 
-                                    model.getTemplate().setIsChangable(false);
+                                    
model.getTemplateWithVersion().setIsChangable(false);
                                     cdImage = vm.getIsoPath();
                                     
model.getVmType().setSelectedItem(vm.getVmType());
                                 }
@@ -459,7 +458,7 @@
                         
vm.setVmInit(model.getVmInitModel().buildCloudInitParameters(model));
                         
vm.setBalloonEnabled(model.getMemoryBalloonDeviceEnabled().getEntity());
 
-                        
vm.setUseLatestVersion(model.getTemplate().getSelectedItem() instanceof 
LatestVmTemplate);
+                        
vm.setUseLatestVersion(model.getTemplateWithVersion().getSelectedItem().isLatest());
                         vm.setStateless(false);
                         
vm.setInstanceTypeId(model.getInstanceTypes().getSelectedItem().getId());
 
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/templates/LatestVmTemplate.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/templates/LatestVmTemplate.java
index fe73015..6692796 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/templates/LatestVmTemplate.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/templates/LatestVmTemplate.java
@@ -6,6 +6,14 @@
 
 /**
  * It allows for frontend to distinguish between regular template and latest 
template.
+ * <p>
+ *     Note: Latest template instance equals to its pattern.
+ *     <pre>
+ *         VmTemplate a = ...
+ *         LatestVmTemplate b = new LatestVmTemplate(a);
+ *         a.equals(b); // returns true
+ *     </pre>
+ * </p>
  */
 public class LatestVmTemplate extends VmTemplate {
 
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/templates/TemplateWithVersion.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/templates/TemplateWithVersion.java
new file mode 100644
index 0000000..f02c6b4
--- /dev/null
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/templates/TemplateWithVersion.java
@@ -0,0 +1,134 @@
+package org.ovirt.engine.ui.uicommonweb.models.templates;
+
+import org.ovirt.engine.core.common.businessentities.VmTemplate;
+
+/**
+ * Connection of 'base template' and 'template version'.
+ *
+ * <p>
+ *     Ordering: <br/>
+ *     Lexicographically - first by base template then by template version 
<br/>
+ *     Ordering of base templates:
+ *     <ul>
+ *         <li>Blank</li>
+ *         <li>Alphabetically by displayed name
+ *             {@link 
org.ovirt.engine.core.common.businessentities.VmTemplate#getName()}</li>
+ *     </ul>
+ *     Ordering of template versions:
+ *     <ul>
+ *         <li>Latest</li>
+ *         <li>by version number
+ *             {@link 
org.ovirt.engine.core.common.businessentities.VmTemplate#getTemplateVersionNumber()}</li>
+ *     </ul>
+ * </p>
+ *
+ * <p>
+ *     Equality based on {@link #baseTemplate}, {@link #templateVersion} and 
being latest template.
+ * </p>
+ */
+public class TemplateWithVersion implements Comparable<TemplateWithVersion> {
+
+    private VmTemplate baseTemplate;
+
+    private VmTemplate templateVersion;
+
+    /**
+     * It has to hold {@code 
baseTemplate.getId().equals(templateVersion.getBaseTemplateId())}
+     * @param baseTemplate base template, required non-null
+     * @param templateVersion template version of {@code baseTemplate}, 
required non-null
+     */
+    public TemplateWithVersion(VmTemplate baseTemplate, VmTemplate 
templateVersion) {
+        if (!(baseTemplate != null
+                && templateVersion != null
+                && 
baseTemplate.getId().equals(templateVersion.getBaseTemplateId()))) {
+            throw new IllegalArgumentException();
+        }
+        this.baseTemplate = baseTemplate;
+        this.templateVersion = templateVersion;
+    }
+
+    public VmTemplate getTemplateVersion() {
+        return templateVersion;
+    }
+
+    public VmTemplate getBaseTemplate() {
+        return baseTemplate;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (!(o instanceof TemplateWithVersion)) return false;
+
+        TemplateWithVersion that = (TemplateWithVersion) o;
+
+        if (!baseTemplate.equals(that.baseTemplate)) return false;
+        if (!templateVersion.equals(that.templateVersion)) return false;
+
+        boolean isThisLatest = templateVersion instanceof LatestVmTemplate;
+        boolean isOtherLatest = that.getTemplateVersion() instanceof 
LatestVmTemplate;
+        if (isThisLatest != isOtherLatest) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = baseTemplate.hashCode();
+        result = 31 * result + templateVersion.hashCode();
+        result = 31 * result + (templateVersion instanceof LatestVmTemplate ? 
1 : 0);
+        return result;
+    }
+
+    @Override
+    public int compareTo(TemplateWithVersion other) {
+        final int baseTemplateComparison = compareBaseTemplate(
+                this.getBaseTemplate(), other.getBaseTemplate());
+        if (baseTemplateComparison != 0) {
+            return baseTemplateComparison;
+        }
+        return compareTemplateVersion(this.getTemplateVersion(), 
other.getTemplateVersion());
+    }
+
+    /**
+     * First <em>Latest</em>, then by version number
+     */
+    private static int compareTemplateVersion(VmTemplate a, VmTemplate b) {
+        if (a instanceof LatestVmTemplate) {
+            if (b instanceof LatestVmTemplate) {
+                return 0;
+            } else {
+                return -1;
+            }
+        } else {
+            if (b instanceof LatestVmTemplate) {
+                return 1;
+            } else {
+                return - Integer.compare(a.getTemplateVersionNumber(), 
b.getTemplateVersionNumber());
+            }
+        }
+    }
+
+    /**
+     * First blank, then by name
+     */
+    private static int compareBaseTemplate(VmTemplate a, VmTemplate b) {
+        if (a.isBlank()) {
+            if (b.isBlank()) {
+                return 0;
+            } else {
+                return -1;
+            }
+        } else {
+            if (b.isBlank()) {
+                return 1;
+            } else {
+                return a.getName().compareTo(b.getName());
+            }
+        }
+    }
+
+    public boolean isLatest() {
+        return this.getTemplateVersion() instanceof LatestVmTemplate;
+    }
+}
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalListModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalListModel.java
index 62cd9cf..2d1e47a 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalListModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/userportal/UserPortalListModel.java
@@ -58,7 +58,6 @@
 import org.ovirt.engine.ui.uicommonweb.models.pools.PoolDiskListModel;
 import org.ovirt.engine.ui.uicommonweb.models.pools.PoolGeneralModel;
 import org.ovirt.engine.ui.uicommonweb.models.pools.PoolInterfaceListModel;
-import org.ovirt.engine.ui.uicommonweb.models.templates.LatestVmTemplate;
 import org.ovirt.engine.ui.uicommonweb.models.vms.CloneVmModel;
 import org.ovirt.engine.ui.uicommonweb.models.vms.ConsoleModel;
 import org.ovirt.engine.ui.uicommonweb.models.vms.DataCenterWithCluster;
@@ -598,7 +597,7 @@
 
         UnitVmModel model = (UnitVmModel) getWindow();
 
-        if (!model.validate())
+        if (!model.validate(false))
         {
             model.setIsValid(false);
         }
@@ -1083,7 +1082,7 @@
         else
         {
             final VM selectedItem = (VM) ((UserPortalItemModel) 
userPortalListModel.getSelectedItem()).getEntity();
-            
gettempVm().setUseLatestVersion(model.getTemplate().getSelectedItem() 
instanceof LatestVmTemplate);
+            
gettempVm().setUseLatestVersion(model.getTemplateWithVersion().getSelectedItem().isLatest());
 
             if (selectedItem.isRunningOrPaused()) {
                 
AsyncDataProvider.getInstance().getVmChangedFieldsForNextRun(editedVm, 
gettempVm(), getUpdateVmParameters(false), new AsyncQuery(this,
@@ -1125,7 +1124,7 @@
         setstorageDomain(model.getStorageDomain().getSelectedItem());
 
         VM vm = gettempVm();
-        vm.setUseLatestVersion(model.getTemplate().getSelectedItem() 
instanceof LatestVmTemplate);
+        
vm.setUseLatestVersion(model.getTemplateWithVersion().getSelectedItem().isLatest());
 
         AddVmParameters parameters = new AddVmParameters(vm);
         
parameters.setDiskInfoDestinationMap(model.getDisksAllocationModel().getImageToDestinationDomainMap());
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/CloneVmFromSnapshotModelBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/CloneVmFromSnapshotModelBehavior.java
index b67bbf6..3915145 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/CloneVmFromSnapshotModelBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/CloneVmFromSnapshotModelBehavior.java
@@ -13,9 +13,8 @@
     }
 
     @Override
-    public void template_SelectedItemChanged()
-    {
-        super.template_SelectedItemChanged();
+    public void templateWithVersion_SelectedItemChanged() {
+        super.templateWithVersion_SelectedItemChanged();
 
         getModel().getName().setEntity(""); //$NON-NLS-1$
         getModel().getDescription().setEntity(""); //$NON-NLS-1$
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingPoolModelBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingPoolModelBehavior.java
index e28f223..d1b2243 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingPoolModelBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingPoolModelBehavior.java
@@ -76,19 +76,16 @@
     }
 
     public void initTemplate() {
-        setupTemplate(pool.getVmtGuid(), pool.isUseLatestVersion());
+        setupReadOnlyTemplateWithVersion(pool.getVmtGuid(), 
pool.isUseLatestVersion());
     }
 
     @Override
-    public void template_SelectedItemChanged() {
+    public void templateWithVersion_SelectedItemChanged() {
+        super.templateWithVersion_SelectedItemChanged();
         getModel().setIsDisksAvailable(true);
-        VmTemplate template = getModel().getTemplate().getSelectedItem();
+        VmTemplate template = 
getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion();
         updateRngDevice(template.getId());
         
getModel().getCustomPropertySheet().deserialize(template.getCustomProperties());
-    }
-
-    @Override
-    protected void baseTemplateSelectedItemChanged() {
     }
 
     @Override
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java
index 109ce2b..20fd452 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/ExistingVmModelBehavior.java
@@ -88,37 +88,37 @@
 
     private void loadDataCenter() {
         AsyncDataProvider.getInstance().getDataCenterById(new 
AsyncQuery(getModel(),
-                new INewAsyncCallback() {
-                    @Override
-                    public void onSuccess(Object target, Object returnValue) {
+                        new INewAsyncCallback() {
+                            @Override
+                            public void onSuccess(Object target, Object 
returnValue) {
 
-                        UnitVmModel model = (UnitVmModel) target;
-                        if (returnValue != null) {
-                            StoragePool dataCenter = (StoragePool) returnValue;
-                            final List<StoragePool> dataCenters =
-                                    new 
ArrayList<StoragePool>(Arrays.asList(new StoragePool[]{dataCenter}));
+                                UnitVmModel model = (UnitVmModel) target;
+                                if (returnValue != null) {
+                                    StoragePool dataCenter = (StoragePool) 
returnValue;
+                                    final List<StoragePool> dataCenters =
+                                            new 
ArrayList<StoragePool>(Arrays.asList(new StoragePool[]{dataCenter}));
 
-                            initClusters(dataCenters);
-                        } else {
-                            ExistingVmModelBehavior behavior = 
(ExistingVmModelBehavior) model.getBehavior();
-                            VM currentVm = behavior.vm;
-                            VDSGroup tempVar = new VDSGroup();
-                            tempVar.setId(currentVm.getVdsGroupId());
-                            tempVar.setName(currentVm.getVdsGroupName());
-                            
tempVar.setcompatibility_version(currentVm.getVdsGroupCompatibilityVersion());
-                            
tempVar.setStoragePoolId(currentVm.getStoragePoolId());
-                            VDSGroup cluster = tempVar;
-                            DataCenterWithCluster dataCenterWithCluster =
-                                    new DataCenterWithCluster(null, cluster);
-                            
model.getDataCenterWithClustersList().setItems(Arrays.asList(dataCenterWithCluster));
-                            
model.getDataCenterWithClustersList().setSelectedItem(dataCenterWithCluster);
-                            behavior.initTemplate();
-                            behavior.initCdImage();
-                        }
+                                    initClusters(dataCenters);
+                                } else {
+                                    ExistingVmModelBehavior behavior = 
(ExistingVmModelBehavior) model.getBehavior();
+                                    VM currentVm = behavior.vm;
+                                    VDSGroup tempVar = new VDSGroup();
+                                    tempVar.setId(currentVm.getVdsGroupId());
+                                    
tempVar.setName(currentVm.getVdsGroupName());
+                                    
tempVar.setcompatibility_version(currentVm.getVdsGroupCompatibilityVersion());
+                                    
tempVar.setStoragePoolId(currentVm.getStoragePoolId());
+                                    VDSGroup cluster = tempVar;
+                                    DataCenterWithCluster 
dataCenterWithCluster =
+                                            new DataCenterWithCluster(null, 
cluster);
+                                    
model.getDataCenterWithClustersList().setItems(Arrays.asList(dataCenterWithCluster));
+                                    
model.getDataCenterWithClustersList().setSelectedItem(dataCenterWithCluster);
+                                    behavior.initTemplate();
+                                    behavior.initCdImage();
+                                }
 
-                    }
-                },
-                getModel().getHash()),
+                            }
+                        },
+                        getModel().getHash()),
                 vm.getStoragePoolId());
     }
 
@@ -146,12 +146,7 @@
     }
 
     @Override
-    protected void baseTemplateSelectedItemChanged() {
-    }
-
-    @Override
-    public void template_SelectedItemChanged()
-    {
+    public void templateWithVersion_SelectedItemChanged() {
         // This method will be called even if a VM created from Blank template.
 
         // Update model state according to VM properties.
@@ -195,7 +190,7 @@
             }), vm.getRunOnVds());
         }
 
-    updateCpuProfile(vm.getVdsGroupId(), vm.getVdsGroupCompatibilityVersion(), 
vm.getCpuProfileId());
+        updateCpuProfile(vm.getVdsGroupId(), 
vm.getVdsGroupCompatibilityVersion(), vm.getCpuProfileId());
     }
 
     @Override
@@ -287,9 +282,8 @@
         }
     }
 
-    protected void initTemplate()
-    {
-        setupTemplate(vm.getVmtGuid(), vm.isUseLatestVersion());
+    protected void initTemplate() {
+        setupReadOnlyTemplateWithVersion(vm.getVmtGuid(), 
vm.isUseLatestVersion());
     }
 
     public void initCdImage()
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewPoolModelBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewPoolModelBehavior.java
index cac481c..695aec2 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewPoolModelBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewPoolModelBehavior.java
@@ -55,21 +55,19 @@
             @Override
             public void onSuccess(Object target1, Object returnValue1) {
 
-                List<VmTemplate> baseTemplates =
-                        filterNotBaseTemplates((List<VmTemplate>) 
returnValue1);
-
-                List<VmTemplate> filteredTemplates =
-                        
AsyncDataProvider.getInstance().filterTemplatesByArchitecture(baseTemplates,
+                List<VmTemplate> templatesByDataCenter = (List<VmTemplate>) 
returnValue1;
+                List<VmTemplate> properArchitectureTemplates =
+                        
AsyncDataProvider.getInstance().filterTemplatesByArchitecture(templatesByDataCenter,
                                 
dataCenterWithCluster.getCluster().getArchitecture());
-
-                List<VmTemplate> templatesWithoutBlank = new 
ArrayList<VmTemplate>();
-                for (VmTemplate template : filteredTemplates) {
-                    if (!template.getId().equals(Guid.Empty)) {
+                List<VmTemplate> templatesWithoutBlank = new ArrayList<>();
+                for (VmTemplate template : properArchitectureTemplates) {
+                    final boolean isBlankOrVersionOfBlank = 
template.getId().equals(Guid.Empty)
+                            || template.getBaseTemplateId().equals(Guid.Empty);
+                    if (!isBlankOrVersionOfBlank) {
                         templatesWithoutBlank.add(template);
                     }
                 }
-
-                getModel().getBaseTemplate().setItems(templatesWithoutBlank);
+                initTemplateWithVersion(templatesWithoutBlank);
             }
         }), dataCenter.getId());
 
@@ -77,9 +75,11 @@
     }
 
     @Override
-    public void template_SelectedItemChanged() {
-        super.template_SelectedItemChanged();
-        VmTemplate template = getModel().getTemplate().getSelectedItem();
+    public void templateWithVersion_SelectedItemChanged() {
+        super.templateWithVersion_SelectedItemChanged();
+        VmTemplate template = 
getModel().getTemplateWithVersion().getSelectedItem() != null
+                ? 
getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion()
+                : null;
 
         if (template == null) {
             return;
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewTemplateVmModelBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewTemplateVmModelBehavior.java
index aaed3f3..783ef19 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewTemplateVmModelBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewTemplateVmModelBehavior.java
@@ -51,7 +51,7 @@
         super.initialize(systemTreeSelectedItem);
         getModel().getVmInitEnabled().setEntity(vm.getVmInit() != null);
         getModel().getVmInitModel().init(vm.getStaticData());
-        getModel().getTemplate().setIsChangable(false);
+        //getModel().getTemplate().setIsChangable(false);
 
         getModel().getVmType().setIsChangable(true);
         getModel().getCopyPermissions().setIsAvailable(true);
@@ -189,9 +189,8 @@
         }
     }
 
-    private void postInitTemplate(List<VmTemplate> templates)
-    {
-        List<VmTemplate> baseTemplates = filterNotBaseTemplates(templates);
+    private void postInitTemplate(List<VmTemplate> templates) {
+        List<VmTemplate> baseTemplates = keepBaseTemplates(templates);
 
         VmTemplate currentTemplate = Linq.firstOrDefault(templates,
                 new Linq.TemplatePredicate(vm.getVmtGuid()));
@@ -262,11 +261,6 @@
             list.add(diskModel);
         }
         getModel().setDisks(list);
-    }
-
-    @Override
-    public void template_SelectedItemChanged()
-    {
     }
 
     @Override
@@ -457,8 +451,8 @@
         if (!getModel().getIsSubTemplate().getEntity()) {
             getModel().getName().setEntity(""); //$NON-NLS-1$
         } else {
-            // by default select the template of the vm
-            
getModel().getBaseTemplate().setEntity(getModel().getTemplate().getEntity());
+            // there will always be at least 'Blank' base template
+            
getModel().getBaseTemplate().setSelectedItem(getModel().getBaseTemplate().getItems().iterator().next());
 
             // copy any entered name to be the template-version name
             
getModel().getTemplateVersionName().setEntity(getModel().getName().getEntity());
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewVmModelBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewVmModelBehavior.java
index 4a29c3b..5d6f191 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewVmModelBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/NewVmModelBehavior.java
@@ -1,7 +1,5 @@
 package org.ovirt.engine.ui.uicommonweb.models.vms;
 
-import java.util.ArrayList;
-import java.util.List;
 import org.ovirt.engine.core.common.businessentities.InstanceType;
 import org.ovirt.engine.core.common.businessentities.StorageDomain;
 import org.ovirt.engine.core.common.businessentities.StoragePool;
@@ -21,11 +19,15 @@
 import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
 import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemModel;
 import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemType;
+import org.ovirt.engine.ui.uicommonweb.models.templates.TemplateWithVersion;
 import 
org.ovirt.engine.ui.uicommonweb.models.vms.instancetypes.InstanceTypeManager;
 import 
org.ovirt.engine.ui.uicommonweb.models.vms.instancetypes.NewVmInstanceTypeManager;
 import org.ovirt.engine.ui.uicompat.ConstantsManager;
 
-public class NewVmModelBehavior extends VmModelBehaviorBase {
+import java.util.ArrayList;
+import java.util.List;
+
+public class NewVmModelBehavior extends VmModelBehaviorBase<UnitVmModel> {
 
     private InstanceTypeManager instanceTypeManager;
 
@@ -81,74 +83,84 @@
         instanceTypeManager = new NewVmInstanceTypeManager(getModel());
     }
 
+//    @Override
+//    public void template_SelectedItemChanged() {
+//        VmTemplate template = getModel().getTemplate().getSelectedItem();
+//        if (template != null) {
+//            selectedTemplateChanged(template);
+//        }
+//    }
+
     @Override
-    public void template_SelectedItemChanged()
-    {
-        VmTemplate template = getModel().getTemplate().getSelectedItem();
+    public void templateWithVersion_SelectedItemChanged() {
+        TemplateWithVersion selectedTemplateWithVersion = 
getModel().getTemplateWithVersion().getSelectedItem();
+        if (selectedTemplateWithVersion != null) {
+            VmTemplate selectedTemplate = 
selectedTemplateWithVersion.getTemplateVersion();
+            selectedTemplateChanged(selectedTemplate);
+        }
+    }
 
-        if (template != null)
+    private void selectedTemplateChanged(VmTemplate template) {
+        // Copy VM parameters from template.
+        buildModel(template);
+
+        setSelectedOSType(template, 
getModel().getSelectedCluster().getArchitecture());
+        doChangeDefautlHost(template.getDedicatedVmForVds());
+
+        getModel().getIsStateless().setEntity(template.isStateless());
+
+        boolean hasCd = !StringHelper.isNullOrEmpty(template.getIsoPath());
+
+        getModel().getCdImage().setIsChangable(hasCd);
+        getModel().getCdAttached().setEntity(hasCd);
+        if (hasCd) {
+            getModel().getCdImage().setSelectedItem(template.getIsoPath());
+        }
+
+        updateTimeZone(template.getTimeZone());
+
+        if (!template.getId().equals(Guid.Empty))
         {
-            // Copy VM parameters from template.
-            buildModel(template);
+            getModel().getStorageDomain().setIsChangable(true);
+            getModel().getProvisioning().setIsChangable(true);
 
-            setSelectedOSType(template, 
getModel().getSelectedCluster().getArchitecture());
-            doChangeDefautlHost(template.getDedicatedVmForVds());
+            getModel().getVmType().setSelectedItem(template.getVmType());
+            getModel().setIsBlankTemplate(false);
+            getModel().getCopyPermissions().setIsAvailable(true);
+            
getModel().getAllowConsoleReconnect().setEntity(template.isAllowConsoleReconnect());
+            initDisks();
+            updateRngDevice(template.getId());
+        }
+        else
+        {
+            getModel().getStorageDomain().setIsChangable(false);
+            getModel().getProvisioning().setIsChangable(false);
 
-            getModel().getIsStateless().setEntity(template.isStateless());
+            getModel().setIsBlankTemplate(true);
+            getModel().setIsDisksAvailable(false);
+            getModel().getCopyPermissions().setIsAvailable(false);
+            getModel().setDisks(null);
+        }
 
-            boolean hasCd = !StringHelper.isNullOrEmpty(template.getIsoPath());
+        initStorageDomains();
 
-            getModel().getCdImage().setIsChangable(hasCd);
-            getModel().getCdAttached().setEntity(hasCd);
-            if (hasCd) {
-                getModel().getCdImage().setSelectedItem(template.getIsoPath());
-            }
+        InstanceType selectedInstanceType = 
getModel().getInstanceTypes().getSelectedItem();
+        int instanceTypeMinAllocatedMemory = selectedInstanceType != null ? 
selectedInstanceType.getMinAllocatedMem() : 0;
 
-            updateTimeZone(template.getTimeZone());
+        // do not update if specified on template or instance type
+        if (template.getMinAllocatedMem() == 0 && 
instanceTypeMinAllocatedMemory == 0) {
+            updateMinAllocatedMemory();
+        }
 
-            if (!template.getId().equals(Guid.Empty))
-            {
-                getModel().getStorageDomain().setIsChangable(true);
-                getModel().getProvisioning().setIsChangable(true);
+        updateQuotaByCluster(template.getQuotaId(), template.getQuotaName());
+        
getModel().getCustomPropertySheet().deserialize(template.getCustomProperties());
 
-                getModel().getVmType().setSelectedItem(template.getVmType());
-                getModel().setIsBlankTemplate(false);
-                getModel().getCopyPermissions().setIsAvailable(true);
-                
getModel().getAllowConsoleReconnect().setEntity(template.isAllowConsoleReconnect());
-                initDisks();
-                updateRngDevice(template.getId());
-            }
-            else
-            {
-                getModel().getStorageDomain().setIsChangable(false);
-                getModel().getProvisioning().setIsChangable(false);
+        getModel().getVmInitModel().init(template);
+        getModel().getVmInitEnabled().setEntity(template.getVmInit() != null);
 
-                getModel().setIsBlankTemplate(true);
-                getModel().setIsDisksAvailable(false);
-                getModel().getCopyPermissions().setIsAvailable(false);
-                getModel().setDisks(null);
-            }
-
-            initStorageDomains();
-
-            InstanceType selectedInstanceType = 
getModel().getInstanceTypes().getSelectedItem();
-            int instanceTypeMinAllocatedMemory = selectedInstanceType != null 
? selectedInstanceType.getMinAllocatedMem() : 0;
-
-            // do not update if specified on template or instance type
-            if (template.getMinAllocatedMem() == 0 && 
instanceTypeMinAllocatedMemory == 0) {
-                updateMinAllocatedMemory();
-            }
-
-            updateQuotaByCluster(template.getQuotaId(), 
template.getQuotaName());
-            
getModel().getCustomPropertySheet().deserialize(template.getCustomProperties());
-
-            getModel().getVmInitModel().init(template);
-            getModel().getVmInitEnabled().setEntity(template.getVmInit() != 
null);
-
-            if (getModel().getSelectedCluster() != null) {
-                updateCpuProfile(getModel().getSelectedCluster().getId(),
-                        getClusterCompatibilityVersion(), 
template.getCpuProfileId());
-            }
+        if (getModel().getSelectedCluster() != null) {
+            updateCpuProfile(getModel().getSelectedCluster().getId(),
+                    getClusterCompatibilityVersion(), 
template.getCpuProfileId());
         }
     }
 
@@ -171,8 +183,8 @@
         updateCustomPropertySheet();
         updateMinAllocatedMemory();
         updateNumOfSockets();
-        if (getModel().getTemplate().getSelectedItem() != null) {
-            VmTemplate template = getModel().getTemplate().getSelectedItem();
+        if (getModel().getTemplateWithVersion().getSelectedItem() != null) {
+            VmTemplate template = 
getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion();
             updateQuotaByCluster(template.getQuotaId(), 
template.getQuotaName());
         }
         updateCpuPinningVisibility();
@@ -210,7 +222,9 @@
 
     @Override
     public void oSType_SelectedItemChanged() {
-        VmTemplate template = getModel().getTemplate().getSelectedItem();
+        VmTemplate template = 
getModel().getTemplateWithVersion().getSelectedItem() == null
+                ? null
+                : 
getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion();
         Integer osType = getModel().getOSType().getSelectedItem();
         if ((template != null || !basedOnCustomInstanceType()) && osType != 
null) {
             Guid id = basedOnCustomInstanceType() ? template.getId() : 
getModel().getInstanceTypes().getSelectedItem().getId();
@@ -232,10 +246,11 @@
                 .setEntity((int) (getModel().getMemSize().getEntity() * 
overCommitFactor));
     }
 
+    // TODO jakub this reference cleanup
     private void updateTemplate()
     {
         final DataCenterWithCluster dataCenterWithCluster =
-                (DataCenterWithCluster) 
getModel().getDataCenterWithClustersList().getSelectedItem();
+                getModel().getDataCenterWithClustersList().getSelectedItem();
         StoragePool dataCenter = dataCenterWithCluster == null ? null : 
dataCenterWithCluster.getDataCenter();
         if (dataCenter == null) {
             return;
@@ -244,25 +259,20 @@
         // Filter according to system tree selection.
         if (getSystemTreeSelectedItem() != null && 
getSystemTreeSelectedItem().getType() == SystemTreeItemType.Storage)
         {
-            StorageDomain storage = (StorageDomain) 
getSystemTreeSelectedItem().getEntity();
+            final StorageDomain storage = (StorageDomain) 
getSystemTreeSelectedItem().getEntity();
 
-            AsyncDataProvider.getInstance().getTemplateListByDataCenter(new 
AsyncQuery(new Object[] { this, storage },
+            AsyncDataProvider.getInstance().getTemplateListByDataCenter(new 
AsyncQuery(null,
                     new INewAsyncCallback() {
                         @Override
-                        public void onSuccess(Object target1, Object 
returnValue1) {
+                        public void onSuccess(Object nothing, Object 
returnValue1) {
 
-                            Object[] array1 = (Object[]) target1;
-                            NewVmModelBehavior behavior1 = 
(NewVmModelBehavior) array1[0];
-                            StorageDomain storage1 = (StorageDomain) array1[1];
-                            
AsyncDataProvider.getInstance().getTemplateListByStorage(new AsyncQuery(new 
Object[] { behavior1,
-                                    returnValue1 },
+                            final List<VmTemplate> templatesByDataCenter = 
(List<VmTemplate>) returnValue1;
+
+                            
AsyncDataProvider.getInstance().getTemplateListByStorage(new AsyncQuery(null,
                                     new INewAsyncCallback() {
                                         @Override
-                                        public void onSuccess(Object target2, 
Object returnValue2) {
+                                        public void onSuccess(Object nothing, 
Object returnValue2) {
 
-                                            Object[] array2 = (Object[]) 
target2;
-                                            NewVmModelBehavior behavior2 = 
(NewVmModelBehavior) array2[0];
-                                            List<VmTemplate> 
templatesByDataCenter = (List<VmTemplate>) array2[1];
                                             List<VmTemplate> 
templatesByStorage = (List<VmTemplate>) returnValue2;
                                             VmTemplate blankTemplate =
                                                     
Linq.firstOrDefault(templatesByDataCenter,
@@ -275,11 +285,11 @@
                                             List<VmTemplate> templateList = 
AsyncDataProvider.getInstance().filterTemplatesByArchitecture(templatesByStorage,
                                                             
dataCenterWithCluster.getCluster().getArchitecture());
 
-                                            
behavior2.postInitTemplate(templateList);
+                                            
NewVmModelBehavior.this.postInitTemplate(templateList);
 
                                         }
                                     }),
-                                    storage1.getId());
+                                    storage.getId());
 
                         }
                     }, getModel().getHash()),
@@ -287,16 +297,14 @@
         }
         else
         {
-            AsyncDataProvider.getInstance().getTemplateListByDataCenter(new 
AsyncQuery(this,
+            AsyncDataProvider.getInstance().getTemplateListByDataCenter(new 
AsyncQuery(null,
                     new INewAsyncCallback() {
                         @Override
-                        public void onSuccess(Object target, Object 
returnValue) {
-
-                            NewVmModelBehavior behavior = (NewVmModelBehavior) 
target;
+                        public void onSuccess(Object nothing, Object 
returnValue) {
 
                             List<VmTemplate> templates = (List<VmTemplate>) 
returnValue;
 
-                            
behavior.postInitTemplate(AsyncDataProvider.getInstance().filterTemplatesByArchitecture(templates,
+                            
NewVmModelBehavior.this.postInitTemplate(AsyncDataProvider.getInstance().filterTemplatesByArchitecture(templates,
                                     
dataCenterWithCluster.getCluster().getArchitecture()));
 
                         }
@@ -304,18 +312,8 @@
         }
     }
 
-    private void postInitTemplate(List<VmTemplate> templates)
-    {
-        List<VmTemplate> baseTemplates = filterNotBaseTemplates(templates);
-
-        // If there was some template selected before, try select it again.
-        VmTemplate prevBaseTemplate = 
getModel().getBaseTemplate().getSelectedItem();
-
-        getModel().getBaseTemplate().setItems(baseTemplates);
-
-        
getModel().getBaseTemplate().setSelectedItem(Linq.firstOrDefault(baseTemplates,
-                new Linq.TemplatePredicate(prevBaseTemplate != null ? 
prevBaseTemplate.getId() : Guid.Empty)));
-
+    private void postInitTemplate(List<VmTemplate> templates) {
+        initTemplateWithVersion(templates);
         updateIsDisksAvailable();
     }
 
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/PoolModelBehaviorBase.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/PoolModelBehaviorBase.java
index cb1e473..2689ff5 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/PoolModelBehaviorBase.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/PoolModelBehaviorBase.java
@@ -171,11 +171,6 @@
     }
 
     @Override
-    public void template_SelectedItemChanged() {
-        // overrideSerialNumberPolicy if there is a need to do some actions
-    }
-
-    @Override
     public void postDataCenterWithClusterSelectedItemChanged()
     {
         updateDefaultHost();
@@ -184,8 +179,8 @@
         updateNumOfSockets();
         updateOSValues();
 
-        if (getModel().getTemplate().getSelectedItem() != null) {
-            VmTemplate template = getModel().getTemplate().getSelectedItem();
+        if (getModel().getTemplateWithVersion().getSelectedItem() != null) {
+            VmTemplate template = 
getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion();
             updateQuotaByCluster(template.getQuotaId(), 
template.getQuotaName());
         }
         updateMemoryBalloon();
@@ -205,8 +200,10 @@
     }
 
     @Override
-    public void oSType_SelectedItemChanged() {
-        VmTemplate template = getModel().getTemplate().getSelectedItem();
+    public void oSType_SelectedItemChanged() { // grep for this bug
+        VmTemplate template = 
getModel().getTemplateWithVersion().getSelectedItem() == null
+                ? null
+                : 
getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion();
         Integer osType = getModel().getOSType().getSelectedItem();
         if ((template != null || !basedOnCustomInstanceType()) && osType != 
null) {
             Guid id = basedOnCustomInstanceType() ? template.getId() : 
getModel().getInstanceTypes().getSelectedItem().getId();
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/TemplateVmModelBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/TemplateVmModelBehavior.java
index 46952c9..a57201f 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/TemplateVmModelBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/TemplateVmModelBehavior.java
@@ -21,6 +21,7 @@
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.List;
 
 public class TemplateVmModelBehavior extends VmModelBehaviorBase
@@ -36,8 +37,9 @@
     public void initialize(SystemTreeItemModel systemTreeSelectedItem)
     {
         super.initialize(systemTreeSelectedItem);
-        getModel().getTemplate().setIsChangable(false);
+        getModel().getTemplateWithVersion().setIsChangable(false);
         getModel().getBaseTemplate().setIsChangable(false);
+        getModel().getTemplateWithVersion().setIsChangable(false);
         getModel().getProvisioning().setIsChangable(false);
         getModel().getStorageDomain().setIsChangable(false);
         getModel().getIsSoundcardEnabled().setIsChangable(true);
@@ -47,18 +49,16 @@
 
         if (template.getStoragePoolId() != null && 
!template.getStoragePoolId().equals(Guid.Empty))
         {
-            AsyncDataProvider.getInstance().getDataCenterById(new 
AsyncQuery(getModel(),
+            AsyncDataProvider.getInstance().getDataCenterById(new 
AsyncQuery(null,
                     new INewAsyncCallback() {
                         @Override
-                        public void onSuccess(Object target, Object 
returnValue) {
+                        public void onSuccess(Object nothing, Object 
returnValue) {
                             final StoragePool dataCenter = (StoragePool) 
returnValue;
                             
AsyncDataProvider.getInstance().getClusterListByService(
-                                    new AsyncQuery(getModel(), new 
INewAsyncCallback() {
+                                    new AsyncQuery(null, new 
INewAsyncCallback() {
 
                                         @Override
-                                        public void onSuccess(Object target, 
Object returnValue) {
-                                            UnitVmModel model = (UnitVmModel) 
target;
-
+                                        public void onSuccess(Object nothing, 
Object returnValue) {
                                             ArrayList<VDSGroup> clusters = 
(ArrayList<VDSGroup>) returnValue;
                                             ArrayList<VDSGroup> 
clustersSupportingVirt = new ArrayList<VDSGroup>();
                                             // filter clusters supporting virt 
service only
@@ -72,16 +72,16 @@
                                                     
AsyncDataProvider.getInstance().filterByArchitecture(clustersSupportingVirt,
                                                             
template.getClusterArch());
 
-                                            
model.setDataCentersAndClusters(model,
-                                                    new 
ArrayList<StoragePool>(Arrays.asList(new StoragePool[] { dataCenter })),
+                                            
getModel().setDataCentersAndClusters(getModel(),
+                                                    new 
ArrayList<StoragePool>(Arrays.asList(new StoragePool[]{dataCenter})),
                                                     filteredClusters,
                                                     template.getVdsGroupId());
 
-                                            
AsyncDataProvider.getInstance().isSoundcardEnabled(new AsyncQuery(getModel(),
+                                            
AsyncDataProvider.getInstance().isSoundcardEnabled(new AsyncQuery(null,
                                                     new INewAsyncCallback() {
 
                                                         @Override
-                                                        public void 
onSuccess(Object model, Object returnValue) {
+                                                        public void 
onSuccess(Object nothing, Object returnValue) {
                                                             
getModel().getIsSoundcardEnabled().setEntity((Boolean) returnValue);
                                                             initTemplate();
                                                             initCdImage();
@@ -97,10 +97,10 @@
                     template.getStoragePoolId());
         }
 
-        AsyncDataProvider.getInstance().getWatchdogByVmId(new 
AsyncQuery(this.getModel(), new INewAsyncCallback() {
+        AsyncDataProvider.getInstance().getWatchdogByVmId(new AsyncQuery(null, 
new INewAsyncCallback() {
             @Override
-            public void onSuccess(Object target, Object returnValue) {
-                UnitVmModel model = (UnitVmModel) target;
+            public void onSuccess(Object nothing, Object returnValue) {
+                UnitVmModel model = TemplateVmModelBehavior.this.getModel();
                 @SuppressWarnings("unchecked")
                 Collection<VmWatchdog> watchdogs =
                         ((VdcQueryReturnValue) returnValue).getReturnValue();
@@ -116,16 +116,25 @@
         
getModel().getMigrationMode().setSelectedItem(template.getMigrationSupport());
 
         setupBaseTemplate(template.getBaseTemplateId());
+
     }
 
-    @Override
-    protected void baseTemplateSelectedItemChanged() {
-    }
+    protected void setupBaseTemplate(Guid baseTemplateId) {
+        AsyncDataProvider.getInstance().getTemplateById(new AsyncQuery(null,
+                        new INewAsyncCallback() {
+                            @Override
+                            public void onSuccess(Object nothing, Object 
returnValue) {
 
-    @Override
-    public void template_SelectedItemChanged()
-    {
-        // Leave this method empty. Not relevant for template.
+                                UnitVmModel model = getModel();
+                                VmTemplate template = (VmTemplate) returnValue;
+
+                                
model.getBaseTemplate().setItems(Collections.singletonList(template));
+                                
model.getBaseTemplate().setSelectedItem(template);
+                                model.getBaseTemplate().setIsChangable(false);
+                            }
+                        },
+                        getModel().getHash()),
+                baseTemplateId);
     }
 
     @Override
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java
index 174f35d..733711f 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UnitVmModel.java
@@ -59,6 +59,7 @@
 import org.ovirt.engine.ui.uicommonweb.models.hosts.numa.NumaSupportModel;
 import org.ovirt.engine.ui.uicommonweb.models.hosts.numa.VmNumaSupportModel;
 import org.ovirt.engine.ui.uicommonweb.models.storage.DisksAllocationModel;
+import org.ovirt.engine.ui.uicommonweb.models.templates.TemplateWithVersion;
 import 
org.ovirt.engine.ui.uicommonweb.models.vms.instancetypes.InstanceTypeManager;
 import org.ovirt.engine.ui.uicommonweb.models.vms.key_value.KeyValueModel;
 import org.ovirt.engine.ui.uicommonweb.validation.GuidValidation;
@@ -216,7 +217,7 @@
             getMaxAssignedVmsPerUser().setIsChangable(false);
 
             getBaseTemplate().setIsChangable(false);
-            getTemplate().setIsChangable(false);
+            getTemplateWithVersion().setIsChangable(false);
             getInstanceTypes().setIsChangable(false);
             getMemSize().setIsChangable(false);
             getTotalCPUCores().setIsChangable(false);
@@ -390,16 +391,14 @@
         privateStorageDomain = value;
     }
 
-    private NotChangableForVmInPoolListModel<VmTemplate> privateTemplate;
+    private NotChangableForVmInPoolListModel<TemplateWithVersion> 
templateWithVersion;
 
-    public ListModel<VmTemplate> getTemplate()
-    {
-        return privateTemplate;
+    public ListModel<TemplateWithVersion> getTemplateWithVersion() {
+        return templateWithVersion;
     }
 
-    private void setTemplate(NotChangableForVmInPoolListModel<VmTemplate> 
value)
-    {
-        privateTemplate = value;
+    public void 
setTemplateWithVersion(NotChangableForVmInPoolListModel<TemplateWithVersion> 
templateWithVersion) {
+        this.templateWithVersion = templateWithVersion;
     }
 
     private NotChangableForVmInPoolListModel<VmTemplate> baseTemplate;
@@ -865,6 +864,15 @@
         privateDisplayProtocol = value;
     }
 
+    /**
+     * Template provisioning: clone / thin - how to copy template disk.
+     * <ul>
+     *     <li>true - Clone</li>
+     *     <li>false - Thin</li>
+     * </ul>
+     * Aggregation of {@link #privateProvisioningThin_IsSelected}
+     * and {@link #privateProvisioningClone_IsSelected}.
+     */
     private NotChangableForVmInPoolEntityModel<Boolean> privateProvisioning;
 
     public EntityModel<Boolean> getProvisioning()
@@ -1509,9 +1517,8 @@
         setSysprepEnabled(new EntityModel<Boolean>());
         getVmInitEnabled().getEntityChangedEvent().addListener(this);
         setVmInitModel(new VmInitModel());
-
-        setTemplate(new NotChangableForVmInPoolListModel<VmTemplate>());
-        getTemplate().getSelectedItemChangedEvent().addListener(this);
+        setTemplateWithVersion(new 
NotChangableForVmInPoolListModel<TemplateWithVersion>());
+        
getTemplateWithVersion().getSelectedItemChangedEvent().addListener(this);
 
         setInstanceTypes(new NotChangableForVmInPoolListModel<InstanceType>());
 
@@ -1754,9 +1761,9 @@
                 behavior.updateEmulatedMachines();
                 behavior.updateCustomCpu();
             }
-            else if (sender == getTemplate())
+            else if (sender == getTemplateWithVersion())
             {
-                template_SelectedItemChanged(sender, args);
+                templateWithVersion_SelectedItemChanged(sender, args);
             }
             else if (sender == getTimeZone())
             {
@@ -2210,9 +2217,8 @@
         }
     }
 
-    private void template_SelectedItemChanged(Object sender, EventArgs args)
-    {
-        behavior.template_SelectedItemChanged();
+    private void templateWithVersion_SelectedItemChanged(Object sender, 
EventArgs args) {
+        behavior.templateWithVersion_SelectedItemChanged();
         behavior.updateMigrationForLocalSD();
     }
 
@@ -2624,8 +2630,12 @@
 
         return null;
     }
-
     public boolean validate() {
+        return this.validate(true);
+    }
+
+    public boolean validate(boolean templateWithVersionRequired) {
+
         boolean hwPartValid = validateHwPart();
 
         getInstanceTypes().setIsValid(true);
@@ -2675,8 +2685,9 @@
                     && getComment().getIsValid());
         }
 
-
-        getTemplate().validateSelectedItem(new IValidation[] { new 
NotEmptyValidation() });
+        if (templateWithVersionRequired) {
+            getTemplateWithVersion().validateSelectedItem(new 
IValidation[]{new NotEmptyValidation()});
+        }
         getDisksAllocationModel().validateEntity(new IValidation[] {});
 
         getCdImage().setIsValid(true);
@@ -2712,7 +2723,7 @@
 
         setValidTab(TabName.GENERAL_TAB, isValidTab(TabName.GENERAL_TAB)
                 && getDataCenterWithClustersList().getIsValid()
-                && getTemplate().getIsValid());
+                && getTemplateWithVersion().getIsValid());
 
         setValidTab(TabName.INITIAL_RUN_TAB, getTimeZone().getIsValid());
 
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UserPortalNewTemplateVmModelBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UserPortalNewTemplateVmModelBehavior.java
index d88d8b0..225302e 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UserPortalNewTemplateVmModelBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UserPortalNewTemplateVmModelBehavior.java
@@ -55,10 +55,10 @@
     }
 
     private void initTemplates(List<VmTemplate> templates) {
-        List<VmTemplate> rootTemplates = filterNotBaseTemplates(templates);
+        List<VmTemplate> rootTemplates = keepBaseTemplates(templates);
 
         // Filter templates list (include only templates that belong to the 
selected datacenter)
-        ArrayList<VmTemplate> templatesList = new ArrayList<VmTemplate>();
+        List<VmTemplate> templatesList = new ArrayList<>();
         VmTemplate blankTemplate = null;
         DataCenterWithCluster dataCenterWithCluster = 
getModel().getDataCenterWithClustersList().getSelectedItem();
         StoragePool selectedDataCenter = dataCenterWithCluster.getDataCenter();
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UserPortalNewVmModelBehavior.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UserPortalNewVmModelBehavior.java
index 6e9eff6..3d8ba12 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UserPortalNewVmModelBehavior.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/UserPortalNewVmModelBehavior.java
@@ -6,7 +6,6 @@
 import org.ovirt.engine.core.common.businessentities.VDSGroup;
 import org.ovirt.engine.core.common.businessentities.VmTemplate;
 import org.ovirt.engine.core.common.businessentities.VmTemplateStatus;
-import 
org.ovirt.engine.core.common.businessentities.comparators.NameableComparator;
 import 
org.ovirt.engine.core.common.queries.GetEntitiesWithPermittedActionParameters;
 import org.ovirt.engine.core.common.queries.IdQueryParameters;
 import org.ovirt.engine.core.common.queries.VdcQueryParametersBase;
@@ -16,7 +15,6 @@
 import org.ovirt.engine.ui.frontend.AsyncQuery;
 import org.ovirt.engine.ui.frontend.Frontend;
 import org.ovirt.engine.ui.frontend.INewAsyncCallback;
-import org.ovirt.engine.ui.uicommonweb.Linq;
 import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
 import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemModel;
 import 
org.ovirt.engine.ui.uicommonweb.models.vms.instancetypes.InstanceTypeManager;
@@ -27,7 +25,6 @@
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 
 @SuppressWarnings("unused")
@@ -56,10 +53,8 @@
                     public void onSuccess(Object target, Object returnValue) {
 
                         final List<StoragePool> dataCenters = new 
ArrayList<StoragePool>();
-                        for (StoragePool a : (ArrayList<StoragePool>) 
returnValue)
-                        {
-                            if (a.getStatus() == StoragePoolStatus.Up)
-                            {
+                        for (StoragePool a : (ArrayList<StoragePool>) 
returnValue) {
+                            if (a.getStatus() == StoragePoolStatus.Up) {
                                 dataCenters.add(a);
                             }
                         }
@@ -114,63 +109,29 @@
     public void executed(FrontendMultipleQueryAsyncResult result)
     {
         List<VdcQueryReturnValue> returnValueList = result.getReturnValues();
-        ArrayList<VmTemplate> templates =
+        List<VmTemplate> templates =
                 (ArrayList<VmTemplate>) 
returnValueList.get(0).getReturnValue();
-        initTemplates(templates);
+        initTemplateWithVersion(templates);
         initCdImage();
     }
 
-    private void initTemplates(List<VmTemplate> templates)
-    {
-        List<VmTemplate> rootTemplates = filterNotBaseTemplates(templates);
-
-        // Filter templates list (include only templates that belong to the 
selected datacenter)
-        ArrayList<VmTemplate> templatesList = new ArrayList<VmTemplate>();
-        VmTemplate blankTemplate = null;
-        DataCenterWithCluster dataCenterWithCluster = 
getModel().getDataCenterWithClustersList().getSelectedItem();
+    @Override
+    protected void initTemplateWithVersion(List<VmTemplate> templates) {
+        DataCenterWithCluster dataCenterWithCluster = 
this.getModel().getDataCenterWithClustersList().getSelectedItem();
         StoragePool selectedDataCenter = dataCenterWithCluster.getDataCenter();
         Guid selectedDataCenterId = selectedDataCenter.getId();
         if (selectedDataCenterId == null) {
             return;
         }
-
-        for (VmTemplate template : rootTemplates)
-        {
-            Guid datacenterId =
-                    template.getStoragePoolId() == null ? Guid.Empty : 
template.getStoragePoolId();
-
-            if (template.getId().equals(Guid.Empty))
-            {
-                blankTemplate = template;
-            }
-            else if (!selectedDataCenterId.equals(datacenterId))
-            {
-                continue;
-            }
-            else if (template.getStatus() == VmTemplateStatus.OK)
-            {
-                templatesList.add(template);
+        List<VmTemplate> properArchitectureTemplates = 
AsyncDataProvider.getInstance()
+                .filterTemplatesByArchitecture(templates, 
dataCenterWithCluster.getCluster().getArchitecture());
+        List<VmTemplate> properStateTemplates = new ArrayList<>();
+        for (VmTemplate template : properArchitectureTemplates) {
+            if (template.getStatus().equals(VmTemplateStatus.OK)) {
+                properStateTemplates.add(template);
             }
         }
-
-        // Sort list and position "Blank" template as first
-        Collections.sort(templatesList, new NameableComparator());
-        if (blankTemplate != null && rootTemplates.contains(blankTemplate))
-        {
-            templatesList.add(0, blankTemplate);
-        }
-
-        List<VmTemplate> filteredTemplates = 
AsyncDataProvider.getInstance().filterTemplatesByArchitecture(templatesList,
-                dataCenterWithCluster.getCluster().getArchitecture());
-
-        // If there was some template selected before, try select it again.
-        VmTemplate prevBaseTemplate = 
getModel().getBaseTemplate().getSelectedItem();
-
-        getModel().getBaseTemplate().setItems(filteredTemplates);
-
-        
getModel().getBaseTemplate().setSelectedItem(Linq.firstOrDefault(filteredTemplates,
-                new Linq.TemplatePredicate(prevBaseTemplate != null ? 
prevBaseTemplate.getId() : Guid.Empty)));
-
+        super.initTemplateWithVersion(properStateTemplates);
         updateIsDisksAvailable();
     }
 
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmListModel.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmListModel.java
index 0bbad98..74ec5e0 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmListModel.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmListModel.java
@@ -93,7 +93,6 @@
 import org.ovirt.engine.ui.uicommonweb.models.storage.ImportCloneModel;
 import org.ovirt.engine.ui.uicommonweb.models.tags.TagListModel;
 import org.ovirt.engine.ui.uicommonweb.models.tags.TagModel;
-import org.ovirt.engine.ui.uicommonweb.models.templates.LatestVmTemplate;
 import org.ovirt.engine.ui.uicommonweb.models.templates.VmBaseListModel;
 import org.ovirt.engine.ui.uicommonweb.models.userportal.AttachCdModel;
 import org.ovirt.engine.ui.uicommonweb.place.WebAdminApplicationPlaces;
@@ -1250,14 +1249,14 @@
             model.startProgress(null);
 
             Frontend.getInstance().runMultipleAction(VdcActionType.ExportVm, 
parameters,
-                                                     new 
IFrontendMultipleActionAsyncCallback() {
-                                                         @Override
-                                                         public void 
executed(FrontendMultipleActionAsyncResult result) {
-                                                             ExportVmModel 
localModel = (ExportVmModel) result.getState();
-                                                             
localModel.stopProgress();
-                                                             cancel();
-                                                         }
-                                                     }, model);
+                    new IFrontendMultipleActionAsyncCallback() {
+                        @Override
+                        public void executed(FrontendMultipleActionAsyncResult 
result) {
+                            ExportVmModel localModel = (ExportVmModel) 
result.getState();
+                            localModel.stopProgress();
+                            cancel();
+                        }
+                    }, model);
         }
     }
 
@@ -1404,7 +1403,7 @@
             return;
         }
 
-        if (!model.validate())
+        if (!model.validate(false))
         {
             model.setIsValid(false);
         }
@@ -2009,7 +2008,7 @@
             final VM selectedItem = (VM) getSelectedItem();
             // explicitly pass non-editable field from the original VM
             
getcurrentVm().setCreatedByUserId(selectedItem.getCreatedByUserId());
-            
getcurrentVm().setUseLatestVersion(model.getTemplate().getSelectedItem() 
instanceof LatestVmTemplate);
+            
getcurrentVm().setUseLatestVersion(model.getTemplateWithVersion().getSelectedItem().isLatest());
 
             if (selectedItem.isRunningOrPaused()) {
                 
AsyncDataProvider.getInstance().getVmChangedFieldsForNextRun(editedVm, 
getcurrentVm(), getUpdateVmParameters(false), new AsyncQuery(this,
@@ -2130,7 +2129,7 @@
         if (!StringHelper.isNullOrEmpty(model.getVmId().getEntity())) {
             vm.setId(new Guid(model.getVmId().getEntity()));
         }
-        vm.setUseLatestVersion(model.getTemplate().getSelectedItem() 
instanceof LatestVmTemplate);
+        
vm.setUseLatestVersion(model.getTemplateWithVersion().getSelectedItem().isLatest());
 
         AddVmParameters parameters = new AddVmParameters(vm);
         
parameters.setDiskInfoDestinationMap(model.getDisksAllocationModel().getImageToDestinationDomainMap());
@@ -2414,20 +2413,16 @@
         if (command == getNewVmCommand())
         {
             newVm();
-        }
-        else if (command == getImportVmCommand()) {
+        } else if (command == getImportVmCommand()) {
             importVms();
-        }
-        else if (command == getCloneVmCommand())
+        } else if (command == getCloneVmCommand())
         {
             cloneVm();
-        }
-        else if (command == getEditCommand())
+        } else if (command == getEditCommand())
         {
             edit();
         }
-        else if (command == getEditConsoleCommand())
-        {
+        else if (command == getEditConsoleCommand()) {
             editConsole();
         }
         else if (command == getConsoleConnectCommand())
@@ -2445,44 +2440,36 @@
         else if (command == getPauseCommand())
         {
             pause();
-        }
-        else if (command == getStopCommand())
+        } else if (command == getStopCommand())
         {
             stop();
-        }
-        else if (command == getShutdownCommand())
+        } else if (command == getShutdownCommand())
         {
             shutdown();
         }
         else if (command == getRebootCommand()) {
             reboot();
-        }
-        else if (command == getMigrateCommand())
+        } else if (command == getMigrateCommand())
         {
             migrate();
         }
         else if (command == getNewTemplateCommand())
         {
             newTemplate();
-        }
-        else if (command == getRunOnceCommand())
+        } else if (command == getRunOnceCommand())
         {
             runOnce();
-        }
-        else if (command == getExportCommand())
-        {
+        } else if (command == getExportCommand()) {
             export();
         }
         else if (command == getCreateSnapshotCommand())
         {
             createSnapshot();
         }
-        else if (command == getGuideCommand())
-        {
+        else if (command == getGuideCommand()) {
             guide();
         }
-        else if (command == getRetrieveIsoImagesCommand())
-        {
+        else if (command == getRetrieveIsoImagesCommand()) {
             retrieveIsoImages();
         }
         else if (command == getChangeCdCommand())
@@ -2656,8 +2643,8 @@
                 setWindow(null); // remove current window first
                 setWindow(importVmsModel);
             }
-        })
-        .setTitle(ConstantsManager.getInstance().getConstants().back())
+                })
+                        
.setTitle(ConstantsManager.getInstance().getConstants().back())
         );
 
         model.getCommands().add(new UICommand(CMD_CANCEL, this)
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java
index 05c2578..0bc1d09 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/VmModelBehaviorBase.java
@@ -4,10 +4,10 @@
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Map;
 import java.util.Set;
 import java.util.TreeSet;
 import org.ovirt.engine.core.common.TimeZoneType;
@@ -44,6 +44,7 @@
 import org.ovirt.engine.ui.frontend.AsyncQuery;
 import org.ovirt.engine.ui.frontend.Frontend;
 import org.ovirt.engine.ui.frontend.INewAsyncCallback;
+import org.ovirt.engine.ui.uicommonweb.models.templates.LatestVmTemplate;
 import org.ovirt.engine.ui.uicommonweb.Linq;
 import org.ovirt.engine.ui.uicommonweb.dataprovider.AsyncDataProvider;
 import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
@@ -52,11 +53,12 @@
 import org.ovirt.engine.ui.uicommonweb.models.SystemTreeItemType;
 import org.ovirt.engine.ui.uicommonweb.models.hosts.numa.NumaSupportModel;
 import org.ovirt.engine.ui.uicommonweb.models.hosts.numa.VmNumaSupportModel;
-import org.ovirt.engine.ui.uicommonweb.models.templates.LatestVmTemplate;
+import org.ovirt.engine.ui.uicommonweb.models.templates.TemplateWithVersion;
 import 
org.ovirt.engine.ui.uicommonweb.models.vms.instancetypes.InstanceTypeManager;
 import org.ovirt.engine.ui.uicompat.ConstantsManager;
 import org.ovirt.engine.ui.uicompat.UIConstants;
 import org.ovirt.engine.ui.uicompat.UIMessages;
+
 
 public abstract class VmModelBehaviorBase<TModel extends UnitVmModel> {
 
@@ -64,7 +66,6 @@
     private final UIMessages messages = 
ConstantsManager.getInstance().getMessages();
 
     private TModel privateModel;
-    private final HashMap<Guid, List<VmTemplate>> baseTemplateToSubTemplates = 
new HashMap<Guid, List<VmTemplate>>();
 
     public TModel getModel() {
         return privateModel;
@@ -176,7 +177,7 @@
     protected void buildModel(VmBase vmBase) {
     }
 
-    public abstract void template_SelectedItemChanged();
+    public void templateWithVersion_SelectedItemChanged() {}
 
     public abstract void postDataCenterWithClusterSelectedItemChanged();
 
@@ -218,49 +219,94 @@
 
     }
 
-    protected List<VmTemplate> filterNotBaseTemplates(List<VmTemplate> 
templates) {
-        List<VmTemplate> baseTemplates = new ArrayList<VmTemplate>();
-        for (VmTemplate template : templates) {
-            if (template.getId().equals(template.getBaseTemplateId())) {
-                baseTemplates.add(template);
-                baseTemplateToSubTemplates.put(template.getId(),
-                        new ArrayList<VmTemplate>());
-            }
-        }
-
-        for (VmTemplate template : templates) {
-            Guid baseTemplateId = template.getBaseTemplateId();
-            if (baseTemplateToSubTemplates.containsKey(baseTemplateId)) {
-                baseTemplateToSubTemplates.get(baseTemplateId).add(template);
-            }
-        }
-
-        for (List<VmTemplate> subversions : 
baseTemplateToSubTemplates.values()) {
-            Collections.sort(subversions, new Comparator<VmTemplate>() {
-                @Override
-                public int compare(VmTemplate o1, VmTemplate o2) {
-                    return o2.getTemplateVersionNumber() - 
o1.getTemplateVersionNumber();
-                }
-            });
-        }
-
-        for (List<VmTemplate> subversions : 
baseTemplateToSubTemplates.values()) {
-            subversions.add(0, new LatestVmTemplate(subversions.get(0)));
-        }
-
-        return baseTemplates;
+    protected void baseTemplateSelectedItemChanged() {
     }
 
-    protected void baseTemplateSelectedItemChanged() {
-        VmTemplate baseTemplate = 
getModel().getBaseTemplate().getSelectedItem();
-        if (baseTemplate != null) {
-            List<VmTemplate> subVersions = 
baseTemplateToSubTemplates.get(baseTemplate.getId());
-            getModel().getTemplate().setItems(new 
ArrayList<VmTemplate>(subVersions));
-
-            // it's safe because in index 0 there's the latest version and
-            // in index 1 the base version or the last custom version
-            getModel().getTemplate().setSelectedItem(subVersions.get(1));
+    /**
+     *
+     * @param templates empty list is allowed
+     */
+    protected void initTemplateWithVersion(List<VmTemplate> templates) {
+        List<TemplateWithVersion> templatesWithVersion = 
createTemplateWithVersionsAddLatest(templates);
+        TemplateWithVersion previouslySelectedTemplate = 
getModel().getTemplateWithVersion().getSelectedItem();
+        TemplateWithVersion templateToSelect = 
computeTemplateWithVersionToSelect(templatesWithVersion,
+                previouslySelectedTemplate);
+        getModel().getTemplateWithVersion().setItems(templatesWithVersion);
+        if (templateToSelect != null) {
+            
getModel().getTemplateWithVersion().setSelectedItem(templateToSelect);
         }
+    }
+
+    private static TemplateWithVersion computeTemplateWithVersionToSelect(
+            List<TemplateWithVersion> newItems,
+            TemplateWithVersion previousSelection) {
+        if (previousSelection == null) {
+            return computeNewTemplateWithVersionToSelect(newItems);
+        }
+        Guid previousTemplateId = 
previousSelection.getTemplateVersion().getId();
+        TemplateWithVersion oldTemplateToSelect = Linq.firstOrDefault(
+                newItems,
+                new Linq.TemplateWithVersionPredicate(previousTemplateId));
+        return oldTemplateToSelect != null
+                ? oldTemplateToSelect
+                : computeNewTemplateWithVersionToSelect(newItems);
+    }
+
+    /**
+     * It prefers to select second element (usually [Blank-1]) to the first 
one (usually [Blank-latest]).
+     */
+    private static TemplateWithVersion 
computeNewTemplateWithVersionToSelect(List<TemplateWithVersion> newItems) {
+        return newItems.isEmpty()
+                ? null
+                : newItems.size() >= 2
+                        ? newItems.get(1)
+                        : newItems.get(0);
+    }
+
+    /**
+     *
+     * @param templates raw templates from backend, latest not included
+     * @return model ready for 'Template' comobox, including latest
+     */
+    private static List<TemplateWithVersion> 
createTemplateWithVersionsAddLatest(List<VmTemplate> templates) {
+        final Map<Guid, VmTemplate> baseIdToBaseTemplateMap = new HashMap<>();
+        final Map<Guid, VmTemplate> baseIdToLastVersionMap = new HashMap<>();
+        for (VmTemplate template : templates) {
+            if (template.isBaseTemplate())  {
+                baseIdToBaseTemplateMap.put(template.getId(), template);
+                baseIdToLastVersionMap.put(template.getId(), template);
+            }
+        }
+        final List<TemplateWithVersion> result = new ArrayList<>();
+        for (VmTemplate template : templates) {
+            // update last version map
+            if 
(baseIdToLastVersionMap.get(template.getBaseTemplateId()).getTemplateVersionNumber()
 < template.getTemplateVersionNumber()) {
+                baseIdToLastVersionMap.put(template.getBaseTemplateId(), 
template);
+            }
+
+            final VmTemplate baseTemplate = 
baseIdToBaseTemplateMap.get(template.getBaseTemplateId());
+            result.add(new TemplateWithVersion(baseTemplate, template));
+        }
+
+        // add latest
+        for (Map.Entry<Guid, VmTemplate> pair : 
baseIdToLastVersionMap.entrySet()) {
+            VmTemplate baseTemplate = 
baseIdToBaseTemplateMap.get(pair.getKey());
+            VmTemplate latestTemplate = new LatestVmTemplate(pair.getValue());
+            result.add(new TemplateWithVersion(baseTemplate, latestTemplate));
+        }
+
+        Collections.sort(result);
+        return result;
+    }
+
+    protected static List<VmTemplate> keepBaseTemplates(List<VmTemplate> 
templates) {
+        List<VmTemplate> baseTemplates = new ArrayList<>();
+        for (VmTemplate template : templates) {
+            if (template.isBaseTemplate()) {
+                baseTemplates.add(template);
+            }
+        }
+        return baseTemplates;
     }
 
     protected void isSubTemplateEntityChanged() {
@@ -525,9 +571,8 @@
                 }, getModel().getHash()), version);
     }
 
-    public void initDisks()
-    {
-        VmTemplate template = getModel().getTemplate().getSelectedItem();
+    public void initDisks() {
+        VmTemplate template = 
getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion();
 
         AsyncDataProvider.getInstance().getTemplateDiskList(new 
AsyncQuery(getModel(),
                 new INewAsyncCallback() {
@@ -580,9 +625,9 @@
             return;
         }
 
-        VmTemplate template = getModel().getTemplate().getSelectedItem();
+        TemplateWithVersion templateWithVersion = 
getModel().getTemplateWithVersion().getSelectedItem();
 
-        if (template != null && !template.getId().equals(Guid.Empty))
+        if (templateWithVersion != null && 
!templateWithVersion.getTemplateVersion().getId().equals(Guid.Empty))
         {
             postInitStorageDomains();
         }
@@ -742,24 +787,33 @@
         
getModel().getIsVirtioScsiEnabled().setIsAvailable(isVirtioScsiEnabled);
     }
 
-    protected void setupTemplate(Guid templateId, final boolean useLatest) {
-        AsyncDataProvider.getInstance().getTemplateById(new 
AsyncQuery(getModel(),
+    protected void setupReadOnlyTemplateWithVersion(Guid templateId, final 
boolean useLatest) {
+        AsyncDataProvider.getInstance().getTemplateById(new AsyncQuery(null,
                         new INewAsyncCallback() {
                             @Override
-                            public void onSuccess(Object target, Object 
returnValue) {
+                            public void onSuccess(Object nothing, Object 
returnValue) {
+                                VmTemplate rawTemplate = (VmTemplate) 
returnValue;
 
-                                UnitVmModel model = (UnitVmModel) target;
-                                VmTemplate template = (VmTemplate) returnValue;
+                                final VmTemplate template = useLatest
+                                        ? new LatestVmTemplate(rawTemplate)
+                                        : rawTemplate;
 
-                                if (useLatest) {
-                                    template = new LatestVmTemplate(template);
+                                if (template.isBaseTemplate()) {
+                                    TemplateWithVersion templateCouple = new 
TemplateWithVersion(template, template);
+                                    
setReadOnlyTemplateWithVersion(templateCouple);
+                                } else {
+                                    
AsyncDataProvider.getInstance().getTemplateById(new AsyncQuery(null,
+                                                    new INewAsyncCallback() {
+                                                        @Override
+                                                        public void 
onSuccess(Object nothing, Object returnValue) {
+                                                            VmTemplate 
baseTemplate = (VmTemplate) returnValue;
+                                                            
TemplateWithVersion templateCouple = new TemplateWithVersion(baseTemplate, 
template);
+                                                            
setReadOnlyTemplateWithVersion(templateCouple);
+                                                        }
+                                                    }),
+                                            template.getBaseTemplateId());
                                 }
 
-                                
setupBaseTemplate(template.getBaseTemplateId());
-
-                                
model.getTemplate().setItems(Collections.singletonList(template));
-                                model.getTemplate().setSelectedItem(template);
-                                model.getTemplate().setIsChangable(false);
                             }
                         },
                         getModel().getHash()
@@ -768,22 +822,11 @@
         );
     }
 
-    protected void setupBaseTemplate(Guid baseTemplateId) {
-        AsyncDataProvider.getInstance().getTemplateById(new 
AsyncQuery(getModel(),
-                new INewAsyncCallback() {
-                    @Override
-                    public void onSuccess(Object target, Object returnValue) {
+    protected void setReadOnlyTemplateWithVersion(TemplateWithVersion 
templateCouple) {
+        
getModel().getTemplateWithVersion().setItems(Collections.singleton(templateCouple));
+        getModel().getTemplateWithVersion().setSelectedItem(templateCouple);
+        getModel().getTemplateWithVersion().setIsChangable(false);
 
-                        UnitVmModel model = (UnitVmModel) target;
-                        VmTemplate template = (VmTemplate) returnValue;
-
-                        
model.getBaseTemplate().setItems(Collections.singletonList(template));
-                        model.getBaseTemplate().setSelectedItem(template);
-                        model.getBaseTemplate().setIsChangable(false);
-                    }
-                },
-                getModel().getHash()),
-                baseTemplateId);
     }
 
     protected void updateCpuPinningVisibility() {
@@ -1198,9 +1241,6 @@
 
     /**
      * In case of a blank template, use the proper value for the default OS.
-     *
-     * @param VmBase
-     * @param ArchitectureType
      */
     protected void setSelectedOSType(VmBase vmBase,
             ArchitectureType architectureType) {
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/InstanceTypeManager.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/InstanceTypeManager.java
index 8d617a5..1fd5b77 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/InstanceTypeManager.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/InstanceTypeManager.java
@@ -176,7 +176,7 @@
     private void registerListeners(UnitVmModel model) {
         ManagedFieldsManager managedFieldsManager = new ManagedFieldsManager();
         
model.getInstanceTypes().getSelectedItemChangedEvent().addListener(managedFieldsManager);
-        
model.getTemplate().getSelectedItemChangedEvent().addListener(managedFieldsManager);
+        
model.getTemplateWithVersion().getSelectedItemChangedEvent().addListener(managedFieldsManager);
 
         model.getOSType().getSelectedItemChangedEvent().addListener(new 
IEventListener<EventArgs>() {
             @Override
@@ -230,7 +230,7 @@
 
             boolean customInstanceTypeSelected = 
model.getInstanceTypes().getSelectedItem() instanceof CustomInstanceType;
 
-            if (sender == model.getTemplate() && customInstanceTypeSelected) {
+            if (sender == model.getTemplateWithVersion() && 
customInstanceTypeSelected) {
                 // returns the VM/Pool's static data or the template 
(depending on the specific new/existing manager)
                 updateInstanceTypeFieldsFrom(getSource());
             } else if (sender == model.getInstanceTypes() && 
!customInstanceTypeSelected) {
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/InstanceTypeModelBehaviorBase.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/InstanceTypeModelBehaviorBase.java
index 826d8d1..6234514 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/InstanceTypeModelBehaviorBase.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/InstanceTypeModelBehaviorBase.java
@@ -63,11 +63,6 @@
     }
 
     @Override
-    public void template_SelectedItemChanged() {
-
-    }
-
-    @Override
     public void postDataCenterWithClusterSelectedItemChanged() {
     }
 
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/NewPoolInstanceTypeManager.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/NewPoolInstanceTypeManager.java
index 0596f24..73e7622 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/NewPoolInstanceTypeManager.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/NewPoolInstanceTypeManager.java
@@ -16,7 +16,9 @@
         if (!(getModel().getInstanceTypes().getSelectedItem() instanceof 
CustomInstanceType)) {
             return (VmBase) getModel().getInstanceTypes().getSelectedItem();
         } else {
-            return getModel().getTemplate().getSelectedItem();
+            return getModel().getTemplateWithVersion().getSelectedItem() == 
null
+                    ? null
+                    : 
getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion();
         }
     }
 
@@ -33,8 +35,9 @@
     protected void maybeSetSingleQxlPci(VmBase vmBase) {
         boolean customInstanceTypeUsed = 
getModel().getInstanceTypes().getSelectedItem() instanceof CustomInstanceType;
         boolean blankTemplateUsed =
-                getModel().getTemplate().getSelectedItem() != null
-                        && 
getModel().getTemplate().getSelectedItem().getId().equals(Guid.Empty);
+                getModel().getTemplateWithVersion().getSelectedItem() != null
+                        && 
getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion()
+                                .getId().equals(Guid.Empty);
         if (customInstanceTypeUsed && blankTemplateUsed) {
             maybeSetEntity(getModel().getIsSingleQxlEnabled(), 
getModel().getIsQxlSupported());
         } else {
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/NewVmInstanceTypeManager.java
 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/NewVmInstanceTypeManager.java
index 5de63ef..14694eb 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/NewVmInstanceTypeManager.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/main/java/org/ovirt/engine/ui/uicommonweb/models/vms/instancetypes/NewVmInstanceTypeManager.java
@@ -20,7 +20,9 @@
         if (!(getModel().getInstanceTypes().getSelectedItem() instanceof 
CustomInstanceType)) {
             return (VmBase) getModel().getInstanceTypes().getSelectedItem();
         } else {
-            return getModel().getTemplate().getSelectedItem();
+            return getModel().getTemplateWithVersion().getSelectedItem() == 
null
+                    ? null
+                    : 
getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion();
         }
     }
 
@@ -44,8 +46,9 @@
         // The default value cannot be set in the template since it will 
effect REST API as well
         boolean customInstanceTypeUsed = 
getModel().getInstanceTypes().getSelectedItem() instanceof CustomInstanceType;
         boolean blankTemplateUsed =
-                getModel().getTemplate().getSelectedItem() != null
-                        && 
getModel().getTemplate().getSelectedItem().getId().equals(Guid.Empty);
+                getModel().getTemplateWithVersion().getSelectedItem() != null
+                        && 
getModel().getTemplateWithVersion().getSelectedItem().getTemplateVersion()
+                                .getId().equals(Guid.Empty);
         if (customInstanceTypeUsed && blankTemplateUsed) {
             maybeSetEntity(getModel().getIsSingleQxlEnabled(), 
getModel().getIsQxlSupported());
         } else {
diff --git 
a/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/models/vms/BaseVmListModelTest.java
 
b/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/models/vms/BaseVmListModelTest.java
index 0017f7d..216d08a 100644
--- 
a/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/models/vms/BaseVmListModelTest.java
+++ 
b/frontend/webadmin/modules/uicommonweb/src/test/java/org/ovirt/engine/ui/uicommonweb/models/vms/BaseVmListModelTest.java
@@ -17,6 +17,7 @@
 import org.ovirt.engine.core.common.businessentities.profiles.CpuProfile;
 import org.ovirt.engine.ui.uicommonweb.models.EntityModel;
 import org.ovirt.engine.ui.uicommonweb.models.ListModel;
+import org.ovirt.engine.ui.uicommonweb.models.templates.TemplateWithVersion;
 
 public class BaseVmListModelTest extends BaseVmTest {
 
@@ -24,7 +25,9 @@
         when(model.getVmType().getSelectedItem()).thenReturn(VM_TYPE);
         VmTemplate template = new VmTemplate();
         template.setId(TEMPLATE_GUID);
-        when(model.getTemplate().getSelectedItem()).thenReturn(template);
+        TemplateWithVersion templateWithVersion = 
mock(TemplateWithVersion.class);
+        when(templateWithVersion.getTemplateVersion()).thenReturn(template);
+        
when(model.getTemplateWithVersion().getSelectedItem()).thenReturn(templateWithVersion);
         when(model.getName().getEntity()).thenReturn(VM_NAME);
         InstanceType instanceType = new VmTemplate();
         instanceType.setId(INSTANCE_TYPE_ID);


-- 
To view, visit http://gerrit.ovirt.org/36278
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Iec2b522adc72ed0040e79059c1cd514ae3f5ad34
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-engine
Gerrit-Branch: master
Gerrit-Owner: Jakub Niedermertl <[email protected]>
_______________________________________________
Engine-patches mailing list
[email protected]
http://lists.ovirt.org/mailman/listinfo/engine-patches

Reply via email to