function ContextManager() {
	this.history = {};
	this.history.stack = [];
	this.history.maxLength = 20; // arbitrary
	this.history.cursor = 0;
	this.history.push = function(historyItem){
		this.stack.push(historyItem);
	};
	this.history.clear = function() {// remove all history
		this.stack = [];
	};
	this.history.getCurrentPosition = function() {
		return this.cursor;
	};
	this.history.setCurrentPosition = function(n) {
		if (n > this.stack.length - 1) {
			this.cursor = this.stack.length - 1;
		} else if ( n < 0) {
			this.cursor = 0;
		} else {
			this.cursor = n;
		}
	};
	this.history.get = function(index) { // get history item at index
		if (index >= 0 && index < this.stack.length) {
			return this.stack[index];
		}
	};
	this.history.next = function(n) {// advance the cursor n positions
		if (this.cursor < (this.stack.length - n)) {
			this.cursor = this.cursor + n;
		} else {
			this.cursor = this.stack.length - 1;
		}
		return this.getCurrentPosition();
	};
	this.history.previous = function(n) {// move the cursor n positions backwards
		if ((this.cursor - n) > 0) {
			this.cursor = this.cursor - n;
		} else {
			this.cursor = 0;
		}
		return this.getCurrentPosition();
	};
	this.history.hasNext = function() {
		return (this.stack.length - this.cursor > 1);
	};
	this.history.hasPrevious = function() {
		return this.cursor > 0;
	};
	this.history.size = function() {
		return this.stack.length;
	};
	
	
	var gl = [];
	// initialize the context to all genes in the dataset
	for (var i=0; i<genes.list.length; i++) {
		if(genes.list[i].inContext) gl.push(i);
	}
	
	this.addHistory = function(historyItem) {
		this.history.push(historyItem);
		
		if (this.history.size() > 1) { // Skip logging the first one, since it is the default history item.
			var htopicName = (typeof historyItem.topicName === 'undefined') ? 'undefined' : historyItem.topicName;
		}
	};
	
	this.addHistory(new HistoryItem("initialize", "genes", genes, gl,0));  // initialize the list
	
	this.updateViewers = function(historyAction) {

	  
		if(Charts[gSelType]) {
			window.setTimeout(function() {
        Charts[gSelType].calcRowCols();
      },0);
		}
		
    // if(parent.view.historyPanel) {
    //  // add an object to the graph
    //  parent.view.historyPanel.render(historyAction);
    // }
    // if(parent.view.wheel) {
    //  // redraw the wheel center and title
    //  if(parent.view.pageType == "context") {
    //    // update the hierarchies to determine what's in or out
    //    for (var i=0;i<hierarchies.length; i++) {
    //      hierarchies[i].setContext();
    //    }
    //    // have to redo the hierarchy because the chip colors have changed due to context
    //    
    //    if(!tourOptions.isOnTour) parent.view.document.body.style.cursor = "wait";
    //    window.setTimeout(function() {
    //        parent.view.wheel.rim.colorByContext();  // recolor the rim, don't relay it out
    //        parent.view.wheel.center.layout();    // need a new wheel center
    //      
    //        //parent.view.wheel.resize(parent.view.wheel.wide, parent.view.wheel.hi);
    //        parent.view.wheel.rim.hiliteChip();
    // 
    //        var selGenes = parent.view.selectionMgr.get().geneList;
    //        for (var i=0; i<selGenes.length; i++) {
    //          var g = genes.list[selGenes[i]];
    //          if(g.inContext) {
    //            // redraw the wheel center and title
    //            if(g.graphics.wheel) g.graphics.wheel.select();
    //          } 
    //        }
    //        
    //        if(!tourOptions.isOnTour) parent.view.document.body.style.cursor = "default";
    //      }, 0); // allow the cursor to be set
    //    //parent.view.legend.setVizType(); 
    //  } else {
    //    if(!tourOptions.isOnTour) parent.view.document.body.style.cursor = "wait";
    //    window.setTimeout(function() {
    //        parent.view.wheel.center.layout();
    //        parent.view.wheel.setContextBtns();
    //        if(!tourOptions.isOnTour) parent.view.document.body.style.cursor = "default";
    //      }, 0); // allow the cursor to be set
    //  }
    //  parent.view.wheel.setContextBtns();
    // }


		if (details) {
      details.set();
		}
		
		
	};
	
	this.setGeneList = function(listOfGenes, topicObj) {
		//  use topicObj if its available - do an add then focus
		// if topicObj is null then make sure this list is in and all others are out
		if(topicObj) {
			var topic = topicObj.getTopic();
			if(topic.indexOf("process")>=0) topic = "processes";
			this.addHistory(new HistoryItem("add",     topic, topicObj, topicObj.getGeneList(), this.history.length ));
			this.addHistory(new HistoryItem("focusOn", topic, topicObj, topicObj.getGeneList(), this.history.length ));
		} else {
			this.addHistory(new HistoryItem("setGeneList", "genes", genes, listOfGenes, this.history.length));
		}
		this.update("addHistory");
	};

	this.getGeneList = function() {
		var g;
		var gLen = genes.list.length;
		var contextList = [];

		for (g=0; g < gLen; g++) {
			if (genes.list[g].inContext) contextList.push(genes.list[g].index);
		}

		return contextList;
	};
	
	this.changeContext = function(action, topic, topicObj, listOfGenes) {
		this.addHistory(new HistoryItem(action, topic, topicObj, listOfGenes, this.history.size()));		

		// refresh the selection to take the context into account
		selectionMgr.set(topicObj, listOfGenes, '',true);

		this.update("addHistory");
	};
		
	this.update = function(historyAction) {
		this.updateTopics();
		this.updateViewers(historyAction);
	};
	
	this.previous = function() {
		if(this.history.size() > 1) {
			var curHistory = this.history.pop();   // get rid of the current one
			
			var gl = this.history.get(this.history.size()-1).items;
			for (var i=0; i<genes.list.length; i++) {
				genes.list[i].inContext = false;
			};
			for (i=0; i<gl.length; i++) {
				genes.list[gl[i]].inContext = true;
			}
			this.update("removeHistory");
		}
	};
	
	
	this.restore = function(index) {
		if(index >=0 && index < this.history.size()-1) {
			// clone this and append to the end of the history
			var cloneItem = this.history.get(index);
			this.addHistory(new HistoryItem("restore", cloneItem.topicName, cloneItem.topicObj, cloneItem.context, this.history.size(), cloneItem));
			this.update("addHistory");
		}
	};
	
	this.updateTopics = function() {
		// go thru and calculate all topic items to see if they're in or out
    for (var i=0; i<pathways.list.length; i++) {
     pathways.list[i].inContext = false;
    }
		for (i=0; i<diseases.list.length; i++) {
			diseases.list[i].inContext = false;
		}
		for (i=0; i<bioProcesses.list.length; i++) {
			bioProcesses.list[i].inContext = false;
		};
		for (i=0; i<interactionTypeGroups.list.length; i++) {
			var itg = interactionTypeGroups.list[i];
			itg.inContext = false;
			for (var j=0;j<itg.genes.length; j++) {
				if(genes.list[itg.genes[j]].inContext) {
					itg.inContext = true;
					break;
				};
			};
		};
		for (i=0; i<genes.list.length; i++) {
			if(genes.list[i].inContext) {
				var g = genes.list[i];
				for (var j=0; j<g.diseases.length; j++) {
					diseases.list[g.diseases[j]].inContext = true;
				};
				for (j=0; j<g.pathways.length; j++) {
					pathways.list[g.pathways[j]].inContext = true;
				};
				for (j=0; j<g.bioProcesses.length; j++) {
					bioProcesses.list[g.bioProcesses[j]].inContext = true;
				};
			}
		};
		
	};
}

//////////////////
//////////////////////      insights
/////////////////

function InsightManager() {
	this.list = new Object();
	for (t in pageTypeList) {   // insightMgr.list["diseases"] = new Array();
		this.list[pageTypeList[t]] = [];
	}
	
	this.getCount = function() {
		return this.list.length;
	};
	
	this.isGeneMember = function(g, insItem) {
		// is o a member of this insight?
		var gid = g.getId();
		for (var i=0; i<insItem.genes.length; i++) {
			if(insItem.genes[i] == gid) return true;
		}
		return false;
	};
	
	this.add = function(pageTopic, objName, objId, geneIds, type, observation) {
		var id = "insight_" + (new Date()).getTime();
		var insight = new InsightItem(id, pageTopic, objName, objId, geneIds, type, observation);
		this.list[pageTopic].push(insight);

		ingEventLogger.log(pageTopic,'Insights','Add', type, {InsightText: observation});
		parent._gaq.push(['_trackEvent', 'insights|'+parent.view.pageType+'Page', 'add', type]);
		return insight;
	};
	
	this.remove = function(insId, pageTopic) {
		var delInsight = null;
		var pt;
		for(t in pageTypeList) {
			pt = pageTypeList[t];
			for (var i=0; i<this.list[pt].length; i++) {
				if (this.list[pt][i].id == insId) {
					delInsight = this.list[pt].splice(i, 1);
					break;
				}
			}
			
			if (delInsight != null) {
				break;
			}
		}
		
		if (delInsight != null) {
			//this.save();
			ingEventLogger.log(pageTopic,'Insights','Remove', delInsight.type, {InsightText: delInsight.text});
			parent._gaq.push(['_trackEvent', 'insights|'+parent.view.pageType+'Page', 'remove', delInsight.type]);
		}
	};
	
	this.getInsightById = function(insId) {
		var pt;
		for(t in pageTypeList) {
			pt = pageTypeList[t];
			for (var i=0; i<this.list[pt].length; i++) {
				if (this.list[pt][i].id == insId) {
					return this.list[pt][i];
				}
			}
		}
		return null;
	};
	
	this.getGeneInsights = function(g) {
		var lst = [];
		var pt;
		for(t in pageTypeList) {
			pt = pageTypeList[t];
			for (var i=0; i<this.list[pt].length; i++) {
				if(this.isGeneMember(g, this.list[pt][i])) {
					lst.push(this.list[pt][i]);
				}
			}
		}
		return lst;
	};
	
	this.updateObservation = function(id, pt, txt) {
		var selInsight = this.getInsightById(id); 
		if (selInsight != null) {
			selInsight.observation = txt;
		}
	};


    this.load = function(callback) {
        if (this.loaded) {
            handleCallback(callback);
            return;
        }
        var reportid = parent.reportid;
        var url = "/bda/data/insight/load/" + reportid;
        var params = {};
        (function(insightMgr) {
            $.getJSON(url, params, function(json) {
                if (json) {
                    //insightMgr.list = deserialize(json);
                	insightMgr.list = json;
                	for (t in pageTypeList) {
                		if (!insightMgr.list[pageTypeList[t]]) {
                			insightMgr.list[pageTypeList[t]] = []; // add storage for all page types
                		}
                	}
                }
                insightMgr.loaded = true;
                handleCallback(callback);
            });
        })(this);
    };

    this.save = function(pageTopic, insId, callback) {
        var reportid = parent.reportid;
        var url = "/bda/data/insight/save";
        //var leanInsights = serialize(this.list);
        var params = {
            reportid: reportid,
            json: JSON.stringify(this.list)
        };
        $.post(url, params, function(xhr) {
            if (typeof callback == "function") {
                callback();
            } else if (typeof callback == "object") {
                callback[1].apply(callback[0], arguments);
            }
        });
        
        ingEventLogger.log(pageTopic,'Insights','Save', 'Insights', {count: this.getCount()});
        parent._gaq.push(['_trackEvent', 'insights|'+parent.view.pageType+'Page', 'save', this.getCount()]);
        
        if (insId) {
			var selInsight = this.getInsightById(insId);
			if (selInsight != null) {
				ingEventLogger.log(pageTopic,'Insights','Update', selInsight.type, {InsightText: selInsight.text});
				parent._gaq.push(['_trackEvent', 'insights|'+parent.view.pageType+'Page', 'update', selInsight.type]);
			}
		}
    };

    var handleCallback = function(callback) {
        if (typeof callback == "function") {
            callback();
        } else if (typeof callback == "object") {
            callback[1].apply(callback[0], arguments);
        }
    };
}

function InsightItem(id, pageTopic, name, objId, geneList, type, observation) {
	this.id = id;
	this.pageTopic = pageTopic;
	this.name = name;
	this.objId = objId;
	this.type = type;
	this.observation = observation ? observation : "";
	//this.jObj = jObj;  // reference to jQuery object
	this.genes = geneList;
}

//////////////////
/////////////////     selection

function SelectionManager() {
	// not yet implemented
	// this will direct updates for highlighting in the various viewers
	// such as details, geneMatrix, wheel, etc
	this.list = [];
	this.geneList = [];
	this.topic = '';
	this.index = null;
	this.o = null;
	this.topicMapping = [];
	this.topicMapping["diseases"]  		= "disease";  // this isn't good.... this is used to get proper object for details
	this.topicMapping["interactions"]  	= "gene";
	this.topicMapping["processes"]  	= "process";
	this.topicMapping["pathways"]  		= "pathway";
	this.topicMapping["biomarkers"]  	= "biomarker";

	this.history = {};
	this.history.stack = [];
	this.history.maxLength = 20; // arbitrary
	this.history.cursor = 0;
	this.history.size = function() {
		return this.stack.length;
	};
	this.history.push = function(historyItem){
		if (this.hasNext()) { // we have navigated back in history. If a new item is pushed then the history should be forked.
			this.fork(historyItem);
		} else {
			if (this.stack.length == this.maxLength) {
				this.stack = this.stack.slice(1); // remove the oldest item
			}
			this.stack.push(historyItem);
		}
	};
	this.history.pop = function() {
		return this.stack.pop();
	};
	this.history.next = function() {// advance the cursor one position
		if (this.cursor < this.stack.length - 1) {
			this.cursor++;
		}
		return this.getCurrentSelection();
	};
	this.history.previous = function() {// move the cursor one position backwards
		if (this.cursor > 0) {
			this.cursor--;
		}
		return this.getCurrentSelection();
	};
	this.history.clear = function() {// remove all history
		this.stack = [];
	};
	this.history.fork = function(historyItem) {// clear all history from the current cursor (and add a new item?)
		this.stack.splice(this.cursor + 1, this.stack.length - this.cursor, historyItem);
		this.cursor++;
	};
	this.history.getCurrentPosition = function() {
		return this.cursor;
	};
	this.history.getCurrentSelection = function() {
		var cursel = null;
		if (this.stack.length > 0) {
			cursel = this.stack[this.cursor];
		}
		return cursel;
	};
	this.history.hasNext = function() {
		return (this.stack.length - this.cursor > 1);
	};
	this.history.hasPrevious = function() {
		return this.cursor > 0;
	};
	
	this.history.createHistoryItem = function(iobj, igeneList) {
		var hi = {
			obj: iobj, 
			geneList: igeneList, 
			adhocGeneSet: null,
			calculateGeneSetProps: function() {
					this.adhocGeneSet = new AdHocGeneSet(this.obj == null ? "Unknown Name" : this.obj.name, this.geneList, this.obj);
					this.adhocGeneSet.calculateCommonality();
				}
			};
		hi.calculateGeneSetProps();
		
		return hi;
	};
	
	this.history.getItem = function(itemId) {
		var hi = null;
		for (var i = 0; i < this.stack.length; i++) {
			if (this.stack[i].obj.id == itemId) {
				hi = this.stack[i];
				break;
			}
		}
		
		return hi;
	};
	
	this.hilite = function() {
		var lastGene = null;
    var pageType = gSelType;
    
		if(!this.geneList) this.geneList = [];

		if(pageType == "interactions") {
			if(geneMatrix) {
				var go = null;
				if (this.o != null && this.o.getTopic() == "adhocGenes" && this.o.parentObj && this.o.parentObj != null && this.o.parentObj.getTopic() == "genes") {
					go = this.o.parentObj;
				} else {
					if (this.geneList.length == 1 && (this.o == null || this.o.getTopic() == "genes" )) {	
						go = genes.list[this.geneList[0]];
					}
				}


        if(go!= null && go.inContext && go.graphics.matrix) {
						go.graphics.matrix.select();
						geneMatrix.drawConnections(go);
        }
				
				for (var i=0; i<this.geneList.length; i++) {
					var g = genes.list[this.geneList[i]];
					if(g.inContext) {
						if(g.graphics.matrix) {
							g.graphics.matrix.select();
						}
					}
				}
			}
		} else {
			for (var i=0; i<this.geneList.length; i++) {
				var g = genes.list[this.geneList[i]];
				if(g.inContext) {
					if(geneMatrix) {
						// hide / restore genes, relayout and redraw
						if(g.graphics.matrix) {
							g.graphics.matrix.select();
						}
						
					}
					this.lastGene = g;
				}	
			}
			
    }
	};
	
	this.get = function() {
		return {obj:this.o, geneList:this.geneList};
	};
	
	
	this.dehilite = function() {
    var pageType = gSelType;	  
		for (var i=0; i<this.geneList.length; i++) {
			var g = genes.list[this.geneList[i]];
			if(g.inContext) {
				
				if(geneMatrix) {
					// hide / restore genes, relayout and redraw
					if(g.graphics.matrix) g.graphics.matrix.deselect();
				}
				
				if(pageType == "gene table" && parent.view.insights) {
					parent.view.insights.clear();
				}
			}
		}
    // RE - Im not hilighting the table
    // if(this.o) {
    //  if(parent.view.rankTable) {
    //    parent.view.rankTable.clearHilite();
    //  }
    // };
	};
	
	this.compareToCurrentSelection = function(newSelObj, newGeneList) { // returns true if the new selection is the same as the current selection
		
		var curhi = this.history.getCurrentSelection();
		var curSel = (curhi == null ? null : curhi.obj);
		if (newSelObj) {
			if (typeof newSelObj == "string") { // in the case of a pathway molecule DID or finding molecule DID 
				return curSel == newSelObj;
			} else { 
				if (curSel) {
					return curSel.id == newSelObj.id; // assumes that all the selectable objects have a 'id' property
				} else {
					return false;
				}
			}
		} else { // assumes newGeneList is not null 
			if (curSel) {
				return false;
			} else {
				var curgl = (curhi == null ? null : curhi.geneList);
				if (curgl != null) {
					var geneMap = new Object(); // add everything to a map so that is easier to compare
					for (var i = 0; i < curgl; i++) {
						geneMap[curgl[i].id] = curgl[i].id;
					}
					
					var isEqual = true;
					for (var i = 0; i < newGeneList; i++) {
						if (!geneMap.hasOwnProperty(newGeneList[i].id)) {
							isEqual = false;
							break;
						}
					}
					return isEqual;
				}
				
				return false;
			}
		}
	};
	
	this.set = function(o, geneList, shiftOpt, noLoad) {
		
		if (!o && (!geneList || geneList == null || geneList.length == 0)) return;
		// is this where add / remove is determined (using shift key modifier?)
		this.dehilite();  // remove hilite of any current objects
		
		if(o) {
			this.topic = o.getTopic();
			this.index = o.getIndex();
			this.o = o;
			if(geneList == null) {
				this.geneList = o.getGeneList();
			} else {
				this.geneList = geneList;
			}
		} else {
			this.topic = "";
			this.index = null;
			this.o = null;
			this.geneList = geneList;
		}
		
		if (!this.compareToCurrentSelection(o, geneList)) {
			// add this to the selection history stack
			if (!shiftOpt) {
				var hi = this.history.createHistoryItem(this.o, this.geneList);
				this.history.push(hi);
				this.history.next();
			}
		}
		
		if (!noLoad) this.displayInfo();
		// Not sure if this is required
    // if (parent.view.selectionNavPanel) {
    //  parent.view.selectionNavPanel.update();
    // }
		
		this.hilite();
	};

	this.displayInfo = function() {
    var pageType = gSelType;	  
		if (this.o) {
		  
      // if (parent.view.pageType == "gene table" && this.o.getTopic() == "genes"  && parent.view.insights) {
      //  var isights = insightMgr.getGeneInsights(this.o);
      //  parent.view.insights.loadList(isights);
      // }

			if (pageType != "summary"){ //Summary page doesn't have details section

				// Handle the details panel
				if (this.o.type == "category") {
          details.set(this.o.type, this.o);
				} else {
				  
          details.set(this.o.getTopic(), this.o);

          // if(this.o.getTopic() == pageHeaders[pageType].topicType) {
           // hilite row in rank table
           // TODO RE - We have no RankTable yet
           // if (rankTable) rankTable.setHilite(this.o);
          // }

					var scope = this;
					this.evidenceTimer = setTimeout(function() {scope.displayEvidence()}, 1000);

				}
			} else {
				if(this.lastGene != null && parent.view.pageType != "summary") {
					parent.view.details.set("gene", this.lastGene);   // fill details
				}
			}
			
      // var rankTable = Ext.getCmp('gridRankTable');
      // if (rankTable && this.o.getTopic() != pageHeaders[pageType].topicType) {
      //  rankTable.deselectAll();
      // }
		}

	};

	this.displayEvidence = function() {
	  var pageType = gSelType;
		// clear any previous evidence calls
		if (this.evidenceTimer) clearTimeout(this.evidenceTimer);

		//Handle the evidence panel
		if (evidencePanel != undefined) { // Do not show evidence if the panel does not exist. TODO: clear evidence panel.

			if (this.o.getTopic() == "genes") { // the evidence depends on the current chapter
				evidencePanel.set(this.o.getTopic(), this.o, evidence, pageType);
			} else if ((this.o.getTopic() == "adhocGenes")
				&&(pageType == "interactions" // show evidence only for the parent gene (only for the interaction chapter group selections)
				&& this.o.parentObj && this.o.parentObj != null && this.o.parentObj.getTopic() == "genes")) {
					var po = this.o.parentObj;
					if (po.inContext) {
						evidencePanel.set(po.getTopic(), po, evidence,pageType);
					}
			} else if (this.o.getTopic() != "nondatasetconcept") { // evidence for a nondatasetconcept is shown only in pathways chapter.
					evidencePanel.set(this.o.getTopic(), this.o, evidence, this.o.getTopic() == "bioProcesses" ? "process" : this.o.getTopic());
			} else {
				evidencePanel.hideAll();
			}

		}
	};
	
	// RE - Removed Next Previous from Ipad.
  // this.next = function() {
  //  if(this.history.hasNext()) {
  //    var curSel = this.history.getCurrentSelection();
  //    var curSelType = curSel.obj != null ? curSel.obj.topic : "genelist";
  //    ingEventLogger.log(parent.view.pageType,'SelectionHistory', 'next', curSelType, {size: curSel.geneList.length});
  //    parent._gaq.push(['_trackEvent', 'selectionHistory|'+parent.view.pageType+'Page', 'navNext', curSelType]);
  //    
  //    var newSel = this.history.next();
  //    var rankTable = null;
  //    rankTable = parent.view.Ext.getCmp('gridRankTable');
  // 
  //             if (rankTable 
  //                && newSel.obj.getTopic() == pageHeaders[parent.view.pageType].topicType
  //                && rankTable.hasItem(newSel.obj)) {
  // 
  //                  rankTable.selectItem(newSel.obj);
  //             } else {
  //              if (rankTable) {
  //                rankTable.deselectAll();
  //            }
  //      var gl = newSel.geneList;
  //      if (gl.length == 0) {
  //        gl = newSel.obj.getGenesInContext();
  //      }
  //             this.set(newSel.obj, gl, true);
  //             }
  //  }
  // };
	
	// RE - Removed Next Previous from Ipad.
  // this.previous = function() {
  //  
  //     if(this.history.hasPrevious()) {
  //       var curSel = this.history.getCurrentSelection();
  //    var curSelType = curSel.obj != null ? curSel.obj.topic : "genelist";
  //    ingEventLogger.log(parent.view.pageType,'SelectionHistory', 'previous', curSelType, {size: curSel.geneList.length});
  //    parent._gaq.push(['_trackEvent', 'selectionHistory|'+parent.view.pageType+'Page', 'navPrevious', curSelType]);
  //    
  //    var newSel = this.history.previous();
  //    var rankTable = null;
  //    rankTable = parent.view.Ext.getCmp('gridRankTable');
  //    
  //    if (rankTable 
  //         && newSel.obj.getTopic() == pageHeaders[parent.view.pageType].topicType
  //         && rankTable.hasItem(newSel.obj)) {
  //           rankTable.selectItem(newSel.obj);
  //       } else { 
  //         if (rankTable) {
  //           rankTable.deselectAll();
  //         }
  //         var gl = newSel.geneList;
  //         if (gl.length == 0) {
  //           gl = newSel.obj.getGenesInContext();
  //         }
  //         this.set(newSel.obj, gl, true);
  //       }
  //     }
  //   };
  // 
	this.isSelected = function(index, topic) {
		var isInSelection = false;
		if(topic == "genes") {
			for (var i=0; i<this.geneList.length; i++) {
				if(this.geneList[i] == index) {
					isInSelection = true;
					continue;
				}
			}
		}
		// only genes implemented so far...
		return isInSelection;
	};
}
