private RevisionId GetToRevision(RevisionRange processedRevisionRange, RevisionId newToRevision)
		{
			if (RevisionComparer.Is(newToRevision).GreaterThan(processedRevisionRange.ToChangeset))
			{
				return newToRevision;
			}
			return processedRevisionRange.ToChangeset;
		}
		public RevisionId FindMaxToRevision(RevisionRange[] revisionRanges)
		{
			var result =
				(from revisionRange in revisionRanges orderby revisionRange.ToChangeset.Time descending select revisionRange).
					FirstOrDefault();

			return result != null ? result.ToChangeset : new RevisionId {Time = GitRevisionId.UtcTimeMin};
		}
		public RevisionId FindMaxToRevision(RevisionRange[] revisionRanges)
		{
			var result =
				(from revisionRange in revisionRanges orderby int.Parse(revisionRange.ToChangeset.Value) descending select revisionRange).
					FirstOrDefault();

			return result != null ? result.ToChangeset : new RevisionId { Value = "1", Time = TfsRevisionId.UtcTimeMin };
		}
        public RevisionId FindMinFromRevision(RevisionRange[] revisionRanges)
        {
            var result =
                (from revisionRange in revisionRanges orderby revisionRange.FromChangeset.Time ascending select revisionRange).
                    FirstOrDefault();

            return result != null ? result.FromChangeset : new RevisionId {Time = MercurialRevisionId.UtcTimeMin};
        }
		private RevisionId GetFromRevision(RevisionRange processedRevisionRange, RevisionId newFromRevision)
		{
			if (RevisionComparer.Is(StartRevision).LessThan(newFromRevision))
				newFromRevision = StartRevision;

			if (RevisionComparer.Is(newFromRevision).LessThan(processedRevisionRange.FromChangeset))
			{
				return newFromRevision;
			}
			return processedRevisionRange.FromChangeset;
		}
		protected void SetStartRevisionBy(RevisionRange[] revisionRanges)
		{
			if (revisionRanges.Empty())
			{
				return;
			}

			var newFromRevision = RevisionComparer.FindMinFromRevision(revisionRanges);
			var newToRevision = RevisionComparer.FindMaxToRevision(revisionRanges);
			var processedRevisionRangeStorage = Storage.Get<RevisionRange>();
			var processedRevisionRange = processedRevisionRangeStorage.SingleOrDefault() ?? new RevisionRange(newFromRevision, newToRevision);
			var newProcessedRevisionRange = new RevisionRange(GetFromRevision(processedRevisionRange, newFromRevision),
			                                                  GetToRevision(processedRevisionRange, newToRevision));

			processedRevisionRangeStorage.Clear();
			processedRevisionRangeStorage.Add(newProcessedRevisionRange);
		}
		private static SvnRevisionRange CreateSvnRevisionRangeBy(RevisionRange revisionRange)
		{
			SvnRevisionId fromChangeset = revisionRange.FromChangeset;
			SvnRevisionId toChangeSet = revisionRange.ToChangeset;
			return new SvnRevisionRange(fromChangeset.Value, toChangeSet.Value);
		}
		private SvnLogArgs CreateSvnLogArgument(string path, RevisionRange revisionRange)
		{
			return new SvnLogArgs(CreateSvnRevisionRangeBy(revisionRange)) {BaseUri = GetPath(path), ThrowOnError = true};
		}
		public RevisionInfo[] GetRevisions(RevisionRange revisionsRange, string path)
		{
			_logger.DebugFormat("GET SVN Revisions for {0} [{1}, {2}]", path, revisionsRange.FromChangeset, revisionsRange.ToChangeset);
			var arg = CreateSvnLogArgument(path, new RevisionRange(revisionsRange.FromChangeset, revisionsRange.ToChangeset));
			var tpRevisionInfo = SubversionUtils.ArrayOfSvnRevisionToArrayOfRevisionInfo(GetSvnRevisions(arg, path), this);
			_logger.DebugFormat("SVN Revisions for {0} [{1}, {2}] is retrieved", path, revisionsRange.FromChangeset, revisionsRange.ToChangeset);

			return tpRevisionInfo.ToArray();
		}
		public override RevisionInfo[] GetRevisions(RevisionRange revisionRange)
		{
			try
			{
				SvnRevisionId fromChangeset = revisionRange.FromChangeset;
				SvnRevisionId toChangeset = revisionRange.ToChangeset;

				_logger.DebugFormat("Getting revision infos [{0}:{1}]", fromChangeset, toChangeset);
				var arg = new SvnLogArgs(new SvnRevisionRange(fromChangeset.Value, toChangeset.Value)) {ThrowOnError = true};
				return SubversionUtils.ArrayOfSvnRevisionToArrayOfRevisionInfo(GetSvnRevisions(arg), this).ToArray();
			}
			catch (SvnException e)
			{
				throw new VersionControlException(String.Format("Subversion exception: {0}", e.Message), e);
			}
		}
		public RevisionInfo[] GetRevisions(RevisionRange revisionRange)
		{
			return Revisions.FindAll(x =>
			                         long.Parse(x.Id.Value) >= long.Parse(revisionRange.FromChangeset.Value) &&
			                         long.Parse(x.Id.Value) <= long.Parse(revisionRange.ToChangeset.Value)).ToArray();
		}
		public RevisionId FindMinFromRevision(RevisionRange[] revisionRanges)
		{
			var revisions = (from revisionRange in revisionRanges select (SvnRevisionId) revisionRange.FromChangeset);
			return (from revision in revisions orderby revision.Value ascending select revision).First();
		}
		bool ICompareRevisionSecondArg.Before(RevisionRange revisionRange)
		{
			return int.Parse(_firstArg.Value) < int.Parse(revisionRange.FromChangeset.Value);
		}
		public abstract RevisionInfo[] GetRevisions(RevisionRange revisionRange);
		bool ICompareRevisionSecondArg.Belong(RevisionRange revisionRange)
		{
			SvnRevisionId fromChangeset = revisionRange.FromChangeset;
			SvnRevisionId toChangeset = revisionRange.ToChangeset;
			return fromChangeset.Value <= _firstArg.Value && _firstArg.Value <= toChangeset.Value;
		}
		bool ICompareRevisionSecondArg.Behind(RevisionRange revisionRange)
		{
			SvnRevisionId toChangeSet = revisionRange.ToChangeset;
			return _firstArg.Value > toChangeSet.Value;
		}
		bool ICompareRevisionSecondArg.Before(RevisionRange revisionRange)
		{
			SvnRevisionId fromChangeSet = revisionRange.FromChangeset;

			return _firstArg.Value < fromChangeSet.Value;
		}
		private static RevisionRange[] GetFromTo(SvnRevisionId @from, SvnRevisionId lastRevision, int pageSize)
		{
			var result = new List<RevisionRange>();

			while (from.Value <= lastRevision.Value)
			{
				var fromRevisionId = from;

				RevisionRange revisionRange;

				var fromRevision = fromRevisionId;
				if ((fromRevisionId.Value + pageSize) < lastRevision.Value)
				{
					revisionRange = new RevisionRange(fromRevision, new RevisionId {Value = (fromRevisionId.Value + pageSize - 1).ToString()});
				}
				else
				{
					revisionRange = new RevisionRange(fromRevision, lastRevision);
				}

				result.Add(revisionRange);

				from = new SvnRevisionId(fromRevisionId.Value + pageSize);
			}
			return result.ToArray();
		}
		bool ICompareRevisionSecondArg.Before(RevisionRange revisionRange)
		{
			return _firstArg.Time < ((GitRevisionId) revisionRange.FromChangeset).Time;
		}
		bool ICompareRevisionSecondArg.Belong(RevisionRange revisionRange)
		{
			return int.Parse(_firstArg.Value) >= int.Parse(revisionRange.FromChangeset.Value) &&
						 int.Parse(_firstArg.Value) <= int.Parse(revisionRange.ToChangeset.Value);
		}
		bool ICompareRevisionSecondArg.Behind(RevisionRange revisionRange)
		{
			return int.Parse(_firstArg.Value) > int.Parse(revisionRange.ToChangeset.Value);
		}
		bool ICompareRevisionSecondArg.Behind(RevisionRange revisionRange)
		{
			return _firstArg.Time > ((GitRevisionId) revisionRange.ToChangeset).Time;
		}
		public RevisionInfo[] GetRevisions(RevisionRange revisionRange, string path)
		{
			throw new NotImplementedException();
		}
		bool ICompareRevisionSecondArg.Belong(RevisionRange revisionRange)
		{
			return _firstArg.Time >= ((GitRevisionId) revisionRange.FromChangeset).Time &&
			       _firstArg.Time <= ((GitRevisionId) revisionRange.ToChangeset).Time;
		}
		public override RevisionInfo[] GetRevisions(RevisionRange revisionRange)
		{
			return _git.GetRevisions(revisionRange.FromChangeset, revisionRange.ToChangeset);
		}
 public abstract RevisionInfo[] GetRevisions(RevisionRange revisionRange);