docs: function(options, callback) {
  			if (typeof options === "function") {
  				callback = options;
  				options = null;
  			}
  
  			options = options || {};
  			var startSegment = options.first || this.internal.initialSegment;
  			var lastSegment = options.last;
  
  			var item = null;
  			var index = 0;
  			var end = 0;
  			var segment = null;
  			var visited = Object.create(null);
  			var stack = [
  				[startSegment, 0]
  			];
  			var skippedSegment = null;
  			var broken = false;
  			var controller = {
  				skip: function() {
  					if (stack.length <= 1) {
  						broken = true;
  					} else {
  						skippedSegment = stack[stack.length - 2][0];
  					}
  				},
  				break: function() {
  					broken = true;
  				}
  			};
  
  			/**
  			 * Checks a given previous segment has been visited.
  			 * @param {CodePathSegment} prevSegment - A previous segment to check.
  			 * @returns {boolean} `true` if the segment has been visited.
  			 */
  			function isVisited(prevSegment) {
  				return visited[prevSegment.id] ||
  					segment.isLoopedPrevSegment(prevSegment);
  			}
  
  			while (stack.length > 0) {
  				item = stack[stack.length - 1];
  				segment = item[0];
  				index = item[1];
  
  				if (index === 0) {
  
  					// Skip if this segment has been visited already.
  					if (visited[segment.id]) {
  						stack.pop();
  						continue;
  					}
  
  					// Skip if all previous segments have not been visited.
  					if (segment !== startSegment &&
  						segment.prevSegments.length > 0 &&
  						!segment.prevSegments.every(isVisited)
  					) {
  						stack.pop();
  						continue;
  					}
  
  					// Reset the flag of skipping if all branches have been skipped.
  					if (skippedSegment && segment.prevSegments.indexOf(skippedSegment) !== -1) {
  						skippedSegment = null;
  					}
  					visited[segment.id] = true;
  
  					// Call the callback when the first time.
  					if (!skippedSegment) {
  						callback.call(this, segment, controller); // eslint-disable-line callback-return
  						if (segment === lastSegment) {
  							controller.skip();
  						}
  						if (broken) {
  							break;
  						}
  					}
  				}
  
  				// Update the stack.
  				end = segment.nextSegments.length - 1;
  				if (index < end) {
  					item[1] += 1;
  					stack.push([segment.nextSegments[index], 0]);
  				} else if (index === end) {
  					item[0] = segment.nextSegments[index];
  					item[1] = 0;
  				} else {
  					stack.pop();
  				}
  			}
  		}