Lots of changes. Maybe half ported from csharp version.