function DataObject(nameSpace, id){

	this.nameSpace = nameSpace
	this.id = id

	this.getValue = function(cellName){
		var cachedData = getCachedData(this.nameSpace)
		var updateSummary = cachedData.changeSummary.update[this.id]
		var sheet = cachedData.serverGraph[this.id]
		var value = null
		if(updateSummary && updateSummary[cellName] != null)
			value = updateSummary[cellName]
		else if(sheet)
			value = sheet[cellName]

		if (value != null)
		{
			if (value instanceof Array)
				return value;
			else if (value instanceof Object){
				if (cellName.indexOf('.') == -1) {
					if(arrayContainsKey(value,'selected'))
				    {
					    return value['selected']
				    }
				    else{
						for (var key in value){
							return key
						}
					}
					return ""
				}
				return value
			}
			else{
				return value;
			}
		}
		else{
			return ""
		}
	}

	this.getDisplayValue = function(cellName, format, category){
		var cachedData = getCachedData(this.nameSpace)
		var updateSummary = cachedData.changeSummary.update[this.id]
		var sheet = cachedData.serverGraph[this.id]
		var value = null
		if(updateSummary && updateSummary[cellName] != null)
			value = updateSummary[cellName]
		else if(sheet)
			value = sheet[cellName]

		if (value != null)
		{
			if (value instanceof Array)
				return formatdata(value, format, category)
			else if (value instanceof Object){
			 	if (cellName.indexOf('.') == -1) {
					if(arrayContainsKey(value,'selected'))
				    {
				    	var sheetid = value['selected']
				    	if (sheetid && value[sheetid])
				       		return formatdata(value[sheetid], format, category)
				    }
				    else{
						for (var key in value){
							return formatdata(value[key], format, category)
						}
					}
					return formatdata("", format, category)
				}
				return formatdata(value, format, category)
			}
			else{
				return formatdata(value, format, category)
			}
		}
		else {
			return formatdata("", format, category)
		}
	}

	this.get = function(refCellName){
		var value = this.getValue(refCellName)
		var cachedData = getCachedData(this.nameSpace)
		//need to revisit the delete parent refCellName
		var deleteSummary = cachedData.changeSummary.remove[this.id]
		var deletedKey = null
		if(deleteSummary != null){
			deleteKeyList = deleteSummary[refCellName]
			//check whether refernce item is present in deletesummary
			if (deleteKeyList && deleteKeyList.length > 0 && deleteKeyList.pop() == value){
				value = null
			}
		}
		var createSummary = cachedData.changeSummary.create[this.id]
		if(createSummary != null && createSummary[refCellName]){
			var idList = createSummary[refCellName];
			value = idList.pop();
		}
		if(value)
			return new DataObject(this.nameSpace, value)
		//logging("error", "get() the value for the cell '"+refCellName+"' inside the sheet '"+this.id+"' is null)
		return null;
	}

	this.getList = function(refCellName, childModelName, orderByCellName, isDesc){
		var list = new Array();
		var sheetIdList = this.getValue(refCellName+"."+childModelName)
		var cachedData = getCachedData(this.nameSpace)
		var deleteSummary = cachedData.changeSummary.remove[this.id]
		var deleteKeyList = null
		if(deleteSummary != null){
			deleteKeyList = deleteSummary[refCellName+"."+childModelName]
		}
		//because getValue returns empty str ""
		if(sheetIdList instanceof Object)
		{
			for (var id in sheetIdList){
				//check whether list item is present in deletesummary
				var isAvailableInDeleteDict = false
				if(deleteKeyList != null)
					isAvailableInDeleteDict = arrayContains(deleteKeyList, id)
				if(!isAvailableInDeleteDict)
					list.push(new DataObject(this.nameSpace, id));
			}
		}

		var createSummary = cachedData.changeSummary.create[this.id]
		if(createSummary != null && createSummary[refCellName+"."+childModelName]){
			var idList = createSummary[refCellName+"."+childModelName]
			for(var i in idList)
				list.push(new DataObject(this.nameSpace, idList[i]));
		}
		if(orderByCellName){
			if (isDesc)
				list.sort(function(a,b){return (a.getValue(orderByCellName) > b.getValue(orderByCellName)) ? -1 : ((a.getValue(orderByCellName) < b.getValue(orderByCellName)) ? 1 : 0)})
			else
				list.sort(function(a,b){return (a.getValue(orderByCellName) < b.getValue(orderByCellName)) ? -1 : ((a.getValue(orderByCellName) > b.getValue(orderByCellName)) ? 1 : 0)})
		}
		return list;
	}

	this.getDataObject = function(sheetId){
		return new DataObject(this.nameSpace, sheetId)
	}

	this.getUrlList = function(){
		var cachedData = getCachedData(this.nameSpace)
		return cachedData.baseUrlList
	}

	this.update = function(args){
		var cachedData = getCachedData(this.nameSpace)
		var changeSummary = cachedData.changeSummary
		if(arrayLength(args) > 0){
			var updatedSummary = changeSummary.update[this.id]
			if(updatedSummary == null){
				updatedSummary = {"SheetMetadataId":this.getValue("SheetMetadataId")}
				if(!cachedData.updateCount)
					cachedData.updateCount = 0
				cachedData.updateCount = cachedData.updateCount + 1
				updatedSummary["__OrderBy"] =  cachedData.updateCount
				changeSummary.update[this.id] = updatedSummary
			}
			$.extend(updatedSummary, args)
		}
		//console.info("********************  inside update method ************************")
		//console.info(changeSummary)
	}

	this.create = function( args ){
		var cachedData = getCachedData(this.nameSpace)
		var changeSummary = cachedData.changeSummary
		if(args.referenceCellName){
			var createSummary = changeSummary.create[this.id]
			if(createSummary == null){
				createSummary = {"SheetMetadataId":this.getValue("SheetMetadataId")}
				if(!cachedData.createCount)
					cachedData.createCount = 0
				cachedData.createCount = cachedData.createCount + 1
				createSummary["__OrderBy"] =  cachedData.createCount
				changeSummary.create[this.id] = createSummary
			}

			var refcellName = args.referenceCellName
			if(args.childModelName)
				refcellName += "."+args.childModelName

			var currentkeyList = createSummary[refcellName]
			if(currentkeyList == null || args.childModelName == null){
				//to create child reference it can be more than one,but creating parent reference should always be only one
				//if args.childModelName is null, then it is creation of parent reference,so the list is always newly created
				currentkeyList = new Array();
				createSummary[refcellName] = currentkeyList
			}
			//id generation
			var count = 0
			if(currentkeyList.length > 0){
				var lastRecordId = currentkeyList[currentkeyList.length - 1]
				count = parseInt(lastRecordId.split(".").pop()) + 1
			}
			var newSheetId = this.id+"."+refcellName+"."+count
			currentkeyList.push(newSheetId)

			var createdDataObject = new DataObject(this.nameSpace, newSheetId)
			//updating the newly created item part of update dict
			var updateDict = {"SheetId": newSheetId}
			if(args.data)
				$.extend(updateDict, args.data)
			createdDataObject.update(updateDict)

			//console.info("********************  inside create method ************************")
			//console.info(changeSummary)
			return createdDataObject
		}else{
			logging("error","referenceCellName param is missing while calling create command")
		}
	}

	this.remove = function( args ){
		var cachedData = getCachedData(this.nameSpace)
		var changeSummary = cachedData.changeSummary
		//need to check to delete the root sheet
		if(args.referenceCellName && args.instanceId){
			var isNewlyCreatedItem = false
			var refcellName = args.referenceCellName
			if(args.childModelName)
				refcellName += "."+args.childModelName

			var createSummary = changeSummary.create[this.id]
			if(createSummary && createSummary[refcellName]){
				var createdIdList = createSummary[refcellName]
				for(var i in createdIdList){
					if(createdIdList[i] == args.instanceId){
						isNewlyCreatedItem = true;
						//remove the element from createdDict and updateDict
						createdIdList.splice(i, 1)
						delete changeSummary.update[args.instanceId]
						break;
					}
				}
			}
			if(!isNewlyCreatedItem){
				var deleteSummary = changeSummary.remove[this.id]
				if(deleteSummary == null){
					deleteSummary = {"SheetMetadataId":this.getValue("SheetMetadataId")}
					changeSummary.remove[this.id] = deleteSummary
				}

				var currentkeyList = deleteSummary[refcellName]
				if(currentkeyList == null || args.childModelName == null){
					currentkeyList = new Array();
					deleteSummary[refcellName] = currentkeyList
					currentkeyList.push(args.instanceId)
				}else if(!arrayContains(currentkeyList, args.instanceId)){
					currentkeyList.push(args.instanceId)
				}
			}

			//console.info("********************  inside delete method ************************")
			//console.info(changeSummary)

		}else if(args.referenceCellName == null){
			logging("error","referenceCellName param is missing while calling delete command")
		}else{
			logging("error","instanceId param is missing while calling delete command")
		}
	}

	this.invoke = function( args ){
		var cachedData = getCachedData(this.nameSpace)
		var changeSummary = cachedData.changeSummary
		if(args.actionName){
			var rootSheet = cachedData.serverGraph[cachedData.instanceId]
			changeSummary.invoke["rootSheetMetadataId"] = cachedData.modelId
			if(cachedData.baseArguments.form)
				changeSummary.invoke["form"] = cachedData.baseArguments.form
			var invokeSummary = changeSummary.invoke[this.id]
			if(invokeSummary == null){
				invokeSummary = {"SheetMetadataId":this.getValue("SheetMetadataId")}
				if(!cachedData.invokeCount)
					cachedData.invokeCount = 0
				cachedData.invokeCount = cachedData.invokeCount + 1
				invokeSummary["__OrderBy"] =  cachedData.invokeCount
				changeSummary.invoke[this.id] = invokeSummary
			}

			var caption = args.caption?args.caption:args.actionName
			var actionArguments = args.data?args.data:{}
			invokeSummary[args.actionName+"~"+caption] = actionArguments
			//console.info("********************  inside invoke method ************************")
			//console.info(changeSummary)
		}else{
			logging("error","actionName param is missing while calling invoke command")
		}
	}

	this.getActualJson = function(sheetId)
	{
		if(!sheetId)
			sheetId = this.id
		var cachedData = getCachedData(this.nameSpace)
		return cachedData.serverGraph[sheetId]
	}

}
