RSS 2.0
Sign In
# Saturday, September 2, 2017

Don't you think there is something wrong with world map according to Yandex?

They seems have optimized something in Black Sea region.

Saturday, September 2, 2017 2:58:06 PM UTC  #    Comments [0] -

# Tuesday, August 22, 2017

Today we wanted to write some code in java that performs some or the other action depending on a condition. At the same time if some action fails we wanted to fall back to the other action.

We've written it like this:

  case true:
      // Some actions.
    catch(Exception e)
      // Fall back to false route. 
  case false:
    // Other actions.

The fun part is that it's not valid java code.


The answer can be found in spec: 14.11. The switch Statement

The type of the Expression must be char, byte, short, int, Character, Byte, Short, Integer, String, or an enum type (§8.9), or a compile-time error occurs.

But why?

Who knows...

Sure there are workarounds, even with switch, but it just not justified restriction...

Tuesday, August 22, 2017 3:18:29 PM UTC  #    Comments [0] -
Java | Thinking aloud
# Saturday, July 15, 2017

Saxon-HE 9.8.0-3 is out but still problems are there.

See Incorrect behavior in Saxon-HE-9.8.0-3 (maven).

Another problem is that we see that something has propably happened with tail call optimization. Code that was working earlier now give an error:

err:SXLM0001: Too many nested function calls. May be due to infinite recursion.

We have to figure out how to build a simple TC for Michael Kay to test it.

See Saxon-HE 9.8.0-3 Tail Calls.

Saturday, July 15, 2017 2:14:43 PM UTC  #    Comments [0] -

# Tuesday, June 27, 2017

We've found that there is a Saxon HE update that was going to fix problems we mentioned in the previous post, and decided to give it a second chance.

Now Saxon fails with two other errors:

We shall be waiting for the fixes. Mean time we're back to version 9.7.

Tuesday, June 27, 2017 10:30:28 PM UTC  #    Comments [0] -
Announce | xslt
# Wednesday, June 14, 2017
Finally, Saxon 9.8 is out!
This means that basic xslt 3 is available in the HE version.

Update: as usually, each new release has new bugs...
Wednesday, June 14, 2017 9:05:51 PM UTC  #    Comments [0] -
# Tuesday, May 16, 2017

We have found that Saxon HE 9.7.0-18 has finally exposed partial support to map and array item types. So, now you can encapsulate your data in sequence rather than having a single sequence and treating odd and even elements specially.

Basic example is:

<xsl:stylesheet version="3.0"
  exclude-result-prefixes="xs t map">

  <xsl:template match="/">
    <xsl:variable name="map" as="map(xs:string, xs:string)" select="
        'Su': 'Sunday',
        'Mo': 'Monday',
        'Tu': 'Tuesday',
        'We': 'Wednesday',
        'Th': 'Thursday',
        'Fr': 'Friday',
        'Sa': 'Saturday'
     <xsl:message select="map:keys($map)"/>


A list of map functions can be found here, though not all are available, as Saxon HE still does not allow inline functions.

P.S. From the development perspective it's a great harm that Saxon HE is so limited. Basically limited to xslt 2.0 + some selected parts of 3.0.

Tuesday, May 16, 2017 6:20:48 AM UTC  #    Comments [0] -
Thinking aloud | xslt
# Sunday, March 26, 2017

Lately we do not program in XSLT too often but rather in java, C#, SQL and javascript, but from time to time we have tasks in XSLT.

People claim that those languages are too different and use this argument to explain why XSLT is only a niche language. We, on the other hand, often spot similarities between them.

So, what it is in other languages that is implemented as tunnel parameters in XSLT?

To get an answer we reiterated how they work in XSLT, so, you:

  • define a template with parameters marked as tunnel="yes";
  • use these parameters the same way as regular parameters;
  • pass template parameters down to other templates marking them as tunnel="yes";

The important difference of regular template parameters from tunnel parameters is that the tunnel parameters are implicitly passed down the call chain of templates. This means that you:

  • define your API that is expected to receive some parameter;
  • pass these parameters somewhere high in the stack, or override them later in the stack chain;
  • do not bother to propagate them (you might not even know all of the tunnel parameters passed, so encapsulation is in action);

As a result we have a template with some parameters passed explicitly, and some others are receiving values from somewhere, usually not from direct caller. It’s possible to say that these tunnel parameters are injected into a template call. This resembles a lot injection API in other languages where you configure that some parameters are prepared for you by some container rather then by direct caller.

Now, when we have expressed this idea it seems so obvious but before we thought of this we did not realize that tunnel parameters in XSLT and Dependency Injection in other languages are the same thing.

Sunday, March 26, 2017 4:21:36 AM UTC  #    Comments [0] -
Thinking aloud | xslt
# Wednesday, January 4, 2017

Although the golden age of IE8 has already passed and Microsoft already has stopped its support, this browser still occupies about 3% of the of the world market desktop browsers. Despite this, many big organisations still use this browser for enterprise web applications. We may confirm this, since we deal with such organisations around the world. Companies try to get rid of IE8, but this often requires Windows upgrade and resources to re-test all their web applications. If such company has many web terminals  with Windows 7 or even with XP, this task becames rather expensive. So, this process advances rather slowly. Meanwhile, these organizations don't stop development of new web applications that must work on new HTML5 browsers and on old IE8.

A year ago we had developed an UIUpload AngularJS directive and service that simplifies file uploading in web applications with AngularJS client. It works as expected on all HTML5 browsers. But few days ago, we were asked to help with file uploading from AngularJS web application that will work in IE8. We've spent few hours in order to investigate existing third-party AngularJS directives and components. Here are few of them:

All of these directives for IE8 degrade down to <form> and <iframe> and then track the uploading progress. These solutions don't allow to select files for old browsers. At the same time, our aim was to implement an AngularJS directive that allows selecting a file and perform uploading, which will work for IE8 and for new browsers too.

Since IE8 neither supports FormData nor File API, thus, the directive must work with DOM elements directly. In order to open file selection dialog we need to hide  <input type="file"/> element and then to route client-side event to it. When a file is selected it is sent to a server as multipart/form-data message. The server's result will be caught by hidden <iframe> element and passed to the directive's controller.

After few attempts we've implemented the desired directive. The small VS2015 solution that demonstrates this directive and server-side file handler you may download here.

The key feature of this directive is emulation of replace and template directive's definition properties:

       var directive =
          restrict: "AE",
            id: "@",
            serverUrl: "@",
            accept: "@?",
            onSuccess: "&",
            onError: "&?",
          link: function (scope, element, attrs, controller)
            var id = || ("fileUpload" + scope.$id);

            var template = "<iframe name='%id%$iframe' id='%id%$iframe' style='display: none;'>" +
              "</iframe><form name='%id%$form' enctype='multipart/form-data' " +
              "method='post' action='%action%' target='%id%$iframe'>" +
              "<span style='position:relative;display:inline-block;overflow:hidden;padding:0;'>" +
              "%html%<input type='file' name='%id%$file' id='%id%$file' " +
              "style='position:absolute;height:100%;width:100%;left:-10px;top:-1px;z-index:100;" +
                replace("%action%", scope.serverUrl).
                  replace("%html%", element.html()).
                    replace(/%id%/g, id);


We used such emulation, since each directive instance (an element) must have unique name and ID in order to work properly. On the one hand template that returned by function should have a root element when you use replace. On the other hand, IE8 doesn't like such root element (e.g. we've not succeeded to dispatch the click javascript event to the <input> element).

The usage of the directive looks like as our previous example (see UIUpload):

    <a file-upload=""
      class="btn btn-primary"        
      on-success="controller.uploadSucceed(data, fileName)"
      on-error="controller.uploadFailed(e)">Click here to upload file</a>    


is a comma separated list of acceptable file extensions.
is server URL where to upload the selected file. In case when there is no "server-url" attribute the content of selected file will be passed to success handler as a data URI.
A "success" handler, which is called when upload is finished successfully.
An "error" handler, which is called when upload is failed.

We hope this simple directive may help to keep calm for those of you who is forced to deal with IE8 and more advanced browsers at the same time.

Wednesday, January 4, 2017 10:52:41 AM UTC  #    Comments [0] -
.NET | AngularJS | ASP.NET | javascript
# Wednesday, December 21, 2016

Recently we have found and fixed a bug in unreachable statement optimization in jxom.

Latest version of stylesheets can be found at languages-xom.

Wednesday, December 21, 2016 10:10:06 PM UTC  #    Comments [0] -
# Thursday, October 6, 2016

Our genuine love is C++. Unfortunately clients don't always share our favors, so we mostly occupied in the C#, java and javascript. Nevertheless, we're closely watching the evolution of the C++. It became more mature in the latest specs.

Recently, we wondered how would we deal with dependency injection in C++. What we found is only strengthened our commitment to C++.

Parameter packs introduced in C++ 11 allow trivial implementation of constructor injection, while std::type_index, std::type_info and std:any give service containers.

In fact there are many DI implementations out there. The one we refer here is Boost.DI. It's not standard nor we can claim it's the best but it's good example of how this concept can be implemented.

So, consider their example seen in Java with CDI, in C# in .NET Core injection, and in C++:


public class Renderer 
  @Inject @Device
  private int device;

public class View 
  @Inject @Title
  private String title;
  private Renderer renderer;

public class Model {};

public class Controller 
  private Model model;
  private View view;

public class User {};

public class App 
  private Controller controller;
  private User user;

  Privider<App> provider = ...

  App app = provider.get();


public class RenderedOptions
  public int Device { get; set; }
public class ViewOptions
  public int Title { get; set; }
public class Renderer 
  public Renderer(IOptions<RendererOptions> options)
    Device = options.Device;

  public int Device { get; set; }

public class View 
  public View(IOptions<ViewOptions> options, Renderer renderer)
    Title = options.Title;
    Renderer = renderer;

  public string Title { get; set; }
  public Renderer Renderer { get; set; }

public class Model {}

public class Controller 
  public Controller(Model model, View view) 
    Model = model;
    View = view;

  public Model Model { get; set; }
  public View View { get; set; }

public class User {};

public class App 
  public App(Controller controller, User user) 
    Controller = controller;
    User = user;

  public Controller Controller { get; set; }
  public User User { get; set; }

  IServiceProvider serviceProvider = ...



#include <boost/di.hpp>

namespace di = boost::di;

struct renderer 
  int device;

class view 
  view(std::string title, const renderer&) {}

class model {};

class controller 
  controller(model&, view&) {}

class user {};

class app 
  app(controller&, user&) {}

int main()
   * renderer renderer_;
   * view view_{"", renderer_};
   * model model_;
   * controller controller_{model_, view_};
   * user user_;
   * app app_{controller_, user_};

  auto injector = di::make_injector();

What is different between these DI flavors?

Not too much from the perspective of the final task achieved.

In java we used member injection, with qualifiers to inject scalars.

In C# we used constructor injection with Options pattern to inject scalars.

In C++ we used constructor injection with direct constants injected.

All technologies have their API to initialize DI container, but, again, while API is different, the idea is the same.

So, expressiveness of C++ matches to those of java and C#.

Deeper analysis shows that java's CDI is more feature rich than DI of C# and C++, but, personally, we consider it's advantage of C# and C++ that they have such a light DI.

At the same time there is an important difference between C++ vs java and C#.

While both java and C# are deemed to use reflection (C# in theory could use code generation on the fly to avoid reflection), C++'s DI natively constructs and injects services.

What does it mean for the user?

Well, a lot! Both in java and in C# you would not want to use DI in a performance critical part of code (e.g. in a tight loop), while it's Ok in C++ due to near to zero performance impact from DI. This may result in more modular and performant code in C++.

Thursday, October 6, 2016 11:27:42 AM UTC  #    Comments [0] -
.NET | C++ | Java | Thinking aloud
# Wednesday, September 28, 2016

While reading on ASP.NET Core Session, and analyzing the difference with previous version of ASP.NET we bumped into a problem...

At Managing Application State they note:

Session is non-locking, so if two requests both attempt to modify the contents of session, the last one will win. Further, Session is implemented as a coherent session, which means that all of the contents are stored together. This means that if two requests are modifying different parts of the session (different keys), they may still impact each other.

This is different from previous versions of ASP.NET where session was blocking, which meant that if you had multiple concurrent requests to the session, then all requests were synchronized. So, you could keep consistent state.

In ASP.NET Core you have no built-in means to keep a consistent state of the session. Even assurances that the session is coherent does not help in any way.

You options are:

  • build your own synchronization to deal with this problem (e.g. around the database);
  • decree that your application cannot handle concurrent requests to the same session, so client should not attempt it, otherwise behaviour is undefined.
Wednesday, September 28, 2016 7:22:15 PM UTC  #    Comments [0] -
.NET | ASP.NET | Thinking aloud
# Sunday, September 11, 2016

Angular 2 is already available though there are a lot of code and libraries that are still in Angular 1.x. Here we outline how to write AngularJS 1.x in the modern javascript.

Prerequisites: EcmaScript 2015, javascript decorators, AngularJS 1.x. No knowledge of Angular 2.0 is required.

Please note that decorators we have introduced, while resemble those from Angular 2, do not match them exactly.

A sample uses nodejs, npm and gulp as a building pipeline. In addition we have added Visual Studio Nodejs project, and maven project.

Build pipeline uses Babel with ES 2015 and decorator plugins to transpile sources into javascript that today's browsers do support. Babel can be replaced or augmented with Typescript compiler to support Microsoft's javascript extensions. Sources are combinded and optionally minified into one or more javascript bundles. In addition html template files are transformed into javascript modules that export a content of html body as a string literals. In general all sources are in src folder and the build's output is assembled in the dist folder. Details of build process are in gulpfile.js

So, let's introduce an API we have defined in angular-decorators.js module:

  • Class decorators:
    • Component(name, options?) - a decorator to register angular component.
    • Controller(name) - a decorator to register angular controller.
    • Directive(name, options?) - a decorator to register angular directive.
    • Injectable(name) - a decorator to register angular service.
    • Module(name, ...require) - a decorator to declare an angular module;
    • Pipe(name, pure?) - a decorator to register angular filter.

    Component's and Directive's options is the same object passed into Module.component(), Module.directive() calls with difference that no options.bindings, options.scope, options.require is specified. Instead @Attribute(), @Input(), @Output(), @TwoWay(), @Collection(), @Optional() are used to describe options.bindings, and @Host(), Self(), SkipSelf(), @Optional() are used to describe options.require

    Every decorated class can use @Inject() member decorator to inject a service.

  • Member decorators:
    • Attribute(name?) - a decorator that binds attribute to the property.
    • BindThis() - a decorator that binds "this" of the function to the class instance.
    • Collection() - a decorator that binds a collection property to an expression in attribute in two directions.
    • Host(name?) - a decorator that binds a property to a host controller of a directive found on the element or its ancestors.
    • HostListener(name?) - a decorator that binds method to a host event.
    • Inject(name?) - an injection member decorator.
    • Input(name?) - a decorator that binds a property to an expression in attribute.
    • Optional() - a decorator that optionally binds a property.
    • Output(name?) - a decorator that provides a way to execute an expression in the context of the parent scope.
    • Self(name?) - a decorator that binds a property to a host controller of a directive found on the element.
    • SkipSelf(name?) - a decorator that binds a property to a host controller of a directive found on the ancestors of the element.
    • TwoWay() - a decorator that binds a property to an expression in attribute in two directions.

    If optional name is omitted in the member decorator then property name is used as a name parameter. @Host(), @Self(), @SkipSelf() accept class decorated with @Component() or @Directive() as a name parameter.

    @Inject() accepts class decorated with @Injectable() or @Pipe() as a name parameter.

  • Other:
    • modules(...require) - converts an array of modules, possibly referred by module classes, to an array of module names.

Now we can start with samples. Please note that we used samples scattered here and there on the Anuglar site.

@Component(), @SkipSelf(), @Attribute()

In the Angular's component development guide there is a sample myTabs and myPane components.
Here its rewritten form components/myTabs.js:
import { Component } from "../angular-decorators"; // Import decorators
import template from "../templates/my-tabs.html"; // Import template for my-tabs component
@Component("myTabs", { template, transclude: true }) // Decorate class as a component
export class MyTabs // Controller class for the component
  panes = []; // List of active panes
  select(pane) // Selects an active pane
    this.panes.forEach(function(pane) { pane.selected = false; });
    pane.selected = true;
  addPane(pane) // Adds a new pane
    if (this.panes.length === 0)
import { Component, Attribute, SkipSelf } "../angular-decorators"; // Import decorators
import { MyTabs } from "./myTabs"; // Import container's directive.
import template from "../templates/my-pane.html"; // Import template.
@Component("myPane", { template, transclude: true }) // Decorate class as a component
export class MyPane // Controller class for the component
  @SkipSelf(MyTabs) tabsCtrl; //Inject ancestor MyTabs controller.
  @Attribute() title; // Attribute "@" binding.
  $onInit() // Angular's $onInit life-cycle hook.
@Component(), @Input(), @Output()
In the Angular's component development guide there is a sample myTabs component.
Here its rewritten form components/heroDetail.js:
import { Component, Input, Output } from "../angular-decorators";
import template from "../templates/heroDetail.html";
@Component("heroDetail", { template }) // Decorate class as a component
export class HeroDetail // Controller class for the component
  @Input() hero; // One way binding "<"
  @Output() onDelete; // Bind expression in the context of the parent scope "&"
  @Output() onUpdate; // Bind expression in the context of the parent scope "&"
    this.onDelete({ hero: this.hero });
  update(prop, value)
    this.onUpdate({ hero: this.hero, prop, value });
@Directive(), @Inject(), @Input(), @BindThis()

In the Angular's directive development guide there is a sample myCurrentTime directive.
Here its rewritten form directives/myCurrentTime.js:
import { Directive, Inject, Input, BindThis } from "../angular-decorators"; // Import decorators
@Directive("myCurrentTime") // Decorate MyCurrentTime class as a directive
export class MyCurrentTime // Controller class for the directive
  @Inject() $interval; // "$interval" service is injected into $interval property
  @Inject() dateFilter; // "date" filter service is injected into dateFilter property
  @Inject() $element; // "$element" instance is injected into $element property.
  @Input() myCurrentTime; // Input one way "<" property.
  // updateTime is adapted as following in the constructor: 
  //   this.updateTime = this.updateTime.bind(this);
  @BindThis() updateTime() 
    this.$element.text(this.dateFilter(new Date(), this.myCurrentTime));
  $onInit() // Angular's $onInit life-cycle hook.
    this.timeoutId = this.$interval(this.updateTime, 1000);
  $onDestroy() // Angular's $onDestroys life-cycle hook.
  $onChanges(changes) // Angular's $onChanges life-cycle hook.
@Directive(), @Inject(), @HostListener(), @BindThis()

In the Angular's directive development guide there is a sample myDraggable directive.
Here its rewritten form. directives/myDraggable.js:
import { Directive, Inject, HostListener, BindThis } from "../angular-decorators"; // Import decorators
@Directive("myDraggable") // Decorate class as a directive
export class MyDraggable // Controller class for the directive
  @Inject() $document; // "$document" instance is injected into $document property.
  @Inject() $element;// "$element" instance is injected into $element property.
  startX = 0;
  startY = 0;
  x = 0;
  y = 0;
  // Listen mousedown event over $element.
  @HostListener() mousedown(event)
    // Prevent default dragging of selected content
    this.startX = event.pageX - this.x;
    this.startY = event.pageY - this.y;
    this.$document.on('mousemove', this.mousemove);
    this.$document.on('mouseup', this.mouseup);
  @BindThis() mousemove(event) // bind mousemove() function to "this" instance.
    this.y = event.pageY - this.startY;
    this.x = event.pageX - this.startX;
      top: this.y + 'px',
      left: this.x + 'px'
  @BindThis() mouseup() // bind mouseup() function to "this" instance.
    this.$'mousemove', this.mousemove);
    this.$'mouseup', this.mouseup);
  $onInit() // Angular's $onInit life-cycle hook.
      position: 'relative',
      border: '1px solid red',
      backgroundColor: 'lightgrey',
      cursor: 'pointer'
@Injectable(), @Inject()

In the Angular's providers development guide there is a sample notifier service.
Here its rewritten form. services/notify.js:
import { Inject, Injectable } from "../angular-decorators"; // Import decorators
@Injectable("notifier") // Decorate class as a service
export class NotifierService
  @Inject() $window; // Inject "$window" instance into the property
  msgs = [];
    if (this.msgs.length === 3)
      this.msgs = [];

In the Angular's filters development guide there is a sample reverse custom filter.
Here its rewritten form. filters/reverse.js:
import { Pipe } from "../angular-decorators"; // Import decorators
@Pipe("reverse") // Decorate class as a filter
export class ReverseFilter
  transform(input, uppercase) // filter function.
    input = input || '';
    var out = '';
    for(var i = 0; i < input.length; i++)
      out = input.charAt(i) + out;
    // conditional based on optional argument
    if (uppercase)
      out = out.toUpperCase();
    return out;
Module(), modules(), angular.bootstrap()
Here are an examples of a class representing angular module, and manual angular bootstrap:
import { angular, modules, Module } from "../angular-decorators"; // Import decorators
import { MyController } from "./controllers/myController"; // Import components.
import { HeroList } from "./components/heroList";
import { HeroDetail } from "./components/heroDetail";
import { EditableField } from "./components/editableField";
import { NotifierService } from "./services/notify";
import { MyTabs } from "./components/myTabs";
import { MyPane } from "./components/myPane";
import { ReverseFilter } from "./filters/reverse";
import { MyCurrentTime } from "./directives/myCurrentTime";
import { MyDraggable } from "./directives/myDraggable";
@Module( // Decorator to register angular module, and refer to other modules or module components.
class MyApp { }
// Manual bootstrap, with modules() converting module classes into an array of module names.
angular.bootstrap(document, modules(MyApp));

Please see angular-decorators.js to get detailed help on decorators.

Sunday, September 11, 2016 8:32:54 AM UTC  #    Comments [0] -
.NET | AngularJS | Announce | Java | javascript
# Friday, June 3, 2016

Good bad and good news.

Good: recently a new version Saxon XSLT processor was published:

12 May 2016
Saxon maintenance release for Java and .NET.

Bad: we run that release on our code base and found a bug:

See Internal error in Saxon-HE-9.7.0-5

Good: Michael Kay has confirmed the problem and even fixed it:

See Bug #2770

The only missing ingredient is when the patch will be available to the public:

"We tend to do a new maintenance release every 4-6 weeks. Can't commit to firm dates."

Friday, June 3, 2016 9:09:10 PM UTC  #    Comments [0] -
# Thursday, March 10, 2016

Our recent task required us to find all sets of not intersecting rectangles for a rectangle list.

At first glance it did not look like a trivial task. Just consider that for a list of N rectangles you can form 2^N different subsets. So, even result list, theoretically, can be enormous.

Fortunately, we knew that our result will be manageable in size. But nevertheless, suppose you have a list of couple of hundred rectangles, how would you enumerate all different sets of rectangles?

By the way, this task sounds the same as one of a Google interview's question. So, you may try to solve it by yourself before to check our solution.

We didn't even dare to think of brute-force solution: to enumerate all sets and then check each one whether it fits our needs.

Instead we used induction:

  • Suppose S(N) - is an solution for our task for N rectangles R(n), where S(N) is a set of sets of rectangles;
  • Then solution for S(N+1) will contain whole S(N), R(N+1) - a set consisting of single rectangle, and some sets of rectangles from S(N) combinded with R(N+1) provided they fit the condition;
  • S(0) - is an empty set.

The algorithm was implemented in java, and at first it was using Streaming and recursion.

Then we have figured out that we can use Stream.reduce or Stream.collect to implement the same algorithm. That second implementation was a little bit longer but probably faster, and besides it used standard idioms.

But then at last step we reformulated the algorithms in terms of Collections.

Though the final implementation is the least similar to original induction algorithm, it's straightforward and definitely fastest among all implementations we tried.

So, here is the code:

 * For a sequence of items builds a list of matching groups.
 * @param identity an identity instance used for the group.
 * @param items original sequence of items.
 * @param matcher a group matcher of item against a group.
 * @param combiner creates a new group from a group (optional) and an item.
 * @return a list of matching groups.
public static <T, G> List<G> matchingGroups(
  G identity,
  Iterable<T> items, 
  BiPredicate<G, T> matcher,
  BiFunction<G, T, G> combiner)
  ArrayList<G> result = new ArrayList<>();
  for(T item: items)
    int size = result.size();
    result.add(combiner.apply(identity, item));
    for(int i = 0; i < size; ++i)
      G group = result.get(i);
      if (matcher.test(group, item))
        result.add(combiner.apply(group, item));
  return result;

The sample project on GitHub contains implementation and a tests of this algorithm.

Thursday, March 10, 2016 11:31:48 AM UTC  #    Comments [0] -
Java | Tips and tricks
# Monday, February 29, 2016

8 Ways to Become a Better Coder is a good article. Read and apply to yourself. Never mind what your occupation is. Replace "coder" with your profession. Suits to everybody who wants to be the best.

Monday, February 29, 2016 6:33:04 PM UTC  #    Comments [0] -
Thinking aloud
<September 2017>
Total Posts: 387
This Year: 3
This Month: 0
This Week: 0
Comments: 1371
Locations of visitors to this page
The opinions expressed herein are our own personal opinions and do not represent our employer's view in anyway.

© 2024, Nesterovsky bros
All Content © 2024, Nesterovsky bros
DasBlog theme 'Business' created by Christoph De Baene (delarou)