changeset 77:91362ffbecf8 v2

ported tests to mono
author cin
date Thu, 11 Sep 2014 10:56:14 +0400
parents c761fc982e1d
children 05f74c39a143
files Implab.Fx.Test/Implab.Fx.Test.mono.csproj Implab.Fx.Test/OverlayTest.cs Implab.Test/AsyncTests.cs Implab.Test/Implab.Test.mono.csproj Implab.Test/PromiseHelper.cs Implab.Test/Properties/AssemblyInfo.cs Implab.mono.sln
diffstat 7 files changed, 887 insertions(+), 442 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab.Fx.Test/Implab.Fx.Test.mono.csproj	Thu Sep 11 10:56:14 2014 +0400
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{2BD05F84-E067-4B87-9477-FDC2676A21C6}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>Implab.Fx.Test</RootNamespace>
+    <AssemblyName>Implab.Fx.Test</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;MONO</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+    <DefineConstants>MONO</DefineConstants>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;TRACE;NET_4_5;MONO</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <DefineConstants>NET_4_5;MONO</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="nunit.framework" />
+    <Reference Include="System.Windows.Forms" />
+    <Reference Include="System.Drawing" />
+    <Reference Include="System.Data" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <ProjectReference Include="..\Implab.Fx\Implab.Fx.csproj">
+      <Project>{06E706F8-6881-43EB-927E-FFC503AF6ABC}</Project>
+      <Name>Implab.Fx</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Implab\Implab.csproj">
+      <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project>
+      <Name>Implab</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="OverlayTest.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="Sample\MainForm.Designer.cs" />
+    <Compile Include="Sample\MainForm.cs" />
+    <Compile Include="Sample\OverlayForm.Designer.cs" />
+    <Compile Include="Sample\OverlayForm.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Sample\MainForm.resx" />
+    <None Include="Sample\OverlayForm.resx" />
+  </ItemGroup>
+</Project>
\ No newline at end of file
--- a/Implab.Fx.Test/OverlayTest.cs	Wed Sep 10 17:53:05 2014 +0400
+++ b/Implab.Fx.Test/OverlayTest.cs	Thu Sep 11 10:56:14 2014 +0400
@@ -1,12 +1,18 @@
-using System;
-using System.Text;
-using System.Collections.Generic;
-using System.Linq;
+using System.Windows.Forms;
+using Implab.Fx.Test.Sample;
+using Implab.Fx;
+
+#if MONO
+
+using NUnit.Framework;
+using TestClassAttribute = NUnit.Framework.TestFixtureAttribute;
+using TestMethod = NUnit.Framework.TestAttribute;
+
+#else
+
 using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.Windows.Forms;
-using Implab.Fx.Test.Sample;
-using System.Drawing;
-using Implab.Fx;
+
+#endif
 
 namespace Implab.Fx.Test
 {
@@ -22,10 +28,7 @@
             {
                 var overlay = new OverlayForm();
                 mainForm.OverlayFadeIn(overlay).Then(
-                    o => o.ButtonEvent += (s2, args2) =>
-                    {
-                        o.CloseFadeOut();
-                    }
+                    o => o.ButtonEvent += (s2, args2) => o.CloseFadeOut()
                 );
             };
             
--- a/Implab.Test/AsyncTests.cs	Wed Sep 10 17:53:05 2014 +0400
+++ b/Implab.Test/AsyncTests.cs	Thu Sep 11 10:56:14 2014 +0400
@@ -1,423 +1,434 @@
-using System;
-using Microsoft.VisualStudio.TestTools.UnitTesting;
-using System.Reflection;
-using System.Threading;
-using Implab.Parallels;
-
-namespace Implab.Test {
-    [TestClass]
-    public class AsyncTests {
-        [TestMethod]
-        public void ResolveTest() {
-            int res = -1;
-            var p = new Promise<int>();
-            p.Then(x => res = x);
-            p.Resolve(100);
-
-            Assert.AreEqual(100, res);
-        }
-
-        [TestMethod]
-        public void RejectTest() {
-            int res = -1;
-            Exception err = null;
-
-            var p = new Promise<int>();
-            p.Then(
-                x => res = x,
-                e => {
-                    err = e;
-                    return -2;
-                }
-            );
-            p.Reject(new ApplicationException("error"));
-
-            Assert.AreEqual(res, -1);
-            Assert.AreEqual(err.Message, "error");
-
-        }
-
-        [TestMethod]
-        public void CancelExceptionTest() {
-            var p = new Promise<bool>();
-            p.Cancel();
-
-            var p2 = p.Cancelled(() => {
-                throw new ApplicationException("CANCELLED"); 
-            });
-
-            try {
-                p2.Join();
-                Assert.Fail();
-            } catch (ApplicationException err) {
-                Assert.AreEqual("CANCELLED", err.InnerException.Message);
-            }
-
-        }
-
-        [TestMethod]
-        public void ContinueOnCancelTest() {
-            var p = new Promise<bool>();
-            p.Cancel();
-
-            var p2 = p
-                .Cancelled(() => {
-                    throw new ApplicationException("CANCELLED");
-                })
-                .Error(e => true);
-
-            Assert.AreEqual(true, p2.Join());
-        }
-
-        [TestMethod]
-        public void JoinSuccessTest() {
-            var p = new Promise<int>();
-            p.Resolve(100);
-            Assert.AreEqual(p.Join(), 100);
-        }
-
-        [TestMethod]
-        public void JoinFailTest() {
-            var p = new Promise<int>();
-            p.Reject(new ApplicationException("failed"));
-
-            try {
-                p.Join();
-                throw new ApplicationException("WRONG!");
-            } catch (TargetInvocationException err) {
-                Assert.AreEqual(err.InnerException.Message, "failed");
-            } catch {
-                Assert.Fail("Got wrong excaption");
-            }
-        }
-
-        [TestMethod]
-        public void MapTest() {
-            var p = new Promise<int>();
-
-            var p2 = p.Then(x => x.ToString());
-            p.Resolve(100);
-
-            Assert.AreEqual(p2.Join(), "100");
-        }
-
-        [TestMethod]
-        public void FixErrorTest() {
-            var p = new Promise<int>();
-
-            var p2 = p.Error(e => 101);
-
-            p.Reject(new Exception());
-
-            Assert.AreEqual(p2.Join(), 101);
-        }
-
-        [TestMethod]
-        public void ChainTest() {
-            var p1 = new Promise<int>();
-
-            var p3 = p1.Chain(x => {
-                var p2 = new Promise<string>();
-                p2.Resolve(x.ToString());
-                return p2;
-            });
-
-            p1.Resolve(100);
-
-            Assert.AreEqual(p3.Join(), "100");
-        }
-
-        [TestMethod]
-        public void PoolTest() {
-            var pid = Thread.CurrentThread.ManagedThreadId;
-            var p = AsyncPool.Invoke(() => Thread.CurrentThread.ManagedThreadId);
-
-            Assert.AreNotEqual(pid, p.Join());
-        }
-
-        [TestMethod]
-        public void WorkerPoolSizeTest() {
-            var pool = new WorkerPool(5, 10, 0);
-
-            Assert.AreEqual(5, pool.PoolSize);
-
-            pool.Invoke(() => { Thread.Sleep(100000000); return 10; });
-            pool.Invoke(() => { Thread.Sleep(100000000); return 10; });
-            pool.Invoke(() => { Thread.Sleep(100000000); return 10; });
-
-            Assert.AreEqual(5, pool.PoolSize);
-
-            for (int i = 0; i < 100; i++)
-                pool.Invoke(() => { Thread.Sleep(100000000); return 10; });
-            Thread.Sleep(200);
-            Assert.AreEqual(10, pool.PoolSize);
-
-            pool.Dispose();
-        }
-
-        [TestMethod]
-        public void WorkerPoolCorrectTest() {
-            var pool = new WorkerPool(0,1000,100);
-
-            int iterations = 1000;
-            int pending = iterations;
-            var stop = new ManualResetEvent(false);
-
-            var count = 0;
-            for (int i = 0; i < iterations; i++) {
-                pool
-                    .Invoke(() => 1)
-                    .Then(x => Interlocked.Add(ref count, x))
-                    .Then(x => Math.Log10(x))
-                    .Anyway(() => {
-                        Interlocked.Decrement(ref pending);
-                        if (pending == 0)
-                            stop.Set();
-                    });
-            }
-
-            stop.WaitOne();
-
-            Assert.AreEqual(iterations, count);
-            Console.WriteLine("Max threads: {0}", pool.MaxRunningThreads);
-            pool.Dispose();
-            
-        }
-
-        [TestMethod]
-        public void WorkerPoolDisposeTest() {
-            var pool = new WorkerPool(5, 20);
-            Assert.AreEqual(5, pool.PoolSize);
-            pool.Dispose();
-            Thread.Sleep(500);
-            Assert.AreEqual(0, pool.PoolSize);
-            pool.Dispose();
-        }
-
-        [TestMethod]
-        public void MTQueueTest() {
-            var queue = new MTQueue<int>();
-            int res;
-
-            queue.Enqueue(10);
-            Assert.IsTrue(queue.TryDequeue(out res));
-            Assert.AreEqual(10, res);
-            Assert.IsFalse(queue.TryDequeue(out res));
-
-            for (int i = 0; i < 1000; i++)
-                queue.Enqueue(i);
-
-            for (int i = 0; i < 1000; i++) {
-                queue.TryDequeue(out res);
-                Assert.AreEqual(i, res);
-            }
-
-            int writers = 0;
-            int readers = 0;
-            var stop = new ManualResetEvent(false);
-            int total = 0;
-
-            int itemsPerWriter = 10000;
-            int writersCount = 10;
-
-            for (int i = 0; i < writersCount; i++) {
-                Interlocked.Increment(ref writers);
-                var wn = i;
-                AsyncPool
-                    .InvokeNewThread(() => {
-                        for (int ii = 0; ii < itemsPerWriter; ii++) {
-                            queue.Enqueue(1);
-                        }
-                        return 1;
-                    })
-                    .Anyway(() => Interlocked.Decrement(ref writers));
-            }
-
-            for (int i = 0; i < 10; i++) {
-                Interlocked.Increment(ref readers);
-                var wn = i;
-                AsyncPool
-                    .InvokeNewThread(() => {
-                        int t;
-                        do {
-                            while (queue.TryDequeue(out t))
-                                Interlocked.Add(ref total, t);
-                        } while (writers > 0);
-                        return 1;
-                    })
-                    .Anyway(() => {
-                        Interlocked.Decrement(ref readers);
-                        if (readers == 0)
-                            stop.Set();
-                    });
-            }
-
-            stop.WaitOne();
-
-            Assert.AreEqual(itemsPerWriter * writersCount, total);
-        }
-
-        [TestMethod]
-        public void ParallelMapTest() {
-
-            int count = 100000;
-
-            double[] args = new double[count];
-            var rand = new Random();
-
-            for (int i = 0; i < count; i++)
-                args[i] = rand.NextDouble();
-
-            var t = Environment.TickCount;
-            var res = args.ParallelMap(x => Math.Sin(x*x), 4).Join();
-
-            Console.WriteLine("Map complete in {0} ms", Environment.TickCount - t);
-
-            t = Environment.TickCount;
-            for (int i = 0; i < count; i++)
-                Assert.AreEqual(Math.Sin(args[i] * args[i]), res[i]);
-            Console.WriteLine("Verified in {0} ms", Environment.TickCount - t);
-        }
-
-        [TestMethod]
-        public void ChainedMapTest() {
-
-            using (var pool = new WorkerPool(0,100,100)) {
-                int count = 10000;
-
-                double[] args = new double[count];
-                var rand = new Random();
-
-                for (int i = 0; i < count; i++)
-                    args[i] = rand.NextDouble();
-
-                var t = Environment.TickCount;
-                var res = args
-                    .ChainedMap(
-                        x => pool.Invoke(
-                            () => Math.Sin(x * x)
-                        ),
-                        4
-                    )
-                    .Join();
-
-                Console.WriteLine("Map complete in {0} ms", Environment.TickCount - t);
-
-                t = Environment.TickCount;
-                for (int i = 0; i < count; i++)
-                    Assert.AreEqual(Math.Sin(args[i] * args[i]), res[i]);
-                Console.WriteLine("Verified in {0} ms", Environment.TickCount - t);
-                Console.WriteLine("Max workers: {0}", pool.MaxRunningThreads);
-            }
-        }
-
-        [TestMethod]
-        public void ParallelForEachTest() {
-
-            int count = 100000;
-
-            int[] args = new int[count];
-            var rand = new Random();
-
-            for (int i = 0; i < count; i++)
-                args[i] = (int)(rand.NextDouble() * 100);
-
-            int result = 0;
-
-            var t = Environment.TickCount;
-            args.ParallelForEach(x => Interlocked.Add(ref result, x), 4).Join();
-
-            Console.WriteLine("Iteration complete in {0} ms, result: {1}", Environment.TickCount - t, result);
-
-            int result2 = 0;
-
-            t = Environment.TickCount;
-            for (int i = 0; i < count; i++)
-                result2 += args[i];
-            Assert.AreEqual(result2, result);
-            Console.WriteLine("Verified in {0} ms", Environment.TickCount - t);
-        }
-
-        [TestMethod]
-        public void ComplexCase1Test() {
-            var flags = new bool[3];
-
-            // op1 (aync 200ms) => op2 (async 200ms) => op3 (sync map)
-
-            var p = PromiseHelper
-                .Sleep(200, "Alan")
-                .Cancelled(() => flags[0] = true)
-                .Chain(x =>
-                    PromiseHelper
-                        .Sleep(200, "Hi, " + x)
-                        .Then(y => y)
-                        .Cancelled(() => flags[1] = true)
-                )
-                .Cancelled(() => flags[2] = true);
-            Thread.Sleep(300);
-            p.Cancel();
-            try {
-                Assert.AreEqual(p.Join(), "Hi, Alan");
-                Assert.Fail("Shouldn't get here");
-            } catch (OperationCanceledException) {
-            }
-
-            Assert.IsFalse(flags[0]);
-            Assert.IsTrue(flags[1]);
-            Assert.IsTrue(flags[2]);
-        }
-
-        [TestMethod]
-        public void ChainedCancel1Test() {
-            //        
-            //   OperationCanceledException
-            var p = PromiseHelper
-                .Sleep(1, "Hi, HAL!")
-                .Then(x => {
-                    //    
-                    var result = PromiseHelper.Sleep(1000, "HEM ENABLED!!!");
-                    //      
-                    PromiseHelper
-                        .Sleep(100, "HAL, STOP!")
-                        .Then(() => result.Cancel());
-                    return result;
-                });
-            try {
-                p.Join();
-            } catch (TargetInvocationException err) {
-                Assert.IsTrue(err.InnerException is OperationCanceledException);
-            }
-        }
-
-        [TestMethod]
-        public void ChainedCancel2Test() {
-            //    ,     
-            var pSurvive = new Promise<bool>();
-            var hemStarted = new ManualResetEvent(false);
-            var p = PromiseHelper
-                .Sleep(1, "Hi, HAL!")
-                .Chain(x => {
-                    hemStarted.Set();
-                    //    
-                    var result = PromiseHelper
-                        .Sleep(10000, "HEM ENABLED!!!")
-                        .Then(s => pSurvive.Resolve(false));
-
-                    result
-                        .Cancelled(() => pSurvive.Resolve(true));
-                    
-                    return result;
-                });
-
-            hemStarted.WaitOne();
-            p.Cancel();
-
-            try {
-                p.Join();
-            } catch (OperationCanceledException) {
-                Assert.IsTrue(pSurvive.Join());
-            }
-        }
-    }
-}
-
+using System;
+using System.Reflection;
+using System.Threading;
+using Implab.Parallels;
+
+#if MONO
+
+using NUnit.Framework;
+using TestClassAttribute = NUnit.Framework.TestFixtureAttribute;
+using TestMethod = NUnit.Framework.TestAttribute;
+
+#else
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+#endif
+
+namespace Implab.Test {
+    [TestClass]
+    public class AsyncTests {
+        [TestMethod]
+        public void ResolveTest() {
+            int res = -1;
+            var p = new Promise<int>();
+            p.Then(x => res = x);
+            p.Resolve(100);
+
+            Assert.AreEqual(100, res);
+        }
+
+        [TestMethod]
+        public void RejectTest() {
+            int res = -1;
+            Exception err = null;
+
+            var p = new Promise<int>();
+            p.Then(
+                x => res = x,
+                e => {
+                    err = e;
+                    return -2;
+                }
+            );
+            p.Reject(new ApplicationException("error"));
+
+            Assert.AreEqual(res, -1);
+            Assert.AreEqual(err.Message, "error");
+
+        }
+
+        [TestMethod]
+        public void CancelExceptionTest() {
+            var p = new Promise<bool>();
+            p.Cancel();
+
+            var p2 = p.Cancelled(() => {
+                throw new ApplicationException("CANCELLED"); 
+            });
+
+            try {
+                p2.Join();
+                Assert.Fail();
+            } catch (ApplicationException err) {
+                Assert.AreEqual("CANCELLED", err.InnerException.Message);
+            }
+
+        }
+
+        [TestMethod]
+        public void ContinueOnCancelTest() {
+            var p = new Promise<bool>();
+            p.Cancel();
+
+            var p2 = p
+                .Cancelled(() => {
+                    throw new ApplicationException("CANCELLED");
+                })
+                .Error(e => true);
+
+            Assert.AreEqual(true, p2.Join());
+        }
+
+        [TestMethod]
+        public void JoinSuccessTest() {
+            var p = new Promise<int>();
+            p.Resolve(100);
+            Assert.AreEqual(p.Join(), 100);
+        }
+
+        [TestMethod]
+        public void JoinFailTest() {
+            var p = new Promise<int>();
+            p.Reject(new ApplicationException("failed"));
+
+            try {
+                p.Join();
+                throw new ApplicationException("WRONG!");
+            } catch (TargetInvocationException err) {
+                Assert.AreEqual(err.InnerException.Message, "failed");
+            } catch {
+                Assert.Fail("Got wrong excaption");
+            }
+        }
+
+        [TestMethod]
+        public void MapTest() {
+            var p = new Promise<int>();
+
+            var p2 = p.Then(x => x.ToString());
+            p.Resolve(100);
+
+            Assert.AreEqual(p2.Join(), "100");
+        }
+
+        [TestMethod]
+        public void FixErrorTest() {
+            var p = new Promise<int>();
+
+            var p2 = p.Error(e => 101);
+
+            p.Reject(new Exception());
+
+            Assert.AreEqual(p2.Join(), 101);
+        }
+
+        [TestMethod]
+        public void ChainTest() {
+            var p1 = new Promise<int>();
+
+            var p3 = p1.Chain(x => {
+                var p2 = new Promise<string>();
+                p2.Resolve(x.ToString());
+                return p2;
+            });
+
+            p1.Resolve(100);
+
+            Assert.AreEqual(p3.Join(), "100");
+        }
+
+        [TestMethod]
+        public void PoolTest() {
+            var pid = Thread.CurrentThread.ManagedThreadId;
+            var p = AsyncPool.Invoke(() => Thread.CurrentThread.ManagedThreadId);
+
+            Assert.AreNotEqual(pid, p.Join());
+        }
+
+        [TestMethod]
+        public void WorkerPoolSizeTest() {
+            var pool = new WorkerPool(5, 10, 0);
+
+            Assert.AreEqual(5, pool.PoolSize);
+
+            pool.Invoke(() => { Thread.Sleep(100000000); return 10; });
+            pool.Invoke(() => { Thread.Sleep(100000000); return 10; });
+            pool.Invoke(() => { Thread.Sleep(100000000); return 10; });
+
+            Assert.AreEqual(5, pool.PoolSize);
+
+            for (int i = 0; i < 100; i++)
+                pool.Invoke(() => { Thread.Sleep(100000000); return 10; });
+            Thread.Sleep(200);
+            Assert.AreEqual(10, pool.PoolSize);
+
+            pool.Dispose();
+        }
+
+        [TestMethod]
+        public void WorkerPoolCorrectTest() {
+            var pool = new WorkerPool(0,1000,100);
+
+            const int iterations = 1000;
+            int pending = iterations;
+            var stop = new ManualResetEvent(false);
+
+            var count = 0;
+            for (int i = 0; i < iterations; i++) {
+                pool
+                    .Invoke(() => 1)
+                    .Then(x => Interlocked.Add(ref count, x))
+                    .Then(x => Math.Log10(x))
+                    .Anyway(() => {
+                        Interlocked.Decrement(ref pending);
+                        if (pending == 0)
+                            stop.Set();
+                    });
+            }
+
+            stop.WaitOne();
+
+            Assert.AreEqual(iterations, count);
+            Console.WriteLine("Max threads: {0}", pool.MaxRunningThreads);
+            pool.Dispose();
+            
+        }
+
+        [TestMethod]
+        public void WorkerPoolDisposeTest() {
+            var pool = new WorkerPool(5, 20);
+            Assert.AreEqual(5, pool.PoolSize);
+            pool.Dispose();
+            Thread.Sleep(500);
+            Assert.AreEqual(0, pool.PoolSize);
+            pool.Dispose();
+        }
+
+        [TestMethod]
+        public void MTQueueTest() {
+            var queue = new MTQueue<int>();
+            int res;
+
+            queue.Enqueue(10);
+            Assert.IsTrue(queue.TryDequeue(out res));
+            Assert.AreEqual(10, res);
+            Assert.IsFalse(queue.TryDequeue(out res));
+
+            for (int i = 0; i < 1000; i++)
+                queue.Enqueue(i);
+
+            for (int i = 0; i < 1000; i++) {
+                queue.TryDequeue(out res);
+                Assert.AreEqual(i, res);
+            }
+
+            int writers = 0;
+            int readers = 0;
+            var stop = new ManualResetEvent(false);
+            int total = 0;
+
+            const int itemsPerWriter = 10000;
+            const int writersCount = 10;
+
+            for (int i = 0; i < writersCount; i++) {
+                Interlocked.Increment(ref writers);
+                AsyncPool
+                    .InvokeNewThread(() => {
+                        for (int ii = 0; ii < itemsPerWriter; ii++) {
+                            queue.Enqueue(1);
+                        }
+                        return 1;
+                    })
+                    .Anyway(() => Interlocked.Decrement(ref writers));
+            }
+
+            for (int i = 0; i < 10; i++) {
+                Interlocked.Increment(ref readers);
+                AsyncPool
+                    .InvokeNewThread(() => {
+                        int t;
+                        do {
+                            while (queue.TryDequeue(out t))
+                                Interlocked.Add(ref total, t);
+                        } while (writers > 0);
+                        return 1;
+                    })
+                    .Anyway(() => {
+                        Interlocked.Decrement(ref readers);
+                        if (readers == 0)
+                            stop.Set();
+                    });
+            }
+
+            stop.WaitOne();
+
+            Assert.AreEqual(itemsPerWriter * writersCount, total);
+        }
+
+        [TestMethod]
+        public void ParallelMapTest() {
+
+            const int count = 100000;
+
+            var args = new double[count];
+            var rand = new Random();
+
+            for (int i = 0; i < count; i++)
+                args[i] = rand.NextDouble();
+
+            var t = Environment.TickCount;
+            var res = args.ParallelMap(x => Math.Sin(x*x), 4).Join();
+
+            Console.WriteLine("Map complete in {0} ms", Environment.TickCount - t);
+
+            t = Environment.TickCount;
+            for (int i = 0; i < count; i++)
+                Assert.AreEqual(Math.Sin(args[i] * args[i]), res[i]);
+            Console.WriteLine("Verified in {0} ms", Environment.TickCount - t);
+        }
+
+        [TestMethod]
+        public void ChainedMapTest() {
+
+            using (var pool = new WorkerPool(0,100,100)) {
+                const int count = 10000;
+
+                var args = new double[count];
+                var rand = new Random();
+
+                for (int i = 0; i < count; i++)
+                    args[i] = rand.NextDouble();
+
+                var t = Environment.TickCount;
+                var res = args
+                    .ChainedMap(
+                        // Analysis disable once AccessToDisposedClosure
+                        x => pool.Invoke(
+                            () => Math.Sin(x * x)
+                        ),
+                        4
+                    )
+                    .Join();
+
+                Console.WriteLine("Map complete in {0} ms", Environment.TickCount - t);
+
+                t = Environment.TickCount;
+                for (int i = 0; i < count; i++)
+                    Assert.AreEqual(Math.Sin(args[i] * args[i]), res[i]);
+                Console.WriteLine("Verified in {0} ms", Environment.TickCount - t);
+                Console.WriteLine("Max workers: {0}", pool.MaxRunningThreads);
+            }
+        }
+
+        [TestMethod]
+        public void ParallelForEachTest() {
+
+            const int count = 100000;
+
+            var args = new int[count];
+            var rand = new Random();
+
+            for (int i = 0; i < count; i++)
+                args[i] = (int)(rand.NextDouble() * 100);
+
+            int result = 0;
+
+            var t = Environment.TickCount;
+            args.ParallelForEach(x => Interlocked.Add(ref result, x), 4).Join();
+
+            Console.WriteLine("Iteration complete in {0} ms, result: {1}", Environment.TickCount - t, result);
+
+            int result2 = 0;
+
+            t = Environment.TickCount;
+            for (int i = 0; i < count; i++)
+                result2 += args[i];
+            Assert.AreEqual(result2, result);
+            Console.WriteLine("Verified in {0} ms", Environment.TickCount - t);
+        }
+
+        [TestMethod]
+        public void ComplexCase1Test() {
+            var flags = new bool[3];
+
+            // op1 (aync 200ms) => op2 (async 200ms) => op3 (sync map)
+
+            var step1 = PromiseHelper
+                .Sleep(200, "Alan")
+                .Cancelled(() => flags[0] = true);
+            var p = step1
+                .Chain(x =>
+                    PromiseHelper
+                        .Sleep(200, "Hi, " + x)
+                        .Then(y => y)
+                        .Cancelled(() => flags[1] = true)
+                )
+                .Cancelled(() => flags[2] = true);
+            step1.Join();
+            p.Cancel();
+            try {
+                Assert.AreEqual(p.Join(), "Hi, Alan");
+                Assert.Fail("Shouldn't get here");
+            } catch (OperationCanceledException) {
+            }
+
+            Assert.IsFalse(flags[0]);
+            Assert.IsTrue(flags[1]);
+            Assert.IsTrue(flags[2]);
+        }
+
+        [TestMethod]
+        public void ChainedCancel1Test() {
+            // при отмене сцепленной асинхронной операции все обещание должно
+            // завершаться ошибкой OperationCanceledException
+            var p = PromiseHelper
+                .Sleep(1, "Hi, HAL!")
+                .Then(x => {
+                    // запускаем две асинхронные операции
+                    var result = PromiseHelper.Sleep(1000, "HEM ENABLED!!!");
+                    // вторая операция отменяет первую до завершения
+                    PromiseHelper
+                        .Sleep(100, "HAL, STOP!")
+                        .Then(result.Cancel);
+                    return result;
+                });
+            try {
+                p.Join();
+            } catch (TargetInvocationException err) {
+                Assert.IsTrue(err.InnerException is OperationCanceledException);
+            }
+        }
+
+        [TestMethod]
+        public void ChainedCancel2Test() {
+            // при отмене цепочки обещаний, вложенные операции также должны отменяться
+            var pSurvive = new Promise<bool>();
+            var hemStarted = new ManualResetEvent(false);
+            var p = PromiseHelper
+                .Sleep(1, "Hi, HAL!")
+                .Chain(x => {
+                    hemStarted.Set();
+                    // запускаем две асинхронные операции
+                    var result = PromiseHelper
+                        .Sleep(10000, "HEM ENABLED!!!")
+                        .Then(s => pSurvive.Resolve(false));
+
+                    result
+                        .Cancelled(() => pSurvive.Resolve(true));
+                    
+                    return result;
+                });
+
+            hemStarted.WaitOne();
+            p.Cancel();
+
+            try {
+                p.Join();
+            } catch (OperationCanceledException) {
+                Assert.IsTrue(pSurvive.Join());
+            }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab.Test/Implab.Test.mono.csproj	Thu Sep 11 10:56:14 2014 +0400
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{2BD05F84-E067-4B87-9477-FDC2676A21C6}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <RootNamespace>Implab.Test</RootNamespace>
+    <AssemblyName>Implab.Test</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;MONO</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+    <DefineConstants>MONO</DefineConstants>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug 4.5|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;TRACE;NET_4_5;MONO</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release 4.5|AnyCPU' ">
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <DefineConstants>NET_4_5;MONO</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="nunit.framework" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <Compile Include="AsyncTests.cs" />
+    <Compile Include="PromiseHelper.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Implab\Implab.csproj">
+      <Project>{F550F1F8-8746-4AD0-9614-855F4C4B7F05}</Project>
+      <Name>Implab</Name>
+    </ProjectReference>
+  </ItemGroup>
+</Project>
\ No newline at end of file
--- a/Implab.Test/PromiseHelper.cs	Wed Sep 10 17:53:05 2014 +0400
+++ b/Implab.Test/PromiseHelper.cs	Thu Sep 11 10:56:14 2014 +0400
@@ -1,12 +1,8 @@
 using Implab.Parallels;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
 using System.Threading;
 
 namespace Implab.Test {
-    class PromiseHelper {
+    static class PromiseHelper {
         public static IPromise<T> Sleep<T>(int timeout, T retVal) {
             return AsyncPool.Invoke(() => {
                 Thread.Sleep(timeout);
--- a/Implab.Test/Properties/AssemblyInfo.cs	Wed Sep 10 17:53:05 2014 +0400
+++ b/Implab.Test/Properties/AssemblyInfo.cs	Thu Sep 11 10:56:14 2014 +0400
@@ -31,5 +31,4 @@
 //
 // 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.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
+[assembly: AssemblyVersion("0.0.*")]
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab.mono.sln	Thu Sep 11 10:56:14 2014 +0400
@@ -0,0 +1,290 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab", "Implab\Implab.csproj", "{F550F1F8-8746-4AD0-9614-855F4C4B7F05}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{CE8D8D18-437A-445C-B662-4C2CE79A76F6}"
+	ProjectSection(SolutionItems) = preProject
+		Implab.vsmdi = Implab.vsmdi
+		Local.testsettings = Local.testsettings
+		TraceAndTestImpact.testsettings = TraceAndTestImpact.testsettings
+	EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx", "Implab.Fx\Implab.Fx.csproj", "{06E706F8-6881-43EB-927E-FFC503AF6ABC}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{BCA337C3-BFDC-4825-BBDB-E6D467E4E452}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Test.mono", "Implab.Test\Implab.Test.mono.csproj", "{2BD05F84-E067-4B87-9477-FDC2676A21C6}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implab.Fx.Test.mono", "Implab.Fx.Test\Implab.Fx.Test.mono.csproj", "{2BD05F84-E067-4B87-9477-FDC2676A21C6}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+		Debug 4.5|Any CPU = Debug 4.5|Any CPU
+		Release 4.5|Any CPU = Release 4.5|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
+		{06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
+		{06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{06E706F8-6881-43EB-927E-FFC503AF6ABC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
+		{06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
+		{06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{06E706F8-6881-43EB-927E-FFC503AF6ABC}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
+		{2F31E405-E267-4195-A05D-574093C21209}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
+		{2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{2F31E405-E267-4195-A05D-574093C21209}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
+		{2F31E405-E267-4195-A05D-574093C21209}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
+		{2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{2F31E405-E267-4195-A05D-574093C21209}.Release|Any CPU.Build.0 = Release|Any CPU
+		{63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
+		{63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
+		{63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
+		{63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
+		{63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{63F92C0C-61BF-48C0-A377-8D67C3C661D0}.Release|Any CPU.Build.0 = Release|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.ActiveCfg = Debug 4.5|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug 4.5|Any CPU.Build.0 = Debug 4.5|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.ActiveCfg = Release 4.5|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release 4.5|Any CPU.Build.0 = Release 4.5|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F550F1F8-8746-4AD0-9614-855F4C4B7F05}.Release|Any CPU.Build.0 = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(NestedProjects) = preSolution
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6} = {BCA337C3-BFDC-4825-BBDB-E6D467E4E452}
+		{2BD05F84-E067-4B87-9477-FDC2676A21C6} = {BCA337C3-BFDC-4825-BBDB-E6D467E4E452}
+	EndGlobalSection
+	GlobalSection(MonoDevelopProperties) = preSolution
+		StartupItem = Implab\Implab.csproj
+		Policies = $0
+		$0.CSharpFormattingPolicy = $1
+		$1.IndentSwitchBody = True
+		$1.NamespaceBraceStyle = EndOfLine
+		$1.ClassBraceStyle = EndOfLine
+		$1.InterfaceBraceStyle = EndOfLine
+		$1.StructBraceStyle = EndOfLine
+		$1.EnumBraceStyle = EndOfLine
+		$1.MethodBraceStyle = EndOfLine
+		$1.ConstructorBraceStyle = EndOfLine
+		$1.DestructorBraceStyle = EndOfLine
+		$1.BeforeMethodDeclarationParentheses = False
+		$1.BeforeMethodCallParentheses = False
+		$1.BeforeConstructorDeclarationParentheses = False
+		$1.NewLineBeforeConstructorInitializerColon = NewLine
+		$1.NewLineAfterConstructorInitializerColon = SameLine
+		$1.BeforeIndexerDeclarationBracket = False
+		$1.BeforeDelegateDeclarationParentheses = False
+		$1.NewParentheses = False
+		$1.SpacesBeforeBrackets = False
+		$1.inheritsSet = Mono
+		$1.inheritsScope = text/x-csharp
+		$1.scope = text/x-csharp
+		$0.TextStylePolicy = $2
+		$2.FileWidth = 120
+		$2.EolMarker = Unix
+		$2.inheritsSet = VisualStudio
+		$2.inheritsScope = text/plain
+		$2.scope = text/x-csharp
+		$0.DotNetNamingPolicy = $3
+		$3.DirectoryNamespaceAssociation = PrefixedHierarchical
+		$3.ResourceNamePolicy = MSBuild
+		$0.TextStylePolicy = $4
+		$4.FileWidth = 120
+		$4.TabsToSpaces = False
+		$4.inheritsSet = VisualStudio
+		$4.inheritsScope = text/plain
+		$4.scope = application/xml
+		$0.XmlFormattingPolicy = $5
+		$5.inheritsSet = Mono
+		$5.inheritsScope = application/xml
+		$5.scope = application/xml
+		$0.TextStylePolicy = $6
+		$6.FileWidth = 120
+		$6.TabsToSpaces = False
+		$6.inheritsSet = VisualStudio
+		$6.inheritsScope = text/plain
+		$6.scope = text/plain
+		$0.NameConventionPolicy = $7
+		$7.Rules = $8
+		$8.NamingRule = $9
+		$9.Name = Namespaces
+		$9.AffectedEntity = Namespace
+		$9.VisibilityMask = VisibilityMask
+		$9.NamingStyle = PascalCase
+		$9.IncludeInstanceMembers = True
+		$9.IncludeStaticEntities = True
+		$8.NamingRule = $10
+		$10.Name = Types
+		$10.AffectedEntity = Class, Struct, Enum, Delegate
+		$10.VisibilityMask = VisibilityMask
+		$10.NamingStyle = PascalCase
+		$10.IncludeInstanceMembers = True
+		$10.IncludeStaticEntities = True
+		$8.NamingRule = $11
+		$11.Name = Interfaces
+		$11.RequiredPrefixes = $12
+		$12.String = I
+		$11.AffectedEntity = Interface
+		$11.VisibilityMask = VisibilityMask
+		$11.NamingStyle = PascalCase
+		$11.IncludeInstanceMembers = True
+		$11.IncludeStaticEntities = True
+		$8.NamingRule = $13
+		$13.Name = Attributes
+		$13.RequiredSuffixes = $14
+		$14.String = Attribute
+		$13.AffectedEntity = CustomAttributes
+		$13.VisibilityMask = VisibilityMask
+		$13.NamingStyle = PascalCase
+		$13.IncludeInstanceMembers = True
+		$13.IncludeStaticEntities = True
+		$8.NamingRule = $15
+		$15.Name = Event Arguments
+		$15.RequiredSuffixes = $16
+		$16.String = EventArgs
+		$15.AffectedEntity = CustomEventArgs
+		$15.VisibilityMask = VisibilityMask
+		$15.NamingStyle = PascalCase
+		$15.IncludeInstanceMembers = True
+		$15.IncludeStaticEntities = True
+		$8.NamingRule = $17
+		$17.Name = Exceptions
+		$17.RequiredSuffixes = $18
+		$18.String = Exception
+		$17.AffectedEntity = CustomExceptions
+		$17.VisibilityMask = VisibilityMask
+		$17.NamingStyle = PascalCase
+		$17.IncludeInstanceMembers = True
+		$17.IncludeStaticEntities = True
+		$8.NamingRule = $19
+		$19.Name = Methods
+		$19.AffectedEntity = Methods
+		$19.VisibilityMask = VisibilityMask
+		$19.NamingStyle = PascalCase
+		$19.IncludeInstanceMembers = True
+		$19.IncludeStaticEntities = True
+		$8.NamingRule = $20
+		$20.Name = Static Readonly Fields
+		$20.AffectedEntity = ReadonlyField
+		$20.VisibilityMask = Internal, Protected, Public
+		$20.NamingStyle = PascalCase
+		$20.IncludeInstanceMembers = False
+		$20.IncludeStaticEntities = True
+		$8.NamingRule = $21
+		$21.Name = Fields (Non Private)
+		$21.AffectedEntity = Field
+		$21.VisibilityMask = Internal, Public
+		$21.NamingStyle = CamelCase
+		$21.IncludeInstanceMembers = True
+		$21.IncludeStaticEntities = True
+		$8.NamingRule = $22
+		$22.Name = ReadOnly Fields (Non Private)
+		$22.AffectedEntity = ReadonlyField
+		$22.VisibilityMask = Internal, Public
+		$22.NamingStyle = CamelCase
+		$22.IncludeInstanceMembers = True
+		$22.IncludeStaticEntities = False
+		$8.NamingRule = $23
+		$23.Name = Fields (Private)
+		$23.RequiredPrefixes = $24
+		$24.String = m_
+		$23.AffectedEntity = Field, ReadonlyField
+		$23.VisibilityMask = Private, Protected
+		$23.NamingStyle = CamelCase
+		$23.IncludeInstanceMembers = True
+		$23.IncludeStaticEntities = False
+		$8.NamingRule = $25
+		$25.Name = Static Fields (Private)
+		$25.RequiredPrefixes = $26
+		$26.String = _
+		$25.AffectedEntity = Field
+		$25.VisibilityMask = Private
+		$25.NamingStyle = CamelCase
+		$25.IncludeInstanceMembers = False
+		$25.IncludeStaticEntities = True
+		$8.NamingRule = $27
+		$27.Name = ReadOnly Fields (Private)
+		$27.RequiredPrefixes = $28
+		$28.String = m_
+		$27.AffectedEntity = ReadonlyField
+		$27.VisibilityMask = Private, Protected
+		$27.NamingStyle = CamelCase
+		$27.IncludeInstanceMembers = True
+		$27.IncludeStaticEntities = False
+		$8.NamingRule = $29
+		$29.Name = Constant Fields
+		$29.AffectedEntity = ConstantField
+		$29.VisibilityMask = VisibilityMask
+		$29.NamingStyle = AllUpper
+		$29.IncludeInstanceMembers = True
+		$29.IncludeStaticEntities = True
+		$8.NamingRule = $30
+		$30.Name = Properties
+		$30.AffectedEntity = Property
+		$30.VisibilityMask = VisibilityMask
+		$30.NamingStyle = PascalCase
+		$30.IncludeInstanceMembers = True
+		$30.IncludeStaticEntities = True
+		$8.NamingRule = $31
+		$31.Name = Events
+		$31.AffectedEntity = Event
+		$31.VisibilityMask = VisibilityMask
+		$31.NamingStyle = PascalCase
+		$31.IncludeInstanceMembers = True
+		$31.IncludeStaticEntities = True
+		$8.NamingRule = $32
+		$32.Name = Enum Members
+		$32.AffectedEntity = EnumMember
+		$32.VisibilityMask = VisibilityMask
+		$32.NamingStyle = PascalCase
+		$32.IncludeInstanceMembers = True
+		$32.IncludeStaticEntities = True
+		$8.NamingRule = $33
+		$33.Name = Parameters
+		$33.AffectedEntity = Parameter, LocalVariable
+		$33.VisibilityMask = VisibilityMask
+		$33.NamingStyle = CamelCase
+		$33.IncludeInstanceMembers = True
+		$33.IncludeStaticEntities = True
+		$8.NamingRule = $34
+		$34.Name = Type Parameters
+		$34.RequiredPrefixes = $35
+		$35.String = T
+		$34.AffectedEntity = TypeParameter
+		$34.VisibilityMask = VisibilityMask
+		$34.NamingStyle = PascalCase
+		$34.IncludeInstanceMembers = True
+		$34.IncludeStaticEntities = True
+	EndGlobalSection
+	GlobalSection(TestCaseManagementSettings) = postSolution
+		CategoryFile = Implab.vsmdi
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal