diff --git a/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/ColorProgressBar.cs b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/ColorProgressBar.cs
new file mode 100644
index 0000000..ed7c152
--- /dev/null
+++ b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/ColorProgressBar.cs
@@ -0,0 +1,235 @@
+using System;
+using System.ComponentModel;
+using System.Windows.Forms;
+using System.Drawing;
+
+namespace ColorProgressBar
+{
+    [Description("Color Progress Bar")]
+    [ToolboxBitmap(typeof(ProgressBar))]
+    [Designer(typeof(ColorProgressBarDesigner))]
+    public class ColorProgressBar : System.Windows.Forms.Control
+    {
+
+        private int _Value = 0;
+        private int _Minimum = 0;
+        private int _Maximum = 100;
+        private int _Step = 10;
+
+        private Color _BarColor = Color.Green;
+        private Color _BorderColor = Color.Black;
+
+        public ColorProgressBar()
+        {
+            base.Size = new Size(200, 20);
+            SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer, true);
+        }
+
+        [Description("Progress bar color")]
+        [Category("ColorProgressBar")]
+        public Color BarColor
+        {
+            get
+            {
+                return _BarColor;
+            }
+            set
+            {
+                _BarColor = value;
+                this.Invalidate();
+            }
+        }
+
+        [Description("The current value for the progres bar. Must be between Minimum and Maximum.")]
+        [Category("ColorProgressBar")]
+        [RefreshProperties(RefreshProperties.All)]
+        public int Value
+        {
+            get
+            {
+                return _Value;
+            }
+            set
+            {
+                if (value < _Minimum)
+                {
+                    throw new ArgumentException($"'{value}' is not a valid 'Value'.\n'Value' must be between 'Minimum' and 'Maximum'.");
+                }
+
+                if (value > _Maximum)
+                {
+                    throw new ArgumentException($"'{value}' is not a valid 'Value'.\n'Value' must be between 'Minimum' and 'Maximum'.");
+                }
+
+                _Value = value;
+                this.Invalidate();
+            }
+        }
+
+        [Description("The lower bound of the range.")]
+        [Category("ColorProgressBar")]
+        [RefreshProperties(RefreshProperties.All)]
+        public int Minimum
+        {
+            get
+            {
+                return _Minimum;
+            }
+            set
+            {
+                _Minimum = value;
+
+                if (_Minimum > _Maximum)
+                    _Maximum = _Minimum;
+                if (_Minimum > _Value)
+                    _Value = _Minimum;
+
+                this.Invalidate();
+            }
+        }
+
+        [Description("The uppper bound of the range.")]
+        [Category("ColorProgressBar")]
+        [RefreshProperties(RefreshProperties.All)]
+        public int Maximum
+        {
+            get
+            {
+                return _Maximum;
+            }
+            set
+            {
+                _Maximum = value;
+
+                if (_Maximum < _Value)
+                    _Value = _Maximum;
+                if (_Maximum < _Minimum)
+                    _Minimum = _Maximum;
+
+                this.Invalidate();
+            }
+        }
+
+        [Description("The value to move the progess bar when the Step() method is called.")]
+        [Category("ColorProgressBar")]
+        public int Step
+        {
+            get
+            {
+                return _Step;
+            }
+            set
+            {
+                _Step = value;
+                this.Invalidate();
+            }
+        }
+
+        [Description("The border color")]
+        [Category("ColorProgressBar")]
+        public Color BorderColor
+        {
+            get
+            {
+                return _BorderColor;
+            }
+            set
+            {
+                _BorderColor = value;
+                this.Invalidate();
+            }
+        }
+
+        ///
+        /// <summary>Call the PerformStep() method to increase the value displayed by the value set in the Step property</summary>
+        ///
+        public void PerformStep()
+        {
+            if (_Value < _Maximum)
+                _Value += _Step;
+            else
+                _Value = _Maximum;
+
+            this.Invalidate();
+        }
+
+        ///
+        /// <summary>Call the PerformStepBack() method to decrease the value displayed by the value set in the Step property</summary>
+        ///
+        public void PerformStepBack()
+        {
+            if (_Value > _Minimum)
+                _Value -= _Step;
+            else
+                _Value = _Minimum;
+
+            this.Invalidate();
+        }
+
+        ///
+        /// <summary>Call the Increment() method to increase the value displayed by the passed value</summary>
+        /// 
+        public void Increment(int value)
+        {
+            if (_Value < _Maximum)
+                _Value += value;
+            else
+                _Value = _Maximum;
+
+            this.Invalidate();
+        }
+
+        //
+        // <summary>Call the Decrement() method to decrease the value displayed by the passed value</summary>
+        // 
+        public void Decrement(int value)
+        {
+            if (_Value > _Minimum)
+                _Value -= value;
+            else
+                _Value = _Minimum;
+
+            this.Invalidate();
+        }
+
+        protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)
+        {
+            // 
+            // Check for value
+            //
+            if (_Maximum == _Minimum || _Value == 0)
+            {
+                // Draw border only and exit;
+                DrawBorder(e.Graphics);
+                return;
+            }
+
+            //
+            // The following is the width of the bar. This will vary with each value.
+            //
+            int fillWidth = (this.Width * _Value) / (_Maximum - _Minimum);
+
+            //
+            // Rectangles for upper and lower half of bar
+            //
+            Rectangle rect = new Rectangle(0, 0, fillWidth, this.Height);
+
+            //
+            // The brush
+            //
+            SolidBrush brush = new SolidBrush(_BarColor);
+            e.Graphics.FillRectangle(brush, rect);
+            brush.Dispose();
+
+            //
+            // Draw border and exit
+            DrawBorder(e.Graphics);
+        }
+
+        protected void DrawBorder(Graphics g)
+        {
+            Rectangle borderRect = new Rectangle(0, 0, ClientRectangle.Width - 1, ClientRectangle.Height - 1);
+            g.DrawRectangle(new Pen(_BorderColor, 1), borderRect);
+        }
+    }
+}
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.Ui.Standalone/utPLSQL.Ui.Standalone.csproj b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/ColorProgressBar.csproj
similarity index 77%
rename from PlsqlDeveloperUtPlsqlPlugin/utPLSQL.Ui.Standalone/utPLSQL.Ui.Standalone.csproj
rename to PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/ColorProgressBar.csproj
index 6500b06..e67f3fc 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.Ui.Standalone/utPLSQL.Ui.Standalone.csproj
+++ b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/ColorProgressBar.csproj
@@ -4,11 +4,11 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{5D3EA63E-AAFE-47DB-9D48-4BA9C205ADBE}</ProjectGuid>
-    <OutputType>WinExe</OutputType>
-    <RootNamespace>utPLSQL.UI.Standalone</RootNamespace>
-    <AssemblyName>utPLSQL.UI.Standalone</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <ProjectGuid>{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>ColorProgressBar</RootNamespace>
+    <AssemblyName>ColorProgressBar</AssemblyName>
+    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <Deterministic>true</Deterministic>
     <TargetFrameworkProfile />
@@ -34,9 +34,13 @@
     <WarningLevel>4</WarningLevel>
     <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
+  <PropertyGroup>
+    <StartupObject />
+  </PropertyGroup>
   <ItemGroup>
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Design" />
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
@@ -47,17 +51,11 @@
     <Reference Include="System.Xml" />
   </ItemGroup>
   <ItemGroup>
-    <Compile Include="LoginForm.cs">
-      <SubType>Form</SubType>
-    </Compile>
-    <Compile Include="LoginForm.Designer.cs">
-      <DependentUpon>LoginForm.cs</DependentUpon>
+    <Compile Include="ColorProgressBar.cs">
+      <SubType>Component</SubType>
     </Compile>
-    <Compile Include="Program.cs" />
+    <Compile Include="ColorProgressBarDesigner.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <EmbeddedResource Include="LoginForm.resx">
-      <DependentUpon>LoginForm.cs</DependentUpon>
-    </EmbeddedResource>
     <EmbeddedResource Include="Properties\Resources.resx">
       <Generator>ResXFileCodeGenerator</Generator>
       <LastGenOutput>Resources.Designer.cs</LastGenOutput>
@@ -68,7 +66,6 @@
       <DependentUpon>Resources.resx</DependentUpon>
       <DesignTime>True</DesignTime>
     </Compile>
-    <None Include="App.config" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -79,11 +76,5 @@
       <DesignTimeSharedInput>True</DesignTimeSharedInput>
     </Compile>
   </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\utPLSQL.Ui\utPLSQL.Ui.csproj">
-      <Project>{7669189c-4a58-4e82-9dcb-7956624a719b}</Project>
-      <Name>utPLSQL.Ui</Name>
-    </ProjectReference>
-  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/ColorProgressBarDesigner.cs b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/ColorProgressBarDesigner.cs
new file mode 100644
index 0000000..81c0085
--- /dev/null
+++ b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/ColorProgressBarDesigner.cs
@@ -0,0 +1,22 @@
+using System.Collections;
+
+namespace ColorProgressBar
+{
+    internal class ColorProgressBarDesigner : System.Windows.Forms.Design.ControlDesigner
+    {
+        /// <summary>Clean up some unnecessary properties</summary> 
+        protected override void PostFilterProperties(IDictionary Properties)
+        {
+            Properties.Remove("AllowDrop");
+            Properties.Remove("BackgroundImage");
+            Properties.Remove("ContextMenu");
+            Properties.Remove("FlatStyle");
+            Properties.Remove("Image");
+            Properties.Remove("ImageAlign");
+            Properties.Remove("ImageIndex");
+            Properties.Remove("ImageList");
+            Properties.Remove("Text");
+            Properties.Remove("TextAlign");
+        }
+    }
+}
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/AssemblyInfo.cs b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..c0079b2
--- /dev/null
+++ b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("ColorProgressBar")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("utPLSQL.org")]
+[assembly: AssemblyProduct("ColorProgressBar")]
+[assembly: AssemblyCopyright("Copyright �  2021")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components.  If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("739e6f07-e688-4d16-8fdf-7472e7f0fea0")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+[assembly: AssemblyVersion("3.1.6")]
+[assembly: AssemblyFileVersion("3.1.6")]
diff --git a/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Resources.Designer.cs b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Resources.Designer.cs
new file mode 100644
index 0000000..d9db046
--- /dev/null
+++ b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Resources.Designer.cs
@@ -0,0 +1,63 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:4.0.30319.42000
+//
+//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace ColorProgressBar.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
+    /// </summary>
+    // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
+    // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
+    // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
+    // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ColorProgressBar.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
+        ///   Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+    }
+}
diff --git a/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Resources.resx b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Resources.resx
new file mode 100644
index 0000000..af7dbeb
--- /dev/null
+++ b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Resources.resx
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+</root>
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Settings.Designer.cs b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Settings.Designer.cs
new file mode 100644
index 0000000..04a8807
--- /dev/null
+++ b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Settings.Designer.cs
@@ -0,0 +1,26 @@
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:4.0.30319.42000
+//
+//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace ColorProgressBar.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.3.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+    }
+}
diff --git a/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Settings.settings b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Settings.settings
new file mode 100644
index 0000000..3964565
--- /dev/null
+++ b/PlsqlDeveloperUtPlsqlPlugin/ColorProgressBar/Properties/Settings.settings
@@ -0,0 +1,7 @@
+<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>
diff --git a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.sln b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.sln
index 8b8a352..34ae292 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.sln
+++ b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.sln
@@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "utPLSQL.Ui", "utPLSQL.Ui\ut
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "utPLSQL.Ui.Standalone", "utPLSQL.Ui.Standalone\utPLSQL.Ui.Standalone.csproj", "{5D3EA63E-AAFE-47DB-9D48-4BA9C205ADBE}"
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ColorProgressBar", "ColorProgressBar\ColorProgressBar.csproj", "{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}"
+EndProject
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 		Debug|Any CPU = Debug|Any CPU
@@ -55,6 +57,18 @@ Global
 		{5D3EA63E-AAFE-47DB-9D48-4BA9C205ADBE}.Release|x64.Build.0 = Release|Any CPU
 		{5D3EA63E-AAFE-47DB-9D48-4BA9C205ADBE}.Release|x86.ActiveCfg = Release|Any CPU
 		{5D3EA63E-AAFE-47DB-9D48-4BA9C205ADBE}.Release|x86.Build.0 = Release|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Debug|x64.ActiveCfg = Debug|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Debug|x64.Build.0 = Debug|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Debug|x86.Build.0 = Debug|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Release|x64.ActiveCfg = Release|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Release|x64.Build.0 = Release|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Release|x86.ActiveCfg = Release|Any CPU
+		{739E6F07-E688-4D16-8FDF-7472E7F0FEA0}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
diff --git a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/App.config b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/App.config
index 4338a08..3e0e37c 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/App.config
+++ b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/App.config
@@ -1,3 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>
diff --git a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.cs b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.cs
index 863f71f..2cf307f 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.cs
@@ -10,6 +10,9 @@
 
 namespace utPLSQL
 {
+    //*FUNC: 4*/ extern char *(*SYS_OracleHome)();
+    internal delegate IntPtr SysOracleHome();
+
     //*FUNC: 11*/ BOOL (*IDE_Connected)();
     internal delegate bool IdeConnected();
 
@@ -23,8 +26,7 @@ namespace utPLSQL
     internal delegate void IdeCreatePopupItem(int id, int index, string name, string objectType);
 
     //*FUNC: 74*/ int (*IDE_GetPopupObject)(char **ObjectType, char **ObjectOwner, char **ObjectName, char **SubObject);
-    internal delegate int IdeGetPopupObject(out IntPtr objectType, out IntPtr objectOwner, out IntPtr objectName,
-        out IntPtr subObject);
+    internal delegate int IdeGetPopupObject(out IntPtr objectType, out IntPtr objectOwner, out IntPtr objectName, out IntPtr subObject);
 
     //*FUNC: 79*/ char *(*IDE_GetObjectSource)(char *ObjectType, char *ObjectOwner, char *ObjectName);
     internal delegate IntPtr IdeGetObjectSource(string objectType, string objectOwner, string objectName);
@@ -41,9 +43,12 @@ public class PlsqlDeveloperUtPlsqlPlugin
 
         private const int PluginMenuIndexAllTests = 3;
         private const int PluginMenuIndexAllTestsWithCoverage = 4;
+        private const int PluginMenuIndexPath = 5;
         private const int PluginPopupIndex = 1;
         private const int PluginPopupIndexWithCoverage = 2;
 
+        private static SysOracleHome sysOracleHome;
+
         private static IdeConnected connected;
         private static IdeGetConnectionInfo getConnectionInfo;
 
@@ -59,9 +64,9 @@ public class PlsqlDeveloperUtPlsqlPlugin
         private static string password;
         private static string database;
         private static string connectAs;
+        private static string oracleHome;
 
         private static PlsqlDeveloperUtPlsqlPlugin _plugin;
-
         private static readonly List<TestRunnerWindow> Windows = new List<TestRunnerWindow>();
 
         #region DLL exported API
@@ -83,7 +88,7 @@ public static void OnActivate()
         {
             try
             {
-                ConnectToDatabase();
+                getDatabaseInformation();
 
                 // Separate streams are needed!
                 var assembly = Assembly.GetExecutingAssembly();
@@ -103,6 +108,14 @@ public static void OnActivate()
                     }
                 }
 
+                using (var stream = assembly.GetManifestResourceStream("utPLSQL.utPLSQL.bmp"))
+                {
+                    if (stream != null)
+                    {
+                        createToolButton(pluginId, PluginMenuIndexPath, "utPLSQL", "utPLSQL.bmp", new Bitmap(stream).GetHbitmap().ToInt64());
+                    }
+                }
+
                 using (var stream = assembly.GetManifestResourceStream("utPLSQL.utPLSQL.bmp"))
                 {
                     if (stream != null)
@@ -129,6 +142,12 @@ public static void OnActivate()
 
             createPopupItem(pluginId, PluginPopupIndex, "Run utPLSQL Test", "PACKAGE");
             createPopupItem(pluginId, PluginPopupIndexWithCoverage, "Run Code Coverage", "PACKAGE");
+
+            createPopupItem(pluginId, PluginPopupIndex, "Run utPLSQL Test", "PACKAGE BODY");
+            createPopupItem(pluginId, PluginPopupIndexWithCoverage, "Run Code Coverage", "PACKAGE BODY");
+
+            createPopupItem(pluginId, PluginPopupIndex, "Run utPLSQL Test", "PROCEDURE");
+            createPopupItem(pluginId, PluginPopupIndexWithCoverage, "Run Code Coverage", "PROCEDURE");
         }
 
         [DllExport("CanClose", CallingConvention = CallingConvention.Cdecl)]
@@ -150,6 +169,9 @@ public static void RegisterCallback(int index, IntPtr function)
         {
             switch (index)
             {
+                case 4:
+                    sysOracleHome = (SysOracleHome)Marshal.GetDelegateForFunctionPointer(function, typeof(SysOracleHome));
+                    break;
                 case 11:
                     connected = (IdeConnected)Marshal.GetDelegateForFunctionPointer(function, typeof(IdeConnected));
                     break;
@@ -181,7 +203,7 @@ public static void RegisterCallback(int index, IntPtr function)
         [DllExport("OnConnectionChange", CallingConvention = CallingConvention.Cdecl)]
         public static void OnConnectionChange()
         {
-            ConnectToDatabase();
+            getDatabaseInformation();
         }
 
         [DllExport("CreateMenuItem", CallingConvention = CallingConvention.Cdecl)]
@@ -197,6 +219,8 @@ public static string CreateMenuItem(int index)
                     return "LARGEITEM=Run all tests of current user";
                 case PluginMenuIndexAllTestsWithCoverage:
                     return "LARGEITEM=Run code coverage for current user";
+                case PluginMenuIndexPath:
+                    return "LARGEITEM=Run tests for specific path";
                 default:
                     return "";
             }
@@ -205,48 +229,64 @@ public static string CreateMenuItem(int index)
         [DllExport("OnMenuClick", CallingConvention = CallingConvention.Cdecl)]
         public static void OnMenuClick(int index)
         {
-            if (index == PluginMenuIndexAllTests)
+            try
             {
-                if (connected() && !Sydba())
+                if (index == PluginMenuIndexAllTests)
                 {
-                    var testResultWindow = new TestRunnerWindow(_plugin, username, password, database, connectAs);
-                    Windows.Add(testResultWindow);
-                    testResultWindow.RunTestsAsync("_ALL", username, null, null, false);
+                    if (isConnected() && !isSydba())
+                    {
+                        var testResultWindow = new TestRunnerWindow(_plugin, username, password, database, connectAs, oracleHome);
+                        Windows.Add(testResultWindow);
+                        testResultWindow.RunTestsAsync("_ALL", username, null, null, false, false);
+                    }
                 }
-            }
-            else if (index == PluginMenuIndexAllTestsWithCoverage)
-            {
-                if (connected() && !Sydba())
+                else if (index == PluginMenuIndexAllTestsWithCoverage)
                 {
-                    var testResultWindow = new TestRunnerWindow(_plugin, username, password, database, connectAs);
-                    Windows.Add(testResultWindow);
-                    testResultWindow.RunTestsAsync("_ALL", username, null, null, true);
+                    if (isConnected() && !isSydba())
+                    {
+                        var testResultWindow = new TestRunnerWindow(_plugin, username, password, database, connectAs, oracleHome);
+                        Windows.Add(testResultWindow);
+                        testResultWindow.RunTestsAsync("_ALL", username, null, null, true, false);
+                    }
                 }
-            }
-            else if (index == PluginPopupIndex)
-            {
-                if (connected() && !Sydba())
+                else if (index == PluginMenuIndexPath)
                 {
-                    getPopupObject(out IntPtr type, out IntPtr owner, out IntPtr name, out IntPtr subType);
+                    if (isConnected() && !isSydba())
+                    {
+                        var testResultWindow = new TestRunnerWindow(_plugin, username, password, database, connectAs, oracleHome);
+                        Windows.Add(testResultWindow);
+                        testResultWindow.RunTestsAsync(null, null, null, null, false, true);
+                    }
+                }
+                else if (index == PluginPopupIndex)
+                {
+                    if (isConnected() && !isSydba())
+                    {
+                        getPopupObject(out IntPtr type, out IntPtr owner, out IntPtr name, out IntPtr subType);
 
-                    var testResultWindow = new TestRunnerWindow(_plugin, username, password, database, connectAs);
-                    Windows.Add(testResultWindow);
-                    testResultWindow.RunTestsAsync(Marshal.PtrToStringAnsi(type), Marshal.PtrToStringAnsi(owner),
-                        Marshal.PtrToStringAnsi(name), Marshal.PtrToStringAnsi(subType), false);
+                        var testResultWindow = new TestRunnerWindow(_plugin, username, password, database, connectAs, oracleHome);
+                        Windows.Add(testResultWindow);
+                        testResultWindow.RunTestsAsync(Marshal.PtrToStringAnsi(type), Marshal.PtrToStringAnsi(owner),
+                            Marshal.PtrToStringAnsi(name), Marshal.PtrToStringAnsi(subType), false, false);
+                    }
                 }
-            }
-            else if (index == PluginPopupIndexWithCoverage)
-            {
-                if (connected() && !Sydba())
+                else if (index == PluginPopupIndexWithCoverage)
                 {
-                    getPopupObject(out IntPtr type, out IntPtr owner, out IntPtr name, out IntPtr subType);
+                    if (isConnected() && !isSydba())
+                    {
+                        getPopupObject(out IntPtr type, out IntPtr owner, out IntPtr name, out IntPtr subType);
 
-                    var testResultWindow = new TestRunnerWindow(_plugin, username, password, database, connectAs);
-                    Windows.Add(testResultWindow);
-                    testResultWindow.RunTestsAsync(Marshal.PtrToStringAnsi(type), Marshal.PtrToStringAnsi(owner),
-                        Marshal.PtrToStringAnsi(name), Marshal.PtrToStringAnsi(subType), true);
+                        var testResultWindow = new TestRunnerWindow(_plugin, username, password, database, connectAs, oracleHome);
+                        Windows.Add(testResultWindow);
+                        testResultWindow.RunTestsAsync(Marshal.PtrToStringAnsi(type), Marshal.PtrToStringAnsi(owner),
+                            Marshal.PtrToStringAnsi(name), Marshal.PtrToStringAnsi(subType), true, false);
+                    }
                 }
             }
+            catch (Exception e)
+            {
+                MessageBox.Show($"{e.Message}\n\n{e.StackTrace}", "Unexpected Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+            }
         }
 
         [DllExport("About", CallingConvention = CallingConvention.Cdecl)]
@@ -263,16 +303,27 @@ public void OpenPackageBody(string owner, string name)
             var source = getObjectSource("PACKAGE BODY", owner, name);
             createWindow(3, Marshal.PtrToStringAnsi(source), false);
         }
-        private static bool Sydba()
+        private static bool isSydba()
         {
-            if (connectAs.ToLower().Equals("sysdba")) {
+            if (connectAs.ToLower().Equals("sysdba"))
+            {
                 MessageBox.Show("You shouldn't run utPLSQL as SYSDBA.\n\nTest will not run.", "Connected as SYSDBA", MessageBoxButtons.OK, MessageBoxIcon.Error);
                 return true;
             }
             return false;
         }
 
-        private static void ConnectToDatabase()
+        private static bool isConnected()
+        {
+            if (!connected())
+            {
+                MessageBox.Show("Please connect before running tests!", "No connection", MessageBoxButtons.OK, MessageBoxIcon.Error);
+                return false;
+            }
+            return true;
+        }
+
+        private static void getDatabaseInformation()
         {
             try
             {
@@ -287,6 +338,10 @@ private static void ConnectToDatabase()
                     IntPtr ptrConnectAs = getConnectAs();
 
                     connectAs = Marshal.PtrToStringAnsi(ptrConnectAs);
+
+                    IntPtr ptrOracleHome = sysOracleHome();
+
+                    oracleHome = Marshal.PtrToStringAnsi(ptrOracleHome);
                 }
             }
             catch (Exception e)
diff --git a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.csproj b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.csproj
index e62f061..47062f2 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.csproj
+++ b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin.csproj
@@ -10,7 +10,7 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>utPLSQL</RootNamespace>
     <AssemblyName>PlsqlDeveloperUtPlsqlPlugin</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <Deterministic>true</Deterministic>
     <TargetFrameworkProfile />
diff --git a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/Properties/AssemblyInfo.cs b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/Properties/AssemblyInfo.cs
index 21ab34f..f74de45 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/Properties/AssemblyInfo.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/Properties/AssemblyInfo.cs
@@ -1,4 +1,4 @@
-using System.Reflection;
+using System.Reflection;
 using System.Runtime.InteropServices;
 
 // General Information about an assembly is controlled through the following
@@ -9,7 +9,7 @@
 [assembly: AssemblyConfiguration("")]
 [assembly: AssemblyCompany("utPLSQL.org")]
 [assembly: AssemblyProduct("PlsqlDeveloperUtPlsqlPlugin")]
-[assembly: AssemblyCopyright("Copyright © 2020")]
+[assembly: AssemblyCopyright("Copyright � 2021")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
@@ -28,8 +28,5 @@
 //      Build Number
 //      Revision
 //
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.1.0.0")]
-[assembly: AssemblyFileVersion("1.1.0.0")]
+[assembly: AssemblyVersion("3.1.6")]
+[assembly: AssemblyFileVersion("3.1.6")]
diff --git a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/Properties/Resources.Designer.cs b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/Properties/Resources.Designer.cs
index aed0e2d..c8d1576 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/Properties/Resources.Designer.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/Properties/Resources.Designer.cs
@@ -1,10 +1,10 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.42000
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:4.0.30319.42000
 //
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
+//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
 // </auto-generated>
 //------------------------------------------------------------------------------
 
@@ -13,13 +13,13 @@ namespace utPLSQL.Properties {
     
     
     /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    ///   Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
     /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // class via a tool like ResGen or Visual Studio.
-    // To add or remove a member, edit your .ResX file then rerun ResGen
-    // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
+    // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
+    // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
+    // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
+    // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
     internal class Resources {
@@ -33,7 +33,7 @@ internal Resources() {
         }
         
         /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
+        ///   Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
         /// </summary>
         [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
         internal static global::System.Resources.ResourceManager ResourceManager {
@@ -47,8 +47,8 @@ internal Resources() {
         }
         
         /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
+        ///   Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
+        ///   Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
         /// </summary>
         [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
         internal static global::System.Globalization.CultureInfo Culture {
@@ -61,7 +61,7 @@ internal Resources() {
         }
         
         /// <summary>
-        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        ///   Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
         /// </summary>
         internal static System.Drawing.Bitmap utPLSQL {
             get {
@@ -71,7 +71,7 @@ internal static System.Drawing.Bitmap utPLSQL {
         }
         
         /// <summary>
-        ///   Looks up a localized resource of type System.Drawing.Bitmap.
+        ///   Sucht eine lokalisierte Ressource vom Typ System.Drawing.Bitmap.
         /// </summary>
         internal static System.Drawing.Bitmap utPLSQL_coverage {
             get {
diff --git a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/packages.config b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/packages.config
index 90cda05..a54dbe2 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/packages.config
+++ b/PlsqlDeveloperUtPlsqlPlugin/PlsqlDeveloperUtPlsqlPlugin/packages.config
@@ -3,5 +3,5 @@
   <package id="Costura.Fody" version="4.1.0" targetFramework="net40" />
   <package id="Fody" version="6.3.0" targetFramework="net45" developmentDependency="true" />
   <package id="UnmanagedExports" version="1.2.7" targetFramework="net40" />
-  <package id="UnmanagedExports.Repack" version="1.0.4" targetFramework="net40" />
+  <package id="UnmanagedExports.Repack" version="1.0.4" targetFramework="net40" requireReinstallation="true" />
 </packages>
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/SetAssemblyVersion.ps1 b/PlsqlDeveloperUtPlsqlPlugin/SetAssemblyVersion.ps1
new file mode 100644
index 0000000..69e5f7e
--- /dev/null
+++ b/PlsqlDeveloperUtPlsqlPlugin/SetAssemblyVersion.ps1
@@ -0,0 +1,6 @@
+param([string]$NewVersion)
+
+Get-ChildItem -Include AssemblyInfo.cs -Recurse | ForEach-Object {
+	$_.IsReadOnly = $false
+        (Get-Content -Path $_) -replace '(?<=Assembly(?:File)?Version\(")[^"]*(?="\))', $NewVersion |Set-Content -Path $_
+}
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/App.config b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/App.config
index 4338a08..3e0e37c 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/App.config
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/App.config
@@ -1,3 +1,3 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/FodyWeavers.xml b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/FodyWeavers.xml
new file mode 100644
index 0000000..5029e70
--- /dev/null
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/FodyWeavers.xml
@@ -0,0 +1,3 @@
+<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
+  <Costura />
+</Weavers>
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/FodyWeavers.xsd b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/FodyWeavers.xsd
new file mode 100644
index 0000000..44a5374
--- /dev/null
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/FodyWeavers.xsd
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+  <!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
+  <xs:element name="Weavers">
+    <xs:complexType>
+      <xs:all>
+        <xs:element name="Costura" minOccurs="0" maxOccurs="1">
+          <xs:complexType>
+            <xs:all>
+              <xs:element minOccurs="0" maxOccurs="1" name="ExcludeAssemblies" type="xs:string">
+                <xs:annotation>
+                  <xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks</xs:documentation>
+                </xs:annotation>
+              </xs:element>
+              <xs:element minOccurs="0" maxOccurs="1" name="IncludeAssemblies" type="xs:string">
+                <xs:annotation>
+                  <xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks.</xs:documentation>
+                </xs:annotation>
+              </xs:element>
+              <xs:element minOccurs="0" maxOccurs="1" name="Unmanaged32Assemblies" type="xs:string">
+                <xs:annotation>
+                  <xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with line breaks.</xs:documentation>
+                </xs:annotation>
+              </xs:element>
+              <xs:element minOccurs="0" maxOccurs="1" name="Unmanaged64Assemblies" type="xs:string">
+                <xs:annotation>
+                  <xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with line breaks.</xs:documentation>
+                </xs:annotation>
+              </xs:element>
+              <xs:element minOccurs="0" maxOccurs="1" name="PreloadOrder" type="xs:string">
+                <xs:annotation>
+                  <xs:documentation>The order of preloaded assemblies, delimited with line breaks.</xs:documentation>
+                </xs:annotation>
+              </xs:element>
+            </xs:all>
+            <xs:attribute name="CreateTemporaryAssemblies" type="xs:boolean">
+              <xs:annotation>
+                <xs:documentation>This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file.</xs:documentation>
+              </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="IncludeDebugSymbols" type="xs:boolean">
+              <xs:annotation>
+                <xs:documentation>Controls if .pdbs for reference assemblies are also embedded.</xs:documentation>
+              </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="DisableCompression" type="xs:boolean">
+              <xs:annotation>
+                <xs:documentation>Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option.</xs:documentation>
+              </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="DisableCleanup" type="xs:boolean">
+              <xs:annotation>
+                <xs:documentation>As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off.</xs:documentation>
+              </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="LoadAtModuleInit" type="xs:boolean">
+              <xs:annotation>
+                <xs:documentation>Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code.</xs:documentation>
+              </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="IgnoreSatelliteAssemblies" type="xs:boolean">
+              <xs:annotation>
+                <xs:documentation>Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior.</xs:documentation>
+              </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="ExcludeAssemblies" type="xs:string">
+              <xs:annotation>
+                <xs:documentation>A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with |</xs:documentation>
+              </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="IncludeAssemblies" type="xs:string">
+              <xs:annotation>
+                <xs:documentation>A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |.</xs:documentation>
+              </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="Unmanaged32Assemblies" type="xs:string">
+              <xs:annotation>
+                <xs:documentation>A list of unmanaged 32 bit assembly names to include, delimited with |.</xs:documentation>
+              </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="Unmanaged64Assemblies" type="xs:string">
+              <xs:annotation>
+                <xs:documentation>A list of unmanaged 64 bit assembly names to include, delimited with |.</xs:documentation>
+              </xs:annotation>
+            </xs:attribute>
+            <xs:attribute name="PreloadOrder" type="xs:string">
+              <xs:annotation>
+                <xs:documentation>The order of preloaded assemblies, delimited with |.</xs:documentation>
+              </xs:annotation>
+            </xs:attribute>
+          </xs:complexType>
+        </xs:element>
+      </xs:all>
+      <xs:attribute name="VerifyAssembly" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
+        </xs:annotation>
+      </xs:attribute>
+      <xs:attribute name="VerifyIgnoreCodes" type="xs:string">
+        <xs:annotation>
+          <xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
+        </xs:annotation>
+      </xs:attribute>
+      <xs:attribute name="GenerateXsd" type="xs:boolean">
+        <xs:annotation>
+          <xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
+        </xs:annotation>
+      </xs:attribute>
+    </xs:complexType>
+  </xs:element>
+</xs:schema>
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/LoginForm.Designer.cs b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/LoginForm.Designer.cs
index 2d8389b..7c2308e 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/LoginForm.Designer.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/LoginForm.Designer.cs
@@ -111,6 +111,7 @@ private void InitializeComponent()
             // 
             // LoginForm
             // 
+            this.AcceptButton = this.btnRunTests;
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
             this.ClientSize = new System.Drawing.Size(271, 124);
@@ -123,6 +124,8 @@ private void InitializeComponent()
             this.Controls.Add(this.txtUsername);
             this.Controls.Add(this.btnRunTests);
             this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
+            this.MaximizeBox = false;
+            this.MinimizeBox = false;
             this.Name = "LoginForm";
             this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
             this.Text = "utPLSQL";
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/LoginForm.cs b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/LoginForm.cs
index a4533c7..0b808b1 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/LoginForm.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/LoginForm.cs
@@ -12,14 +12,14 @@ public LoginForm()
 
         private void BtnRunTests_Click(object sender, EventArgs e)
         {
-            var testRunnerWindow = new TestRunnerWindow(null, txtUsername.Text, txtPassword.Text, txtDatabase.Text, null);
-            testRunnerWindow.RunTestsAsync("USER", null, txtUsername.Text, null, false);
+            var testRunnerWindow = new TestRunnerWindow(null, txtUsername.Text, txtPassword.Text, txtDatabase.Text, null, null);
+            testRunnerWindow.RunTestsAsync("USER", null, txtUsername.Text, null, false, false);
         }
 
         private void btnCodeCoverage_Click(object sender, EventArgs e)
         {
-            var testRunnerWindow = new TestRunnerWindow(null, txtUsername.Text, txtPassword.Text, txtDatabase.Text, null);
-            testRunnerWindow.RunTestsAsync("USER", null, txtUsername.Text, null, true);
+            var testRunnerWindow = new TestRunnerWindow(null, txtUsername.Text, txtPassword.Text, txtDatabase.Text, null, null);
+            testRunnerWindow.RunTestsAsync("USER", null, txtUsername.Text, null, true, false);
         }
     }
 }
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/AssemblyInfo.cs b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/AssemblyInfo.cs
index cb815b9..747cc77 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/AssemblyInfo.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/AssemblyInfo.cs
@@ -1,4 +1,4 @@
-using System.Reflection;
+using System.Reflection;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
@@ -8,9 +8,9 @@
 [assembly: AssemblyTitle("utPLSQL.UI.Standalone")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("HP Inc.")]
+[assembly: AssemblyCompany("utPLSQL.org")]
 [assembly: AssemblyProduct("utPLSQL.UI.Standalone")]
-[assembly: AssemblyCopyright("Copyright © HP Inc. 2020")]
+[assembly: AssemblyCopyright("Copyright � 2021")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
@@ -29,8 +29,5 @@
 //      Build Number
 //      Revision
 //
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.1.0.0")]
-[assembly: AssemblyFileVersion("1.1.0.0")]
+[assembly: AssemblyVersion("3.1.6")]
+[assembly: AssemblyFileVersion("3.1.6")]
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/Resources.Designer.cs b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/Resources.Designer.cs
index fa38f58..a1baf06 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/Resources.Designer.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/Resources.Designer.cs
@@ -1,10 +1,10 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.42000
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:4.0.30319.42000
 //
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
+//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
 // </auto-generated>
 //------------------------------------------------------------------------------
 
@@ -13,13 +13,13 @@ namespace utPLSQL.UI.Standalone.Properties {
     
     
     /// <summary>
-    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    ///   Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
     /// </summary>
-    // This class was auto-generated by the StronglyTypedResourceBuilder
-    // class via a tool like ResGen or Visual Studio.
-    // To add or remove a member, edit your .ResX file then rerun ResGen
-    // with the /str option, or rebuild your VS project.
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
+    // Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
+    // -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
+    // Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
+    // mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
     internal class Resources {
@@ -33,7 +33,7 @@ internal Resources() {
         }
         
         /// <summary>
-        ///   Returns the cached ResourceManager instance used by this class.
+        ///   Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
         /// </summary>
         [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
         internal static global::System.Resources.ResourceManager ResourceManager {
@@ -47,8 +47,8 @@ internal Resources() {
         }
         
         /// <summary>
-        ///   Overrides the current thread's CurrentUICulture property for all
-        ///   resource lookups using this strongly typed resource class.
+        ///   Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
+        ///   Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
         /// </summary>
         [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
         internal static global::System.Globalization.CultureInfo Culture {
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/Settings.Designer.cs b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/Settings.Designer.cs
index 83b35b5..82c597d 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/Settings.Designer.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/Properties/Settings.Designer.cs
@@ -1,10 +1,10 @@
 //------------------------------------------------------------------------------
 // <auto-generated>
-//     This code was generated by a tool.
-//     Runtime Version:4.0.30319.42000
+//     Dieser Code wurde von einem Tool generiert.
+//     Laufzeitversion:4.0.30319.42000
 //
-//     Changes to this file may cause incorrect behavior and will be lost if
-//     the code is regenerated.
+//     Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
+//     der Code erneut generiert wird.
 // </auto-generated>
 //------------------------------------------------------------------------------
 
@@ -12,7 +12,7 @@ namespace utPLSQL.UI.Standalone.Properties {
     
     
     [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
-    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "16.8.1.0")]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.0.3.0")]
     internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
         
         private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/utPLSQL.UI.Standalone.csproj b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/utPLSQL.UI.Standalone.csproj
index 6500b06..1e92865 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/utPLSQL.UI.Standalone.csproj
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI.Standalone/utPLSQL.UI.Standalone.csproj
@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" />
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -8,10 +9,12 @@
     <OutputType>WinExe</OutputType>
     <RootNamespace>utPLSQL.UI.Standalone</RootNamespace>
     <AssemblyName>utPLSQL.UI.Standalone</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <Deterministic>true</Deterministic>
     <TargetFrameworkProfile />
+    <NuGetPackageImportStamp>
+    </NuGetPackageImportStamp>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -35,6 +38,9 @@
     <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <ItemGroup>
+    <Reference Include="Costura, Version=4.1.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
+      <HintPath>..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll</HintPath>
+    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -69,6 +75,7 @@
       <DesignTime>True</DesignTime>
     </Compile>
     <None Include="App.config" />
+    <None Include="packages.config" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>
@@ -86,4 +93,5 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <Import Project="..\packages\Fody.6.0.0\build\Fody.targets" Condition="Exists('..\packages\Fody.6.0.0\build\Fody.targets')" />
 </Project>
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/App.config b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/App.config
index 292458b..7b54b1e 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/App.config
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/App.config
@@ -25,4 +25,4 @@
       </dataSources>
     </version>
   </oracle.manageddataaccess.client>
-<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
+<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/></startup></configuration>
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/CodeCoverageReportDialog.cs b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/CodeCoverageReportDialog.cs
index 256fd2e..0a4d987 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/CodeCoverageReportDialog.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/CodeCoverageReportDialog.cs
@@ -5,7 +5,7 @@ namespace utPLSQL
 {
     public partial class CodeCoverageReportDialog : Form
     {
-        public CodeCoverageReportDialog(List<string> paths)
+        public CodeCoverageReportDialog(IReadOnlyList<string> paths)
         {
             InitializeComponent();
 
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/Properties/AssemblyInfo.cs b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/Properties/AssemblyInfo.cs
index 0a66e28..3f2d36e 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/Properties/AssemblyInfo.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/Properties/AssemblyInfo.cs
@@ -1,4 +1,4 @@
-using System.Reflection;
+using System.Reflection;
 using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
@@ -8,9 +8,9 @@
 [assembly: AssemblyTitle("utPLSQL.UI")]
 [assembly: AssemblyDescription("")]
 [assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("HP Inc.")]
+[assembly: AssemblyCompany("utPLSQL.org")]
 [assembly: AssemblyProduct("utPLSQL.UI")]
-[assembly: AssemblyCopyright("Copyright © HP Inc. 2020")]
+[assembly: AssemblyCopyright("Copyright � 2021")]
 [assembly: AssemblyTrademark("")]
 [assembly: AssemblyCulture("")]
 
@@ -29,8 +29,5 @@
 //      Build Number
 //      Revision
 //
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.1.0.0")]
-[assembly: AssemblyFileVersion("1.1.0.0")]
+[assembly: AssemblyVersion("3.1.6")]
+[assembly: AssemblyFileVersion("3.1.6")]
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestResult.cs b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestResult.cs
deleted file mode 100644
index 466af16..0000000
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestResult.cs
+++ /dev/null
@@ -1,38 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.Drawing;
-
-namespace utPLSQL
-{
-    internal class TestResult
-    {
-        public Bitmap Icon { get; set; }
-
-        public string Package { get; set; }
-        public string Procedure { get; set; }
-        public decimal Time { get; set; }
-        internal string Id { get; set; }
-
-        internal string Status { get; set; }
-        internal DateTime Start { get; set; }
-        internal DateTime End { get; set; }
-
-        internal string Owner { get; set; }
-        internal string Name { get; set; }
-        internal string Description { get; set; }
-
-        internal string Error { get; set; }
-
-        internal BindingList<Expectation> failedExpectations = new BindingList<Expectation>();
-    }
-    internal class Expectation
-    {
-        internal Expectation(string message, string caller)
-        {
-            this.Message = message;
-            this.Caller = caller.Replace("s*", "\n");
-        }
-        public string Message { get; set; }
-        public string Caller { get; set; }
-    }
-}
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.Designer.cs b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.Designer.cs
index f160fde..1b4503c 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.Designer.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.Designer.cs
@@ -30,6 +30,7 @@ protected override void Dispose(bool disposing)
         private void InitializeComponent()
         {
             this.components = new System.ComponentModel.Container();
+            System.Windows.Forms.DataGridViewCellStyle dataGridViewCellStyle1 = new System.Windows.Forms.DataGridViewCellStyle();
             System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TestRunnerWindow));
             this.btnClose = new System.Windows.Forms.Button();
             this.lblTests = new System.Windows.Forms.Label();
@@ -42,12 +43,34 @@ private void InitializeComponent()
             this.txtFailures = new System.Windows.Forms.TextBox();
             this.lblDisabled = new System.Windows.Forms.Label();
             this.txtDisabled = new System.Windows.Forms.TextBox();
-            this.gridResults = new System.Windows.Forms.DataGridView();
+            this.dataGridViewTestResults = new System.Windows.Forms.DataGridView();
+            this.iconDataGridViewImageColumn = new System.Windows.Forms.DataGridViewImageColumn();
+            this.packageDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
+            this.procedureDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
+            this.timeDataGridViewTextBoxColumn = new System.Windows.Forms.DataGridViewTextBoxColumn();
             this.contextMenuResults = new System.Windows.Forms.ContextMenuStrip(this.components);
             this.menuItemRunTests = new System.Windows.Forms.ToolStripMenuItem();
             this.menuItemCoverage = new System.Windows.Forms.ToolStripMenuItem();
+            this.dataSet = new System.Data.DataSet();
+            this.dataTableTestResults = new System.Data.DataTable();
+            this.dataColumnTestResultId = new System.Data.DataColumn();
+            this.dataColumnTestResultIcon = new System.Data.DataColumn();
+            this.dataColumnTestResultPackage = new System.Data.DataColumn();
+            this.dataColumnTestResultProcedure = new System.Data.DataColumn();
+            this.dataColumnTestResultTime = new System.Data.DataColumn();
+            this.dataColumnTestResultStatus = new System.Data.DataColumn();
+            this.dataColumnTestResultStart = new System.Data.DataColumn();
+            this.dataColumnTestResultEnd = new System.Data.DataColumn();
+            this.dataColumnTestResultOwner = new System.Data.DataColumn();
+            this.dataColumnTestResultName = new System.Data.DataColumn();
+            this.dataColumnTestResultDescription = new System.Data.DataColumn();
+            this.dataColumnTestResultError = new System.Data.DataColumn();
+            this.dataTableExpectations = new System.Data.DataTable();
+            this.dataColumnExpectationTestResultId = new System.Data.DataColumn();
+            this.dataColumnExpectationMessage = new System.Data.DataColumn();
+            this.dataColumnExpectationCaller = new System.Data.DataColumn();
+            this.dataColumnExpectationLine = new System.Data.DataColumn();
             this.txtStatus = new System.Windows.Forms.TextBox();
-            this.progressBar = new System.Windows.Forms.ProgressBar();
             this.iconPictureBox1 = new FontAwesome.Sharp.IconPictureBox();
             this.iconPictureBox2 = new FontAwesome.Sharp.IconPictureBox();
             this.tabs = new System.Windows.Forms.TabControl();
@@ -72,7 +95,8 @@ private void InitializeComponent()
             this.txtTestOwner = new System.Windows.Forms.TextBox();
             this.lblTestOwner = new System.Windows.Forms.Label();
             this.tabFailures = new System.Windows.Forms.TabPage();
-            this.gridTestFailures = new System.Windows.Forms.DataGridView();
+            this.txtFailureMessage = new System.Windows.Forms.TextBox();
+            this.dataGridViewExpectations = new System.Windows.Forms.DataGridView();
             this.tabErrors = new System.Windows.Forms.TabPage();
             this.txtErrorMessage = new System.Windows.Forms.TextBox();
             this.label1 = new System.Windows.Forms.Label();
@@ -89,14 +113,21 @@ private void InitializeComponent()
             this.lblSuccess = new System.Windows.Forms.Label();
             this.txtSuccess = new System.Windows.Forms.TextBox();
             this.iconPictureBox3 = new FontAwesome.Sharp.IconPictureBox();
-            ((System.ComponentModel.ISupportInitialize)(this.gridResults)).BeginInit();
+            this.btnRun = new System.Windows.Forms.Button();
+            this.btnRunWithCoverage = new System.Windows.Forms.Button();
+            this.colorProgressBar = new ColorProgressBar.ColorProgressBar();
+            this.Line = new System.Windows.Forms.DataGridViewTextBoxColumn();
+            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewTestResults)).BeginInit();
             this.contextMenuResults.SuspendLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.dataSet)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.dataTableTestResults)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.dataTableExpectations)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.iconPictureBox1)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.iconPictureBox2)).BeginInit();
             this.tabs.SuspendLayout();
             this.tabTest.SuspendLayout();
             this.tabFailures.SuspendLayout();
-            ((System.ComponentModel.ISupportInitialize)(this.gridTestFailures)).BeginInit();
+            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewExpectations)).BeginInit();
             this.tabErrors.SuspendLayout();
             ((System.ComponentModel.ISupportInitialize)(this.iconPictureBox4)).BeginInit();
             ((System.ComponentModel.ISupportInitialize)(this.iconPictureBox3)).BeginInit();
@@ -104,10 +135,10 @@ private void InitializeComponent()
             // 
             // btnClose
             // 
-            this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
-            this.btnClose.Location = new System.Drawing.Point(921, 588);
+            this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnClose.Location = new System.Drawing.Point(919, 694);
             this.btnClose.Name = "btnClose";
-            this.btnClose.Size = new System.Drawing.Size(75, 21);
+            this.btnClose.Size = new System.Drawing.Size(75, 23);
             this.btnClose.TabIndex = 4;
             this.btnClose.Text = "Close";
             this.btnClose.Click += new System.EventHandler(this.btnClose_Click);
@@ -128,6 +159,7 @@ private void InitializeComponent()
             this.txtTests.ReadOnly = true;
             this.txtTests.Size = new System.Drawing.Size(120, 20);
             this.txtTests.TabIndex = 7;
+            this.txtTests.TabStop = false;
             // 
             // lblTime
             // 
@@ -145,6 +177,7 @@ private void InitializeComponent()
             this.txtTime.ReadOnly = true;
             this.txtTime.Size = new System.Drawing.Size(120, 20);
             this.txtTime.TabIndex = 9;
+            this.txtTime.TabStop = false;
             this.txtTime.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
             // 
             // lblErrors
@@ -163,6 +196,7 @@ private void InitializeComponent()
             this.txtErrors.ReadOnly = true;
             this.txtErrors.Size = new System.Drawing.Size(50, 20);
             this.txtErrors.TabIndex = 13;
+            this.txtErrors.TabStop = false;
             this.txtErrors.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
             // 
             // lblFailures
@@ -181,6 +215,7 @@ private void InitializeComponent()
             this.txtFailures.ReadOnly = true;
             this.txtFailures.Size = new System.Drawing.Size(50, 20);
             this.txtFailures.TabIndex = 15;
+            this.txtFailures.TabStop = false;
             this.txtFailures.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
             // 
             // lblDisabled
@@ -199,32 +234,81 @@ private void InitializeComponent()
             this.txtDisabled.ReadOnly = true;
             this.txtDisabled.Size = new System.Drawing.Size(50, 20);
             this.txtDisabled.TabIndex = 17;
+            this.txtDisabled.TabStop = false;
             this.txtDisabled.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
             // 
-            // gridResults
+            // dataGridViewTestResults
             // 
-            this.gridResults.AllowUserToAddRows = false;
-            this.gridResults.AllowUserToDeleteRows = false;
-            this.gridResults.AllowUserToResizeRows = false;
-            this.gridResults.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
+            this.dataGridViewTestResults.AllowUserToAddRows = false;
+            this.dataGridViewTestResults.AllowUserToDeleteRows = false;
+            this.dataGridViewTestResults.AllowUserToResizeRows = false;
+            this.dataGridViewTestResults.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) 
             | System.Windows.Forms.AnchorStyles.Left) 
             | System.Windows.Forms.AnchorStyles.Right)));
-            this.gridResults.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.DisplayedCells;
-            this.gridResults.ContextMenuStrip = this.contextMenuResults;
-            this.gridResults.ImeMode = System.Windows.Forms.ImeMode.On;
-            this.gridResults.Location = new System.Drawing.Point(12, 126);
-            this.gridResults.MultiSelect = false;
-            this.gridResults.Name = "gridResults";
-            this.gridResults.ReadOnly = true;
-            this.gridResults.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None;
-            this.gridResults.RowHeadersVisible = false;
-            this.gridResults.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
-            this.gridResults.ShowEditingIcon = false;
-            this.gridResults.Size = new System.Drawing.Size(986, 216);
-            this.gridResults.TabIndex = 18;
-            this.gridResults.CellContextMenuStripNeeded += new System.Windows.Forms.DataGridViewCellContextMenuStripNeededEventHandler(this.gridResults_CellContextMenuStripNeeded);
-            this.gridResults.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridResults_CellDoubleClick);
-            this.gridResults.SelectionChanged += new System.EventHandler(this.gridResults_SelectionChanged);
+            this.dataGridViewTestResults.AutoGenerateColumns = false;
+            this.dataGridViewTestResults.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+            this.iconDataGridViewImageColumn,
+            this.packageDataGridViewTextBoxColumn,
+            this.procedureDataGridViewTextBoxColumn,
+            this.timeDataGridViewTextBoxColumn});
+            this.dataGridViewTestResults.ContextMenuStrip = this.contextMenuResults;
+            this.dataGridViewTestResults.DataMember = "TestResults";
+            this.dataGridViewTestResults.DataSource = this.dataSet;
+            this.dataGridViewTestResults.ImeMode = System.Windows.Forms.ImeMode.On;
+            this.dataGridViewTestResults.Location = new System.Drawing.Point(12, 126);
+            this.dataGridViewTestResults.MultiSelect = false;
+            this.dataGridViewTestResults.Name = "dataGridViewTestResults";
+            this.dataGridViewTestResults.ReadOnly = true;
+            this.dataGridViewTestResults.RowHeadersBorderStyle = System.Windows.Forms.DataGridViewHeaderBorderStyle.None;
+            this.dataGridViewTestResults.RowHeadersVisible = false;
+            this.dataGridViewTestResults.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
+            this.dataGridViewTestResults.ShowEditingIcon = false;
+            this.dataGridViewTestResults.Size = new System.Drawing.Size(986, 324);
+            this.dataGridViewTestResults.TabIndex = 18;
+            this.dataGridViewTestResults.TabStop = false;
+            this.dataGridViewTestResults.CellContextMenuStripNeeded += new System.Windows.Forms.DataGridViewCellContextMenuStripNeededEventHandler(this.gridResults_CellContextMenuStripNeeded);
+            this.dataGridViewTestResults.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridResults_CellDoubleClick);
+            this.dataGridViewTestResults.SelectionChanged += new System.EventHandler(this.gridResults_SelectionChanged);
+            // 
+            // iconDataGridViewImageColumn
+            // 
+            this.iconDataGridViewImageColumn.DataPropertyName = "Icon";
+            this.iconDataGridViewImageColumn.FillWeight = 0.2504606F;
+            this.iconDataGridViewImageColumn.HeaderText = "";
+            this.iconDataGridViewImageColumn.Name = "iconDataGridViewImageColumn";
+            this.iconDataGridViewImageColumn.ReadOnly = true;
+            this.iconDataGridViewImageColumn.SortMode = System.Windows.Forms.DataGridViewColumnSortMode.Automatic;
+            this.iconDataGridViewImageColumn.Width = 35;
+            // 
+            // packageDataGridViewTextBoxColumn
+            // 
+            this.packageDataGridViewTextBoxColumn.DataPropertyName = "Package";
+            this.packageDataGridViewTextBoxColumn.FillWeight = 14.3167F;
+            this.packageDataGridViewTextBoxColumn.HeaderText = "Package";
+            this.packageDataGridViewTextBoxColumn.Name = "packageDataGridViewTextBoxColumn";
+            this.packageDataGridViewTextBoxColumn.ReadOnly = true;
+            this.packageDataGridViewTextBoxColumn.Width = 300;
+            // 
+            // procedureDataGridViewTextBoxColumn
+            // 
+            this.procedureDataGridViewTextBoxColumn.DataPropertyName = "Procedure";
+            this.procedureDataGridViewTextBoxColumn.FillWeight = 182.3871F;
+            this.procedureDataGridViewTextBoxColumn.HeaderText = "Procedure";
+            this.procedureDataGridViewTextBoxColumn.Name = "procedureDataGridViewTextBoxColumn";
+            this.procedureDataGridViewTextBoxColumn.ReadOnly = true;
+            this.procedureDataGridViewTextBoxColumn.Width = 530;
+            // 
+            // timeDataGridViewTextBoxColumn
+            // 
+            this.timeDataGridViewTextBoxColumn.DataPropertyName = "Time";
+            dataGridViewCellStyle1.Alignment = System.Windows.Forms.DataGridViewContentAlignment.MiddleRight;
+            dataGridViewCellStyle1.Format = "N3";
+            dataGridViewCellStyle1.NullValue = null;
+            this.timeDataGridViewTextBoxColumn.DefaultCellStyle = dataGridViewCellStyle1;
+            this.timeDataGridViewTextBoxColumn.FillWeight = 203.0457F;
+            this.timeDataGridViewTextBoxColumn.HeaderText = "Time";
+            this.timeDataGridViewTextBoxColumn.Name = "timeDataGridViewTextBoxColumn";
+            this.timeDataGridViewTextBoxColumn.ReadOnly = true;
             // 
             // contextMenuResults
             // 
@@ -249,26 +333,145 @@ private void InitializeComponent()
             this.menuItemCoverage.Text = "Run Code Coverage";
             this.menuItemCoverage.Click += new System.EventHandler(this.menuItemCoverage_ClickAsync);
             // 
+            // dataSet
+            // 
+            this.dataSet.DataSetName = "DataSet";
+            this.dataSet.Tables.AddRange(new System.Data.DataTable[] {
+            this.dataTableTestResults,
+            this.dataTableExpectations});
+            // 
+            // dataTableTestResults
+            // 
+            this.dataTableTestResults.Columns.AddRange(new System.Data.DataColumn[] {
+            this.dataColumnTestResultId,
+            this.dataColumnTestResultIcon,
+            this.dataColumnTestResultPackage,
+            this.dataColumnTestResultProcedure,
+            this.dataColumnTestResultTime,
+            this.dataColumnTestResultStatus,
+            this.dataColumnTestResultStart,
+            this.dataColumnTestResultEnd,
+            this.dataColumnTestResultOwner,
+            this.dataColumnTestResultName,
+            this.dataColumnTestResultDescription,
+            this.dataColumnTestResultError});
+            this.dataTableTestResults.Constraints.AddRange(new System.Data.Constraint[] {
+            new System.Data.UniqueConstraint("Constraint1", new string[] {
+                        "Id"}, true)});
+            this.dataTableTestResults.PrimaryKey = new System.Data.DataColumn[] {
+        this.dataColumnTestResultId};
+            this.dataTableTestResults.TableName = "TestResults";
+            // 
+            // dataColumnTestResultId
+            // 
+            this.dataColumnTestResultId.AllowDBNull = false;
+            this.dataColumnTestResultId.Caption = "Id";
+            this.dataColumnTestResultId.ColumnName = "Id";
+            // 
+            // dataColumnTestResultIcon
+            // 
+            this.dataColumnTestResultIcon.Caption = "Icon";
+            this.dataColumnTestResultIcon.ColumnName = "Icon";
+            this.dataColumnTestResultIcon.DataType = typeof(byte[]);
+            // 
+            // dataColumnTestResultPackage
+            // 
+            this.dataColumnTestResultPackage.Caption = "Package";
+            this.dataColumnTestResultPackage.ColumnName = "Package";
+            // 
+            // dataColumnTestResultProcedure
+            // 
+            this.dataColumnTestResultProcedure.Caption = "Procedure";
+            this.dataColumnTestResultProcedure.ColumnName = "Procedure";
+            // 
+            // dataColumnTestResultTime
+            // 
+            this.dataColumnTestResultTime.Caption = "Time";
+            this.dataColumnTestResultTime.ColumnName = "Time";
+            this.dataColumnTestResultTime.DataType = typeof(decimal);
+            // 
+            // dataColumnTestResultStatus
+            // 
+            this.dataColumnTestResultStatus.Caption = "Status";
+            this.dataColumnTestResultStatus.ColumnName = "Status";
+            // 
+            // dataColumnTestResultStart
+            // 
+            this.dataColumnTestResultStart.Caption = "Start";
+            this.dataColumnTestResultStart.ColumnName = "Start";
+            this.dataColumnTestResultStart.DataType = typeof(System.DateTime);
+            // 
+            // dataColumnTestResultEnd
+            // 
+            this.dataColumnTestResultEnd.Caption = "End";
+            this.dataColumnTestResultEnd.ColumnName = "End";
+            this.dataColumnTestResultEnd.DataType = typeof(System.DateTime);
+            // 
+            // dataColumnTestResultOwner
+            // 
+            this.dataColumnTestResultOwner.Caption = "Owner";
+            this.dataColumnTestResultOwner.ColumnName = "Owner";
+            // 
+            // dataColumnTestResultName
+            // 
+            this.dataColumnTestResultName.Caption = "Name";
+            this.dataColumnTestResultName.ColumnName = "Name";
+            // 
+            // dataColumnTestResultDescription
+            // 
+            this.dataColumnTestResultDescription.Caption = "Description";
+            this.dataColumnTestResultDescription.ColumnName = "Description";
+            // 
+            // dataColumnTestResultError
+            // 
+            this.dataColumnTestResultError.Caption = "Error";
+            this.dataColumnTestResultError.ColumnName = "Error";
+            // 
+            // dataTableExpectations
+            // 
+            this.dataTableExpectations.Columns.AddRange(new System.Data.DataColumn[] {
+            this.dataColumnExpectationTestResultId,
+            this.dataColumnExpectationMessage,
+            this.dataColumnExpectationCaller,
+            this.dataColumnExpectationLine});
+            this.dataTableExpectations.Constraints.AddRange(new System.Data.Constraint[] {
+            new System.Data.ForeignKeyConstraint("FkTestResult", "TestResults", new string[] {
+                        "Id"}, new string[] {
+                        "TestResultId"}, System.Data.AcceptRejectRule.None, System.Data.Rule.Cascade, System.Data.Rule.Cascade)});
+            this.dataTableExpectations.TableName = "Expectations";
+            // 
+            // dataColumnExpectationTestResultId
+            // 
+            this.dataColumnExpectationTestResultId.Caption = "TestResultId";
+            this.dataColumnExpectationTestResultId.ColumnName = "TestResultId";
+            // 
+            // dataColumnExpectationMessage
+            // 
+            this.dataColumnExpectationMessage.Caption = "Message";
+            this.dataColumnExpectationMessage.ColumnName = "Message";
+            // 
+            // dataColumnExpectationCaller
+            // 
+            this.dataColumnExpectationCaller.Caption = "Caller";
+            this.dataColumnExpectationCaller.ColumnName = "Caller";
+            // 
+            // dataColumnExpectationLine
+            // 
+            this.dataColumnExpectationLine.Caption = "Line";
+            this.dataColumnExpectationLine.ColumnName = "Line";
+            // 
             // txtStatus
             // 
-            this.txtStatus.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) 
-            | System.Windows.Forms.AnchorStyles.Right)));
+            this.txtStatus.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left)));
             this.txtStatus.BorderStyle = System.Windows.Forms.BorderStyle.None;
             this.txtStatus.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
-            this.txtStatus.Location = new System.Drawing.Point(16, 592);
+            this.txtStatus.Location = new System.Drawing.Point(16, 703);
             this.txtStatus.Name = "txtStatus";
             this.txtStatus.ReadOnly = true;
-            this.txtStatus.Size = new System.Drawing.Size(899, 13);
-            this.txtStatus.TabIndex = 0;
+            this.txtStatus.Size = new System.Drawing.Size(699, 13);
+            this.txtStatus.TabIndex = 7;
             this.txtStatus.TabStop = false;
             // 
-            // progressBar
-            // 
-            this.progressBar.Location = new System.Drawing.Point(12, 85);
-            this.progressBar.Name = "progressBar";
-            this.progressBar.Size = new System.Drawing.Size(986, 23);
-            this.progressBar.TabIndex = 21;
-            // 
             // iconPictureBox1
             // 
             this.iconPictureBox1.BackColor = System.Drawing.SystemColors.Control;
@@ -304,11 +507,12 @@ private void InitializeComponent()
             this.tabs.Controls.Add(this.tabTest);
             this.tabs.Controls.Add(this.tabFailures);
             this.tabs.Controls.Add(this.tabErrors);
-            this.tabs.Location = new System.Drawing.Point(12, 357);
+            this.tabs.Location = new System.Drawing.Point(12, 465);
             this.tabs.Name = "tabs";
             this.tabs.SelectedIndex = 0;
             this.tabs.Size = new System.Drawing.Size(986, 225);
             this.tabs.TabIndex = 28;
+            this.tabs.TabStop = false;
             // 
             // tabTest
             // 
@@ -346,6 +550,7 @@ private void InitializeComponent()
             this.txtTestSuitePath.ReadOnly = true;
             this.txtTestSuitePath.Size = new System.Drawing.Size(900, 20);
             this.txtTestSuitePath.TabIndex = 40;
+            this.txtTestSuitePath.TabStop = false;
             // 
             // lblTestSuitePath
             // 
@@ -371,6 +576,7 @@ private void InitializeComponent()
             this.txtTestTime.ReadOnly = true;
             this.txtTestTime.Size = new System.Drawing.Size(120, 20);
             this.txtTestTime.TabIndex = 37;
+            this.txtTestTime.TabStop = false;
             // 
             // lblTestTime
             // 
@@ -397,6 +603,7 @@ private void InitializeComponent()
             this.txtTestEnd.ReadOnly = true;
             this.txtTestEnd.Size = new System.Drawing.Size(120, 20);
             this.txtTestEnd.TabIndex = 34;
+            this.txtTestEnd.TabStop = false;
             // 
             // txtTestStart
             // 
@@ -405,6 +612,7 @@ private void InitializeComponent()
             this.txtTestStart.ReadOnly = true;
             this.txtTestStart.Size = new System.Drawing.Size(120, 20);
             this.txtTestStart.TabIndex = 33;
+            this.txtTestStart.TabStop = false;
             // 
             // lblTestStart
             // 
@@ -422,6 +630,7 @@ private void InitializeComponent()
             this.txtTestName.ReadOnly = true;
             this.txtTestName.Size = new System.Drawing.Size(900, 20);
             this.txtTestName.TabIndex = 31;
+            this.txtTestName.TabStop = false;
             // 
             // lblTestName
             // 
@@ -439,6 +648,7 @@ private void InitializeComponent()
             this.txtTestDescription.ReadOnly = true;
             this.txtTestDescription.Size = new System.Drawing.Size(900, 20);
             this.txtTestDescription.TabIndex = 29;
+            this.txtTestDescription.TabStop = false;
             // 
             // lblTestDescription
             // 
@@ -456,6 +666,7 @@ private void InitializeComponent()
             this.txtTestProcuedure.ReadOnly = true;
             this.txtTestProcuedure.Size = new System.Drawing.Size(900, 20);
             this.txtTestProcuedure.TabIndex = 5;
+            this.txtTestProcuedure.TabStop = false;
             // 
             // lblTestProcedure
             // 
@@ -473,6 +684,7 @@ private void InitializeComponent()
             this.txtTestPackage.ReadOnly = true;
             this.txtTestPackage.Size = new System.Drawing.Size(900, 20);
             this.txtTestPackage.TabIndex = 3;
+            this.txtTestPackage.TabStop = false;
             // 
             // lblTestPackage
             // 
@@ -490,6 +702,7 @@ private void InitializeComponent()
             this.txtTestOwner.ReadOnly = true;
             this.txtTestOwner.Size = new System.Drawing.Size(900, 20);
             this.txtTestOwner.TabIndex = 1;
+            this.txtTestOwner.TabStop = false;
             // 
             // lblTestOwner
             // 
@@ -503,7 +716,8 @@ private void InitializeComponent()
             // tabFailures
             // 
             this.tabFailures.BackColor = System.Drawing.SystemColors.Control;
-            this.tabFailures.Controls.Add(this.gridTestFailures);
+            this.tabFailures.Controls.Add(this.txtFailureMessage);
+            this.tabFailures.Controls.Add(this.dataGridViewExpectations);
             this.tabFailures.Location = new System.Drawing.Point(4, 22);
             this.tabFailures.Name = "tabFailures";
             this.tabFailures.Padding = new System.Windows.Forms.Padding(3);
@@ -511,19 +725,38 @@ private void InitializeComponent()
             this.tabFailures.TabIndex = 0;
             this.tabFailures.Text = "Failures";
             // 
-            // gridTestFailures
-            // 
-            this.gridTestFailures.AllowUserToAddRows = false;
-            this.gridTestFailures.AllowUserToDeleteRows = false;
-            this.gridTestFailures.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
-            this.gridTestFailures.Location = new System.Drawing.Point(6, 6);
-            this.gridTestFailures.MultiSelect = false;
-            this.gridTestFailures.Name = "gridTestFailures";
-            this.gridTestFailures.RowHeadersVisible = false;
-            this.gridTestFailures.ShowEditingIcon = false;
-            this.gridTestFailures.Size = new System.Drawing.Size(966, 188);
-            this.gridTestFailures.TabIndex = 0;
-            this.gridTestFailures.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridTestFailures_CellDoubleClick);
+            // txtFailureMessage
+            // 
+            this.txtFailureMessage.Location = new System.Drawing.Point(131, 6);
+            this.txtFailureMessage.Multiline = true;
+            this.txtFailureMessage.Name = "txtFailureMessage";
+            this.txtFailureMessage.ReadOnly = true;
+            this.txtFailureMessage.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
+            this.txtFailureMessage.Size = new System.Drawing.Size(841, 187);
+            this.txtFailureMessage.TabIndex = 1;
+            this.txtFailureMessage.TabStop = false;
+            // 
+            // dataGridViewExpectations
+            // 
+            this.dataGridViewExpectations.AllowUserToAddRows = false;
+            this.dataGridViewExpectations.AllowUserToDeleteRows = false;
+            this.dataGridViewExpectations.AutoGenerateColumns = false;
+            this.dataGridViewExpectations.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
+            this.dataGridViewExpectations.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
+            this.Line});
+            this.dataGridViewExpectations.DataMember = "Expectations";
+            this.dataGridViewExpectations.DataSource = this.dataSet;
+            this.dataGridViewExpectations.Location = new System.Drawing.Point(6, 6);
+            this.dataGridViewExpectations.MultiSelect = false;
+            this.dataGridViewExpectations.Name = "dataGridViewExpectations";
+            this.dataGridViewExpectations.ReadOnly = true;
+            this.dataGridViewExpectations.RowHeadersVisible = false;
+            this.dataGridViewExpectations.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect;
+            this.dataGridViewExpectations.ShowEditingIcon = false;
+            this.dataGridViewExpectations.Size = new System.Drawing.Size(119, 187);
+            this.dataGridViewExpectations.TabIndex = 0;
+            this.dataGridViewExpectations.CellDoubleClick += new System.Windows.Forms.DataGridViewCellEventHandler(this.gridTestFailures_CellDoubleClick);
+            this.dataGridViewExpectations.SelectionChanged += new System.EventHandler(this.dataGridViewExpectations_SelectionChanged);
             // 
             // tabErrors
             // 
@@ -562,6 +795,7 @@ private void InitializeComponent()
             this.txtPath.ReadOnly = true;
             this.txtPath.Size = new System.Drawing.Size(466, 20);
             this.txtPath.TabIndex = 30;
+            this.txtPath.TabStop = false;
             // 
             // lblStart
             // 
@@ -579,6 +813,7 @@ private void InitializeComponent()
             this.txtStart.ReadOnly = true;
             this.txtStart.Size = new System.Drawing.Size(120, 20);
             this.txtStart.TabIndex = 32;
+            this.txtStart.TabStop = false;
             // 
             // lblEnd
             // 
@@ -596,6 +831,7 @@ private void InitializeComponent()
             this.txtEnd.ReadOnly = true;
             this.txtEnd.Size = new System.Drawing.Size(120, 20);
             this.txtEnd.TabIndex = 34;
+            this.txtEnd.TabStop = false;
             // 
             // iconPictureBox4
             // 
@@ -619,7 +855,7 @@ private void InitializeComponent()
             this.cbFailure.Location = new System.Drawing.Point(499, 48);
             this.cbFailure.Name = "cbFailure";
             this.cbFailure.Size = new System.Drawing.Size(15, 14);
-            this.cbFailure.TabIndex = 35;
+            this.cbFailure.TabIndex = 1;
             this.cbFailure.UseVisualStyleBackColor = true;
             this.cbFailure.CheckedChanged += new System.EventHandler(this.cbFailures_CheckedChanged);
             // 
@@ -631,7 +867,7 @@ private void InitializeComponent()
             this.cbSuccess.Location = new System.Drawing.Point(338, 48);
             this.cbSuccess.Name = "cbSuccess";
             this.cbSuccess.Size = new System.Drawing.Size(15, 14);
-            this.cbSuccess.TabIndex = 36;
+            this.cbSuccess.TabIndex = 0;
             this.cbSuccess.UseVisualStyleBackColor = true;
             this.cbSuccess.CheckedChanged += new System.EventHandler(this.cbSuccess_CheckedChanged);
             // 
@@ -643,7 +879,7 @@ private void InitializeComponent()
             this.cbError.Location = new System.Drawing.Point(652, 48);
             this.cbError.Name = "cbError";
             this.cbError.Size = new System.Drawing.Size(15, 14);
-            this.cbError.TabIndex = 37;
+            this.cbError.TabIndex = 2;
             this.cbError.UseVisualStyleBackColor = true;
             this.cbError.CheckedChanged += new System.EventHandler(this.cbErrors_CheckedChanged);
             // 
@@ -655,7 +891,7 @@ private void InitializeComponent()
             this.cbDisabled.Location = new System.Drawing.Point(819, 48);
             this.cbDisabled.Name = "cbDisabled";
             this.cbDisabled.Size = new System.Drawing.Size(15, 14);
-            this.cbDisabled.TabIndex = 38;
+            this.cbDisabled.TabIndex = 3;
             this.cbDisabled.UseVisualStyleBackColor = true;
             this.cbDisabled.CheckedChanged += new System.EventHandler(this.cbDisabled_CheckedChanged);
             // 
@@ -665,7 +901,7 @@ private void InitializeComponent()
             this.lblSuccess.Location = new System.Drawing.Point(228, 49);
             this.lblSuccess.Name = "lblSuccess";
             this.lblSuccess.Size = new System.Drawing.Size(48, 13);
-            this.lblSuccess.TabIndex = 39;
+            this.lblSuccess.TabIndex = 3;
             this.lblSuccess.Text = "Success";
             // 
             // txtSuccess
@@ -675,6 +911,7 @@ private void InitializeComponent()
             this.txtSuccess.ReadOnly = true;
             this.txtSuccess.Size = new System.Drawing.Size(50, 20);
             this.txtSuccess.TabIndex = 40;
+            this.txtSuccess.TabStop = false;
             this.txtSuccess.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
             // 
             // iconPictureBox3
@@ -691,12 +928,58 @@ private void InitializeComponent()
             this.iconPictureBox3.TabIndex = 41;
             this.iconPictureBox3.TabStop = false;
             // 
+            // btnRun
+            // 
+            this.btnRun.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnRun.Location = new System.Drawing.Point(722, 694);
+            this.btnRun.Name = "btnRun";
+            this.btnRun.Size = new System.Drawing.Size(75, 23);
+            this.btnRun.TabIndex = 5;
+            this.btnRun.Text = "Run";
+            this.btnRun.UseVisualStyleBackColor = true;
+            this.btnRun.Click += new System.EventHandler(this.btnRun_Click);
+            // 
+            // btnRunWithCoverage
+            // 
+            this.btnRunWithCoverage.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
+            this.btnRunWithCoverage.Location = new System.Drawing.Point(803, 694);
+            this.btnRunWithCoverage.Name = "btnRunWithCoverage";
+            this.btnRunWithCoverage.Size = new System.Drawing.Size(110, 23);
+            this.btnRunWithCoverage.TabIndex = 6;
+            this.btnRunWithCoverage.Text = "Run with Coverage";
+            this.btnRunWithCoverage.UseVisualStyleBackColor = true;
+            this.btnRunWithCoverage.Click += new System.EventHandler(this.button1_Click);
+            // 
+            // colorProgressBar
+            // 
+            this.colorProgressBar.BarColor = System.Drawing.Color.Green;
+            this.colorProgressBar.BorderColor = System.Drawing.SystemColors.ControlDarkDark;
+            this.colorProgressBar.Location = new System.Drawing.Point(12, 86);
+            this.colorProgressBar.Maximum = 100;
+            this.colorProgressBar.Minimum = 0;
+            this.colorProgressBar.Name = "colorProgressBar";
+            this.colorProgressBar.Size = new System.Drawing.Size(986, 23);
+            this.colorProgressBar.Step = 10;
+            this.colorProgressBar.TabIndex = 43;
+            this.colorProgressBar.Value = 0;
+            // 
+            // Line
+            // 
+            this.Line.DataPropertyName = "Line";
+            this.Line.FillWeight = 101.5228F;
+            this.Line.HeaderText = "Line";
+            this.Line.Name = "Line";
+            this.Line.ReadOnly = true;
+            // 
             // TestRunnerWindow
             // 
             this.AcceptButton = this.btnClose;
             this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
             this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
-            this.ClientSize = new System.Drawing.Size(1008, 621);
+            this.ClientSize = new System.Drawing.Size(1008, 729);
+            this.Controls.Add(this.colorProgressBar);
+            this.Controls.Add(this.btnRunWithCoverage);
+            this.Controls.Add(this.btnRun);
             this.Controls.Add(this.iconPictureBox3);
             this.Controls.Add(this.txtSuccess);
             this.Controls.Add(this.lblSuccess);
@@ -714,9 +997,8 @@ private void InitializeComponent()
             this.Controls.Add(this.iconPictureBox4);
             this.Controls.Add(this.iconPictureBox2);
             this.Controls.Add(this.iconPictureBox1);
-            this.Controls.Add(this.progressBar);
             this.Controls.Add(this.txtStatus);
-            this.Controls.Add(this.gridResults);
+            this.Controls.Add(this.dataGridViewTestResults);
             this.Controls.Add(this.txtDisabled);
             this.Controls.Add(this.lblDisabled);
             this.Controls.Add(this.txtFailures);
@@ -729,20 +1011,24 @@ private void InitializeComponent()
             this.Controls.Add(this.lblTests);
             this.Controls.Add(this.btnClose);
             this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
-            this.MinimumSize = new System.Drawing.Size(1024, 598);
+            this.MinimumSize = new System.Drawing.Size(1024, 768);
             this.Name = "TestRunnerWindow";
             this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
             this.Text = "utPLSQL TestRunner";
             this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.TestResultWindow_FormClosing);
-            ((System.ComponentModel.ISupportInitialize)(this.gridResults)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewTestResults)).EndInit();
             this.contextMenuResults.ResumeLayout(false);
+            ((System.ComponentModel.ISupportInitialize)(this.dataSet)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.dataTableTestResults)).EndInit();
+            ((System.ComponentModel.ISupportInitialize)(this.dataTableExpectations)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.iconPictureBox1)).EndInit();
             ((System.ComponentModel.ISupportInitialize)(this.iconPictureBox2)).EndInit();
             this.tabs.ResumeLayout(false);
             this.tabTest.ResumeLayout(false);
             this.tabTest.PerformLayout();
             this.tabFailures.ResumeLayout(false);
-            ((System.ComponentModel.ISupportInitialize)(this.gridTestFailures)).EndInit();
+            this.tabFailures.PerformLayout();
+            ((System.ComponentModel.ISupportInitialize)(this.dataGridViewExpectations)).EndInit();
             this.tabErrors.ResumeLayout(false);
             this.tabErrors.PerformLayout();
             ((System.ComponentModel.ISupportInitialize)(this.iconPictureBox4)).EndInit();
@@ -764,9 +1050,8 @@ private void InitializeComponent()
         private System.Windows.Forms.TextBox txtFailures;
         private System.Windows.Forms.Label lblDisabled;
         private System.Windows.Forms.TextBox txtDisabled;
-        private System.Windows.Forms.DataGridView gridResults;
+        private System.Windows.Forms.DataGridView dataGridViewTestResults;
         private System.Windows.Forms.TextBox txtStatus;
-        private System.Windows.Forms.ProgressBar progressBar;
         private FontAwesome.Sharp.IconPictureBox iconPictureBox1;
         private FontAwesome.Sharp.IconPictureBox iconPictureBox2;
         private System.Windows.Forms.TabControl tabs;
@@ -788,7 +1073,7 @@ private void InitializeComponent()
         private System.Windows.Forms.TextBox txtTestStart;
         private System.Windows.Forms.TextBox txtTestEnd;
         private System.Windows.Forms.Label lblTestEnd;
-        private System.Windows.Forms.DataGridView gridTestFailures;
+        private System.Windows.Forms.DataGridView dataGridViewExpectations;
         private System.Windows.Forms.Label label1;
         private System.Windows.Forms.TextBox txtPath;
         private System.Windows.Forms.Label lblStart;
@@ -811,5 +1096,33 @@ private void InitializeComponent()
         private System.Windows.Forms.Label lblSuccess;
         private System.Windows.Forms.TextBox txtSuccess;
         private FontAwesome.Sharp.IconPictureBox iconPictureBox3;
+        private System.Windows.Forms.Button btnRun;
+        private System.Windows.Forms.Button btnRunWithCoverage;
+        private System.Data.DataSet dataSet;
+        private System.Data.DataTable dataTableTestResults;
+        private System.Data.DataColumn dataColumnTestResultId;
+        private System.Data.DataColumn dataColumnTestResultIcon;
+        private System.Data.DataColumn dataColumnTestResultPackage;
+        private System.Data.DataColumn dataColumnTestResultProcedure;
+        private System.Data.DataColumn dataColumnTestResultTime;
+        private System.Data.DataColumn dataColumnTestResultStatus;
+        private System.Data.DataColumn dataColumnTestResultStart;
+        private System.Data.DataColumn dataColumnTestResultEnd;
+        private System.Data.DataColumn dataColumnTestResultOwner;
+        private System.Data.DataColumn dataColumnTestResultName;
+        private System.Data.DataColumn dataColumnTestResultDescription;
+        private System.Data.DataColumn dataColumnTestResultError;
+        private System.Data.DataTable dataTableExpectations;
+        private System.Data.DataColumn dataColumnExpectationTestResultId;
+        private System.Data.DataColumn dataColumnExpectationMessage;
+        private System.Data.DataColumn dataColumnExpectationCaller;
+        private ColorProgressBar.ColorProgressBar colorProgressBar;
+        private System.Windows.Forms.TextBox txtFailureMessage;
+        private System.Windows.Forms.DataGridViewImageColumn iconDataGridViewImageColumn;
+        private System.Windows.Forms.DataGridViewTextBoxColumn packageDataGridViewTextBoxColumn;
+        private System.Windows.Forms.DataGridViewTextBoxColumn procedureDataGridViewTextBoxColumn;
+        private System.Windows.Forms.DataGridViewTextBoxColumn timeDataGridViewTextBoxColumn;
+        private System.Data.DataColumn dataColumnExpectationLine;
+        private System.Windows.Forms.DataGridViewTextBoxColumn Line;
     }
 }
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.cs b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.cs
index a6be044..5091c2b 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.cs
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.cs
@@ -1,11 +1,11 @@
-using Equin.ApplicationFramework;
-using FontAwesome.Sharp;
+using FontAwesome.Sharp;
 using System;
 using System.Collections.Generic;
-using System.ComponentModel;
+using System.Data;
 using System.Drawing;
 using System.Globalization;
 using System.IO;
+using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Windows.Forms;
 
@@ -13,10 +13,11 @@ namespace utPLSQL
 {
     public partial class TestRunnerWindow : Form
     {
+        Regex regexLine = new Regex("(.*line )([0-9]+)( .*)", RegexOptions.IgnoreCase);
+
         public bool Running { get; private set; }
 
         private const int IconSize = 24;
-        private const int Steps = 1000;
         private const string StatusSuccess = "Success";
         private const string StatusFailure = "Failure";
         private const string StatusError = "Error";
@@ -28,10 +29,7 @@ public partial class TestRunnerWindow : Form
         private readonly string password;
         private readonly string database;
         private readonly string connectAs;
-
-        private readonly List<TestResult> testResults = new List<TestResult>();
-
-        private BindingListView<TestResult> viewTestResults;
+        private readonly string oracleHome;
 
         private RealTimeTestRunner testRunner;
 
@@ -39,41 +37,52 @@ public partial class TestRunnerWindow : Form
         private int rowIndexOnRightClick;
         private int completedTests;
 
-        public TestRunnerWindow(object pluginIntegration, string username, string password, string database, string connectAs)
+        private ImageConverter imageConverter = new ImageConverter();
+
+        private DataView dataViewTestResults;
+        private DataView dataViewExpectations;
+
+        public TestRunnerWindow(object pluginIntegration, string username, string password, string database, string connectAs, string oracleHome)
         {
             this.pluginIntegration = pluginIntegration;
             this.username = username;
             this.password = password;
             this.database = database;
             this.connectAs = connectAs;
+            this.oracleHome = oracleHome;
 
             InitializeComponent();
-        }
 
-        private void CreateDataSourceAndConfigureGridColumns()
-        {
-            viewTestResults = new BindingListView<TestResult>(testResults);
-            gridResults.DataSource = viewTestResults;
-
-            gridResults.Columns[0].HeaderText = "";
-            gridResults.Columns[0].MinimumWidth = 30;
-            gridResults.Columns[1].MinimumWidth = 235;
-            gridResults.Columns[2].MinimumWidth = 600;
-            gridResults.Columns[3].MinimumWidth = 100;
-            gridResults.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
+            dataViewTestResults = new DataView(dataTableTestResults);
+            dataGridViewTestResults.DataMember = null;
+            dataGridViewTestResults.DataSource = dataViewTestResults;
+
+            dataViewExpectations = new DataView(dataTableExpectations);
+            dataGridViewExpectations.DataMember = null;
+            dataGridViewExpectations.DataSource = dataViewExpectations;
         }
 
-        public async Task RunTestsAsync(string type, string owner, string name, string procedure, bool coverage)
+        public async Task RunTestsAsync(string type, string owner, string name, string procedure, bool coverage, bool showOnly)
         {
-            ResetComponents();
-
-            testResults.Clear();
-
-            SetWindowTitle(type, owner, name, procedure);
+            var path = showOnly ? null : GetPath(type, owner, name, procedure);
 
             testRunner = new RealTimeTestRunner();
-            testRunner.Connect(username, password, database);
 
+            try
+            {
+                if (oracleHome != null && Environment.GetEnvironmentVariable("ORACLE_HOME") == null)
+                {
+                    Environment.SetEnvironmentVariable("ORACLE_HOME", oracleHome);
+                }
+                Running = true;
+
+                testRunner.Connect(username, password, database);
+            }
+            catch (Exception e)
+            {
+                MessageBox.Show(e.Message, "Connect failed", MessageBoxButtons.OK, MessageBoxIcon.Error);
+                return;
+            }
             try
             {
                 testRunner.GetVersion();
@@ -84,11 +93,29 @@ public async Task RunTestsAsync(string type, string owner, string name, string p
                 return;
             }
 
-            Running = true;
+            if (showOnly)
+            {
+                txtPath.ReadOnly = false;
+                txtPath.Focus();
+                Show();
+            }
+            else
+            {
+                await RunTestsAsync(path, coverage);
+            }
+        }
+
+        private async Task RunTestsAsync(List<string> path, bool coverage)
+        {
+            ResetComponents();
+
+            dataSet.Clear();
+
+            SetWindowTitle(path);
 
             if (coverage)
             {
-                var codeCoverageReportDialog = new CodeCoverageReportDialog(GetPath(type, owner, name, procedure));
+                var codeCoverageReportDialog = new CodeCoverageReportDialog(path);
                 var dialogResult = codeCoverageReportDialog.ShowDialog();
                 if (dialogResult == DialogResult.OK)
                 {
@@ -102,7 +129,7 @@ public async Task RunTestsAsync(string type, string owner, string name, string p
 
                     txtStatus.Text = "Running tests with coverage...";
 
-                    var htmlReport = await testRunner.RunTestsWithCoverageAsync(GetPath(type, owner, name, procedure), CollectResults(coverage), schemas, includes, excludes);
+                    var htmlReport = await testRunner.RunTestsWithCoverageAsync(path, CollectResults(coverage), schemas, includes, excludes);
 
                     var filePath = $"{Path.GetTempPath()}\\utPLSQL_Coverage_Report_{Guid.NewGuid()}.html";
                     using (var sw = new StreamWriter(filePath))
@@ -112,8 +139,6 @@ public async Task RunTestsAsync(string type, string owner, string name, string p
 
                     txtStatus.BeginInvoke((MethodInvoker)delegate
                     {
-                        EnableFilter();
-
                         txtStatus.Text = totalNumberOfTests > 0 ? "Finished" : "No tests found";
                     });
 
@@ -130,60 +155,48 @@ public async Task RunTestsAsync(string type, string owner, string name, string p
 
                 txtStatus.Text = "Running tests...";
 
-                await testRunner.RunTestsAsync(GetPath(type, owner, name, procedure), CollectResults(coverage));
+                await testRunner.RunTestsAsync(path, CollectResults(coverage));
             }
         }
 
-        private void EnableFilter()
-        {
-            cbSuccess.Enabled = true;
-            cbFailure.Enabled = true;
-            cbError.Enabled = true;
-            cbDisabled.Enabled = true;
-        }
-
         private Action<@event> CollectResults(bool coverage)
         {
             return @event =>
             {
                 if (@event.type.Equals("pre-run"))
                 {
-                    gridResults.BeginInvoke((MethodInvoker)delegate
+                    dataGridViewTestResults.BeginInvoke((MethodInvoker)delegate
                     {
                         txtStatus.Text = "Running tests...";
 
                         totalNumberOfTests = @event.totalNumberOfTests;
 
-                        progressBar.Minimum = 0;
-                        progressBar.Maximum = totalNumberOfTests * Steps;
-                        progressBar.Step = Steps;
+                        colorProgressBar.Minimum = 0;
+                        colorProgressBar.Maximum = totalNumberOfTests;
+                        colorProgressBar.Step = 1;
 
                         CreateTestResults(@event);
 
-                        CreateDataSourceAndConfigureGridColumns();
 
-                        if (gridResults.Rows.Count > 0)
-                        {
-                            gridResults.Rows[0].Selected = false;
-                        }
+                        dataTableTestResults.AcceptChanges();
                     });
                 }
                 else if (@event.type.Equals("post-test"))
                 {
-                    gridResults.BeginInvoke((MethodInvoker)delegate
+                    dataGridViewTestResults.BeginInvoke((MethodInvoker)delegate
                     {
                         completedTests++;
 
                         txtTests.Text = (completedTests > totalNumberOfTests ? totalNumberOfTests : completedTests) + "/" + totalNumberOfTests;
 
-                        UpdateProgressBar();
+                        colorProgressBar.PerformStep();
 
                         UpdateTestResult(@event);
                     });
                 }
                 else if (@event.type.Equals("post-run"))
                 {
-                    gridResults.BeginInvoke((MethodInvoker)delegate
+                    dataGridViewTestResults.BeginInvoke((MethodInvoker)delegate
                     {
                         txtStart.Text = @event.run.startTime.ToString(CultureInfo.CurrentCulture);
                         txtEnd.Text = @event.run.endTime.ToString(CultureInfo.CurrentCulture);
@@ -197,13 +210,11 @@ private Action<@event> CollectResults(bool coverage)
 
                         if (@event.run.counter.failure > 0 || @event.run.counter.error > 0)
                         {
-                            progressBar.ForeColor = Color.DarkRed;
+                            colorProgressBar.BarColor = Color.DarkRed;
                         }
 
                         if (!coverage)
                         {
-                            EnableFilter();
-
                             txtStatus.Text = totalNumberOfTests > 0 ? "Finished" : "No tests found";
 
                             Running = false;
@@ -244,36 +255,15 @@ private List<string> ConvertToList(string listValue)
             }
         }
 
-        /*
-        * Workaround for the progressbar animation that produces lagging
-        * https://stackoverflow.com/questions/5332616/disabling-net-progressbar-animation-when-changing-value
-        */
-        private void UpdateProgressBar()
-        {
-            var newValue = completedTests * Steps + 1;
-            if (newValue > progressBar.Maximum)
-            {
-                progressBar.Value = progressBar.Maximum;
-                progressBar.Value--;
-                progressBar.Value++;
-            }
-            else
-            {
-                progressBar.Value = newValue;
-                progressBar.Value--;
-            }
-        }
-
-        private void SetWindowTitle(string type, string owner, string name, string procedure)
+        private void SetWindowTitle(IReadOnlyList<string> path)
         {
             var startTime = DateTime.Now.ToString(CultureInfo.CurrentCulture);
             txtStart.Text = startTime;
-            var path = GetPath(type, owner, name, procedure);
             txtPath.Text = path[0];
             Text = $"{path[0]} {startTime}";
         }
 
-        private List<string> GetPath(string type, string owner, string name, string procedure)
+        private static List<string> GetPath(string type, string owner, string name, string procedure)
         {
             switch (type)
             {
@@ -281,6 +271,8 @@ private List<string> GetPath(string type, string owner, string name, string proc
                     return new List<string> { name };
                 case "PACKAGE":
                     return new List<string> { $"{owner}.{name}" };
+                case "PACKAGE BODY":
+                    return new List<string> { $"{owner}.{name}" };
                 case "PROCEDURE":
                     return new List<string> { $"{owner}.{name}.{procedure}" };
                 default:
@@ -315,90 +307,117 @@ private void ResetComponents()
 
             txtErrorMessage.Text = "";
 
-            var bindingSource = new BindingSource { DataSource = new BindingList<Expectation>() };
-            gridTestFailures.DataSource = bindingSource;
-
-            progressBar.ForeColor = Color.Green;
-            progressBar.Minimum = 0;
-            progressBar.Maximum = 100;
-            progressBar.Value = 0;
-
-            cbSuccess.Enabled = false;
-            cbFailure.Enabled = false;
-            cbError.Enabled = false;
-            cbDisabled.Enabled = false;
+            colorProgressBar.BarColor = Color.Green;
+            colorProgressBar.Minimum = 0;
+            colorProgressBar.Maximum = 100;
+            colorProgressBar.Value = 0;
         }
 
         private void UpdateTestResult(@event @event)
         {
             if (@event.test != null)
             {
-                foreach (var testResult in testResults)
+                var rows = dataTableTestResults.Select($"Id = '{ @event.test.id}'");
+                var testResult = rows[0];
+
+                testResult.BeginEdit();
+
+                testResult["Start"] = @event.test.startTime;
+                testResult["End"] = @event.test.endTime;
+
+                testResult["Time"] = @event.test.executionTime;
+
+                var counter = @event.test.counter;
+                if (counter.disabled > 0)
+                {
+                    testResult["Icon"] = (byte[])imageConverter.ConvertTo(IconChar.Ban.ToBitmap(Color.Gray, IconSize), typeof(byte[]));
+                    testResult["Status"] = StatusDisabled;
+                }
+                else if (counter.success > 0)
+                {
+                    testResult["Icon"] = (byte[])imageConverter.ConvertTo(IconChar.Check.ToBitmap(Color.Green, IconSize), typeof(byte[]));
+                    testResult["Status"] = StatusSuccess;
+                }
+                else if (counter.failure > 0)
                 {
-                    if (testResult.Id.Equals(@event.test.id))
+                    testResult["Icon"] = (byte[])imageConverter.ConvertTo(IconChar.TimesCircle.ToBitmap(IconFont.Solid, IconSize, Color.Orange), typeof(byte[]));
+                    testResult["Status"] = StatusFailure;
+
+                    colorProgressBar.BeginInvoke((MethodInvoker)delegate
                     {
-                        testResult.Start = @event.test.startTime;
-                        testResult.End = @event.test.endTime;
+                        colorProgressBar.BarColor = Color.DarkRed;
+                    });
+                }
+                else if (counter.error > 0)
+                {
+                    testResult["Icon"] = (byte[])imageConverter.ConvertTo(IconChar.ExclamationCircle.ToBitmap(Color.Red, IconSize), typeof(byte[]));
+                    testResult["Status"] = StatusError;
 
-                        testResult.Time = @event.test.executionTime;
+                    colorProgressBar.BeginInvoke((MethodInvoker)delegate
+                    {
+                        colorProgressBar.BarColor = Color.DarkRed;
+                    });
+                }
+                else if (counter.warning > 0)
+                {
+                    testResult["Icon"] = (byte[])imageConverter.ConvertTo(IconChar.ExclamationTriangle.ToBitmap(Color.Orange, IconSize), typeof(byte[]));
+                    testResult["Status"] = StatusWarning;
+                }
 
-                        var counter = @event.test.counter;
-                        if (counter.disabled > 0)
-                        {
-                            testResult.Icon = IconChar.Ban.ToBitmap(Color.Gray, IconSize);
-                            testResult.Status = StatusDisabled;
-                        }
-                        else if (counter.success > 0)
-                        {
-                            testResult.Icon = IconChar.Check.ToBitmap(Color.Green, IconSize);
-                            testResult.Status = StatusSuccess;
-                        }
-                        else if (counter.failure > 0)
-                        {
-                            testResult.Icon = IconChar.TimesCircle.ToBitmap(IconFont.Solid, IconSize, Color.Orange);
-                            testResult.Status = StatusFailure;
-                        }
-                        else if (counter.error > 0)
-                        {
-                            testResult.Icon = IconChar.ExclamationCircle.ToBitmap(Color.Red, IconSize);
-                            testResult.Status = StatusError;
-                        }
-                        else if (counter.warning > 0)
-                        {
-                            testResult.Icon = IconChar.ExclamationTriangle.ToBitmap(Color.Orange, IconSize);
-                            testResult.Status = StatusWarning;
-                        }
+                if (@event.test.errorStack != null)
+                {
+                    testResult["Error"] = @event.test.errorStack;
+                }
 
-                        if (@event.test.errorStack != null)
-                        {
-                            testResult.Error = @event.test.errorStack;
-                        }
+                if (@event.test.failedExpectations != null)
+                {
+                    foreach (var expectation in @event.test.failedExpectations)
+                    {
+                        var rowExpectation = dataTableExpectations.NewRow();
+                        rowExpectation["TestResultId"] = @event.test.id;
+                        rowExpectation["Message"] = expectation.message;
+                        rowExpectation["Caller"] = expectation.caller;
+                        rowExpectation["Line"] = ExtractLine(expectation.caller);
 
-                        if (@event.test.failedExpectations != null)
-                        {
-                            foreach (var expectation in @event.test.failedExpectations)
-                            {
-                                testResult.failedExpectations.Add(new Expectation(expectation.message,
-                                    expectation.caller));
-                            }
-                        }
+                        dataTableExpectations.Rows.Add(rowExpectation);
 
-                        gridResults.Refresh();
-                        try
-                        {
-                            var rowIndex = testResults.IndexOf(testResult);
-                            gridResults.FirstDisplayedScrollingRowIndex = rowIndex;
-                            gridResults.Rows[rowIndex].Selected = true;
-                        }
-                        catch
+                        dataTableExpectations.AcceptChanges();
+                    }
+                }
+
+                testResult.EndEdit();
+
+                dataTableTestResults.AcceptChanges();
+
+                var rowIndex = 0;
+                foreach (DataGridViewRow gridRow in dataGridViewTestResults.Rows)
+                {
+                    if (gridRow.DataBoundItem is DataRowView rowTestResult)
+                    {
+                        if (rowTestResult["Id"].ToString().Equals(@event.test.id))
                         {
-                            // ignore exception that could raise if results are filtered
+                            dataGridViewTestResults.FirstDisplayedScrollingRowIndex = rowIndex;
+                            dataGridViewTestResults.Rows[rowIndex].Selected = true;
+
+                            break;
                         }
+                        rowIndex++;
                     }
                 }
             }
         }
 
+        private string ExtractLine(string caller)
+        {
+            var m = regexLine.Match(caller);
+            if (m.Success)
+            {
+                var g = m.Groups[2];
+                return g.Value;
+            }
+            return caller;
+        }
+
         private void CreateTestResults(@event @event)
         {
             CreateTestResults(@event.items);
@@ -440,50 +459,47 @@ private void CreateTestResults(test test)
         {
             if (test != null)
             {
-                testResults.Add(new TestResult
-                {
-                    Id = test.id,
-                    Owner = test.ownerName,
-                    Package = test.objectName,
-                    Procedure = test.procedureName,
-                    Name = test.name,
-                    Description = test.description,
-                    Icon = IconChar.None.ToBitmap(Color.Black, IconSize)
-                });
+                var rowTestResult = dataTableTestResults.NewRow();
+                rowTestResult["Id"] = test.id;
+                rowTestResult["Owner"] = test.ownerName;
+                rowTestResult["Package"] = test.objectName;
+                rowTestResult["Procedure"] = test.procedureName;
+                rowTestResult["Name"] = test.name;
+                rowTestResult["Description"] = test.description;
+                rowTestResult["Icon"] = (byte[])imageConverter.ConvertTo(IconChar.None.ToBitmap(Color.Black, IconSize), typeof(byte[]));
+
+                dataTableTestResults.Rows.Add(rowTestResult);
             }
         }
 
         private void FilterTestResults()
         {
-            if (!cbSuccess.Checked && !cbFailure.Checked && !cbError.Checked && !cbDisabled.Checked)
+            if (cbSuccess.Checked && cbFailure.Checked && cbError.Checked && cbDisabled.Checked)
             {
-                viewTestResults.RemoveFilter();
+                dataViewTestResults.RowFilter = null;
             }
             else
             {
-                viewTestResults.ApplyFilter(delegate (TestResult testResult)
+                var filter = "Status is null";
+
+                if (cbSuccess.Checked)
                 {
-                    if (testResult.Status != null)
-                    {
-                        if (!cbSuccess.Checked && testResult.Status.Equals(StatusSuccess))
-                        {
-                            return false;
-                        }
-                        if (!cbFailure.Checked && testResult.Status.Equals(StatusFailure))
-                        {
-                            return false;
-                        }
-                        if (!cbError.Checked && testResult.Status.Equals(StatusError))
-                        {
-                            return false;
-                        }
-                        if (!cbDisabled.Checked && testResult.Status.Equals(StatusDisabled))
-                        {
-                            return false;
-                        }
-                    }
-                    return true;
-                });
+                    filter += $" or Status = '{StatusSuccess}'";
+                }
+                if (cbFailure.Checked)
+                {
+                    filter += $" or Status = '{StatusFailure}'";
+                }
+                if (cbError.Checked)
+                {
+                    filter += $" or Status = '{StatusError}'";
+                }
+                if (cbDisabled.Checked)
+                {
+                    filter += $" or Status = '{StatusDisabled}'";
+                }
+
+                dataViewTestResults.RowFilter = filter;
             }
         }
 
@@ -519,48 +535,52 @@ private void TestResultWindow_FormClosing(object sender, FormClosingEventArgs e)
 
         private void gridResults_SelectionChanged(object sender, EventArgs e)
         {
-            if (gridResults.SelectedRows.Count > 0)
+            if (dataGridViewTestResults.SelectedRows.Count > 0)
             {
-                var row = gridResults.SelectedRows[0];
-                var dataBoundItem = (ObjectView<TestResult>)row.DataBoundItem;
-                var testResult = dataBoundItem.Object;
+                var row = dataGridViewTestResults.SelectedRows[0];
 
-                txtTestOwner.Text = testResult.Owner;
-                txtTestPackage.Text = testResult.Package;
-                txtTestProcuedure.Text = testResult.Procedure;
-                txtTestName.Text = testResult.Name;
-                txtTestDescription.Text = testResult.Description;
-                txtTestSuitePath.Text = testResult.Id;
+                if (row.DataBoundItem is DataRowView rowTestResult)
+                {
+                    txtTestOwner.Text = "" + rowTestResult.Row["Owner"];
+                    txtTestPackage.Text = "" + rowTestResult.Row["Package"];
+                    txtTestProcuedure.Text = "" + rowTestResult.Row["Procedure"];
+                    txtTestName.Text = "" + rowTestResult.Row["Name"];
+                    txtTestDescription.Text = "" + rowTestResult.Row["Description"];
+                    txtTestSuitePath.Text = "" + rowTestResult.Row["Id"];
 
-                txtTestStart.Text = testResult.Start.ToString(CultureInfo.CurrentCulture);
-                txtTestEnd.Text = testResult.End.ToString(CultureInfo.CurrentCulture);
-                txtTestTime.Text = $"{testResult.Time} s";
+                    txtTestStart.Text = rowTestResult.Row["Start"].ToString().ToString(CultureInfo.CurrentCulture);
+                    txtTestEnd.Text = rowTestResult.Row["End"].ToString().ToString(CultureInfo.CurrentCulture);
+                    txtTestTime.Text = $"{rowTestResult.Row["Time"]} s";
 
-                txtErrorMessage.Text = testResult.Error;
+                    txtErrorMessage.Text = rowTestResult.Row["Error"] == null ? "" : rowTestResult.Row["Error"].ToString().Replace("\n", "\r\n");
 
-                var bindingSource = new BindingSource { DataSource = testResult.failedExpectations };
-                gridTestFailures.DataSource = bindingSource;
+                    txtFailureMessage.Text = "";
 
-                gridTestFailures.Columns[0].MinimumWidth = 480;
-                gridTestFailures.Columns[1].MinimumWidth = 480;
+                    dataViewExpectations.RowFilter = $"TestResultId = '{rowTestResult.Row["Id"]}'";
 
-                if (!Running)
-                {
-                    if (testResult.Status == null)
-                    {
-                        tabs.SelectedTab = tabTest;
-                    }
-                    else if (testResult.Status.Equals(StatusFailure))
+                    if (dataViewExpectations.Count > 0)
                     {
-                        tabs.SelectedTab = tabFailures;
+                        dataGridViewExpectations.Rows[0].Selected = true;
                     }
-                    else if (testResult.Status.Equals(StatusError))
-                    {
-                        tabs.SelectedTab = tabErrors;
-                    }
-                    else
+
+                    if (!Running)
                     {
-                        tabs.SelectedTab = tabTest;
+                        if (rowTestResult.Row["Status"] == null)
+                        {
+                            tabs.SelectedTab = tabTest;
+                        }
+                        else if (rowTestResult.Row["Status"].ToString().Equals(StatusFailure))
+                        {
+                            tabs.SelectedTab = tabFailures;
+                        }
+                        else if (rowTestResult.Row["Status"].ToString().Equals(StatusError))
+                        {
+                            tabs.SelectedTab = tabErrors;
+                        }
+                        else
+                        {
+                            tabs.SelectedTab = tabTest;
+                        }
                     }
                 }
             }
@@ -584,10 +604,10 @@ private void gridTestFailures_CellDoubleClick(object sender, DataGridViewCellEve
 
         private void invokeOpenPackageBody(DataGridViewCellEventArgs e)
         {
-            var testResult = testResults[e.RowIndex];
+            var rowTestResult = dataTableTestResults.Rows[e.RowIndex];
 
             var methodInfo = pluginIntegration.GetType().GetMethod("OpenPackageBody");
-            methodInfo.Invoke(pluginIntegration, new object[] { testResult.Owner, testResult.Package });
+            methodInfo.Invoke(pluginIntegration, new[] { rowTestResult["Owner"], rowTestResult["Package"] });
         }
 
         private void gridResults_CellContextMenuStripNeeded(object sender, DataGridViewCellContextMenuStripNeededEventArgs e)
@@ -597,18 +617,18 @@ private void gridResults_CellContextMenuStripNeeded(object sender, DataGridViewC
 
         private async void menuItemRunTests_ClickAsync(object sender, EventArgs e)
         {
-            var testResult = testResults[rowIndexOnRightClick];
+            var rowTestResult = dataTableTestResults.Rows[rowIndexOnRightClick];
 
-            var testResultWindow = new TestRunnerWindow(pluginIntegration, username, password, database, connectAs);
-            await testResultWindow.RunTestsAsync("PROCEDURE", testResult.Owner, testResult.Package, testResult.Procedure, false);
+            var testResultWindow = new TestRunnerWindow(pluginIntegration, username, password, database, connectAs, oracleHome);
+            await testResultWindow.RunTestsAsync("PROCEDURE", rowTestResult["Owner"].ToString(), rowTestResult["Package"].ToString(), rowTestResult["Procedure"].ToString(), false, false);
         }
 
         private async void menuItemCoverage_ClickAsync(object sender, EventArgs e)
         {
-            var testResult = testResults[rowIndexOnRightClick];
+            var rowTestResult = dataTableTestResults.Rows[rowIndexOnRightClick];
 
-            var testResultWindow = new TestRunnerWindow(pluginIntegration, username, password, database, connectAs);
-            await testResultWindow.RunTestsAsync("PROCEDURE", testResult.Owner, testResult.Package, testResult.Procedure, true);
+            var testResultWindow = new TestRunnerWindow(pluginIntegration, username, password, database, connectAs, oracleHome);
+            await testResultWindow.RunTestsAsync("PROCEDURE", rowTestResult["Owner"].ToString(), rowTestResult["Package"].ToString(), rowTestResult["Procedure"].ToString(), true, false);
         }
 
         private void cbSuccess_CheckedChanged(object sender, EventArgs e)
@@ -630,5 +650,30 @@ private void cbDisabled_CheckedChanged(object sender, EventArgs e)
         {
             FilterTestResults();
         }
+
+        private async void btnRun_Click(object sender, EventArgs e)
+        {
+            await RunTestsAsync(new List<string> { txtPath.Text }, false);
+        }
+
+        private async void button1_Click(object sender, EventArgs e)
+        {
+            await RunTestsAsync(new List<string> { txtPath.Text }, true);
+        }
+
+        private void dataGridViewExpectations_SelectionChanged(object sender, EventArgs e)
+        {
+            txtFailureMessage.Text = "";
+
+            if (dataGridViewExpectations.SelectedRows.Count > 0)
+            {
+                var row = dataGridViewExpectations.SelectedRows[0];
+
+                if (row.DataBoundItem is DataRowView rowExpectation)
+                {
+                    txtFailureMessage.Text = $"{rowExpectation.Row["Message"].ToString().Replace("\n", "\r\n")}\r\n\r\n{rowExpectation.Row["Caller"].ToString().Replace("\n", "\r\n")}";
+                }
+            }
+        }
     }
 }
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.resx b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.resx
index 1fa3339..af06881 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.resx
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/TestRunnerWindow.resx
@@ -120,6 +120,12 @@
   <metadata name="contextMenuResults.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
     <value>17, 17</value>
   </metadata>
+  <metadata name="dataSet.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
+    <value>179, 17</value>
+  </metadata>
+  <metadata name="Line.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
+    <value>True</value>
+  </metadata>
   <assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
   <data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
     <value>
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/packages.config b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/packages.config
index ca2e476..e4d0a02 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/packages.config
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/packages.config
@@ -1,7 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <packages>
-  <package id="FontAwesome.Sharp" version="5.15.3" targetFramework="net45" />
-  <package id="Geomatics.IO.BindingListView" version="1.3.2" targetFramework="net40" />
-  <package id="Oracle.ManagedDataAccess" version="19.10.0" targetFramework="net40" />
-  <package id="utPLSQL.Api" version="1.5.2" targetFramework="net45" />
+  <package id="FontAwesome.Sharp" version="5.15.3" targetFramework="net45" requireReinstallation="true" />
+  <package id="Oracle.ManagedDataAccess" version="19.10.0" targetFramework="net45" />
+  <package id="utPLSQL.Api" version="1.5.6" targetFramework="net45" />
 </packages>
\ No newline at end of file
diff --git a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/utPLSQL.UI.csproj b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/utPLSQL.UI.csproj
index 1108930..32746a5 100644
--- a/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/utPLSQL.UI.csproj
+++ b/PlsqlDeveloperUtPlsqlPlugin/utPLSQL.UI/utPLSQL.UI.csproj
@@ -9,7 +9,7 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>utPLSQL</RootNamespace>
     <AssemblyName>utPLSQL.UI</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <Deterministic>true</Deterministic>
     <TargetFrameworkProfile />
@@ -34,9 +34,6 @@
     <Prefer32Bit>false</Prefer32Bit>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="BindingListView, Version=1.3.6583.21972, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\Geomatics.IO.BindingListView.1.3.2\lib\net40\BindingListView.dll</HintPath>
-    </Reference>
     <Reference Include="FontAwesome.Sharp, Version=5.15.3.0, Culture=neutral, processorArchitecture=MSIL">
       <HintPath>..\packages\FontAwesome.Sharp.5.15.3\lib\net45\FontAwesome.Sharp.dll</HintPath>
     </Reference>
@@ -45,6 +42,7 @@
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
+    <Reference Include="System.Design" />
     <Reference Include="System.Drawing" />
     <Reference Include="System.Windows.Forms" />
     <Reference Include="System.Xml.Linq" />
@@ -52,8 +50,8 @@
     <Reference Include="Microsoft.CSharp" />
     <Reference Include="System.Data" />
     <Reference Include="System.Xml" />
-    <Reference Include="utPLSQL.Api, Version=1.5.2.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\packages\utPLSQL.Api.1.5.2\lib\net45\utPLSQL.Api.dll</HintPath>
+    <Reference Include="utPLSQL.Api, Version=1.5.6.0, Culture=neutral, processorArchitecture=MSIL">
+      <HintPath>..\packages\utPLSQL.Api.1.5.6\lib\net45\utPLSQL.Api.dll</HintPath>
     </Reference>
   </ItemGroup>
   <ItemGroup>
@@ -64,7 +62,6 @@
       <DependentUpon>CodeCoverageReportDialog.cs</DependentUpon>
     </Compile>
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="TestResult.cs" />
     <Compile Include="TestRunnerWindow.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -89,5 +86,11 @@
     <None Include="App.config" />
     <None Include="packages.config" />
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\ColorProgressBar\ColorProgressBar.csproj">
+      <Project>{739e6f07-e688-4d16-8fdf-7472e7f0fea0}</Project>
+      <Name>ColorProgressBar</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
 </Project>
\ No newline at end of file
diff --git a/README.md b/README.md
index 22aebfd..2d51958 100644
--- a/README.md
+++ b/README.md
@@ -2,33 +2,49 @@
 
 The utPLSQL Plugin integrates [utPLSQL](https://utplsql.org) with [Allround Automations PL/SQL Developer](https://www.allroundautomations.com/products/pl-sql-developer/).
 
-## Running Tests and Code Coverage
+## Running Tests
 
-The plugin adds a Button to the Tools ribbon to execute all tests of the current user or run code coverage.
+The plugin adds three buttons to the tools ribbon to 1) execute all tests of the current user, 2) run code coverage or 3) run tests for a specific path. If you choose 3) the run window will open and you can enter the path manually.
 
-![Tools Ribbon](screenshots/tools_ribbon.png)
+![Tools Ribbon](screenshots/tools_ribbon_full.png)
 
-In the object browser on Packages or Users there is a context menu entry to run the tests or code coverage of either the packages or the users.
+In the object browser on Packages, Package Bodys, Procedures or Users there is a context menu entry to run the tests or code coverage of either the package, the procedure or the user. You can also run tests from an program window. 
 
 ![Context Menu](screenshots/context_menu.png)
 
 ## Viewing Results
 
-The results are opened in a new window. If you've chosen code coverage the coverage report will be opened in the default browser. 
+The results are opened in a new window. Each test run will open a separate window. 
 
 ### Navigating to the package body 
 
 Double-click on a test result entry will open the package body. 
 
-### Runing single tests
+### Running  tests
+
+There are two buttons to run the tests again either with or without coverage.
+
+### Running single tests
 
 A right-click opens the context menu, and you can run the test function.
 
-### Filtering Results
+### Filtering and Sorting Results
+
+You can filter the results by clicking on checkboxes behind the status field. A click on the header cell sorts the results first ascending and with a second click descending.  
+
+![Result Window](screenshots/result_window.png)
+
+## Code Coverage
+
+If you select Run Code Coverage from the menu or the context menu a dialog is displayed. In this dialog you can configure the schemas to check for coverage and include or exclude specific objects.
+
+![Code Coverage Diaog](screenshots/code_coverage_dialog.png)
+
+### Report
 
-Once the tests are run you can filter the results by clicking on checkboxes behind the status field.  
+After running the tests the HTML code coverage report will be opened in the default browser.
 
-![img.png](screenshots/result_window_filter.png)
+![Code Coverage Reports](screenshots/code_coverage_report.png)
 
 ## Releases
 
diff --git a/screenshots/code_coverage_dialog.png b/screenshots/code_coverage_dialog.png
new file mode 100644
index 0000000..332fe3c
Binary files /dev/null and b/screenshots/code_coverage_dialog.png differ
diff --git a/screenshots/code_coverage_report.png b/screenshots/code_coverage_report.png
new file mode 100644
index 0000000..10728e3
Binary files /dev/null and b/screenshots/code_coverage_report.png differ
diff --git a/screenshots/context_menu.png b/screenshots/context_menu.png
index b717557..d6b3db2 100644
Binary files a/screenshots/context_menu.png and b/screenshots/context_menu.png differ
diff --git a/screenshots/result_window.png b/screenshots/result_window.png
new file mode 100644
index 0000000..d5b0612
Binary files /dev/null and b/screenshots/result_window.png differ
diff --git a/screenshots/result_window_filter.png b/screenshots/result_window_filter.png
deleted file mode 100644
index bb5dc1f..0000000
Binary files a/screenshots/result_window_filter.png and /dev/null differ
diff --git a/screenshots/tools_ribbon.png b/screenshots/tools_ribbon.png
deleted file mode 100644
index 9e7a745..0000000
Binary files a/screenshots/tools_ribbon.png and /dev/null differ
diff --git a/screenshots/tools_ribbon_full.png b/screenshots/tools_ribbon_full.png
new file mode 100644
index 0000000..85c1cfb
Binary files /dev/null and b/screenshots/tools_ribbon_full.png differ