C# version contributed by Vincent Jacquet