docs: function setTickPositions() {
  			var length,
  				catPad,
  				linkedParent,
  				linkedParentExtremes,
  				tickIntervalOption = options.tickInterval,
  				tickPixelIntervalOption = options.tickPixelInterval,
  				maxZoom = options.maxZoom || (
  					isXAxis && !defined(options.min) && !defined(options.max) ?
  						mathMin(chart.smallestInterval * 5, dataMax - dataMin) :
  						null
  				),
  				zoomOffset;
  
  
  			axisLength = horiz ? plotWidth : plotHeight;
  
  			// linked axis gets the extremes from the parent axis
  			if (isLinked) {
  				linkedParent = chart[isXAxis ? 'xAxis' : 'yAxis'][options.linkedTo];
  				linkedParentExtremes = linkedParent.getExtremes();
  				min = pick(linkedParentExtremes.min, linkedParentExtremes.dataMin);
  				max = pick(linkedParentExtremes.max, linkedParentExtremes.dataMax);
  			} else { // initial min and max from the extreme data values
  				min = pick(userMin, options.min, dataMin);
  				max = pick(userMax, options.max, dataMax);
  			}
  
  			if (isLog) {
  				min = log2lin(min);
  				max = log2lin(max);
  			}
  
  			// maxZoom exceeded, just center the selection
  			if (max - min < maxZoom) {
  				zoomOffset = (maxZoom - max + min) / 2;
  				// if min and max options have been set, don't go beyond it
  				min = mathMax(min - zoomOffset, pick(options.min, min - zoomOffset), dataMin);
  				max = mathMin(min + maxZoom, pick(options.max, min + maxZoom), dataMax);
  			}
  
  			// pad the values to get clear of the chart's edges
  			if (!categories && !usePercentage && !isLinked && defined(min) && defined(max)) {
  				length = (max - min) || 1;
  				if (!defined(options.min) && !defined(userMin) && minPadding && (dataMin < 0 || !ignoreMinPadding)) {
  					min -= length * minPadding;
  				}
  				if (!defined(options.max) && !defined(userMax)  && maxPadding && (dataMax > 0 || !ignoreMaxPadding)) {
  					max += length * maxPadding;
  				}
  			}
  
  			// get tickInterval
  			if (min === max) {
  				tickInterval = 1;
  			} else if (isLinked && !tickIntervalOption &&
  					tickPixelIntervalOption === linkedParent.options.tickPixelInterval) {
  				tickInterval = linkedParent.tickInterval;
  			} else {
  				tickInterval = pick(
  					tickIntervalOption,
  					categories ? // for categoried axis, 1 is default, for linear axis use tickPix
  						1 :
  						(max - min) * tickPixelIntervalOption / axisLength
  				);
  			}
  
  			if (!isDatetimeAxis && !defined(options.tickInterval)) { // linear
  				tickInterval = normalizeTickInterval(tickInterval);
  			}
  			axis.tickInterval = tickInterval; // record for linked axis
  
  			// get minorTickInterval
  			minorTickInterval = options.minorTickInterval === 'auto' && tickInterval ?
  					tickInterval / 5 : options.minorTickInterval;
  
  			// find the tick positions
  			if (isDatetimeAxis) {
  				setDateTimeTickPositions();
  			} else {
  				setLinearTickPositions();
  			}
  
  			if (!isLinked) {
  				// pad categorised axis to nearest half unit
  				if (categories || (isXAxis && chart.hasColumn)) {
  					catPad = (categories ? 1 : tickInterval) * 0.5;
  					if (categories || !defined(pick(options.min, userMin))) {
  						min -= catPad;
  					}
  					if (categories || !defined(pick(options.max, userMax))) {
  						max += catPad;
  					}
  				}
  
  				// reset min/max or remove extremes based on start/end on tick
  				var roundedMin = tickPositions[0],
  					roundedMax = tickPositions[tickPositions.length - 1];
  
  				if (options.startOnTick) {
  					min = roundedMin;
  				} else if (min > roundedMin) {
  					tickPositions.shift();
  				}
  
  				if (options.endOnTick) {
  					max = roundedMax;
  				} else if (max < roundedMax) {
  					tickPositions.pop();
  				}
  
  				// record the greatest number of ticks for multi axis
  				if (!maxTicks) { // first call, or maxTicks have been reset after a zoom operation
  					maxTicks = {
  						x: 0,
  						y: 0
  					};
  				}
  
  				if (!isDatetimeAxis && tickPositions.length > maxTicks[xOrY]) {
  					maxTicks[xOrY] = tickPositions.length;
  				}
  			}
  			
  			// PATCH
              //
              // call the tickPositionsSet hook after the tick positions have been calculated
              //
              // + if(hooks.tickPositionsSet) {
              // +    hooks.tickPositionsSet(options, categories, tickPositions, chart);
              // + }
              
              if(hooks.tickPositionsSet) {
                  hooks.tickPositionsSet(options, categories, tickPositions, chart);
              }
  
  		}