Imports System.ComponentModel
Imports ComponentPro.Net
Imports System.Text
Imports ComponentPro
Imports ComponentPro.Net.Mail

Namespace EmailValidatorDemo
	Partial Public Class Main
		Inherits Form
		Private ReadOnly _exception As Boolean
		Private _blackListFile As String
		Private _whiteListFile As String

		Private _selectedTabIndex As Integer

		Private _dataDir As String
		Public ReadOnly Property DataDir() As String
			Get
				If _dataDir Is Nothing Then
					' Set default data dir.
					_dataDir = AppDomain.CurrentDomain.BaseDirectory & "..\..\Data"
					If Not System.IO.Directory.Exists(_dataDir) Then
						_dataDir = AppDomain.CurrentDomain.BaseDirectory & "Data"
					End If
				End If
				Return _dataDir
			End Get
		End Property

		Public Sub New()
			Dim emailListFile As String

			' This licensing exception handling code segment is not needed if you have a production license.
			Try
				InitializeComponent()
			Catch exc As ComponentPro.Licensing.EmailValidator.UltimateLicenseException
				MessageBox.Show(exc.Message)
				_exception = True
				Return
			End Try

			emailListFile = DataDir & "\EmailList.txt"
			txtEmailListFile.Text = emailListFile
			txtEmailListThread.Text = emailListFile

#If (Not Framework4_5) AndAlso (Not SYNC) Then
			AddHandler Me.emailValidator.ValidateCompleted, AddressOf sfbEmailValidator_ValidateCompleted
			AddHandler Me.emailValidator.ValidateEmailsCompleted, AddressOf sfbEmailValidator_ValidateTextFileCompleted
			AddHandler Me.emailValidator.GetMailExchangeRecordsCompleted, AddressOf sfbEmailValidator_GetMailExchangeRecordsCompleted
#End If
		End Sub

		''' <summary>
		''' Handles the form Load's event.
		''' </summary>
		''' <param name="e">The event arguments.</param>
		Protected Overrides Sub OnLoad(ByVal e As EventArgs)
			MyBase.OnLoad(e)
			If _exception Then
				Me.Close()
			End If

			LoadConfig()
		End Sub

		''' <summary>
		''' Handles the form Closing's event.
		''' </summary>
		''' <param name="e">The event arguments.</param>
		Protected Overrides Sub OnClosing(ByVal e As System.ComponentModel.CancelEventArgs)
			SaveConfig()

			MyBase.OnClosing(e)
		End Sub

		#Region "Configuration"

		''' <summary>
		''' Loads settings from the Registry.
		''' </summary>
		Private Sub LoadConfig()
			_blackListFile = CStr(Util.GetProperty("BlackList", DataDir & "\BlackList.txt"))
			_whiteListFile = CStr(Util.GetProperty("WhiteList", DataDir & "\WhiteList.txt"))

			' General
			emailValidator.SmtpFromEmail = CStr(Util.GetProperty("From", "someone@microsoft.com"))
			emailValidator.SmtpHeloDomain = CStr(Util.GetProperty("FromDomain", "microsoft.com"))
			emailValidator.SmtpPort = Util.GetIntProperty("SmtpPort", 25)
			emailValidator.SmtpTimeout = Util.GetIntProperty("Timeout", 15000)
			emailValidator.DnsTimeout = Util.GetIntProperty("DnsTimeout", 15000)
			'emailValidator.UseRandomDnsServer = Util.GetIntProperty("UseRandomDnsServer", 1) == 1;
			emailValidator.ValidationLevel = CType(Util.GetIntProperty("Level", CInt(Fix(ValidationLevel.Mailbox))), ValidationLevel)
			emailValidator.UseMailExchangeRecordCache = Util.GetIntProperty("UseMailExchangeRecordCache", 1) = 1
			emailValidator.EmailSyntaxPattern = CStr(Util.GetProperty("Pattern", "^[\w-\.]{1,}\@([\da-zA-Z-]{1,}\.){1,}[\da-zA-Z-]{2,3}$"))
			emailValidator.MailExchangeRecordCacheTimeout = Util.GetIntProperty("MailExchangeRecordCacheTimeout", 30)

			' Proxy
			emailValidator.ProxyHost = CStr(Util.GetProperty("ProxyHost", String.Empty))
			emailValidator.ProxyPort = Util.GetIntProperty("ProxyPort", 1080)
			emailValidator.ProxyUserName = CStr(Util.GetProperty("ProxyUser", String.Empty))
			emailValidator.ProxyPassword = CStr(Util.GetProperty("ProxyPass", String.Empty))
			emailValidator.ProxyDomain = CStr(Util.GetProperty("ProxyDomain", String.Empty))
			emailValidator.ProxyHttpConnectAuthMethodMethod = CType(Util.GetIntProperty("ProxyAuth", CInt(Fix(ProxyHttpConnectAuthMethod.Basic))), ProxyHttpConnectAuthMethod)
			emailValidator.ProxyType = CType(Util.GetIntProperty("ProxyType", CInt(Fix(ProxyType.None))), ProxyType)
		End Sub

		''' <summary>
		''' Saves settings to the registry.
		''' </summary>
		Private Sub SaveConfig()
			Util.SaveProperty("BlackList", _blackListFile)
			Util.SaveProperty("WhiteList", _whiteListFile)

			' General
			Util.SaveProperty("From", emailValidator.SmtpFromEmail)
			Util.SaveProperty("FromDomain", emailValidator.SmtpHeloDomain)
			Util.SaveProperty("SmtpPort", emailValidator.SmtpPort)
			Util.SaveProperty("Timeout", emailValidator.SmtpTimeout)
			Util.SaveProperty("DnsTimeout", emailValidator.DnsTimeout)
			'Util.SaveProperty("UseRandomDnsServer", emailValidator.UseRandomDnsServer ? 1 : 0);
			Util.SaveProperty("Level", CInt(Fix(emailValidator.ValidationLevel)))
			If emailValidator.UseMailExchangeRecordCache Then
				Util.SaveProperty("UseMailExchangeRecordCache",1)
			Else
				Util.SaveProperty("UseMailExchangeRecordCache",0)
			End If
			Util.SaveProperty("Pattern", emailValidator.EmailSyntaxPattern)
			Util.SaveProperty("MailExchangeRecordCacheTimeout", emailValidator.MailExchangeRecordCacheTimeout)

			' Proxy
			Util.SaveProperty("ProxyHost", emailValidator.ProxyHost)
			Util.SaveProperty("ProxyPort", emailValidator.ProxyPort)
			Util.SaveProperty("ProxyUser", emailValidator.ProxyUserName)
			Util.SaveProperty("ProxyPass", emailValidator.ProxyPassword)
			Util.SaveProperty("ProxyDomain", emailValidator.ProxyDomain)
			Util.SaveProperty("ProxyAuth", CInt(Fix(emailValidator.ProxyHttpConnectAuthMethodMethod)))
			Util.SaveProperty("ProxyType", CInt(Fix(emailValidator.ProxyType)))
		End Sub

		#End Region

		#Region "Message Logging"

		''' <summary>
		''' Handles the emailvalidator's MessageLogging event.
		''' </summary>
		''' <param name="sender">The emailvalidator object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub sfbEmailValidator_MessageLogging(ByVal sender As Object, ByVal e As ComponentPro.Net.EmailValidatorLogEventArgs) Handles emailValidator.MessageLogging
			If Not IsDisposed Then
				Invoke(New EventHandler(Of EmailValidatorLogEventArgs)(AddressOf MessageLogging), sender, e)
			End If
		End Sub

		Private Sub MessageLogging(ByVal sender As Object, ByVal e As ComponentPro.Net.EmailValidatorLogEventArgs)
			Dim msg As String = e.SmtpTranscript.Replace(vbCrLf, String.Empty)

			AdvancedLog(msg, e.ThreadId)
		End Sub

		Private Sub AdvancedLog(ByVal msg As String, ByVal threadId As Integer)
			Select Case _selectedTabIndex
				Case 0 ' Single Email
					lst1AdvancedLog.Items.Add(msg)

				Case 1 ' Validate Email Addresses loaded from a file with a single thread
					lst2AdvancedLog.Items.Add(msg)

				Case 2 ' Validate Email Addresses loaded from a file with two threads
					Dim lb As ListBox
					If threadId = 0 Then
						lb = lst3AdvancedLog
					Else
						lb = lst4AdvancedLog
					End If
					lb.Items.Add(msg)
					lb.Invalidate()
			End Select
		End Sub

		Private Sub Log(ByVal msg As String, ByVal threadId As Integer)
			Select Case _selectedTabIndex
				Case 0 ' Single Email
					lst1Log.Items.Add(msg)

				Case 1 ' Validate Email Addresses loaded from a file with a single thread
					lst2Log.Items.Add(msg)

				Case 2 ' Validate Email Addresses loaded from a file with two threads
					Dim lb As ListBox
					If threadId = 0 Then
						lb = lst3Log
					Else
						lb = lst4Log
					End If
					lb.Items.Add(msg)
					lb.Invalidate()
			End Select
		End Sub

		#End Region

		Private _processed As Integer
		Private _passed As Integer

		Private Sub sfbEmailValidator_EmailValidated(ByVal sender As Object, ByVal e As EmailValidatedEventArgs) Handles emailValidator.EmailValidated
			If Not IsDisposed Then
				Invoke(New EventHandler(Of EmailValidatedEventArgs)(AddressOf EmailValidated), sender, e)
			End If
		End Sub

		Private Sub EmailValidated(ByVal sender As Object, ByVal e As EmailValidatedEventArgs)
			If e.Error IsNot Nothing Then
				AdvancedLog(String.Format("Email '{0}' validated at level {1} with error: {2}.", e.EmailAddress, e.ValidatedLevel, e.Error.Message), e.ThreadId)
				Log(String.Format("    Mailbox '{0}' is invalid - completed with error: {1}", e.EmailAddress, e.Error.Message), e.ThreadId)
			Else
				AdvancedLog(String.Format("Email '{0}' validated at level {1}.", e.EmailAddress, e.ValidatedLevel), e.ThreadId)

				If e.ValidatedLevel = ValidationLevel.Success Then
					Log(String.Format("    Completed successfully - Mailbox {0} is valid", e.EmailAddress), e.ThreadId)
					_passed += 1
				Else
					Log(String.Format("    Mailbox '{0}' is invalid - completed at level: {1}", e.EmailAddress, e.ValidatedLevel), e.ThreadId)
				End If
			End If
			AdvancedLog("------------------------------------", e.ThreadId)
			Log("----------------", e.ThreadId)
			_processed += 1
		End Sub

		''' <summary>
		''' Loads black and white lists from files.
		''' </summary>
		Private Sub LoadBlackAndWhiteListFiles()
			If Not String.IsNullOrEmpty(_blackListFile) Then
				Try
					emailValidator.BlackList.LoadFromFile(_blackListFile)
				Catch exc As Exception
					MessageBox.Show("Unable to load: " & _blackListFile & vbCrLf & exc.Message)
				End Try
			End If

			If Not String.IsNullOrEmpty(_whiteListFile) Then
				Try
					emailValidator.WhiteList.LoadFromFile(_whiteListFile)
				Catch exc As Exception
					MessageBox.Show("Unable to load: " & _whiteListFile & vbCrLf & exc.Message)
				End Try
			End If
		End Sub

		Private Sub settingsToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles settingsToolStripMenuItem.Click
			' Show the Settings form.
			Dim form As New SettingsDialog(emailValidator, _whiteListFile, _blackListFile)
			form.ShowDialog()
			_blackListFile = form.BlackListFile
			_whiteListFile = form.WhiteListFile
			' Clear the DNS cache.
			EmailValidator.ClearDnsCache()
		End Sub

		Private Sub lblSettings_LinkClicked(ByVal sender As Object, ByVal e As LinkLabelLinkClickedEventArgs) Handles lblSettings.LinkClicked
			settingsToolStripMenuItem_Click(Nothing, Nothing)
		End Sub

		Private Sub EnableDialog(ByVal enable As Boolean)
			toolbarMain.Enabled = enable
			Util.EnableCloseButton(Me, enable)
		End Sub

		#Region "MailXChange Rec"

		Private Sub EnableMailXChangeRecord(ByVal enable As Boolean)
			EnableDialog(enable)

			lblSettings.Enabled = enable

			tpValidateSingleEmail.Enabled = enable
			tpEmails.Enabled = enable
			tpMultipleThreads.Enabled = enable
			btnGet.Enabled = enable
			txtMXServerAddress.Enabled = enable
		End Sub

		''' <summary>
		''' Handles the Get mail xchange records button's Click event.
		''' </summary>
		''' <param name="sender">The button object.</param>
		''' <param name="e">The event arguments.</param>
#If Framework4_5 Then
		Private Async Sub btnGet_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnGet.Click
#Else
		Private Sub btnGet_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnGet.Click
#End If
			_selectedTabIndex = 3
			lstMXRecords.Items.Clear()

			' Disable some controls.
			EnableMailXChangeRecord(False)

#If Framework4_5 OrElse SYNC Then
			Try
#If SYNC Then
				ShowResult(emailValidator.GetMailExchangeRecords(txtMXServerAddress.Text))
#Else
				' Asynchronously get mail exchange records.
				ShowResult(Await emailValidator.GetMailExchangeRecordsAsync(txtMXServerAddress.Text))
#End If
			Catch exc As Exception
				MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop)
			Finally
				EnableMailXChangeRecord(True)
			End Try
#Else
			' Asynchronously get mail exchange records.
			emailValidator.GetMailExchangeRecordsAsync(txtMXServerAddress.Text)
#End If
		End Sub

		Private Sub ShowResult(ByVal result() As MailExchangeRecord)
			' Get Mail Exchange records.
			For Each m As MailExchangeRecord In result
				' Add to the list control.
				lstMXRecords.Items.Add(m.ToString())
			Next m

			If lstMXRecords.Items.Count = 0 Then
				MessageBox.Show("No MX Records found", "ComponentPro Email Validator", MessageBoxButtons.OK, MessageBoxIcon.Information)
			End If
		End Sub

#If Not Framework4_5 Then
		''' <summary>
		''' Handles the emailvalidator's GetMailExchangeRecordsCompleted event.
		''' </summary>
		''' <param name="sender">The emailvalidator object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub sfbEmailValidator_GetMailExchangeRecordsCompleted(ByVal sender As Object, ByVal e As ExtendedAsyncCompletedEventArgs(Of MailExchangeRecord()))
			If e.Error IsNot Nothing Then
				Util.ShowError(e.Error)
			Else
				ShowResult(e.Result)
			End If

			' Enable controls.
			EnableMailXChangeRecord(True)
		End Sub
#End If

		#End Region

		#Region "Single Mail Validation"

		Private Sub EnableSingleMode(ByVal enable As Boolean)
			EnableDialog(enable)

			lnkSettingsSingle.Enabled = enable

			tpEmails.Enabled = enable
			tpGetMxRecords.Enabled = enable
			tpMultipleThreads.Enabled = enable
			txtEmailSingle.Enabled = enable
			If enable Then
				btnValidateSingle.Text = "Validate"
			Else
				btnValidateSingle.Text = "Stop"
			End If
			If enable Then
				btnValidateSingle.Enabled = True
			End If
		End Sub

		''' <summary>
		''' Handles the validate single email button's Click event.
		''' </summary>
		''' <param name="sender">The button object.</param>
		''' <param name="e">The event arguments.</param>
#If Framework4_5 Then
		Private Async Sub btnValidateSingle_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnValidateSingle.Click
#Else
		Private Sub btnValidateSingle_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnValidateSingle.Click
#End If
			' Is not validating?
			If btnValidateSingle.Text = "Validate" Then
				' Clear logs.
				_selectedTabIndex = 0
				lst1AdvancedLog.Items.Clear()
				lst1Log.Items.Clear()

				EnableSingleMode(False)

				' Load black and white lists.
				LoadBlackAndWhiteListFiles()

#If Framework4_5 OrElse SYNC Then
				Try
#If SYNC Then
					ShowSingleEmailResult(emailValidator.Validate(txtEmailSingle.Text))
#Else
					' Asynchronously validate a single email.
					ShowSingleEmailResult(Await emailValidator.ValidateAsync(txtEmailSingle.Text))
#End If
				Catch exc As Exception
					MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop)
					EnableSingleMode(True)
				End Try
#Else
				' Asynchronously validate a single email.
				emailValidator.ValidateAsync(txtEmailSingle.Text)
#End If
			Else
				' Abort the validation.
				btnValidateSingle.Enabled = False
				emailValidator.Cancel()
			End If
		End Sub

		Private Sub ShowSingleEmailResult(ByVal level As ValidationLevel)
			MessageBox.Show("E-mail address validation completed at level: " & level.ToString(), "Email Validator Demo", MessageBoxButtons.OK, MessageBoxIcon.Information)
		End Sub

#If Not Framework4_5 Then
		''' <summary>
		''' Handles the email validator's ValidateCompleted event.
		''' </summary>
		''' <param name="sender">The email validator object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub sfbEmailValidator_ValidateCompleted(ByVal sender As Object, ByVal e As ExtendedAsyncCompletedEventArgs(Of ValidationLevel))
			If e.Error IsNot Nothing Then
				Util.ShowError(e.Error)
			Else
				ShowSingleEmailResult(e.Result)
			End If

			EnableSingleMode(True)
		End Sub
#End If

		#End Region

		#Region "Validate Text File"

		Private Sub EnableValidateFile(ByVal enable As Boolean)
			EnableDialog(enable)

			lnkSettingsEmailList.Enabled = enable

			tpGetMxRecords.Enabled = enable
			tpMultipleThreads.Enabled = enable
			tpValidateSingleEmail.Enabled = enable
			txtEmailListFile.Enabled = enable
			btnBrowseListFile.Enabled = enable
			If enable Then
				btnValidateFile.Text = "Validate"
			Else
				btnValidateFile.Text = "Stop"
			End If
			If enable Then
				btnValidateFile.Enabled = True
			End If
		End Sub

		''' <summary>
		''' Handles the validate a single file button's Click event.
		''' </summary>
		''' <param name="sender">The button object.</param>
		''' <param name="e">The event arguments.</param>
#If Framework4_5 Then
		Private Async Sub btnValidateFile_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnValidateFile.Click
#Else
		Private Sub btnValidateFile_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnValidateFile.Click
#End If
			' Validating?
			If btnValidateFile.Text = "Validate" Then
				' Clear logs.
				_selectedTabIndex = 1
				lst2AdvancedLog.Items.Clear()
				lst2Log.Items.Clear()
				EnableValidateFile(False)

				' Load email list from a file and validate it easily with ValidateTextFile method.
				LoadBlackAndWhiteListFiles()

				' Reset counters.
				_processed = 0
				_passed = 0

#If Framework4_5 OrElse SYNC Then
				Try
#If SYNC Then
					emailValidator.ValidateTextFile(txtEmailListFile.Text)
#Else
					Await emailValidator.ValidateTextFileAsync(txtEmailListFile.Text)
#End If

					ShowSummary()
				Catch exc As Exception
					MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop)
					EnableValidateFile(True)
				End Try
#Else
				emailValidator.ValidateTextFileAsync(txtEmailListFile.Text)
#End If
			Else
				' Abort the validation.
				btnValidateFile.Enabled = False
				emailValidator.Cancel()
			End If
		End Sub

		Private Sub ShowSummary()
			MessageBox.Show(String.Format("E-mail addresses validation has completed. {0} email(s) processed, {1} passed.", _processed, _passed), "Email Validator Demo", MessageBoxButtons.OK, MessageBoxIcon.Information)
		End Sub

#If (Not Framework4_5) AndAlso (Not SYNC) Then
		''' <summary>
		''' Handles the email validator's ValidateTextFileCompleted event.
		''' </summary>
		''' <param name="sender">The email validator object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub sfbEmailValidator_ValidateTextFileCompleted(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
			If e.Error IsNot Nothing Then
				Util.ShowError(e.Error)
			Else
				ShowSummary()
			End If

			' Enable controls.
			EnableValidateFile(True)
		End Sub
#End If

		#End Region

		#Region "Validate with multiple threads"

		Private Sub EnableValidateWithThreads(ByVal enable As Boolean)
			EnableDialog(enable)

			lnkMultiThreadsSettings.Enabled = enable

			tpEmails.Enabled = enable
			tpGetMxRecords.Enabled = enable
			tpValidateSingleEmail.Enabled = enable
			txtEmailListThread.Enabled = enable
			btnBrowseThread.Enabled = enable
			If enable Then
				btnValidateThreads.Text = "Validate"
			Else
				btnValidateThreads.Text = "Stop"
			End If
			If enable Then
				btnValidateThreads.Enabled = True
			End If
		End Sub

		''' <summary>
		''' Handles the validate with threads button's Click event.
		''' </summary>
		''' <param name="sender">The button object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub btnValidateThreads_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnValidateThreads.Click
			' Validating?
			If btnValidateThreads.Text = "Validate" Then
				' Clear logs.
				_selectedTabIndex = 2
				lst3AdvancedLog.Items.Clear()
				lst4AdvancedLog.Items.Clear()
				lst3Log.Items.Clear()
				lst4Log.Items.Clear()

				Try
					' Disable controls.
					EnableValidateWithThreads(False)

					' Load black and white list files.
					LoadBlackAndWhiteListFiles()
					' Start validate file with multi-threads.
					emailValidator.MultiThreadsValidateTextFile(txtEmailListThread.Text, 2, True)
				Catch exc As Exception
					MessageBox.Show(exc.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop)
					EnableValidateWithThreads(True)
				End Try
			Else
				' Abort operation.
				btnValidateThreads.Enabled = False
				emailValidator.Cancel()
			End If
		End Sub

		''' <summary>
		''' Handles the emailvalidator's ThreadCompleted event.
		''' </summary>
		''' <param name="sender">The emailvalidator object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub sfbEmailValidator_ThreadsCompleted(ByVal sender As Object, ByVal e As EmailValidatorThreadsCompletedEventArgs) Handles emailValidator.ThreadsCompleted
			If Not IsDisposed Then
				Invoke(New EventHandler(Of EmailValidatorThreadsCompletedEventArgs)(AddressOf ThreadsCompleted), sender, e)
			End If
		End Sub

		Private Sub ThreadsCompleted(ByVal sender As Object, ByVal e As EmailValidatorThreadsCompletedEventArgs)
			' Enable controls.
			EnableValidateWithThreads(True)

			Dim sb As New StringBuilder()

			For Each info As EmailValidatorThreadInfo In e.Result
				If info.LastException IsNot Nothing Then
					sb.AppendFormat(vbCrLf & "Thread {0} error: {1}", info.ThreadId, info.LastException.Message)
				End If
			Next info

			MessageBox.Show("Multi-threads validation completed!" & sb.ToString() & String.Format(vbCrLf & "{0} email(s) processed, {1} passed", e.EmailsProcessed, e.EmailsPassed), "Email Validator Demo", MessageBoxButtons.OK, MessageBoxIcon.Information)
		End Sub

		''' <summary>
		''' Handles the emailvalidator's ThreadCompleted event.
		''' </summary>
		''' <param name="sender">The emailverifer object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub sfbEmailValidator_ThreadCompleted(ByVal sender As Object, ByVal e As EmailValidatorThreadCompletedEventArgs) Handles emailValidator.ThreadCompleted
			If Not IsDisposed Then
				Invoke(New EventHandler(Of EmailValidatorThreadCompletedEventArgs)(AddressOf ThreadCompleted), sender, e)
			End If
		End Sub

		Private Sub ThreadCompleted(ByVal sender As Object, ByVal e As EmailValidatorThreadCompletedEventArgs)
			Log(String.Format("Validation completed. {0} email(s) processed, {1} passed", e.EmailsProcessed, e.EmailsPassed), e.ThreadId)
			If e.LastException IsNot Nothing Then
				Log("Last error: " & e.LastException.Message, e.ThreadId)
			End If
		End Sub

		#End Region

		Private Sub lnkSettingsSingle_LinkClicked(ByVal sender As Object, ByVal e As LinkLabelLinkClickedEventArgs) Handles lnkSettingsSingle.LinkClicked
			' Show settings dialog.
			settingsToolStripMenuItem_Click(Nothing, Nothing)
		End Sub

		Private Sub lnkMultiThreadsSettings_LinkClicked(ByVal sender As Object, ByVal e As LinkLabelLinkClickedEventArgs) Handles lnkMultiThreadsSettings.LinkClicked
			' Show settings dialog.
			settingsToolStripMenuItem_Click(Nothing, Nothing)
		End Sub

		''' <summary>
		''' Handles the BrowseListFile button's Click event.
		''' </summary>
		''' <param name="sender">The button object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub btnBrowseListFile_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnBrowseListFile.Click
			Dim dlg As New OpenFileDialog()
			Try
				dlg.FileName = txtEmailListFile.Text
				dlg.Filter = "List File (*.txt)|*.txt|All files (*.*)|*.*"
				dlg.FilterIndex = 1
				dlg.Title = "Select Email List File"
				' Show select file dialog.
				If dlg.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
					Return
				End If

				txtEmailListFile.Text = dlg.FileName
			Catch
				MessageBox.Show(dlg.FileName & " is not a valid address list", "Error")
			End Try
		End Sub

		''' <summary>
		''' Handles the Browse list file button's Click event.
		''' </summary>
		''' <param name="sender">The button object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub btnBrowseThread_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnBrowseThread.Click
			Dim dlg As New OpenFileDialog()
			Try
				dlg.FileName = txtEmailListThread.Text
				dlg.Filter = "List File (*.txt)|*.txt|All files (*.*)|*.*"
				dlg.FilterIndex = 1
				dlg.Title = "Select Email List File"
				' Show select file dialog.
				If dlg.ShowDialog() <> System.Windows.Forms.DialogResult.OK Then
					Return
				End If

				txtEmailListThread.Text = dlg.FileName
			Catch
				MessageBox.Show(dlg.FileName & " is not a valid address list", "Error")
			End Try
		End Sub

		Private Sub lnkSettingsEmailList_LinkClicked(ByVal sender As Object, ByVal e As LinkLabelLinkClickedEventArgs) Handles lnkSettingsEmailList.LinkClicked
			' Show settings dialog.
			settingsToolStripMenuItem_Click(Nothing, Nothing)
		End Sub

		''' <summary>
		''' Handles the proxy setting menu item's Click event.
		''' </summary>
		''' <param name="sender">The menu item object.</param>
		''' <param name="e">The event arguments.</param>
		Private Sub proxySettingsToolStripMenuItem_Click(ByVal sender As Object, ByVal e As EventArgs) Handles proxySettingsToolStripMenuItem.Click
			Dim dlg As New ProxySettings()

			dlg.ProxyServer = emailValidator.ProxyHost
			dlg.UserName = emailValidator.ProxyUserName
			dlg.Password = emailValidator.ProxyPassword
			dlg.Domain = emailValidator.ProxyDomain
			dlg.Port = emailValidator.ProxyPort
			dlg.AuthenticationMethod = emailValidator.ProxyHttpConnectAuthMethodMethod
			dlg.Type = emailValidator.ProxyType

			' Show the proxy setting dialog.
			If dlg.ShowDialog() = System.Windows.Forms.DialogResult.OK Then
				emailValidator.ProxyHost = dlg.ProxyServer
				emailValidator.ProxyUserName = dlg.UserName
				emailValidator.ProxyPassword = dlg.Password
				emailValidator.ProxyDomain = dlg.Domain
				emailValidator.ProxyPort = dlg.Port
				emailValidator.ProxyHttpConnectAuthMethodMethod = dlg.AuthenticationMethod
				emailValidator.ProxyType = dlg.Type
			End If
		End Sub

		Private Sub sfbEmailValidator_EmailValidating(ByVal sender As Object, ByVal e As EmailValidatingEventArgs) Handles emailValidator.EmailValidating
			If Not IsDisposed Then
				Invoke(New EventHandler(Of EmailValidatingEventArgs)(AddressOf EmailValidating), sender, e)
			End If
		End Sub

		Private Sub EmailValidating(ByVal sender As Object, ByVal e As EmailValidatingEventArgs)
			Log(String.Format("Start validating e-mail address: '{0}'", e.EmailAddress), e.ThreadId)
		End Sub

		Private Sub sfbEmailValidator_Progress(ByVal sender As Object, ByVal e As EmailValidatorProgressEventArgs) Handles emailValidator.Progress
			If Not IsDisposed Then
				Invoke(New EventHandler(Of EmailValidatorProgressEventArgs)(AddressOf Progress), sender, e)
			End If
		End Sub

		Private Sub Progress(ByVal sender As Object, ByVal e As EmailValidatorProgressEventArgs)
			If e.EmailAddress IsNot Nothing Then
				If e.Passed Then
					Log("    Passed: " & e.Level.ToString(), e.ThreadId)
				Else
					Log("    Failed: " & e.Level.ToString(), e.ThreadId)
				End If
			End If

			If _selectedTabIndex = 0 Then
				Return ' Progress bar is not available in single email validation.
			End If

			If _selectedTabIndex = 1 Then
				progressBar.Value = e.ProgressPercentage
			Else
				progressBarThreads.Value = e.ProgressPercentage
			End If
		End Sub
	End Class
End Namespace