TypeProjection interface extracted
Suppress warnings when compiling runtime for tests
Field made final
Use wrapping instead of copying when creating nullable/non-null types

 Why wrapping is better:
1. It's requires less memory: a copy has many fields, while a wrapper has only one
2. It preserves laziness of types
Common logic extracted from lazy type implementations
Profiler uses loggers

This allows us to leave profiler calls in production code