Unit tests are a vital part of emerging code design

When a developer writes code there is always an aspect of design to it.  Some developers spend more time on initial upfront design others like to start coding straight away.    The design and structure of code will emerge to a more efficient structure during the writing of the code, this process can be helped by writing units to assist the refactoring process.

Designing Code

I like to encourage developers to pause and think about the design of their code before they start writing code.  The benefits from developers thinking before coding

Think before you act

It’s quicker to change a design plan than design and code

This reminds me of the carpenter saying

measure twice and cut once

Thinking = planning

They are stopping to think about the task and creating a design is similar to looking at a map before you set off driving towards a destination.

  • A brief design gives you a plan
  • code designs emerge

You initial design will not be the finished design because designs are high level.  When you focus on individual parts of the design more questions and problems will come into view.

It’s like viewing something from far away, you see some general shapes and details.  The closer you get the more detail you see.

The role of unit testing in code design

Many people believe unit tests are written to catch bugs, it’s true writing unit tests could find some additional bugs you might have missed.

reusable tests for all developers.

It’s true unit testing has many benefits but here are the benefits to code design

Benefits of unit tests to code

  • Refactoring
  • Simpler code design
  • Code Documentation


the main benefit I have experienced with unit tests recently is the ability to refactor my code and run tests against the code to make sure it still works and hasn’t broken anything.

Simpler code design

When code is written to be tested the code design is simplified so testing the code is easier.  It’s easier to test code which does one thing and adhere’s to the single responsibility principle.

Code Documentation

Unit tests provide a working documentation of code.  Allowing other developers to easy see what the code should do by the tests and run/debug the code using the unit tests

This article (which is very good) THE ACTUAL COST OF TESTS – PART I, adds  additional benefits to unit testing

  • Code coverage
  • bugs in tests

The goal of code (design)

The way most developers work is they aim to get the initial code working and aim to tidy the code later.

This approach is driven by two factors

  • working code not matter how ugly can be shipped
  • The developer has proven their logic is sound

Primary requirements of code

  1. The primary requirement of code is deliver the functionality required

long term requirements of code

  1. Readable (expressive names, logically structured)(
  2. Modular/independent code to manage the effects of change (cohesive code, loose coupling)
  3. Reuse
  4. Easy to maintain/debug/enhance the code

The primary and short term goal of code can be achieved with minimal effort in the design of the code.  The code will deliver the required functionality but usually in spaghetti code with these characteristics

  • Big classes and Methods
  • classes\methods doing many things
  • high complexity
  • tight coupling

The above code is what I call Legacy code and developers have given up trying to keep this code manageable because the task of refactoring the project has become to big to contemplate.

An important aspect of refactoring is removing duplicate code, Martin Fowler has a great article on repetition.  Removing duplicate code has numerous benefits such as

  • Create reusable classes/methods
  • Reduces code
  • Better designed code

Unit Tests and refactoring

If you code has unit tests it allows developers to refactor the code with confidence because they can easily test the code still works by running the unit tests.

Unit tests fit in with the way developers write code (get it working first) but without unit tests the refactoring and structuring the code for the long term is  considerable more difficult because the developer would need to manually test the code is working.

Code designs emerge during the coding process, developers see more efficient ways to structure code which usually involves removing duplicate code, writing smaller more efficient code.

Code design can be viewed in similar way to writing a novel.  Novels go through many drafts and revisions whilst the writer removes unneeded sections and poorly written sections.  Some novelists can change the core structure/characters of books during revisions as a byproduct of investing more time focused on the task.

Code design is a similar process because it’s easier to restructure a working code design and improve a current design than it is to create a perfect code design first time.

Problems and efficiencies of code only come into view when a developer moves closer to the problem.

The key points

Without unit tests developers won’t refactor code to deliver the long terms benefits of well designed code.

Code and projects where code is not refactored reach legacy code status very quickly.  The developers who have to manage and work legacy code will take longer and longer to interact with the code (debug/enhance/extend/understand).

The end result is not writing unit tests will cost you more time and developers jobs are less enjoyable

CRM 2015 SP1 – Turbo forms use asynchronous JavaScript web resource loading

I was reading this blog post from the CRM Lady

Turbo Forms in Microsoft Dynamics CRM 2015 (v7.1.0)

The article points to some good resource learn more about the new turbo forms.

The article from the CRM Team has a wealth of interesting information and lots of healthy warnings for you

Microsoft Dynamics CRM Online 2015 Update 1 – New Form Rendering Engine

What are the new turbo form

Microsoft have been doing lots of tinkering how the CRM forms are rendered.  This graphic shows the effect

// // // // // //

When I saw the graph above my first thoughts were

  1. WOW, Awesome
  2. How did they get such a dramatic improvement
  3. Will this break my customizations

How did Microsoft Improve loading times

I will quote the article

There are 2 main changes that have been made: loading process of the form, and handling of cache.

The article indicates they have moved to parallel loading and are caching more data.


Hmmmm Parallel Javascript loading

The increased form loading is great but parallel loading can have some downsides.  I first came across Javascript parallel loading in CRM 2011 rollup 12, you can read about here

To speed up form loading in CRM 2011 they switched to parallel loading and the result meant lots of Javascript methods suddenly stopped working.  The reason for this was because one Javascript file was calling a method on another javascript file.  This worked when the Javascript files were loaded in an order but when you load them all at once sometimes one Javascript file tries to call another dependant Javascript file which is still loading.

So suddenly lots of Javascript errors appeared and all developers had to write a Javascript wait file, like CRM MVP Scott Durow talks about in this article

This is a significant change and could cause lots of errors if you have Javascript code in your OnLoad functions which call other Javascript files.

I noticed a new section appeared in the mdsn article Write code for Microsoft Dynamics CRM forms

Manage library dependencies

As a performance optimization, Microsoft Dynamics CRM forms load JavaScript web resources asynchronously and in parallel. This means that the order in which the libraries are configured for a form does not guarantee that a library will be fully downloaded and initialized before another library might attempt to use one of the objects defined in it.

If you have code that depends on another library to be fully downloaded and initialized, the most straightforward approach is to combine both libraries within a single JavaScript web resource with your code below the library code. A more sophisticated approach is to use libraries such as head.js or require.js to control how the separate libraries are loaded.


Is Parallel loading good or bad

There is a quote in blade runner

Replicants are like any other machine. They’re either a benefit or a hazard. If they’re a benefit, it’s not my problem.

Upgrading to CRM 2015 SP1 could cause big problems to Javascript customizations.  It’s good practise to split up your Javascript code to separate files to make it reusable and maintainable but now Microsoft are recommending we put everything in one file.  This could turn out to be one big massive Javascript file, which is ok for performance but maintaining and working with this file is difficult.

This change could catch many CRM developers out because the errors are intermittent, sometimes the javascript files will have loaded in the correct order and work.

It will involve developers writing Javascript code which waits until all the Javascript files load which will cancel out any benefits from parallel loading.

It could be seen as an opportunity to restructure Javascript code to have a self contained loading script and then move other Javascript functions to OnChange events.  This would be a double win of increased loading time due to parallel loading and running less code.

You can use Legacy form loading style

There is a system setting which contains a global setting to control which form loading style you use.

It’s a great idea for Microsoft to put this in because the new speedier form loading code might take some while getting use to it.  When CRM 2011 polaris release came it, it caused a raft of blog posts because CRM Javascript customizations suddenly stopped working.

Settings -> Administration -> System Settings -> General. Select “Yes” under “Use legacy form rendering”

In a perfect world it would have been great to have a entity setting rather than a global setting for the form rendering.

I thought I would write about this because it could effect a lot of people and I never spotted this change until today.


Hosk’s Top CRM Articles of the week – 15th May

Article of the Week

Customizing Lead Qualification Process in CRM 2015

Great article from CRM MVP Jukka, going through customizing the lead process in CRM 2015

Best of the Rest

Good coding practices – Information hiding

A Hosk article looking at the good coding practise of Information hiding and encapsulation and why you should be doing it in your code

Querying Many to Many Relationships in Microsoft Dynamics CRM

A useful blog showing you how to query many to many relationships in CRM advanced find

Information to Get started with Unit Testing with Microsoft Fakes and Microsoft Dynamics CRM 2013

CRM Developers should be unit testing, here is some information to help you get started with Microsoft Fakes

Using Queues in Microsoft Dynamics CRM

detailed post on queues in CRM

Hierarchical Visualization – Features & Limitations

How to Retrieve all the Access Team Members for all Accounts in Dynamics CRM

It uses SQL but it’s interesting to understand the underlying configuration

update CRM 2015 with a single request

No more special messages in CRM 2015 SP1 if you use the new update request

What is the !! Javascript operator!!!!

A double !! operator in Javascript but what the hell does it do?

Microsoft Dynamics CRM 2015 / 2013 / 2011 SDK Example Index

A big long list of examples in CRM SDK

Getting CRM Dev toolkit to work with Visual Studio 2013

There is still no CRM 2015 Developer toolkit and you can’t use the current DEV toolkit with Visual studio 2013 but you can if you hack a few things.  Come on Microsoft help the CRM developers out a bit and get stuff working with the latest versions

Why two CRM addins within Outlook?

Why are there two CRM Addins!

Zsolt Zombik Dynamics CRM Blog’s Top CRM Articles of the week – 15th May

Another Article of the week collection!! Such a great idea I have decided to do one myself


Mature Developers

Announcing TypeScript 1.5 Beta

Principle of abstraction

SOLID Principles of Class Design

Ebook – 97 Things Every Programmer Should Know – Extended


Warren Buffett on How he Keeps up with Information

Nassim Taleb: How to Not be a Sucker From the Past

Last Weeks Top CRM Articles

Hosk’s Top CRM Articles of the week – 8th May

Useful Hosk Links

Hosk list Of CRM 2013 Tools

A list and review of CRM 2013 tools, this will probably work in CRM 2015 as well

Hosk’s CRM Developer Articles

A collection of my favourite CRM Developer articles I have written

MB2-703 – CRM 2013 Customization and Configuration Certification Information

All the CRM 2013 content to help you pass the exam

HoskWisdom – Hosk Developer Quotes

 Words of Wisdom from the Hosk.  I have written over 900 articles, surely I should have said a few memorable things

Good coding practices – Information hiding

I was reading code complete 2, which is an excellent book and I would recommend all CRM developer read it, you will learn lots of things.

The book mentions information hiding, this may be a new concept to some CRM developers because it’s not a term you hear very often.

Steve McConnell the author of Code Complete 2 has a great article on it called Missing in Action: Information Hiding

Information hiding would be a by product of code using the S.O.L.I.D principles

What is information hiding

I find it helpful to use multiple definitions, design principles it can be difficult to understand and different perspectives can be beneficial.

Programming Practices

Information hiding focuses on hiding the non-essential details of functions and code in a program so that they are inaccessible to other components of the software. A software developer applies information hiding in software design and coding to hide unnecessary details from the rest of the program. The objective of information hiding is to minimize complexities among different modules of the software. Note that complexities arise when one program or module in software is dependent on several other programs and modules.

Information Hiding

The basic idea is that if code chunk A doesn’t really need to know something about how code chunk B (which it calls) does its job, don’t make it know it. Then, when that part of B changes, you don’t have to go back and change A.


Hosk Definition of Information hiding

Information hiding is not just about hiding data but hiding how it implements those behaviours.   Classes  have public methods but hides the private methods and variables which implement the logic behind the public methods

Why is information hiding important

Information hiding reduces dependency on class variables, allowing classes/methods to act like black boxes, hiding logic from the consumers of the class.  Hiding variables reduces potential coupling and dependant classes, which will reduce the effect of change on your code.

Information hiding is not just hiding variables but the methods and internal logic.  Hiding information results in less code being dependant on concrete classes/implementation, allowing internal workings of classes without needing to change any other classes.

This blog post highlights some good points about information hiding

Why you should care about information hiding

Information hiding makes methods and variables private, hiding the internal logic from other classes.  Developers can change the internal logic without changing dependent code.

Methods should only accessed is via the public methods, hiding the internal workings of the class.  CRM developer can change the internal workings of the class and not effect any of the classes which call those methods.

If classes have public variables, public variables might be used by other classes creating a dependency, if you change a public variable you need to check the calling classes still work.

Changing the logic of public variables/methods can effect any dependent classes which will result in more code changed, more testing and an increased chance of creating a bug.

To help understand information hiding it’s helpful to think the CRM SDK.  When we call IOrganisationService.Update(Entity).  We don’t have access to any fields, we have no idea how the code updates the CRM database or what steps it does.

Microsoft could change the IOrganisationService.Update(Entity) to use a different language but because I only consume the public method none of my code would need to change (assuming it works the same way).  Code calling the CRM SDK is loosely coupled.

How you use Information hiding outside of coding

Information hiding and Encapsulation in OOP has a great definition of information hiding

Showing only those details to the outside world which are necessary for the outside world and hiding all other details from the outside world.”


Real life examples


You can hide private information from certain people to stop them using it and only show your name.

Computer operating system

Windows/Linux give you a nice GUI operating system to manage your computers but underneath there are lots of private files and programs.

The article Information hiding and Encapsulation in OOP  has a good example
  1. Your name and other personal information is stored in your brain we can’t access this information directly. For getting this information we need to ask you about it and it will be up to you how much details you would like to share with us.


Information hiding isn’t the same as encapsulation but I’m not entirely sure of the difference. Encapsulation and Information hiding share a common goal in hiding business logic.
Wiki quote

Hiding the internals of the object protects its integrity by preventing users from setting the internal data of the component into an invalid or inconsistent state. A supposed benefit of encapsulation is that it can reduce system complexity, and thus increase robustness, by allowing the developer to limit the inter-dependencies between software components[citation needed].


The benefit of encapsulation,  hiding business logic by using private methods and interfaces/abstract classes.  Encapsulation limits the effects of change.  Encapsulation hides/removes dependency on the concrete code behind your public methods

Information Hiding helps reduce the effects of change

Code changes all the time and there are lots of things which can result in code change

  • Change in requirements
  • Fixing a bug
  • Refactoring
  • Extension

Developers cannot control change but they can control how the code will be affecting by change.  Good code design using the S.O.L.I.D principles will reduce the effect of code changes in the code.

Information hiding is one of the tools developers have to reduce the effect of change, hiding the information will create loosing coupling/low dependency and using interfaces/abstract classes will isolate your concrete implementation code from the rest of the system and create loose coupling.

This design principle is described in the Law of Demeter, which described excellent in this article  SOLID Design principles

I find it useful to refer to these principles when writing code because it helps to create

Information hiding helps reduce the complexity of code by creating loosely coupled code and more modular code.  Information hiding reduces the dependencies on classes, a class coupled with multiple classes in a system, it’s difficult to understand and change the code because you need to understand how the change would effect all the dependent classes.

Information hiding helps reduce coupling by hiding concrete logic which helps mitigate the effects of changing the concrete logic.

The more independent/loosely coupled code you have the more code reuse you will have.

Benefits of Information hiding

  • Simplifies the code
  • Reduce complexity
  • Limit dependencies in code
  • Improved code readability/Increased understanding

futher reading



High Cohesion – Loose Coupling

information hiding with Javascript

Why you should care about encapsulation

Information to Get started with Unit Testing with Microsoft Fakes and Microsoft Dynamics CRM 2013

This blog will highlight useful information for any CRM developers wanting to learn about Microsoft fakes and Microsoft Fakes with CRM.

I have recently decided I should be unit testing my CRM code, to be honest I knew I should have been doing it before but I had excuses not to

  • The projects I had worked on didn’t have unit tests
  • The other developers were not unit testing their code
  • The company/project didn’t stipulate unit tests should be written
  • Unit testing CRM code is difficult

You can read about this in more detail

Experiences of Unit testing with Microsoft Dynamics CRM Projects

If you want more reasons why CRM developers should write unit tests then read this article it has 18 reasons benefits of unit testing your code

Why CRM Developers should unit test their code

Since I have started unit testing my CRM code not only is my code designed better (smaller classes/methods which are easier to test).  My code is tested and I have caught more bugs, particularly bugs where the testing diverted from the happy path and tested the alternative and exception path tests – Don’t just test the happy path.

The biggest benefit to having unit tests is you can refactor and change the code with confidence because after you have finished making changes you can test your code with unit tests.

What Framework should I use?

I wasn’t sure what framework I should use to test my code.  I had previously worked on a project where they used NUnit, another project used RhinoMocks.

I started writing some unit tests with RhinoMocks but found difficulties when trying to test some code using Metadata because the Metadata was a read only collection.  Microsoft Fakes is an isolation framework which allows you to create shims to overwrite read only data.

CRM 2015 – Understanding CRM Metadata

I had problems setting Attributes collection on the Metadata record.  This was a mixture of me not knowing standard unit testing methods and Attributes is a read only collection.

Many developers were put off using fakes due to cost.  Fakes was free in Visual Studio Ultimate (which is expensive).  The prohibitive cost put off many developers who turned to other free/cheaper testing frameworks.

Sometime in 2013 Microsoft bundled in Microsoft Fakes with Premium license (which is much more common).

Microsoft Fakes is included in Visual Ultimate and Premium in release 2012 and 2013, the key point is Fakes is free with Visual Studio Premium edition.

I had heard good things about Microsoft Fakes, it had shims which would allow me to overwrite read only collections.  So I decided to start testing with Microsoft Fakes.

Start learning about Microsoft Fakes

When I started writing a unit test, I quickly released I was going to have to do some fast learning.  The terms used by Microsoft Fakes were completely alien to me

  • Shims
  • Stubs
  • and no mention of the word Mock
  • Isolation Framework

There are two main hurdles when learning about Microsoft fakes

  • The terminology
  • Getting into the testing mindset
  • Writing tests for the first

To begin with it was tricky to understand the structure and terminology of Microsoft fakes, let alone start testing my tricky CRM code.

Microsoft Fakes Introduction General

This section highlights content I found useful whilst learning about Microsoft Fakes in general without focusing on using Microsoft fakes with to Test CRM code.

A good, quick (7 minutes) video introduction to Microsoft Fakes

Below is a good general article on Unit testing with Visual studio

Writing Unit Tests for the .NET Framework with the Microsoft Unit Test Framework for Managed Code

Microsoft’s main page on Microsoft Fakes

Isolating Code Under Test with Microsoft Fakes

The Isolating Code Under Test with Microsoft fakes is a great introduction to fakes and it explains what Stubs and Shims and gives you some code examples.

Free Microsoft Fakes Ebook

Better Unit Testing with Microsoft Fakes

The ebook above gives a good introduction to Microsoft Fakes but the majority of the ebook is comparing Fakes to other testing frameworks, explaining how to convert your tests/logic from another testing framework to fakes.  It’s useful (and free) but for users getting started with Microsoft fakes you will probably stop reading half way through.

Unit testing with Fakes with Visual studio Premium 2012

This is a good article which is a good introduction to Microsoft fakes with the bonus of the source code being available for download.

CRM and Microsoft Fakes

The best single resource for getting started with writing unit tests using Microsoft Fakes and CRM is a series of 10 blog posts by Zhongchen Zhou

Dynamics CRM 2011 Unit Test Part 1: Introduction and Series Contents

This a fantastic tutorial, going through all the major elements in CRM you need Stub/Shim to enable testing of your CRM code.  Below are links to the fakes CRM testing.  I recommend clicking on the introduction which gives a description of each blog.

The examples are for CRM 2011 but CRM plugin development is based around the IOrganisationService and OrganizationServiceContext and these are still in the same in CRM 2015.

You can also download the source code shown in the tutorials in the link below


Having the code is useful because you can run the tests yourself and walk through the code to follow the unit testing flow (you can also copy parts of it into your unit tests)

Unit Testing Plugins using Microsoft Fakes

A short article which runs through setting up Microsoft fakes, it goes through all the steps to manually test a CRM plugin.  It has useful examples stubbing the IOrganisationService.

OrganizationService.RetrieveMultipleQueryBase = (query) =>
var result = new EntityCollection();
return result;

CRM 2015/2013 Testing Framework

Wael Hamze with help from Ramon Tebar (MVP) have done some great work and created a CRM 2015/2013 testing framework.  This is a framework for testing plugins/custom workflows.  The framework does a lot of mocking of the common plugin objects.

The framework is useful but I think the business logic code should be kept inside plugins.  I prefer to split it up into smaller focused classes and methods but I know a lot of people will be interested in testing the plugins, if so this project will speed up the process.

The project is very well documentated, so you should be up and running in no time.


Not only is this framework excellent but there are some very useful videos showing you how to use the framework

xRM Test Framework for Dynamics CRM 2015

Webcasts and Slides which has videos and presentation on the subject.  There is lots of source

 (Webinar Recording) – CRMUG SIG: Technical/Developer – Unit Testing Plug-ins in Dynamics CRM 2013 (June 2014)

 Technical/Developer – Unit Testing Custom Workflow Activities in Dynamics CRM 2013 (July 2014)

Technical/Developer – Integration Testing Plug-ins in Dynamics CRM 2013 (July 2014)

Books (Unit testing in general)

I’m not qualified to say what books are good but I’m reading and enjoying

The Art of Unit Testing: with Examples in .NET


What is the !! Javascript operator!!!!

I saw some Javascript code which the CRM Developer Pacman was working on and it had a bizarre If statement which used a double exclamation mark!!

One exclamation mark means not but what does two exclamation marks mean Not Not?

Below is the code in question

var roleName = null;
    type: "GET",
    async: false,
    contentType: "application/json; charset=utf-8",
    datatype: "json",
    url: odataSelect,
    beforeSend: function (XMLHttpRequest) { XMLHttpRequest.setRequestHeader("Accept", "application/json"); },
    success: function (data, textStatus, XmlHttpRequest) {
        var result = data.d;
        if (!!result) {
            roleName = result.results[0].Name;
    error: function (XmlHttpRequest, textStatus, errorThrown) {
        //alert('OData Select Failed: ' + odataSelect);

The code was doing an OData query and then checking the result with the if Statement

if (!!result) {

      roleName = result.results[0].Name;


What does the !! exclamation do

It’s quite clever because the first exclamation mark converts the object into a boolean value, the second exclamation mark checks to see if the boolean is false.

In C# developer terms its like casting the object to a boolean and then doing an inverted check (e.g. if not false)

This two Stackoverflow articles discuss and explain the !! exclamation in more detail but this answer and the truth table helped me understand

Double Exclamation points

''        ==   '0'           // false
0         ==   ''            // true
0         ==   '0'           // true
false     ==   'false'       // false
false     ==   '0'           // true
false     ==   undefined     // false
false     ==   null          // false
null      ==   undefined     // true
" \t\r\n" ==   0             // true

Using the table above my understand is the !! exclamation in the examples checks to see if the result object is not 0, undefined, null because all those values would be converted to a boolean type of false.

Here is another good discussion on the topic

What is the !! (not not) operator in JavaScript?

Whilst researching this topic I found the article below

Truthy and falsy in JavaScript

The article talks you understand how Javascript uses true, truthy, false and falsy in JavaScript


Hosk’s Top CRM Articles of the week – 8th May

Article of the Week

Microsoft Dynamics CRM Online 2015 Update 1 (7.1.0) Product Documentation is Available!

The documentation for CRM 2015 SP1 is fantastic.  This link shows all the documentation for the new features

CRM 2013 – Managed solution problems with out of sync solutions

Hosk blog posts about solutions, managed solutions and problems with branching solutions

Best of the Rest

What are the limitations of Microsoft Dynamics CRM Online and how do you work with them?

CRM Online has some limitations this article looks at how you can create solutions to work around them based on an interesting white paper from Microsoft

Query and visualize hierarchical data

A page on the hierarchical data structure in CRM

Improved Business Rules in CRM 2015

A look at the changes in business rules in CRM 2015

toLookup and toEntityReference helper methods

a nice helper method

Error Logging Options in CRM

logging options in CRM

Convert FetchXML to SQL query

a tool to convert FetchXML to sql

CRM 2015 – {Javascript Code Example #2} – Save a form asynchronously with call back function

JavaScript code to implement a callback function

“Mind the gap” to make your CRM charts look better

Great blog post from CRM MVP on charts

Dynamics CRM 2015 Update 0.1 Full Text Search Quick Find Performance Feature

The dynamics support team have a feature to improve wildcard searching with CRM on premise


Why TypeScript is Hot Now, and Looking Forward

getting started with test driven development


How a Scientifically Proven Technique Can Improve How Well You Learn and Remember

Local boy Elon Musk unveils Eskom’s end, the battery to set South Africans free

Stephen Hawking – Master of the universe

Last Weeks Top CRM Articles

Hosk’s Top CRM Articles of the week – 1st May

Useful Hosk Links

Hosk list Of CRM 2013 Tools

A list and review of CRM 2013 tools, this will probably work in CRM 2015 as well

Hosk’s CRM Developer Articles

A collection of my favourite CRM Developer articles I have written

MB2-703 – CRM 2013 Customization and Configuration Certification Information

All the CRM 2013 content to help you pass the exam

HoskWisdom – Hosk Developer Quotes

 Words of Wisdom from the Hosk.  I have written over 900 articles, surely I should have said a few memorable things

%d bloggers like this: