').addClass('main-desc').append(
                                                $('
').html(_l('message.select.affinity.groups'))
                                            )
                                        );
                                        $step.find('.select-container').append(
                                            makeSelects(
                                                'affinity-groups',
                                                args.data.affinityGroups, {
                                                    name: 'name',
                                                    desc: 'description',
                                                    id: 'id'
                                                }, {
                                                    type: 'checkbox',
                                                    'wizard-field': 'affinity-groups'
                                                },
                                                args.data.selectedObj,
                                                args.data.selectedObjNonEditable
                                            )
                                        );
                                    } else {
                                        $step.find('.select-container').append(
                                            $('
').addClass('no-affinity-groups').html(_l('message.no.affinity.groups'))
                                        );
                                    }
                                }
                            }
                        };
                    },
                    'sshkeyPairs': function($step, formData) {
                        var originalValues = function(formData) {
                            if (formData.sshkeypair) {
                                $step.find('input[type=radio]').filter(function() {
                                    return $(this).val() == formData.sshkeypair;
                                }).click();
                            } else {
                                $step.find('input[type=radio]:first').click();
                            }
                        };
                        return {
                            response: {
                                success: function(args) {
                                    $step.find('.main-desc, p.no-sshkey-pairs').remove();
                                    if (args.data.sshkeyPairs && args.data.sshkeyPairs.length) {
                                        sortArrayByKey(args.data.sshkeyPairs, 'name');
                                        $step.prepend(
                                            $('
').addClass('main-desc').append(
                                                $('
').html(_l('message.please.select.ssh.key.pair.use.with.this.vm'))
                                            )
                                        );
                                        $step.find('.section.no-thanks').show();
                                        $step.find('.select-container').append(
                                            makeSelects(
                                                'sshkeypair',
                                                args.data.sshkeyPairs, {
                                                    name: 'name',
                                                    id: 'name'
                                                }, {
                                                    'wizard-field': 'sshkey-pairs'
                                                }
                                            )
                                        );
                                        originalValues(formData); // if we can select only one.
                                    } else {
                                        $step.find('.section.no-thanks').hide();
                                        $step.find('.select-container').append(
                                            $('
').addClass('no-sshkey-pairs').html(_l('You do not have any ssh key pairs. Please continue to the next step.'))
                                        );
                                    }
                                }
                            }
                        };
                    },
                    'network': function($step, formData) {
                        var showAddNetwork = true;
                        var checkShowAddNetwork = function($newNetwork) {
                            if (!showAddNetwork) {
                                $newNetwork.hide();
                            } else {
                                $newNetwork.show();
                            }
                        };
                        var originalValues = function(formData) {
                            // Default networks
                            $step.find('input[type=radio]').filter(function() {
                                return $(this).val() == formData['defaultNetwork'];
                            }).click();
                            // Optional networks
                            var selectedOptionalNetworks = [];
                            if ($.isArray(formData['shared-networks']) != -1) {
                                $(formData['shared-networks']).each(function() {
                                    selectedOptionalNetworks.push(this);
                                });
                            } else {
                                selectedOptionalNetworks.push(formData['shared-networks']);
                            }
                            var $checkboxes = $step.find('input[name=shared-networks]');
                            $(selectedOptionalNetworks).each(function() {
                                var networkID = this;
                                $checkboxes.filter(function() {
                                    return $(this).val() == networkID;
                                }).attr('checked', 'checked');
                            });
                        };
                        var $newNetwork = $step.find('.new-network');
                        var $newNetworkCheckbox = $newNetwork.find('input[type=checkbox]');
                        // Setup new network field
                        $newNetworkCheckbox.unbind('click');
                        $newNetworkCheckbox.click(function() {
                            $newNetwork.toggleClass('unselected');
                            // Select another default if hiding field
                            if ($newNetwork.hasClass('unselected')) {
                                $step.find('input[type=radio]:visible:first').click();
                            } else {
                                $newNetwork.find('input[type=radio]').click();
                            }
                        });
                        setTimeout(function() {
                            var $checkbox = $step.find('.new-network input[type=checkbox]');
                            var $newNetwork = $checkbox.closest('.new-network');
                            if ($step.find('.select.my-networks .select-container .select:visible').length) {
                                $checkbox.attr('checked', false);
                                $newNetwork.addClass('unselected');
                            } else {
                                $newNetwork.find('input[name=defaultNetwork]').filter('[value=new-network]').click();
                            }
                            $checkbox.change();
                        });
                        // Show relevant conditional sub-step if present
                        $step.find('.wizard-step-conditional').hide();
                        if ($.isFunction(args.showAddNetwork)) {
                            showAddNetwork = args.showAddNetwork({
                                data: formData,
                                context: context
                            });
                        }
                        // Filter network list by VPC ID
                        var filterNetworkList = function(vpcID) {
                            var $selects = $step.find('.my-networks .select-container .select');
                            var $visibleSelects = $($.grep($selects, function(select) {
                                var $select = $(select);
                                return args.vpcFilter($select.data('json-obj'), vpcID);
                            }));
                            var $addNetworkForm = $step.find('.select.new-network');
                            var $addNewNetworkCheck = $addNetworkForm.find('input[name=new-network]');
                            // VPC networks cannot be created via instance wizard
                            if (vpcID != -1) {
                                $step.find('.my-networks .select-container').addClass('single-select');
                                $addNetworkForm.hide();
                                if ($addNewNetworkCheck.is(':checked')) {
                                    $addNewNetworkCheck.click();
                                    $addNewNetworkCheck.attr('checked', false);
                                }
                            } else {
                                $step.find('.my-networks .select-container').removeClass('single-select');
                                $addNetworkForm.show();
                                checkShowAddNetwork($addNetworkForm);
                            }
                            $selects.find('input[type=checkbox]').attr('checked', false);
                            $selects.hide();
                            $visibleSelects.show();
                            // Select first visible item by default
                            $visibleSelects.filter(':first')
                                .find('input[type=radio]')
                                .click();
                            cloudStack.evenOdd($visibleSelects, 'div.select', {
                                even: function($elem) {
                                    $elem.removeClass('odd');
                                    $elem.addClass('even');
                                },
                                odd: function($elem) {
                                    $elem.removeClass('even');
                                    $elem.addClass('odd');
                                }
                            });
                        };
                        var $vpcSelect = $step.find('select[name=vpc-filter]');
                        $vpcSelect.unbind('change');
                        $vpcSelect.change(function() {
                            filterNetworkList($vpcSelect.val());
                        });
                        return {
                            response: {
                                success: function(args) {
                                    var vpcs = args.data.vpcs;
                                    var addClass = args.addClass;
                                    var removeClass = args.removeClass;
                                    // Populate VPC drop-down
                                    $vpcSelect.html('');
                                    sortArrayByKey(vpcs, 'name');
                                    $(vpcs).map(function(index, vpc) {
                                        var $option = $('');
                                        var id = vpc.id;
                                        var description = vpc.name;
                                        $option.attr('value', id);
                                        $option.html(description);
                                        $option.appendTo($vpcSelect);
                                    });
                                    // 'No VPC' option
                                    $(' ').attr('value', '-1').html(_l('ui.listView.filters.all')).prependTo($vpcSelect);
                                    $vpcSelect.val(-1);
                                    // Populate network offering drop-down
                                    $(args.data.networkOfferings).each(function() {
                                        $(' ')
                                            .val(this.id)
                                            .html(this.name)
                                            .appendTo($newNetwork.find('select'));
                                    });
                                    if (args.type) {
                                        $step.find('.wizard-step-conditional').filter(function() {
                                            return $(this).hasClass(args.type);
                                        }).show();
                                    } else {
                                        $step.find('.select-network').show();
                                    }
                                    // My networks
                                    $step.find('.my-networks .select-container').append(
                                        makeSelects('my-networks', args.data.networkObjs, {
                                            name: 'name',
                                            desc: 'type',
                                            id: 'id'
                                        }, {
                                            type: 'checkbox',
                                            'wizard-field': 'my-networks',
                                            secondary: {
                                                desc: 'Default',
                                                name: 'defaultNetwork',
                                                type: 'radio',
                                                'wizard-field': 'default-network'
                                            }
                                        })
                                    );
                                    // Add IP/advanced option fields
                                    $step.find('.my-networks .select-container .select, .select.new-network .select').each(function () {
                                        var $select = $(this);
                                        var $advancedLink = $('').addClass('advanced-options hide-if-unselected');
                                        var $specifyIpField = $('
').addClass('specify-ip hide-if-unselected').append(
                                            $('').html(_l('label.ip.address')),
                                            $('');
                                    var id = 'LEGACY';
                                    var description = 'LEGACY';
                                    $option.attr('value', id);
                                    $option.html(description);
                                    $option.appendTo($bootmode);
                                    var $option2 = $(' ');
                                    var id2 = 'SECURE';
                                    var description2 = 'SECURE';
                                    $option2.attr('value', id2);
                                    $option2.html(description2);
                                    $option2.appendTo($bootmode);
                                }
                                if(bootType.toLowerCase() == 'bios' ){
                                     $bootmode.html('');
                                     var $option = $(' ');
                                     var id = 'LEGACY';
                                     var description = 'LEGACY';
                                     $option.attr('value', id);
                                     $option.html(description);
                                     $option.appendTo($bootmode);
                                }
                            }
                            var $uefiselect  = $step.find('select[name=customboot]');
                            $uefiselect.unbind('change');
                            $uefiselect.change(function(){
                                 uefi($uefiselect.val());
                            });
                        });
                    }
                };
                $wizard.bind('cloudStack.instanceWizard.showStep', function(e, args) {
                    showStep(args.index, { refresh: true });
                });
                // Go to specified step in wizard,
                // updating nav items and diagram
                var showStep = function(index, options) {
                    if (!options) options = {};
                    var targetIndex = index - 1;
                    if (index <= 1) targetIndex = 0;
                    if (targetIndex == $steps.length) {
                        completeAction();
                        return;
                    }
                    var $targetStep = $($steps.hide()[targetIndex]).show();
                    var stepID = $targetStep.attr('wizard-step-id');
                    var formData = cloudStack.serializeForm($form);
                    if (options.refresh) {
                        $targetStep.removeClass('loaded');
                    }
                    if (!$targetStep.hasClass('loaded')) {
                        // Remove previous content
                        if (!$targetStep.hasClass('review')) { // Review row content is not autogenerated
                            $targetStep.find('.select-container:not(.fixed) div, option:not(:disabled)').remove();
                        }
                        dataProvider(
                            index,
                            dataGenerators[stepID](
                                $targetStep,
                                formData
                            )
                        );
                        if (!$targetStep.hasClass('repeat') && !$targetStep.hasClass('always-load')) $targetStep.addClass('loaded');
                    }
                    // Show launch vm button if last step
                    var $nextButton = $wizard.find('.button.next');
                    $nextButton.find('span').html(_l('label.next'));
                    $nextButton.removeClass('final');
                    if ($targetStep.hasClass('review')) {
                        $nextButton.find('span').html(_l('label.launch.vm'));
                        $nextButton.addClass('final');
                    }
                    // Hide previous button on first step
                    var $previousButton = $wizard.find('.button.previous');
                    if (index == 1) $previousButton.hide();
                    else $previousButton.show();
                    // Update progress bar
                    var $targetProgress = $progress.removeClass('active').filter(function() {
                        return $(this).index() <= targetIndex;
                    }).toggleClass('active');
                    // Update diagram; show/hide as necessary
                    $diagramParts.filter(function() {
                        return $(this).index() <= targetIndex;
                    }).fadeIn('slow');
                    $diagramParts.filter(function() {
                        return $(this).index() > targetIndex;
                    }).fadeOut('slow');
                    setTimeout(function() {
                        if (!$targetStep.find('input[type=radio]:checked').length) {
                            $targetStep.find('input[type=radio]:first').click();
                        }
                    }, 50);
                };
                // Events
                $wizard.click(function(event) {
                    var $target = $(event.target);
                    var $activeStep = $form.find('.step:visible');
                    // Next button
                    if ($target.closest('div.button.next').length) {
                        //step 2 - select template/ISO
                        if($activeStep.hasClass('select-iso')) {
                            if ($activeStep.find('.content:visible input:checked').length == 0) {
                                cloudStack.dialog.notice({
                                    message: 'message.step.1.continue'
                                });
                                return false;
                            }
                            $(window).trigger("cloudStack.module.instanceWizard.clickNextButton", {
                                $form: $form,
                                currentStep: 2
                            });
                        }
                        //step 6 - select network
                        if ($activeStep.find('.wizard-step-conditional.select-network:visible').length > 0) {
                            var data = $activeStep.data('my-networks');
                            if (!data) {
                                $activeStep.closest('form').data('my-networks', cloudStack.serializeForm(
                                    $activeStep.closest('form')
                                )['my-networks']);
                            }
                            if ($activeStep.find('input[type=checkbox]:checked').length == 0) { //if no checkbox is checked
                                cloudStack.dialog.notice({
                                    message: 'message.step.4.continue'
                                });
                                return false;
                            }
                            if ($activeStep.hasClass('next-use-security-groups')) {
                                var advSGFilter = args.advSGFilter({
                                    data: cloudStack.serializeForm($form)
                                });
                                if (advSGFilter == 0) { //when total number of selected sg networks is 0, then 'Select Security Group' is skipped, go to step 6 directly
                                    showStep(6);
                                } else if (advSGFilter > 0) { //when total number of selected sg networks > 0
                                    if ($activeStep.find('input[type=checkbox]:checked').length > 1) { //when total number of selected networks > 1
                                        cloudStack.dialog.notice({
                                            message: "Can't create a vm with multiple networks one of which is Security Group enabled"
                                        });
                                        return false;
                                    }
                                } else if (advSGFilter == -1) { // vm with multiple IPs is supported in KVM
                                    var $selectNetwork = $activeStep.find('input[type=checkbox]:checked');
                                    var myNetworkIps = [];
                                    $selectNetwork.each(function() {
                                        var $specifyIp = $(this).parent().find('.specify-ip input[type=text]');
                                        myNetworkIps.push($specifyIp.val() == -1 ? null : $specifyIp.val());
                                    });
                                    $activeStep.closest('form').data('my-network-ips', myNetworkIps);
                                    $selectNetwork.each(function() {
                                        if ($(this).parent().find('input[type=radio]').is(':checked')) {
                                            $activeStep.closest('form').data('defaultNetwork', $(this).val());
                                            return;
                                        }
                                    })
                                }
                            }
                        }
                        //step 6 - review (spcifiy displyname, group as well)
                        if ($activeStep.hasClass('review')) {
                            if ($activeStep.find('input[name=displayname]').length > 0 && $activeStep.find('input[name=displayname]').val().length > 0) {
                                //validate
                                var b = cloudStack.validate.vmHostName($activeStep.find('input[name=displayname]').val());
                                if (b == false)
                                    return false;
                            }
                        }
                        // Step 7 - Skip OVF properties tab if there are no OVF properties for the template
                        if ($activeStep.hasClass('sshkeyPairs')) {
                            if ($activeStep.hasClass('next-skip-ovf-properties')) {
                                showStep(8);
                            }
                        }
                        // Optional Step - Pre-step 8
                        if ($activeStep.hasClass('ovf-properties')) {
                            var ok = true;
                            if ($activeStep.find('input').length > 0) { //if no checkbox is checked
                                $.each($activeStep.find('input'), function(index, item) {
                                    var item = $activeStep.find('input#' + item.id);
                                    var internalCheck = true;
                                    if (this.maxLength && this.maxLength !== -1) {
                                        internalCheck = item.val().length <= this.maxLength;
                                    } else if (this.min && this.max) {
                                        var numberValue = parseFloat(item.val());
                                        internalCheck = numberValue >= this.min && numberValue <= this.max;
                                    }
                                    ok = ok && internalCheck;
                                });
                            }
                            if (!ok) {
                                cloudStack.dialog.notice({
                                    message: 'Please enter valid values for every property'
                                });
                                return false;
                            }
                        }
                        if (!$form.valid()) {
                            if ($form.find('input.error:visible, select.error:visible').length) {
                                return false;
                            }
                        }
                        if ($activeStep.hasClass('repeat')) {
                            showStep($steps.filter(':visible').index() + 1);
                        } else {
                            showStep($steps.filter(':visible').index() + 2);
                        }
                        return false;
                    }
                    // Previous button
                    if ($target.closest('div.button.previous').length) {
                        var $step = $steps.filter(':visible');
                        var $networkStep = $steps.filter('.network');
                        var index = $step.index();
                        $networkStep.removeClass('next-use-security-groups');
                        if (index) {
                            if (index == $steps.length - 1 && $networkStep.hasClass('next-use-security-groups')) {
                                showStep(5);
                            } else if ($activeStep.find('.select-security-group:visible').length &&
                                $activeStep.find('.select-network.no-add-network').length) {
                                showStep(5);
                            } else {
                                showStep(index);
                            }
                        }
                        if ($activeStep.hasClass('review')) {
                            if ($activeStep.hasClass('previous-skip-ovf-properties')) {
                                showStep(7);
                            }
                        }
                        return false;
                    }
                    // Close button
                    if ($target.closest('div.button.cancel').length) {
                        close();
                        return false;
                    }
                    // Edit link
                    if ($target.closest('div.edit').length) {
                        var $edit = $target.closest('div.edit');
                        showStep($edit.find('a').attr('href'));
                        return false;
                    }
                    return true;
                });
                showStep(1);
                $wizard.bind('change', function(event) {
                    var $target = $(event.target);
                    var $step = $target.closest('.step');
                    var $futureSteps = $step.siblings().filter(function() {
                        return $(this).index() > $step.index();
                    });
                    // Reset all fields in futher steps
                    $futureSteps.removeClass('loaded');
                });
                var minCustomDiskSize = args.minDiskOfferingSize ?
                                    args.minDiskOfferingSize() : 1;
                var maxCustomDiskSize = args.maxDiskOfferingSize ?
                    args.maxDiskOfferingSize() : 100;
                // Setup tabs and slider
                $wizard.find('.section.custom-size.custom-slider-container .size.min span').html(minCustomDiskSize);
                $wizard.find('.section.custom-size.custom-slider-container input[type=text]').val(minCustomDiskSize);
                $wizard.find('.section.custom-size.custom-slider-container .size.max span').html(maxCustomDiskSize);
                $wizard.find('.tab-view').tabs();
                $wizard.find('.slider').each(function() {
                   var $slider = $(this);
                    $slider.slider({
                        min: minCustomDiskSize,
                        max: maxCustomDiskSize,
                        start: function(event) {
                            $slider.closest('.section.custom-size').find('input[type=radio]').click();
                        },
                        slide: function(event, ui) {
                            $slider.closest('.section.custom-size').find('input[type=text]').val(
                                ui.value
                            );
                            $slider.closest('.step').find('span.custom-slider-container').html(
                                ui.value
                            );
                        }
                    });
                });
                $wizard.find('div.data-disk-offering div.custom-size input[type=text]').bind('change', function() {
                    var old = $wizard.find('div.data-disk-offering div.custom-size input[type=text]').val();
                    $wizard.find('div.data-disk-offering span.custom-slider-container').html(_s(old));
                });
                
                var wizardDialog = $wizard.dialog({
                    title: _l('label.vm.add'),
                    width: 896,
                    minHeight: 600,
                    height: 'auto',
                    closeOnEscape: false,
                    modal: true
                });
                var wizardDialogDiv = wizardDialog.closest('.ui-dialog');
                $('button.ui-dialog-titlebar-close').remove();
                return wizardDialogDiv.overlay();
            };
            instanceWizard(args);
        };
    };
})(jQuery, cloudStack);