return {\n key: optionValue.key,\n value: optionValue.value,\n id: generateId()\n };\n });\n\n var optionsToRemove = [];\n var optionsById = [];\n options.forEach(function(option) {\n optionsById[option.id] = option;\n });\n\n /**\n * Returns the current advanced options.\n *\n * @returns the current advanced options\n */\n function getOptions() {\n return options;\n }\n\n function getOptionByKey(key) {\n return options.find(function (option) {\n return option.key === key;\n });\n }\n\n /**\n * Builds an array with advanced options to submit, adding the deleted\n * options and options with modified keys with null values in order to\n * be properly handled by the backend.\n *\n * @returns the advanced options to submit\n */\n function buildOptions() {\n var optionsResult = [];\n if(isCluster){\n optionsResult = angular.copy(initialOptions);\n }\n var advOptionsByKey = {};\n optionsResult.forEach(function(optionValue) {\n optionValue.value = null;\n advOptionsByKey[optionValue.key] = optionValue;\n });\n\n if(!isCluster) {\n _.each(optionsToRemove, function(option) {\n optionsResult.push({\n _type: \"com.vmware.vim.binding.vim.storageDrs.OptionSpec\",\n option: {\n _type: 'com.vmware.vim.binding.vim.option.OptionValue',\n key: option.key,\n value: option.value\n },\n operation: \"remove\",\n removeKey: option.key\n });\n });\n }\n\n options.forEach(function(optionValue) {\n if (!optionValue || !optionValue.key || !optionValue.value) {\n return true;\n }\n if (advOptionsByKey[optionValue.key]) {\n advOptionsByKey[optionValue.key].value = optionValue.value;\n } else {\n\n if(isCluster){\n optionsResult.push({\n _type: 'com.vmware.vim.binding.vim.option.OptionValue',\n key: optionValue.key,\n value: optionValue.value\n });\n } else {\n if(optionValue.type !== undefined) {\n optionsResult.push({\n _type: \"com.vmware.vim.binding.vim.storageDrs.OptionSpec\",\n option: {\n _type: 'com.vmware.vim.binding.vim.option.OptionValue',\n key: optionValue.key,\n value: optionValue.value\n },\n operation: optionValue.type\n });\n }\n }\n\n }\n });\n return optionsResult;\n }\n\n /**\n * Adds a new advanced option.\n *\n * @param option to add\n */\n function addOption(option) {\n var newOptionId = generateId();\n var advancedOption = {\n key: option.key,\n value: option.value,\n id: newOptionId,\n type: \"add\"\n };\n optionsById[newOptionId] = advancedOption;\n options = options.concat([advancedOption]);\n\n return newOptionId;\n }\n\n /**\n * Updates advanced option by id.\n *\n * @param optionId\n * @param advancedOption option with new values\n */\n function updateOption(optionId, advancedOption) {\n var optionToUpdate = optionsById[optionId];\n\n if(isCluster) {\n optionToUpdate.key = advancedOption.key;\n optionToUpdate.value = advancedOption.value;\n optionToUpdate.type = \"edit\";\n } else {\n var optionToRemove;\n var optionExists = false;\n\n _.each(initialOptions, function(option,index) {\n if(index + 1 === optionToUpdate.id && option.key === optionToUpdate.key) {\n optionToRemove = {\n key: option.key,\n value: option.value,\n type: \"remove\"\n };\n optionExists = true;\n }\n });\n if (optionToUpdate.key === advancedOption.key && optionExists){\n optionToUpdate.value = advancedOption.value;\n optionToUpdate.type = \"edit\";\n } else {\n if (optionExists) {\n optionsToRemove.push(optionToRemove);\n }\n\n optionToUpdate.key = advancedOption.key;\n optionToUpdate.value = advancedOption.value;\n optionToUpdate.type = \"add\";\n }\n }\n }\n\n /**\n * Removes an advanced option by id.\n *\n * @param optionId\n */\n function removeOption(optionId) {\n var optionExists = false;\n if(optionsById[optionId] !== undefined ) {\n _.each(initialOptions, function(option, index) {\n if (index + 1 === optionsById[option