whole_func_string: function update(obj, expression){
      if(isObject(expression)) for(var key in expression){
          if(isObject(expression[key])){
              
              if(key==='$set') obj = update(obj, expression[key]);
              
              else if(key==='$inc') for(var prop in expression[key]){
                  if(typeof expression[key][prop] === 'number'){
                      var orig = deepGet(obj, prop);
                      if(orig === undefined) obj = deepSet(obj, prop, expression[key][prop]);
                      else if(typeof orig === 'number') obj = deepSet(obj, prop, orig+expression[key][prop]);
                  }
              }
              
              else if(key==='$max' || key==='$min') for(var prop in expression[key]){
                  if(typeof expression[key][prop] === 'number'){
                      var orig = deepGet(obj, prop);
                      if(key==='$max' && orig < expression[key][prop]) obj = deepSet(obj, prop, expression[key][prop]);
                      else if(key==='$min' && orig > expression[key][prop]) obj = deepSet(obj, prop, expression[key][prop]);
                  }
                  
              }
              
              else if(key==='$pull' || key==='$pullAll') for(var prop in expression[key]){
                  var orig = deepGet(obj, prop), value = expression[key][prop];
                  if(Array.isArray(orig)){
                      if(!Array.isArray(value)) value = [value];
                      for(var i=0;i<value.length;i++){
                          var index = orig.indexOf( value[i] );
                          if(index!==-1) orig.splice(index, 1);
                      }
                      obj = deepSet(obj, prop, orig);
                  }
              }
              
              else if(key==='$push') for(var prop in expression[key]){
                  var orig = deepGet(obj, prop), value = expression[key][prop];
                  if(value.$each) value = value.$each;
                  if(Array.isArray(orig)){
                      if(!Array.isArray(value)) value = [value];
                      for(var i=0;i<value.length;i++){
                          orig.push(value[i]);
                      }
                      obj = deepSet(obj, prop, orig);
                  }
              }
              
              else if(key[0]==='$') continue; // skip not recognized keys
              
              else obj = deepSet(obj, key, expression[key]); // key is simple property
          }
          
          // if expression.$set, ignore data properties outside it
          else if(!expression.$set) obj = deepSet(obj, key, expression[key]);
      }
      return obj;
  }
func_code_string: function update(obj, expression){
      if(isObject(expression)) for(var key in expression){
          if(isObject(expression[key])){
              
              if(key==='$set') obj = update(obj, expression[key]);
              
              else if(key==='$inc') for(var prop in expression[key]){
                  if(typeof expression[key][prop] === 'number'){
                      var orig = deepGet(obj, prop);
                      if(orig === undefined) obj = deepSet(obj, prop, expression[key][prop]);
                      else if(typeof orig === 'number') obj = deepSet(obj, prop, orig+expression[key][prop]);
                  }
              }
              
              else if(key==='$max' || key==='$min') for(var prop in expression[key]){
                  if(typeof expression[key][prop] === 'number'){
                      var orig = deepGet(obj, prop);
                      if(key==='$max' && orig < expression[key][prop]) obj = deepSet(obj, prop, expression[key][prop]);
                      else if(key==='$min' && orig > expression[key][prop]) obj = deepSet(obj, prop, expression[key][prop]);
                  }
                  
              }
              
              else if(key==='$pull' || key==='$pullAll') for(var prop in expression[key]){
                  var orig = deepGet(obj, prop), value = expression[key][prop];
                  if(Array.isArray(orig)){
                      if(!Array.isArray(value)) value = [value];
                      for(var i=0;i<value.length;i++){
                          var index = orig.indexOf( value[i] );
                          if(index!==-1) orig.splice(index, 1);
                      }
                      obj = deepSet(obj, prop, orig);
                  }
              }
              
              else if(key==='$push') for(var prop in expression[key]){
                  var orig = deepGet(obj, prop), value = expression[key][prop];
                  if(value.$each) value = value.$each;
                  if(Array.isArray(orig)){
                      if(!Array.isArray(value)) value = [value];
                      for(var i=0;i<value.length;i++){
                          orig.push(value[i]);
                      }
                      obj = deepSet(obj, prop, orig);
                  }
              }
              
              else if(key[0]==='$') continue; // skip not recognized keys
              
              else obj = deepSet(obj, key, expression[key]); // key is simple property
          }
          
          // if expression.$set, ignore data properties outside it
          else if(!expression.$set) obj = deepSet(obj, key, expression[key]);
      }
      return obj;
  }
func_documentation_string: /*
  Update object using mongodb update query
  implemented: $set, $inc, $max, $min