text: import binarySearch from '../Core/binarySearch.js';
  import Check from '../Core/Check.js';
  import defaultValue from '../Core/defaultValue.js';
  import defined from '../Core/defined.js';
  import DeveloperError from '../Core/DeveloperError.js';
  import Event from '../Core/Event.js';
  import ExtrapolationType from '../Core/ExtrapolationType.js';
  import JulianDate from '../Core/JulianDate.js';
  import LinearApproximation from '../Core/LinearApproximation.js';
  
      var PackableNumber = {
          packedLength : 1,
          pack : function(value, array, startingIndex) {
              startingIndex = defaultValue(startingIndex, 0);
              array[startingIndex] = value;
          },
          unpack : function(array, startingIndex, result) {
              startingIndex = defaultValue(startingIndex, 0);
              return array[startingIndex];
          }
      };
  
      //We can't use splice for inserting new elements because function apply can't handle
      //a huge number of arguments.  See https://code.google.com/p/chromium/issues/detail?id=56588
      function arrayInsert(array, startIndex, items) {
          var i;
          var arrayLength = array.length;
          var itemsLength = items.length;
          var newLength = arrayLength + itemsLength;
  
          array.length = newLength;
          if (arrayLength !== startIndex) {
              var q = arrayLength - 1;
              for (i = newLength - 1; i >= startIndex; i--) {
                  array[i] = array[q--];
              }
          }
  
          for (i = 0; i < itemsLength; i++) {
              array[startIndex++] = items[i];
          }
      }
  
      function convertDate(date, epoch) {
          if (date instanceof JulianDate) {
              return date;
          }
          if (typeof date === 'string') {
              return JulianDate.fromIso8601(date);
          }
          return JulianDate.addSeconds(epoch, date, new JulianDate());
      }
  
      var timesSpliceArgs = [];
      var valuesSpliceArgs = [];
  
      function mergeNewSamples(epoch, times, values, newData, packedLength) {
          var newDataIndex = 0;
          var i;
          var prevItem;
          var timesInsertionPoint;
          var valuesInsertionPoint;
          var currentTime;
          var nextTime;
  
          while (newDataIndex < newData.length) {
              currentTime = convertDate(newData[newDataIndex], epoch);
              timesInsertionPoint = binarySearch(times, currentTime, JulianDate.compare);
              var timesSpliceArgsCount = 0;
              var valuesSpliceArgsCount = 0;
  
              if (timesInsertionPoint < 0) {
                  //Doesn't exist, insert as many additional values as we can.
                  timesInsertionPoint = ~timesInsertionPoint;
  
                  valuesInsertionPoint = timesInsertionPoint * packedLength;
                  prevItem = undefined;
                  nextTime = times[timesInsertionPoint];
                  while (newDataIndex < newData.length) {
                      currentTime = convertDate(newData[newDataIndex], epoch);
                      if ((defined(prevItem) && JulianDate.compare(prevItem, currentTime) >= 0) || (defined(nextTime) && JulianDate.compare(currentTime, nextTime) >= 0)) {
                          break;
                      }
                      timesSpliceArgs[timesSpliceArgsCount++] = currentTime;
                      newDataIndex = newDataIndex + 1;
                      for (i = 0; i < packedLength; i++) {
                          valuesSpliceArgs[valuesSpliceArgsCount++] = newData[newDataIndex];
                          newDataIndex = newDataIndex + 1;
                      }
                      prevItem = currentTime;
                  }
  
                  if (timesSpliceArgsCount > 0) {
                      valuesSpliceArgs.length = valuesSpliceArgsCount;
                      arrayInsert(values, valuesInsertionPoint, valuesSpliceArgs);
  
                      timesSpliceArgs.length = timesSpliceArgsCount;
                      arrayInsert(times, timesInsertionPoint, timesSpliceArgs);
                  }
              } else {
                  //Found an exact match
                  for (i = 0; i < packedLength; i++) {
                      newDataIndex++;
                      values[(timesInsertionPoint * packedLength) + i] = newData[newDataIndex];
                  }
                  newDataIndex++;
              }
          }
      }
  
      /**
       * A {@link Property} whose value is interpolated for a given time from the
       * provided set of samples and specified interpolation algorithm and degree.
       * @alias SampledProperty
       * @constructor
       *
       * @param {Number|Packable} type The type of property.
       * @param {Packable[]} [derivativeTypes] When supplied, indicates that samples will contain derivative information of the specified types.
       *
       *
       * @example
       * //Create a linearly interpolated Cartesian2
       * var property = new Cesium.SampledProperty(Cesium.Cartesian2);
       *
       * //Populate it with data
       * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:00:00.00Z'), new Cesium.Cartesian2(0, 0));
       * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-02T00:00:00.00Z'), new Cesium.Cartesian2(4, 7));
       *
       * //Retrieve an interpolated value
       * var result = property.getValue(Cesium.JulianDate.fromIso8601('2012-08-01T12:00:00.00Z'));
       *
       * @example
       * //Create a simple numeric SampledProperty that uses third degree Hermite Polynomial Approximation
       * var property = new Cesium.SampledProperty(Number);
       * property.setInterpolationOptions({
       *     interpolationDegree : 3,
       *     interpolationAlgorithm : Cesium.HermitePolynomialApproximation
       * });
       *
       * //Populate it with data
       * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:00:00.00Z'), 1.0);
       * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:01:00.00Z'), 6.0);
       * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:02:00.00Z'), 12.0);
       * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:03:30.00Z'), 5.0);
       * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:06:30.00Z'), 2.0);
       *
       * //Samples can be added in any order.
       * property.addSample(Cesium.JulianDate.fromIso8601('2012-08-01T00:00:30.00Z'), 6.2);
       *
       * //Retrieve an interpolated value
       * var result = property.getValue(Cesium.JulianDate.fromIso8601('2012-08-01T00:02:34.00Z'));
       *
       * @see SampledPositionProperty
       */
      function SampledProperty(type, derivativeTypes) {
          //>>includeStart('debug', pragmas.debug);
          Check.defined('type', type);
          //>>includeEnd('debug');
  
          var innerType = type;
          if (innerType === Number) {
              innerType = PackableNumber;
          }
          var packedLength = innerType.packedLength;
          var packedInterpolationLength = defaultValue(innerType.packedInterpolationLength, packedLength);
  
          var inputOrder = 0;
          var innerDerivativeTypes;
          if (defined(derivativeTypes)) {
              var length = derivativeTypes.length;
              innerDerivativeTypes = new Array(length);
              for (var i = 0; i < length; i++) {
                  var derivativeType = derivativeTypes[i];
                  if (derivativeType === Number) {
                      derivativeType = PackableNumber;
                  }
                  var derivativePackedLength = derivativeType.packedLength;
                  packedLength += derivativePackedLength;
                  packedInterpolationLength += defaultValue(derivativeType.packedInterpolationLength, derivativePackedLength);
                  innerDerivativeTypes[i] = derivativeType;
              }
              inputOrder = length;
          }
  
          this._type = type;
          this._innerType = innerType;
          this._interpolationDegree = 1;
          this._interpolationAlgorithm = LinearApproximation;
          this._numberOfPoints = 0;
          this._times = [];
          this._values = [];
          this._xTable = [];
          this._yTable = [];
          this._packedLength = packedLength;
          this._packedInterpolationLength = packedInterpolationLength;
          this._updateTableLength = true;
          this._interpolationResult = new Array(packedInterpolationLength);
          this._definitionChanged = new Event();
          this._derivativeTypes = derivativeTypes;
          this._innerDerivativeTypes = innerDerivativeTypes;
          this._inputOrder = inputOrder;
          this._forwardExtrapolationType = ExtrapolationType.NONE;
          this._forwardExtrapolationDuration = 0;
          this._backwardExtrapolationType = ExtrapolationType.NONE;
          this._backwardExtrapolationDuration = 0;
      }
  
      Object.defineProperties(SampledProperty.prototype, {
          /**
           * Gets a value indicating if this property is constant.  A property is considered
           * constant if getValue always returns the same result for the current definition.
           * @memberof SampledProperty.prototype
           *
           * @type {Boolean}
           * @readonly
           */
          isConstant : {
              get : function() {
                  return this._values.length === 0;
              }
          },
          /**
           * Gets the event that is raised whenever the definition of this property changes.
           * The definition is considered to have changed if a call to getValue would return
           * a different result for the same time.
           * @memberof SampledProperty.prototype
           *
           * @type {Event}
           * @readonly
           */
          definitionChanged : {
              get : function() {
                  return this._definitionChanged;
              }
          },
          /**
           * Gets the type of property.
           * @memberof SampledProperty.prototype
           * @type {*}
           */
          type : {
              get : function() {
                  return this._type;
              }
          },
          /**
           * Gets the derivative types used by this property.
           * @memberof SampledProperty.prototype
           * @type {Packable[]}
           */
          derivativeTypes : {
              get : function() {
                  return this._derivativeTypes;
              }
          },
          /**
           * Gets the degree of interpolation to perform when retrieving a value.
           * @memberof SampledProperty.prototype
           * @type {Number}
           * @default 1
           */
          interpolationDegree : {
              get : function() {
                  return this._interpolationDegree;
              }
          },
          /**
           * Gets the interpolation algorithm to use when retrieving a value.
           * @memberof SampledProperty.prototype
           * @type {InterpolationAlgorithm}
           * @default LinearApproximation
           */
          interpolationAlgorithm : {
              get : function() {
                  return this._interpolationAlgorithm;
              }
          },
          /**
           * Gets or sets the type of extrapolation to perform when a value
           * is requested at a time after any available samples.
           * @memberof SampledProperty.prototype
           * @type {ExtrapolationType}
           * @default ExtrapolationType.NONE
           */
          forwardExtrapolationType : {
              get : function() {
                  return this._forwardExtrapolationType;
              },
              set : function(value) {
                  if (this._forwardExtrapolationType !== value) {
                      this._forwardExtrapolationType = value;
                      this._definitionChanged.raiseEvent(this);
                  }
              }
          },
          /**
           * Gets or sets the amount of time to extrapolate forward before
           * the property becomes undefined.  A value of 0 will extrapolate forever.
           * @memberof SampledProperty.prototype
           * @type {Number}
           * @default 0
           */
          forwardExtrapolationDuration : {
              get : function() {
                  return this._forwardExtrapolationDuration;
              },
              set : function(value) {
                  if (this._forwardExtrapolationDuration !== value) {
                      this._forwardExtrapolationDuration = value;
                      this._definitionChanged.raiseEvent(this);
                  }
              }
          },
          /**
           * Gets or sets the type of extrapolation to perform when a value
           * is requested at a time before any available samples.
           * @memberof SampledProperty.prototype
           * @type {ExtrapolationType}
           * @default ExtrapolationType.NONE
           */
          backwardExtrapolationType : {
              get : function() {
                  return this._backwardExtrapolationType;
              },
              set : function(value) {
                  if (this._backwardExtrapolationType !== value) {
                      this._backwardExtrapolationType = value;
                      this._definitionChanged.raiseEvent(this);
                  }
              }
          },
          /**
           * Gets or sets the amount of time to extrapolate backward
           * before the property becomes undefined.  A value of 0 will extrapolate forever.
           * @memberof SampledProperty.prototype
           * @type {Number}
           * @default 0
           */
          backwardExtrapolationDuration : {
              get : function() {
                  return this._backwardExtrapolationDuration;
              },
              set : function(value) {
                  if (this._backwardExtrapolationDuration !== value) {
                      this._backwardExtrapolationDuration = value;
                      this._definitionChanged.raiseEvent(this);
                  }
              }
          }
      });
  
      /**
       * Gets the value of the property at the provided time.
       *
       * @param {JulianDate} time The time for which to retrieve the value.
       * @param {Object} [result] The object to store the value into, if omitted, a new instance is created and returned.
       * @returns {Object} The modified result parameter or a new instance if the result parameter was not supplied.
       */
      SampledProperty.prototype.getValue = function(time, result) {
          //>>includeStart('debug', pragmas.debug);
          Check.defined('time', time);
          //>>includeEnd('debug');
  
          var times = this._times;
          var timesLength = times.length;
          if (timesLength === 0) {
              return undefined;
          }
  
          var timeout;
          var innerType = this._innerType;
          var values = this._values;
          var index = binarySearch(times, time, JulianDate.compare);
  
          if (index < 0) {
              index = ~index;
  
              if (index === 0) {
                  var startTime = times[index];
                  timeout = this._backwardExtrapolationDuration;
                  if (this._backwardExtrapolationType === ExtrapolationType.NONE || (timeout !== 0 && JulianDate.secondsDifference(startTime, time) > timeout)) {
                      return undefined;
                  }
                  if (this._backwardExtrapolationType === ExtrapolationType.HOLD) {
                      return innerType.unpack(values, 0, result);
                  }
              }
  
              if (index >= timesLength) {
                  index = timesLength - 1;
                  var endTime = times[index];
                  timeout = this._forwardExtrapolationDuration;
                  if (this._forwardExtrapolationType === ExtrapolationType.NONE || (timeout !== 0 && JulianDate.secondsDifference(time, endTime) > timeout)) {
                      return undefined;
                  }
                  if (this._forwardExtrapolationType === ExtrapolationType.HOLD) {
                      index = timesLength - 1;
                      return innerType.unpack(values, index * innerType.packedLength, result);
                  }
              }
  
              var xTable = this._xTable;
              var yTable = this._yTable;
              var interpolationAlgorithm = this._interpolationAlgorithm;
              var packedInterpolationLength = this._packedInterpolationLength;
              var inputOrder = this._inputOrder;
  
              if (this._updateTableLength) {
                  this._updateTableLength = false;
                  var numberOfPoints = Math.min(interpolationAlgorithm.getRequiredDataPoints(this._interpolationDegree, inputOrder), timesLength);
                  if (numberOfPoints !== this._numberOfPoints) {
                      this._numberOfPoints = numberOfPoints;
                      xTable.length = numberOfPoints;
                      yTable.length = numberOfPoints * packedInterpolationLength;
                  }
              }
  
              var degree = this._numberOfPoints - 1;
              if (degree < 1) {
                  return undefined;
              }
  
              var firstIndex = 0;
              var lastIndex = timesLength - 1;
              var pointsInCollection = lastIndex - firstIndex + 1;
  
              if (pointsInCollection >= degree + 1) {
                  var computedFirstIndex = index - ((degree / 2) | 0) - 1;
                  if (computedFirstIndex < firstIndex) {
                      computedFirstIndex = firstIndex;
                  }
                  var computedLastIndex = computedFirstIndex + degree;
                  if (computedLastIndex > lastIndex) {
                      computedLastIndex = lastIndex;
                      computedFirstIndex = computedLastIndex - degree;
                      if (computedFirstIndex < firstIndex) {
                          computedFirstIndex = firstIndex;
                      }
                  }
  
                  firstIndex = computedFirstIndex;
                  lastIndex = computedLastIndex;
              }
              var length = lastIndex - firstIndex + 1;
  
              // Build the tables
              for (var i = 0; i < length; ++i) {
                  xTable[i] = JulianDate.secondsDifference(times[firstIndex + i], times[lastIndex]);
              }
  
              if (!defined(innerType.convertPackedArrayForInterpolation)) {
                  var destinationIndex = 0;
                  var packedLength = this._packedLength;
                  var sourceIndex = firstIndex * packedLength;
                  var stop = (lastIndex + 1) * packedLength;
  
                  while (sourceIndex < stop) {
                      yTable[destinationIndex] = values[sourceIndex];
                      sourceIndex++;
                      destinationIndex++;
                  }
              } else {
                  innerType.convertPackedArrayForInterpolation(values, firstIndex, lastIndex, yTable);
              }
  
              // Interpolate!
              var x = JulianDate.secondsDifference(time, times[lastIndex]);
              var interpolationResult;
              if (inputOrder === 0 || !defined(interpolationAlgorithm.interpolate)) {
                  interpolationResult = interpolationAlgorithm.interpolateOrderZero(x, xTable, yTable, packedInterpolationLength, this._interpolationResult);
              } else {
                  var yStride = Math.floor(packedInterpolationLength / (inputOrder + 1));
                  interpolationResult = interpolationAlgorithm.interpolate(x, xTable, yTable, yStride, inputOrder, inputOrder, this._interpolationResult);
              }
  
              if (!defined(innerType.unpackInterpolationResult)) {
                  return innerType.unpack(interpolationResult, 0, result);
              }
              return innerType.unpackInterpolationResult(interpolationResult, values, firstIndex, lastIndex, result);
          }
          return innerType.unpack(values, index * this._packedLength, result);
      };
  
      /**
       * Sets the algorithm and degree to use when interpolating a value.
       *
       * @param {Object} [options] Object with the following properties:
       * @param {InterpolationAlgorithm} [options.interpolationAlgorithm] The new interpolation algorithm.  If undefined, the existing property will be unchanged.
       * @param {Number} [options.interpolationDegree] The new interpolation degree.  If undefined, the existing property will be unchanged.
       */
      SampledProperty.prototype.setInterpolationOptions = function(options) {
          if (!defined(options)) {
              return;
          }
  
          var valuesChanged = false;
  
          var interpolationAlgorithm = options.interpolationAlgorithm;
          var interpolationDegree = options.interpolationDegree;
  
          if (defined(interpolationAlgorithm) && this._interpolationAlgorithm !== interpolationAlgorithm) {
              this._interpolationAlgorithm = interpolationAlgorithm;
              valuesChanged = true;
          }
  
          if (defined(interpolationDegree) && this._interpolationDegree !== interpolationDegree) {
              this._interpolationDegree = interpolationDegree;
              valuesChanged = true;
          }
  
          if (valuesChanged) {
              this._updateTableLength = true;
              this._definitionChanged.raiseEvent(this);
          }
      };
  
      /**
       * Adds a new sample.
       *
       * @param {JulianDate} time The sample time.
       * @param {Packable} value The value at the provided time.
       * @param {Packable[]} [derivatives] The array of derivatives at the provided time.
       */
      SampledProperty.prototype.addSample = function(time, value, derivatives) {
          var innerDerivativeTypes = this._innerDerivativeTypes;
          var hasDerivatives = defined(innerDerivativeTypes);
  
          //>>includeStart('debug', pragmas.debug);
          Check.defined('time', time);
          Check.defined('value', value);
          if (hasDerivatives) {
              Check.defined('derivatives', derivatives);
          }
          //>>includeEnd('debug');
  
          var innerType = this._innerType;
          var data = [];
          data.push(time);
          innerType.pack(value, data, data.length);
  
          if (hasDerivatives) {
              var derivativesLength = innerDerivativeTypes.length;
              for (var x = 0; x < derivativesLength; x++) {
                  innerDerivativeTypes[x].pack(derivatives[x], data, data.length);
              }
          }
          mergeNewSamples(undefined, this._times, this._values, data, this._packedLength);
          this._updateTableLength = true;
          this._definitionChanged.raiseEvent(this);
      };
  
      /**
       * Adds an array of samples.
       *
       * @param {JulianDate[]} times An array of JulianDate instances where each index is a sample time.
       * @param {Packable[]} values The array of values, where each value corresponds to the provided times index.
       * @param {Array[]} [derivativeValues] An array where each item is the array of derivatives at the equivalent time index.
       *
       * @exception {DeveloperError} times and values must be the same length.
       * @exception {DeveloperError} times and derivativeValues must be the same length.
       */
      SampledProperty.prototype.addSamples = function(times, values, derivativeValues) {
          var innerDerivativeTypes = this._innerDerivativeTypes;
          var hasDerivatives = defined(innerDerivativeTypes);
  
          //>>includeStart('debug', pragmas.debug);
          Check.defined('times', times);
          Check.defined('values', values);
          if (times.length !== values.length) {
              throw new DeveloperError('times and values must be the same length.');
          }
          if (hasDerivatives && (!defined(derivativeValues) || derivativeValues.length !== times.length)) {
              throw new DeveloperError('times and derivativeValues must be the same length.');
          }
          //>>includeEnd('debug');
  
          var innerType = this._innerType;
          var length = times.length;
          var data = [];
          for (var i = 0; i < length; i++) {
              data.push(times[i]);
              innerType.pack(values[i], data, data.length);
  
              if (hasDerivatives) {
                  var derivatives = derivativeValues[i];
                  var derivativesLength = innerDerivativeTypes.length;
                  for (var x = 0; x < derivativesLength; x++) {
                      innerDerivativeTypes[x].pack(derivatives[x], data, data.length);
                  }
              }
          }
          mergeNewSamples(undefined, this._times, this._values, data, this._packedLength);
          this._updateTableLength = true;
          this._definitionChanged.raiseEvent(this);
      };
  
      /**
       * Adds samples as a single packed array where each new sample is represented as a date,
       * followed by the packed representation of the corresponding value and derivatives.
       *
       * @param {Number[]} packedSamples The array of packed samples.
       * @param {JulianDate} [epoch] If any of the dates in packedSamples are numbers, they are considered an offset from this epoch, in seconds.
       */
      SampledProperty.prototype.addSamplesPackedArray = function(packedSamples, epoch) {
          //>>includeStart('debug', pragmas.debug);
          Check.defined('packedSamples', packedSamples);
          //>>includeEnd('debug');
  
          mergeNewSamples(epoch, this._times, this._values, packedSamples, this._packedLength);
          this._updateTableLength = true;
          this._definitionChanged.raiseEvent(this);
      };
  
      /**
       * Removes a sample at the given time, if present.
       *
       * @param {JulianDate} time The sample time.
       * @returns {Boolean} <code>true</code> if a sample at time was removed, <code>false</code> otherwise.
       */
      SampledProperty.prototype.removeSample = function(time) {
          //>>includeStart('debug', pragmas.debug);
          Check.defined('time', time);
          //>>includeEnd('debug');
  
          var index = binarySearch(this._times, time, JulianDate.compare);
          if (index < 0) {
              return false;
          }
          removeSamples(this, index, 1);
          return true;
      };
  
      function removeSamples(property, startIndex, numberToRemove) {
          var packedLength = property._packedLength;
          property._times.splice(startIndex, numberToRemove);
          property._values.splice(startIndex * packedLength, numberToRemove * packedLength);
          property._updateTableLength = true;
          property._definitionChanged.raiseEvent(property);
      }
  
      /**
       * Removes all samples for the given time interval.
       *
       * @param {TimeInterval} time The time interval for which to remove all samples.
       */
      SampledProperty.prototype.removeSamples = function(timeInterval) {
          //>>includeStart('debug', pragmas.debug);
          Check.defined('timeInterval', timeInterval);
          //>>includeEnd('debug');
  
          var times = this._times;
          var startIndex = binarySearch(times, timeInterval.start, JulianDate.compare);
          if (startIndex < 0) {
              startIndex = ~startIndex;
          } else if (!timeInterval.isStartIncluded) {
              ++startIndex;
          }
          var stopIndex = binarySearch(times, timeInterval.stop, JulianDate.compare);
          if (stopIndex < 0) {
              stopIndex = ~stopIndex;
          } else if (timeInterval.isStopIncluded) {
              ++stopIndex;
          }
  
          removeSamples(this, startIndex, stopIndex - startIndex);
      };
  
      /**
       * Compares this property to the provided property and returns
       * <code>true</code> if they are equal, <code>false</code> otherwise.
       *
       * @param {Property} [other] The other property.
       * @returns {Boolean} <code>true</code> if left and right are equal, <code>false</code> otherwise.
       */
      SampledProperty.prototype.equals = function(other) {
          if (this === other) {
              return true;
          }
          if (!defined(other)) {
              return false;
          }
  
          if (this._type !== other._type || //
              this._interpolationDegree !== other._interpolationDegree || //
              this._interpolationAlgorithm !== other._interpolationAlgorithm) {
              return false;
          }
  
          var derivativeTypes = this._derivativeTypes;
          var hasDerivatives = defined(derivativeTypes);
          var otherDerivativeTypes = other._derivativeTypes;
          var otherHasDerivatives = defined(otherDerivativeTypes);
          if (hasDerivatives !== otherHasDerivatives) {
              return false;
          }
  
          var i;
          var length;
          if (hasDerivatives) {
              length = derivativeTypes.length;
              if (length !== otherDerivativeTypes.length) {
                  return false;
              }
  
              for (i = 0; i < length; i++) {
                  if (derivativeTypes[i] !== otherDerivativeTypes[i]) {
                      return false;
                  }
              }
          }
  
          var times = this._times;
          var otherTimes = other._times;
          length = times.length;
  
          if (length !== otherTimes.length) {
              return false;
          }
  
          for (i = 0; i < length; i++) {
              if (!JulianDate.equals(times[i], otherTimes[i])) {
                  return false;
              }
          }
  
          var values = this._values;
          var otherValues = other._values;
          for (i = 0; i < length; i++) {
              if (values[i] !== otherValues[i]) {
                  return false;
              }
          }
  
          return true;
      };
  
      //Exposed for testing.
      SampledProperty._mergeNewSamples = mergeNewSamples;
  export default SampledProperty;
  