/// <summary>
		/// Fills the list of LESS-files, that were added to a LESS-asset
		/// by using the LESS <code>@import</code> rules
		/// </summary>
		/// <param name="rootAssetUrl">URL of root LESS-asset file</param>
		/// <param name="parentStylesheet">Parent LESS-stylesheet</param>
		/// <param name="dependencies">List of LESS-files, that were added to a
		/// LESS-asset by using the LESS <code>@import</code> rules</param>
		public void FillDependencies(string rootAssetUrl, LessStylesheet parentStylesheet, DependencyCollection dependencies)
		{
			foreach (string dataUriFunctionImageUrl in parentStylesheet.DataUriFunctionAssetUrls)
			{
				var dependency = new Dependency(dataUriFunctionImageUrl, string.Empty);
				dependencies.Add(dependency);
			}

			foreach (LessImport import in parentStylesheet.Imports)
			{
				string dependencyUrl = import.Url;
				LessImportOptions dependencyOptions = import.ImportOptions;

				if (UrlHelpers.StartsWithProtocol(dependencyUrl))
				{
					if (!dependencies.ContainsUrl(dependencyUrl))
					{
						var dependency = new Dependency(dependencyUrl, string.Empty, false);
						dependencies.Add(dependency);
					}

					continue;
				}

				if (string.Equals(dependencyUrl, rootAssetUrl, StringComparison.OrdinalIgnoreCase))
				{
					continue;
				}

				var duplicateDependency = dependencies.GetByUrl(dependencyUrl);
				bool isDuplicateDependency = (duplicateDependency != null);
				bool isEmptyDependency = isDuplicateDependency && (duplicateDependency.Content.Length == 0);
				bool isNonExistentOptionalDependency = false;

				if (!isDuplicateDependency || isEmptyDependency)
				{
					if (!LessStylesheetExists(dependencyUrl))
					{
						if (dependencyOptions.Optional)
						{
							isNonExistentOptionalDependency = true;
						}
						else
						{
							throw new FileNotFoundException(
								string.Format(CoreStrings.Common_FileNotExist, dependencyUrl));
						}
					}

					var stylesheet = new LessStylesheet(dependencyUrl, string.Empty);
					string dependencyContent = null;

					if (dependencyOptions.Less || dependencyOptions.Inline)
					{
						if (!isNonExistentOptionalDependency)
						{
							stylesheet = GetLessStylesheet(dependencyUrl, dependencyOptions);
							dependencyContent = stylesheet.Content;
						}

						if (isEmptyDependency && stylesheet.Content.Length > 0)
						{
							duplicateDependency.Content = dependencyContent;
							duplicateDependency.IsObservable = true;
						}
						else
						{
							var dependency = new Dependency(dependencyUrl, dependencyContent);
							dependencies.Add(dependency);
						}
					}
					else
					{
						if (!isNonExistentOptionalDependency)
						{
							dependencyContent = string.Empty;
						}

						if (!isDuplicateDependency)
						{
							var dependency = new Dependency(dependencyUrl, dependencyContent, false);
							dependencies.Add(dependency);
						}
					}

					FillDependencies(rootAssetUrl, stylesheet, dependencies);
				}
			}
		}
		/// <summary>
		/// Preprocess a stylesheet content
		/// </summary>
		/// <param name="assetContent">Text content of LESS-asset</param>
		/// <param name="assetUrl">URL of LESS-asset file</param>
		/// <param name="assetImportOptions">Import options</param>
		/// <returns>Preprocessed text content of LESS-asset</returns>
		public LessStylesheet PreprocessStylesheet(string assetContent, string assetUrl,
			LessImportOptions assetImportOptions)
		{
			var stylesheet = new LessStylesheet(assetUrl, assetContent);

			int contentLength = assetContent.Length;
			if (contentLength == 0)
			{
				return stylesheet;
			}

			MatchCollection importRuleMatches = _lessImportRuleRegex.Matches(assetContent);
			MatchCollection dataUriFunctionMatches = _dataUriFunctionRegex.Matches(assetContent);
			MatchCollection urlRuleMatches = null;
			if (assetImportOptions.Inline)
			{
				urlRuleMatches = CommonRegExps.CssUrlRuleRegex.Matches(assetContent);
			}

			if (importRuleMatches.Count == 0 && dataUriFunctionMatches.Count == 0
				&& (urlRuleMatches == null || urlRuleMatches.Count == 0))
			{
				return stylesheet;
			}

			var nodeMatches = new List<LessNodeMatch>();

			foreach (Match importRuleMatch in importRuleMatches)
			{
				var nodeMatch = new LessNodeMatch(importRuleMatch.Index,
					importRuleMatch.Length,
					LessNodeType.ImportRule,
					importRuleMatch);
				nodeMatches.Add(nodeMatch);
			}

			foreach (Match dataUriFunctionMatch in dataUriFunctionMatches)
			{
				var nodeMatch = new LessNodeMatch(dataUriFunctionMatch.Index,
					dataUriFunctionMatch.Length,
					LessNodeType.DataUriFunction,
					dataUriFunctionMatch);
				nodeMatches.Add(nodeMatch);
			}

			if (urlRuleMatches != null)
			{
				foreach (Match urlRuleMatch in urlRuleMatches)
				{
					var nodeMatch = new LessNodeMatch(urlRuleMatch.Index,
						urlRuleMatch.Length,
						LessNodeType.UrlRule,
						urlRuleMatch);
					nodeMatches.Add(nodeMatch);
				}
			}

			MatchCollection multilineCommentMatches;
			if (assetImportOptions.Less)
			{
				multilineCommentMatches = CommonRegExps.CStyleMultilineCommentRegex.Matches(assetContent);
			}
			else
			{
				multilineCommentMatches = CommonRegExps.CssMultilineCommentRegex.Matches(assetContent);
			}

			foreach (Match multilineCommentMatch in multilineCommentMatches)
			{
				var nodeMatch = new LessNodeMatch(multilineCommentMatch.Index,
					multilineCommentMatch.Length,
					LessNodeType.MultilineComment,
					multilineCommentMatch);
				nodeMatches.Add(nodeMatch);
			}

			nodeMatches = nodeMatches
				.OrderBy(n => n.Position)
				.ThenByDescending(n => n.Length)
				.ToList()
				;

			var contentBuilder = new StringBuilder();
			int endPosition = contentLength - 1;
			int currentPosition = 0;

			foreach (LessNodeMatch nodeMatch in nodeMatches)
			{
				LessNodeType nodeType = nodeMatch.NodeType;
				int nodePosition = nodeMatch.Position;
				Match match = nodeMatch.Match;

				if (nodePosition < currentPosition)
				{
					continue;
				}

				if (nodeType == LessNodeType.ImportRule || nodeType == LessNodeType.DataUriFunction
					|| nodeType == LessNodeType.UrlRule)
				{
					ProcessOtherContent(contentBuilder, assetContent,
						ref currentPosition, nodePosition);

					int startLinePosition;
					int endLinePosition;
					string currentLine = SourceCodeNavigator.GetCurrentLine(assetContent, nodePosition,
						out startLinePosition, out endLinePosition);
					int localNodePosition = nodePosition - startLinePosition;

					if (StylesheetHelpers.IncludedInSinglelineComment(currentLine, localNodePosition))
					{
						int nextPosition = (endLinePosition < endPosition) ? endLinePosition + 1 : endPosition;

						ProcessOtherContent(contentBuilder, assetContent,
							ref currentPosition, nextPosition);
						continue;
					}

					if (nodeType == LessNodeType.ImportRule)
					{
						GroupCollection importRuleGroups = match.Groups;

						string url = importRuleGroups["url"].Value.Trim();
						string quote = importRuleGroups["quote"].Success ?
							importRuleGroups["quote"].Value : @"""";
						string typeList = importRuleGroups["typeList"].Value;
						IList<string> types = Utils.ConvertToStringCollection(typeList, ',',
							trimItemValues: true, removeEmptyItems: true);
						LessImport processedImport;

						string importRule = match.Value;
						string processedImportRule = ProcessImportRule(assetUrl, url, types, quote,
							out processedImport);

						if (processedImport != null)
						{
							var imports = stylesheet.Imports;
							LessImportOptions importOptions = processedImport.ImportOptions;
							string urlInUpperCase = processedImport.Url.ToUpperInvariant();

							if (imports.Count(i => i.Url.ToUpperInvariant() == urlInUpperCase
								&& i.ImportOptions == importOptions) == 0)
							{
								imports.Add(processedImport);
							}
						}

						contentBuilder.Append(processedImportRule);
						currentPosition += importRule.Length;
					}
					else if (nodeType == LessNodeType.DataUriFunction)
					{
						GroupCollection dataUriFunctionGroups = match.Groups;

						string url = dataUriFunctionGroups["url"].Value.Trim();
						string mimeType = dataUriFunctionGroups["mimeType"].Value;
						string processedDataUriFunctionAssetUrl;

						string dataUriFunction = match.Value;
						string processedDataUriFunction = ProcessDataUriFunction(assetUrl, url, mimeType,
							out processedDataUriFunctionAssetUrl);

						if (!string.IsNullOrWhiteSpace(processedDataUriFunctionAssetUrl))
						{
							var dataUriFunctionAssetUrls = stylesheet.DataUriFunctionAssetUrls;
							string urlInUpperCase = processedDataUriFunctionAssetUrl.ToUpperInvariant();

							if (dataUriFunctionAssetUrls.Count(u => u.ToUpperInvariant() == urlInUpperCase) == 0)
							{
								dataUriFunctionAssetUrls.Add(processedDataUriFunctionAssetUrl);
							}
						}

						contentBuilder.Append(processedDataUriFunction);
						currentPosition += dataUriFunction.Length;
					}
					else if (nodeType == LessNodeType.UrlRule)
					{
						GroupCollection urlRuleGroups = match.Groups;

						string url = urlRuleGroups["url"].Value.Trim();
						string quote = urlRuleGroups["quote"].Success ?
							urlRuleGroups["quote"].Value : string.Empty;

						string urlRule = match.Value;
						string processedUrlRule = ProcessUrlRule(assetUrl, url, quote);

						contentBuilder.Append(processedUrlRule);
						currentPosition += urlRule.Length;
					}
				}
				else if (nodeType == LessNodeType.MultilineComment)
				{
					int nextPosition = nodePosition + match.Length;

					ProcessOtherContent(contentBuilder, assetContent,
						ref currentPosition, nextPosition);
				}
			}

			if (currentPosition > 0 && currentPosition <= endPosition)
			{
				ProcessOtherContent(contentBuilder, assetContent,
					ref currentPosition, endPosition + 1);
			}

			stylesheet.Content = contentBuilder.ToString();

			return stylesheet;
		}