code: function(w, x, y, z) {
  
        parse(P, w, x, y, z);
  
        // Q1 * Q2 = [w1 * w2 - dot(v1, v2), w1 * v2 + w2 * v1 + cross(v1, v2)]
  
        // Not commutative because cross(v1, v2) != cross(v2, v1)!
  
        var w1 = this['w'];
        var x1 = this['x'];
        var y1 = this['y'];
        var z1 = this['z'];
  
        var w2 = P['w'];
        var x2 = P['x'];
        var y2 = P['y'];
        var z2 = P['z'];
  
        return new Quaternion(
                w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2,
                w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2,
                w1 * y2 + y1 * w2 + z1 * x2 - x1 * z2,
                w1 * z2 + z1 * w2 + x1 * y2 - y1 * x2);
      }
docs: Calculates the Hamilton product of two quaternions
  Leaving out the imaginary part results in just scaling the quat
  
  @param {number|Object|string} w real
  @param {number=} x imag
  @param {number=} y imag
  @param {number=} z imag
  @returns {Quaternion}