.net, Computer Vision, UWP, Visual Studio, Windows Store Apps

How to use the camera on your device with C# in a UWP application: Part #2, how to focus the preview

In the previous part of the series, we looked at how to preview your device’s camera output.

This part is about how to focus the device using C#. Not all devices will be capable of focussing – for example, a normal laptop webcam won’t be able to focus, but a Nokia 1520 can focus. Fortunately, we don’t need to guess – testing support for focussing is part of the API provided for Windows UWP apps. We can test this by using the “_mediaCapture” object, which we created in the code shown in Part #1.

if (_mediaCapture.VideoDeviceController.FocusControl.Supported)
    // Code here is executed if focus is supported by the device.

On my phone,  I’d like to use the camera button when it’s half-pressed to focus the image. I’m able to do this in a UWP app, but I need to add a reference to a UWP library first first.

Setting up mobile extension references

In the solution view in VS2015, right click on the “References” node, and select “Add Reference…”.


The window that appears is called the “Reference Manager”. On the left hand menu, expand the “Universal Windows” node, and select “Extensions”. In the list of extensions, tick the box for “Windows Mobile Extensions for the UWP”. Now click OK.


Testing for hardware buttons on the device, and handling events

Obviously enough, we’ve now added a reference to a library which allows you to test for the availability of certain sensors which are specific to a mobile device, such as the hardware button used to take a picture.

if (ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
    // This code will only run if the HardwareButtons type is present.

The Camera button has three events – CameraPressed, CameraHalfPressed, and CameraReleased. I’m interested in intercepting the CameraHalfPressed event for focussing, so I’ve assigned the event handler in the code below, and put this in the constructor for the MainPage class.

if (ApiInformation.IsTypePresent("Windows.Phone.UI.Input.HardwareButtons"))
    HardwareButtons.CameraHalfPressed += HardwareButtons_CameraHalfPressed;

The event handler is shown below, including the snippet of code to test if focussing is supported.

private void HardwareButtons_CameraHalfPressed(object sender, CameraEventArgs e)
    if (_mediaCapture.VideoDeviceController.FocusControl.Supported)
        // Focussing code is here.

Focus range and focus mode

To focus the camera device, I need to configure the focus control of the _mediaCapture object – this means getting the focus mode and focus range. We can get the supported ranges and modes from the focus control object, and then assign these as settings. Finally, we need to call the asynchronous focus method. The code below shows how this works.

private async void HardwareButtons_CameraHalfPressed(object sender, CameraEventArgs e)
    // test if focus is supported
    if (_mediaCapture.VideoDeviceController.FocusControl.Supported)
        // Get the focus control from the _mediaCapture object.
        var focusControl = _mediaCapture.VideoDeviceController.FocusControl;
        // Try to get full range autofocus, but settle for the first supported range.
        var focusRange = focusControl.SupportedFocusRanges.Contains(AutoFocusRange.FullRange) ? AutoFocusRange.FullRange : focusControl.SupportedFocusRanges.FirstOrDefault();
        // Try to get the focus mode for focussing just once, but settle for the first supported one.
        var focusMode = focusControl.SupportedFocusModes.Contains(FocusMode.Single) ? FocusMode.Single : focusControl.SupportedFocusModes.FirstOrDefault();
        // Now configure the focus control with the range and mode as settings.
            new FocusSettings
                Mode = focusMode,
                AutoFocusRange = focusRange
        // Finally wait for the camera to focus.
        await focusControl.FocusAsync();

So again, only a few lines of code are needed to register a button press event, and then configure the focus control. Hopefully this helps someone trying to set up focussing.

In the next part, I’ll look at how to change our code to actually capture an image when we fully press the camera button.

.net, Computer Vision, UWP, Visual Studio

How to use the camera on your device with C# in a UWP application: Part #1, previewing the output

I’ve recently started writing some UWP applications, and I am really enjoying learning the challenges of WPF and app programming (admittedly I’ve come to the party pretty late on this).

I’ve decided to write a short series of posts on how to use the camera on Windows devices – my plan is to write articles covering:

  1. Previewing the camera output to the device’s screen;
  2. Adding the ability to focus;
  3. Allowing the user to capture an image;
  4. And finally add error handling and resource clean-up.

This first part will just be about writing an app that will preview the device’s camera output to the device’s screen.

Since I’m adding error handling in the final part of the series, this first part will assume that the device running this code has a camera connected.

Note: This series is meant to use the absolute minimum number of lines of code necessary. For much more functional samples, check out the sample UWP code released by Microsoft to Github.

Step 1: Create the project and set capabilities

In VS2015, create a new Windows 10 UWP “Blank App” project.


Once the project has been created, you need to open the Package.appmanifest file (which was created as part of the Blank App), and click on the Capabilities tab. You need to tick boxes for:

  • Microphone
  • Webcam

It took me a little while to understand why the microphone would be required because you don’t need the microphone to take a picture. The reason is that the camera on the device is actually a video recorder (which records sound and images) – in order to use this device in code, you need access to both hardware features.

Step 2: Add the XAML control to preview the camera output

The CaptureElement control renders a stream from a capture device, such as a device camera or a webcam. We need to add one of these controls to the MainPage.xaml file.

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
    <CaptureElement Name="PreviewControl" Stretch="Uniform"/>

Step 3: Create a private asynchronous method to initialise the camera

This is where the main part of the application lives.

We need a member variable (a class property would be fine as well) – the MediaCapture control to allows us to see a preview of what the camera sees in the CaptureElement (and later, we’ll use this to capture the photograph).

// Provides functionality to preview and capture the photograph
private MediaCapture _mediaCapture;

We’ll need to initialise the camera asynchronously a few times, so we need a method to repeat this process:

  1. First this method needs to test if instantiation of the camera has already happened (specifically initialisation of the MediaCapture object) . If it hasn’t been initialised, then we need to go through the process.
  2. Next, we need to get a reference to the actual camera device. We’d prefer a back facing camera (usually the case for a phone) – but since this is a UWP and might run on a desktop as well, it’s possible that a back facing camera doesn’t exist. In that case, we’ll just take a reference to whatever the first camera device is.
  3. Once we have the camera, we’ll initialise the MediaCapture object, and initialise it by telling it the camera device identifier that we want it to use.
  4. Almost done – we’ll set the MediaCapture object to be the source of the CaptureElement object added to the Xaml earlier.
  5. Finally, tell the MediaCapture object to allow us to start previewing through the CaptureElement object.
private async Task InitializeCameraAsync()
    if (_mediaCapture == null)
        // Get the camera devices
        var cameraDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
        // try to get the back facing device for a phone
        var backFacingDevice = cameraDevices
            .FirstOrDefault(c => c.EnclosureLocation?.Panel == Windows.Devices.Enumeration.Panel.Back);
        // but if that doesn't exist, take the first camera device available
        var preferredDevice = backFacingDevice ?? cameraDevices.FirstOrDefault();
        // Create MediaCapture
        _mediaCapture = new MediaCapture();
        // Initialize MediaCapture and settings
        await _mediaCapture.InitializeAsync(
            new MediaCaptureInitializationSettings {
                VideoDeviceId = preferredDevice.Id
        // Set the preview source for the CaptureElement
        PreviewControl.Source = _mediaCapture;
        // Start viewing through the CaptureElement 
        await _mediaCapture.StartPreviewAsync();

This is pretty much the most complicated part.

Step 4. Register and override app events

We need to capture when the application is starting and suspending to carry out initialisation actions.

We can register one of these events in the MainPage constructor.

public MainPage()
    Application.Current.Resuming += Application_Resuming;

Additionally, we need to override the events when we navigate to the application – the code below shows the methods that handle each of the two events.

private async void Application_Resuming(object sender, object o)
    await InitializeCameraAsync();
protected override async void OnNavigatedTo(NavigationEventArgs e)
    await InitializeCameraAsync();


So that’s it – just a few lines of code to display what the camera views on your device. In summary:

  1. Create an app and set the capabilities to microphone and webcam;
  2. Add a CaptureElement to the app’s Xaml;
  3. Add the code to initialise and start previewing the camera’s view through the CaptureElement.

Remember that this isn’t code that’s good enough to be used in a production app – there’s no error handling or resource clean-up yet, and it doesn’t really do anything (like focus or record a picture).

The code I used to complete this part of the series is shown below:

public sealed partial class MainPage : Page
    // Provides functionality to capture the output from the camera
    private MediaCapture _mediaCapture;
    public MainPage()
        Application.Current.Resuming += Application_Resuming;
    private async void Application_Resuming(object sender, object o)
        await InitializeCameraAsync();
    protected override async void OnNavigatedTo(NavigationEventArgs e)
        await InitializeCameraAsync();

    private async Task InitializeCameraAsync()
        if (_mediaCapture == null)
            // Get the camera devices
            var cameraDevices = await DeviceInformation.FindAllAsync(DeviceClass.VideoCapture);
            // try to get the back facing device for a phone
            var backFacingDevice = cameraDevices
                .FirstOrDefault(c => c.EnclosureLocation?.Panel == Windows.Devices.Enumeration.Panel.Back);
            // but if that doesn't exist, take the first camera device available
            var preferredDevice = backFacingDevice ?? cameraDevices.FirstOrDefault();
            // Create MediaCapture
            _mediaCapture = new MediaCapture();
            // Initialize MediaCapture and settings
            await _mediaCapture.InitializeAsync(
                new MediaCaptureInitializationSettings {
                    VideoDeviceId = preferredDevice.Id
            // Set the preview source for the CaptureElement
            PreviewControl.Source = _mediaCapture;
            // Start viewing through the CaptureElement 
            await _mediaCapture.StartPreviewAsync();

Next time in this series, I’ll look at how to test if the camera is capable of focussing, and if so, how to make it focus.

.net, Accessibility, Non-functional Requirements, Visual Studio, Visual Studio Plugin, Web Development

How to use the Web Accessibility Checker for Visual Studio to help conform to accessibility guidelines

I’ve previously blogged about assessibility a few times and I’d love to find a good way to identify accessibility issues from my development environment. So I was really interested to see that recently Mads Kristensen from Microsoft released the Web Accessibility Checker for Visual Studio 2015. This extension uses the aXe-core library for analysing code in Visual Studio.

The Visual Studio Gallery gives some good instructions on how to install and use this extension. It’s a pretty straightforward install – once you run your website, a list of non-conformances will appear in the Error List in VS 2015 (to see the Error List, go to the View Menu and select Error List from there).

Obviously this can’t identify every accessibility problem on your site, so fixing all the errors on this list isn’t going to guarantee your website is accessible. But one of the manifesto items from aXe-core’s github page states the tool aims to report zero false positives – so if aXe-core is raising an error, it’s worth investigating.

Let’s look at an example.

How does it report errors?

I’ve written some HTML code and pasted it below…ok, it’s some pretty ropey HTML code, with some really obvious accessibility issues.

<!DOCTYPE html>
        This is simple text on a page.
        Here's a picture:
        <br />
        <img src="/image.png" />
        <br />
        And here's a button:
        <br />


Let’s see what the Web Accessibility Checker picks up:


Four errors are reported:

  • No language attribute is specified in the HTML element. This is pretty easy to fix – I’ve blogged about this before;
  • The <button> element has no text inside it;
  • The page has no <title> element.
  • The image does not have an alternative text attribute.

Note – these errors are first reported at the application runtime, don’t expect to see them when your writing your code, or just after compiling it.

If you want to discover more about any of these errors, the Error List has a column called “Code”, and clicking the text will take you to an explanation of what the problem is.

In addition, you can just double click on the description, and the VS editor focus will move to the line of code where the issue is.

I’ve corrected some of the errors – why are they still in the Error List?

I found that the errors stayed in the list, even after starting to fix the issues. In order to clear the errors away, I found that I needed to right click on the Error List, and from the context menu select “Clear All Accessibility Errors”.


When I hit refresh on my browser, and I was able to see the remaining issues without it showing the ones that I had fixed.

What more does this give me when compared to some of the existing accessibility tools?

Previously I’ve used tools like the HTML_CodeSniffer bookmarklet, which also report accessibility errors.


This is a great tool, but it will only point to the issues on the web page – the Web Accessibility Checker in VS2015 has the advantage of taking your cursor straight to the line of source code with the issue.


Obviously you can’t completely test if a website is accessible using automated tools. But you can definitely use tools to check if certain rules are being adhered to in your code. Tools like the Web Accessibility Checker for VS2015 help you identify and locate accessibility issues in your code – and when it’s free, there’s no reason not use it in your web application development process today.

.net, Visual Studio

Some useful links from the first /Build2016 sessions

I’m not at /Build2016 this year – but my timezone allows me to get home at 5pm BST and I can pick up some of the sessions live on my PC at home – I can also pick up the videos from here.

The keynote intro was obviously by Satya Nadella – but it also had Marcus Ash talking about Cortana, Lilian Rincon talking about the Skype Developer SDK, Dan Driscoll and Lili Cheng talking about Bot Development, Alex Kipman and Kudo Tsunoda talking about Hololens Development, and Saqib Shaikh talking about Cognitive Services (I hope I didn’t forget anyone here). I think the big message from Nadella was that all of the services showcased were intended to augment our existing abilities – to make us more than we already are.

Here are some links to the new technologies and APIs. I haven’t tried all of these yet! But hopefully there’ll be inspiration in here for some future posts on this site.


Here’s Alex Kipman and Kudo Tsunoda talking about the HoloLens.

If your computer is good enough, you run the tools needed for development and grab them from here:


You’ll need:

And you can try the sample Hololens Galaxy Explorer application, which is on GitHub here:


Cortana Intelligence Suite


A big data and analytics suite: Cortana Intelligence Suite

Follow this on Twitter here: https://twitter.com/MSAdvAnalytics

Cognitive Services

Read more about the cognitive services and pricing here:



Try a fun sample here to try to work out what’s in a photo:


And you can get source code for cognitive services:


Bot Development, Skype and CRIS

Here’s an article which explains all about it. http://mspoweruser.com/microsoft-introduces-bot-framework/


Find more about the bot framework here: https://dev.botframework.com/

And sign up for the Skype Developer SDK here: https://www.skype.com/en/developer/

You can get the code from GitHub here: https://github.com/Microsoft/BotBuilder

And here’s CRIS – Custom Recognition Intelligence Service: https://www.cris.ai/

And some of the rest…

Visual Studio 2015 Update 2 and Visual Studio “15”




Bash on Windows




Convert Win32 applications to UWP





.net, C# tip, nuget, Visual Studio, Visual Studio Plugin

What’s the link between C# 6.0 language specifications, .NET Frameworks and Visual Studios?

My current work project uses the .NET framework v4.5, and we’re developing using Visual Studio 2013. I’ve been reading about the new language features of C# 6.0 for a while, and I’m really interested in finding a way to use them.

I used Bing/Google to identify what the new language features are, read some blogs and fired up my personal copy of Visual Studio 2015 to try out a few examples. The one I was really interested in was Primary Constructors, but there were a list of new features I wanted to try:

  • Primary Constructors
  • Import of static type members into namespace
  • Auto property initializers
  • Default values for getter-only properties
  • String interpolation
  • nameof operator
  • Dictionary initializer
  • Null propagator

This isn’t a comprehensive list of the new features, they’re just the ones that I think I would use most in my day-to-day coding.

The first feature I decided to try was creating a Primary Constructor…but when I wrote the code in VS2015 and .NET 4.6, it showed the dreaded red squiggly line and didn’t compile. What went wrong?

After some more research, I found that the Primary Constructor feature has been removed (at least temporarily). So those articles (for example, this one) showing me how to do this are, for now, wrong.

This made me sit back and think a bit more.

  • When I look at the dropdown list of available .NET frameworks in Visual Studio 2015, there’s quite a few (at least in my system). Which one should I be using to compile C# 6.0 language features?
  • And what does C# 6.0 actually mean? Should I be assuming that .NET Framework 4.6 necessarily corresponds to C# 6.0?
  • Can I make Visual Studio 2013 compile code written using C# 6.0 language features?
  • And where does Roslyn fit into all of this?

Some Sample Code for C# language features

I wrote a simple class which contains each of the C# 6.0 features that I listed above (except Primary Constructors, obviously). It’s a bit of a silly example, but hopefully it illustrates the point. I’ve commented each of the features, and put some of the most relevant code in bold font.

namespace CSharp6SampleApplication
    using System;
    using System.Collections.Generic;
    using static System.Console;

    public class SuperCar
        // Dictionary initializer
        private static readonly Dictionary<string, DateTime> _specialDates =
            new Dictionary<string, DateTime>
                ["past"] = new DateTime(1985, 10, 26),
                ["current"] = new DateTime(1985, 11, 5),
                ["future"] = new DateTime(2015, 10, 21)

        // Auto property initializers
        public string Manufacturer { get; set; } = "DeLorean";

        // Auto property initializers
        public int TopSpeed { get; set; } = 88;

        // Default values for getter-only properties - no need to specify a private setter;
        public double Power { get; }

        public Engine Engine { get; set; }

        public SuperCar()
            // Default values for getter-only properties - possible to set in the constructor only
            Power = 1.21;

        public override string ToString()
            // String interpolation
            return $"Made by {Manufacturer}, Top Speed = {TopSpeed}";

    public class Engine
        public string Manufacturer { get; set; }

        public bool IsEfficient(string engineType)
            // nameof operator
            if (engineType == null)
                throw new ArgumentNullException(nameof(engineType));

            if (engineType == "Mr. Fusion")
                return true;

            return false;

    class Program
        static void Main(string[] args)
            var car = new SuperCar();

            // Import of static type members into namespace

            // Null propagator
            WriteLine(car.Engine?.Manufacturer ?? "No engine type specified yet");

How it works

There’s a difference between a language specification and the version of the framework that supports it.

C# 6.0 is a language specification that is supported by the Roslyn compiler for the .NET platform. This compiler ships by default with Visual Studio 2015 – however, Roslyn doesn’t ship with Visual Studio 2013 (obviously, because this came out before Roslyn).

So all of the above code will compile and works out of the box in Visual Studio 2015, and it works for .NET framework versions 2.0, 3, 3.5, 4, 4.5, 4.5.1, 4.5.2, and 4.6 (I just haven’t included version 1.0 and 1.1 because I don’t have them installed on my machine). It doesn’t matter about the framework – it’s the compiler that matters.

Can it work in VS2013?

I think the answer to this is “partly but not really”.

When I try the above code in VS2013, the environment looks like the screenshot below, with more of the red-squiggly lines and a bunch of compiler errors.


But it’s possible to compile C# 6.0 features with Visual Studio 2013 – you just need to install a nuget package. Run the code below from the package manager console.

Install-Package Microsoft.Net.Compilers -Version 1.1.1

This will now compile, but the VS2013 development environment still thinks there’s a problem – it leaves the red squiggly lines and reports the errors in the Error List window. This is because Visual Studio 2013’s real-time compiler hasn’t been replaced, and the development environment doesn’t understand the new language features. So this isn’t really a long term workable solution to develop in VS2013 with C# 6.0 language features. But you can make the code compile if you need to.

.net, Clean Code, Visual Studio, Visual Studio Plugin

VS2013 Extension (#3) – Clean your imported namespaces with Productivity Power Tools

This entry in the ‘Visual Studio Extension’ series is not really going to cover all the power tools in the Productivity Power Tools suite (which you can get here). I might blog about some of these later, but today I just want to cover what I think is a hidden gem in the suite which just doesn’t seem to get enough exposure.

Oftentimes when you inherit a legacy code-base that hasn’t been shown the love/technical review it deserved, each class header will looks something like this:

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Runtime.InteropServices;
using System.Web.Mvc;
using System.Web.Mvc.Html;
using System.Linq;
using System.IO;
using Microsoft.Web.Infrastructure;
using System.Web.Mvc.Html;
using Newtonsoft.Json;

How many of these are really used?
And how many were made redundant when during refactoring?
And why are they out of order?

Ok, it’s fair to comment ‘what’s the big deal’ – they aren’t doing any harm, and when you compile the code they are removed anyway. But these unused imports are actually a big bugbear of mine.

  • If you don’t need to import some namespaces, they shouldn’t be there
  • It looks sloppy
  • It hides whether your class is obeying the Single Responsibility Principle – meaning if you’re importing lots and lots of namespaces, your class is probably doing more than one kind of thing
  • It’s so easy to fix, especially with the power tools extension.

Obviously in the usual Visual Studio IDE, you can right click on each class and fix them individually with the “Remove and Sort Usings” context command.

But why do this when you can do it at a project level, and do it for every class in the project?

And once you’ve cleaned your legacy project up, you can configure your settings so that every time you save, it cleans it up for you automatically!

You can read the Visual Studio team’s blog entry announcing this extension here.

You can watch the Channel 9 introduction to using the extension here.

.net, Unit Testing, Visual Studio, Visual Studio Plugin, xUnit

VS2013 Extension (#2) – Xunit Test Runner (plus a few issues)

Normally I use NUnit to create my unit tests.  But after looking through the ASP.net core source code for vNext, I noticed that Microsoft are now using Xunit as their unit testing tool. I’d like to follow Microsoft coding standards and practices as much as possible, so I decided to try out a move from NUnit to Xunit.

Changing the Syntax

First, the [TestFixture] decoration is no longer needed – you don’t need to decorate your test classes. This is pretty nice – I can’t think of a good reason why I should be sorry this isn’t in Xunit.

But now you don’t use [Test] as the decoration for your unit tests – these are now decorated with [Fact]. This blog gives a good explanation of the arguments for and against the revised terminology – it comes down firmly on the side of staying with [Test], but it does present the Xunit team’s reasons for the change as well.

I don’t tend to use [Setup] or [Teardown], which is lucky, because they’re not in Xunit. There are few options if you really need an equivalent – the constructor to set things up, IDispoable implementation to tear things down, and the IUseTestFixture interface which allows you to pass in a data from a your custom type and process it.

Finally, the Assert method names have changed slightly. So, for example, rather than IsTrue from NUnit, the Xunit method is just True. You can read a full list of changes here, and most of the changes are pretty intuitive.

But I did find a few wrinkles in the transition – this might be issues with my particular set up, but I’ll document them in case it helps anyone else.

Running Xunit Tests through VS2013 Test Explorer

Installing Xunit using Nuget was simple – however, I wasn’t able to run the tests out of the box in VS2013. After some searching, I found this link which correctly told me I needed to use a test runner extension. But the details on that site are now out of date so don’t install the VS2013 extension.

The preferred solution is to install the Xunit runner as a Nuget package.  I found another issue here – when I tried to install this through the Nuget tool in Visual Studio, nothing (observable) happened. I certainly didn’t see any of my unit tests appearing in the built-in VS2013 Test Explorer.  Eventually the steps I took to get this to work were:

1. Make sure that the tests are in a project which has been created using the built in “Unit Test Project” template.

2. Install the runner through the Nuget Package Manager Console, with the command:

Install-Package xunit.runner.visualstudio -Pre

After doing these things, I saw my Xunit tests appearing in the VS2013 Text Explorer.

In case the package comes out of pre-release mode, here’s the direct link to Nuget so you can get the most recent information.

Running Xunit Tests through JetBrains dotCover v2.6

I’ve got dotCover v2.6 installed on my development machine, and it can’t see any Xunit tests. Ok – this version is a bit old now, but this is a big problem for me and really makes me want to go back to NUnit or MSTest. I’ve read some posts on xunitcontrib, but this is only up to v2.5 of dotCover. I’ve also read some posts saying that Xunit support comes with an extension from the Nuget gallery – but presently the gallery URL which is supplied with dotCover v2.6 is returning a 404 error.

So presently this is not working for me.

[Update: After writing this post, I contacted JetBrains and they got right back to me to say they had addressed the 404 issue from above. So now I can download the Xunit extension to allow dotCover 2.6 see my Xunit tests.]

(I should say I’ve also tried it with dotCover v3 and it works fine out of the box).

Final Thoughts

I don’t have any compelling reason to switch to Xunit right now. I agree with the Xunit team’s reasons for not implementing [Setup]/[Teardown], but I’m able to replicate that omission in NUnit by just not using that feature.

If I need/choose to switch to Xunit at some point, I think it’ll be trivial to change.

Primarily the reason why I’m staying with NUnit is economic – I’m licensed to use dotCover v2.6 and NUnit just works. I don’t want to pay for an expensive upgrade (just yet anyway, and ReSharper Ultimate looks great).

[Update – as mentioned above, with a little help from JetBrains, I’ve managed to get dotCover v2.6 to work with Xunit. So this has reduced a major barrier for me to the move across to Xunit.

So my updated conclusion is that for new projects, I will give Xunit another try, but I’m not going to retrospectively re-factor stable and mature tests written using the NUnit framework.]