Imports Microsoft.Win32
Imports System.Globalization
Imports System.IO
Imports System.Reflection
Imports System.Runtime.InteropServices
Imports System.Runtime.Serialization
Imports System.Runtime.Serialization.Formatters.Binary
Imports System.Text
Imports System.Text.RegularExpressions
Imports System.Threading
Imports System.Windows.Forms
Imports System.Security.Cryptography
Imports System.ComponentModel
Imports System.Xml.Serialization
Imports System.Xml

Imports Stax.UI

Public Class StringHelp
    Public Shared Function IsNumeric(ByVal value As String) As Boolean
        If value = "" Then
            Return False
        End If

        If value.StartsWith("0") Then
            Return False
        End If

        For Each i As Char In value
            If Not Char.IsDigit(i) Then
                Return False
            End If
        Next

        Return True
    End Function

    Public Shared Function ContainsUnicodeChars(ByVal value As String) As Boolean
        For Each i As Char In value
            If AscW(i) > 255 Then
                Return True
            End If
        Next

        Return False
    End Function

    Public Shared Function GetInt(ByVal value As String, ByVal defaultValue As Integer) As Integer
        If Not StringHelp.IsNumeric(value) Then
            Return defaultValue
        End If

        Return CInt(value)
    End Function

    Public Shared Sub WriteFile(ByVal path As String, ByVal value As String)
        WriteFile(path, value, Encoding.Default)
    End Sub

    Public Shared Sub WriteFile(ByVal path As String, ByVal value As String, ByVal encoding As Encoding)
        Using sw As New StreamWriter(File.Create(path), encoding)
            sw.Write(value)
        End Using
    End Sub

    Public Shared Function ToTitleCase(ByVal text As String) As String
        Dim chars As Char() = text.ToLower.ToCharArray

        For i As Integer = 0 To chars.Length - 1
            If i = 0 Then
                chars(i) = CChar(chars(i).ToString.ToUpper)
            End If

            If chars(i) = " "c AndAlso chars.Length > i + 1 Then
                chars(i + 1) = CChar(chars(i + 1).ToString.ToUpper)
            End If
        Next

        Dim sb As New StringBuilder(chars.Length)

        For Each i As Char In chars
            sb.Append(i.ToString)
        Next

        Return sb.ToString
    End Function

    Public Shared Function ReadFile(ByVal path As String) As String
        Using sr As New StreamReader(File.OpenRead(path))
            Return sr.ReadToEnd()
        End Using
    End Function

    Public Shared Function GetRightLast(ByVal value As String, ByVal start As String) As String
        If Not value.Contains(start) Then
            Return ""
        End If

        Return value.Substring(value.LastIndexOf(start) + start.Length)
    End Function

    Public Shared Function GetLeft(ByVal value As String, ByVal index As Integer) As String
        If value = "" OrElse value Is Nothing OrElse index < 0 Then
            Return ""
        End If

        If index > value.Length Then
            Return value
        End If

        Return value.Substring(0, index)
    End Function

    Public Shared Function GetLeft(ByVal value As String, ByVal start As String) As String
        If Not value.Contains(start) Then
            Return ""
        End If

        Return value.Substring(0, value.IndexOf(start))
    End Function

    Public Shared Function GetLeftLast(ByVal value As String, ByVal start As String) As String
        If Not value.Contains(start) Then
            Return ""
        End If

        Return value.Substring(0, value.LastIndexOf(start))
    End Function

    Public Shared Function GetRight(ByVal value As String, ByVal index As Integer) As String
        If value = "" OrElse value Is Nothing OrElse index < 0 Then
            Return ""
        End If

        If index > value.Length Then
            Return value
        End If

        Return value.Substring(value.Length - index)
    End Function

    Public Shared Function GetRight(ByVal value As String, ByVal start As String) As String
        If Not value.Contains(start) Then
            Return ""
        End If

        Return value.Substring(value.IndexOf(start) + start.Length)
    End Function

    Public Shared Function ContainsValue(ByVal ParamArray strings As String()) As Boolean
        For Each i As String In strings
            If i Is Nothing OrElse i = "" Then
                Return False
            End If
        Next

        Return True
    End Function

    Public Shared Function FixBreak(ByVal value As String) As String
        value = value.Replace(vbCrLf, vbLf)
        value = value.Replace(vbCr, vbLf)
        Return value.Replace(vbLf, vbCrLf)
    End Function

    Public Shared Function Split(ByVal value As String, ByVal delimiter As String) As String()
        Return value.Split(New String() {delimiter}, StringSplitOptions.RemoveEmptyEntries)
    End Function

    Public Shared Function SplitLines(ByVal value As String) As String()
        Return Split(value, Environment.NewLine)
    End Function

    Public Shared Function GetAllowedChars(ByVal value As String, ByVal allowedChars As String) As String
        Dim ret As String = value

        For Each i As Char In value
            If allowedChars.IndexOf(i) = -1 Then
                ret = ret.Replace(i, "")
            End If
        Next

        Return ret
    End Function

    Public Shared Function TrimStart(ByVal value As String, ByVal trimValue As String) As String
        If value = "" OrElse value Is Nothing Then
            Return ""
        End If

        If trimValue = "" OrElse trimValue Is Nothing Then
            Return value
        End If

        If value.StartsWith(trimValue) Then
            Return GetRight(value, trimValue)
        End If

        Return value
    End Function

    Public Shared Function DeleteLeft(ByVal value As String, ByVal count As Integer) As String
        Return StringHelp.GetRight(value, value.Length - count)
    End Function

    Public Shared Function DeleteRight(ByVal value As String, ByVal count As Integer) As String
        Return StringHelp.GetLeft(value, value.Length - count)
    End Function

    Public Shared Function GetMD5Hash(ByVal value As String) As String
        Dim crypt As MD5 = MD5CryptoServiceProvider.Create()
        Dim hash As Byte() = crypt.ComputeHash(ASCIIEncoding.ASCII.GetBytes(value))
        Dim sb As New StringBuilder()

        For Each i As Byte In hash
            sb.Append(i.ToString("x2"))
        Next

        Return sb.ToString()
    End Function
End Class

Public Class ObjectHelp
    'parse recursive serializable fields and lists 
    Public Shared Function GetCompareString(ByVal obj As Object) As String
        Dim sb As New StringBuilder
        ParseCompareString(obj, Nothing, sb)
        Return sb.ToString
    End Function

    Public Shared Sub ParseCompareString(ByVal obj As Object, ByVal declaringObj As Object, ByVal sb As StringBuilder)
        If TypeOf obj Is ICollection Then
            For Each i As Object In CType(obj, ICollection)
                If IsGoodType(i) Then
                    If IsToString(i) Then
                        sb.Append(i.ToString)
                    Else
                        ParseCompareString(i, obj, sb)
                    End If
                End If
            Next
        Else
            If IsGoodType(obj) Then
                Dim t As Type = obj.GetType

                While Not t Is Nothing
                    For Each i As FieldInfo In t.GetFields(BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Instance Or BindingFlags.DeclaredOnly)
                        If Not i.IsNotSerialized Then
                            Dim o As Object = i.GetValue(obj)

                            If IsGoodType(o) Then
                                If IsToString(o) Then
                                    sb.Append(i.Name + "=" + o.ToString + vbCrLf)
                                    'sb.Append(i.Name + "=" + o.ToString + " [" + t.Name + "]" + vbCrLf)
                                Else
                                    If Not o Is declaringObj Then
                                        ParseCompareString(o, obj, sb)
                                    End If
                                End If
                            End If
                        End If
                    Next

                    t = t.BaseType
                End While
            End If
        End If
    End Sub

    Private Shared Function IsGoodType(ByVal o As Object) As Boolean
        If o Is Nothing Then
            Return False
        End If

        If TypeOf o Is Pointer Then
            Return False
        End If

        If Not o.GetType.IsSerializable Then
            Return False
        End If

        Return True
    End Function

    Private Shared Function IsToString(ByVal o As Object) As Boolean
        If Not o Is Nothing Then
            If o.GetType.IsPrimitive Then
                Return True
            End If

            If TypeOf o Is String Then
                Return True
            End If

            If TypeOf o Is CultureInfo Then 'some fields change here
                Return True
            End If
        End If
    End Function

    <DebuggerHidden()> _
    Public Shared Function GetCopy(ByVal o As Object) As Object
        Using ms As New MemoryStream
            Dim bf As New BinaryFormatter
            bf.Serialize(ms, o)
            ms.Position = 0
            Return bf.Deserialize(ms)
        End Using
    End Function

    Public Shared Sub Serialize(ByVal o As Object, ByVal path As String)
        Dim fs As FileStream = New FileStream(path, FileMode.OpenOrCreate)
        Dim bf As BinaryFormatter = New BinaryFormatter
        bf.Serialize(fs, o)
        fs.Close()
    End Sub

    Public Shared Function Deserialize(ByVal path As String) As Object
        Dim fs As FileStream = New FileStream(path, FileMode.Open)
        Dim bf As BinaryFormatter = New BinaryFormatter
        Dim o As Object = bf.Deserialize(fs)
        fs.Close()
        Return o
    End Function
End Class

Public Class ListBoxHelp
    Private Shared LastTick As Long
    Private Shared KeyText As String = ""

    Public Shared Sub KeyDownSequence(ByVal lb As ListBox, ByVal e As KeyEventArgs)
        If Environment.TickCount - LastTick > 1000 Then
            KeyText = Convert.ToChar(e.KeyValue).ToString()
        Else
            KeyText += Convert.ToChar(e.KeyValue).ToString()
        End If

        For i As Integer = 0 To lb.Items.Count - 1
            If lb.Items(i).ToString().ToLower().StartsWith(KeyText.ToLower) Then
                Application.DoEvents()

                lb.SelectedIndex = -1
                lb.SelectedIndex = i

                Exit For
            End If
        Next

        LastTick = Environment.TickCount
    End Sub

    Public Shared Sub DrawNumbered(ByVal lb As ListBox, ByVal e As DrawItemEventArgs)
        If e.Index > -1 Then
            e.DrawBackground()
            e.DrawFocusRectangle()

            Dim sb As SolidBrush = New SolidBrush(lb.ForeColor)
            Dim pf As PointF

            If e.Index > 998 Then
                pf = New PointF(e.Bounds.Left + 40, e.Bounds.Top)
            Else
                If e.Index > 98 Then
                    pf = New PointF(e.Bounds.Left + 30, e.Bounds.Top)
                Else
                    pf = New PointF(e.Bounds.Left + 20, e.Bounds.Top)
                End If
            End If

            e.Graphics.DrawString(lb.Items(e.Index).ToString, lb.Font, sb, pf)
            e.Graphics.DrawString((e.Index + 1).ToString, lb.Font, sb, e.Bounds.Left, e.Bounds.Top)
        End If
    End Sub

    Public Shared Function CanMoveUp(ByVal lb As ListBox) As Boolean
        If lb.Sorted Then
            Throw New Exception("Can't move because ListBox property ""Sorted"" is enabled.")
        End If

        Return lb.SelectedIndices.Count > 0 AndAlso lb.SelectedIndices(0) > 0
    End Function

    Public Shared Function CanMoveDown(ByVal lb As ListBox) As Boolean
        If lb.Sorted Then
            Throw New Exception("Can't move because ListBox property ""Sorted"" is enabled.")
        End If

        Return lb.SelectedIndices.Count > 0 AndAlso lb.SelectedIndices(lb.SelectedIndices.Count - 1) < lb.Items.Count - 1
    End Function

    Public Shared Sub MoveSelectionUp(ByVal lb As ListBox)
        If CanMoveUp(lb) Then
            Dim iAbove As Integer = lb.SelectedIndices(0) - 1

            If iAbove = -1 Then
                Exit Sub
            End If

            Dim itemAbove As Object = lb.Items(iAbove)
            lb.Items.RemoveAt(iAbove)
            Dim iLastItem As Integer = lb.SelectedIndices(lb.SelectedIndices.Count - 1)
            lb.Items.Insert(iLastItem + 1, itemAbove)
        End If
    End Sub

    Public Shared Sub MoveSelectionDown(ByVal lb As ListBox)
        If CanMoveDown(lb) Then
            Dim iBelow As Integer = lb.SelectedIndices(lb.SelectedIndices.Count - 1) + 1

            If iBelow >= lb.Items.Count Then
                Exit Sub
            End If

            Dim itemBelow As Object = lb.Items(iBelow)
            lb.Items.RemoveAt(iBelow)
            Dim iAbove As Integer = lb.SelectedIndices(0) - 1
            lb.Items.Insert(iAbove + 1, itemBelow)
        End If
    End Sub

    Public Shared Sub RemoveSelection(ByVal lb As ListBox)
        If lb.SelectedIndex > -1 Then
            If lb.SelectionMode = SelectionMode.One Then
                Dim index As Integer = lb.SelectedIndex

                If lb.Items.Count - 1 > lb.SelectedIndex Then
                    lb.SelectedIndex += 1
                Else
                    lb.SelectedIndex -= 1
                End If

                lb.Items.RemoveAt(index)
            Else
                Dim iFirst As Integer = lb.SelectedIndex

                Dim indices(lb.SelectedIndices.Count - 1) As Integer
                lb.SelectedIndices.CopyTo(indices, 0)

                lb.SelectedIndex = -1

                For i As Integer = indices.Length - 1 To 0 Step -1
                    lb.Items.RemoveAt(indices(i))
                Next

                If iFirst > lb.Items.Count - 1 Then
                    lb.SelectedIndex = lb.Items.Count - 1
                Else
                    lb.SelectedIndex = iFirst
                End If
            End If
        End If
    End Sub

    Public Shared Sub DeleteItem(ByVal text As String, ByVal lb As ListBox)
        If lb.FindStringExact(text) > -1 Then
            lb.Items.RemoveAt(lb.FindStringExact(text))
        End If
    End Sub
End Class

Public Class ListViewHelp
    Public Shared Sub AutoSize(ByVal lv As ListView)
        For Each i As ColumnHeader In lv.Columns
            Dim g As Graphics = lv.CreateGraphics

            Dim s As SizeF = g.MeasureString(i.Text, lv.Font)
            i.AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent)

            If i.Width < s.Width + 10 Then
                i.Width = CInt(s.Width + 10)
            End If
        Next
    End Sub
End Class

Public Class IntegerHelp
    Public Shared Function Parse(ByVal value As String) As Integer
        Return Parse(value, 0)
    End Function

    Public Shared Function Parse(ByVal value As String, ByVal defaultValue As Integer) As Integer
        If IsInteger(value) Then
            Return Convert.ToInt32(value)
        Else
            Return defaultValue
        End If
    End Function

    Public Shared Function IsInteger(ByVal value As String) As Boolean
        If value = "" OrElse value Is Nothing Then
            Return False
        End If

        For Each i As Char In value
            If Not Char.IsDigit(i) Then
                Return False
            End If
        Next

        Return True
    End Function
End Class

Public Class RegistryHelp
    Public Shared CurrentUser As New RootKey(Registry.CurrentUser)
    Public Shared LocalMachine As New RootKey(Registry.LocalMachine)
    Public Shared ClassesRoot As New RootKey(Registry.ClassesRoot)

    Private Shared ApplicationKey As String = "Software\" + Application.ProductName

    Public Class RootKey
        Private RootRegistryKey As RegistryKey

        Public Sub New(ByVal rootKey As RegistryKey)
            RootRegistryKey = rootKey
        End Sub

        Public Function GetValue(ByVal key As String, ByVal name As String) As Object
            Dim ret As Object = Nothing
            Dim subKey As RegistryKey = RootRegistryKey.OpenSubKey(key)

            If Not subKey Is Nothing Then
                ret = subKey.GetValue(name)
                subKey.Close()
            End If

            Return ret
        End Function

        Public Function GetString(ByVal key As String, ByVal name As String) As String
            Return DirectCast(GetValue(key, name), String)
        End Function

        Public Sub SetValue(ByVal key As String, ByVal name As String, ByVal value As Object)
            Dim subKey As RegistryKey = RootRegistryKey.OpenSubKey(key, True)

            If subKey Is Nothing Then
                subKey = RootRegistryKey.CreateSubKey(key)
            End If

            subKey.SetValue(name, value)
            subKey.Close()
        End Sub

        Public Sub DeleteKey(ByVal key As String)
            Dim rk As RegistryKey = RootRegistryKey.OpenSubKey(key)

            If Not rk Is Nothing Then
                If rk.SubKeyCount = 0 Then
                    RootRegistryKey.DeleteSubKey(key)
                Else
                    RootRegistryKey.DeleteSubKeyTree(key)
                End If
            End If
        End Sub

        Public Sub DeleteValue(ByVal key As String, ByVal name As String)
            Dim rk As RegistryKey = RootRegistryKey.OpenSubKey(key, True)

            If Not rk Is Nothing Then
                rk.DeleteValue(name, False)
                rk.Close()
            End If
        End Sub

        Public Sub SetApplicationValue(ByVal name As String, ByVal value As Object)
            SetValue(ApplicationKey, name, value)
        End Sub

        Public Function GetApplicationValue(ByVal name As String) As Object
            Return GetValue(ApplicationKey, name)
        End Function

        Public Function GetApplicationString(ByVal name As String) As String
            Return GetString(ApplicationKey, name)
        End Function
    End Class

    Public Shared Sub SetAssociation(ByVal extNoDot As String)
        Dim value As String = RegistryHelp.ClassesRoot.GetString("." + extNoDot, "")

        If value Is Nothing OrElse value = "" Then
            Dim rk As RegistryKey = Registry.ClassesRoot.CreateSubKey("." + extNoDot)
            rk.SetValue("", extNoDot + "file")
            rk.Close()
            value = extNoDot + "file"
        End If

        Dim rk2 As RegistryKey = Registry.ClassesRoot.CreateSubKey( _
            value + "\shell\" + Application.ProductName + "\command")

        rk2.SetValue("", """" + Application.ExecutablePath + """ ""%1"" ""%n""")
        rk2.Close()

        Dim rk3 As RegistryKey = Registry.ClassesRoot.CreateSubKey(value + "\shell")
        rk3.SetValue("", Application.ProductName)
        rk3.Close()

        RegistryHelp.ClassesRoot.DeleteKey(value + "\DefaultIcon")
        RegistryHelp.CurrentUser.DeleteValue("Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\." + extNoDot, "Application")
    End Sub

    Public Shared Sub SetContextMenu(ByVal extNoDot As String)
        Dim value As String = RegistryHelp.ClassesRoot.GetString("." + extNoDot, "")

        If value Is Nothing OrElse value = "" Then
            Dim rk As RegistryKey = Registry.ClassesRoot.CreateSubKey("." + extNoDot)
            rk.SetValue("", extNoDot + "file")
            rk.Close()
            value = extNoDot + "file"
        End If

        Dim rk2 As RegistryKey = Registry.ClassesRoot.CreateSubKey( _
            value + "\shell\" + Application.ProductName + "\command")

        rk2.SetValue("", """" + Application.ExecutablePath + """ ""%1"" ""%n""")
        rk2.Close()
    End Sub

    Public Shared Sub DeleteAssociation(ByVal extension As String)
        Dim value As String = RegistryHelp.ClassesRoot.GetString("." + extension, "")
        RegistryHelp.ClassesRoot.DeleteKey(value + "\shell\" + Application.ProductName)
    End Sub
End Class

Public Class DirectoryHelp
    Public Shared Function FindFiles(ByVal startDir As String, ByVal filename As String, ByVal mode As StringComparison, ByVal subdirs As Boolean) As List(Of String)
        Dim ret As New List(Of String)
        AddFiles(startDir, filename, ret, mode, subdirs)
        Return ret
    End Function

    Private Shared Sub AddFiles(ByVal startDir As String, ByVal filename As String, ByVal filePaths As List(Of String), ByVal mode As StringComparison, ByVal subdirs As Boolean)
        If Directory.Exists(startDir) Then
            Dim di As New DirectoryInfo(startDir)

            For Each i As FileSystemInfo In di.GetFileSystemInfos()
                If TypeOf i Is FileInfo Then
                    If String.Compare(Filepath.GetNameWithExt(i.FullName), filename, mode) = 0 Then
                        filePaths.Add(i.FullName)
                    End If
                Else
                    If subdirs Then
                        AddFiles(i.FullName, filename, filePaths, mode, subdirs)
                    End If
                End If
            Next
        End If
    End Sub

    Public Shared Sub FileCallback(ByVal startDir As String, ByVal d As ParamDelegate(Of String), ByVal cancel As CancelEventArgs, ByVal subDirs As Boolean)
        If Directory.Exists(startDir) Then
            Dim di As New DirectoryInfo(startDir)
            Dim fsi As FileSystemInfo

            For Each fsi In di.GetFileSystemInfos()
                Try
                    If cancel.Cancel Then
                        Exit Sub
                    End If

                    If TypeOf fsi Is FileInfo Then
                        d(fsi.FullName)
                    Else
                        If subDirs Then
                            FileCallback(fsi.FullName, d, cancel, subDirs)
                        End If
                    End If
                Catch ex As Exception
                End Try
            Next
        End If
    End Sub
End Class

Public Class ClipboardHelp
    Public Shared Function GetText() As String
        Dim data As Object = Clipboard.GetDataObject.GetData(DataFormats.Text)

        If Not data Is Nothing Then
            Return data.ToString
        End If

        Return ""
    End Function
End Class

Public Class MenuHelp
    Public Shared Sub Check(ByVal mi As MenuItem)
        For Each i As MenuItem In mi.Parent.MenuItems
            i.Checked = False
        Next

        mi.Checked = True
    End Sub
End Class

Public Class XMLSerializerHelp
    Public Shared Sub SaveXML(ByVal path As String, ByVal obj As Object)
        Dim s As XmlSerializer = New XmlSerializer(obj.GetType)

        Using w As New XmlTextWriter(path, Encoding.UTF8)
            w.Formatting = Formatting.Indented
            s.Serialize(w, obj)
        End Using
    End Sub

    Public Shared Function LoadXML(Of T)(ByVal path As String) As T
        Dim s As XmlSerializer = New XmlSerializer(GetType(T))

        Using r As New XmlTextReader(path)
            Return CType(s.Deserialize(r), T)
        End Using
    End Function
End Class

Public Class EnvironmentHelp
    Public Shared Function GetCommandLineArguments() As List(Of String)
        Dim ret As New List(Of String)(Environment.GetCommandLineArgs)
        ret.RemoveAt(0)
        Return ret
    End Function
End Class

Public Class DebugHelp
    Private Shared CounterValue As Integer
    Private Shared PerformanceTestValue As Long

    Public Shared Sub WriteCounter()
        CounterValue += 1
        Debug.WriteLine(CounterValue)
    End Sub

    Public Shared Sub StartPerformanceTest()
        PerformanceTestValue = Environment.TickCount
    End Sub

    Public Shared Sub StopPerformanceTest()
        MsgBox(Environment.TickCount - PerformanceTestValue)
    End Sub
End Class

Public Class ListHelp
    Public Shared Function GetIntegerList(ByVal startValue As Integer, ByVal endValue As Integer, ByVal stepValue As Integer) As List(Of Object)
        Dim ret As New List(Of Object)
        Dim value As Integer = startValue

        While value <= endValue
            ret.Add(value)
            value += stepValue
        End While

        Return ret
    End Function

    Public Shared Function GetDoubleList(ByVal startValue As Single, ByVal endValue As Single, ByVal stepValue As Double, ByVal digits As Integer) As List(Of Object)
        Dim ret As New List(Of Object)
        Dim value As Double = startValue

        While value <= endValue
            ret.Add(value)
            value += stepValue
            value = Math.Round(value, digits)
        End While

        Return ret
    End Function
End Class

Public Class FileHelp
    Public Shared Sub Move(ByVal src As String, ByVal dest As String)
        Try
            File.Move(src, dest)
        Catch
            If Msg.Show("Failed to move file from:" + vbCrLf + vbCrLf + src + vbCrLf + vbCrLf + "to:" + vbCrLf + vbCrLf + dest, MsgIcon.Error, MessageBoxButtons.RetryCancel) = DialogResult.Retry Then
                Try
                    File.Move(src, dest)
                Catch
                    Msg.Show("Failed to move file.", MsgIcon.Error)
                End Try
            End If
        End Try
    End Sub

    Public Shared Sub Copy(ByVal src As String, ByVal dest As String)
        Try
            File.Copy(src, dest, True)
        Catch
            If Msg.Show("Failed to copy file from:" + vbCrLf + vbCrLf + src + vbCrLf + vbCrLf + "to:" + vbCrLf + vbCrLf + dest, MsgIcon.Error, MessageBoxButtons.RetryCancel) = DialogResult.Retry Then
                Try
                    File.Copy(src, dest, True)
                Catch
                    Msg.Show("Failed to copy file.", MsgIcon.Error)
                End Try
            End If
        End Try
    End Sub

    Public Shared Sub Delete(ByVal path As String)
        Try
            File.Delete(path)
        Catch
            If Msg.Show("Failed to delete the file:" + vbCrLf + vbCrLf + path, MsgIcon.Error, MessageBoxButtons.RetryCancel) = DialogResult.Retry Then
                Try
                    File.Delete(path)
                Catch
                    Msg.Show("Failed to delete file.", MsgIcon.Error)
                End Try
            End If
        End Try
    End Sub
End Class