Mini Kabibi Habibi

Current Path : C:/Users/Public/Documents/DXperience 13.1 Demos/Reporting/VB/ReportWebDemo/App_Code/
Upload File :
Current File : C:/Users/Public/Documents/DXperience 13.1 Demos/Reporting/VB/ReportWebDemo/App_Code/Utils.vb

Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Configuration
Imports System.IO
Imports System.Linq
Imports System.Reflection
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Web
Imports System.Web.Configuration
Imports System.Web.UI
Imports System.Web.UI.HtmlControls
Imports System.Web.UI.WebControls
Imports DevExpress.Web.ASPxClasses.Internal
Imports DevExpress.Web.ASPxClasses

Namespace DevExpress.Web.Demos

	Public Class SourceCodePage
		Public Title As String = ""
		Public Code As String = ""
		Public Expanded As Boolean = False

		Public Sub New(ByVal title As String, ByVal code As String, ByVal expanded As Boolean)
			Me.Title = title
			Me.Code = code
			Me.Expanded = expanded
		End Sub
	End Class

	Public Class FeaturedDemoInfo
		Private privateTitle As String
		Public Property Title() As String
			Get
				Return privateTitle
			End Get
			Set(ByVal value As String)
				privateTitle = value
			End Set
		End Property
		Private privateDescription As String
		Public Property Description() As String
			Get
				Return privateDescription
			End Get
			Set(ByVal value As String)
				privateDescription = value
			End Set
		End Property
		Private privateNavigateUrl As String
		Public Property NavigateUrl() As String
			Get
				Return privateNavigateUrl
			End Get
			Set(ByVal value As String)
				privateNavigateUrl = value
			End Set
		End Property
		Private privateImageUrl As String
		Public Property ImageUrl() As String
			Get
				Return privateImageUrl
			End Get
			Set(ByVal value As String)
				privateImageUrl = value
			End Set
		End Property
	End Class

	Public Class ProductInfo
		Private privateTitle As String
		Public Property Title() As String
			Get
				Return privateTitle
			End Get
			Set(ByVal value As String)
				privateTitle = value
			End Set
		End Property
		Private privateDescription As String
		Public Property Description() As String
			Get
				Return privateDescription
			End Get
			Set(ByVal value As String)
				privateDescription = value
			End Set
		End Property
		Private privateNavigateUrl As String
		Public Property NavigateUrl() As String
			Get
				Return privateNavigateUrl
			End Get
			Set(ByVal value As String)
				privateNavigateUrl = value
			End Set
		End Property
		Private privateImageUrl As String
		Public Property ImageUrl() As String
			Get
				Return privateImageUrl
			End Get
			Set(ByVal value As String)
				privateImageUrl = value
			End Set
		End Property
	End Class

	Public NotInheritable Class Utils
		Private Const CurrentDemoKey As String = "DXCurrentDemo", CurrentThemeCookieKeyPrefix As String = "DXCurrentTheme", DefaultTheme As String = "Metropolis"

		Private Shared ReadOnly sourceCodeCache As New Dictionary(Of DemoModel, IEnumerable(Of SourceCodePage))()
		Private Shared ReadOnly sourceCodeCacheLock As Object = New Object()

		Private Shared _codeLanguage As String

		Private Sub New()
		End Sub
		Private Shared ReadOnly Property Context() As HttpContext
			Get
				Return HttpContext.Current
			End Get
		End Property

		Private Shared ReadOnly Property Request() As HttpRequest
			Get
				Return Context.Request
			End Get
		End Property

		Public Shared ReadOnly Property IsMvc() As Boolean
			Get
				Return DemosModel.Current.IsMvc
			End Get
		End Property
		Public Shared ReadOnly Property IsMvcRazor() As Boolean
			Get
				Return DemosModel.Current.IsMvcRazor
			End Get
		End Property

		Public Shared ReadOnly Property CurrentDemo() As DemoModel
			Get
				Return CType(Context.Items(CurrentDemoKey), DemoModel)
			End Get
		End Property
		Public Shared ReadOnly Property RootProduct() As DemoProductModel
			Get
				If IsMvc Then
					Return DemosModel.Current
				Else
					Return DemosModel.Instance.SortedDemoProducts.Find(Function(p) p.IsRootDemo)
				End If
			End Get
		End Property
		Public Shared ReadOnly Property CurrentDemoNodeName() As String
			Get
				If IsMvc Then
					If CurrentDemoPage Is Nothing Then
						Return CurrentDemo.Product.Key
					Else
						Return String.Format("{0}_{1}", CurrentDemoPage.Group.Key, CurrentDemoPage.Key)
					End If
				Else
					If CurrentDemoPage IsNot Nothing Then
						Return String.Format("{0}_{1}_{2}", CurrentDemoPage.Product.Key, CurrentDemoPage.Group.Key, CurrentDemoPage.Key)
					End If
					If CurrentDemo IsNot Nothing Then
						Return CurrentDemo.Product.Key
					End If
					Return Nothing
				End If
			End Get
		End Property

		Public Shared ReadOnly Property CurrentDemoTitleHtml() As String
			Get
				Return GetDemoTitleHtml(CurrentDemo)
			End Get
		End Property

		Public Shared ReadOnly Property CurrentIntro() As IntroPageModel
			Get
				If TypeOf CurrentDemo Is IntroPageModel OrElse CurrentDemo Is Nothing Then
					Return CType(CurrentDemo, IntroPageModel)
				End If
				Return CurrentDemo.Product.Intro
			End Get
		End Property
		Public Shared ReadOnly Property CurrentDemoPage() As DemoPageModel
			Get
				Return TryCast(CurrentDemo, DemoPageModel)
			End Get
		End Property

		Public Shared ReadOnly Property CurrentThemeCookieKey() As String
			Get
				Return CurrentThemeCookieKeyPrefix
			End Get
		End Property

		Public Shared ReadOnly Property CurrentTheme() As String
			Get
				If CanChangeTheme AndAlso Request.Cookies(CurrentThemeCookieKey) IsNot Nothing Then
					Return HttpUtility.UrlDecode(Request.Cookies(CurrentThemeCookieKey).Value)
				End If
				Return DefaultTheme
			End Get
		End Property
		Public Shared ReadOnly Property CurrentThemeTitle() As String
			Get
				Dim theme = CurrentTheme
				Dim themeModel = ThemesModel.Current.Groups.SelectMany(Function(g) g.Themes).FirstOrDefault(Function(t) t.Name Is theme)
				If themeModel IsNot Nothing Then
					Return themeModel.Title
				Else
					Return theme
				End If
			End Get
		End Property

		Public Shared ReadOnly Property IsIntro() As Boolean
			Get
				Return TypeOf Utils.CurrentDemo Is IntroPageModel
			End Get
		End Property

		Public Shared Function GetDemoTitleHtml(ByVal demo As DemoModel) As String
			Dim result As String = String.Empty
			If TypeOf demo Is DemoPageModel Then
				result = String.Format("{0} - {1}", (CType(demo, DemoPageModel)).Group.Title, demo.Title)
			End If
			If String.IsNullOrEmpty(result) Then
				result = demo.Title
			ElseIf result.Length > 60 Then
				result = demo.Title
			End If
			Return HttpUtility.HtmlEncode(result)
		End Function

		Public Shared ReadOnly Property CodeLanguage() As String
			Get
				If _codeLanguage Is Nothing Then
					Try
						Using _file As FileStream = File.OpenRead(Context.Server.MapPath("~/Site.master"))
						Using reader As TextReader = New StreamReader(_file)
							Dim line As String = reader.ReadLine()
							Dim match As Match = Regex.Match(line, "language=""([^""]+)", RegexOptions.IgnoreCase)
							If match.Success Then
								_codeLanguage = match.Groups(1).Value.ToUpper()
							End If
						End Using
						End Using
					Catch
					End Try
					If String.IsNullOrEmpty(_codeLanguage) Then
						_codeLanguage = "C#"
					End If
				End If
				Return _codeLanguage
			End Get
		End Property

		Public Shared Function GetCurrentSourceCodePages() As IEnumerable(Of SourceCodePage)
			Return GetSourceCodePages(TryCast(CurrentDemo, DemoPageModel))
		End Function

		Public Shared Function GetSourceCodePages(ByVal demo As DemoPageModel) As IEnumerable(Of SourceCodePage)
			SyncLock sourceCodeCacheLock
				If (Not sourceCodeCache.ContainsKey(demo)) Then
					sourceCodeCache(demo) = CreateSourceCodePages(demo)
				End If
				Return sourceCodeCache(demo)
			End SyncLock
		End Function

		Private Shared Function CreateSourceCodePages(ByVal demo As DemoPageModel) As IEnumerable(Of SourceCodePage)
			Dim result As New List(Of SourceCodePage)()
			If IsMvc Then
				For Each fileName As String In demo.SourceFiles
					If fileName.StartsWith("~/Models/") Then
						AddSourceCodePage(result, String.Format("Model ({0})", Path.GetFileNameWithoutExtension(fileName)), fileName, False)
					End If
				Next fileName
				Dim controllerUrl As String = String.Format("~/Controllers/{0}/{0}Controller.{1}.cs", demo.Group.Key, demo.Key)
				AddSourceCodePage(result, "Controller", controllerUrl, True, False)
				Dim commonControllerUrl As String = String.Format("~/Controllers/{0}Controller.cs", demo.Group.Key)
				AddSourceCodePage(result, "Controller (common)", commonControllerUrl, False)
				Dim viewUrl As String
				If IsMvcRazor Then
					viewUrl = String.Format("~/Views/{0}/{1}.{2}", demo.Group.Key, demo.Key,"cshtml")
				Else
					viewUrl = String.Format("~/Views/{0}/{1}.{2}", demo.Group.Key, demo.Key,"aspx")
				End If
				AddSourceCodePage(result, "View", viewUrl, True, False)
				For Each fileName As String In demo.SourceFiles
					If fileName.StartsWith("~/Views/") Then
						AddSourceCodePage(result, String.Format("View ({0})", Path.GetFileNameWithoutExtension(fileName)), fileName, True)
					End If
				Next fileName
			Else
				Dim baseUrl As String = GenerateWebFormsDemoUrl(demo)
				AddSourceCodePage(result, "ASPX", baseUrl, True)
				AddSourceCodePage(result, "C#", baseUrl & ".cs", CodeLanguage = "C#")
				AddSourceCodePage(result, "VB", baseUrl & ".vb", CodeLanguage = "VB")
				For Each fileName As String In demo.SourceFiles
					AddSourceCodePage(result, Path.GetFileName(fileName), fileName, False)
				Next fileName
			End If
			Return result
		End Function

		Private Shared Sub AddSourceCodePage(ByVal list As List(Of SourceCodePage), ByVal title As String, ByVal url As String, ByVal expanded As Boolean)
			AddSourceCodePage(list, title, url, expanded, True)
		End Sub
		Private Shared Sub AddSourceCodePage(ByVal list As List(Of SourceCodePage), ByVal title As String, ByVal url As String, ByVal expanded As Boolean, ByVal showIfError As Boolean)
			Dim content As String = String.Empty
			Try
				content = GetHighlightedFileContent(url)
			Catch
				If showIfError Then
					content = "Error rendering source code"
				Else
					content = String.Empty
				End If
			End Try
			If (Not String.IsNullOrEmpty(content)) Then
				list.Add(New SourceCodePage(title, content, expanded))
			End If
		End Sub
		Private Shared Function GetHighlightedFileContent(ByVal virtualPath As String) As String
			Dim filePath As String = GetHighlightedFilePath(virtualPath)
			Dim text As String = File.ReadAllText(filePath)
			Return CodeFormatter.GetFormattedCode(Path.GetExtension(filePath), text, IsMvc, IsMvcRazor)
		End Function
		Private Shared Function GetHighlightedFilePath(ByVal virtualPath As String) As String
			Dim result As String = New DirectoryInfo(Context.Server.MapPath("~/")).FullName
			result = Path.Combine(result, ".Source")
			result = Path.Combine(result, virtualPath.Substring(2))
			If File.Exists(result) Then
				Return result
			End If

			result = Context.Server.MapPath(virtualPath)
			If (Not File.Exists(result)) Then
				result = CorrectSourceFilePath(result)
			End If
			Return result
		End Function

		Private Shared Function CorrectSourceFilePath(ByVal filePath As String) As String
			Dim csPathItem As String = String.Format("{0}cs{0}", Path.DirectorySeparatorChar)
			Dim vbPathItem As String = String.Format("{0}vb{0}", Path.DirectorySeparatorChar)
			filePath = filePath.ToLower()
			If filePath.EndsWith(".cs") Then
				Return filePath.Replace(vbPathItem, csPathItem)
			End If
			If filePath.EndsWith(".vb") Then
				Return filePath.Replace(csPathItem, vbPathItem)
			End If
			Return filePath
		End Function

		Public Shared Function GetVersionText() As String
			Dim parts() As String = AssemblyInfo.Version.Split("."c)
			Return String.Format("v{0} vol {1}.{2}", 2000 + Integer.Parse(parts(0)), parts(1), parts(2))
		End Function

		Public Shared Sub RegisterCurrentWebFormsDemo(ByVal page As Page)
			Dim path As String = page.AppRelativeVirtualPath.Replace("~/", "").Replace(".aspx", "")
			Dim parts() As String = path.Split("/"c)
			If parts.Length < 1 Then
				Throw New ArgumentException("Invalid demo URL")
			End If

			Dim groupKey As String = ""
			Dim demoKey As String = ""

			If parts.Length > 1 Then
				groupKey = parts(0)
				demoKey = parts(1)
			Else
				demoKey = parts(0)
			End If

			RegisterCurrentDemo(groupKey, demoKey)
		End Sub

		Public Shared Sub RegisterCurrentMvcDemo(ByVal controllerName As String, ByVal actionName As String)
			RegisterCurrentDemo(controllerName, actionName)
		End Sub
		Public Shared Function IsIntroPage(ByVal groupKey As String, ByVal demoKey As String) As Boolean
			If IsMvc OrElse IsMvcRazor Then
				Return groupKey.Equals("Home", StringComparison.InvariantCultureIgnoreCase) AndAlso demoKey.Equals("Index", StringComparison.InvariantCultureIgnoreCase)
			End If
			Return demoKey.Equals("default", StringComparison.InvariantCultureIgnoreCase)
		End Function
		Private Shared Sub RegisterCurrentDemo(ByVal groupKey As String, ByVal demoKey As String)
			Dim demo As DemoModel = Nothing
			If IsIntroPage(groupKey, demoKey) Then
				demo = DemosModel.Current.Intro
			Else
				Dim group As DemoGroupModel = DemosModel.Current.FindGroup(groupKey)
				If group IsNot Nothing Then
					demo = group.FindDemo(demoKey)
				End If
			End If

			If demo Is Nothing Then
				demo = CreateBogusDemoModel()
			End If

			Context.Items(CurrentDemoKey) = demo
			DevExpress.Web.ASPxClasses.Internal.DemoUtils.RegisterDemo(DemosModel.Current.Key, groupKey, demoKey)
		End Sub

		Private Shared Function CreateBogusDemoModel() As DemoPageModel
			Dim group As New DemoGroupModel()
			group.Title = "ASP.NET"

			Dim result As New DemoPageModel()
			result.Group = group
			result.HideSourceCode = True
			result.Title = "Delivered!"

			Return result
		End Function

		Public Shared Function GetCurrentDemoPageTitle() As String
			Dim builder As New StringBuilder()
			If TypeOf CurrentDemo Is IntroPageModel Then
				builder.Append(CurrentDemo.SeoTitle)
			ElseIf TypeOf CurrentDemo Is DemoPageModel Then
				Dim product As String = DemosModel.Current.GetSeoTitle()
				Dim group As String = (CType(CurrentDemo, DemoPageModel)).Group.SeoTitle

				builder.Append(CurrentDemo.GetSeoTitle())
				builder.Append(" - ")
				If String.IsNullOrEmpty(group) Then
					builder.Append(product)
				Else
					builder.Append(group)
				End If
				builder.Append(" Demo")
			End If
			builder.Append(" | DevExpress")
			Return builder.ToString()
		End Function

		Public Shared Sub RegisterCssLink(ByVal page As Page, ByVal url As String)
			RegisterCssLink(page, url, Nothing)
		End Sub

		Public Shared Sub RegisterCssLink(ByVal page As Page, ByVal url As String, ByVal clientId As String)
			If IsMvc Then
				Throw New NotImplementedException()
			End If
			Dim link As New HtmlLink()
			page.Header.Controls.Add(link)
			link.EnableViewState = False
			link.Attributes("type") = "text/css"
			link.Attributes("rel") = "stylesheet"
			If (Not String.IsNullOrEmpty(clientId)) Then
				link.Attributes("id") = clientId
			End If
			link.Href = url
		End Sub

		Public Shared Function GenerateDemoUrl(ByVal demo As DemoModel) As String
			If (Not String.IsNullOrEmpty(demo.HighlightedLink)) Then
				Return demo.HighlightedLink
			End If
			If IsMvc Then
				Return GenerateMvcDemoUrl(demo)
			End If
			Return GenerateWebFormsDemoUrl(demo)
		End Function

		Private Shared Function GenerateWebFormsDemoUrl(ByVal demo As DemoModel) As String
			Dim str As New StringBuilder()
			If demo.Product.IsCurrent Then
				str.Append("~/")
			Else
				Dim url = HttpContext.Current.Request.Url.AbsolutePath
				Dim productUrl = "/" & CurrentDemo.Product.Url
				url = url.Substring(0, url.IndexOf(productUrl, StringComparison.InvariantCultureIgnoreCase) + 1)
				str.AppendFormat("{0}{1}/", url, demo.Product.Url)
			End If

			Dim demoGroup As DemoGroupModel
			If TypeOf demo Is DemoPageModel Then
				demoGroup = (CType(demo, DemoPageModel)).Group
			Else
				demoGroup = Nothing
			End If
			If demoGroup IsNot Nothing AndAlso (Not String.IsNullOrEmpty(demoGroup.Key)) Then
				str.Append(demoGroup.Key)
				str.Append("/")
			End If
			str.Append(demo.Key)
			str.Append(".aspx")
			Return str.ToString()
		End Function

		Private Shared Function GenerateMvcDemoUrl(ByVal demo As DemoModel) As String
			Dim builder As New StringBuilder("~/")

			If TypeOf demo Is DemoPageModel Then
				Dim demoGroup As DemoGroupModel = (CType(demo, DemoPageModel)).Group
				If (Not String.IsNullOrEmpty(demoGroup.Key)) Then
					builder.Append(demoGroup.Key)
					builder.Append("/")
				End If
				builder.Append(demo.Key)
			End If
			Return builder.ToString()
		End Function

		Public Shared Function GenerateFeaturedDemos() As List(Of FeaturedDemoInfo)
			Dim result = New List(Of FeaturedDemoInfo)()
			For Each demo In DemosModel.Current.HighlightedDemos
				result.Add(New FeaturedDemoInfo With {.Title = demo.GetHighlightedTitle(), .ImageUrl = demo.HighlightedImageUrl, .NavigateUrl = GenerateDemoUrl(demo), .Description = demo.HighlightedDescription})
			Next demo
			If Utils.CurrentIntro IsNot Nothing Then
				For Each demo In Utils.CurrentIntro.ExternalDemos
					result.Add(New FeaturedDemoInfo With {.Title = demo.Title, .ImageUrl = demo.ImageUrl, .NavigateUrl = demo.Url})
				Next demo
			End If
			Return result
		End Function
		Public Shared Function GenerateProductDemos(ByVal highlited As Boolean) As List(Of ProductInfo)
			Dim result = New List(Of ProductInfo)()
			For Each item In DemosModel.Instance.SortedDemoProducts.Where(Function(p) (Not p.HideNavItem) AndAlso (Not p.IsRootDemo) AndAlso p.IntegrationHighlighted = highlited)
				result.Add(New ProductInfo() With {.NavigateUrl = GenerateDemoUrl(item.Intro), .ImageUrl = item.IntegrationImageUrl, .Description = item.IntegrationDescription, .Title = item.NavItemTitle})
			Next item
			Return result
		End Function
		Public Shared Sub EnsureRequestValidationMode()
			Try
				If Environment.Version.Major >= 4 Then
					Dim type As Type = GetType(WebControl).Assembly.GetType("System.Web.Configuration.RuntimeConfig")
					Dim getConfig As MethodInfo = type.GetMethod("GetConfig", BindingFlags.Static Or BindingFlags.NonPublic, Nothing, New Type() { }, Nothing)
					Dim runtimeConfig As Object = getConfig.Invoke(Nothing, Nothing)
					Dim getSection As MethodInfo = type.GetMethod("GetSection", BindingFlags.Instance Or BindingFlags.NonPublic, Nothing, New Type() { GetType(String), GetType(Type) }, Nothing)
					Dim httpRuntimeSection As HttpRuntimeSection = CType(getSection.Invoke(runtimeConfig, New Object() { "system.web/httpRuntime", GetType(HttpRuntimeSection) }), HttpRuntimeSection)
					Dim bReadOnly As FieldInfo = GetType(ConfigurationElement).GetField("_bReadOnly", BindingFlags.Instance Or BindingFlags.NonPublic)
					bReadOnly.SetValue(httpRuntimeSection, False)

					Dim pi As PropertyInfo = GetType(HttpRuntimeSection).GetProperty("RequestValidationMode")
					If pi IsNot Nothing Then
						Dim version As Version = CType(pi.GetValue(httpRuntimeSection, Nothing), Version)
						Dim RequiredRequestValidationMode As New Version(2, 0)
						If version IsNot Nothing AndAlso (Not Version.Equals(version, RequiredRequestValidationMode)) Then
							pi.SetValue(httpRuntimeSection, RequiredRequestValidationMode, Nothing)
						End If
					End If
					bReadOnly.SetValue(httpRuntimeSection, True)
				End If
			Catch
			End Try
		End Sub

		Private Shared _isSiteMode As Nullable(Of Boolean)
		Public Shared ReadOnly Property IsSiteMode() As Boolean
			Get
				If (Not _isSiteMode.HasValue) Then
					_isSiteMode = ConfigurationManager.AppSettings("SiteMode").Equals("true", StringComparison.InvariantCultureIgnoreCase)
				End If
				Return _isSiteMode.Value
			End Get
		End Property

		Public Shared Function GetReadOnlyMessageHtml() As String
			Return String.Format("<b>Data modifications are not allowed in the online demo.</b><br />" & "If you need to test data editing functionality, please install " & "{0} on your machine and run the demo locally.", DemosModel.Current.Title)
		End Function
		Public Shared Function GetReadOnlyMessageText() As String
			Return String.Format("Data modifications are not allowed in the online demo." & Constants.vbLf & "If you need to test data editing functionality, please install " & Constants.vbLf & "{0} on your machine and run the demo locally.", DemosModel.Current.Title)
		End Function

		Public Shared Sub AssertNotReadOnly()
			If (Not IsSiteMode) Then
				Return
			End If
			Throw New InvalidOperationException(GetReadOnlyMessageHtml())
		End Sub
		Public Shared Sub AssertNotReadOnlyText()
			If (Not IsSiteMode) Then
				Return
			End If
			Throw New InvalidOperationException(GetReadOnlyMessageText())
		End Sub
		Public Shared ReadOnly Property CanChangeTheme() As Boolean
			Get
				Return (Not IsIntro) AndAlso (Not IsIE6()) AndAlso DemosModel.Current.SupportsTheming
			End Get
		End Property

		Public Shared Sub InjectDescriptionMeta(ByVal parent As Control)
			If String.IsNullOrEmpty(Utils.CurrentDemo.MetaDescription) Then
				Return
			End If

			Dim page As Page = TryCast(parent, Page)
			Dim header As HtmlHead
			If (page IsNot Nothing AndAlso page.Header IsNot Nothing) Then
				header = page.Header
			Else
				header = RenderUtils.FindHead(parent)
			End If
			If header IsNot Nothing Then
				Dim metaControl As New LiteralControl(String.Format("<meta name=""description"" content=""{0}"" />", Utils.CurrentDemo.MetaDescription))
				header.Controls.AddAt(0, metaControl)
			End If
		End Sub

		Public Shared Sub InjectIE7CompatModeMeta(ByVal parent As Control)
			InjectIECompatModeMeta(parent, 7)
		End Sub
		Public Shared Sub InjectIEEdgeCompatModeMeta(ByVal parent As Control)
			If RenderUtils.Browser.IsIE Then
			   ASPxWebControl.SetIECompatibilityModeEdge(parent)
			End If
		End Sub

		Public Shared Sub InjectIECompatModeMeta(ByVal parent As Control, ByVal compatibilityVersion As Integer)
			If (Not RenderUtils.Browser.IsIE) OrElse RenderUtils.Browser.Version >= 10 OrElse RenderUtils.Browser.Version < compatibilityVersion + 1 Then
				Return
			End If
			ASPxWebControl.SetIECompatibilityMode(compatibilityVersion, parent)
		End Sub

		Public Shared Function IsIE6() As Boolean
			Return RenderUtils.Browser.IsIE AndAlso RenderUtils.Browser.Version < 7
		End Function

		Public Shared Function IsIE9() As Boolean
			Return RenderUtils.Browser.IsIE AndAlso RenderUtils.Browser.Version > 8
		End Function

		Public Shared Function IsIE10() As Boolean
			Return RenderUtils.Browser.IsIE AndAlso RenderUtils.Browser.Version > 9
		End Function
	End Class
	Public NotInheritable Class SearchUtils
		Private Shared ReadOnly separators() As String = { " ", ",", "/", "\", "-", "+" }

		Private Shared _requestExclusions() As String
		Private Shared _prefixes() As String
		Private Shared _postfixes() As String
		Private Shared _synonyms()() As String

		Private Sub New()
		End Sub
		Private Shared ReadOnly Property WordsExclusions() As String()
			Get
				If _requestExclusions Is Nothing Then
					_requestExclusions = DemosModel.Instance.Search.Exclusions.Words.Split(separators, StringSplitOptions.RemoveEmptyEntries)
				End If
				Return _requestExclusions
			End Get
		End Property
		Private Shared ReadOnly Property PrefixesExclusions() As String()
			Get
				If _prefixes Is Nothing Then
					_prefixes = DemosModel.Instance.Search.Exclusions.Prefixes.Split(separators, StringSplitOptions.RemoveEmptyEntries)
				End If
				Return _prefixes
			End Get
		End Property
		Private Shared ReadOnly Property PostfixesExclusions() As String()
			Get
				If _postfixes Is Nothing Then
					_postfixes = DemosModel.Instance.Search.Exclusions.Postfixes.Split(separators, StringSplitOptions.RemoveEmptyEntries)
				End If
				Return _postfixes
			End Get
		End Property
		Private Shared ReadOnly Property Synonyms() As String()()
			Get
				If _synonyms Is Nothing Then
					_synonyms = DemosModel.Instance.Search.Synonyms.Groups.Select(Function(s) s.Split(separators, StringSplitOptions.RemoveEmptyEntries)).ToArray()
				End If
				Return _synonyms
			End Get
		End Property

		Public Shared Function DoSearch(ByVal request As String) As List(Of SearchResult)
			Dim results = New List(Of SearchResult)()
			Dim requests = SplitRequests(request)
			Try
				Dim products = DemosModel.Instance.SortedDemoProducts.Where(Function(dp) (Not dp.IsRootDemo) AndAlso (dp Is DemosModel.Current OrElse ((Not dp.HideNavItem) AndAlso Utils.IsSiteMode)))
				For Each product In products
					results.AddRange(DoSearch(requests, product))
				Next product
			Catch
			End Try
			results.Sort()
			Return results
		End Function
		Public Shared Function GetKeywordsRankList(ByVal model As ModelBase) As Dictionary(Of String, Integer)
			Dim textRanks As New List(Of TextRank) (New TextRank() {New TextRank(model.Keywords, 3)})

			Dim product = TryCast(model, DemoProductModel)
			Dim group = TryCast(model, DemoGroupModel)
			Dim demo = TryCast(model, DemoPageModel)

			If product IsNot Nothing Then
				textRanks.Add(New TextRank(product.NavItemTitle, 5))
				textRanks.Add(New TextRank(product.Key, 3))
				textRanks.Add(New TextRank(product.Title, 3))
				textRanks.Add(New TextRank(product.SeoTitle, 2))
			ElseIf group IsNot Nothing Then
				textRanks.Add(New TextRank(group.Title, 5))
				textRanks.Add(New TextRank(group.Key, 3))
				textRanks.Add(New TextRank(group.SeoTitle, 2))
			ElseIf demo IsNot Nothing Then
				textRanks.Add(New TextRank(demo.Title, 5))
				textRanks.Add(New TextRank(demo.Key, 3))
				textRanks.Add(New TextRank(demo.SeoTitle, 2))
			End If
			Return GetKeywordsRankList(textRanks)
		End Function

		Private Shared Function CalculateRank(ByVal requests As List(Of String()), ByVal demo As DemoPageModel) As Integer
			Dim resultRank As Integer = 0
			Dim keywordRank As Integer = 0
			For Each request In requests
				Dim requestRank As Integer = -1
				If CalculateRank(request, demo.KeywordsRankList, keywordRank) Then
					requestRank += keywordRank
				End If
				If CalculateRank(request, demo.Group.KeywordsRankList, keywordRank) Then
					requestRank += keywordRank
				End If
				If CalculateRank(request, demo.Product.KeywordsRankList, keywordRank) Then
					requestRank += keywordRank
				End If
				If requestRank = -1 AndAlso WordsExclusions.Any(Function(re) re.Equals(request(0), StringComparison.InvariantCultureIgnoreCase)) Then
					requestRank = 0
				End If

				If requestRank > -1 Then
					resultRank += requestRank
				Else
					Return -1
				End If
			Next request
			Return resultRank
		End Function
		Private Shared Function CalculateRank(ByVal synonyms() As String, ByVal keywordsRankList As Dictionary(Of String, Integer), <System.Runtime.InteropServices.Out()> ByRef rank As Integer) As Boolean
			Dim keyword = keywordsRankList.Keys.FirstOrDefault(Function(k) MatchWord(synonyms(0), k))
			If keyword IsNot Nothing Then
				rank = keywordsRankList(keyword)
			Else
				rank = -1
			End If
			If rank = -1 Then
				For Each syn In synonyms.Skip(1)
					keyword = keywordsRankList.Keys.FirstOrDefault(Function(k) MatchWord(syn, k))
					If keyword IsNot Nothing Then
						rank += keywordsRankList(keyword)
					Else
						rank += -1
					End If
					If rank > -1 Then
						Exit For
					End If
				Next syn
			End If
			Return rank > -1
		End Function
		Private Shared Function DoSearch(ByVal requests As List(Of String()), ByVal product As DemoProductModel) As IEnumerable(Of SearchResult)
			Dim results = New List(Of SearchResult)()
			For Each demo In product.Groups.SelectMany(Function(g) g.Demos)
				Dim rank = CalculateRank(requests, demo)
				If rank > -1 Then
					Dim sr = New SearchResult(demo, rank)
					If Utils.IsMvc Then
						sr.Text = HighlightOccurences(demo.Title, requests)
					Else
						sr.Text = String.Format("{0} ({1})", HighlightOccurences(demo.Title, requests), HighlightOccurences(demo.Group.Title, requests))
					End If
					If Utils.IsMvc Then
						sr.ProductText = (demo.Group.Title).ToUpper()
					Else
						sr.ProductText = (demo.Product.Title).ToUpper()
					End If
					results.Add(sr)
				End If
			Next demo
			Return results
		End Function

		Private Shared Function HighlightOccurences(ByVal text As String, ByVal requests As List(Of String())) As String
			Dim validRequest = New Regex("[0-9a-zA-Z]+", RegexOptions.IgnoreCase)
			For Each request In requests.SelectMany(Function(r) r)
				If validRequest.IsMatch(request) Then
					Dim re As New Regex("([a-zA-Z0-9]*" & request & "[a-zA-Z0-9]*)", RegexOptions.IgnoreCase)
					text = re.Replace(text, "<b>$0</b>")
				End If
			Next request
			Return text
		End Function

		Private Shared Function SplitRequests(ByVal request As String) As List(Of String())
			Dim words = request.Split(separators, StringSplitOptions.RemoveEmptyEntries)
			Dim result = New List(Of String())()
			For Each word In words
				Dim resultWord = PrepareWord(word)
				Dim synonymList = Synonyms.FirstOrDefault(Function(list) list.Any(Function(s) MatchWord(resultWord, s)))
				Dim wordSynonyms = New List(Of String) (New String() {resultWord})
				If synonymList IsNot Nothing Then
					wordSynonyms.AddRange(synonymList.Where(Function(s) (Not MatchWord(resultWord, s))))
				End If
				result.Add(wordSynonyms.Distinct().ToArray())
			Next word
			Return result
		End Function
		Private Shared Function PrepareWord(ByVal word As String) As String
			For Each prefix In PrefixesExclusions
				If word.StartsWith(prefix, StringComparison.InvariantCultureIgnoreCase) AndAlso word.Length > prefix.Length Then
					word = word.Remove(0, prefix.Length)
				End If
			Next prefix
			For Each postfix In PostfixesExclusions
				If word.EndsWith(postfix, StringComparison.InvariantCultureIgnoreCase) AndAlso word.Length > postfix.Length Then
					word = word.Substring(0, word.Length - postfix.Length)
				End If
			Next postfix
			Return word
		End Function
		Private Shared Function MatchWord(ByVal request As String, ByVal word As String) As Boolean
			Return word.IndexOf(request, StringComparison.InvariantCultureIgnoreCase) > -1
		End Function
		Friend Shared Function GetKeywordsList(ParamArray ByVal words() As String) As String()
			Return words.SelectMany(Function(w) w.Split(separators, StringSplitOptions.RemoveEmptyEntries)).Distinct().ToArray()
		End Function

		Private Shared Function GetKeywordsRankList(ByVal textRanks As List(Of TextRank)) As Dictionary(Of String, Integer)
			Dim result = New Dictionary(Of String, Integer)()
			For Each textRank In textRanks
				Dim words = textRank.Text.Split(separators, StringSplitOptions.RemoveEmptyEntries)
				For Each word In words
					Dim rankWord = PrepareWord(word)
					If (Not result.ContainsKey(rankWord)) Then
						result(rankWord) = textRank.Rank
					End If
				Next word
			Next textRank
			Return result
		End Function
	End Class


	Public Class TextRank
		Public Sub New(ByVal text As String, ByVal rank As Integer)
			Text = text
			Rank = rank
		End Sub
		Private privateText As String
		Public Property Text() As String
			Get
				Return privateText
			End Get
			Set(ByVal value As String)
				privateText = value
			End Set
		End Property
		Private privateRank As Integer
		Public Property Rank() As Integer
			Get
				Return privateRank
			End Get
			Set(ByVal value As Integer)
				privateRank = value
			End Set
		End Property
	End Class
	Public Class SearchResult
		Implements IComparable(Of SearchResult)
		Public Sub New(ByVal demo As DemoModel, ByVal rank As Integer)
			Demo = demo
			Me.Rank = rank
			Product = demo.Product
			If TypeOf demo Is DemoPageModel Then
				Group = (TryCast(demo, DemoPageModel)).Group
			End If
		End Sub

		Private privateProduct As DemoProductModel
		Public Property Product() As DemoProductModel
			Get
				Return privateProduct
			End Get
			Set(ByVal value As DemoProductModel)
				privateProduct = value
			End Set
		End Property
		Private privateDemo As DemoModel
		Public Property Demo() As DemoModel
			Get
				Return privateDemo
			End Get
			Set(ByVal value As DemoModel)
				privateDemo = value
			End Set
		End Property
		Private privateGroup As DemoGroupModel
		Public Property Group() As DemoGroupModel
			Get
				Return privateGroup
			End Get
			Set(ByVal value As DemoGroupModel)
				privateGroup = value
			End Set
		End Property
		Private privateText As String
		Public Property Text() As String
			Get
				Return privateText
			End Get
			Set(ByVal value As String)
				privateText = value
			End Set
		End Property
		Private privateProductText As String
		Public Property ProductText() As String
			Get
				Return privateProductText
			End Get
			Set(ByVal value As String)
				privateProductText = value
			End Set
		End Property

		Public Rank As Integer = 0

		#Region "IComparable<SearchResult> Members"

		Public Function CompareTo(ByVal other As SearchResult) As Integer Implements IComparable(Of SearchResult).CompareTo
			Return other.Rank.CompareTo(Rank)
		End Function

		#End Region
	End Class
End Namespace