IMAPTalk 2 (final) Released

The final version of IMAPTalk 2 has finally been released. This version is mostly the same as the beta 3 release from last week. IMAPTalk 2 had been in beta since October, allowing ample time for testing.

The IMAPTalk page has also been updated to reflect the new version. Some older downloads, instructions and screenshots from the early versions have been removed. Go there to download the latest version!

Remember that since beta 3, IMAPTalk can be used for manual interaction with Redis servers. I am planning some new tools (for upcoming releases) that should be useful when using IMAPTalk for Redis.

A Framework for Application Settings

It is a very common practice to store settings in config keys within the AppSettings section of an App.config file. These settings then need to be read and converted to the appropriate type. One must also take care to cater for situations where the key is not found, or the value is invalid. This article provides a structured approach to this practice. Feel free to review and use the accompanying source code.

Update 2015-02-28: I made a minor improvement to ReadAsync() suggested by Stephen Cleary, who I thank for the code review.

Update 2015-03-03: Some people have asked why we actually need AppSettings any more, given that there are alternatives such as .NET Settings or custom configuration sections. They are correct. However I still see a lot of projects using AppSettings, and this article is intended to provide a better way to deal with those AppSettings.

Update 2015-11-12: If you want to use this in your own code, check out my .NET Settings Framework project which is based on this article and provides NuGet packages that you can just drop into your projects.

The Problem

I’ve seen a lot of production code that reads values from config keys in App.config that looks something like this:

            // set a default, just in case the key is not found or the conversion fails

            int timeout = 3000;

            // retrieve the value for the desired key

            string timeoutStr = ConfigurationManager.AppSettings["timeoutInMilliseconds"];

            // check whether the key was actually found; if not, the default value is retained

            if (timeoutStr != null)
            {
                // attempt to convert to the desired type
                //   -> if it succeeds, the default value is replaced with the retrieved value
                //   -> if it fails, the default value is retained

                bool converted = int.TryParse(timeoutStr, out timeout);
            }

Aside from the bloat due to comments and braces (which were both necessary to make this example clear), you can see that we essentially have four lines of code just to read an integer setting from App.config.

What’s really bad is that there will essentially be four lines of code for every setting, all doing essentially the same thing for different settings. That isn’t very DRY.

A Basic Solution

One of my earlier attempts at solving this problem involved a utility class which took care of reading the settings and converting them to the appropriate type, using a specific method per type:

    public class ConfigKey
    {
        private string key;

        public ConfigKey(string key)
        {
            this.key = key;
        }

        public int GetAsInt(int defaultValue = 0)
        {
            int value = defaultValue;

            string valueStr = ConfigurationManager.AppSettings[this.key];

            if (valueStr != null)
            {
                bool converted = int.TryParse(valueStr, out value);
            }

            return value;
        }

        public bool GetAsBool(bool defaultValue = false)
        {
            bool value = defaultValue;

            string valueStr = ConfigurationManager.AppSettings[this.key];

            if (valueStr != null)
            {
                bool converted = bool.TryParse(valueStr, out value);
            }

            return value;
        }

        // ...
    }

This approach was pretty decent, as it made it very easy to read settings and specify optional default values:

            int timeout = new ConfigKey("timeoutInMilliseconds").GetAsInt(3000);
            bool enabled = new ConfigKey("enabled").GetAsBool(false);

The only problem with this class is that while removes the bloat and duplication from the actual logic, it is full of duplication itself: you need a method per type to perform the type-specific conversion.

A Generic Approach

The duplication in the ConfigKey class is solved by using a generic conversion method:

        public T Get<T>(T defaultValue = default(T)) where T : IConvertible
        {
            T value = defaultValue;

            string valueStr = ConfigurationManager.AppSettings[this.key];

            if (valueStr != null)
            {
                try
                {
                    value = (T)Convert.ChangeType(valueStr, typeof(T));
                }
                catch(Exception)
                {
                    return defaultValue;
                }
            }

            return value;
        }

The usage changes as follows:

            int timeout = new ConfigKey("timeoutInMilliseconds").Get<int>(3000);
            bool enabled = new ConfigKey("enabled").Get<bool>(false);

That’s good enough for reading settings from App.config.

Dependency injection

In order to unit test our ConfigKey class, it’s best if we abstract out the dependency on App.config. In particular, we want to separate the part that reads the settings (reader) from the part that does the conversion and returns the value (provider).

For this, we need two interfaces. First, IConfigKeyReader is responsible to read the value of a setting from a source (e.g. App.config):

    public interface IConfigKeyReader
    {
        string Read(string key);
    }

Secondly, IConfigKeyProvider does all the rest: given a key, it returns a value (by internally using the IConfigKeyReader, which is not immediately evident from the interface):

    public interface IConfigKeyProvider
    {
        T Get<T>(string key, T defaultValue = default(T)) where T : IConvertible;
    }

The IConfigKeyReader implementation for reading from App.config is extremely simple:

    public class AppSettingReader : IConfigKeyReader
    {
        public string Read(string key)
        {
            return ConfigurationManager.AppSettings[key];
        }
    }

The IConfigKeyProvider for App.config settings is almost the same as the code we had in the previous section, with one important exception: it no longer depends directly on ConfigurationManager. Instead, it depends on the IConfigKeyReader which is injected in the constructor. This reader can be mocked in unit tests.

    public class ConfigKeyProvider: IConfigKeyProvider
    {
        private IConfigKeyReader reader;

        public ConfigKeyProvider(IConfigKeyReader reader)
        {
            this.reader = reader;
        }

        public T Get<T>(string key, T defaultValue = default(T)) where T : IConvertible
        {
            T value = defaultValue;

            string valueStr = reader.Read(key);

            if (valueStr != null)
            {
                try
                {
                    value = (T)Convert.ChangeType(valueStr, typeof(T));
                }
                catch (Exception)
                {
                    return defaultValue;
                }
            }

            return value;
        }
    }

You’ll also notice that we can now use a single instance of this AppSettingProvider to retrieve all our settings, rather than create a different ConfigKey for each setting. This approach is pretty handy if you’re using an IoC container to inject utility classes into your class constructors.

At this point we can throw away our old ConfigKey class, and instead use the new classes as follows:

            var reader = new AppSettingReader();
            var provider = new ConfigKeyProvider(reader);

            int timeout = provider.Get<int>("timeoutInMilliseconds", 3000);
            bool enabled = provider.Get<bool>("enabled", false);

Unit tests

Thanks to the separation between reader and provider, it is now easy to unit test our provider code while mocking our reader code. The reader will be source-specific and depends on external factors (e.g. files or databases) so it doesn’t make sense to unit test that. But we can unit test our provider, which handles the conversion and default values, and which will be reused whatever the reader (in fact notice the names used in the code above: AppSettingReader is specific to App.config AppSettings, but ConfigKeyProvider is used for any config key).

In the example unit test below, I’m using Moq to create a mock IConfigKeyReader, and thus test that the provider code works as expected:

        [TestMethod]
        public void Get_IntAvailableWithDefault_ValueReturned()
        {
            // arrange

            var key = "timeoutInMilliseconds";

            var reader = new Mock<IConfigKeyReader>();
            reader.Setup(r => r.Read(key)).Returns("5000");

            var provider = new ConfigKeyProvider(reader.Object);

            // act

            var expected = 5000;
            var actual = provider.Get<int>(key, 3000);

            // assert

            Assert.AreEqual(expected, actual);
        }

For the sake of brevity I won’t include the other unit tests here, but you can find them in the source code accompanying this article.

Database settings

The separation between reader and provider that we achieved in the previous section means that we can reuse the provider code (responsible for conversion and default values) regardless of the source of the settings. This means that anyone can write, for example, a DbSettingReader class which implements IConfigKeyReader and retrieves settings from a database. Its implementation would depend on the database structure so there won’t be any single standard implementation.

However, there is one improvement to our framework that we can make to facilitate reading settings from external sources such as databases. In particular, nowadays it is quite easy to query a database asynchronously without having to block the application. So it makes sense to add support for async methods in our interfaces so that anyone writing a DbSettingReader can then provide an asynchronous implementation.

IConfigKeyReader now becomes:

    public interface IConfigKeyReader
    {
        string Read(string key);

        Task<string> ReadAsync(string key);
    }

We now need to update our AppSettingReader implementation accordingly. Since reading AppSettings from App.config isn’t asynchronous, we can use Task.FromResult() to help satisfy the contract:

    public class AppSettingReader : IConfigKeyReader
    {
        public string Read(string key)
        {
            return ConfigurationManager.AppSettings[key];
        }

        public Task<string> ReadAsync(string key)
        {
            var value = this.Read(key);
            return Task.FromResult(value);
        }
    }

The provider code also needs to be updated to support asynchrony. First the interface:

    public interface IConfigKeyProvider
    {
        T Get<T>(string key, T defaultValue = default(T)) where T : IConvertible;

        Task<T> GetAsync<T>(string key, T defaultValue = default(T)) where T : IConvertible;
    }

The changes necessary to ConfigKeyProvider are a little more radical:

    public class ConfigKeyProvider : IConfigKeyProvider
    {
        private IConfigKeyReader reader;

        public ConfigKeyProvider(IConfigKeyReader reader)
        {
            this.reader = reader;
        }

        public T Get<T>(string key, T defaultValue = default(T)) where T : IConvertible
        {
            string valueStr = reader.Read(key);

            return this.ConvertValue<T>(valueStr, defaultValue);
        }

        public async Task<T> GetAsync<T>(string key, T defaultValue = default(T)) where T : IConvertible
        {
            string valueStr = await reader.ReadAsync(key).ConfigureAwait(false);

            return this.ConvertValue<T>(valueStr, defaultValue);
        }

        private T ConvertValue<T>(string valueStr, T defaultValue)
        {
            if (valueStr != null)
            {
                try
                {
                    return (T)Convert.ChangeType(valueStr, typeof(T));
                }
                catch (Exception)
                {
                    return defaultValue;
                }
            }
            else
                return defaultValue;
        }
    }

I opted to move the conversion code to a method shared by the async and non-async methods, and then call separate reader code in them. I intentionally avoided having Get() call GetAsync().Result as it can result in deadlocks.

Technically the best approach would have been to drop the synchronous Get() method altogether and force the use of the asynchronous version. However, I realise there are times when people actually want to call the synchronous version, such as in Console applications or in constructors (although there are workarounds for both – see Async Console Programs and “Can constructors be async?“).

Conclusion and Source Code

This article has presented a simple framework that can be used to read application settings without having to bloat actual program logic. It supports reading AppSettings from an App.config file out of the box, and can easily be extended to support other sources (e.g. databases). It makes it easy to provide default values, works nicely with dependency injection, and can also be used asynchronously.

Check out the source code at the Gigi Labs Bitbucket repository. Feel free to use this code as you like, and let me know if you think it can be improved.

IMAPTalk 2 beta 3 released

I have just released a new beta release of IMAPTalk 2. While the changes involve fairly minor enhancements, I am more excited to have found another protocol that IMAPTalk is compatible with. It’s RESP, the protocol used by Redis. You can use IMAPTalk to communicate with a Redis server instead of the Redis CLI on Windows, giving you several advantages including colorization and standard rich text features.

Automating a WinForms login form using SendKeys

This article describes how you can fill in form fields and invoke buttons from code using SendKeys, without directly interacting with the UI. The initial examples do this from the same application, but it is later shown how to do this UI automation from a separate application.

sendkeys-login-initial2

In this article, we’re going to use a simple login form as an example. It contains what you’d normally expect: fields to enter the username and password, and a Login button. Additionally, it contains an Automate button at the top which we’ll use to execute our automation code.

You’ll notice that I already have something in the Automate button’s click event handler:

            SendKeys.Send("username");

If you try this, you might expect that something gets written in the username field. But alas, nothing happens. That’s because SendKeys is limited to sending keystrokes to the focused control on the currently active application. Therefore, to actually send text to the username field, we first have to focus it.

We can try forcing focus on the username field:

            this.usernameField.Focus();
            SendKeys.Send("username");

…and indeed that works. But that won’t quite work if we’re automating the UI from a second application, since it has no idea about the fields present in our login form.

Therefore, another way is to actually send TAB keys to navigate to the desired control, before sending actual text. Special keys such as TAB and ENTER are represented by special codes such as {TAB} and {ENTER} (refer to the SendKeys documentation for a full list). Thus we can achieve the same effect like this:

            SendKeys.Send("{TAB}username");

And likewise, we can fill in the whole form, and finally invoke the Login button by first giving it focus and then sending an ENTER key:

            SendKeys.Send("{TAB}username{TAB}password{TAB}{ENTER}");

So you can see that the result is just what we expected:

sendkeys-login-loggedin

Naturally, keep in mind that tabbing to the desired control is entirely dependent on the tab index of the controls. If that changes, your automation code will have to change accordingly. It might not be an ideal approach, but it’s just about the best you can do for SendKeys if you want an application to send keystrokes to another.

Speaking of which, so far we’ve taken the shortcut of doing everything within the same application, in which case giving focus to controls directly is just fine. Let us now create a second Windows Forms application, and see how we can use it to automate our login form’s UI.

Actually, all we need is a simple form with a button, whose Click event handler will execute our automation code:

sendkeys-login-automatorstub

Now as I said before, SendKeys works only with the currently active application. If we want to automate our login form, we’ll need some code to find it from the list of running applications, and activate it. This StackOverflow answer has some code that takes care of this.

The first thing we need to do is find the process we want to automate. For that we need the name of the process. If it’s already running, you can find it in the Task Manager:

sendkeys-login-taskmanager

Notice how if you’re running directly from Visual Studio, the process will contain a “.vshost” before the file extension.

We can now get the process we want (Process is in the System.Diagnostics namespace):

            Process p = Process.GetProcessesByName("WinFormsLogin.vshost").FirstOrDefault();

Note that we omit the .exe extension from the process name above.

Once that is done, we need to bring that process to the foreground using some code from the answer linked above. So first, import the Win32 SetForegroundWindow() function (DllImport requires the System.Runtime.InteropServices namespace):

[DllImport ("User32.dll")]
static extern int SetForegroundWindow(IntPtr point);

Once we have this, we bring the process to the foreground, and send any keystrokes we need:

            Process p = Process.GetProcessesByName("WinFormsLogin.vshost").FirstOrDefault();

            if (p != null)
            {
                IntPtr h = p.MainWindowHandle;
                SetForegroundWindow(h);
                SendKeys.SendWait("{ENTER}");
            }

And there you go, the Automator application invokes the automation button on the Login application:

sendkeys-login-acrossapps

Now you’ll notice I’m kind of cheating here: I’m just sending the ENTER key to activate the Automate button in the Login form (which happens to have a tab index of zero, i.e. it’s the first thing to be focused). The applications you want to automate won’t normally have an Automate button. But just as you can send an ENTER key from one application to another, you can send other keys. We can thus do our automation anyway:

            Process p = Process.GetProcessesByName("WinFormsLogin.vshost").FirstOrDefault();

            if (p != null)
            {
                IntPtr h = p.MainWindowHandle;
                SetForegroundWindow(h);
                SendKeys.Send("{TAB}username{TAB}password{TAB}{ENTER}");
            }

Great! You can use SendKeys for simple automation of Windows Forms applications by sending keystrokes – even across applications. If you want to automate Microsoft Word or anything of the sort, this won’t work, although there are alternatives. If you’re doing more serious stuff (e.g. WPF) there are entire APIs you can look at.

Update the updater to update

update-windows-update

I formatted one of my laptops and reinstalled Windows the other day. Whilst reinstalling software and bringing it up to date, Windows update gave me this ridiculous message:

“To check for updates, you must first install an update for Windows Update.”

I guess software has become so complex that even updates require various levels of abstraction. 🙂

C# 6 Preview: Changes in VS2015 CTP 5

C# 6 and Visual Studio 2015 are both prerelease software at the moment, and thus they are subject to change at any time.

There have indeed been some changes in C# 6 that came out in CTP 5 but which don’t seem to have been mentioned anywhere.

String interpolation

If you’ve read my original article on string interpolation, you’ll know that the syntax was expected to change. Well, that has happened, and the expected syntax is now in place. So now, you can use string interpolation to write special formatted strings as follows:

            var name = "Chuck";
            var surname = "Norris";

            string message = $"The man is {name} {surname}";

The placeholders in the curly brackets no longer require a prefixing backslash, but a dollar sign is necessary at the start of the string to allow them to be interpreted properly.

Just like before, the placeholders are not restricted to simple variables. They may contain arbitrary expressions including properties and methods:

            var numbers = new int[] { 1, 2, 3, 4, 5 };

            string message = $"There are {numbers.Length} numbers, and their average is {numbers.Average()}";

You can use format strings in placeholders. Unlike in the original implementation, they don’t need to be enclosed in quotes if they contain operators (e.g. dashes which normally represent minus signs). However you need to be a little precise with them, as any extra space after the colon (:) appears in the output:

            var dateOfBirth = DateTime.Now;
            string message = $"It's {dateOfBirth:yyyy-MM-dd}!";

using static

I’ve also written about the using static feature before, which lets you declare a static class among the using statements and then omit the class prefix when using static methods.

The syntax has changed, and you will need to prefix the static class with the keyword “static” in the declaration. This is a good thing because it eliminates the confusion between which using statements are namespaces and which are static classes.

    using static System.Console;

    class Program
    {
        static void Main(string[] args)
        {   
            WriteLine("Hello Lilly!");

            ReadLine();
        }
    }

VS2015 Preview: Layout Management

In earlier versions of Visual Studio, if you happened to mess up your window layout in Visual Studio, you could reset it back to the default layout by using the appropriate item in the Window menu:

vs2015-windowlayouts-duringreset

This rearranges the docked windows to whatever you originally had when Visual Studio was installed:

vs2015-windowlayouts-afterreset

That’s nice and all. But you may have noticed some new items above “Reset Window Layout” in the Window menu which are pretty handy when it comes to managing your window layouts.

For instance, when developing a new WPF application, the toolbox can sometimes come in handy for those without much experience with XAML. So, after introducing the Toolbox window, you can save the current layout:

vs2015-windowlayouts-duringsave

To save a layout, you need to give it a name:

vs2015-windowlayouts-promptsave

…and if that name happens to already exist, you’re asked whether you want to replace it (this is how you update saved layouts):

vs2015-windowlayouts-promptsaveexisting

You can then load (apply) these layouts by selecting them from the list in the Window menu, or by using the appropriate shortcut key (available for the first nine layouts in order). For instance, I saved this alternate layout suitable for unit tests, and I can apply it like this:

vs2015-windowlayouts-duringapply

…and then, like magic, the selected layout is applied:

vs2015-windowlayouts-afterapply

There’s also a menu item for management of these layouts:

vs2015-windowlayouts-managemenuitem

This opens a dialog which allows you to rename, delete, or reorder layouts.

vs2015-windowlayouts-managedialog

Reordering layouts has the effect of reassigning their keyboard shortcuts, since they are assigned in order to the first nine (from Ctrl+Alt+1 to Ctrl+Alt+9).

So, there you have it! Window layout management is yet another new feature in Visual Studio 2015 to improve your productivity.

VS2015 Preview: Live Static Code Analysis

In Visual Studio 2015, the new C# and VB .NET compilers are based on the .NET Compiler Platform known as Roslyn. This allows third-party tools to use the compiler itself to query the structure of code, rather than having to redo the compiler’s job. It also provides the ability to fix the code by modifying its structure.

You can use the NuGet Package Manager in VS2015 to install analyzers. At the moment there are very few available, and they’re still prerelease software. For this demonstration we’ll use the CodeCracker C# analyzer:

vs2015-analyzers-nuget

Once you install the package, you’ll see that the analyzer has been added under a special Analyzers node under the References in Solution Explorer. If you expand the analyzer, you can see all the rules that it enforces:

vs2015-analyzers-solution-explorer

As you can see, the code analysis rules may be enforced at various levels. Those marked as errors will result in actual compiler errors, and obviously cause the build to fail.

The rules that are broken by the code will then show up in the error list, which in VS2015 has been enhanced so that you can see more info about the error/rule and also click on the error code link to go to its online documentation (at the time of writing this article, the CodeCracker’s error code links are broken):

vs2015-analyzers-error-list

The best thing about live static code analysis is that they’re live: the rules will be checked as you’re writing your code, and you don’t even need to build for them to be evaulated.

Warnings may be sorted out by moving the caret within the relevant code and pressing Ctrl+. (Control Dot), after which the Quick Actions become available. See, code analyzers don’t need to limit themselves to complaining. If a fix is available, you’ll have the option to apply it, and you can preview the changes as with any other refactoring:

vs2015-analyzers-fix

If you know better than the code analyzer, you can opt to suppress the warning instead:

vs2015-analyzers-suppress

Code analysis allows rules to be enforced on your team’s code. Roslyn facilitates this by making it easy to plug in different code analyzers (and hopefully in future there will be a wider range to choose from) and by running code analysis live, without the need to build the project.

Note: this demonstration used the CodeCracker C# analyzer in order to show the different levels of rules (e.g. warnings, errors, etc), since the StyleCop analyzer’s rules are all warnings. The CodeCracker C# analyzer is in quite a mess at the time of writing, with missing fixes, broken rule documentation links, and countless grammatical errors. But it’s prerelease, so we’ll pretend that’s a good excuse and forgive it for its sins.

Deserializing Derived Types with JSON.NET

If you’re using Json.NET to serialize objects which involve inheritance hierarchies, there’s a little issue you might run into.

Let’s say we have a class Person:

    public class Person
    {
        public string Name { get; set; }
    }

…and we also have another class Employee which derives from Person:

    public class Employee : Person
    {
        public decimal Salary { get; set; }
    }

Then I can write the following little Console Application (in which Json.NET is installed via NuGet):

            var employee = new Employee() { Name = "John", Salary = 1000m };

            var json = JsonConvert.SerializeObject(employee);

            var deserialized = JsonConvert.DeserializeObject<Person>(json);

We’re serializing an Employee (which derives from Person), and then deserializing into a Person (the base class). Due to polymorphism, we’d expect the result to hold a reference to an Employee instance complete with Salary. Alas, this is not the case:

json-derivedclasses-problem

As you can see, the result is actually of type Person, and the Salary goes missing in the deserialization.

Apparently the solution is to turn on Type Name Handling. The code is thus transformed:

            var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };

            var employee = new Employee() { Name = "John", Salary = 1000m };

            var json = JsonConvert.SerializeObject(employee, settings);

            var deserialized = JsonConvert.DeserializeObject<Person>(json, settings);

Once we create an instance of JsonDerializerSettings with TypeNameHandling turned on, we can pass that object as a paramater in the serialization/deserialization methods to obtain the correct result:

json-derivedclasses-solution

As you can see, the deserialized result is now an Employee, complete with Salary. You’ll also notice that the actual serialized JSON has changed: there is now type information in it, and that’s what allows the correct type to be deserialized.

So why is this functionality not enabled by default? I can only guess that it’s for performance reasons.

What’s in a Job Title?

The companies I’ve worked for so far have always had some kind of hierarchical organisation. For instance, you start off as a Software Developer, then you are promoted to Senior Software Developer, and so on. However, I’m aware that there are other companies which prefer to have a flat hierarchy, and keep job titles to a minimum.

Well, what’s in a job title, anyway? Does it really matter what your job title is?

Motivation

There’s this scene from the film “Kingdom of Heaven“, where the main character (Balian) selects a peasant and knights him on the spot. The bishop is horrified.

Bishop: “Who do you think you are? Will you alter the world? Does making a man a knight make him a better fighter?

Balian: “Yes.”

You see, making a man a knight doesn’t give him any special power. But he knows that he is now a knight. This means that he is responsible to uphold his duties as such.

On the job, it’s pretty much the same. Becoming a Senior Software Developer does not make you any more able in your work than turning 18 years old makes you suitable to drive. But it does put you into a bag of a handful of accomplished and trusted developers, and as such you will work a lot harder to show that you deserve that title. It also means that you will most likely take more initiative in your work, and go outside the scope of your individual duties by guiding others in performing theirs.

A little recognition goes a long way in motivating individuals.

Categorisation

Some companies offer the excuse that their employees have the same job titles or salaries in the interest of fairness, so that they are all treated equally.

Such companies should wake up and realise that people aren’t all equal. Some work harder than others. Those people do not deserve to be lumped in the same boat as those who do a miserable job.

The CV Factor

When an employee applies for a job, having “Senior Software Developer” looks a lot better than “Software Developer”.

It is true that job titles mean different things from one company to another. In some companies, a Software Developer is merely responsible for coding; while in others, he might actually be managing a whole project. Hiring companies should ideally look beyond the job title and ask about the roles that the candidate played in his employment.

However it is also true that companies and recruitment agencies receiving a lot of job applications often resort to simple filtering at face value in order to reduce the number of applications.

Consider this: individual A has been a loyal and hard-working Software Developer for 20 years, and his company never gave him a promotion. His friend, individual B, has been promoted to Senior Software Developer and then Lead Developer, even though his skills and responsibilities are less than those of individual A. When recruiters look at their CVs at face value, who will they prefer? What will they think about individual A when they see that he’s had the same role for 20 years?

"You don't learn to walk by following rules. You learn by doing, and by falling over." — Richard Branson