1 var nowUtil = require('./nowUtil').nowUtil;
  2 var ScopeTable = function (data) {
  3   this.data = data || {};
  4   this.arrays = {};
  5 };
  6 
  7 ScopeTable.prototype.get = function (fqn) {
  8   // does not reconstruct objects. :P
  9   return this.data[fqn];
 10 };
 11 
 12 ScopeTable.prototype.set = function (fqn, val) {
 13   if (this.data[fqn] !== undefined) {
 14     this.deleteChildren(fqn);
 15   } else {
 16     var lastIndex = fqn.lastIndexOf('.');
 17     var parent = fqn.substring(0, lastIndex);
 18     this.addParent(parent, fqn.substring(lastIndex + 1));
 19   }
 20   delete this.arrays[fqn];
 21   return (this.data[fqn] = val);
 22 };
 23 
 24 ScopeTable.prototype.addParent = function (parent, key) {
 25   if (parent) {
 26     if (!Array.isArray(this.data[parent])) {
 27       this.set(parent, []); // Handle changing a non-object to an object.
 28     }
 29     this.data[parent].push(key);
 30   }
 31 };
 32 
 33 ScopeTable.prototype.deleteChildren = function (fqn) {
 34   var keys = this.data[fqn];
 35   if (Array.isArray(this.data[fqn])) {
 36     // Deleting a child will remove it via splice.
 37     for (var i = 0; keys.length;) {
 38       // Recursive delete all children.
 39       this.deleteVar(fqn + '.' + keys[i]);
 40     }
 41   }
 42 };
 43 
 44 ScopeTable.prototype.deleteVar = function (fqn) {
 45   var lastIndex = fqn.lastIndexOf('.');
 46   var parent = fqn.substring(0, lastIndex);
 47 
 48   if (nowUtil.hasProperty(this.data, fqn)) {
 49     // Remove from its parent.
 50     var index = this.data[parent].indexOf(fqn.substring(lastIndex + 1));
 51     if (index > -1) {
 52       this.data[parent].splice(index, 1);
 53     }
 54     this.deleteChildren(fqn);
 55     delete this.data[fqn];
 56     delete this.arrays[fqn];
 57   }
 58 };
 59 
 60 ScopeTable.prototype.flagAsArray = function (fqn, len) {
 61   return (this.arrays[fqn] = len);
 62 };
 63 
 64 exports.ScopeTable = ScopeTable;