Semantic wrappers are used to define a meaning of an input and consequently, determine what operations can be applied on that input.
Each semantic wrapper is expected to implement constructor which takes the original object and wraps it, and the
Augmentor.unwrap method, which returns the wrapped object. I.e., for a wrapper
W, the following holds:
obj == unwrap(W(obj)).
To prevent name conflicts, it is suggested not to export any semantic wrappers.
A SemanticWrapper determines the semantics of data that it wraps. Any subtype needs to implement function
unwrap(wrapper) that returns the wrapped data.
Returns the original object.