diff --git a/.gitignore b/.gitignore
index 870c5b5..672d37a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,91 +1,81 @@
 # Compiled Object files
 *.slo
 *.lo
 *.o
 *.obj
 
 # Compiled Dynamic libraries
 *.so
 *.so.*
 *.dylib
 *.dll
 
 # Compiled Static libraries
 *.lai
 *.la
 *.a
 *.lib
 
 # Executables
 *.exe
 *.out
 *.app
 
 *.class
 
 # Mobile Tools for Java (J2ME)
 .mtj.tmp/
 
 # Package Files #
 *.jar
 *.war
 *.ear
 
 # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
 hs_err_pid*
 
 # Qt-es
 
 /.qmake.cache
 /.qmake.stash
 *.pro.user
 *.pro.user.*
 *.moc
 moc_*.cpp
 qrc_*.cpp
 ui_*.h
 Makefile*
 *-build-*
 
 # QtCreator
 
 *.autosave
 
 coco/*.old
 coco/*~
 *~
 
 cpp/build-*/*
 cpp/xreate-debug/*
 cpp/xreate-release/*
 cpp/.idea
 CMakeLists.txt.user
 cmake_install.cmake
 project/*
 nb*.xml
 .*
 target/*
 /tools/phabricator/xreate-frontend/nbproject/private/
 documentation/trash4/
 trash/
 CMakeFiles/
 gen-cpp/
 generated-cpp/
 gen-php/
 generated-js/
 books/
 build/
 coco/Parser.*
 coco/Scanner.*
 
-cpp/src/compilation/latecontextcompiler.cpp
-cpp/src/compilation/latecontextcompiler.h
-cpp/src/pass/environmenttestspass.cpp
-cpp/src/pass/environmenttestspass.h
-cpp/src/query/ptrvalid.cpp
-cpp/src/query/ptrvalid.h
-cpp/tests/deferred/
-cpp/tests/vendorAPI/
-
-scripts/metatests/
 tools/phabricator/administration/
diff --git a/coco/xreate.ATG b/coco/xreate.ATG
index 61a41af..b50fb1b 100644
--- a/coco/xreate.ATG
+++ b/coco/xreate.ATG
@@ -1,550 +1,599 @@
 //TODO add ListLiteral
 //TODO ExprTyped:  assign default(none) type
 
 #include "ast.h"
 #include "ExternLayer.h"
+#include "pass/adhocpass.h"
 #include <string>
 #include <stack>
 
 #define wprintf(format, ...) \
                 char __buffer[100];    \
                 wcstombs(__buffer, format, 100);   \
                 fprintf(stderr, __buffer, __VA_ARGS__)
                 
 using namespace xreate;
 using namespace std;
+
 COMPILER Xreate
 
  xreate::AST root;  // current program unit 
  
  struct {
      std::stack<xreate::CodeScope*> scopesOld;
     xreate::CodeScope* scope = nullptr;
  } context;
  
  void pushContextScope(CodeScope* scope){
     context.scopesOld.push(context.scope);
     context.scope = scope;
  }
  
  void popContextScope(){
         context.scope = context.scopesOld.top();
         context.scopesOld.pop();
  }
      
-int skipIdent()
+int nextToken()
 {
-  int kind = 0;
   scanner->ResetPeek();
-  while ((kind = scanner->Peek()->kind) == _colon)
-    if (scanner->Peek()->kind != _ident)
-      return 0;
-    
-  return kind;  
+  return scanner->Peek()->kind;
 }
 
 bool checkParametersList()
 {
-  return la->kind == _ident && skipIdent() == _lparen;
+    return la->kind == _ident && nextToken() == _lparen;
 }
 
 bool checkInfix()
 {
-  return la->kind == _ident && skipIdent() == _ident;
+  return la->kind == _ident && nextToken() == _ident;
 }
 
 bool checkIndex()
 {
-  return la->kind == _ident && skipIdent()  == _lbrack;
+  return la->kind == _ident && nextToken()  == _lbrack;
 }
 
 bool checkFuncDecl()
 {
   if (la->kind != _ident) return false;
   
-  int xkind = skipIdent();
-  Token* y = scanner->Peek();
-  return  xkind  == _assign && (y->kind == _function || y->kind == _pre);
+  int token2 = nextToken();
+  int token3 = scanner->Peek()->kind;
+  
+  return  token2  == _assign && (token3 == _function || token3 == _pre);
 }
 
 bool checkAssignment()
 {
+  if (la->kind != _ident) return false;
+  
   scanner->ResetPeek();
-  Token* x = scanner->Peek();
-  return la->kind == _ident && x->kind  == _assign;
+  int token2 = scanner->Peek()->kind;
+  if (token2 == _lcurbrack) {
+      scanner->Peek();
+      int token3 = scanner->Peek()->kind;
+      if (token3 != _rcurbrack) return false;
+      
+      int token4 = scanner->Peek()->kind;
+      return token4 == _assign;
+  }
+  
+  return  token2  == _assign;
+}
+
+void recognizeIdentifier(Expression& i){
+    if (!context.scope->recognizeIdentifier(i)){       
+        if (!root.recognizeVariantIdentifier(i)){
+            root.postponeIdentifier(context.scope, i);
+        }
+    }
 }
 
+enum SwitchKind{SWITCH_NORMAL, SWITCH_META};
+
 CHARACTERS
   letter = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
   any = ANY - '"'.
   digit = "0123456789".
   cr  = '\r'.
   lf  = '\n'.
   tab = '\t'.
 
 TOKENS
   ident = (letter | '_') {letter | digit | '_'}.
   number = digit {digit}.
   string = '"' { any } '"'.
   function = "function".
   pre =  "pre".  
   lparen = '('. 
   rparen = ')'.
   lbrack = '['.
   rbrack = ']'.
   lcurbrack = '{'.
   rcurbrack = '}'.
   equal = "==".
   assign = '='.
   implic = '-' '>'.
   colon = ':'.
   context = "context".
   tagcolon   = "::".
   lse = "<=".
   lss = "<".
   gte = ">=".
   gtr = ">".
   
   ne1 = "!=".
   ne2= "<>".
   
 
 COMMENTS FROM "/*" TO "*/" NESTED
 COMMENTS FROM "//" TO lf
 
 IGNORE cr + lf + tab
 
 PRODUCTIONS
 
 Xreate =    (. Function* function; .)
-{ ( RuleDecl | InterfaceData | Imprt | ContextSection 
+{(  RuleDecl 
+    | InterfaceData | Imprt | ContextSection 
     | IF(checkFuncDecl()) FDecl<function>  (. root.add(function); .)
-    | TDecl ) }.
+    | TDecl 
+)}                                         (. root.recognizePostponedIdentifiers(); .)
+.
 
 Ident<std::wstring& name>
-= ident {':' ident}               (. name = t->val; .).
+= ident                                     (. name = t->val; .).
+
+VarIdent<Expression& e>
+= ident                                     (. e = Expression(Atom<Identifier_t>(t->val)); .)
+  [ lcurbrack (                              
+        ident                               (. SemErr(coco_string_create("var version as ident is not implemented yet")); .)
+      | number                              (. Attachments::put<VariableVersion>(e, Atom<Number_t>(t->val).get()); .)
+  ) rcurbrack ]  .
+  
 
 FDecl<Function*& f> =       (. std::wstring fname; std::wstring argName; TypeAnnotation typIn; TypeAnnotation typOut; bool flagIsPrefunct = false; Expression binding; .)
 Ident<fname> assign 
 [pre            (. flagIsPrefunct = true; .)]
 function 		(. f = new Function(fname); f->isPrefunction = flagIsPrefunct; CodeScope* entry = f->getEntryScope(); .)
 
 ['(' Ident<argName> tagcolon ExprAnnotations<binding>  (. f->addBinding(Atom<Identifier_t>(argName), move(binding)); .)
 {',' Ident<argName> tagcolon ExprAnnotations<binding>  (. f->addBinding(Atom <Identifier_t>(argName), move(binding));.)
 } ')']
 
 [ tagcolon  
 ( IF(flagIsPrefunct) FnTag<f>
-  |  Type<typOut>				(. f->setReturnType(typOut); .)
+  |  Type<typOut>
 )
 {';' FnTag<f> }]
 BDecl<entry>    (. entry->getBody().bindType(move(typOut));.)
 .
 
 ContextSection<>=                       (. Expression context; Function* f; .)
 "case" "context" tagcolon MetaSimpExpr<context>  
 lcurbrack { FDecl<f>                    (. f->guardContext = context; root.add(f); .)
 } rcurbrack.
 
   /**
    *                          TYPES  
    * 
    */
-TypeTerm<TypeAtom& typ> =                       (. std::wstring tid; .)
-  ("string" | "num" | "int" | "i8" | "i32" | "float" | "bool") (. typ = Atom<Type_t>(t->val); .)
-.
+TypeTerm<TypePrimitive& typ> =                       (. std::wstring tid; .)
+  ("string" (. typ = TypePrimitive::String;.)
+  | "num"   (. typ = TypePrimitive::Num;.)
+  | "int"   (. typ = TypePrimitive::Int;.)
+  | "float" (. typ = TypePrimitive::Float;.)
+  | "bool" (. typ = TypePrimitive::Bool; .)
+  | "i8"    (. typ = TypePrimitive::I8; .)
+  | "i32"   (. typ = TypePrimitive::I32; .)
+  ).
 
-Type<TypeAnnotation& typ> =  (. TypeAnnotation typ2; TypeAtom typ3; std::wstring tid, field; .)
+Type<TypeAnnotation& typ> =  (. TypeAnnotation typ2; TypePrimitive typ3; std::wstring tid, field; .)
 ( 
   TList<typ>   
 | TStruct<typ>
-| TypeTerm<typ3> (. typ = TypeAnnotation(typ3); .) 
-|IF (checkIndex()) Ident<tid> lbrack
+| TypeTerm<typ3> (. typ = typ3; .) 
+| IF (checkIndex()) Ident<tid> lbrack
       Ident<field>      (. typ = TypeAnnotation(TypeOperator::ACCESS, {}); typ.__valueCustom = Atom<Identifier_t>(tid).get(); typ.fields.push_back(Atom<Identifier_t>(field).get()); .)
       {',' Ident<field> (.  typ.fields.push_back(Atom<Identifier_t>(field).get());  .)
       } rbrack
       
 | Ident<tid>            (. typ = TypeAnnotation(TypeOperator::CUSTOM, {}); typ.__valueCustom = Atom<Identifier_t>(tid).get(); .)
     ['(' Type<typ2>     (. typ.__operator = TypeOperator::CALL; typ.__operands.push_back(typ2); .)
     {',' Type<typ2>     (. typ.__operands.push_back(typ2); .)
     } ')']
 ) .
 
 TList<TypeAnnotation& typ> =      (.      TypeAnnotation ty; .)
     '[' Type<ty>                         (. typ = TypeAnnotation(TypeOperator::ARRAY, {ty}); .)
     {',' Type<ty>                        (. typ.__operator = TypeOperator::TUPLE; typ.__operands.push_back(ty); .)
     }']'
   .
   
 TStruct<TypeAnnotation& typ> = (. TypeAnnotation t; std::wstring field; .)
-  '{'
+  lcurbrack
     Ident<field> tagcolon Type<t>       (. typ = TypeAnnotation(TypeOperator::STRUCT, {t}); typ.fields.push_back(Atom<Identifier_t>(field).get()); .)
     {',' Ident<field> tagcolon Type<t>} (. typ.__operands.push_back(t); typ.fields.push_back(Atom<Identifier_t>(field).get()); .)
-  '}'.
+  rcurbrack.
   
  TDecl =  (. std::wstring ttag; TypeAnnotation t, t1; std::wstring tname, arg; std::vector<Atom<Identifier_t>> args; .)
   Ident<tname> assign "type"
   (
     "alias" Type<t>             (. root.add(move(t), Atom<Identifier_t>(tname)); .)
     | "variant" lparen Ident<arg>  (. t = TypeAnnotation(TypeOperator::VARIANT, {}); args.push_back(Atom<Identifier_t>(arg)); .)
         {',' Ident<arg>         (. args.push_back(Atom<Identifier_t>(arg)); .)
         } rparen                (. t.addFields(move(args)); root.add(move(t), Atom<Identifier_t>(tname)); .)
     
     | Ident<ttag> 
       ['('  Ident<arg>        (. args.push_back(Atom<Identifier_t>(arg));   .)
       {',' Ident<arg>         (. args.push_back(Atom<Identifier_t>(arg));   .)
       } ')']
       Type<t>                   (. t.addBindings(move(args)); root.add(move(t), Atom<Identifier_t>(tname)); .)
   ) '.' 
   .
   
-VDecl<CodeScope* f> =  (. std::wstring vname; Expression e;.)
-Ident<vname> assign ExprTyped<e>      (. f->addDeclaration(Atom<Identifier_t>(vname), move(e)); .)
-.
-
 ContextDecl<CodeScope * scope> =        (. Expression tag; .)
 context tagcolon 
 MetaSimpExpr<tag>                     (. scope->tags.push_back(tag); .)
 {';' MetaSimpExpr<tag>                (. scope->tags.push_back(tag); .)
 }.
 
+VDecl<CodeScope* f> =  (. std::wstring vname; Expression var, value;.)
+    VarIdent<var> assign ExprTyped<value>      (. f->addDeclaration(move(var), move(value)); .)
+.
+
 //TODO forbid multiple body declaration (ExprTyped) 
-BDecl<CodeScope* scope> =  '{'      (. Expression body; pushContextScope(scope);
-                                    .)
-    { (RuleContextDecl<scope>  | ContextDecl<scope>    '.'
-    | IF(checkAssignment()) VDecl<scope> '.'
-    | ExprTyped<body>              (. scope->setBody(body); popContextScope();.)
-)} '}'. 
+BDecl<CodeScope* scope> =  lcurbrack      (. Expression body; pushContextScope(scope);  .)
+    {(IF(checkAssignment()) VDecl<scope> '.'
+    | RuleContextDecl<scope>  
+    | ContextDecl<scope>'.'
+    | ExprTyped<body>                     (. scope->setBody(body); .)    
+    )}                                    (. popContextScope(); .)      
+    rcurbrack . 
 
 IfDecl<Expression& e> =     (. Expression cond; ManagedScpPtr blockTrue = root.add(new xreate::CodeScope(context.scope)); ManagedScpPtr blockFalse = root.add(new xreate::CodeScope(context.scope)); .)
 "if" '(' Expr<cond> ')'                         (. e = Expression(Operator::IF, {cond}); .)
 tagcolon ExprAnnotations<e> 
 BDecl<&*blockTrue> "else" BDecl<&*blockFalse>   (.  e.addBlock(blockTrue); e.addBlock(blockFalse); .)
 .
 
 LoopDecl<Expression& e> = 
   (. Expression eIn, eAcc, eFilters; std::wstring varEl, varAcc, contextClass; Expression tagsEl;
     ManagedScpPtr block = root.add(new xreate::CodeScope(context.scope)); .)
    "loop"
    ("map" '(' Expr<eIn> implic Ident<varEl>     (. e = Expression(Operator::MAP, {eIn}); .)
     tagcolon ExprAnnotations<tagsEl> ')' tagcolon ExprAnnotations<e> BDecl<&*block>
       (.
          e.addBindings({Atom<Identifier_t>(varEl)});
          block->addBinding(Atom<Identifier_t>(varEl), move(tagsEl)); 
          e.addBlock(block); 
       .)
 
   |"fold" 
     ("inf" '(' Expr<eAcc> implic Ident<varAcc> ')' 
         (.
                 e = Expression(Operator::FOLD_INF, {eAcc});
                 e.addBindings({Atom<Identifier_t>(varAcc)});
         .)        
      tagcolon ExprAnnotations<e> BDecl<&*block>
         (.
                 block->addBinding(Atom<Identifier_t>(varAcc), Expression());
                 e.addBlock(block); 
         .)
   
      | '(' Expr<eIn> implic Ident<varEl> tagcolon ExprAnnotations<tagsEl> ['|' Expr<eFilters> ] ',' Expr<eAcc> implic Ident<varAcc>')'
             (.
                 e = Expression(Operator::FOLD, {eIn, eAcc});
                 e.addBindings({Atom<Identifier_t>(varEl), Atom<Identifier_t>(varAcc)});
             .)
         tagcolon ExprAnnotations<e> BDecl<&*block>
             (.  
                 
                 block->addBinding(Atom<Identifier_t>(varEl), move(tagsEl));
                 block->addBinding(Atom<Identifier_t>(varAcc), Expression());
                 e.addBlock(block); 
             .)
     )
   | "context" '(' string                          (. contextClass = t->val; .)
     ')' BDecl<&*block> 
         (. e = Expression(Operator::LOOP_CONTEXT, {Expression(Atom<String_t>(std::move(contextClass)))});
             e.addBlock(block);
          .)
 ).
    
-SwitchDecl<Expression& eSwitch> =                  (. TypeAnnotation typ; eSwitch = Expression(Operator::SWITCH, {}); Expression eCondition; Expression tag;.)
+SwitchDecl<Expression& eSwitch, SwitchKind flagSwitchKind> = (. TypeAnnotation typ; eSwitch = Expression(Operator::SWITCH, {}); Expression eCondition; Expression tag;.)
 ["switch" 
-    (   "ad" "hoc" lparen Expr<eCondition> tagcolon MetaSimpExpr<tag> rparen (. eSwitch.op = Operator::SWITCH_ADHOC; eSwitch.operands.push_back(eCondition); eSwitch.tags.emplace(tag.getValueString(), move(tag)); .)
+    (   "ad" "hoc" lparen Expr<eCondition> tagcolon MetaSimpExpr<tag> rparen (. eSwitch.op = Operator::SWITCH_ADHOC;
+                                                                                eSwitch.operands.push_back(eCondition); 
+                                                                                eSwitch.addTags({tag}); 
+                                                                                flagSwitchKind = SWITCH_META; .)    
         | lparen Expr<eCondition> rparen tagcolon  ExprAnnotations<eSwitch>  (. eSwitch.operands.push_back(eCondition);.)
     )
 ]
-  CaseDecl<eSwitch> {CaseDecl<eSwitch>}
+  CaseDecl<eSwitch, flagSwitchKind> {CaseDecl<eSwitch, flagSwitchKind>}
 .
   
-CaseDecl<Expression& outer> =                    (. ManagedScpPtr scope = root.add(new xreate::CodeScope(context.scope)); .)
+CaseDecl<Expression& outer, SwitchKind flagSwitchKind> = (. ManagedScpPtr scope = root.add(new xreate::CodeScope(context.scope)); Expression condition; .)
   "case" 
-  (   "default" BDecl<&*scope>                   (. Expression exprCase(Operator::CASE_DEFAULT, {});       
+  ( IF(flagSwitchKind == SWITCH_META)
+        lparen MetaSimpExpr<condition> rparen BDecl<&*scope>  (. Expression exprCase(Operator::CASE, {}); exprCase.addTags({condition}); exprCase.addBlock(scope); outer.addArg(move(exprCase));.)
+        
+    | "default" BDecl<&*scope>                    (. Expression exprCase(Operator::CASE_DEFAULT, {});       
                                                    exprCase.addBlock(scope); 
                                                    outer.operands.insert(++outer.operands.begin(), exprCase); .)
   
-    | CaseParams<&*scope>                 (. ManagedScpPtr scopeBody = root.add(new xreate::CodeScope(&*scope)); .)
-      BDecl<&*scopeBody>                  (. Expression exprCase(Operator::CASE, {});
-                                            exprCase.addBlock(scope); exprCase.addBlock(scopeBody); outer.addArg(move(exprCase)); .)
+    | lparen CaseParams<&*scope> rparen         (. ManagedScpPtr scopeBody = root.add(new xreate::CodeScope(&*scope)); Expression exprCase(Operator::CASE, {}); .)
+      BDecl<&*scopeBody>                                (. exprCase.addBlock(scope); exprCase.addBlock(scopeBody); outer.addArg(move(exprCase)); .)
  ).
 
-CaseParams<CodeScope* scope> =           (. Expression e; Expression guard(Operator::LOGIC_AND, {}); pushContextScope(scope); .)
-   CaseParam<scope, guard>               
-   {',' CaseParam<scope, guard>
-  }                                      (. scope->setBody(guard); popContextScope(); .).
-  
-CaseParam<CodeScope* scope, Expression& guard> =           (. Expression condition; .)
-  (
-    IF(checkAssignment()) VDecl<scope>
-   | ExprTyped<condition>                                (. guard.addArg(move(condition)); .)
-  ).
-  
-SequenceDecl<Expression& sequence> =
-"sequence" ListLiteral<sequence>    (. sequence.setOp(Operator::SEQUENCE); .).
+CaseParams<CodeScope* scope> =           (. Expression condition; Expression guard(Operator::LOGIC_AND, {}); pushContextScope(scope); .)
+ ExprTyped<condition>                  (. guard.addArg(Expression(condition)); .)
+   {',' ExprTyped<condition>             (. guard.addArg(Expression(condition)); .)
+   }                                     (. scope->setBody(guard); popContextScope(); .)
+.
 
+IntrinsicDecl<Expression& outer>=        (. std::wstring name; .)
+"intrinsic" Ident< name>                 (. outer = Expression(Operator::CALL_INTRINSIC, {}); outer.setValue(Atom<Identifier_t>(name)); .)
+lparen [CalleeParams<outer>] rparen .
   
                               /*============================ INTERFACES ===============================*/
 Imprt<> =                           
 "import" "raw" lparen string      (. root.__rawImports.push_back(Atom<String_t>(t->val).get()); .) 
 rparen .
 
 InterfaceData<> = "interface" '('
   (   "dfa" ')'  InterfaceDFA
     | "extern-c" ')' InterfaceExternC
     | "cfa" ')' InterfaceCFA
     | "adhoc" ')' InterfaceAdhoc
     
   ).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            
 
 InterfaceAdhoc<> = 
-    '{' [ PrefunctionSchemeDecl ]  '}'.
+    '{' { PrefunctionSchemeDecl }  '}'.
      
 PrefunctionSchemeDecl<> =         (. TypeAnnotation typReturn; std::wstring prefName; Expression exprCases; .)
     pre function Ident<prefName> tagcolon Type<typReturn>
-    '{' SwitchDecl<exprCases>      '}'
+    lcurbrack SwitchDecl<exprCases, SWITCH_META> rcurbrack
                                   (. Expression prefData(Operator::CALL, {Atom<Identifier_t>(prefName), exprCases}); 
-                                     prefData.type = typReturn; 
+                                     prefData.bindType(typReturn); 
                                      root.addInterfaceData(Adhoc, move(prefData));  
                                   .).    
 
 
 InterfaceExternC<>  =   (.xreate::ExternData data; .)
   '{' {IncludeExternDecl<data> | LibExternDecl<data> } '}'
       (. root.addExternData(move(data));  .)
 .
 
 LibExternDecl<xreate::ExternData& data> =       (. std::wstring pkgname, libname; .)
   Ident<libname> assign "library" tagcolon "pkgconfig" 
   '(' string            (. pkgname = t->val; .)
   ')' '.'               (. data.addLibrary(Atom<Identifier_t>(libname), Atom<String_t>(pkgname)); .)
 . 
 
 IncludeExternDecl<xreate::ExternData& data> =   (. Expression inc; .)
   "include" StructLiteral<inc> '.'              (. data.addIncludeDecl(move(inc)); .)
 .
   
 InterfaceDFA<> = '{' { InstructDecl } '}' .
 
 InstructDecl =                        (.Operator op; Expression tag; 
                                   Expression scheme; 
                                   std::vector<Expression>& tags = scheme.operands; 
                                   tags.push_back(Expression()); /* return value */ .)
 "operator" InstructAlias<op> tagcolon '('      (.scheme.setOp(op); .)
 [
   MetaSimpExpr<tag>             (. tags.push_back(tag); .)
   {
       ',' MetaSimpExpr<tag>     (. tags.push_back(tag); .)
   }
 ] ')' [ implic MetaSimpExpr<tag>             (. tags[0] = tag; .) 
       ]                                      (. root.addDFAData(move(scheme)); .)
 '.'.
 
 InstructAlias<Operator& op> = 
 (
    "map"  (. op = Operator::MAP; .)
   | "list_range" (. op = Operator::LIST_RANGE; .)
   | "list"       (. op = Operator::LIST; .)
   | "fold"       (. op = Operator::FOLD; .)
   | "index"      (. op = Operator::INDEX; .) 
 ). 
 
 
 InterfaceCFA<> = '{' { InstructCFADecl } '}' .
 
 InstructCFADecl<> =                          (.Operator op; Expression tag; 
                                                 Expression scheme; 
                                                 std::vector<Expression>& tags = scheme.operands;  .)
 
 "operator" InstructAlias<op> tagcolon     (. scheme.setOp(op); .)
 [
   MetaSimpExpr<tag>             (. tags.push_back(tag); .)
   {
       ',' MetaSimpExpr<tag>     (. tags.push_back(tag); .)
   }
 ] '.'                           (. root.addInterfaceData(CFA, move(scheme)); .).
     
                               /*============================ METAPROGRAMMING ===============================*/
 // TagsDecl<CodeScope* f> = (. Expression tag; TagModifier mod = TagModifier::NONE; .)
 // ':' { MetaSimpExpr<tag> (. /*f.addTag(std::move(tag), mod); */ .)
 // }.
 
 
 FnTag<Function* f> = (. Expression tag; TagModifier mod = TagModifier::NONE; .)
 MetaSimpExpr<tag>
 ['-' TagMod<mod>] (. f->addTag(std::move(tag), mod); .).
 
 TagMod<TagModifier& mod> = 
 (  "assert" (. mod = TagModifier::ASSERT; .)
  | "require" (. mod = TagModifier::REQUIRE; .)
 ).
  
 RuleDecl<> =
 "rule" tagcolon         		(. RuleArguments args; RuleGuards guards; DomainAnnotation typ; std::wstring arg; .)
 '(' Ident<arg> tagcolon Domain<typ>  	(. args.add(arg, typ); .)
 {',' Ident<arg> tagcolon Domain<typ>  	(. args.add(arg, typ); .)
 } ')'
 ["case" RGuard<guards> {',' RGuard<guards>}]
 '{' RBody<args, guards> '}' .    	
 
 /* - TODO use RGuard for guards-*/
 RuleContextDecl<CodeScope* scope> =     (.Expression eHead, eGuards, eBody; .)
 "rule" "context" tagcolon MetaSimpExpr<eHead>
-"case" MetaSimpExpr<eGuards>
+"case" lparen MetaSimpExpr<eGuards> rparen
 '{' MetaSimpExpr<eBody> '}'             (.scope->contextRules.push_back(Expression(Operator::CONTEXT_RULE, {eHead, eGuards, eBody})); .).
 
 Domain<DomainAnnotation& dom> = 
 (
   "function"  				(. dom = DomainAnnotation::FUNCTION; .)
   | "variable"    			(. dom = DomainAnnotation::VARIABLE; .)
 ).
 
 RGuard<RuleGuards& guards>=          (. Expression e; .)
 MetaExpr<e>                       (. guards.add(std::move(e)); .).
 
 MetaExpr<Expression& e>=            (.Operator op; Expression e2; .)
 MetaExpr2<e>
 [MetaOp<op> MetaExpr2<e2>           (. e = Expression(op, {e, e2}); .)
 ].
 
 MetaExpr2<Expression& e>=
 (
 '(' MetaExpr<e> ')'
 | MetaSimpExpr<e>
 ).
 
 MetaSimpExpr<Expression& e>=      (. std::wstring i1, infix; Expression e2; .)
 ( '-' MetaSimpExpr<e2>            (. e = Expression(Operator::NEG, {e2}); .)
 | IF(checkParametersList()) Ident<i1>   (. e = Expression(Operator::CALL, {Expression(Atom<Identifier_t>(i1))}); .)
-'(' [ CalleeParams<e> ] ')'
+'(' [ MetaCalleeParams<e> ] ')'
 | IF(checkInfix()) Ident<i1> Ident<infix> MetaSimpExpr<e2>                                       
                                         (. e = Expression(Operator::CALL, {Expression(Atom<Identifier_t>(infix))});
                                            e.addArg(Expression(Atom<Identifier_t>(i1)));
                                            e.addArg(std::move(e2));
                                         .)
 | Ident<i1>                             (. e = Expression(Atom<Identifier_t>(i1)); .)
 ).
 
+MetaCalleeParams<Expression& e> = (. Expression e2; .)
+  MetaSimpExpr<e2>	     	(. e.addArg(Expression(e2)); .)
+  {',' MetaSimpExpr<e2>		(. e.addArg(Expression(e2)); .)
+  }.
+
 RBody<const RuleArguments& args, const RuleGuards& guards> =
                                   (. Expression e; std::wstring msg; .)
  "warning" MetaExpr<e> ["message" string (. msg = t->val; .)
 ]                                 (. root.add(new RuleWarning(RuleArguments(args), RuleGuards(guards), std::move(e), Atom<String_t>(msg))); .)
  .
 
 MetaOp< Operator& op> =
  implic                          (. op = Operator::IMPL; .)
 .
 
         /*============================ Expressions ===============================*/
-ExprAnnotations<Expression& e> = (. TypeAnnotation typ; Expression tag; e.tags.clear();.)
+ExprAnnotations<Expression& e> = (. TypeAnnotation typ; std::list<Expression> tags; Expression tag; e.tags.clear();.)
 Type<typ>                    (. e.bindType(move(typ)); .)
-  {';' MetaSimpExpr<tag>     (. e.tags.emplace(tag.getValueString(), tag); .)
-  }.
+  {';' MetaSimpExpr<tag>     (. tags.push_back(tag); .)
+  }                          (. e.addTags(tags); .)
+.
   
 ExprTyped<Expression&e> = Expr<e> [tagcolon ExprAnnotations<e>].
 
 Expr< Expression& e>         (. Operator op; Expression e2; .)
-= SimExpr<e>		 
+= ExprArithmAdd<e>		 
   [ RelOp<op>
-SimExpr<e2>      (. e = Expression(op, {e, e2});  .)
+    ExprArithmAdd<e2>      (. e = Expression(op, {e, e2});  .)
   ].
 
-SimExpr< Expression& e>      (. Operator op; Expression e2; .)
-= Term< e>
-  { AddOp< op>
-    Term< e2>         (. e = Expression(op, {e, e2});.)
-	}.
+ExprArithmAdd< Expression& e>=      (. Operator op; Expression e2; .)
+  ExprArithmMul< e>
+  [ AddOp< op>
+    ExprArithmAdd< e2>         (. e = Expression(op, {e, e2});.)
+  ].
 
-Term< Expression& e>         (. Operator op; Expression e2; .)
-= Factor< e>
-  { MulOp< op>
-            Factor< e2>        (. e = Expression(op, {e, e2}); .)
-  }.
+ExprArithmMul< Expression& e>         (. Operator op; Expression e2; .)
+= ExprPostfix< e>
+  [ MulOp< op>
+    ExprArithmMul< e2>        (. e = Expression(op, {e, e2}); .)
+  ].
 
-Factor< Expression& e>       (. std::wstring name; e = Expression(); .)
+ExprPostfix<Expression& e> 
+= Term<e> 
+  [lbrack                    (. e = Expression(Operator::INDEX, {e}); .)
+    CalleeParams<e> rbrack   
+  ].
+
+
+Term< Expression& e>       (. std::wstring name; e = Expression(); .)
 =                        
   (IF (checkParametersList()) Ident< name> 
                                     (. e = Expression(Operator::CALL, {Atom<Identifier_t>(name)}); .)
   '(' [CalleeParams<e>] ')'
-  |IF (checkIndex()) Ident<name>    
-    lbrack  CalleeParams<e> rbrack  (. e.setOp(Operator::INDEX); e.setValue({Atom<Identifier_t>(name)}); .)
-  | Ident< name>                    (. e = Expression(Atom<Identifier_t>(name)); root.recognizeVariantIdentifier(e); .)
+  | VarIdent<e>                     (. recognizeIdentifier(e); .)
   | ListLiteral<e>                  (. /* tuple */.)    
   | StructLiteral<e>                (. /* struct */.)
-  | SequenceDecl<e> 
   | LoopDecl<e>
-  | IfDecl<e>  
-  | SwitchDecl<e>
+  | IfDecl<e>   
+  | SwitchDecl<e, SWITCH_NORMAL>
   | AdhocDecl<e>
-
+  | IntrinsicDecl<e>
+  | "true"                          (. e = Expression(Atom<Number_t>(1)); e.bindType(TypePrimitive::Bool); .)
+  | "false"                         (. e = Expression(Atom<Number_t>(0)); e.bindType(TypePrimitive::Bool); .)
   | number                          (. e = Expression(Atom<Number_t>(t->val)); .)
   | string                          (. e = Expression(Atom<String_t>(t->val)); .)
-  | '-' Factor< e>                  (. e = Expression(Operator::NEG, {e}); .)
+  | '-' Term<e>                     (. e = Expression(Operator::NEG, {e}); .)
   | '(' ExprTyped<e> ')'  
   ).
   
 StructLiteral<Expression& e> =                     (. std::wstring key; Expression val; std::list<Atom<Identifier_t>> keys; .)
   '{' Ident<key> '=' Expr<val>                    (. keys.push_back(Atom<Identifier_t>(key)); e = Expression(Operator::LIST_NAMED, {val}); .)
   {',' Ident<key> '=' Expr<val>                 (.e.addArg(Expression(val)); keys.push_back(Atom<Identifier_t>(key)); .)
   } '}'                                         (. e.addBindings(keys.begin(), keys.end()); .)
   .
   
 ListLiteral<Expression& e> =  (. Expression eFrom, eTo; .)
 '['                                                             
 [ Expr<eFrom>                                                   (. e.addArg(Expression(eFrom)); .)
 (".."  Expr<eTo>                                                (. e.addArg(Expression(eTo)); e.setOp(Operator::LIST_RANGE); .)
  |{',' Expr<eFrom>                                              (. e.addArg(Expression(eFrom)); .)
 }                                                               (. e.setOp(Operator::LIST); .) 
 ) ] ']'.
 
 AdhocDecl<Expression& e> = (. Expression command; .)
-"ad" "hoc" Expr<command>       (. e.setOp(Operator::ADHOC); e.addArg(std::move(command));  .).
+"ad" "hoc" MetaSimpExpr<command>       (. AdhocExpression exprAdhoc; exprAdhoc.setCommand(command); e = exprAdhoc; .).
 
 CalleeParams<Expression& e> = (. Expression e2; .)
   ExprTyped<e2>		(. e.addArg(Expression(e2)); .)
   {',' ExprTyped<e2> 		(. e.addArg(Expression(e2)); .)
   }.
 
 AddOp< Operator& op>
 =                        (. op = Operator::ADD; .)
   ( '+'
   | '-'                  (. op = Operator::SUB; .)
   ).
 
 MulOp< Operator& op>
 =                        (. op = Operator::MUL; .)
   ( '*'
   | '/'                  (. op = Operator::DIV; .)
   ).
 
 RelOp< Operator& op>
 =                         (. op = Operator::EQU; .)
   ( equal
   | (ne1 | ne2)           (. op = Operator::NE; .)
   
   | lse                   (. op = Operator::LSE; .)
   | lss                   (. op = Operator::LSS; .)
   
   | gte                   (. op = Operator::GTE; .)
   | gtr                   (. op = Operator::GTR; .)
   
   ).
   
 END Xreate.
diff --git a/config/default.json b/config/default.json
index f72b68e..9f1f85a 100644
--- a/config/default.json
+++ b/config/default.json
@@ -1,73 +1,69 @@
 {
     "containers": {
       "id": {
           "implementations": "impl_fulfill_cluster",
           "clusters": "var_cluster",
           "prototypes": "proto_cluster",
           "linkedlist": "linkedlist"
       }, 
       
       "impl": {
         "solid": "solid",
         "onthefly": "on_the_fly"
       }
     },
     
     "logging": {
       "id": "logging"
     },
     
     "function-entry": "entry",
     
     "clasp": {
       "bindings" : {
         "variable": "bind",
         "function": "bind_func",
         "scope": "bind_scope",
         "function_demand" : "bind_function_demand",
         "scope_decision": "bind_scope_decision"
       },
       
       "context" : {
         "decisions":{
             "dependent": "resolution_dependency"
         },
       }, 
       
       "nonevalue": "nonevalue",
       "ret": {
         "symbol": "retv",
         "tag": "ret"
       } 
     },
     
     "tests": { 
-      "template": "containers",
+      "template": "default",
       
       "templates": {
         "default": "*-",
         
-        "basic": "Basic.*",
+        "adhocs": "Adhoc.*",
+        "effects": "Effects.*",
+        "basic": "Attachments.*", 
         "ast": "AST.*",
         "cfa": "CFA.*",
         "dfa": "DFA.*",
-        "compilation": "Compilation.*",
-        "containers": "Containers.ListAsArray2-",
+        "compilation": "Compilation.*",        
         "diagnostic": "Diagnostic.*",
-        "serializer": "ExpressionSerializer.*",
+        "ExpressionSerializer": "ExpressionSerializer.*",
         "externc": "InterfaceExternC.*",
-        "context": "ExpressionSerializer.*:Context.*",
-        "types": "Types.*-",
-        "log":  "Logging*",
-        "clang": "ClangAPI.*",
-        "skip": "SkipDetection*:Adhoc_Loop_SkipDetection.*",
-        "raw-xml": "libxml2*",
-        "xml": "Xml.*",
-        "installation": "Compilation.*:Sprint1.*",
-        "exploitation": "Exploitation.*",
-        "loops": "Loop.*",
+        "types": "Types.*-",       
+        "vendorsAPI/clang": "ClangAPI.*",
+        "vendorsAPI/xml2": "libxml2*",
         "dsl": "Interpretation.*",
-        "adhocs": "Adhoc.*",
+        "context": "Context.*",
+        "containers": "Containers.*",
+        "loops": "Loop.*"
       }
     }
 }
diff --git a/core/containers.lp b/core/containers.lp
index 63b7269..16b5432 100644
--- a/core/containers.lp
+++ b/core/containers.lp
@@ -1,58 +1,44 @@
 %defines
-  impl(solid; on_the_fly; linked_list). 
-  op(seqaccess; randaccess).
+  impl(llvm_array; llvm_const_array; on_the_fly). 
+  op(seqaccess). op(randaccess).
   
   relation(recommends; satisfied; unsupported).
   relation_score(satisfied, 0).
   relation_score(recommends, 1).
   relation_score(unsupported, -1).
   score(-1..1).
 
 %domain facts:
         relation_op(seqaccess, on_the_fly, recommends).
-        
-        relation_op(randaccess, solid, recommends).
+        relation_op(randaccess, llvm_const_array, recommends).
         relation_op(randaccess, on_the_fly, unsupported).
         
 %dfa analysis: 
-%scheme:       dfa_connection(Vto, Vfrom, proto);
-%--            dfa_connection(VTo, VFrom, alias); 
-%--            dfa_connection(VFormal, VActual, arg); 
-%--            dfa_connection(VActual, VFormal, ret)
+% --
 
 %compilation:
 %--
 
 %domain rules:
-  %aliases:
-        var_origin(VAR) :- not dfa_connection(VAR, _, alias), v(VAR).
-        var_alias(VAR0, VAR_TO) :- dfa_connection(VAR_TO, VAR0, alias), var_origin(VAR0).
-        var_alias(VAR0, VAR_TO2) :- dfa_connection(VAR_TO2, VAR_TO1, alias), var_alias(VAR0, VAR_TO1).
-        var_alias(VAR0, VAR0):- var_origin(VAR0).
-  
-  %prototypes:
-        var_proto(V0, Vproto) :- var_origin(V0); var_origin(Vproto); var_alias(Vproto, Vp); dfa_connection(V0, Vp, proto).
-
-  %implementations:
         -impl_fulfill(OP, IMPL) :- relation_op(OP, IMPL, unsupported).
         impl_fulfill(OP, IMPL, SCORE):- SCORE = #sum{SCORE1, (OP, IMPL, RL): relation_op(OP, IMPL, RL),relation_score(RL, SCORE1)}
             ; op(OP); impl(IMPL); not -impl_fulfill(OP, IMPL).
             
-        -var_impl_fulfill(Var0, Impl) :- var_alias(Var0, Var_Any); bind(Var_Any, op(Op)); -impl_fulfill(Op, Impl).
-        var_impl_fulfill(VAR0, IMPL, Score) :- 
-            Score = #sum{SCORE, (OP, IMPL, VAR_ANY): impl_fulfill(OP, IMPL, SCORE), var_alias(VAR0, VAR_ANY), bind(VAR_ANY, op(OP))}
-          ; bind(VAR0, impl(IMPL)); var_origin(VAR0); not -var_impl_fulfill(VAR0, IMPL).
+        cluster_root(VAR) :- not dfa_connection(VAR, _, strong), v(VAR).
+        var_cluster(VAR0, VAR_TO) :- dfa_connection(VAR_TO, VAR0, strong), cluster_root(VAR0).
+        var_cluster(VAR0, VAR_TO2) :- dfa_connection(VAR_TO2, VAR_TO1, strong), var_cluster(VAR0, VAR_TO1).
+        var_cluster(VAR0, VAR0):- cluster_root(VAR0).
 
-  %transfunction implementation:
-        %bind(Vactual, op(Op)) :- var_alias(Vformal, V1); bind(V1, op(Op)); dfa_connection(Vformal, Vactual, arg); op(Op).
+        -impl_fulfill_cluster(Var0, Impl) :- var_cluster(Var0, Var_Any); bind(Var_Any, op(Op)); -impl_fulfill(Op, Impl).
+        impl_fulfill_cluster(VAR0, IMPL, Score) :- 
+            Score = #sum{SCORE, (OP, IMPL, VAR_ANY): impl_fulfill(OP, IMPL, SCORE), var_cluster(VAR0, VAR_ANY), bind(VAR_ANY, op(OP))}
+          ; bind(VAR0, impl(IMPL)); cluster_root(VAR0); not -impl_fulfill_cluster(VAR0, IMPL).
+          
         
-        %bind(Vactual, op(Op)) :- var_alias(VO, Vformal); var_alias(VO, V); bind(V, op(Op)); dfa_connection(Vactual,Vformal, ret); op(Op).
-        % --uncomment to add possible implementations(impl) to an actual var
-        %bind(Vres, op(Op)) :- var_alias(VO, VA); bind(VA, op(Op)); dfa_connection(VArg,VO, result); op(Op).
+        proto_cluster(V0, Vproto) :- cluster_root(V0); cluster_root(Vproto); var_cluster(Vproto, Vp); dfa_connection(V0, Vp, proto).
         
 %optimization
-%  #maximize {SCORE, (VAR0, IMPL) : var_impl_fulfill(VAR0, IMPL, SCORE)}.
+%  #maximize {SCORE, (VAR0, IMPL) : impl_fulfill_cluster(VAR0, IMPL, SCORE)}.
 
-#show var_alias/2.
-#show var_impl_fulfill/3. 
-#show proto_alias2.
+#show var_cluster/2.
+#show impl_fulfill_cluster/3. 
diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt
index beae275..0f5feae 100644
--- a/cpp/CMakeLists.txt
+++ b/cpp/CMakeLists.txt
@@ -1,34 +1,35 @@
+project(Xreate)
 cmake_minimum_required(VERSION 2.8.11)
 
 set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -Wall -fprofile-arcs -ftest-coverage -O0")
 set(CMAKE_BUILD_TYPE Debug)
 
 #       BUILD OPTIONS
 #======================
 set(XREATE_DEFINITIONS
     -D_GNU_SOURCE -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -DWITH_THREADS=1
 )
 
 add_definitions(${XREATE_DEFINITIONS})
 add_compile_options(-Winvalid-pch -fPIC -std=c++14)
 
 
 #       XREATE
 #======================
 add_subdirectory(src)
 
 
 #       XREATE-TESTS
 #======================
 if (BUILD_XREATE_TESTS)
     message ("Building xreate tests")
     add_subdirectory(tests)
 endif ()
 
 
 #       XREATE-SERVER
 #======================
 if (BUILD_XREATE_SERVER)
     message ("Building xreate server")
     add_subdirectory(../tools/execution-server execution-server)
 endif ()
diff --git a/cpp/src/CMakeLists.txt b/cpp/src/CMakeLists.txt
index f44d338..c42834a 100644
--- a/cpp/src/CMakeLists.txt
+++ b/cpp/src/CMakeLists.txt
@@ -1,211 +1,218 @@
 cmake_minimum_required(VERSION 2.8.11)
 project(xreate)
 cmake_policy(SET CMP0022 NEW)
 
 message("MODULES" ${CMAKE_MODULE_PATH})
 
 #       LLVM
 #======================
 FIND_PACKAGE (LLVM REQUIRED)
 set(LLVM_VERSION ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR})
 
 message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
 message("LLVM LIB PATH:" ${LLVM_LIBRARY_DIRS})
 message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
 
 INCLUDE_DIRECTORIES(${LLVM_INCLUDE_DIRS})
 message(STATUS "INCLUDE DIR: ${LLVM_INCLUDE_DIRS}")
 
 add_definitions(${LLVM_DEFINITIONS})
 message("LLVM DEFS: " ${LLVM_DEFINITIONS})
 
 llvm_map_components_to_libnames(LLVM_LIBS core nativecodegen native executionengine mcjit support option)
 message("LLVM LIBS: " ${LLVM_LIBS})
 
 
 
 #       CLANG
 #======================
 set(CLANG_LIBS
 	clangCodeGen 
 	clangASTMatchers
 	clangQuery
 	clangTooling
 	clangFrontend
 	clangSerialization
 	clangDriver
 	clangParse
 	clangSema
 	clangAnalysis
 	clangAST
 	clangEdit
 	clangLex
 	clangBasic	
 )
 
 
 
 #       POTASSCO
 #======================
 set(POTASSCO_PATH "/opt/potassco/clingo" CACHE PATH "Path to potassco sources")
 set(POTASSCO_INCLUDE_PATH
     ${POTASSCO_PATH}/libgringo
     ${POTASSCO_PATH}/libclasp
     ${POTASSCO_PATH}/libclingo
     ${POTASSCO_PATH}/libprogram_opts
     ${POTASSCO_PATH}/liblp
 )
 INCLUDE_DIRECTORIES(${POTASSCO_INCLUDE_PATH})
 set(LIBCLASP_LIBS
     clingo
     clasp
     gringo
     program_opts
     reify
     lp
 )
 message("CLASP LIBS: " ${LIBCLASP_LIBS})
 
 
 
 #       OTHER DEPENDENCIES
 #===========================
 set(JEAYESON_INCLUDE_PATH
     ${CMAKE_HOME_DIRECTORY}/../vendors/jeayeson/include/
 )
 INCLUDE_DIRECTORIES(${JEAYESON_INCLUDE_PATH})
 
 
 
 #       COCO
 #===========================
 
 set(COCO_EXECUTABLE "" CACHE PATH "Path to coco executable")
 set(COCO_FRAMES_PATH "" CACHE PATH "Path to coco frames")
 
 set(COCO_GRAMMAR_PATH ${CMAKE_HOME_DIRECTORY}/../coco/)
 set(COCO_SOURCE_FILES 
         ${COCO_GRAMMAR_PATH}/Parser.cpp
         ${COCO_GRAMMAR_PATH}/Scanner.cpp)
 INCLUDE_DIRECTORIES(${COCO_GRAMMAR_PATH})
 
 add_custom_command(OUTPUT ${COCO_SOURCE_FILES}
     COMMAND ${COCO_GRAMMAR_PATH}/gen-grammar ${COCO_EXECUTABLE} ${COCO_FRAMES_PATH}
     WORKING_DIRECTORY ${COCO_GRAMMAR_PATH}
     MAIN_DEPENDENCY ${COCO_GRAMMAR_PATH}/xreate.ATG
 )
 message(STATUS "COCO GRAMMAR BUILD STATUS:" ${COCO_OUTPUT})
 
 
 
 #       XREATE
 #======================
 set(SOURCE_FILES
-    pass/compilepass.cpp     
-    ast.cpp
-    ExternLayer.cpp 
-    attachments.cpp
-    analysis/cfagraph.cpp
-    analysis/dfagraph.cpp
-    analysis/aux.cpp
-    compilation/containers.cpp
-    compilation/advanced.cpp
     compilation/transformations.cpp
-    clasplayer.cpp
-    compilation/latecontextcompiler2.cpp
-    query/context.cpp
-    #compilation/latecontextcompiler.cpp
-    serialization/expressionserializer2.cpp
-    llvmlayer.cpp 
-    utils.cpp
-    passmanager.cpp
-    pass/abstractpass.cpp pass/dfapass.cpp 
-    pass/cfapass.cpp
-    pass/adhocpass.cpp
-    contextrule.cpp
-    query/containers.cpp
-    pass/loggerpass.cpp
-	pass/interpretationpass.cpp
-	serialization/expressionserializer.cpp
+    compilation/transformersaturation.cpp
+    pass/compilepass.cpp 
+    pass/dfapass.cpp 
+    analysis/dfagraph.cpp
+    
+    pass/versionspass.cpp
     compilation/targetinterpretation.cpp
-    analysis/DominatorsTreeAnalysisProvider.cpp
+        
+    attachments.cpp
+    ast.cpp
     
-    #query/ptrvalid.cpp
-    #pass/rulespass.cpp #
+     ExternLayer.cpp 
+
+     analysis/cfagraph.cpp
+     
+     analysis/aux.cpp
+     compilation/containers.cpp
+     compilation/advanced.cpp
+
+     clasplayer.cpp
+     compilation/latecontextcompiler2.cpp
+     query/context.cpp
+     
+     llvmlayer.cpp 
+     utils.cpp
+     passmanager-bare.cpp
+     passmanager-full.cpp
+     pass/abstractpass.cpp 
+     
+     pass/cfapass.cpp
+     pass/adhocpass.cpp
+     contextrule.cpp
+     query/containers.cpp
+ 	 pass/interpretationpass.cpp
+     analysis/DominatorsTreeAnalysisProvider.cpp
+     serialization/expressionserializer.cpp
 )
 
 set(XREATE_INCLUDE_DIRS
     ${CMAKE_CURRENT_SOURCE_DIR}/
 )
 
 INCLUDE_DIRECTORIES(${XREATE_INCLUDE_DIRS})
 
 set(XREATE_PRIVATE_INCLUDE_DIRS
     ${XREATE_INCLUDE_DIRS}
     ${COCO_GRAMMAR_PATH}
     ${JEAYESON_INCLUDE_PATH}
     ${LLVM_INCLUDE_DIRS}
     ${POTASSCO_INCLUDE_PATH}
 )
 
 add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${COCO_SOURCE_FILES})
+
 target_link_libraries(${PROJECT_NAME})
 
 
 target_include_directories(${PROJECT_NAME} INTERFACE 
     ${XREATE_INCLUDE_DIRS}
     ${COCO_GRAMMAR_PATH}
     ${JEAYESON_INCLUDE_PATH}
     ${LLVM_INCLUDE_DIRS}
     ${POTASSCO_INCLUDE_PATH}
 )
 
 get_directory_property(DEFINITIONS_ALL DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS)
 message("definitions all: " ${DEFINITIONS_ALL})
 target_compile_definitions(${PROJECT_NAME} INTERFACE ${DEFINITIONS_ALL})
 
 get_directory_property(COMPILATION_OPTIONS_ALL DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_OPTIONS)
 message("compilations all: " ${COMPILATION_OPTIONS_ALL})
 target_compile_options(${PROJECT_NAME} INTERFACE ${COMPILATION_OPTIONS_ALL})
 
 SET_PROPERTY(TARGET ${PROJECT_NAME} PROPERTY
     INTERFACE_LINK_LIBRARIES ${LIBCLASP_LIBS} ${CLANG_LIBS} ${LLVM_LIBS}    tbb
 )
 
 #${CLANG_LIBS}
 
 
 #set (LINK_INTERFACE_LIBRARIES "")
 
 # FUNCTION(PREPEND var prefix)
 #    SET(listVar "")
 #    FOREACH(f ${ARGN})
 #       LIST(APPEND listVar "${prefix}/${f}")
 #    ENDFOREACH(f)
 #    SET(${var} "${listVar}" PARENT_SCOPE)
 # ENDFUNCTION(PREPEND)
 
 #set(COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "-j4")
 #cotire(xreate)
 
 
 # MACRO (ADD_PCH_RULE  _header_filename _src_list)
 # 	SET(_gch_filename "${_header_filename}.gch")
 # 	LIST(APPEND ${_src_list} ${_gch_filename})
 # 	SET (_args ${CMAKE_CXX_FLAGS})
 # 	LIST(APPEND _args -c ${_header_filename} -o ${_gch_filename})
 # 	GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES)
 # 	foreach (_inc ${DIRINC})
 # 		LIST(APPEND _args "-I" ${_inc})
 # 	endforeach(_inc ${DIRINC})
 # 	SEPARATE_ARGUMENTS(_args)
 # 	add_custom_command(OUTPUT ${_gch_filename}
 # 		   COMMAND rm -f ${_gch_filename}
 # 		   COMMAND ${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1} ${_args}
 # 			    DEPENDS ${_header_filename})
 # ENDMACRO(ADD_PCH_RULE _header_filename _src_list)
 
 # ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/ast.h SOURCE_FILES)
 # ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/llvmlayer.h SOURCE_FILES)
 # ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/clasplayer.h SOURCE_FILES)
 # ADD_PCH_RULE (${CMAKE_HOME_DIRECTORY}/src/pass/abstractpass.h SOURCE_FILES)
diff --git a/cpp/src/analysis/aux.cpp b/cpp/src/analysis/aux.cpp
index 6d5192c..7ac53fc 100644
--- a/cpp/src/analysis/aux.cpp
+++ b/cpp/src/analysis/aux.cpp
@@ -1,136 +1,136 @@
 #include "aux.h"
 #include <boost/format.hpp>
 
 namespace xreate { namespace analysis {
 
 using namespace std;
 
 list<string>
 multiplyLists(list<list<string>> &&lists) {
     typedef list<string> StringList;
     assert(lists.size());
     StringList result(*lists.begin());
     lists.pop_front();
 
     boost::format concat("%s, %s");
     for (StringList &list: lists) {
         StringList::const_iterator end = result.end();
         for (StringList::iterator expr1I = result.begin(); expr1I != end; ++expr1I) {
             if (list.size() == 0) continue;
 
             StringList::const_iterator expr2I = list.begin();
             for (int expr2No = 0, size = list.size() - 1; expr2No < size; ++expr2No, ++expr1I)
                 result.push_back(str(concat %(*expr1I) %(*expr2I)));
 
             *expr1I = str(concat %(*expr1I) %(*expr2I));
         }
     }
 
     return result;
 }
 
 std::list<std::string>
 compile(const Expression &e){
     list<string> result;
 
     switch (e.op) {
         case Operator::CALL: {
             assert(e.__state == Expression::COMPOUND);
 
             std::list<list<string>> operands;
             std::transform(e.operands.begin(), e.operands.end(), std::inserter(operands, operands.begin()),
                     [](const Expression &e) {
                         return compile(e);
                     });
 
             list<string> &&operands_ = multiplyLists(std::move(operands));
             result.push_back(boost::str(boost::format("%1%(%2%)") % (e.getValueString()) % (boost::algorithm::join(operands_, ", "))));
             break;
         }
         case Operator::NEG: {
             assert(e.operands.size() == 1);
 
             const Expression &op = e.operands.at(0);
             list<string> &&rawOp = compile(op);
 
             assert(rawOp.size() == 1);
             result.push_back((boost::format("not %1%")%(rawOp.front())).str());
             break;
         };
 
         case Operator::NONE: {
             switch (e.__state) {
                 case Expression::IDENT:
                     result.push_back(e.getValueString());
                     break;
 
                 case Expression::NUMBER:
                     result.push_back(to_string(e.getValueDouble()));
                     break;
 
                 default:
                     assert(true);
             }
             break;
         }
 
         default: break;
     }
 
 //TODO Null ad hoc ClaspLayer implementation
 //        if (e.isNone()){
 //             result.push_back(e.__valueS);
 //        }
 
     assert(result.size());
     return result;
 }
 
 std::list<std::string>
 compileNeg(const Expression &e){
     list<string> result;
     switch (e.op) {
         case Operator::IMPL: {
             assert(e.__state == Expression::COMPOUND);
             assert(e.operands.size() == 2);
             list<string> operands1 = compile(e.operands.at(0));
             list<string> operands2 = compile(e.operands.at(1));
 
             boost::format formatNeg("%1%, not %2%");
             for (const auto &op1: operands1)
                 for (const auto &op2: operands2) {
                     result.push_back(boost::str(formatNeg %(op1) % (op2)));
                 }
             break;
         }
         case Operator::NEG: {
             assert(e.operands.size() == 1);
 
             const Expression &op = e.operands.at(0);
             list<string> &&rawOp = compile(op);
 
             assert(rawOp.size() == 1);
             result.push_back(rawOp.front());
             break;
         };
 
         default:
             assert(true);
     }
 
     return result;
 }
 
-boost::format 
+boost::format
 formatSymbol(const SymbolPacked& s){
-    boost::format formatSymbNamed("(%1%, %2%)");
-    boost::format formatSymbAnonymous("(anonym(%1%), %2%)");
+    boost::format formatSymbNamed("(%1%, %2%, %3%)");
+    boost::format formatSymbAnonymous("anonym(%1%, %2%)");
 
     if (!s.categoryTransient){
-        return formatSymbNamed % s.identifier % s.scope;
+        return formatSymbNamed % s.identifier % s.version % s.scope;
     } else {
         return formatSymbAnonymous % s.identifier % s.scope;
     }
 }
-    
+
 }}
\ No newline at end of file
diff --git a/cpp/src/analysis/dfagraph.cpp b/cpp/src/analysis/dfagraph.cpp
index 00a3006..b1f52dc 100644
--- a/cpp/src/analysis/dfagraph.cpp
+++ b/cpp/src/analysis/dfagraph.cpp
@@ -1,250 +1,250 @@
 #include "analysis/dfagraph.h"
 #include "analysis/aux.h"
 
 #include <list>
 
 
 using namespace xreate;
 using namespace xreate::analysis;
 using namespace std;
 
 namespace xreate {
     namespace analysis {
 
         void
         DFAGraph::print(std::ostringstream& output) const {
             std::set<SymbolPacked> symbols;
 
             output << endl << "%\t\tStatic analysis: DFA" << endl;
 
             std::vector<std::pair<SymbolPacked, SymbolPacked>>::const_iterator i1;
             std::vector<DFGConnection>::const_iterator i2;
 
             boost::format formatDfaConnection("dfa_connection(%1%, %2%, %3%).");
             for (i1 = this->__edges.begin(), i2 = this->__data.begin(); i1 != this->__edges.end(); ++i1, ++i2) {
                 string edgeName;
                 switch (*i2) {
                     case DFGConnection::WEAK: edgeName = "weak";
                         break;
                     case DFGConnection::STRONG: edgeName = "strong";
                         break;
                     case DFGConnection::PROTOTYPE: edgeName = "proto";
                         break;
                 }
 
                 output << formatDfaConnection
                         % formatSymbol(i1->first)
                         % formatSymbol(i1->second)
                         % edgeName
                         << " %" << this->__clasp->getHintForPackedSymbol(i1->first) << " - " << this->__clasp->getHintForPackedSymbol(i1->second)
                         << endl;
 
                 symbols.insert(i1->first);
                 symbols.insert(i1->second);
             }
 
             boost::format formatDfaDependency("dfa_dependency(%1%, %2%).");
             for (auto i = this->__dependencies.begin(); i != this->__dependencies.end(); ++i) {
                 output << formatDfaDependency
                         % formatSymbol(i->first)
                         % formatSymbol(i->second)
                         << " %"
                         << this->__clasp->getHintForPackedSymbol(i->first) << " - "
                         << this->__clasp->getHintForPackedSymbol(i->second)
                         << endl;
             }
 
             boost::format formatBind("bind(%1%, %2%).");
             for (const pair<SymbolPacked, Expression>& tag : this->__tags) {
                 for (string variant : xreate::analysis::compile(tag.second)) {
                     output << formatBind
                             % formatSymbol(tag.first)
                             % (variant)
                             << "%" << this->__clasp->getHintForPackedSymbol(tag.first)
                             << endl;
                 }
 
                 symbols.insert(tag.first);
             }
 
             for (const SymbolPacked& s : symbols) {
                 output << "v(" << formatSymbol(s) << ")."
                         << " %" << this->__clasp->getHintForPackedSymbol(s)
                         << endl;
             }
         }
 
         class VisitorAddTag : public boost::static_visitor<> {
         public:
 
             void operator()(const SymbolPacked& symbol) {
                 __graph->__tags.emplace(symbol, move(__tag));
             }
 
-            void operator()(SymbolTransient& symbol) {
+            void operator()(SymbolAnonymous& symbol) {
                 symbol.tags.push_back(move(__tag));
             }
 
             void operator()(const SymbolInvalid& symbol) {
                 assert(false && "Undefined behaviour");
             }
 
             VisitorAddTag(DFAGraph * const dfagraph, Expression&& tag) :
             __graph(dfagraph), __tag(tag) {
             }
 
         private:
             DFAGraph * const __graph;
             Expression __tag;
         };
 
         class VisitorAddLink : public boost::static_visitor<> {
         public:
 
             void operator()(const SymbolPacked& nodeFrom) {
                 if (!__graph->isConnected(__nodeTo, nodeFrom)) {
                     __graph->__edges.emplace_back(__nodeTo, nodeFrom);
                     __graph->__data.push_back(__link);
 
                     DFAGraph::EdgeId eid = __graph->__edges.size() - 1;
                     __graph->__outEdges.emplace(nodeFrom, eid);
                 }
             }
 
-            void operator()(const SymbolTransient& symbolFrom) {
+            void operator()(const SymbolAnonymous& symbolFrom) {
                 switch (__link) {
                     case DFGConnection::WEAK:
                     {
                         //virtual symbol to hold transient annotations
                         SymbolPacked symbPivot = __graph->createAnonymousSymbol(symbolFrom.scope);
 
                         __graph->addConnection(symbPivot, symbolFrom, DFGConnection::STRONG);
                         __graph->addConnection(__nodeTo, symbPivot, DFGConnection::WEAK);
                         break;
                     }
 
                     case DFGConnection::STRONG:
                     {
                         for (const Expression& tag : symbolFrom.tags) {
                             __graph->__tags.emplace(__nodeTo, tag);
                         }
                         break;
                     }
 
                     default:
                         assert(false && "Undefined behavior");
                 }
             }
 
             void operator()(const SymbolInvalid&) {
                 if (__link == DFGConnection::STRONG) return;
                 if (__link == DFGConnection::WEAK) return;
 
                 assert(false && "Undefined behavior");
             }
 
             VisitorAddLink(DFAGraph * const dfagraph, const SymbolPacked& nodeTo, DFGConnection link) :
             __graph(dfagraph), __nodeTo(nodeTo), __link(link) {
             }
 
         private:
             DFAGraph * const __graph;
             SymbolPacked __nodeTo;
             DFGConnection __link;
         };
 
         class VisitorGetDependencyConnection : public boost::static_visitor<list<SymbolPacked>>
         {
             public:
 
             list<SymbolPacked>
                     operator()(const SymbolPacked & nodeFrom) {
                 return
                 {
                     nodeFrom
                 };
             }
 
             list<SymbolPacked>
-                    operator()(const SymbolTransient & nodeFrom) {
+                    operator()(const SymbolAnonymous & nodeFrom) {
                 return nodeFrom.dependencies;
             }
 
             list<SymbolPacked>
                     operator()(const SymbolInvalid&) {
                 assert(false && "Undefined behavior");
             }
 
             VisitorGetDependencyConnection(DFAGraph * const g) : graph(g) {
             }
             DFAGraph * const graph;
         };
 
         class VisitorSetDependencyConnection : public boost::static_visitor<> {
         public:
 
             void operator()(SymbolPacked& nodeTo) {
                 VisitorGetDependencyConnection visitorGetDepenencies(graph);
                 auto deps = boost::apply_visitor(visitorGetDepenencies, nodeFrom);
 
                 for (const SymbolPacked& dep : deps) {
                     graph->__dependencies.emplace(nodeTo, dep);
                 }
             }
 
-            void operator()(SymbolTransient& nodeTo) {
+            void operator()(SymbolAnonymous& nodeTo) {
                 VisitorGetDependencyConnection visitorGetDepenencies(graph);
                 auto deps = boost::apply_visitor(visitorGetDepenencies, nodeFrom);
 
                 for (const SymbolPacked& dep : deps) {
                     nodeTo.dependencies.push_back(dep);
                 }
             }
 
             void operator()(SymbolInvalid&) {
                 assert(false && "Undefined behavior");
             }
 
             VisitorSetDependencyConnection(DFAGraph * const g, SymbolNode s) : graph(g), nodeFrom(s) {
             }
             DFAGraph * const graph;
             SymbolNode nodeFrom;
         };
 
         bool
         DFAGraph::isConnected(const SymbolPacked& identifierTo, const SymbolPacked& identifierFrom) {
             auto range = __outEdges.equal_range(identifierFrom);
 
             for (std::multimap<SymbolPacked, EdgeId>::iterator edge = range.first; edge != range.second; ++edge) {
                 if (__edges[edge->second].second == identifierTo)
                     return true;
             }
 
             return false;
         }
 
         void
         DFAGraph::addConnection(const SymbolPacked& nodeTo, const SymbolNode& nodeFrom, DFGConnection link) {
             VisitorAddLink visitor(this, nodeTo, link);
             boost::apply_visitor(visitor, nodeFrom);
         }
 
         void
         DFAGraph::addDependencyConnection(SymbolNode& identifierTo, SymbolNode& identifierFrom) {
             VisitorSetDependencyConnection visitor(this, identifierFrom);
             boost::apply_visitor(visitor, identifierTo);
         }
 
         void
         DFAGraph::addAnnotation(SymbolNode& node, Expression&& tag) {
             VisitorAddTag visitor(this, move(tag));
             boost::apply_visitor(visitor, node);
         }
 
         SymbolPacked
         DFAGraph::createAnonymousSymbol(const ScopePacked& scope) {
-            return SymbolPacked(__countAnonymousSymbols++, scope, true);
+            return SymbolPacked(ScopedSymbol{__countAnonymousSymbols++, 0}, scope, true);
         }
 
     }
 }
\ No newline at end of file
diff --git a/cpp/src/analysis/dfagraph.h b/cpp/src/analysis/dfagraph.h
index 374ab14..7962c77 100644
--- a/cpp/src/analysis/dfagraph.h
+++ b/cpp/src/analysis/dfagraph.h
@@ -1,57 +1,60 @@
 /* 
  * File:   dfa.h
  * Author: pgess
  *
  * Created on June 27, 2016, 1:50 PM
  */
 
 #ifndef DFA_H
 #define DFA_H
 
 #include "clasplayer.h"
 
 namespace xreate {namespace analysis {
 
-    struct SymbolTransient {
+    struct SymbolAnonymous {
+        SymbolAnonymous(unsigned int symbolId): id(symbolId){}
+        
+        unsigned int id;
         std::list<Expression> tags;
         ScopePacked scope;
         std::list<SymbolPacked> dependencies;
     };
-
+    
     struct SymbolInvalid { };
 
-    typedef boost::variant<SymbolInvalid, SymbolTransient, xreate::SymbolPacked> SymbolNode;
+    typedef boost::variant<SymbolInvalid, SymbolAnonymous, SymbolPacked> SymbolNode;
     
     class DFAGraph: public IAnalysisData{
             friend class VisitorAddTag;
             friend class VisitorAddLink;
             friend class VisitorGetDependencyConnection;
             friend class VisitorSetDependencyConnection;
             
             
         public:
             DFAGraph(ClaspLayer* engine): __clasp(engine){}
             
             SymbolPacked createAnonymousSymbol(const ScopePacked& scope);
             void addAnnotation(SymbolNode& identifier, Expression&& tag);
             void addConnection(const SymbolPacked& identifierTo, const SymbolNode& identifierFrom, DFGConnection link);
             void addDependencyConnection(SymbolNode& identifierTo, SymbolNode& identifierFrom);
             bool isConnected(const SymbolPacked& identifierTo, const SymbolPacked& identifierFrom);
 
             void print(std::ostringstream& output) const;
             
         private:
             typedef unsigned int EdgeId;
             std::vector<std::pair<SymbolPacked, SymbolPacked>> __edges;
             std::multimap<SymbolPacked, EdgeId> __outEdges;
             std::vector<DFGConnection> __data;
             std::multimap<SymbolPacked, Expression> __tags;
             std::multimap<SymbolPacked, SymbolPacked> __dependencies;
 
             unsigned int __countAnonymousSymbols=0;
             ClaspLayer* __clasp;
     };
 }}
 
 #endif /* DFA_H */
 
diff --git a/cpp/src/ast.cpp b/cpp/src/ast.cpp
index 0ae05a9..95f4f66 100644
--- a/cpp/src/ast.cpp
+++ b/cpp/src/ast.cpp
@@ -1,816 +1,890 @@
 #include "ast.h"
 #include "ExternLayer.h"
 #include <stdexcept>
 #include <iostream>
-#include <clasplayer.h>
+
+namespace std{
+
+    std::size_t
+    hash<xreate::ScopedSymbol>::operator()(xreate::ScopedSymbol const& s) const
+    {return s.id ^ (s.version << 2);}
+
+    bool
+    equal_to<xreate::ScopedSymbol>::operator()(const xreate::ScopedSymbol& __x, const xreate::ScopedSymbol& __y) const
+    { return __x.id == __y.id && __x.version == __y.version; }
+}
 
 using namespace std;
 
-namespace xreate{
-class ExpressionHints{
-public:
-    static bool
-    isStringValueValid(const Expression& e){
-        switch (e.__state){
-            case Expression::INVALID:
-            case Expression::VARIANT:
-                assert(false);
+namespace xreate {
 
-            case Expression::IDENT:
-            case Expression::STRING:
-                return true;
+Atom<Identifier_t>::Atom(const std::wstring& value) {
+    __value = wstring_to_utf8(value);
+}
 
-            case Expression::NUMBER:
-            case Expression::BINDING:
-                return false;
+Atom<Identifier_t>::Atom(std::string && name) : __value(name)
+{}
+
+const std::string&
+Atom<Identifier_t>::get() const {
+    return __value;
+}
 
-            case Expression::COMPOUND: {
-                switch (e.op){
-                    case Operator::CALL:
-                    case Operator::INDEX:
-                        return true;
+Atom<Number_t>::Atom(wchar_t* value) {
+    //DEBT reconsider number literal recognition
+    __value = wcstol(value, 0, 10);
+}
+
+Atom<Number_t>::Atom(int value)
+: __value(value) {
+}
 
-                    default: return false;
+double
+Atom<Number_t>::get()const {
+    return __value;
+}
+
+Atom<String_t>::Atom(const std::wstring& value) {
+    assert(value.size() >=2);
+    __value = wstring_to_utf8(value.substr(1, value.size() -2));
+}
+
+const std::string&
+Atom<String_t>::get() const {
+    return __value;
+}
+
+    class ExpressionHints {
+    public:
+
+        static bool
+        isStringValueValid(const Expression& e) {
+            switch (e.__state) {
+                case Expression::INVALID:
+                    assert(false);
+
+                case Expression::IDENT:
+                case Expression::STRING:
+                    return true;
+
+                case Expression::NUMBER:
+                case Expression::BINDING:
+                case Expression::VARIANT:
+                    return false;
+
+                case Expression::COMPOUND:
+                {
+                    switch (e.op) {
+                        case Operator::CALL:
+                            return true;
+
+                        default: return false;
+                    }
                 }
             }
+
+            return false;
         }
 
-        return false;
-    }
+        static bool
+        isDoubleValueValid(const Expression& e) {
+            switch (e.__state) {
+                case Expression::NUMBER:
+                case Expression::VARIANT:
+                    return true;
+
+                case Expression::INVALID:
+                    assert(false);
+
+                case Expression::IDENT:
+                case Expression::STRING:
+                case Expression::COMPOUND:
+                case Expression::BINDING:
+                    return false;
+            }
 
-    static bool
-    isDoubleValueValid(const Expression& e){
-        switch (e.__state){
-            case Expression::NUMBER:
-                return true;
+            return false;
+        }
+    };
 
-            case Expression::INVALID:
-            case Expression::VARIANT:
-                assert(false);
+    class TypesResolver {
+    private:
+        const AST* ast;
+        std::map<std::string, TypeAnnotation> scope;
+        std::map<TypeAnnotation, int> signatures;
 
-            case Expression::IDENT:
-            case Expression::STRING:
-            case Expression::COMPOUND:
-            case Expression::BINDING:
-                return false;
+        ExpandedType expandType(const TypeAnnotation &t, const std::vector<TypeAnnotation> &args = std::vector<TypeAnnotation>()) {
+            return TypesResolver(ast, scope, signatures)(t, args);
         }
 
-        return false;
-    }
-};
+        std::vector<TypeAnnotation>
+        expandOperands(const std::vector<TypeAnnotation>& operands) {
+            std::vector<TypeAnnotation> pack;
 
-class TypesResolver {
-private:
-	const AST* ast;
-	std::map<std::string, TypeAnnotation> scope;
-	std::map<TypeAnnotation, int> signatures;
+            pack.reserve(operands.size());
+            std::transform(operands.begin(), operands.end(), std::inserter(pack, pack.end()),
+                    [this](const TypeAnnotation & t) {
+                        return expandType(t);
+                    });
 
+            return pack;
+        }
 
-	ExpandedType expandType(const TypeAnnotation &t, const std::vector<TypeAnnotation> &args = std::vector<TypeAnnotation>()){
-		return TypesResolver(ast, scope, signatures)(t, args);
-	}
+    public:
 
-	std::vector<TypeAnnotation>
-	expandOperands(const std::vector<TypeAnnotation>&  operands) {
-		std::vector<TypeAnnotation> pack;
-
-		pack.reserve(operands.size());
-	    std::transform(operands.begin(), operands.end(), std::inserter(pack, pack.end()),
-	                   [this](const TypeAnnotation& t){
-	                       return expandType(t);
-	                   });
-
-	    return pack;
-	}
-
-public:
-	TypesResolver(const AST* root, const std::map<std::string, TypeAnnotation>& scopeOuter = std::map<std::string, TypeAnnotation>(),
-			std::map<TypeAnnotation, int> signaturesOuter = std::map<TypeAnnotation, int>())
-	: ast(root), scope(scopeOuter), signatures(signaturesOuter) {
-	}
+        TypesResolver(const AST* root, const std::map<std::string, TypeAnnotation>& scopeOuter = std::map<std::string, TypeAnnotation>(),
+                std::map<TypeAnnotation, int> signaturesOuter = std::map<TypeAnnotation, int>())
+        : ast(root), scope(scopeOuter), signatures(signaturesOuter) {
+        }
 
+        ExpandedType
+        operator()(const TypeAnnotation &t, const std::vector<TypeAnnotation> &args = std::vector<TypeAnnotation>()) {
+            //assert(args.size() == t.bindings.size()); // invalid number of arguments
+            for (size_t i = 0; i < args.size(); ++i) {
+                scope[t.bindings.at(i)] = args.at(i);
+            }
 
+            switch (t.__operator) {
+                case TypeOperator::ARRAY:
+                {
+                    assert(t.__operands.size() == 1);
 
-	ExpandedType
-	operator()(const TypeAnnotation &t, const std::vector<TypeAnnotation> &args = std::vector<TypeAnnotation>())
-	{
-	    //assert(args.size() == t.bindings.size()); // invalid number of arguments
-        for (size_t i=0; i<args.size(); ++i)
-	    {
-	        scope[t.bindings.at(i)] =  args.at(i);
-	    }
-
-	    switch (t.__operator)
-	    {
-	        case TypeOperator::ARRAY:
-	        {
-	            assert(t.__operands.size()==1);
+                    Expanded<TypeAnnotation> elTy = expandType(t.__operands.at(0));
+                    return ExpandedType(TypeAnnotation(tag_array, elTy, 0));
+                }
 
-	            Expanded<TypeAnnotation> elTy = expandType(t.__operands.at(0));
-	            return ExpandedType(TypeAnnotation(tag_array, elTy, 0));
-	        }
+                case TypeOperator::STRUCT:
+                {
+                    assert(t.__operands.size());
 
-	        case TypeOperator::STRUCT:
-	        {
-	            assert(t.__operands.size());
+                    std::vector<TypeAnnotation>&& pack = expandOperands(t.__operands);
+                    auto tnew = TypeAnnotation(TypeOperator::STRUCT, move(pack));
+                    tnew.fields = t.fields;
 
-	            std::vector<TypeAnnotation>&& pack = expandOperands(t.__operands);
-	            auto tnew = TypeAnnotation(TypeOperator::STRUCT, move(pack));
-	            tnew.fields = t.fields;
+                    return ExpandedType(move(tnew));
+                };
 
-	            return ExpandedType(move(tnew));
-	        };
+                case TypeOperator::CALL:
+                {
+                    std::string alias = t.__valueCustom;
 
-	        case TypeOperator::CALL:
-	        {
-	            std::string alias = t.__valueCustom;
+                    //find in local scope:
+                    TypeAnnotation ty;
+                    if (scope.count(alias)) {
+                        ty = scope.at(alias);
 
-	            		//find in local scope:
-	            TypeAnnotation ty;
-	            if (scope.count(alias))            {
-	                ty = scope.at(alias);
+                    } else if (ast->__indexTypeAliases.count(alias)) {
+                        ty = ast->__indexTypeAliases.at(alias);
 
-	            } else if (ast->__indexTypeAliases.count(alias)){
-	            	ty = ast->__indexTypeAliases.at(alias);
+                    } else {
+                        assert(false && "Undefined or external type");
+                    }
 
-	            } else {
-	            	assert(false && "Undefined or external type");
-	            }
+                    std::vector<TypeAnnotation>&& operands = expandOperands(t.__operands);
+                    TypeAnnotation signature(TypeOperator::CALL, move(operands));
+                    signature.__valueCustom = alias;
 
-	            std::vector<TypeAnnotation>&& operands = expandOperands(t.__operands);
-	            TypeAnnotation signature(TypeOperator::CALL, move(operands));
-	            signature.__valueCustom = alias;
+                    if (signatures.count(signature)) {
+                        auto link = TypeAnnotation(TypeOperator::LINK,{});
+                        link.conjuctionId = signatures.at(signature);
 
-				if (signatures.count(signature)) {
-						auto link = TypeAnnotation(TypeOperator::LINK, {});
-						link.conjuctionId = signatures.at(signature);
+                        return ExpandedType(move(link));
+                    }
 
-						return ExpandedType(move(link));
-				}
+                    int cid = signatures.size();
+                    signatures[signature] = cid;
+                    TypeAnnotation tyResult = expandType(ty, operands);
+                    tyResult.conjuctionId = cid;
 
-				int cid = signatures.size();
-				signatures[signature] = cid;
-	            TypeAnnotation tyResult = expandType(ty, operands);
-	            tyResult.conjuctionId = cid;
+                    return ExpandedType(move(tyResult));
+                };
 
-	            return ExpandedType(move(tyResult));
-	        };
+                case TypeOperator::CUSTOM:
+                {
+                    std::string alias = t.__valueCustom;
 
-	        case TypeOperator::CUSTOM:
-	        {
-	            std::string alias = t.__valueCustom;
-
-	            /*
-	            if (signatures.count(alias)) {
-	            	return ExpandedType(TypeAnnotation(TypeOperator::LINK, {t}));
-	            }
-	            signatures[alias].emplace(t);
-	            */
-
-	            //find in local scope:
-	            if (scope.count(alias))
-	            {
-	                return expandType(scope.at(alias));
-	            }
-
-	            // find in general scope:
-	            if(ast->__indexTypeAliases.count(alias)) {
-	                return expandType(ast->__indexTypeAliases.at(t.__valueCustom));
-	            }
-
-	            //if type is unknown keep it as is.
-	            return ExpandedType(TypeAnnotation(t));
-	        };
-
-	        case TypeOperator::ACCESS:
-	        {
-	        	std::string alias = t.__valueCustom;
-	        	ExpandedType tyAlias= ExpandedType(TypeAnnotation());
+                    /*
+                    if (signatures.count(alias)) {
+                        return ExpandedType(TypeAnnotation(TypeOperator::LINK, {t}));
+                    }
+                    signatures[alias].emplace(t);
+                     */
 
-	        			//find in local scope:
-				if (scope.count(alias)) {
-					tyAlias = expandType(scope.at(alias));
-
-						//find in global scope:
-				} else if((ast->__indexTypeAliases.count(alias))) {
-					tyAlias = expandType(ast->__indexTypeAliases.at(alias));
-
-				} else {
-					assert(false && "Undefined or external type");
-				}
+                    //find in local scope:
+                    if (scope.count(alias)) {
+                        return expandType(scope.at(alias));
+                    }
 
-				assert(tyAlias->__operator == TypeOperator::STRUCT);
-
-				for (const string& field: t.fields){
-					auto fieldIt = std::find(tyAlias->fields.begin(), tyAlias->fields.end(), field);
-					assert(fieldIt != tyAlias->fields.end() && "unknown field");
+                    // find in general scope:
+                    if (ast->__indexTypeAliases.count(alias)) {
+                        return expandType(ast->__indexTypeAliases.at(t.__valueCustom));
+                    }
 
-					int fieldId =  fieldIt -  tyAlias->fields.begin();
-					tyAlias = expandType(tyAlias->__operands.at(fieldId));
-				}
+                    //if type is unknown keep it as is.
+                    return ExpandedType(TypeAnnotation(t));
+                };
 
-				return tyAlias;
-	        }
+                case TypeOperator::ACCESS:
+                {
+                    std::string alias = t.__valueCustom;
+                    ExpandedType tyAlias = ExpandedType(TypeAnnotation());
 
-	        case TypeOperator::TUPLE: {
-	            assert(t.__operands.size());
+                    //find in local scope:
+                    if (scope.count(alias)) {
+                        tyAlias = expandType(scope.at(alias));
 
-	            std::vector<TypeAnnotation> pack;
-	            pack.reserve(t.__operands.size());
+                        //find in global scope:
+                    } else if ((ast->__indexTypeAliases.count(alias))) {
+                        tyAlias = expandType(ast->__indexTypeAliases.at(alias));
 
-	            std::transform(t.__operands.begin(), t.__operands.end(), std::inserter(pack, pack.end()),
-	                           [this](const TypeAnnotation& t){
-	                               return expandType(t);
-	                           });
+                    } else {
+                        assert(false && "Undefined or external type");
+                    }
 
-	            return ExpandedType(TypeAnnotation(TypeOperator::TUPLE, move(pack)));
-	        }
-
-	        case TypeOperator::VARIANT: {
-	        	return ExpandedType(TypeAnnotation(t));
-	        }
+                    assert(tyAlias->__operator == TypeOperator::STRUCT);
 
-	        case TypeOperator::NONE: {
-	            return ExpandedType(TypeAnnotation(t));
-	        }
-
-	        default:
-	            assert(false);
-	    }
-
-	    assert(false);
-	    return  ExpandedType(TypeAnnotation());
-	}
-};
+                    for (const string& field : t.fields) {
+                        auto fieldIt = std::find(tyAlias->fields.begin(), tyAlias->fields.end(), field);
+                        assert(fieldIt != tyAlias->fields.end() && "unknown field");
 
-TypeAnnotation::TypeAnnotation()
-{
-}
+                        int fieldId = fieldIt - tyAlias->fields.begin();
+                        tyAlias = expandType(tyAlias->__operands.at(fieldId));
+                    }
 
-TypeAnnotation::TypeAnnotation(const Atom<Type_t> &typ)
-    : __value(typ.get())
-{
-    ;
-}
+                    return tyAlias;
+                }
 
-TypeAnnotation::TypeAnnotation (TypePrimitive typ)
-    : __value(typ)
-{}
+                case TypeOperator::TUPLE:
+                {
+                    assert(t.__operands.size());
 
-TypeAnnotation::TypeAnnotation(TypeOperator op, std::initializer_list<TypeAnnotation> operands)
-    : __operator(op), __operands(operands)
-{
+                    std::vector<TypeAnnotation> pack;
+                    pack.reserve(t.__operands.size());
 
-}
+                    std::transform(t.__operands.begin(), t.__operands.end(), std::inserter(pack, pack.end()),
+                            [this](const TypeAnnotation & t) {
+                                return expandType(t);
+                            });
 
-TypeAnnotation::TypeAnnotation (TypeOperator op, std::vector<TypeAnnotation>&& operands)
-        : __operator(op), __operands(operands)
-{}
+                    return ExpandedType(TypeAnnotation(TypeOperator::TUPLE, move(pack)));
+                }
 
+                case TypeOperator::VARIANT:
+                {
+                    return ExpandedType(TypeAnnotation(t));
+                }
 
-TypeAnnotation::TypeAnnotation (llvm_array_tag, TypeAnnotation typ, int size)
-    :TypeAnnotation(TypeOperator::ARRAY, {typ})
-{
-    __size=size;
-}
+                case TypeOperator::NONE:
+                {
+                    return ExpandedType(TypeAnnotation(t));
+                }
 
-bool
-TypeAnnotation::operator< (const TypeAnnotation& t) const{
-	if (__operator != t.__operator) return __operator < t.__operator;
+                default:
+                    assert(false);
+            }
 
-	if (__operator == TypeOperator::NONE)
-		return __value < t.__value;
+            assert(false);
+            return ExpandedType(TypeAnnotation());
+        }
+    };
 
-	if (__operator == TypeOperator::CALL || __operator == TypeOperator::CUSTOM || __operator == TypeOperator::ACCESS){
-			if (__valueCustom != t.__valueCustom)
-				return __valueCustom < t.__valueCustom;
-	}
+    TypeAnnotation::TypeAnnotation()
+        : __operator(TypeOperator::NONE), __value(TypePrimitive::Invalid)
+    {}
 
-	return __operands < t.__operands;
-}
+    TypeAnnotation::TypeAnnotation(TypePrimitive typ)
+    : __value(typ) {
+    }
 
-/*
-TypeAnnotation (struct_tag, std::initializer_list<TypeAnnotation>)
-{}
-*/
+    TypeAnnotation::TypeAnnotation(TypeOperator op, std::initializer_list<TypeAnnotation> operands)
+    : __operator(op), __operands(operands) {
 
-void
-TypeAnnotation::addBindings(std::vector<Atom<Identifier_t>>&& params)
-{
-    bindings.reserve(bindings.size() +  params.size());
+    }
 
-    std::transform(params.begin(), params.end(), std::inserter(bindings, bindings.end()),
-        [](const Atom<Identifier_t>& ident){return ident.get(); });
-}
+    TypeAnnotation::TypeAnnotation(TypeOperator op, std::vector<TypeAnnotation>&& operands)
+    : __operator(op), __operands(operands) {
+    }
 
-void
-TypeAnnotation::addFields(std::vector<Atom<Identifier_t>>&& listFields)
-{
-    fields.reserve(fields.size() + listFields.size());
+    TypeAnnotation::TypeAnnotation(llvm_array_tag, TypeAnnotation typ, int size)
+    : TypeAnnotation(TypeOperator::ARRAY,{typ}) {
+        __size = size;
+    }
 
-    std::transform(listFields.begin(), listFields.end(), std::inserter(fields, fields.end()),
-        [](const Atom<Identifier_t>& ident){return ident.get(); });
-}
+    bool
+    TypeAnnotation::isValid() const{
+        return !(__value == TypePrimitive::Invalid && __operator == TypeOperator::NONE);
+    }
 
-Expression::Expression(const Atom<Number_t>& number)
-: __state(NUMBER), op(Operator::NONE), __valueD(number.get())
-{
-}
+    bool
+    TypeAnnotation::operator<(const TypeAnnotation& t) const {
+        if (__operator != t.__operator) return __operator < t.__operator;
 
-Expression::Expression(const Atom<String_t>& a)
-        : __state(STRING), op(Operator::NONE), __valueS(a.get())
-{
-}
+        if (__operator == TypeOperator::NONE)
+            return __value < t.__value;
 
-Expression::Expression(const Atom<Identifier_t> &ident)
-    : __state(IDENT), op(Operator::NONE), __valueS(ident.get())
-{
-}
+        if (__operator == TypeOperator::CALL || __operator == TypeOperator::CUSTOM || __operator == TypeOperator::ACCESS) {
+            if (__valueCustom != t.__valueCustom)
+                return __valueCustom < t.__valueCustom;
+        }
+
+        return __operands < t.__operands;
+    }
 
-Expression::Expression(const Operator &oprt, std::initializer_list<Expression> params)
-    : __state(COMPOUND), op(oprt)
-{
-    if (op == Operator::CALL)
-    {
-        assert(params.size() > 0);
-        Expression arg = *params.begin();
+    /*
+    TypeAnnotation (struct_tag, std::initializer_list<TypeAnnotation>)
+    {}
+     */
 
-        assert(arg.__state == Expression::IDENT);
-        __valueS = std::move(arg.__valueS);
+    void
+    TypeAnnotation::addBindings(std::vector<Atom<Identifier_t>>&& params) {
+        bindings.reserve(bindings.size() + params.size());
 
-        operands.insert(operands.end(), params.begin()+1, params.end());
-        return;
+        std::transform(params.begin(), params.end(), std::inserter(bindings, bindings.end()),
+                [](const Atom<Identifier_t>& ident) {
+                    return ident.get(); });
     }
 
-    operands.insert(operands.end(), params.begin(), params.end());
-}
+    void
+    TypeAnnotation::addFields(std::vector<Atom<Identifier_t>>&& listFields) {
+        fields.reserve(fields.size() + listFields.size());
 
-void
-Expression::setOp(Operator oprt)
-{
-    op = oprt;
+        std::transform(listFields.begin(), listFields.end(), std::inserter(fields, fields.end()),
+                [](const Atom<Identifier_t>& ident) {
+                    return ident.get(); });
+    }
 
-    switch (op)
-    {
-        case Operator::NONE:
-            __state = INVALID;
-            break;
+    unsigned int Expression::nextVacantId = 0;
 
-        default:
-            __state = COMPOUND;
-            break;
+    Expression::Expression(const Atom<Number_t>& number)
+    : Expression() {
+        __state=NUMBER; op=Operator::NONE; __valueD=number.get();
     }
-}
 
-void
-Expression::addArg(Expression &&arg)
-{
-    operands.push_back(arg);
-}
+    Expression::Expression(const Atom<String_t>& a)
+    : Expression(){
+        __state=STRING; op=Operator::NONE; __valueS=a.get();
+    }
 
-void
-Expression::addBindings(std::initializer_list<Atom<Identifier_t>> params)
-{
-    addBindings(params.begin(), params.end());
-}
+    Expression::Expression(const Atom<Identifier_t> &ident)
+    : Expression() {
+        __state=IDENT; op=Operator::NONE; __valueS=ident.get();
+    }
 
-void
-Expression::bindType(TypeAnnotation t)
-{
-    type = move(t);
-}
+    Expression::Expression(const Operator &oprt, std::initializer_list<Expression> params)
+    : Expression() {
+        __state=COMPOUND; op=oprt;
 
-void
-Expression::addBlock(ManagedScpPtr scope)
-{
-    blocks.push_back(scope.operator ->());
-}
+        if (op == Operator::CALL) {
+            assert(params.size() > 0);
+            Expression arg = *params.begin();
 
-const std::vector<Expression>&
-Expression::getOperands() const
-{
-    return operands;
-}
+            assert(arg.__state == Expression::IDENT);
+            __valueS = std::move(arg.__valueS);
 
-double
-Expression::getValueDouble() const
-{
-    return __valueD;
-}
+            operands.insert(operands.end(), params.begin() + 1, params.end());
+            return;
+        }
 
-const std::string&
-Expression::getValueString() const
-{
-    return __valueS;
-}
+        operands.insert(operands.end(), params.begin(), params.end());
+    }
 
-void
-Expression::setValue(const Atom<Identifier_t>&& v){
-    __valueS = v.get();
-}
+    void
+    Expression::setOp(Operator oprt) {
+        op = oprt;
 
-void Expression::setValueDouble(double value){
-	__valueD = value;
-}
+        switch (op) {
+            case Operator::NONE:
+                __state = INVALID;
+                break;
 
-bool
-Expression::isValid() const{
-    return (__state != INVALID);
-}
+            default:
+                __state = COMPOUND;
+                break;
+        }
+    }
 
-bool
-Expression::isDefined() const{
-    return (__state != BINDING);
-}
+    void
+    Expression::addArg(Expression &&arg) {
+        operands.push_back(arg);
+    }
 
-Expression::Expression()
-    : __state(INVALID), op(Operator::NONE)
-{}
+    void
+    Expression::addTags(const std::list<Expression> tags) const{
+        std::transform(tags.begin(), tags.end(), std::inserter(this->tags, this->tags.end()),
+            [](const Expression& tag){
+                return make_pair(tag.getValueString(), tag);
+        });
+    }
 
-bool
-Expression::operator==(const Expression& other) const{
-    assert(!this->blocks.size());
-    assert(!other.blocks.size());
+    void
+    Expression::addBindings(std::initializer_list<Atom<Identifier_t>> params) {
+        addBindings(params.begin(), params.end());
+    }
 
-    if (this->__state != other.__state) return false;
+    void
+    Expression::bindType(TypeAnnotation t) {
+        type = move(t);
+    }
 
-    if (ExpressionHints::isStringValueValid(*this)){
-        if (this->__valueS != other.__valueS) return false;
+    void
+    Expression::addBlock(ManagedScpPtr scope) {
+        blocks.push_back(scope.operator->());
     }
 
-    if (ExpressionHints::isDoubleValueValid(*this)){
-        if (this->__valueD != other.__valueD) return false;
+    const std::vector<Expression>&
+    Expression::getOperands() const {
+        return operands;
     }
 
-    if (this->__state != Expression::COMPOUND){
-        return true;
+    double
+    Expression::getValueDouble() const {
+        return __valueD;
     }
 
-    if (this->operands.size() != other.operands.size()){
-        return false;
+    const std::string&
+    Expression::getValueString() const {
+        return __valueS;
     }
 
-    for (size_t i=0; i<this->operands.size(); ++i){
-        if (!(this->operands[i]==other.operands[i])) return false;
+    void
+    Expression::setValue(const Atom<Identifier_t>&& v) {
+        __valueS = v.get();
     }
 
-    return true;
-}
+    void Expression::setValueDouble(double value) {
+        __valueD = value;
+    }
 
+    bool
+    Expression::isValid() const {
+        return (__state != INVALID);
+    }
 
-AST::AST()
-{
-}
+    bool
+    Expression::isDefined() const {
+        return (__state != BINDING);
+    }
 
+    Expression::Expression()
+    : __state(INVALID), op(Operator::NONE), id(nextVacantId++)
+    {    }
 
-void
-AST::addInterfaceData(const ASTInterface& interface, Expression&& data ) {
-	__interfacesData.emplace(interface, move(data));
-}
+    bool
+    Expression::operator==(const Expression& other) const {
+        if (this->__state != other.__state) return false;
 
-void
-AST::addDFAData(Expression &&data) {
-    __dfadata.push_back(data);
-}
+        if (ExpressionHints::isStringValueValid(*this)) {
+            if (this->__valueS != other.__valueS) return false;
+        }
 
-void
-AST::addExternData(ExternData &&data) {
-    __externdata.insert(__externdata.end(), data.entries.begin(), data.entries.end());
-}
+        if (ExpressionHints::isDoubleValueValid(*this)) {
+            if (this->__valueD != other.__valueD) return false;
+        }
 
-void
-AST::add(Function* f)
-{
-    __functions.push_back(f);
-    __indexFunctions.emplace(f->getName(), __functions.size()-1);
-}
+        if (this->__state != Expression::COMPOUND) {
+            return true;
+        }
 
-void
-AST::add(MetaRuleAbstract *r)
-{
-    __rules.push_back(r);
-}
+        if (this->op != other.op) {
+            return false;
+        }
 
-void
-AST::add(TypeAnnotation t, Atom<Identifier_t> alias){
-	if (t.__operator == TypeOperator::VARIANT){
-		for (int i=0, size=t.fields.size(); i< size; ++i){
-			__dictVariants.emplace(t.fields[i], make_pair(t, i));
-		}
-	}
+        if (this->operands.size() != other.operands.size()) {
+            return false;
+        }
 
-    __indexTypeAliases.emplace(alias.get(), move(t));
-}
+        for (size_t i = 0; i<this->operands.size(); ++i) {
+            if (!(this->operands[i] == other.operands[i])) return false;
+        }
 
-ManagedScpPtr
-AST::add(CodeScope* scope)
-{
-    this->__scopes.push_back(scope);
-    return ManagedScpPtr(this->__scopes.size()-1, &this->__scopes);
-}
+        assert(!this->blocks.size());
+        assert(!other.blocks.size());
 
-std::string
-AST::getModuleName()
-{
-    const std::string name = "moduleTest";
+        return true;
+    }
 
-    return name;
-}
+    AST::AST() {
+        Attachments::init<VariableVersion>();
+        Attachments::init<Symbol>();
+    }
 
-ManagedPtr<Function>
-AST::findFunction(const std::string& name)
-{
-    int count = __indexFunctions.count(name);
-    if (!count) {
-    	return ManagedFnPtr::Invalid();
+    void
+    AST::addInterfaceData(const ASTInterface& interface, Expression&& data) {
+        __interfacesData.emplace(interface, move(data));
     }
 
-    assert(count ==1);
+    void
+    AST::addDFAData(Expression &&data) {
+        __dfadata.push_back(data);
+    }
 
-    auto range = __indexFunctions.equal_range(name);
-    return ManagedPtr<Function>(range.first->second, &this->__functions);
-}
+    void
+    AST::addExternData(ExternData &&data) {
+        __externdata.insert(__externdata.end(), data.entries.begin(), data.entries.end());
+    }
 
-std::list<ManagedFnPtr>
-AST::getAllFunctions() const{
-	const size_t size = __functions.size();
+    void
+    AST::add(Function* f) {
+        __functions.push_back(f);
+        __indexFunctions.emplace(f->getName(), __functions.size() - 1);
+    }
 
-	std::list<ManagedFnPtr> result;
-	for (size_t i=0; i<size; ++i){
-		result.push_back(ManagedFnPtr(i, &this->__functions));
-	}
+    void
+    AST::add(MetaRuleAbstract *r) {
+        __rules.push_back(r);
+    }
 
-	return result;
-}
+    void
+    AST::add(TypeAnnotation t, Atom<Identifier_t> alias) {
+        if (t.__operator == TypeOperator::VARIANT) {
+            for (int i = 0, size = t.fields.size(); i < size; ++i) {
+                __dictVariants.emplace(t.fields[i], make_pair(t, i));
+            }
+        }
 
-//TASK select default  specializations
-std::list<ManagedFnPtr>
-AST::getFunctionVariants(const std::string& name) const{
-	auto functions = __indexFunctions.equal_range(name);
+        __indexTypeAliases.emplace(alias.get(), move(t));
+    }
 
-	std::list<ManagedFnPtr> result;
-	std::transform(functions.first, functions.second, inserter(result, result.end()),
-			[this](auto f){return ManagedFnPtr(f.second, &this->__functions);});
+    ManagedScpPtr
+    AST::add(CodeScope* scope) {
+        this->__scopes.push_back(scope);
+        return ManagedScpPtr(this->__scopes.size() - 1, &this->__scopes);
+    }
 
-	return result;
-}
+    std::string
+    AST::getModuleName() {
+        const std::string name = "moduleTest";
 
-    template<>
-ManagedPtr<Function>
-AST::begin<Function>()
-{return ManagedPtr<Function>(0, &this->__functions);}
+        return name;
+    }
 
-template<>
-ManagedPtr<CodeScope>
-AST::begin<CodeScope>()
-{return ManagedPtr<CodeScope>(0, &this->__scopes);}
+    ManagedPtr<Function>
+    AST::findFunction(const std::string& name) {
+        int count = __indexFunctions.count(name);
+        if (!count) {
+            return ManagedFnPtr::Invalid();
+        }
 
-template<>
-ManagedPtr<MetaRuleAbstract>
-AST::begin<MetaRuleAbstract>()
-{return ManagedPtr<MetaRuleAbstract>(0, &this->__rules);}
+        assert(count == 1);
 
+        auto range = __indexFunctions.equal_range(name);
+        return ManagedPtr<Function>(range.first->second, &this->__functions);
+    }
 
-Expanded<TypeAnnotation>
-AST::expandType(const TypeAnnotation &t) const
-{
-    return TypesResolver(this)(t);
-}
+    std::list<ManagedFnPtr>
+    AST::getAllFunctions() const {
+        const size_t size = __functions.size();
 
-Expanded<TypeAnnotation>
-AST::findType(const std::string& name){
-			// find in general scope:
-    if(__indexTypeAliases.count(name))
-        return expandType(__indexTypeAliases.at(name));
+        std::list<ManagedFnPtr> result;
+        for (size_t i = 0; i < size; ++i) {
+            result.push_back(ManagedFnPtr(i, &this->__functions));
+        }
 
-    		//if type is unknown keep it as is.
-    TypeAnnotation t(TypeOperator::CUSTOM, {});
-    t.__valueCustom = name;
-    return ExpandedType(move(t));
-}
+        return result;
+    }
 
-void
-AST::recognizeVariantIdentifier(Expression& identifier){
+    //TASK select default  specializations
 
-//        TODO get rid of findSymbol. Determine symbol while AST parsing. Re-find symbols not found while first pass.
-//        *   move to codescope
-//        *   use findSymbol to find Symbol
-//        *   register var as alias to
-//        *   ident __doubleValue holds VID of an alias
+    std::list<ManagedFnPtr>
+    AST::getFunctionVariants(const std::string& name) const {
+        auto functions = __indexFunctions.equal_range(name);
 
-	assert(identifier.__state == Expression::IDENT);
+        std::list<ManagedFnPtr> result;
+        std::transform(functions.first, functions.second, inserter(result, result.end()),
+                [this](auto f) {
+                    return ManagedFnPtr(f.second, &this->__functions);
+                });
 
-	std::string name = identifier.getValueString();
-	if (__dictVariants.count(name)){
-		auto record = __dictVariants.at(name);
-		const TypeAnnotation& typ = record.first;
+        return result;
+    }
 
-		identifier.__state = Expression::VARIANT;
-		identifier.setValueDouble(record.second);
-		identifier.type = typ;
-	}
-}
+    template<>
+    ManagedPtr<Function>
+    AST::begin<Function>() {
+        return ManagedPtr<Function>(0, &this->__functions);
+    }
 
-Function::Function(const Atom<Identifier_t>& name)
-    : __entry(new CodeScope(0))
-{
-    __name = name.get();
-}
+    template<>
+    ManagedPtr<CodeScope>
+    AST::begin<CodeScope>() {
+        return ManagedPtr<CodeScope>(0, &this->__scopes);
+    }
 
-void
-Function::addTag(Expression&& tag, const TagModifier mod)
-{
-    string name = tag.getValueString();
-    __tags.emplace(move(name), move(tag));
-}
+    template<>
+    ManagedPtr<MetaRuleAbstract>
+    AST::begin<MetaRuleAbstract>() {
+        return ManagedPtr<MetaRuleAbstract>(0, &this->__rules);
+    }
 
-const std::map<std::string, Expression>&
-Function::getTags() const
-{
-    return __tags;
-}
+    Expanded<TypeAnnotation>
+    AST::expandType(const TypeAnnotation &t) const {
+        return TypesResolver(this)(t);
+    }
 
-CodeScope*
-Function::getEntryScope() const
-{
-    return __entry;
-}
+    Expanded<TypeAnnotation>
+    AST::findType(const std::string& name) {
+        // find in general scope:
+        if (__indexTypeAliases.count(name))
+            return expandType(__indexTypeAliases.at(name));
 
-void
-Function::addBinding(Atom <Identifier_t>&& name, Expression&& argument)
-{
-    __entry->addBinding(move(name), move(argument));
-}
+        //if type is unknown keep it as is.
+        TypeAnnotation t(TypeOperator::CUSTOM,{});
+        t.__valueCustom = name;
+        return ExpandedType(move(t));
+    }
 
-void
-Function::setReturnType(const TypeAnnotation &rtyp)
-{
+    bool
+    AST::recognizeVariantIdentifier(Expression& identifier) {
+        assert(identifier.__state == Expression::IDENT);
 
-    __entry->__declarations[0].type = rtyp;
-}
+        std::string variant = identifier.getValueString();
+        if (!__dictVariants.count(variant)) {
+            return false;
+        }
 
-const std::string&
-Function::getName() const
-{
-    return __name;
-}
+        auto record = __dictVariants.at(variant);
+        const TypeAnnotation& typ = record.first;
 
-Symbol
-CodeScope::registerIdentifier(Atom <Identifier_t> &&name)
-{
-    __identifiers.emplace(name.get(), ++__vCounter);
-    return {__vCounter, this};
-}
+        identifier.__state = Expression::VARIANT;
+        identifier.setValueDouble(record.second);
+        identifier.type = typ;
 
-void
-CodeScope::addBinding(Atom <Identifier_t>&& name, Expression&& argument)
-{
-    __bindings.push_back(name.get());
-    Symbol binding = registerIdentifier(move(name));
-    argument.__state = Expression::BINDING;
-    __declarations[binding.identifier] = move(argument);
-}
+        return true;
+    }
 
-void
-CodeScope::addDeclaration(Atom <Identifier_t>&& name, Expression&& body)
-{
-    Symbol s = registerIdentifier(move(name));
-    __declarations[s.identifier] = move(body);
-}
+    Function::Function(const Atom<Identifier_t>& name)
+    : __entry(new CodeScope(0)) {
+        __name = name.get();
+    }
 
-CodeScope::CodeScope(CodeScope* parent)
-    :__parent(parent)
-{}
+    void
+    Function::addTag(Expression&& tag, const TagModifier mod) {
+        string name = tag.getValueString();
+        __tags.emplace(move(name), move(tag));
+    }
 
-CodeScope::~CodeScope()
-{}
+    const std::map<std::string, Expression>&
+    Function::getTags() const {
+        return __tags;
+    }
 
-void
-CodeScope::setBody(const Expression &body)
-{
-    __declarations[0] = body;
-}
+    CodeScope*
+    Function::getEntryScope() const {
+        return __entry;
+    }
 
-Expression&
-CodeScope::getBody(){
-    return __declarations[0];
-}
+    void
+    Function::addBinding(Atom <Identifier_t>&& name, Expression&& argument) {
+        __entry->addBinding(move(name), move(argument));
+    }
 
-Symbol
-CodeScope::findSymbol(const std::string &name)
-{
-        //search identifier in the current block
-    if (__identifiers.count(name))
-    {
-        VID vId = __identifiers.at(name);
-        Symbol result{vId, this};
-        return result;
+    const std::string&
+    Function::getName() const {
+        return __name;
+    }
+
+    ScopedSymbol
+    CodeScope::registerIdentifier(const Expression& identifier) {
+        VariableVersion version = Attachments::get<VariableVersion>(identifier, VERSION_NONE);
+
+        auto result = __identifiers.emplace(identifier.getValueString(), __vCounter);
+        if (result.second){
+            ++__vCounter;
+            return {__vCounter-1, version};
+        }
+
+        return {result.first->second, version};
     }
 
+    bool
+    CodeScope::recognizeIdentifier(const Expression& identifier) const{
+        VariableVersion version = Attachments::get<VariableVersion>(identifier, VERSION_NONE);
+        const std::string& name = identifier.getValueString();
+
+        //search identifier in the current block
+        if (__identifiers.count(name)){
+            VNameId id = __identifiers.at(name);
+
+            Symbol s;
+            s.identifier = ScopedSymbol{id, version};
+            s.scope = const_cast<CodeScope*>(this);
+            Attachments::put<Symbol>(identifier, s);
+
+            return true;
+        }
+
         //search in the parent scope
-    if (__parent)
-    {
-        return __parent->findSymbol(name);
+        if (__parent)
+        {
+            return __parent->recognizeIdentifier(identifier);
+        }
+
+        return false;
     }
 
-    //exception: Ident not found
-    std::cout << "Unknown symbol: "<< name << std::endl;
-    assert(false && "Symbol not found");
-}
+    ScopedSymbol
+    CodeScope::getSymbol(const std::string& alias){
+        assert(__identifiers.count(alias));
+        VNameId id = __identifiers.at(alias);
 
-const Expression&
-CodeScope::findDeclaration(const Symbol& symbol)
-{
-    CodeScope* self = symbol.scope;
-    return self->__declarations[symbol.identifier];
-}
+        return {id, VERSION_NONE};
+    }
 
+    void
+    AST::postponeIdentifier(CodeScope* scope, const Expression& id) {
+        binUnrecognizedIdentifiers.emplace(scope, id);
+    }
 
+    void
+    AST::recognizePostponedIdentifiers() {
+        for(const auto& identifier: binUnrecognizedIdentifiers){
+            if (!identifier.first->recognizeIdentifier(identifier.second)){
+                            //exception: Ident not found
+                std::cout << "Unknown symbol: "<< identifier.second.getValueString() << std::endl;
+                assert(false && "Symbol not found");
+            }
+        }
+    }
 
-void
-RuleArguments::add(const Atom<Identifier_t> &arg, DomainAnnotation typ)
-{
-    emplace_back(arg.get(), typ);
-}
+    void
+    CodeScope::addBinding(Expression&& var, Expression&& argument) {
+        argument.__state = Expression::BINDING;
 
-void
-RuleGuards::add(Expression&& e)
-{
-    push_back(e);
-}
+        __bindings.push_back(var.getValueString());
+        ScopedSymbol binding = registerIdentifier(var);
+        __declarations[binding] = move(argument);
+    }
 
-MetaRuleAbstract::
-MetaRuleAbstract(RuleArguments&& args, RuleGuards&& guards)
-    : __args(std::move(args)), __guards(std::move(guards))
-{}
+    void
+    CodeScope::addDeclaration(Expression&& var, Expression&& body) {
+        ScopedSymbol s = registerIdentifier(var);
+        __declarations[s] = move(body);
+    }
 
-MetaRuleAbstract::~MetaRuleAbstract(){}
+    CodeScope::CodeScope(CodeScope* parent)
+    : __parent(parent) {
+    }
 
-RuleWarning::
-RuleWarning(RuleArguments&& args, RuleGuards&& guards, Expression&& condition, Atom<String_t>&& message)
-    : MetaRuleAbstract(std::move(args), std::move(guards)), __message(message.get()), __condition(condition)
-{}
+    CodeScope::~CodeScope() {
+    }
 
-RuleWarning::~RuleWarning(){}
+    void
+    CodeScope::setBody(const Expression &body) {
+        __declarations[ScopedSymbol::RetSymbol] = body;
+    }
 
-void
-RuleWarning::compile(ClaspLayer& layer)
-{
-	//TODO restore addRuleWarning
-    //layer.addRuleWarning(*this);
-}
+    Expression&
+    CodeScope::getBody() {
+        return __declarations[ScopedSymbol::RetSymbol];
+    }
 
-bool operator< (const Symbol& s1, const Symbol& s2)
-{
-    return (s1.scope < s2.scope) || (s1.scope==s2.scope && s1.identifier<s2.identifier);
-}
+    const Expression&
+    CodeScope::getDeclaration(const Symbol& symbol) {
+        CodeScope* self = symbol.scope;
+        return self->getDeclaration(symbol.identifier);
+    }
 
-bool operator== (const Symbol& s1, const Symbol& s2)
-{
-    return (s1.scope == s2.scope) && (s1.identifier==s2.identifier);
-}
+    const Expression&
+    CodeScope::getDeclaration(const ScopedSymbol& symbol){
+        assert(__declarations.count(symbol) && "Symbol's declaration not found");
 
-bool operator < (const Expression&a, const Expression&b) {
-if (a.__state != b.__state) return a.__state < b.__state;
-assert(a.__state != Expression::INVALID);
-switch(a.__state) {
-    case Expression::IDENT:
-    case Expression::STRING:
-    case Expression::VARIANT:
-        return a.getValueString() < b.getValueString();
-
-    case Expression::NUMBER:
-        return a.getValueDouble() < b.getValueDouble();
-
-    case Expression::COMPOUND: {
-        assert(a.op == Operator::CALL);
-        assert(a.blocks.size()==0);
-        assert(b.blocks.size()==0);
-
-        if (a.operands.size() != b.operands.size()){
-            return (a.operands.size() < b.operands.size());
-        }
+        return __declarations.at(symbol);
+    }
 
-        if (a.getValueString() != b.getValueString()){
-            return a.getValueString() < b.getValueString();
-        }
+    void
+    RuleArguments::add(const Atom<Identifier_t> &arg, DomainAnnotation typ) {
+        emplace_back(arg.get(), typ);
+    }
 
-        for(size_t i=0; i<a.operands.size(); ++i){
-            bool result = a.operands[i] < b.operands[i];
-            if (result) return true;
+    void
+    RuleGuards::add(Expression&& e) {
+        push_back(e);
+    }
+
+    MetaRuleAbstract::
+    MetaRuleAbstract(RuleArguments&& args, RuleGuards&& guards)
+    : __args(std::move(args)), __guards(std::move(guards)) {
+    }
+
+    MetaRuleAbstract::~MetaRuleAbstract() {
+    }
+
+    RuleWarning::
+    RuleWarning(RuleArguments&& args, RuleGuards&& guards, Expression&& condition, Atom<String_t>&& message)
+    : MetaRuleAbstract(std::move(args), std::move(guards)), __message(message.get()), __condition(condition) {
+    }
+
+    RuleWarning::~RuleWarning() {
+    }
+
+    void
+    RuleWarning::compile(ClaspLayer& layer) {
+        //TODO restore addRuleWarning
+        //layer.addRuleWarning(*this);
+    }
+
+    bool operator<(const ScopedSymbol& s1, const ScopedSymbol& s2) {
+        return (s1.id < s2.id) || (s1.id==s2.id && s1.version < s2.version);
+    }
+
+    bool operator==(const ScopedSymbol& s1, const ScopedSymbol& s2) {
+        return (s1.id == s2.id) && (s1.version == s2.version);
+    }
+
+    bool operator<(const Symbol& s1, const Symbol& s2) {
+        return (s1.scope < s2.scope) || (s1.scope == s2.scope && s1.identifier < s2.identifier);
+    }
+
+    bool operator==(const Symbol& s1, const Symbol& s2) {
+        return (s1.scope == s2.scope) && (s1.identifier == s2.identifier);
+    }
+
+    bool operator<(const Expression&a, const Expression&b) {
+        if (a.__state != b.__state) return a.__state < b.__state;
+        assert(a.__state != Expression::INVALID);
+        switch (a.__state) {
+            case Expression::IDENT:
+            case Expression::STRING:
+            case Expression::VARIANT:
+                return a.getValueString() < b.getValueString();
+
+            case Expression::NUMBER:
+                return a.getValueDouble() < b.getValueDouble();
+
+            case Expression::COMPOUND:
+            {
+                assert(a.op == Operator::CALL);
+                assert(a.blocks.size() == 0);
+                assert(b.blocks.size() == 0);
+
+                if (a.operands.size() != b.operands.size()) {
+                    return (a.operands.size() < b.operands.size());
+                }
+
+                if (a.getValueString() != b.getValueString()) {
+                    return a.getValueString() < b.getValueString();
+                }
+
+                for (size_t i = 0; i < a.operands.size(); ++i) {
+                    bool result = a.operands[i] < b.operands[i];
+                    if (result) return true;
+                }
+
+                return false;
+            }
+
+            case Expression::BINDING:
+            case Expression::INVALID:
+                assert(false);
         }
 
         return false;
     }
 
-    case Expression::BINDING:
-    case Expression::INVALID:
-        assert(false);
+const ScopedSymbol
+ScopedSymbol::RetSymbol = ScopedSymbol{0, VERSION_NONE};
 }
 
-return false;
-}
 
-}
 
 
diff --git a/cpp/src/ast.h b/cpp/src/ast.h
index cd070ab..7407463 100644
--- a/cpp/src/ast.h
+++ b/cpp/src/ast.h
@@ -1,562 +1,558 @@
 #ifndef AST_H
 #define AST_H
 
 #include "attachments.h"
 
 #include <vector>
 #include <stdlib.h>
 #include <string>
 #include <list>
 #include <unordered_map>
 #include <unordered_set>
 #include <climits>
 #include "utils.h"
 #include <algorithm>
 
 namespace llvm {
     class Value;
 }
 
 namespace xreate {
 
-    struct String_t {
-    };
-
-    struct Identifier_t {
-    };
-
-    struct Number_t {
-    };
-
-    struct Type_t {
-    };
-
-    template<typename A>
-    class Atom {
-    };
-
-    //DEBT hold for all atoms/identifiers Parser::Token data, like line:col position
-
-    template<> class Atom<Identifier_t> {
-    public:
-
-        Atom(const std::wstring& value) {
-            char buffer[32];
-            wcstombs(buffer, value.c_str(), 32);
-
-            __value = buffer;
-        }
-
-        Atom(std::string && name) : __value(name) {
-        }
-
-        const std::string& get() const {
-            return __value;
-        }
-    private:
-        std::string __value;
-    };
-
-    template<> class Atom<Number_t> {
-    public:
-
-        Atom(wchar_t* value) {
-            __value = wcstol(value, 0, 10);
-        }
+struct String_t {
+};
 
-        Atom(int value)
-        : __value(value) {
-        }
+struct Identifier_t {
+};
 
-        double get()const {
-            return __value;
-        }
-    private:
-        double __value;
-    };
+struct Number_t {
+};
 
-    template<> class Atom<String_t> {
-    public:
+struct Type_t {
+};
 
-        Atom(const std::wstring& value) {
-            assert(value.size());
-            __value = std::string(++value.begin(), --value.end());
-        }
+template<typename A>
+class Atom {
+};
 
-        const std::string& get() const {
-            return __value;
-        }
-
-    private:
-        std::string __value;
-    };
-
-    enum class TypePrimitive {
-        Bool, Num, Int, I32, I8, Float, String, 
-    };
-
-    template<> class Atom<Type_t> {
-    public:
-
-        Atom(wchar_t* value) {
-            char buffer_[32];
-            wcstombs(buffer_, value, 32);
-            std::string buffer(buffer_);
-
-            if (buffer == "bool") {
-                __value = TypePrimitive::Bool;
-            } else if (buffer == "num") {
-                __value = TypePrimitive::Num;
-            } else if (buffer == "int") {
-                __value = TypePrimitive::Int;
-            } else if (buffer == "i8") {
-                __value = TypePrimitive::I8;
-            } else if (buffer == "i32") {
-                __value = TypePrimitive::I32;                
-            } else if (buffer == "float") {
-                __value = TypePrimitive::Float;
-
-            } else if (buffer == "string") {
-                __value = TypePrimitive::String;
-            }
-        }
+//DEBT hold for all atoms/identifiers Parser::Token data, like line:col position
+template<> class 
+Atom<Identifier_t> {
+public:
+    Atom(const std::wstring& value);
+    Atom(std::string && name);
+    const std::string& get() const;
+    
+private:
+    std::string __value;
+};
+
+template<> 
+class Atom<Number_t> {
+public:
+    Atom(wchar_t* value);
+    Atom(int value);
+    double get()const;
+    
+private:
+    double __value;
+};
 
-        Atom() {
-        }
+template<> 
+class Atom<String_t> {
+public:
+    Atom(const std::wstring& value);
+    const std::string& get() const;
 
-        TypePrimitive get() const {
-            return __value;
-        }
+private:
+    std::string __value;
+};
 
-    private:
-        TypePrimitive __value;
-    };
-
-    typedef Atom<Type_t> TypeAtom;
+enum class TypePrimitive {
+    Invalid, Bool, I8, I32, Num, Int, Float, String
+};
 
     enum class TypeOperator {
         NONE, CALL, CUSTOM, VARIANT, ARRAY, TUPLE, STRUCT, ACCESS, LINK
     };
 
     struct llvm_array_tag {
     };
 
     struct struct_tag {
     };
     const llvm_array_tag tag_array = llvm_array_tag();
     const struct_tag tag_struct = struct_tag();
 
     class TypeAnnotation {
     public:
         TypeAnnotation();
         TypeAnnotation(const Atom<Type_t>& typ);
         TypeAnnotation(TypePrimitive typ);
         TypeAnnotation(llvm_array_tag, TypeAnnotation typ, int size);
 
         TypeAnnotation(TypeOperator op, std::initializer_list<TypeAnnotation> operands);
         TypeAnnotation(TypeOperator op, std::vector<TypeAnnotation>&& operands);
         void addBindings(std::vector<Atom<Identifier_t>>&& params);
         void addFields(std::vector<Atom<Identifier_t>>&& listFields);
         bool operator<(const TypeAnnotation& t) const;
         //   TypeAnnotation (struct_tag, std::initializer_list<TypePrimitive>);
 
+        bool isValid() const;
 
         TypeOperator __operator = TypeOperator::NONE;
 
         std::vector<TypeAnnotation> __operands;
         TypePrimitive __value;
         std::string __valueCustom;
         int conjuctionId = -1; //conjunction point id (relevant for recursive types)
 
         uint64_t __size = 0;
         std::vector<std::string> fields;
         std::vector<std::string> bindings;
     private:
     };
 
     enum class Operator {
-        ADD, SUB, MUL, DIV, EQU, NE, NEG, LSS, LSE, GTR, GTE, LIST, LIST_RANGE, LIST_NAMED, CALL, NONE, IMPL/* implication */, MAP, FOLD, FOLD_INF, LOOP_CONTEXT, INDEX, IF, SWITCH, SWITCH_ADHOC, CASE, CASE_DEFAULT, LOGIC_AND, ADHOC, CONTEXT_RULE, SEQUENCE
+        ADD, SUB, MUL, DIV,
+        EQU, NE, NEG, LSS, 
+        LSE, GTR, GTE, LIST, 
+        LIST_RANGE, LIST_NAMED, 
+        CALL, CALL_INTRINSIC, NONE, 
+        IMPL/* implication */, MAP, 
+        FOLD, FOLD_INF, LOOP_CONTEXT, 
+        INDEX, IF, SWITCH, SWITCH_ADHOC, 
+        CASE, CASE_DEFAULT, LOGIC_AND, 
+        ADHOC, CONTEXT_RULE
     };
 
     class Function;
     class AST;
     class CodeScope;
     class MetaRuleAbstract;
 
     template<class Target>
     struct ManagedPtr {
 
         static ManagedPtr<Target> Invalid() {
             return ManagedPtr<Target>();
         }
 
         ManagedPtr() : __storage(0) {
         }
 
         ManagedPtr(unsigned int id, const std::vector<Target*>* storage)
         : __id(id), __storage(storage) {
         }
 
         Target&
         operator*() const {
             assert(isValid() && "Invalid Ptr");
             return *__storage->at(__id);
         }
 
         void operator=(const ManagedPtr<Target>& other) {
             __id = other.__id;
             __storage = other.__storage;
         }
 
         bool
         operator==(const ManagedPtr<Target>& other) {
             return isValid() && (__id == other.__id);
         }
 
         Target*
         operator->() const noexcept {
             assert(isValid() && "Invalid Ptr");
             return __storage->at(__id);
         }
 
         inline bool isValid() const {
             return (__storage) && (0 <= __id) && (__id < __storage->size());
         }
 
         inline operator bool() const {
             return isValid();
         }
 
         ManagedPtr<Target>& operator++() {
             ++__id;
             return *this;
         }
 
         inline unsigned int id() const {
             return __id;
         }
 
     private:
         unsigned int __id = 0;
         const std::vector<Target*> * __storage = 0;
     };
 
     typedef ManagedPtr<Function> ManagedFnPtr;
     typedef ManagedPtr<CodeScope> ManagedScpPtr;
     typedef ManagedPtr<MetaRuleAbstract> ManagedRulePtr;
     const ManagedScpPtr NO_SCOPE = ManagedScpPtr(UINT_MAX, 0);
 
     //To update ExpressionHints in case of any changes 
     struct Expression {
         friend class CodeScope;
         friend class ClaspLayer;
         friend class CFAPass;
         friend class ExpressionHints;
 
         Expression(const Operator &oprt, std::initializer_list<Expression> params);
         Expression(const Atom<Identifier_t>& ident);
         Expression(const Atom<Number_t>& number);
         Expression(const Atom<String_t>& a);
+        
         Expression();
 
         void setOp(Operator oprt);
         void addArg(Expression&& arg);
         void addBindings(std::initializer_list<Atom<Identifier_t>> params);
         void bindType(TypeAnnotation t);
 
         template<class InputIt>
         void addBindings(InputIt paramsBegin, InputIt paramsEnd);
-
+        void addTags(const std::list<Expression> tags) const;
         void addBlock(ManagedScpPtr scope);
 
         const std::vector<Expression>& getOperands() const;
         double getValueDouble() const;
         void setValueDouble(double value);
         const std::string& getValueString() const;
         void setValue(const Atom<Identifier_t>&& v);
         bool isValid() const;
         bool isDefined() const;
         
 
         bool operator==(const Expression& other) const;
 
         enum {
             INVALID, COMPOUND, IDENT, NUMBER, STRING, VARIANT, BINDING
         } __state = INVALID;
+        
         Operator op;
+        unsigned int id;
         std::vector<std::string> bindings;
         std::map<std::string, size_t> __indexBindings;
         std::vector<Expression> operands;
         TypeAnnotation type;
 
         mutable std::map<std::string, Expression> tags;
-        mutable Attachments tagsInternal;
         std::list<CodeScope*> blocks;
 
     private:
         std::string __valueS;
         double __valueD;
+        
+        static unsigned int nextVacantId;
     };
     
     bool operator< (const Expression&, const Expression&);
 
     template<class InputIt>
     void Expression::addBindings(InputIt paramsBegin, InputIt paramsEnd) {
         size_t index = bindings.size();
 
         std::transform(paramsBegin, paramsEnd, std::inserter(bindings, bindings.end()),
                 [&index, this] (const Atom<Identifier_t> atom) {
                     std::string key = atom.get();
                     this->__indexBindings[key] = index++;
                     return key;
                 });
     }
 
     typedef std::list<Expression> ExpressionList;
 
     enum class TagModifier {
         NONE, ASSERT, REQUIRE
     };
 
     enum class DomainAnnotation {
         FUNCTION, VARIABLE
     };
 
     class RuleArguments : public std::vector<std::pair<std::string, DomainAnnotation>>
     {
         public:
         void add(const Atom<Identifier_t>& name, DomainAnnotation typ);
     };
 
     class RuleGuards : public std::vector<Expression> {
     public:
         void add(Expression&& e);
     };
 
 
     class ClaspLayer;
     class LLVMLayer;
 
     class MetaRuleAbstract {
     public:
         MetaRuleAbstract(RuleArguments&& args, RuleGuards&& guards);
         virtual ~MetaRuleAbstract();
         virtual void compile(ClaspLayer& layer) = 0;
     protected:
         RuleArguments __args;
         RuleGuards __guards;
     };
 
     class RuleWarning : public MetaRuleAbstract {
         friend class ClaspLayer;
     public:
         RuleWarning(RuleArguments&& args, RuleGuards&& guards, Expression&& condition, Atom<String_t>&& message);
         virtual void compile(ClaspLayer& layer);
         ~RuleWarning();
 
     private:
         std::string __message;
         Expression __condition;
     };
 
-    typedef unsigned int VID;
-
-
-
-    /*
-    class Expression: ExpressionAbstract
+    typedef unsigned int VNameId;
+    
+    typedef int VariableVersion;
+    const VariableVersion VERSION_NONE = -2;
+    const VariableVersion VERSION_INIT = 0;
+    
+    template<>
+    struct AttachmentsDict<VariableVersion>
     {
-        friend class CFGPass;
-
-    public:
-        llvm::Value* compile(LLVMLayer& l, Function* f,  std::string* hintRetVar=0) const;
+        typedef VariableVersion Data;
+        static const unsigned int key = 6;
+    };
+    
+    struct ScopedSymbol{
+        VNameId id;
+        VariableVersion version;
+        
+        static const ScopedSymbol RetSymbol;
+    };
+    
+    struct Symbol {
+        ScopedSymbol identifier;
+        CodeScope * scope;
+    };
+    
+    template<>
+    struct AttachmentsDict<Symbol>
+    {
+        typedef Symbol Data;
+        static const unsigned int key = 7;
+    };
+    
+} 
+namespace std
+{
+    template<>
+    struct hash<xreate::ScopedSymbol>{
+        std::size_t operator()(xreate::ScopedSymbol const& s) const;
     };
-     */
 
+    template<>
+    struct equal_to<xreate::ScopedSymbol>{
+      bool operator()(const xreate::ScopedSymbol& __x, const xreate::ScopedSymbol& __y) const;
+    };
+}
 
+namespace xreate {
 
+    
     typedef std::pair<Expression, TagModifier> Tag;
 
-    struct Symbol {
-        VID identifier;
-        CodeScope * scope;
-    };
-
+    bool operator<(const ScopedSymbol& s1, const ScopedSymbol& s2);
+    bool operator==(const ScopedSymbol& s1, const ScopedSymbol& s2);
     bool operator<(const Symbol& s1, const Symbol& s2);
     bool operator==(const Symbol& s1, const Symbol& s2);
 
-    class CodeScope {
-        friend class Function;
-        friend class PassManager;
+class CodeScope {
+    friend class Function;
+    friend class PassManager;
 
-    public:
-        CodeScope(CodeScope* parent = 0);
-        void setBody(const Expression& body);
-        Expression& getBody();
-        void addDeclaration(Atom <Identifier_t>&& name, Expression&& body);
-        void addBinding(Atom <Identifier_t>&& name, Expression&& argument);
-        Symbol findSymbol(const std::string &name);
-        static const Expression& findDeclaration(const Symbol& symbol);
-
-        ~CodeScope();
-
-        std::vector<std::string> __bindings;
-        std::map<std::string, VID> __identifiers;
-        /**
-         * definition of return type has variable index Zero(0)
-         */
-        //TODO move __definitions to SymbolsAttachments data
-        std::unordered_map<VID, Expression> __declarations;
-        std::vector<Expression> tags;
-        std::vector<Expression> contextRules;
-        
-    private:
-        VID __vCounter = 0;
-        CodeScope* __parent;
-        
-        Symbol registerIdentifier(Atom <Identifier_t>&& name);
-    };
+public:
+    CodeScope(CodeScope* parent = 0);
+    void setBody(const Expression& body);
+    Expression& getBody();
+    void addDeclaration(Expression&& var, Expression&& body);
+    void addBinding(Expression&& var, Expression&& argument);
+    static const Expression& getDeclaration(const Symbol& symbol);
+    const Expression& getDeclaration(const ScopedSymbol& symbol);
 
-    class Function {
-        friend class Expression;
-        friend class CodeScope;
-        friend class AST;
+    ~CodeScope();
 
-    public:
-        Function(const Atom<Identifier_t>& name);
+    std::vector<std::string> __bindings;
+    std::map<std::string, VNameId> __identifiers;
 
-        void addBinding(Atom <Identifier_t>&& name, Expression&& argument);
-        void addTag(Expression&& tag, const TagModifier mod);
+    //TODO move __definitions to SymbolsAttachments data
+    //NOTE: definition of return type has zero(0) variable index
+    std::unordered_map<ScopedSymbol, Expression> __declarations;
+    std::vector<Expression> tags;
+    std::vector<Expression> contextRules;
 
-        void setReturnType(const TypeAnnotation& rtyp);
+private:
+    VNameId __vCounter = 1;
+    CodeScope* __parent;
 
-        const std::string& getName() const;
-        const std::map<std::string, Expression>& getTags() const;
-        CodeScope* getEntryScope() const;
-        CodeScope* __entry;
-        std::string __name;
-        bool isPrefunction = false; //SECTIONTAG adhoc Function::isPrefunction flag
+    ScopedSymbol registerIdentifier(const Expression& identifier);
 
-        Expression guardContext;
-    private:
+public:
+    bool recognizeIdentifier(const Expression& identifier) const;
+    ScopedSymbol getSymbol(const std::string& alias);
+};
 
-        std::map<std::string, Expression> __tags;
-    };
+class Function {
+    friend class Expression;
+    friend class CodeScope;
+    friend class AST;
 
+public:
+    Function(const Atom<Identifier_t>& name);
 
-    class ExternData;
+    void addBinding(Atom <Identifier_t>&& name, Expression&& argument);
+    void addTag(Expression&& tag, const TagModifier mod);
 
-    struct ExternEntry {
-        std::string package;
-        std::vector<std::string> headers;
-    };
+    const std::string& getName() const;
+    const std::map<std::string, Expression>& getTags() const;
+    CodeScope* getEntryScope() const;
+    CodeScope* __entry;
+    std::string __name;
+    bool isPrefunction = false; //SECTIONTAG adhoc Function::isPrefunction flag
 
-    typedef Expanded<TypeAnnotation> ExpandedType;
+    Expression guardContext;
+private:
 
-    enum ASTInterface {
-        CFA, DFA, Extern, Adhoc
-    };
+    std::map<std::string, Expression> __tags;
+};
 
-    struct FunctionSpecialization {
-        std::string guard;
-        size_t id;
-    };
 
-    struct FunctionSpecializationQuery {
-        std::unordered_set<std::string> context;
-    };
+class ExternData;
 
-    template<>
-    struct AttachmentsStorage<Symbol> {
+struct ExternEntry {
+    std::string package;
+    std::vector<std::string> headers;
+};
 
-        static Attachments*
-        get(const Symbol& s) {
-            return &s.scope->findDeclaration(s).tagsInternal;
-        }
-    };
+typedef Expanded<TypeAnnotation> ExpandedType;
 
-    template<>
-    struct AttachmentsStorage<Expression> {
+enum ASTInterface {
+    CFA, DFA, Extern, Adhoc
+};
 
-        static Attachments*
-        get(const Expression& e) {
-            return &e.tagsInternal;
-        }
-    };
+struct FunctionSpecialization {
+    std::string guard;
+    size_t id;
+};
 
-    class AST {
-    public:
-        AST();
+struct FunctionSpecializationQuery {
+    std::unordered_set<std::string> context;
+};
 
-        //TASK extern and DFA interfaces move into addInterfaceData
-        /**
-         *  DFA Interface
-         */
-        void addDFAData(Expression&& data);
+template<>
+struct AttachmentsId<Expression>{
+    static unsigned int getId(const Expression& expression){
+        return expression.id;
+    }
+};
 
-        /**
-         * Extern Interface
-         */
-        void addExternData(ExternData&& data);
+template<>
+struct AttachmentsId<Symbol>{
+    static unsigned int getId(const Symbol& s){
+        return s.scope->__declarations.at(s.identifier).id;
+    }
+};
 
-        void addInterfaceData(const ASTInterface& interface, Expression&& data);
-        void add(Function* f);
+template<>
+struct AttachmentsId<ManagedFnPtr>{
+    static unsigned int getId(const ManagedFnPtr& f){
+        const Symbol symbolFunction{ScopedSymbol::RetSymbol, f->getEntryScope()};
+        
+        return AttachmentsId<Symbol>::getId(symbolFunction);
+    }
+};
 
-        void add(MetaRuleAbstract* r);
-        ManagedScpPtr add(CodeScope* scope);
+class AST {
+public:
+    AST();
 
-        std::string getModuleName();
-        ManagedPtr<Function> findFunction(const std::string& name);
+    //TASK extern and DFA interfaces move into addInterfaceData
+    /**
+     *  DFA Interface
+     */
+    void addDFAData(Expression&& data);
 
-        typedef std::multimap<std::string, unsigned int> FUNCTIONS_REGISTRY;
-        std::list<ManagedFnPtr> getAllFunctions() const;
-        std::list<ManagedFnPtr> getFunctionVariants(const std::string& name) const;
+    /**
+     * Extern Interface
+     */
+    void addExternData(ExternData&& data);
 
+    void addInterfaceData(const ASTInterface& interface, Expression&& data);
+    void add(Function* f);
 
-        template<class Target>
-        ManagedPtr<Target> begin();
+    void add(MetaRuleAbstract* r);
+    ManagedScpPtr add(CodeScope* scope);
 
-        std::vector<ExternEntry> __externdata;
-        std::list<Expression> __dfadata; //TODO move to more appropriate place
-        std::list<std::string> __rawImports; //TODO move to more appropriate place
-        std::multimap<ASTInterface, Expression> __interfacesData; //TODO CFA data here.
+    std::string getModuleName();
+    ManagedPtr<Function> findFunction(const std::string& name);
 
-    private:
-        std::vector<MetaRuleAbstract*> __rules;
-        std::vector<Function*> __functions;
-        std::vector<CodeScope*> __scopes;
+    typedef std::multimap<std::string, unsigned int> FUNCTIONS_REGISTRY;
+    std::list<ManagedFnPtr> getAllFunctions() const;
+    std::list<ManagedFnPtr> getFunctionVariants(const std::string& name) const;
 
-        FUNCTIONS_REGISTRY __indexFunctions;
 
+    template<class Target>
+    ManagedPtr<Target> begin();
 
-        // ***** TYPES SECTION *****
-    public:
-        std::map<std::string, TypeAnnotation> __indexTypeAliases;
-        ExpandedType expandType(const TypeAnnotation &t) const;
-        ExpandedType findType(const std::string& name);
-        void add(TypeAnnotation t, Atom<Identifier_t> alias);
-        void recognizeVariantIdentifier(Expression& identifier);
+    std::vector<ExternEntry> __externdata;
+    std::list<Expression> __dfadata; //TODO move to more appropriate place
+    std::list<std::string> __rawImports; //TODO move to more appropriate place
+    std::multimap<ASTInterface, Expression> __interfacesData; //TODO CFA data here.
 
+private:
+    std::vector<MetaRuleAbstract*> __rules;
+    std::vector<Function*> __functions;
+    std::vector<CodeScope*> __scopes;
 
-    private:
-        std::map<std::string, std::pair<TypeAnnotation, int>> __dictVariants;
-        ExpandedType expandType(const TypeAnnotation &t, std::map<std::string, TypeAnnotation> scope,
-                const std::vector<TypeAnnotation> &args = std::vector<TypeAnnotation>()) const;
+    FUNCTIONS_REGISTRY __indexFunctions;
 
-        // ***** TYPES SECTION END *****
-    };
 
-    template<>
-    ManagedPtr<Function>
-    AST::begin<Function>();
+    // ***** TYPES SECTION *****
+public:
+    std::map<std::string, TypeAnnotation> __indexTypeAliases;
+    ExpandedType expandType(const TypeAnnotation &t) const;
+    ExpandedType findType(const std::string& name);
+    void add(TypeAnnotation t, Atom<Identifier_t> alias);
 
-    template<>
-    ManagedPtr<CodeScope>
-    AST::begin<CodeScope>();
+    //TODO revisit enums/variants, move to codescope
+    bool recognizeVariantIdentifier(Expression& identifier);
 
-    template<>
-    ManagedPtr<MetaRuleAbstract>
-    AST::begin<MetaRuleAbstract>();
+
+private:
+    std::map<std::string, std::pair<TypeAnnotation, int>> __dictVariants;
+    ExpandedType expandType(const TypeAnnotation &t, std::map<std::string, TypeAnnotation> scope,
+            const std::vector<TypeAnnotation> &args = std::vector<TypeAnnotation>()) const;
+
+    // ***** SYMBOL RECOGNITION *****
+public:
+    std::set<std::pair<CodeScope*, Expression>> binUnrecognizedIdentifiers;
+
+public:
+    void postponeIdentifier(CodeScope* scope, const Expression& id);
+    void recognizePostponedIdentifiers();
+};
+
+template<>
+ManagedPtr<Function>
+AST::begin<Function>();
+
+template<>
+ManagedPtr<CodeScope>
+AST::begin<CodeScope>();
+
+template<>
+ManagedPtr<MetaRuleAbstract>
+AST::begin<MetaRuleAbstract>();
 
 }
 #endif // AST_H
diff --git a/cpp/src/attachments.cpp b/cpp/src/attachments.cpp
index 83a54d1..61fcdcd 100644
--- a/cpp/src/attachments.cpp
+++ b/cpp/src/attachments.cpp
@@ -1,30 +1,10 @@
 //
 // Created by pgess on 3/15/15.
 //
 
 #include "attachments.h"
 
-namespace xreate {
-    void* xreate::Attachments::put(unsigned int key, void *data) {
-        auto result = __data.emplace(key, data);
-        
-        void* ptrOld = nullptr;
-        if (!result.second){
-            ptrOld = result.first->second;
-            result.first->second  = data;
-        }
-    
-        return ptrOld;
-    }
+using namespace xreate;
 
-    void *xreate::Attachments::get(unsigned int key) {
-        assert(__data.count(key));
-        return __data.at(key);
-    }
-
-    bool
-    xreate::Attachments::exists(unsigned int key)
-    {
-        return __data.count(key)>0;
-    }
-}
\ No newline at end of file
+std::vector<void*>
+Attachments::__storage = std::vector<void*>();
\ No newline at end of file
diff --git a/cpp/src/attachments.h b/cpp/src/attachments.h
index 03b8711..1fd3e48 100644
--- a/cpp/src/attachments.h
+++ b/cpp/src/attachments.h
@@ -1,124 +1,158 @@
 //
 // Created by pgess on 3/15/15.
 //
 
 #ifndef _XREATE_ATTACHMENTS_H_
 #define _XREATE_ATTACHMENTS_H_
-#include <map>
+#include <unordered_map>
+#include <vector>
 #include <assert.h>
 #include <type_traits>
 
 namespace xreate
 {
         //Attachments dictionary
     template<class Tag>
     struct AttachmentsDict
     {
         // typedef void Data;
-        // static const unsigned int key (current unreserved - 6);
+        // static const unsigned int key (current unreserved - 9);
     };
     
-    template<class T>
-    struct AttachmentsStorage
-    {
-        //static Attachments* get(const T&);
+    template<class Object>
+    struct AttachmentsId{
+        //static unsigned int getId(const Object& object);
     };
 
-    namespace detail {
+    
+template<class Data>
+class IAttachmentsContainer{
+    protected:
+        virtual bool  __exists(const unsigned int object)=0;
+        virtual Data& __get(const unsigned int object)=0;
+        virtual void  __put(const unsigned int object, Data data)=0;
 
-        template<class Typ>
-        typename std::enable_if<std::is_pointer<Typ>::value, void*>::type
-        __wrap(const Typ& value){
-            return value;
-        }
-        
-        template<class Typ>
-        typename std::enable_if<std::is_pointer<Typ>::value, Typ>::type
-        __unwrap(void* value){
-            return reinterpret_cast<Typ>(value);
-        }
-        
-        template<class Typ>
-        typename std::enable_if<! std::is_pointer<Typ>::value, void*>::type
-        __wrap(const Typ& value){
-            Typ* holder = new Typ(value);
-            return holder;
+    public:
+        template<class Id>
+        bool  exists(const Id& object){
+            unsigned int id = AttachmentsId<Id>::getId(object);
+
+            return __exists(id);
         }
-        
-        template<class Typ>
-        typename std::enable_if<! std::is_pointer<Typ>::value, Typ&>::type
-        __unwrap(void* value){
-            return *reinterpret_cast<Typ*>(value);
+
+        template<class Id>
+        Data& get(const Id& object){
+            unsigned int id = AttachmentsId<Id>::getId(object);
+
+            return __get(id);
         }
 
-        template<class Typ>
-        typename std::enable_if<std::is_pointer<Typ>::value, void>::type
-        __delete(void* value){
-            delete reinterpret_cast<Typ>(value);
+        template<class Id>
+        Data  get(const Id& object, const Data& dataDefault){
+            unsigned int id = AttachmentsId<Id>::getId(object);
+
+            if (! __exists(id)){
+                return dataDefault;
+            }
+
+            return __get(id);
         }
-        
-        template<class Typ>
-        typename std::enable_if<! std::is_pointer<Typ>::value, void>::type
-        __delete(void* value){
-            delete reinterpret_cast<Typ*>(value);
+
+        template<class Id>
+        void put(const Id& object, Data data){
+            unsigned int id = AttachmentsId<Id>::getId(object);
+
+                __put(id, data);
         }
-    }
+
+        virtual ~IAttachmentsContainer(){};
+};
     
-        //TODO copy whole data from symbol to symbol: copy(sTo, sFrom);
-    class Attachments
-    {
-    public:
-                //TODO add specialization for pointers
-        template<class Tag>
-        using  Data = typename AttachmentsDict<Tag>::Data;
+template<class Data>
+class AttachmentsContainerDefault: public IAttachmentsContainer<Data>{
+private:
+    std::unordered_map<unsigned int, Data> __data;
 
-        template<class Holder, class Tag>
-        static void put(const Holder& holder, const Data<Tag>& data)
-        {
-            const unsigned int key = AttachmentsDict<Tag>::key;
-            Attachments* self = AttachmentsStorage<Holder>::get(holder);
+    virtual bool  __exists(const unsigned int id){
+        return __data.count(id);
+    }
 
-            void* dataWaste = self->put(key, detail::__wrap(data));
-            detail::__delete<Data<Tag>>(dataWaste);
-        }
+    virtual Data& __get(const unsigned int id){
+        return __data.at(id);
+    }
+
+    virtual void __put(const unsigned int id, Data data){
+        auto result = __data.emplace(id, data);
+        assert(result.second);
+    }
+};
 
-        template<class Holder, class Tag>
-        static Data<Tag>&  get(const Holder& holder)
-        {
-            const unsigned int key = AttachmentsDict<Tag>::key;
-            Attachments* self = AttachmentsStorage<Holder>::get(holder);
 
-            return detail::__unwrap<Data<Tag>>(self->get(key));
+class Attachments{
+    private:
+        static std::vector<void*> __storage;
+        
+        template<class Tag>
+        using  Data = typename AttachmentsDict<Tag>::Data;
+        
+    public:
+        template<class Tag, class Id>
+        static bool exists(const Id& object) {
+            assert(AttachmentsDict<Tag>::key < __storage.size());
+            assert(__storage.at(AttachmentsDict<Tag>::key));
+            
+            IAttachmentsContainer<Data<Tag>>* self = reinterpret_cast<IAttachmentsContainer<Data<Tag>>*>(__storage.at(AttachmentsDict<Tag>::key));
+            return self->exists<Id>(object);
         }
         
-        template<class Holder, class Tag>
-        static Data<Tag>  get(const Holder& holder, Data<Tag>&& dataDefault)
-        {
-            if (! exists<Holder, Tag>(holder)){
-                return dataDefault;
+        template<class Tag, class Id>
+        static Data<Tag>& get(const Id& object){
+            assert(AttachmentsDict<Tag>::key < __storage.size());
+            assert(__storage.at(AttachmentsDict<Tag>::key));
+            
+            IAttachmentsContainer<Data<Tag>>* self = reinterpret_cast<IAttachmentsContainer<Data<Tag>>*>(__storage.at(AttachmentsDict<Tag>::key));
+            return self->get<Id>(object);
+        }
+            
+        template<class Tag, class Id>
+        static Data<Tag>  get(const Id& object, const Data<Tag>& dataDefault){
+            assert(AttachmentsDict<Tag>::key < __storage.size());
+            assert(__storage.at(AttachmentsDict<Tag>::key));
+            
+            IAttachmentsContainer<Data<Tag>>* self = reinterpret_cast<IAttachmentsContainer<Data<Tag>>*>(__storage.at(AttachmentsDict<Tag>::key));
+            return self->get<Id>(object, dataDefault);
+        }
+            
+        template<class Tag, class Id>
+        static void put(const Id& object, Data<Tag> data){
+            assert(AttachmentsDict<Tag>::key < __storage.size());
+            assert(__storage.at(AttachmentsDict<Tag>::key));
+            
+            IAttachmentsContainer<Data<Tag>>* self = reinterpret_cast<IAttachmentsContainer<Data<Tag>>*>(__storage.at(AttachmentsDict<Tag>::key));
+            self->put<Id>(object, data);
+        }
+        
+        template<class Tag>
+        static void init(){
+            unsigned int keyStorage = AttachmentsDict<Tag>::key;
+            if (keyStorage+1 > __storage.size()){
+                __storage.resize(keyStorage + 1, nullptr);
             }
             
-            const unsigned int key = AttachmentsDict<Tag>::key;
-            Attachments* self = AttachmentsStorage<Holder>::get(holder);
-
-            return detail::__unwrap<Data<Tag>>(self->get(key));
+            __storage[keyStorage] = new AttachmentsContainerDefault<Data<Tag>>();
         }
-
-        template<class Holder, class Tag>
-        static bool exists(const Holder& holder)
-        {
-            const unsigned int key = AttachmentsDict<Tag>::key;
-            Attachments* self = AttachmentsStorage<Holder>::get(holder);
-            return self->exists(key);
+        
+        template<class Tag>
+        static void init(IAttachmentsContainer<Data<Tag>>* container){
+            unsigned int keyStorage = AttachmentsDict<Tag>::key;
+            if (keyStorage+1 > __storage.size()){
+                __storage.resize(keyStorage + 1, nullptr);
+            }
+            
+            __storage[keyStorage] = container;
         }
+};
 
-    private:
-        std::map<unsigned int, void*> __data;
-
-        void* put(unsigned int key, void *data);
-        void* get(unsigned int key);
-        bool exists(unsigned int key);
-    };
 }
 
-#endif //_XREATE_ATTACHMENTS_H_
+#endif //_XREATE_ATTACHMENTS_H_
\ No newline at end of file
diff --git a/cpp/src/clasplayer.cpp b/cpp/src/clasplayer.cpp
index 6434235..65ff3fb 100644
--- a/cpp/src/clasplayer.cpp
+++ b/cpp/src/clasplayer.cpp
@@ -1,275 +1,275 @@
 #include "clasplayer.h"
 
 #include <iostream>
 #include "utils.h"
 #include <boost/format.hpp>
 #include <boost/algorithm/string/join.hpp>
 #include <gringo/scripts.hh>
 
 #include "analysis/aux.h"
 #include "analysis/DominatorsTreeAnalysisProvider.h"
 #include "analysis/cfagraph.h"
 #include "analysis/dfagraph.h"
 
 using namespace std;
 
 //TODO escape identifiers started from upper case symbol
 namespace xreate {
 
     void
     ClaspLayer::printWarnings(std::ostream& out)
     {
         const std::string warningTag = "warning";
 
         auto warningsRange = __model.equal_range(warningTag);
 
         for (auto warning=warningsRange.first; warning!= warningsRange.second; ++warning) {
             unsigned int warningId;
 
             Gringo::Symbol params;
             std::tie(warningId, params) = parse<unsigned int, Gringo::Symbol>(warning->second);
 
             cout << "Warning: " << __warnings.at(warningId) << " ";
             params.print(out);
             out<<params;
         }
     }
 
     bool
     ClaspLayer::handleSolution(Gringo::Model const &model) {
         std::list<std::string> warnings;
         cout << "Model: " << endl;
 
         const string& atomBindVar = Config::get("clasp.bindings.variable");
         const string& atomBindFunc = Config::get("clasp.bindings.function");
         const string& atomBindScope = Config::get("clasp.bindings.scope");
 
         for (Gringo::Symbol atom : model.atoms(clingo_show_type_atoms)) {
             atom.print(cout);
             cout <<" | "<< endl;
 
             string atomName(atom.name().c_str());
             if (atomName == atomBindVar || atomName == atomBindFunc || atomName == atomBindScope){
                 string name = std::get<1>(parse<Gringo::Symbol, Gringo::Symbol>(atom)).name().c_str();
                 __model.emplace(move(name), move(atom));
             }
 
             __model.emplace(atomName, move(atom));
         }
 
         return true;
     }
 
     void
     ClaspLayer::setCFAData(xreate::analysis::CFAGraph* graph) {
     	dataCFA.reset(graph);
     }
 
     void
     ClaspLayer::setDFAData(xreate::analysis::DFAGraph* graph){
         dataDFA.reset(graph);
     }
 
     void
     ClaspLayer::addRuleWarning(const RuleWarning &rule) {
         //__partGeneral << rule << endl;
 
         list<string> domains;
         boost::format formatDef("%1%(%2%)");
         std::transform(rule.__args.begin(), rule.__args.end(), std::inserter(domains, domains.begin()),
                 [&formatDef](const std::pair<std::string, DomainAnnotation> &argument) {
                     string domain;
                     switch (argument.second) {
                         case DomainAnnotation::FUNCTION:
                             domain = "function";
                             break;
                         case DomainAnnotation::VARIABLE:
                             domain = "variable";
                             break;
                     }
 
                     return boost::str(formatDef % domain % argument.first);
                 });
 
         list<string> vars;
         std::transform(rule.__args.begin(), rule.__args.end(), std::inserter(vars, vars.begin()),
                 [](const std::pair<std::string, DomainAnnotation> &argument) {
                     return argument.first.c_str();
                 });
 
         list<list<string>> guardsRaw;
         std::transform(rule.__guards.begin(), rule.__guards.end(), std::inserter(guardsRaw, guardsRaw.begin()),
                 [this](const Expression &guard) {
                     return xreate::analysis::compile(guard);
                 });
 
         const list<string>& guards = xreate::analysis::multiplyLists(std::move(guardsRaw));
         list<string> &&branches = xreate::analysis::compileNeg(rule.__condition);
 
         boost::format formatWarning("warning(%1%, (%2%)):- %3%, %4%, %5%.");
         for (const string &guardsJoined: guards)
             for (const string &branch: branches) {
                 unsigned int hook = registerWarning(string(rule.__message));
 
                 __partGeneral  <<  formatWarning
                         %(hook)
                         %(boost::algorithm::join(vars, ", "))
                         %(branch)
                         %(guardsJoined)
                         %(boost::algorithm::join(domains, ", "))
                     <<endl;
             }
     }
 
 
 
     unsigned int
     ClaspLayer::registerWarning(std::string &&message) {
         static int warningId = 0;
         __warnings.emplace(warningId, message);
         return warningId++;;
     }
 
     void
     ClaspLayer::involveImports()    {
         ostream &out = __partGeneral;
 
         for (string fn: ast->__rawImports)
         {
             std::ifstream file(fn);
             if (!file) continue;
 
             while(!file.eof()){
                 string line;
                 std::getline(file, line);
                 out << line << endl;
             }
         }
     }
 
     void
     ClaspLayer::addRawScript(std::string&& script){
     	__partGeneral << script;
     }
 
     void
     ClaspLayer::run() {
         involveImports();
 
         if (this->dataDFA){
             this->dataDFA->print(__partGeneral);
         }
 
         if (this->dataCFA){
             this->dataCFA->print(__partGeneral);
         }
 
         DominatorsTreeAnalysisProvider providerDominators;
         providerDominators.run(this);
         providerDominators.print(__partGeneral);
 
         ostringstream program;
         program << __partTags.str() << __partGeneral.str();
         cout << FYEL(program.str()) << endl;
 
         std::vector<char const *> args{"clingo", nullptr};
         DefaultGringoModule moduleDefault;
         Gringo::Scripts scriptsDefault(moduleDefault);
         ClingoLib ctl(scriptsDefault, 0, args.data(), {}, 0);
 
         ctl.add("base", {}, program.str());
         ctl.ground({{"base", {}}}, nullptr);
 
 //          solve
         Gringo::SolveResult result = ctl.solve([this](Gringo::Model const &model) {
             this->handleSolution(model);
             return true;
         }, {});
 
         if (result.satisfiable() == Gringo::SolveResult::Satisfiable) {
             cout << FGRN("SUCCESSFULLY") << endl;
         } else {
             cout << FRED("UNSUCCESSFULLY") << endl;
         }
 
 //      invoke all query plugins to process clasp data
         for (auto q: __queries)
         {
             q.second->init(this);
         }
     }
 
     ClaspLayer::ClaspLayer() {
     }
 
     ClaspLayer::ModelFragment
     ClaspLayer::query(const std::string& atom)
     {
         if (! __model.count(atom)){
             return boost::none;
         }
 
         return ModelFragment(__model.equal_range(atom));
     }
 
     ScopePacked
     ClaspLayer::pack(CodeScope* const scope) {
     	auto pos = __indexScopes.emplace(scope, __indexScopes.size());
         if (pos.second)
         	__registryScopes.push_back(scope);
 
         return pos.first->second;
     }
 
     size_t
     ClaspLayer::getScopesCount() const{
         return __registryScopes.size();
     }
 
     SymbolPacked
     ClaspLayer::pack(const Symbol& symbol, std::string hintSymbolName)
     {
-        SymbolPacked result(symbol.identifier, pack(symbol.scope));
+        SymbolPacked result(symbol.identifier.id, symbol.identifier.version, pack(symbol.scope));
         __indexSymbolNameHints.emplace(result, hintSymbolName);
 
         return result;
     }
 
     Symbol
     ClaspLayer::unpack(const SymbolPacked& symbol)
     {
-        return Symbol{symbol.identifier, __registryScopes[symbol.scope]};
+        return Symbol{ScopedSymbol{symbol.identifier, symbol.version}, __registryScopes[symbol.scope]};
     };
 
     std::string
     ClaspLayer::getHintForPackedSymbol(const SymbolPacked& symbol){
         if (!symbol.categoryTransient) {
             auto result = __indexSymbolNameHints.find(symbol);
             return (result == __indexSymbolNameHints.end())? "" : result->second;
 
         } else {
             return "anonym(" + to_string(symbol.identifier) + ")";
         }
     }
 
     bool operator==(const SymbolPacked& s1, const SymbolPacked& s2)
     {
         return s1.identifier == s2.identifier && s1.scope == s2.scope;
     }
 
     bool operator<(const SymbolPacked& s1, const SymbolPacked& s2)
     {
         return  s1.scope < s2.scope  || (s1.scope ==  s2.scope && s1.identifier < s2.identifier);
     }
 
     IQuery*
     ClaspLayer::registerQuery(IQuery *query, const QueryId& id) {
         return __queries.emplace(id, query).first->second;
     }
 
     IQuery*
     ClaspLayer::getQuery(const QueryId& id){
     	assert(__queries.count(id) && "Undefined query");
     	return __queries.at(id);
     }
 }
\ No newline at end of file
diff --git a/cpp/src/clasplayer.h b/cpp/src/clasplayer.h
index 6961026..1bfe432 100644
--- a/cpp/src/clasplayer.h
+++ b/cpp/src/clasplayer.h
@@ -1,230 +1,233 @@
 #ifndef CLASPLAYER_H
 #define CLASPLAYER_H
 
 #include "ast.h"
 #include "contextrule.h"
 
 #include <clingo/clingocontrol.hh>
 #include <string>
 #include <climits>
 #include <boost/bimap.hpp>
 #include <boost/bimap/multiset_of.hpp>
 #include <boost/optional.hpp>
 #include <boost/scoped_ptr.hpp>
 #include <list>
 
 namespace xreate {
 
     typedef unsigned int ScopePacked;
 
     struct SymbolPacked {
-        VID identifier;
+        VNameId identifier;
+        VariableVersion version;
         ScopePacked scope;
         bool categoryTransient;
         
         SymbolPacked(): categoryTransient(false){}
-        SymbolPacked(VID i, ScopePacked s, bool isTransient = false): identifier(i), scope(s), categoryTransient(isTransient){}
+        SymbolPacked(ScopedSymbol i, ScopePacked s, bool isTransient = false): identifier(i.id), version(i.version), scope(s), categoryTransient(isTransient){}
+        SymbolPacked(VNameId symbolId, VariableVersion symbolVersion, ScopePacked symbolScope, bool isTransient = false)
+            : identifier(symbolId), version(symbolVersion), scope(symbolScope), categoryTransient(isTransient){}
     };
 
     bool operator==(const SymbolPacked& s1, const SymbolPacked& s2);
     bool operator<(const SymbolPacked& s1, const SymbolPacked& s2);
 
     enum class DFGConnection {
         STRONG, WEAK, PROTOTYPE
     };
 
     class IAnalysisData {
     public:
         void print(std::ostringstream& output) const;
         virtual ~IAnalysisData(){};
     };
     
     class IQuery {
     public:
         virtual void init(ClaspLayer* clasp) = 0;
         virtual ~IQuery() {}
     };
 
     enum class QueryId {
         ContainersQuery,
         ContextQuery,
         PtrvalidQuery
     };
 
     namespace analysis{
         class DFAGraph;
         class CFAGraph;
     }
     
     class ClaspLayer {
         friend class ContextRule;
 
                     //PROVIDERS:
     public:
         boost::scoped_ptr<xreate::analysis::DFAGraph> dataDFA;
         void setDFAData(xreate::analysis::DFAGraph* graph);
 
         boost::scoped_ptr<xreate::analysis::CFAGraph> dataCFA;
         void setCFAData(xreate::analysis::CFAGraph* graph);
 
         void addRawScript(std::string&& script);
 
     private: 
         void involveImports();
 
                     //QUERIES
     public:
         IQuery* registerQuery(IQuery* query, const QueryId& id);
         IQuery* getQuery(const QueryId& id);
 
         template<class ...Types>
         static std::tuple<Types...> parse(const Gringo::Symbol& atom);
 
         typedef std::multimap<std::string, Gringo::Symbol>::const_iterator ModelIterator;
         typedef boost::optional<std::pair<ClaspLayer::ModelIterator, ClaspLayer::ModelIterator>> ModelFragment;
         ModelFragment query(const std::string& atom);
 
         size_t getScopesCount() const;
         SymbolPacked pack(const Symbol& symbol, std::string hintSymbolName = "");
         ScopePacked pack(CodeScope * const scope);
         Symbol unpack(const SymbolPacked& symbol);
         std::string getHintForPackedSymbol(const SymbolPacked& symbol);
 
     private:
         std::map<QueryId, IQuery*> __queries;
         std::multimap<std::string, Gringo::Symbol> __model;
         std::map<SymbolPacked, std::string> __indexSymbolNameHints;
         std::unordered_map<const CodeScope*, unsigned int> __indexScopes;
         std::vector<CodeScope*> __registryScopes;
 
                     //WARNINGS
                     //TODO move to separate provider/query 
     public:
         void addRuleWarning(const RuleWarning &rule);
         unsigned int registerWarning(std::string &&message);
 
     private:
         std::map<unsigned int, std::string> __warnings;
         void printWarnings(std::ostream& out);
 
                     //DEFAULT
     public:
         AST *ast;
 
         ClaspLayer();
         void run();
             
     private:
         std::ostringstream __partTags;
         std::ostringstream __partGeneral;
 
         bool handleSolution(Gringo::Model const &model);
     };
 
     template<class typ>
     struct ParseImplAtom {
 
         static typ get(const Gringo::Symbol& atom) {
             return atom.num();
         }
     };
 
     template<>
     struct ParseImplAtom<std::string> {
         static std::string get(const Gringo::Symbol& atom) {
             switch (atom.type()) {
                 case Gringo::SymbolType::Str: return atom.string().c_str();
                 case Gringo::SymbolType::Fun: return atom.name().c_str();
                 
                 default: break;
             }
                 
             assert(false && "Inappropriate symbol type");
         }
     };
 
     template<>
     struct ParseImplAtom<SymbolPacked> {
 
         static SymbolPacked get(const Gringo::Symbol& atom) {
-            auto result = ClaspLayer::parse<unsigned int, unsigned int>(atom);
-            return SymbolPacked(std::get<0>(result), std::get<1>(result));
+            auto result = ClaspLayer::parse<unsigned int, unsigned int, unsigned int>(atom);
+            return SymbolPacked(std::get<0>(result), std::get<1>(result), std::get<2>(result));
         }
     };
 
     template<>
     struct ParseImplAtom<Gringo::Symbol> {
 
         static Gringo::Symbol get(const Gringo::Symbol& atom) {
             return atom;
         }
     };
 
     template<>
     struct ParseImplAtom<Expression> {
 
         static Expression get(const Gringo::Symbol& atom) {
             switch (atom.type()) {
                 case Gringo::SymbolType::Num: return Expression(atom.num());
                 case Gringo::SymbolType::Str: return Expression(std::string(atom.string().c_str()));
                 
                 case Gringo::SymbolType::Fun:
                 {
                     //ID
                     if (!atom.args().size){
                         return Expression(std::string(atom.name().c_str()));
                     }
                     
                     //FUNC
                     Expression result(Operator::CALL,{Expression(std::string(atom.name().c_str()))});
                     for (const Gringo::Symbol& arg : atom.args()) {
                         result.addArg(ParseImplAtom<Expression>::get(arg));
                     }
 
                     return result;
                 }
 
                 default:
                 {
                     assert(false);
                 }
             }
         }
     };
 
     template<class Tuple, size_t index>
     struct Parse_Impl {
 
         static void parse(Tuple& tup, Gringo::SymSpan::iterator arg) {
             const size_t tupleSize = std::tuple_size<Tuple>::value;
             typedef typename std::tuple_element < tupleSize - index, Tuple>::type ElType;
 
             ElType& el = std::get < tupleSize - index > (tup);
 
             Gringo::Symbol atom = *arg;
             el = ParseImplAtom<ElType>::get(atom);
 
             Parse_Impl<Tuple, index - 1 > ::parse(tup, ++arg);
         }
     };
 
     template<class Tuple>
     struct Parse_Impl<Tuple, 0> {
 
         static void parse(Tuple& tup, Gringo::SymSpan::iterator arg) {
         }
     };
 
     template<class ...Types>
     std::tuple<Types...>
     ClaspLayer::parse(const Gringo::Symbol& atom) {
         typedef std::tuple < Types...> Tuple;
         Tuple tup;
         Parse_Impl<Tuple, std::tuple_size<Tuple>::value>::parse(tup, atom.args().first);
 
         return tup;
     }
 
 
 }
 #endif
\ No newline at end of file
diff --git a/cpp/src/compilation/advanced.cpp b/cpp/src/compilation/advanced.cpp
index d49ede8..d5183a8 100644
--- a/cpp/src/compilation/advanced.cpp
+++ b/cpp/src/compilation/advanced.cpp
@@ -1,432 +1,403 @@
 /*
  * File:   InstructionsAdvanced.cpp
  * Author: pgess
  *
  * Created on June 26, 2016, 6:00 PM
  */
 
-#include <compilation/transformations.h>
+//#include <compilation/transformations.h>
 #include "compilation/advanced.h"
 #include "compilation/containers.h"
+#include "compilation/transformersaturation.h"
 
 #include "query/context.h"
 #include "query/containers.h"
 #include "llvmlayer.h"
 #include "ast.h"
 
 using namespace std;
 using namespace llvm;
 using namespace xreate;
 using namespace xreate::containers;
 using namespace xreate::compilation;
 
 #define NAME(x) (hintRetVar.empty()? x : hintRetVar)
 #define UNUSED(x) (void)(x)
 #define EXPAND_CONTEXT         \
     LLVMLayer* llvm = context.pass->man->llvm; \
-    compilation::CodeScopeUnit* scope = context.scope; \
+    compilation::AbstractCodeScopeUnit* scope = context.scope; \
     compilation::FunctionUnit* function = context.function;
 
 Advanced::Advanced(compilation::Context ctx)
 : context(ctx), tyNum(static_cast<llvm::IntegerType*> (ctx.pass->man->llvm->toLLVMType(ExpandedType(TypeAnnotation(TypePrimitive::Num))))) {
 }
 
 llvm::Value*
 Advanced::compileMapSolidOutput(const Expression &expr, const std::string hintRetVar) {
     EXPAND_CONTEXT
 
     //initialization
-    std::string varIn = expr.getOperands()[0].getValueString();
-    Symbol symbolIn = scope->scope->findSymbol(varIn);
+    Symbol symbolIn = Attachments::get<Symbol>(expr.getOperands()[0]);
 
     ImplementationRec<SOLID> implIn = containers::Query::queryImplementation(symbolIn).extract<SOLID>(); // impl of input list
     size_t size = implIn.size;
     CodeScope* scopeLoop = expr.blocks.front();
     std::string varEl = scopeLoop->__bindings[0];
 
     Iterator* it = Iterator::create(context, symbolIn);
     llvm::Value *rangeFrom = it->begin();
     llvm::Value *rangeTo = it->end();
 
     //definitions
     ArrayType* tyNumArray = (ArrayType*) (llvm->toLLVMType(ExpandedType(TypeAnnotation(tag_array, TypePrimitive::Num, size))));
     llvm::IRBuilder<> &builder = llvm->builder;
 
     llvm::BasicBlock *blockLoop = llvm::BasicBlock::Create(llvm::getGlobalContext(), "loop", function->raw);
     llvm::BasicBlock *blockBeforeLoop = builder.GetInsertBlock();
     llvm::BasicBlock *blockAfterLoop = llvm::BasicBlock::Create(llvm::getGlobalContext(), "postloop", function->raw);
     Value* dataOut = llvm->builder.CreateAlloca(tyNumArray, ConstantInt::get(tyNum, size), NAME("map"));
 
     // * initial check
     Value* condBefore = builder.CreateICmpSLE(rangeFrom, rangeTo);
     builder.CreateCondBr(condBefore, blockLoop, blockAfterLoop);
 
     // create PHI:
     builder.SetInsertPoint(blockLoop);
     llvm::PHINode *stateLoop = builder.CreatePHI(tyNum, 2, "mapIt");
     stateLoop->addIncoming(rangeFrom, blockBeforeLoop);
 
     // loop body:
     Value* elIn = it->get(stateLoop, varEl);
-    compilation::CodeScopeUnit* scopeLoopUnit = function->getScopeUnit(scopeLoop);
+    compilation::AbstractCodeScopeUnit* scopeLoopUnit = function->getScopeUnit(scopeLoop);
     scopeLoopUnit->bindArg(elIn, move(varEl));
     Value* elOut = scopeLoopUnit->compile();
     Value *pElOut = builder.CreateGEP(dataOut, ArrayRef<Value *>(std::vector<Value*>{ConstantInt::get(tyNum, 0), stateLoop}));
     builder.CreateStore(elOut, pElOut);
 
     //next iteration preparing
     Value *stateLoopNext = builder.CreateAdd(stateLoop, llvm::ConstantInt::get(tyNum, 1));
-    stateLoop->addIncoming(stateLoopNext, blockLoop);
+    stateLoop->addIncoming(stateLoopNext, builder.GetInsertBlock());
 
     //next iteration checks:
     Value* condAfter = builder.CreateICmpSLE(stateLoopNext, rangeTo);
     builder.CreateCondBr(condAfter, blockLoop, blockAfterLoop);
 
     //finalization:
     builder.SetInsertPoint(blockAfterLoop);
 
     return dataOut;
 }
 
 Value*
 Advanced::compileArrayIndex(llvm::Value* aggregate, std::vector<llvm::Value *> indexes, std::string hintRetVar) {
     EXPAND_CONTEXT
     UNUSED(function);
 
     indexes.insert(indexes.begin(), llvm::ConstantInt::get(tyNum, 0));
     llvm::Value *pEl = llvm->builder.CreateGEP(aggregate, llvm::ArrayRef<llvm::Value *>(indexes));
     return llvm->builder.CreateLoad(pEl, NAME("el"));
 }
 
 Value*
 Advanced::compileStructIndex(llvm::Value* aggregate, const ExpandedType& t, const std::string& idx) {
     EXPAND_CONTEXT
     UNUSED(scope);
 
 
     TypeUtils types(llvm);
 
     std::vector<std::string>&& fields = types.getStructFields(t);
     for (unsigned i = 0, size = fields.size(); i < size; ++i) {
         if (fields.at(i) == idx) {
 
             std::vector<llvm::Value*> refs;
 
             llvm::IntegerType* tyInt = llvm::Type::getInt32Ty(llvm::getGlobalContext());
             llvm::ConstantInt* zero = llvm::ConstantInt::get(tyInt, 0, false);
 
             llvm::BasicBlock *blockSafe = llvm::BasicBlock::Create(llvm::getGlobalContext(), "safe", function->raw);
 
 
             // TODO review safety check: validPtr for `aggregate`
             // SECTIONTAG validptr exception
             PointerType* tyAggr = dyn_cast<PointerType>(aggregate->getType());
             llvm::Value* null = llvm::ConstantPointerNull::get(tyAggr);
             Value* condNull = llvm->builder.CreateICmpNE(aggregate, null);
 
             llvm::BasicBlock *blockException = llvm::BasicBlock::Create(llvm::getGlobalContext(), "exception", function->raw);
             llvm->builder.CreateCondBr(condNull, blockSafe, blockException);
             llvm->initExceptionBlock(blockException);
 
             llvm->builder.SetInsertPoint(blockSafe);
             std::vector<Value*> indexes;
 
             //dereference pointer
             if (types.isPointer(t)) {
                 indexes.push_back(zero);
             }
 
             indexes.push_back(ConstantInt::get(tyInt, i));
 
             Value* addr = llvm->builder.CreateGEP(aggregate, indexes);
             return llvm->builder.CreateLoad(addr);
         }
     }
 
     assert(false && "not found required struct field");
     return nullptr;
 }
 
 llvm::Value*
 Advanced::compileFold(const Expression& fold, const std::string& hintRetVar) {
     EXPAND_CONTEXT
     assert(fold.op == Operator::FOLD);
 
     //initialization:
-    Symbol varInSymbol = scope->scope->findSymbol(fold.getOperands()[0].getValueString());
+    Symbol varInSymbol = Attachments::get<Symbol>(fold.getOperands()[0]);
     Implementation info = Query::queryImplementation(varInSymbol);
 
     Iterator* it = Iterator::create(context, varInSymbol);
     llvm::Value* rangeBegin = it->begin();
     llvm::Value* rangeEnd = it->end();
     llvm::Value* accumInit = scope->process(fold.getOperands()[1]);
     std::string varIn = fold.getOperands()[0].getValueString();
     std::string varAccum = fold.bindings[1];
     std::string varEl = fold.bindings[0];
-    TransformerSaturation* transformerSaturation = context.pass->transformations->get<TransformerSaturation>();
 
     llvm::BasicBlock *blockBeforeLoop = llvm->builder.GetInsertBlock();
+    std::unique_ptr<TransformerSaturation> transformerSaturation(new TransformerSaturation(blockBeforeLoop, context.pass->managerTransformations));
+
+
     llvm::BasicBlock *blockLoop = llvm::BasicBlock::Create(llvm::getGlobalContext(), "fold", function->raw);
-    llvm::BasicBlock *blockBody = llvm::BasicBlock::Create(llvm::getGlobalContext(), "body", function->raw);
-    llvm::BasicBlock *blockAfterLoop = llvm::BasicBlock::Create(llvm::getGlobalContext(), "postfold", function->raw);
+    llvm::BasicBlock *blockLoopBody = llvm::BasicBlock::Create(llvm::getGlobalContext(), "fold_body", function->raw);
+    llvm::BasicBlock *blockAfterLoop = llvm::BasicBlock::Create(llvm::getGlobalContext(), "fold_after", function->raw);
+    llvm::BasicBlock *blockNext = llvm::BasicBlock::Create(llvm::getGlobalContext(), "fold_next", function->raw);
 
     llvm->builder.CreateBr(blockLoop);
 
     // * create phi
     llvm->builder.SetInsertPoint(blockLoop);
-    llvm::PHINode *accum = llvm->builder.CreatePHI(accumInit->getType(), 2, NAME("accum"));
+    llvm::PHINode *accum = llvm->builder.CreatePHI(accumInit->getType(), 2, varAccum);
     accum->addIncoming(accumInit, blockBeforeLoop);
     llvm::PHINode *itLoop = llvm->builder.CreatePHI(rangeBegin->getType(), 2, "foldIt");
     itLoop->addIncoming(rangeBegin, blockBeforeLoop);
 
+    // * loop checks
+    Value* condRange = llvm->builder.CreateICmpNE(itLoop, rangeEnd);
+    llvm->builder.CreateCondBr(condRange, blockLoopBody, blockAfterLoop);
+
     // * loop body
-    llvm->builder.SetInsertPoint(blockBody);
+    llvm->builder.SetInsertPoint(blockLoopBody);
     CodeScope* scopeLoop = fold.blocks.front();
-    compilation::CodeScopeUnit* loopUnit = function->getScopeUnit(scopeLoop);
+    compilation::AbstractCodeScopeUnit* loopUnit = function->getScopeUnit(scopeLoop);
     Value* elIn = it->get(itLoop);
     loopUnit->bindArg(accum, move(varAccum));
     loopUnit->bindArg(elIn, move(varEl));
     Value* accumNext = loopUnit->compile();
 
+    // * Loop saturation checks
+    bool flagSaturationTriggered = transformerSaturation->insertSaturationChecks(blockNext, blockAfterLoop, context);
+    llvm::BasicBlock* blockSaturation = llvm->builder.GetInsertBlock();
+    if (!flagSaturationTriggered){
+        llvm->builder.CreateBr(blockNext);
+    }
+
     // * computing next iteration state
+    llvm->builder.SetInsertPoint(blockNext);
     Value *itLoopNext = it->advance(itLoop);
     accum->addIncoming(accumNext, llvm->builder.GetInsertBlock());
     itLoop->addIncoming(itLoopNext, llvm->builder.GetInsertBlock());
     llvm->builder.CreateBr(blockLoop);
 
-    // * break checks, continue checks
-    //!! only after compiled Loop Body in order to fetch saturation expression
-    llvm->builder.SetInsertPoint(blockLoop);
-    if (transformerSaturation->exists()) {
-        transformerSaturation->inject(blockBeforeLoop, blockAfterLoop, context);
-    }
-
-    // * next iteration checks
-    Value* condRange = llvm->builder.CreateICmpNE(itLoop, rangeEnd);
-    llvm->builder.CreateCondBr(condRange, blockBody, blockAfterLoop);
-
-    // finalization:
+    // * finalization:
     llvm->builder.SetInsertPoint(blockAfterLoop);
+    if (!flagSaturationTriggered){
+        return accum;
+    }
 
-    return accum;
+    llvm::PHINode* result = llvm->builder.CreatePHI(accumInit->getType(), 2);
+    result->addIncoming(accum, blockLoop);
+    result->addIncoming(accumNext, blockSaturation);
+    return result;
 }
 
 llvm::Value*
 Advanced::compileFoldInf(const Expression& fold, const std::string& hintRetVar) {
     EXPAND_CONTEXT
     assert(fold.op == Operator::FOLD_INF);
 
     std::string accumName = fold.bindings[0];
     llvm::Value* accumInit = scope->process(fold.getOperands()[0]);
 
     llvm::BasicBlock *blockBeforeLoop = llvm->builder.GetInsertBlock();
-    llvm::BasicBlock *blockLoop = llvm::BasicBlock::Create(llvm::getGlobalContext(), "fold", function->raw);
-    llvm::BasicBlock *blockBody = llvm::BasicBlock::Create(llvm::getGlobalContext(), "body", function->raw);
-    llvm::BasicBlock *blockAfterLoop = llvm::BasicBlock::Create(llvm::getGlobalContext(), "postfold", function->raw);
-    TransformerSaturation* transformerSaturation = context.pass->transformations->get<TransformerSaturation>();
+    llvm::BasicBlock *blockLoop = llvm::BasicBlock::Create(llvm::getGlobalContext(), "foldinf", function->raw);
+    llvm::BasicBlock *blockNext = llvm::BasicBlock::Create(llvm::getGlobalContext(), "foldinf_next", function->raw);
+    llvm::BasicBlock *blockAfterLoop = llvm::BasicBlock::Create(llvm::getGlobalContext(), "foldinf_post", function->raw);
+    std::unique_ptr<TransformerSaturation> transformerSaturation(new TransformerSaturation(blockBeforeLoop, context.pass->managerTransformations));
 
     llvm->builder.CreateBr(blockLoop);
 
     // * create phi
     llvm->builder.SetInsertPoint(blockLoop);
-    llvm::PHINode *accum = llvm->builder.CreatePHI(accumInit->getType(), 2, NAME("accum"));
+    llvm::PHINode *accum = llvm->builder.CreatePHI(accumInit->getType(), 2, accumName);
     accum->addIncoming(accumInit, blockBeforeLoop);
 
     // * loop body
-    llvm->builder.SetInsertPoint(blockBody);
     CodeScope* scopeLoop = fold.blocks.front();
-    compilation::CodeScopeUnit* unitLoop = function->getScopeUnit(scopeLoop);
+    compilation::AbstractCodeScopeUnit* unitLoop = function->getScopeUnit(scopeLoop);
     unitLoop->bindArg(accum, move(accumName));
     Value* accumNext = unitLoop->compile();
 
+    // * Loop saturation checks
+    bool flagSaturationTriggered = transformerSaturation->insertSaturationChecks(blockNext, blockAfterLoop, context);
+    assert(flagSaturationTriggered);
+
     // * computing next iteration state
+    llvm->builder.SetInsertPoint(blockNext);
     accum->addIncoming(accumNext, llvm->builder.GetInsertBlock());
     llvm->builder.CreateBr(blockLoop);
 
-    // * break checks, continue checks
-    assert(transformerSaturation->exists());
-    llvm->builder.SetInsertPoint(blockLoop);
-    transformerSaturation->inject(blockBeforeLoop, blockAfterLoop, context);
-    llvm->builder.CreateBr(blockBody);
-
     // finalization:
     llvm->builder.SetInsertPoint(blockAfterLoop);
-    return accum;
-}
-
-llvm::Value*
-Advanced::compileLoopContext(const Expression& expression, const std::string& hintRetVar) {
-    EXPAND_CONTEXT
-    llvm::IRBuilder<>& builder = llvm->builder;
-
-    ContextQuery* queryContext = reinterpret_cast<ContextQuery*> (context.pass->man->clasp->getQuery(QueryId::ContextQuery));
-
-    ScopePacked scopeOuterId = context.pass->man->clasp->pack(scope->scope);
-    const Domain& contextScopeOuter = queryContext->getContext(scopeOuterId);
-    std::string classSelected = expression.operands[0].getValueString();
-
-    std::list<Expression> elementsSelected;
-    for (const Expression& c : contextScopeOuter) {
-        if (c.op == Operator::CALL && c.getValueString() == classSelected) {
-            assert(c.operands.size());
-            elementsSelected.push_back(c.operands[0]);
-        }
-    }
-
-    assert(expression.blocks.size());
-    CodeScope* scopeInner = expression.blocks.front();
-    compilation::CodeScopeUnit* scopeInnerUnit = function->getScopeUnit(scopeInner);
-    ScopePacked scopeInnerId = context.pass->man->clasp->pack(scopeInner);
-
-    llvm::Value* result = nullptr;
-    for (const Expression& element : elementsSelected) {
-        std::string blockName = "context" + element.getValueString();
-        llvm::BasicBlock *blockInner = llvm::BasicBlock::Create(llvm::getGlobalContext(), blockName, function->raw);
-        builder.CreateBr(blockInner);
-        builder.SetInsertPoint(blockInner);
-
-        queryContext->forceContext(scopeInnerId,{element});
-        scopeInnerUnit->reset();
-        result = scopeInnerUnit->compile();
-    }
-
-    return result;
+    return accumNext;
 }
 
 llvm::Value*
 Advanced::compileIf(const Expression& exprIf, const std::string& hintRetVar) {
     EXPAND_CONTEXT
 
             //initialization:
             const Expression& condExpr = exprIf.getOperands()[0];
     llvm::IRBuilder<>& builder = llvm->builder;
-    llvm::Type* tyResultType = llvm->toLLVMType(llvm->ast->expandType(exprIf.type));
+    //llvm::Type* tyResultType = llvm->toLLVMType(llvm->ast->expandType(exprIf.type));
 
     llvm::BasicBlock *blockAfter = llvm::BasicBlock::Create(llvm::getGlobalContext(), "ifAfter", function->raw);
     llvm::BasicBlock *blockTrue = llvm::BasicBlock::Create(llvm::getGlobalContext(), "ifTrue", function->raw);
     llvm::BasicBlock *blockFalse = llvm::BasicBlock::Create(llvm::getGlobalContext(), "ifFalse", function->raw);
 
     llvm::Value* cond = scope->process(condExpr);
     llvm->builder.CreateCondBr(cond, blockTrue, blockFalse);
 
     builder.SetInsertPoint(blockTrue);
     CodeScope* scopeTrue = exprIf.blocks.front();
     llvm::Value* resultTrue = function->getScopeUnit(scopeTrue)->compile();
+    blockTrue = builder.GetInsertBlock();
     builder.CreateBr(blockAfter);
 
     builder.SetInsertPoint(blockFalse);
     CodeScope* scopeFalse = exprIf.blocks.back();
     llvm::Value* resultFalse = function->getScopeUnit(scopeFalse)->compile();
+    blockFalse = builder.GetInsertBlock();
     builder.CreateBr(blockAfter);
 
     builder.SetInsertPoint(blockAfter);
-    llvm::PHINode *ret = builder.CreatePHI(tyResultType, 2, NAME("if"));
+    llvm::PHINode *ret = builder.CreatePHI(resultTrue->getType(), 2, NAME("if"));
     ret->addIncoming(resultTrue, blockTrue);
     ret->addIncoming(resultFalse, blockFalse);
 
     return ret;
 }
 
 //TODO Switch: default variant no needed when all possible conditions are considered
 
 llvm::Value*
 Advanced::compileSwitch(const Expression& exprSwitch, const std::string& hintRetVar) {
     EXPAND_CONTEXT
     UNUSED(function);
 
     assert(exprSwitch.operands.size() >= 2);
     assert(exprSwitch.operands[1].op == Operator::CASE_DEFAULT && "No default case in Switch Statement");
     int countCases = exprSwitch.operands.size() - 1;
     llvm::IRBuilder<>& builder = llvm->builder;
 
     llvm::BasicBlock* blockProlog = builder.GetInsertBlock();
     llvm::BasicBlock *blockEpilog = llvm::BasicBlock::Create(llvm::getGlobalContext(), "switchAfter", function->raw);
     builder.SetInsertPoint(blockEpilog);
     llvm::Type* exprSwitchType = llvm->toLLVMType(ExpandedType(exprSwitch.type));
     llvm::PHINode *ret = builder.CreatePHI(exprSwitchType, countCases, NAME("switch"));
 
     builder.SetInsertPoint(blockProlog);
     llvm::Value * conditionSwitch = scope->process(exprSwitch.operands[0]);
     llvm::BasicBlock *blockDefault = llvm::BasicBlock::Create(llvm::getGlobalContext(), "caseDefault", function->raw);
     llvm::SwitchInst * instructionSwitch = builder.CreateSwitch(conditionSwitch, blockDefault, countCases);
 
     for (int size = exprSwitch.operands.size(), i = 2; i < size; ++i) {
         llvm::BasicBlock *blockCase = llvm::BasicBlock::Create(llvm::getGlobalContext(), "case" + std::to_string(i), function->raw);
 
         llvm::Value* condCase = function->getScopeUnit(exprSwitch.operands[i].blocks.front())->compile();
         builder.SetInsertPoint(blockCase);
         llvm::Value* resultCase = function->getScopeUnit(exprSwitch.operands[i].blocks.back())->compile();
         builder.CreateBr(blockEpilog);
 
         ret->addIncoming(resultCase, builder.GetInsertBlock());
         builder.SetInsertPoint(blockProlog);
         instructionSwitch->addCase(dyn_cast<llvm::ConstantInt>(condCase), blockCase);
     }
 
     //compile default block:
     builder.SetInsertPoint(blockDefault);
     CodeScope* scopeDefault = exprSwitch.operands[1].blocks.front();
     llvm::Value* resultDefault = function->getScopeUnit(scopeDefault)->compile();
     builder.CreateBr(blockEpilog);
     ret->addIncoming(resultDefault, builder.GetInsertBlock());
     builder.SetInsertPoint(blockEpilog);
 
     return ret;
 }
 
 //TODO recognize cases to make const arrays/stored in global mem/stack alloced.
 llvm::Value*
 Advanced::compileListAsSolidArray(const Expression &expr, const std::string& hintRetVar) {
     EXPAND_CONTEXT
     UNUSED(scope);
     UNUSED(function);
 
     AST* root = context.pass->man->root;
     const size_t& length = expr.getOperands().size();
     const Expression& expression = expr;
     llvm::Value* zero = ConstantInt::get(tyNum, 0);
     llvm::Value* one = ConstantInt::get(tyNum, 1);
 
     ExpandedType typAggrExpanded = root->expandType(expression.type);
     assert(typAggrExpanded->__operator == TypeOperator::ARRAY);
     llvm::Type* typEl = llvm->toLLVMType(ExpandedType(typAggrExpanded->__operands[0]));
     ArrayType* typAggr = (ArrayType*) llvm::ArrayType::get(typEl, length);
     llvm::Value* list = llvm->builder.CreateAlloca(typAggr, ConstantInt::get(Type::getInt32Ty(llvm::getGlobalContext()), length, false), hintRetVar);
 
     const std::vector<Expression>& operands = expression.getOperands();
     llvm::Value* addrOperand = llvm->builder.CreateGEP(typAggr, list, ArrayRef<Value *>(std::vector<Value*>{zero, zero}));
     llvm->builder.CreateStore(scope->process(operands.front()), addrOperand) ;
     for (auto i=++operands.begin(); i!=operands.end(); ++i){
         addrOperand = llvm->builder.CreateGEP(typEl, addrOperand, ArrayRef<Value *>(std::vector<Value*>{one}));
         llvm->builder.CreateStore(scope->process(*i), addrOperand) ;
     }
 
     return list;
 //        Value* listDest = l.builder.CreateAlloca(typList, ConstantInt::get(typI32, __size), *hintRetVar);
 //        l.buil1der.CreateMemCpy(listDest, listSource, __size, 16);
 }
 
 llvm::Value*
         Advanced::compileConstantStringAsPChar(const string& data, const std::string& hintRetVar) {
     EXPAND_CONTEXT
     UNUSED(function);
             UNUSED(scope);
 
             Type* typPchar = PointerType::getUnqual(Type::getInt8Ty(llvm::getGlobalContext()));
             //ArrayType* typStr = (ArrayType*) (llvm->toLLVMType(ExpandedType(TypeAnnotation(tag_array, TypePrimitive::I8, size+1))));
 
             /*
             std::vector<Constant *> chars;
             chars.reserve(size+1);
 
             for (size_t i=0; i< size; ++i){
                 chars[i] = ConstantInt::get(typI8, (unsigned char) data[i]);
             }
             chars[size] = ConstantInt::get(typI8, 0);
              */
 
             Value* rawData = ConstantDataArray::getString(llvm::getGlobalContext(), data);
             Value* rawPtrData = llvm->builder.CreateAlloca(rawData->getType(), ConstantInt::get(Type::getInt32Ty(llvm::getGlobalContext()), 1, false));
             llvm->builder.CreateStore(rawData, rawPtrData);
     return llvm->builder.CreateCast(llvm::Instruction::BitCast, rawPtrData, typPchar, hintRetVar);
 }
diff --git a/cpp/src/compilation/advanced.h b/cpp/src/compilation/advanced.h
index 373e825..5bef2ef 100644
--- a/cpp/src/compilation/advanced.h
+++ b/cpp/src/compilation/advanced.h
@@ -1,47 +1,49 @@
 /* 
  * File:   InstructionsAdvanced.h
  * Author: pgess
  *
  * Created on June 26, 2016, 6:00 PM
  */
 
 #ifndef INSTRUCTIONSADVANCED_H
 #define INSTRUCTIONSADVANCED_H
 
 #include "ast.h"
 #include "llvmlayer.h"
 #include "pass/compilepass.h"
 
 #include <vector>
 
 namespace xreate {
     namespace compilation {
 
 class Advanced {
 public:
     Advanced(compilation::Context ctx);
     llvm::Value* compileArrayIndex(llvm::Value* aggregate, std::vector<llvm::Value *> indexes, std::string ident = "");
     llvm::Value* compileStructIndex(llvm::Value* aggregate, const ExpandedType& t, const std::string& idx);
         /*
         *    - map Computation -> Llvm_Array: Prohibited, we do not know a result size
         *    - map Llvm_Array -> Computation: considered in `compileGetElement`
         *    - map Llvm_Array -> Llvm_Array considered by this method
         */
     llvm::Value* compileMapSolidOutput(const Expression &expr, const std::string hintRetVar = "");
     llvm::Value* compileFold(const Expression& fold, const std::string& ident="");
     llvm::Value* compileFoldInf(const Expression& fold, const std::string& ident="");
+    
+    //DISABLEDFEATURE Context Loop
     llvm::Value* compileLoopContext(const Expression& expression, const std::string& hintRetVar);
     llvm::Value* compileIf(const Expression& exprIf, const std::string& ident);
     llvm::Value* compileSwitch(const Expression& exprSwitch, const std::string& hintRetVar);
     llvm::Value* compileConstantStringAsPChar(const std::string &data, const std::string& hintRetVar);
     llvm::Value* compileListAsSolidArray(const Expression &expr, const std::string&  hintRetVar="");
 
 private:
     compilation::Context context;
     llvm::IntegerType* const tyNum;
 };
 
 }}
 
 #endif /* INSTRUCTIONSADVANCED_H */
 
diff --git a/cpp/src/compilation/containers.cpp b/cpp/src/compilation/containers.cpp
index df7c9e3..f60f5ed 100644
--- a/cpp/src/compilation/containers.cpp
+++ b/cpp/src/compilation/containers.cpp
@@ -1,195 +1,195 @@
 #include "compilation/containers.h"
 
 using namespace std;
 using namespace llvm;
 using namespace xreate;
 using namespace xreate::containers;
 
 Iterator*
 Iterator::create(xreate::compilation::Context context, const xreate::Symbol& var){
 
 const Implementation& data = Query::queryImplementation(var);
 
 switch(data.impl){
     case ON_THE_FLY:
         return new IteratorForward<ON_THE_FLY>(context, var, data.extract<ON_THE_FLY>());
 
     case SOLID:
         return new IteratorForward<SOLID>(context, var, data.extract<SOLID>());
 
     default: assert(true);
 }
 
 assert(false && "Unknown declaration");
 return nullptr;
 }
 
 llvm::Value*
 IteratorForward<ON_THE_FLY>::begin() {
     switch(sourceDecl.op) {
         case xreate::Operator::LIST:
         {
             sourceRawType = llvm::Type::getInt32Ty(llvm::getGlobalContext());
             return llvm::ConstantInt::get(Type::getInt32Ty(llvm::getGlobalContext()), 0);
         };
 
         case xreate::Operator::LIST_RANGE:{
             assert(sourceDecl.operands.size()==2);
 
             llvm::Value* result = sourceUnit->process(sourceDecl.operands.at(0));
             sourceRawType = result->getType();
 
             return result;
         };
 
         default: break;
     }
 
     if (linkedlist){
         llvm::Value* result = sourceUnit->process(sourceDecl);
         sourceRawType = result->getType();
        return result;
     }
 
     assert(false);
 }
 
 llvm::Value*
 IteratorForward<ON_THE_FLY>::end(){
     switch(sourceDecl.op) {
         case xreate::Operator::LIST: {
             size_t idLast = sourceDecl.operands.size() - 1;
             return ConstantInt::get(sourceRawType, idLast);
         }
 
         case xreate::Operator::LIST_RANGE: {
             assert(sourceDecl.operands.size() == 2);
             llvm::Value* valueEndOfRange =  sourceUnit->process(sourceDecl.operands.at(1));
             llvm::Value* valueConstOne = llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), 1);
 
             return llvm->builder.CreateAdd(valueEndOfRange, valueConstOne);
         };
 
     default: break;
     }
 
                 //return null pointer
     if (linkedlist){
             return ConstantPointerNull::getNullValue(sourceRawType);
     }
 
     assert(false && "Unknown declaration");
     return nullptr;
 }
 
 llvm::Value*
 IteratorForward<ON_THE_FLY>::get(Value* index,const std::string& hintRetVar){
-    const Expression& currentDecl = CodeScope::findDeclaration(current);
+    const Expression& currentDecl = CodeScope::getDeclaration(current);
 
     switch (currentDecl.op) {
         case xreate::Operator::LIST:             {
             //TODO re check is it right scope(source) to compile currentDecl. Provide unittests.
-            llvm::Value* currentValue = sourceUnit->compileSymbol(current);
+            llvm::Value* currentValue = sourceUnit->processSymbol(current);
             return xreate::compilation::Advanced(context).compileArrayIndex(currentValue, std::vector<Value *>{index});
         };
 
         case xreate::Operator::LIST_RANGE: {
             return index;
         };
 
         case xreate::Operator::MAP:             {
             assert(currentDecl.getOperands().size()==1);
             assert(currentDecl.bindings.size());
             assert(currentDecl.blocks.size());
 
             CodeScope* scopeLoop = currentDecl.blocks.front();
-            const std::string& varIn = currentDecl.getOperands()[0].getValueString();
             std::string varEl = currentDecl.bindings[0];
 
-            const Symbol& symbIn =  current.scope->findSymbol(varIn);
+            const Symbol& symbIn = Attachments::get<Symbol>(currentDecl.getOperands()[0]);
             auto it = std::unique_ptr<Iterator>(Iterator::create(context, symbIn));
 
             Value* elIn = it->get(index, varEl);
-            compilation::CodeScopeUnit* unitLoop = function->getScopeUnit(scopeLoop);
+            compilation::AbstractCodeScopeUnit* unitLoop = function->getScopeUnit(scopeLoop);
             unitLoop->bindArg(elIn, std::move(varEl));
             return unitLoop->compile();
         }
 
         case xreate::Operator::NONE: {
             //TODO review iterator determination strategy for case of Expression::BINDING
             assert(currentDecl.__state==Expression::IDENT);
-            const Symbol& symbIn =  current.scope->findSymbol(currentDecl.getValueString());
+
+            const Symbol& symbIn =  Attachments::get<Symbol>(currentDecl);
             auto it = std::unique_ptr<Iterator>(Iterator::create(context, symbIn));
             return it->get(index);
         };
 
         default: break;
     }
 
     if (linkedlist){
         return index;
     }
 
     assert(false && "Unknown declaration");
     return nullptr;
 }
 
 llvm::Value*
 IteratorForward<ON_THE_FLY>::advance(Value* index, const std::string& hintRetVar){
     switch(sourceDecl.op)
     {
         case xreate::Operator::LIST:
         case xreate::Operator::LIST_RANGE:
             return llvm->builder.CreateAdd(index, llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), 1), hintRetVar);
 
         default: break;
     }
 
     if (linkedlist){
-        ExpandedType tySource = llvm->ast->expandType(CodeScope::findDeclaration(source).type);
+        ExpandedType tySource = llvm->ast->expandType(CodeScope::getDeclaration(source).type);
         assert(tySource->__operator == TypeOperator::ARRAY && "Linked list implementation has to have ARRAY type");
         assert(tySource->__operands.size());
 
         return xreate::compilation::Advanced(context).compileStructIndex(index, ExpandedType(TypeAnnotation(tySource->__operands.at(0))), linkedlist.fieldPointer);
     }
 
     assert(false && "Unknown declaration");
     return nullptr;
 }
 
 //const ImplementationRec<ON_THE_FLY>& implementation
 
 IteratorForward<SOLID>::IteratorForward(const compilation::Context& ctx,  const xreate::Symbol& symbolContainer, const ImplementationRec<SOLID>& implementation)
-    : Iterator(), llvm(ctx.pass->man->llvm), __length(implementation.size)
+    : Iterator(), __length(implementation.size), llvm(ctx.pass->man->llvm)
 {
-    __container = ctx.function->getScopeUnit(symbolContainer.scope)->compileSymbol(symbolContainer);
+    __container = ctx.function->getScopeUnit(symbolContainer.scope)->processSymbol(symbolContainer);
 }
 
 llvm::Value*
 IteratorForward<SOLID>::begin(){
     //0
     return llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), 0);
 }
 
 llvm::Value*
 IteratorForward<SOLID>::end(){
     //length
     return llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), __length);
 }
 
 llvm::Value*
 IteratorForward<SOLID>::get(llvm::Value* index,const std::string& hintRetVar){
     //GEP[index]]
 
     llvm::Type* tyNum = llvm::Type::getInt32Ty(llvm::getGlobalContext());
     llvm::Value* pResult = llvm->builder.CreateGEP(__container, ArrayRef<Value *>(std::vector<Value*>{ConstantInt::get(tyNum, 0), index}));
     return llvm->builder.CreateLoad(pResult, hintRetVar);
 }
 
 llvm::Value*
 IteratorForward<SOLID>::advance(llvm::Value* index, const std::string& hintRetVar){
     //index + 1
 
     llvm::Type* tyNum = llvm::Type::getInt32Ty(llvm::getGlobalContext());
     return llvm->builder.CreateAdd(index, llvm::ConstantInt::get(tyNum, 1), hintRetVar);
 }
diff --git a/cpp/src/compilation/containers.h b/cpp/src/compilation/containers.h
index 222be75..71815a7 100644
--- a/cpp/src/compilation/containers.h
+++ b/cpp/src/compilation/containers.h
@@ -1,80 +1,80 @@
 #ifndef CODEINSTRUCTIONS_H
 #define CODEINSTRUCTIONS_H
 
 #include "ast.h"
 
 #include "llvmlayer.h"
 #include "pass/compilepass.h"
 #include "compilation/advanced.h"
 
 #include "query/context.h"
 #include "query/containers.h"
 
 namespace xreate {
     namespace containers {
 
 using namespace llvm;
 
 class Iterator{
 public :
     virtual llvm::Value* begin() =0;
     virtual llvm::Value* end() = 0;
     virtual llvm::Value* get(llvm::Value* index,const std::string& hintRetVar="") = 0;
     virtual llvm::Value* advance(llvm::Value* index, const std::string& hintRetVar="")=0;
     virtual ~Iterator(){};
 
     static Iterator* create(xreate::compilation::Context context, const xreate::Symbol& var);
 };
 
 template<ImplementationType I>
 class IteratorForward;
 
 template<>
 class IteratorForward<ON_THE_FLY> : public Iterator {
 private:
     LLVMLayer* llvm;
     const xreate::Symbol current;
     const Symbol source;
     const ImplementationLinkedList linkedlist;
     CodeScope* const sourceScope;
             //TODO initialize and mark as const (three fields)
-    compilation::CodeScopeUnit* sourceUnit;
+    compilation::AbstractCodeScopeUnit* sourceUnit;
     compilation::FunctionUnit* function; //TODO is used somewhere?
     const Expression& sourceDecl;
     compilation::Context context;
     llvm::Type* sourceRawType =nullptr;
 
 public:
     IteratorForward(const compilation::Context& ctx, const xreate::Symbol& s, const ImplementationRec<ON_THE_FLY>& implementation)
     :   llvm(ctx.pass->man->llvm), 
         current(s), 
         source(implementation.source), 
         linkedlist(source), 
         sourceScope(source.scope),
-        sourceUnit(new compilation::CodeScopeUnit(source.scope, ctx.function, ctx.pass)),
-        sourceDecl(CodeScope::findDeclaration(source)),
+        sourceUnit(ctx.function->getScopeUnit(source.scope)),
+        sourceDecl(CodeScope::getDeclaration(source)),
         context(ctx)
     {}
     
     llvm::Value* begin() override;
     llvm::Value* end() override;
     llvm::Value* get(llvm::Value* index,const std::string& hintRetVar="") override;
     llvm::Value* advance(llvm::Value* index, const std::string& hintRetVar="") override;
 };
 
 template<>
 class IteratorForward<SOLID>: public Iterator{
     size_t __length;
     llvm::Value* __container;
     LLVMLayer* llvm;
     
 public:
     IteratorForward(const compilation::Context& ctx, const xreate::Symbol& symbolContainer, const ImplementationRec<SOLID>& implementation);
     llvm::Value* begin() override;
     llvm::Value* end() override;
     llvm::Value* get(llvm::Value* index,const std::string& hintRetVar="") override;
     llvm::Value* advance(llvm::Value* index, const std::string& hintRetVar="") override;
 };
 }}
 
 #endif //CODEINSTRUCTIONS_H
diff --git a/cpp/src/compilation/scopedecorators.h b/cpp/src/compilation/scopedecorators.h
new file mode 100644
index 0000000..612d68a
--- /dev/null
+++ b/cpp/src/compilation/scopedecorators.h
@@ -0,0 +1,123 @@
+/* 
+ * File:   scopedecorators.h
+ * Author: pgess <v.melnychenko@xreate.org>
+ *
+ * Created on February 24, 2017, 11:35 AM
+ */
+
+#ifndef SCOPEDECORATORS_H
+#define SCOPEDECORATORS_H
+
+#include "ast.h"
+#include "compilation/targetinterpretation.h"
+#include "compilation/versions.h"
+#include "compilation/transformations.h"
+
+namespace xreate { 
+    
+class CompilePass;
+
+namespace compilation {
+
+class AbstractCodeScopeUnit;
+class FunctionUnit;
+
+template<class Parent>
+class CachedScopeDecorator: public Parent{
+    typedef CachedScopeDecorator<Parent> SELF;
+
+public:
+    CachedScopeDecorator(CodeScope* codeScope, FunctionUnit* f, CompilePass* compilePass): Parent(codeScope, f, compilePass){}
+
+    void reset(){
+        __rawVars.clear();
+    }
+    
+    void bindArg(llvm::Value* value, std::string&& alias)
+    {
+        //ensure existence of an alias
+        assert(Parent::scope->__identifiers.count(alias));
+
+        //memorize new value for an alias
+        ScopedSymbol id{Parent::scope->__identifiers.at(alias), VERSION_NONE};
+        __rawVars[id] = value;
+    }
+
+    void bindArg(llvm::Value* value, const ScopedSymbol& s) {
+        __rawVars[s] = value;
+    }
+    
+    llvm::Value* compile(const std::string& hintBlockDecl="") override{
+        if (__rawVars.count(ScopedSymbol::RetSymbol)){
+            return __rawVars[ScopedSymbol::RetSymbol];
+        }
+        
+        return Parent::compile(hintBlockDecl);
+    }
+
+    llvm::Value* 
+    processSymbol(const Symbol& s, std::string hintRetVar) override{
+        CodeScope* scope = s.scope;
+        SELF* self = dynamic_cast<SELF*>(Parent::function->getScopeUnit(scope));
+
+        if (self->__rawVars.count(s.identifier)){
+            return self->__rawVars[s.identifier];
+        }
+
+        //Declaration could be overriden
+        Expression declaration = CodeScope::getDeclaration(s);
+        if (!declaration.isDefined()){
+            if (self->__declarationsOverriden.count(s.identifier)){
+                declaration = self->__declarationsOverriden[s.identifier];
+
+            } else {
+                assert(false); //in case of binding there should be raws provided.
+            }
+        }
+
+        return self->__rawVars[s.identifier] = Parent::processSymbol(s, hintRetVar);
+    }
+
+    void 
+    overrideDeclaration(const Symbol binding, Expression&& declaration){
+        SELF* self = dynamic_cast<SELF*>(Parent::function->getScopeUnit(binding.scope));
+
+        self->__declarationsOverriden.emplace(binding.identifier, std::move(declaration));
+    }
+
+private:
+    std::unordered_map<ScopedSymbol, Expression> __declarationsOverriden;
+    std::unordered_map<ScopedSymbol,llvm::Value*> __rawVars;
+
+};
+
+typedef CachedScopeDecorator<
+        compilation::TransformationsScopeDecorator<
+        compilation::InterpretationScopeDecorator<
+        compilation::VersionsScopeDecorator<compilation::BasicCodeScopeUnit>>>>
+
+        DefaultScopeUnit;
+
+} //end of compilation namespace
+
+struct CachedScopeDecoratorTag;
+struct VersionsScopeDecoratorTag;
+
+template<>
+struct DecoratorsDict<CachedScopeDecoratorTag>{
+    typedef compilation::CachedScopeDecorator<
+            compilation::TransformationsScopeDecorator<
+            compilation::InterpretationScopeDecorator<
+            compilation::VersionsScopeDecorator<compilation::BasicCodeScopeUnit>>>> result;
+};
+
+template<>
+struct DecoratorsDict<VersionsScopeDecoratorTag>{
+    typedef compilation::VersionsScopeDecorator<
+            compilation::BasicCodeScopeUnit> result;
+};
+
+} //end of xreate
+
+#endif /* SCOPEDECORATORS_H */
+
diff --git a/cpp/src/compilation/targetinterpretation.cpp b/cpp/src/compilation/targetinterpretation.cpp
index b50bf13..2969498 100644
--- a/cpp/src/compilation/targetinterpretation.cpp
+++ b/cpp/src/compilation/targetinterpretation.cpp
@@ -1,446 +1,432 @@
 /*
  * File:   targetinterpretation.cpp
  * Author: pgess
  *
  * Created on June 29, 2016, 6:45 PM
  */
 
 #include "compilation/targetinterpretation.h"
 #include "pass/interpretationpass.h"
 #include "llvmlayer.h"
+#include "compilation/scopedecorators.h"
+
 #include <boost/scoped_ptr.hpp>
 #include <iostream>
+#include <clang/AST/DeclBase.h>
 
 using namespace std;
 
 namespace xreate{ namespace compilation {
 
     const Expression EXPRESSION_FALSE = Expression(Atom<Number_t>(0));
     const Expression EXPRESSION_TRUE = Expression(Atom<Number_t>(1));
 
 //Expression
 //InterpretationScope::compile(const Expression& expression){}
 
 CodeScope*
 InterpretationScope::processOperatorIf(const Expression& expression){
     const Expression& exprCondition = process(expression.getOperands()[0]);
 
     if (exprCondition == EXPRESSION_TRUE){
         return expression.blocks.front();
     }
 
     return expression.blocks.back();
 }
 
 CodeScope*
 InterpretationScope::processOperatorSwitch(const Expression& expression) {
     const Expression& exprCondition = process(expression.operands[0]);
 
     bool flagHasDefault = expression.operands[1].op == Operator::CASE_DEFAULT;
 
     //TODO check that one and only one case variant is appropriate
     for (size_t size = expression.operands.size(), i= flagHasDefault? 2: 1; i<size; ++i){
         const Expression& exprCase = process(expression.operands[i]);
 
         if (function->getScope(exprCase.blocks.front())->processScope() == exprCondition){
             return exprCase.blocks.back();
         }
     }
 
     if (flagHasDefault){
         const Expression& exprCaseDefault = expression.operands[1];
         return exprCaseDefault.blocks.front();
     }
 
     assert(false && "Switch has no appropriate variant");
     return nullptr;
 }
 
 llvm::Value*
 InterpretationScope::compileHybrid(const InterpretationOperator& op, const Expression& expression, const Context& context){
     switch(op){
         case IF_INTERPRET_CONDITION: {
             CodeScope* scopeResult = processOperatorIf(expression);
 
             llvm::Value* result = context.function->getScopeUnit(scopeResult)->compile();
             return result;
         }
 
         case SWITCH_INTERPRET_CONDITION:{
             CodeScope* scopeResult = processOperatorSwitch(expression);
 
             llvm::Value* result = context.function->getScopeUnit(scopeResult)->compile();
             return result;
         }
 
         case FOLD_INTERPRET_INPUT: {
             //initialization
             const Expression& exprInput = process(expression.getOperands()[0]);
             assert(exprInput.op == Operator::LIST);
 
             CodeScope* scopeBody = expression.blocks.front();
 
             const string& nameEl = expression.bindings[0];
-            const Symbol& symbolEl = scopeBody->findSymbol(nameEl);
+            Symbol symbEl{ScopedSymbol{scopeBody->__identifiers.at(nameEl), VERSION_NONE}, scopeBody};
             const std::string& idAccum = expression.bindings[1];
             llvm::Value* rawAccum = context.scope->process(expression.getOperands()[1]);
-            compilation::CodeScopeUnit* unitBody = context.function->getScopeUnit(scopeBody);
+            auto unitBody = Decorators<CachedScopeDecoratorTag>::getInterface(context.function->getScopeUnit(scopeBody));
             InterpretationScope* intrBody = function->getScope(scopeBody);
             const std::vector<Expression> elementsInput= exprInput.getOperands();
 
             for (size_t i=0; i<elementsInput.size(); ++i){
                 Expression exprElement  = elementsInput[i];
-
                 unitBody->reset();
 
                 intrBody->overrideBinding(exprElement, nameEl);
-                unitBody->overrideDeclaration(symbolEl, move(exprElement));
+                unitBody->overrideDeclaration(symbEl, move(exprElement));
                 unitBody->bindArg(rawAccum, string(idAccum));
 
                 rawAccum = unitBody->compile();
             }
 
             return rawAccum;
         }
 
         case CALL_INTERPRET_PARTIAL: {
             const std::string &calleeName = expression.getValueString();
-            CodeScopeUnit* scopeUnitSelf = context.scope;
+            AbstractCodeScopeUnit* scopeUnitSelf = context.scope;
             ManagedFnPtr callee = this->function->man->ast->findFunction(calleeName);
             const  FunctionInterpretationData& calleeData = FunctionInterpretationHelper::getSignature(callee);
             std::vector<llvm::Value *> argsActual;
             PIFSignature sig;
             sig.declaration = callee;
 
             for(size_t no=0, size = expression.operands.size(); no < size; ++no){
                 const Expression& op =  expression.operands[no];
 
                 if (calleeData.signature.at(no) == INTR_ONLY){
                     sig.bindings.push_back(process(op));
                     continue;
                 }
 
                 argsActual.push_back(scopeUnitSelf->process(op));
             }
 
             TargetInterpretation* man = dynamic_cast<TargetInterpretation*>(this->function->man);
             PIFunction* pifunction =  man->getFunction(move(sig));
 
             llvm::Function* raw = pifunction->compile();
             boost::scoped_ptr<CallStatementRaw> statement(new CallStatementRaw(raw, man->pass->man->llvm));
             return (*statement)(move(argsActual));
         }
 
         default: break;
     }
 
     assert(false&& "Unknown hybrid operator");
     return nullptr;
 }
 
 llvm::Value*
 InterpretationScope::compile(const Expression& expression, const Context& context){
-    const InterpretationData& data = Attachments::get<Expression, InterpretationData>(expression);
+    const InterpretationData& data = Attachments::get<InterpretationData>(expression);
 
     if (data.op != InterpretationOperator::NONE){
         return compileHybrid(data.op, expression, context);
     }
 
     Expression result = process(expression);
-    return context.scope->processLowlevel(result);
+    return context.scope->process(result);
 }
 
 Expression
 InterpretationScope::process(const Expression& expression){
     switch (expression.__state){
-        case Expression::VARIANT:
         case Expression::INVALID:
             assert(false);
 
+        case Expression::VARIANT:
         case Expression::NUMBER:
         case Expression::STRING:
             return expression;
 
         case Expression::IDENT:{
-            const std::string &ident = expression.getValueString();
-
-            Symbol s = scope->findSymbol(ident);
+            Symbol s = Attachments::get<Symbol>(expression);
             return Parent::processSymbol(s);
         }
 
         case Expression::COMPOUND:
             break;
 
         default: assert(false);
     }
 
     switch (expression.op) {
         case Operator::EQU: {
             const Expression& left = process(expression.operands[0]);
             const Expression& right = process(expression.operands[1]);
 
             if (left == right) return EXPRESSION_TRUE;
             return EXPRESSION_FALSE;
         }
 
         case Operator::NE: {
             const Expression& left = process(expression.operands[0]);
             const Expression& right = process(expression.operands[1]);
 
             if (left == right) return EXPRESSION_FALSE;
             return EXPRESSION_TRUE;
         }
 
         case Operator::LOGIC_AND: {
             assert(expression.operands.size() == 1);
             return process (expression.operands[0]);
         }
 
 
 //        case Operator::LOGIC_OR:
         case Operator::CALL: {
             const std::string &fnName = expression.getValueString();
             ManagedFnPtr fnAst = this->function->man->ast->findFunction(fnName);
             InterpretationFunction* fnUnit = this->function->man->getFunction(fnAst);
 
             vector<Expression> args;
             args.reserve(expression.getOperands().size());
 
             for(size_t i=0, size = expression.getOperands().size(); i<size; ++i) {
                 args.push_back(process(expression.getOperands()[i]));
             }
 
             return fnUnit->process(args);
         }
 
         case Operator::IF:{
             CodeScope* scopeResult = processOperatorIf(expression);
             return function->getScope(scopeResult)->processScope();
         }
 
         case Operator::SWITCH: {
             CodeScope* scopeResult = processOperatorSwitch(expression);
             return function->getScope(scopeResult)->processScope();
         }
 
         case Operator::INDEX: {
-            const Expression& exprKey = process(expression.operands[0]);
-            const Expression& exprData = processSymbol(scope->findSymbol(expression.getValueString()));
-
+            const Expression& exprKey = process(expression.operands[1]);
+            const Expression& exprData = process(expression.operands[0]);
 
             if (exprKey.__state == Expression::STRING){
                 const string& key = exprKey.getValueString();
                 assert(exprData.__indexBindings.count(key));
 
                 return exprData.operands[exprData.__indexBindings.at(key)];
             }
 
             if (exprKey.__state == Expression::NUMBER){
                 int key = exprKey.getValueDouble();
                 return exprData.operands[key];
             }
 
             assert(false);
         }
 
         case Operator::FOLD: {
             const Expression& exprInput = process(expression.getOperands()[0]);
             const Expression& exprInit = process(expression.getOperands()[1]);
 
             const std::string& argEl = expression.bindings[0];
             const std::string& argAccum = expression.bindings[1];
 
             InterpretationScope* body = function->getScope(expression.blocks.front());
 
             Expression accum = exprInit;
             for(size_t size=exprInput.getOperands().size(), i=0; i<size; ++i){
                 body->overrideBinding(exprInput.getOperands()[i], argEl);
                 body->overrideBinding(accum, argAccum);
 
                 accum = body->processScope();
             }
 
             return accum;
         }
 
 //        case Operator::MAP: {
 //            break;
 //        }
 
         default: break;
     }
 
     return expression;
 }
 
 InterpretationFunction*
 TargetInterpretation::getFunction(FunctionUnit* unit){
     if (__dictFunctionsByUnit.count(unit)) {
         return __dictFunctionsByUnit.at(unit);
     }
 
     InterpretationFunction* f = new InterpretationFunction(unit->function, this);
     __dictFunctionsByUnit.emplace(unit, f);
     assert(__functions.emplace(unit->function.id(), f).second);
 
     return f;
 }
 
 PIFunction*
 TargetInterpretation::getFunction(PIFSignature&& sig){
 
     auto f = __pifunctions.find(sig);
     if (f != __pifunctions.end()){
         return f->second;
     }
 
     PIFunction* result  = new PIFunction(PIFSignature(sig), __pifunctions.size(), this);
     __pifunctions.emplace(move(sig), result);
     assert(__dictFunctionsByUnit.emplace(result->functionUnit, result).second);
 
     return result;
 }
 
 InterpretationScope*
 TargetInterpretation::transformContext(const Context& c){
     return this->getFunction(c.function)->getScope(c.scope->scope);
 }
 
-llvm::Value*
-TargetInterpretation::transform(const Expression& expression, llvm::Value* raw, const Context& ctx){
-    return raw;
-}
-
-Expression
-TargetInterpretation::transform(const Expression& expression, const Context& ctx){
-    return transformContext(ctx)->process(expression);
-}
-
 llvm::Value*
 TargetInterpretation::compile(const Expression& expression, const Context& ctx){
     return transformContext(ctx)->compile(expression, ctx);
 }
 
-bool
-TargetInterpretation::isAcceptable(const Expression& expression){
-    const InterpretationData& data = Attachments::get<Expression, InterpretationData>(expression, {ANY, NONE});
-
-    return (data.resolution == INTR_ONLY || data.op != InterpretationOperator::NONE);
-}
-
 InterpretationFunction::InterpretationFunction(const ManagedFnPtr& function, Target<TargetInterpretation>* target)
     : Function<TargetInterpretation>(function, target)
 {}
 
 Expression
 InterpretationFunction::process(const std::vector<Expression>& args){
     InterpretationScope* body = getScope(__function->__entry);
 
     for(size_t i=0, size = args.size(); i<size; ++i) {
         body->overrideBinding(args.at(i), string(body->scope->__bindings.at(i)));
     }
 
     return body->processScope();
 }
 
 //                  Partial function interpretation
 
 typedef BasicFunctionDecorator PIFunctionUnitParent;
 class PIFunctionUnit: public PIFunctionUnitParent{
 public:
 
     PIFunctionUnit(ManagedFnPtr f, std::set<size_t>&& arguments, size_t id, CompilePass* p)
         : PIFunctionUnitParent(f,  p), argumentsActual(move(arguments)), __id(id)
     {}
 
 protected:
     std::vector<llvm::Type*> prepareArguments(){
         LLVMLayer* llvm = PIFunctionUnitParent::pass->man->llvm;
         AST* ast = PIFunctionUnitParent::pass->man->root;
         CodeScope* entry = PIFunctionUnitParent::function->__entry;
         std::vector<llvm::Type*> signature;
 
         for(size_t no: argumentsActual){
-            Symbol arg = entry->findSymbol(entry->__bindings[no]);
+            VNameId argId = entry->__identifiers.at(entry->__bindings.at(no));
+            ScopedSymbol arg{argId, VERSION_NONE};
 
-            signature.push_back(llvm->toLLVMType(ast->expandType(entry->__declarations[arg.identifier].type)));
+            signature.push_back(llvm->toLLVMType(ast->expandType(entry->__declarations.at(arg).type)));
         }
 
         return signature;
     }
 
     llvm::Function::arg_iterator prepareBindings(){
         CodeScope* entry = PIFunctionUnitParent::function->__entry;
-        CodeScopeUnit* entryCompilation = PIFunctionUnitParent::getScopeUnit(entry);
+        AbstractCodeScopeUnit* entryCompilation = PIFunctionUnitParent::getScopeUnit(entry);
         llvm::Function::arg_iterator fargsI = PIFunctionUnitParent::raw->arg_begin();
 
         for(size_t no: argumentsActual){
-            Symbol arg = entry->findSymbol(entry->__bindings[no]);
+            ScopedSymbol arg{entry->__identifiers.at(entry->__bindings.at(no)), VERSION_NONE};
 
-            entryCompilation->__rawVars[arg.identifier] = &*fargsI;
-            fargsI->setName(entry->__bindings[no]);
+            entryCompilation->bindArg(&*fargsI, arg);
+            fargsI->setName(entry->__bindings.at(no));
             ++fargsI;
         }
 
         return fargsI;
     }
 
     virtual std::string prepareName(){
         return PIFunctionUnitParent::prepareName() + "_" + std::to_string(__id);
     }
 
 private:
     std::set<size_t> argumentsActual;
     size_t __id;
 };
 
 PIFunction::PIFunction(PIFSignature&& sig, size_t id, TargetInterpretation* target)
     : InterpretationFunction(sig.declaration, target), signatureInstance(move(sig))
 {
     const FunctionInterpretationData&  functionData = FunctionInterpretationHelper::getSignature(signatureInstance.declaration);
 
     std::set<size_t> argumentsActual;
     for (size_t no=0, size=functionData.signature.size(); no < size; ++no){
         if (functionData.signature.at(no) != INTR_ONLY){
             argumentsActual.insert(no);
         }
     }
 
     functionUnit = new PIFunctionUnit(signatureInstance.declaration, move(argumentsActual), id, target->pass);
     CodeScope* entry = signatureInstance.declaration->__entry;
-    CodeScopeUnit* entryUnit = functionUnit->getEntry();
+    auto entryUnit = Decorators<CachedScopeDecoratorTag>::getInterface<>(functionUnit->getEntry());
     InterpretationScope* entryIntrp = InterpretationFunction::getScope(entry);
 
     for(size_t no=0, sigNo=0, size = entry->__bindings.size(); no < size; ++no){
         if (functionData.signature.at(no) == INTR_ONLY){
             entryIntrp->overrideBinding(signatureInstance.bindings[sigNo], entry->__bindings[no]);
-            entryUnit->overrideDeclaration(entry->findSymbol(entry->__bindings[no]), Expression(signatureInstance.bindings[sigNo]));
+
+            VNameId argId = entry->__identifiers.at(entry->__bindings[no]);
+            Symbol argSymbol{ScopedSymbol{argId, VERSION_NONE}, entry};
+            entryUnit->overrideDeclaration(argSymbol, Expression(signatureInstance.bindings[sigNo]));
             ++sigNo;
         }
     }
 }
 
 llvm::Function*
 PIFunction::compile(){
     llvm::Function* raw = functionUnit->compile();
 
     return raw;
 }
 
 bool operator<(const PIFSignature& lhs, const PIFSignature& rhs){
     if (lhs.declaration.id() != rhs.declaration.id()) {
         return lhs.declaration.id() < rhs.declaration.id();
     }
 
     return lhs.bindings < rhs.bindings;
 }
 
 bool operator<(const PIFSignature& lhs, PIFunction* const rhs){
     return lhs < rhs->signatureInstance;
 }
 
 bool operator<(PIFunction* const lhs, const PIFSignature& rhs){
     return lhs->signatureInstance < rhs;
 }
 
 }}
\ No newline at end of file
diff --git a/cpp/src/compilation/targetinterpretation.h b/cpp/src/compilation/targetinterpretation.h
index 0ef32e7..7b7acdd 100644
--- a/cpp/src/compilation/targetinterpretation.h
+++ b/cpp/src/compilation/targetinterpretation.h
@@ -1,116 +1,134 @@
 /*
  * To change this license header, choose License Headers in Project Properties.
  * To change this template file, choose Tools | Templates
  * and open the template in the editor.
  */
 
 /* 
  * File:   targetstatic.h
  * Author: pgess
  *
  * Created on July 2, 2016, 1:25 PM
  */
 
 #ifndef TARGETSTATIC_H
 #define TARGETSTATIC_H
 
 #include "ast.h"
+#include "pass/compilepass.h"
 #include "compilation/targets.h"
-#include "transformations.h"
 #include "pass/interpretationpass.h"
 
 namespace xreate{ namespace compilation {
 
 class TargetInterpretation;
 class InterpretationScope;
 class InterpretationFunction;
 
     template <>
     struct TargetInfo<TargetInterpretation> {
         typedef Expression Result;
         typedef InterpretationScope Scope;
         typedef InterpretationFunction Function;
     };
     
-    template<> 
-    struct TransformerInfo<TargetInterpretation> {
-        static const int id = 1;
-    };
-
 class InterpretationScope: public  Scope<TargetInterpretation>{
     typedef Scope<TargetInterpretation> Parent;
     
 public:
     InterpretationScope(CodeScope* scope, Function<TargetInterpretation>* f): Parent(scope, f) {}
     Expression process(const Expression& expression) override;
     
     llvm::Value* compile(const Expression& expression, const Context& context);
     
 private:
     llvm::Value* compileHybrid(const InterpretationOperator& op, const Expression& expression, const Context& context);
     //llvm::Value* compilePartialFnCall(const Expression& expression, const Context& context);
     
     CodeScope* processOperatorIf(const Expression& expression);
     CodeScope* processOperatorSwitch(const Expression& expression);
 };
 
 class InterpretationFunction: public Function<TargetInterpretation>{
 public:
     InterpretationFunction(const ManagedFnPtr& function, Target<TargetInterpretation>* target);
     Expression process(const std::vector<Expression>& args);
 };
 
 /*
  * Partially interpreted function signature
  */
 struct PIFSignature{
     ManagedFnPtr declaration;
     std::vector<Expression> bindings;
 };
 
 class PIFunctionUnit;
 
 class PIFunction: public InterpretationFunction{
 public:
     PIFunctionUnit* functionUnit;
     PIFSignature signatureInstance;
     
     PIFunction(PIFSignature&& sig, size_t id, TargetInterpretation* target);
     llvm::Function* compile();
 };
 
 bool operator<(const PIFSignature& lhs, PIFunction* const rhs);
 bool operator<(PIFunction* const lhs, const PIFSignature& rhs);
 
-class TargetInterpretation: public Target<TargetInterpretation>, public Transformer{
+class TargetInterpretation: public Target<TargetInterpretation>{
 public:    
     TargetInterpretation(AST* root, CompilePass* passCompilation): Target<TargetInterpretation>(root), pass(passCompilation){}
 
-        //transformer:
-public:
-    virtual llvm::Value* transform(const Expression& expression, llvm::Value* raw, const Context& ctx) override;
-    virtual Expression transform(const Expression& expression, const Context& ctx) override;
-    virtual bool isAcceptable(const Expression& expression) override;
-    
         //target:
 public:
    InterpretationFunction* getFunction(FunctionUnit* unit);
    PIFunction* getFunction(PIFSignature&& sig);
    
 private:
    std::map<PIFSignature, PIFunction*> __pifunctions;
    std::map<FunctionUnit*, InterpretationFunction*> __dictFunctionsByUnit;
 
         //self:
 public:
     CompilePass* pass;
     llvm::Value* compile(const Expression& expression, const Context& ctx);
 private:
     InterpretationScope* transformContext(const Context& c);
 };
 
+template<class Parent>
+class InterpretationScopeDecorator: public Parent{
+public:
+    InterpretationScopeDecorator(CodeScope* codeScope, FunctionUnit* f, CompilePass* compilePass): Parent(codeScope, f, compilePass){}
+    
+    virtual llvm::Value* process(const Expression& expr, const std::string& hintVarDecl){
+        const InterpretationData& data = Attachments::get<InterpretationData>(expr, {ANY, NONE});
+        bool flagInterpretationEligible = (data.resolution == INTR_ONLY || data.op != InterpretationOperator::NONE);
+
+        if (flagInterpretationEligible){
+            Context ctx{this, this->function, this->pass};
+            return Parent::pass->targetInterpretation->compile(expr, ctx);
+        }
+        
+        return Parent::process(expr, hintVarDecl);
+    }
+};
+
+
+
+} //end of compilation
+
+struct InterpretationScopeDecoratorTag;
+
+} //end of xreate
 
+#endif /* TARGETSTATIC_H */
 
-}}
 
-#endif /* TARGETSTATIC_H */
\ No newline at end of file
+//transformers: 
+//    template<> 
+//    struct TransformerInfo<TargetInterpretation> {
+//        static const int id = 1;
+//    };
\ No newline at end of file
diff --git a/cpp/src/compilation/targets.h b/cpp/src/compilation/targets.h
index f6b47bb..a871d44 100644
--- a/cpp/src/compilation/targets.h
+++ b/cpp/src/compilation/targets.h
@@ -1,161 +1,161 @@
 /* 
  * File:   targetabstract.h
  * Author: pgess
  *
  * Created on July 2, 2016, 1:25 PM
  */
 
 #ifndef TARGETABSTRACT_H
 #define TARGETABSTRACT_H
 #include "ast.h"
 
 #include <boost/optional.hpp>
 #include <map>
 
 namespace xreate{ namespace compilation {
     
 template <typename ConcreteTarget> 
 struct TargetInfo{
     //typedef Result 
     //typedef Function
     //typedef Scope 
 };
     
 template<typename ConcreteTarget>
 class Function;
 
 template<typename ConcreteTarget>
 class Target;
 
 template<typename ConcreteTarget>
 class Scope{
 public:
     CodeScope* scope;
     
     typename TargetInfo<ConcreteTarget>::Result
     processSymbol(const Symbol& s){
         CodeScope* scope = s.scope;
         typename TargetInfo<ConcreteTarget>::Scope* self = function->getScope(scope);
 
         if (self->__bindings.count(s.identifier))     {
             return self->__bindings[s.identifier];
         }
 
-        const Expression& declaration = CodeScope::findDeclaration(s);
+        const Expression& declaration = CodeScope::getDeclaration(s);
         if (!declaration.isDefined()){
             assert(false); //for bindings there should be result already
         }
         
         return self->__bindings[s.identifier] = self->process(declaration);
     }
     
     typename TargetInfo<ConcreteTarget>::Result
     processScope() {
         if (raw) return *raw;
 
         raw = process(scope->getBody());
         return *raw;
     }
     
 //    typename TargetInfo<ConcreteTarget>::Result
 //    processFunction(typename TargetInfo<ConcreteTarget>::Function* fnRemote, const std::vector<typename TargetInfo<ConcreteTarget>::Result>& args){
 //        Scope<ConcreteTarget> scopeRemote = fnRemote->getScope(fnRemote->__function->__entry);
 //        
 //        if (scopeRemote->raw){
 //            return scopeRemote->raw;
 //        }
 //        
 //        return fnRemote->process(args);
 //    }
     
     virtual typename TargetInfo<ConcreteTarget>::Result
     process(const Expression& expression)=0;    
     
     Scope(CodeScope* codeScope, Function<ConcreteTarget>* f)
             : scope(codeScope), function(f)  {}
     
     virtual ~Scope(){}
 
     void 
     overrideBinding(typename TargetInfo<ConcreteTarget>::Result arg, const std::string& name){
         assert(scope->__identifiers.count(name));
         
-        VID id = scope->__identifiers.at(name);
+        ScopedSymbol id{scope->__identifiers.at(name), VERSION_NONE};
         __bindings[id] = arg;
         
         //reset the result if any:
         raw.reset();
     }
     
 protected:
     Function<ConcreteTarget>* function=0;
-    std::map<VID, typename TargetInfo<ConcreteTarget>::Result> __bindings;
+    std::map<ScopedSymbol, typename TargetInfo<ConcreteTarget>::Result> __bindings;
     typename boost::optional<typename TargetInfo<ConcreteTarget>::Result> raw;
     
     //ResultType findFunction(const std::string& callee);
 };
 
 template<typename ConcreteTarget>
 class Function{
     typedef typename TargetInfo<ConcreteTarget>::Result Result;
     
 public:
     Function(const ManagedFnPtr& function, Target<ConcreteTarget>* target)
         : man(target), __function(function)  {}
         
 	virtual ~Function(){};
         
     typename TargetInfo<ConcreteTarget>::Scope*
     getScope(CodeScope* scope){
         if (!__scopes.count(scope)){
             typename TargetInfo<ConcreteTarget>::Scope* unit = new typename TargetInfo<ConcreteTarget>::Scope(scope, this);
             __scopes.emplace(scope, std::unique_ptr<typename TargetInfo<ConcreteTarget>::Scope>(unit));
         }
 
         return __scopes.at(scope).get();
     }
     
     virtual Result
     process(const std::vector<Result>& args)=0;
     
     Target<ConcreteTarget>* man=0;
     ManagedFnPtr __function;
 
 protected:
     std::map<CodeScope*, std::unique_ptr<typename TargetInfo<ConcreteTarget>::Scope>> __scopes;
 };
 
 template<typename ConcreteTarget>
 class Target {
     typedef typename TargetInfo<ConcreteTarget>::Function ConcreteFunction;
     
     public:
         Target(AST* root): ast(root){}
         
         ConcreteFunction*
         getFunction(const ManagedFnPtr& function){
             unsigned int id = function.id();
 
             if (!__functions.count(id)){
                 ConcreteFunction* unit = new ConcreteFunction(function, this);
                 __functions.emplace(id, unit);
                 return unit;
             }
 
             return __functions.at(id);
         }
         
         AST* ast;
         virtual ~Target(){
             for (const auto& entry: __functions){
                 delete entry.second;
             }
         }
         
     protected:
         std::map<unsigned int, ConcreteFunction*> __functions;
 };
 
 }}
 
 #endif /* TARGETABSTRACT_H */
\ No newline at end of file
diff --git a/cpp/src/compilation/transformations.cpp b/cpp/src/compilation/transformations.cpp
index d77ca83..1588af8 100644
--- a/cpp/src/compilation/transformations.cpp
+++ b/cpp/src/compilation/transformations.cpp
@@ -1,143 +1,29 @@
-/* 
- * File:   Transformations.cpp
- * Author: pgess
- * 
- * Created on June 18, 2016, 6:23 PM
+/*
+ * transformation.cpp
+ *
+ * Author: pgess <v.melnychenko@xreate.org>
+ * Created on March 27, 2017, 4:04 PM
  */
 
-#include "compilation/transformations.h"
-#include "pass/compilepass.h"
-#include "llvmlayer.h"
-#include <llvm/IR/Value.h>
+#include "transformations.h"
 
-using namespace llvm;
-
-namespace xreate { namespace compilation {
-
-Transformations::Transformations(CompilePass* passCompilation): pass(passCompilation) {
-}
-
-void
-Transformations::subscribe(const std::string& annotation, int handler){
-    __subscriptions.emplace(annotation, handler);
-}
-
-bool 
-Transformations::isAcceptable(const Expression& expression){
-    //check subscription based on expression attachments
-    if (Attachments::get<Expression, Transformations>(expression, {false, 0}).flagSubscribed){
-        return true;
-    }
-    
-    //subscription based on expression annotations;
-    if (expression.tags.size() == 0) return false;
-    
-    for (auto tag: expression.tags) {
-        if (__subscriptions.count(tag.first)){
-            return true;
-        }
-    }
-    
-    return false;
-}
-
-Expression
-Transformations::transform(const Expression& expression, const Context& ctx){
-    Expression result = expression;
-    
-    for (auto handler: getAppropriateTransformers(expression)){
-        result = handler->transform(result, ctx);
-    }
-    
-    return result;
-}
-
-llvm::Value* 
-Transformations::transform(const Expression& expression, llvm::Value* raw, const Context& ctx){
-    for (auto handler: getAppropriateTransformers(expression)){
-        raw = handler->transform(expression, raw, ctx);
-    }
-    
-    return raw;
-}
+namespace xreate {    namespace compilation {
 
 std::list<Transformer*>
-Transformations::getAppropriateTransformers(const Expression& expression){
-
+TransformationsManager::getRelevantTransformers(const Expression& expression){
     std::list<Transformer*> result;
-    
+
     for (auto tag: expression.tags) {
         if (__subscriptions.count(tag.first)){
             auto handlers = __subscriptions.equal_range(tag.first);
-            
-            for (auto handlerIt=handlers.first; handlerIt!= handlers.second; ++handlerIt){
-                Transformer* handler  = __transformers[handlerIt->second];
-                
-                if (handler->isAcceptable(expression)){
-                    result.push_back(handler);
-                }
+
+            for (auto handler = handlers.first; handler != handlers.second; ++handler){
+                result.push_back(__transformers[handler->second]);
             }
         }
     }
-    
-    auto subscriberInternal = Attachments::get<Expression, Transformations>(expression, {false, 0});
-    if (subscriberInternal.flagSubscribed){
-        result.push_back(__transformers[subscriberInternal.subscriberId]);
-    }
-    
-    return result;
-}
 
-TransformerSaturation::TransformerSaturation(Transformations* man)
-    : __man(man) {
-    
-    man->subscribe("break", TransformerInfo<TransformerSaturation>::id);
-}
-
-bool 
-TransformerSaturation::isAcceptable(const Expression& expression){
-    return true;
-}
-
-bool
-TransformerSaturation::exists() const{
-    return __block != nullptr;
-}
-
-llvm::Value*
-TransformerSaturation::transform(const Expression& expression, llvm::Value* raw, const Context& ctx){
-    __block = __man->pass->man->llvm->builder.GetInsertBlock();
-    
-    return raw;
-}
-
-llvm::BasicBlock* 
-TransformerSaturation::getBlock() const{
-    return __block;
-}
-
-void
-TransformerSaturation::inject(llvm::BasicBlock* blockAllocation, llvm::BasicBlock* blockExit, compilation::Context context){
-    llvm::Type* tyInt1 = llvm::Type::getInt1Ty(llvm::getGlobalContext());
-    llvm::Value* valueConstOne = llvm::ConstantInt::get(tyInt1, 1);
-    llvm::Value* valueConstFalse = llvm::ConstantInt::get(tyInt1, 0);
-
-        //allocation of saturation flag
-    IRBuilder<> builderAlloca(blockAllocation, blockAllocation->getFirstInsertionPt());
-    llvm::Value* flagSaturation =  builderAlloca.CreateAlloca(tyInt1, valueConstOne, "flagSaturation");
-    builderAlloca.CreateStore(valueConstFalse, flagSaturation, true);
-
-    //set up saturation flag
-    llvm::BasicBlock* blockSaturation = __block;
-    IRBuilder<> builderSaturation(blockSaturation, blockSaturation->getFirstInsertionPt());
-    builderSaturation.CreateStore(valueConstOne, flagSaturation, true);
-
-    //check saturation flag:
-    //TODO remove blockContinue, receive from caller block to continue.
-    llvm::BasicBlock *blockContinue = llvm::BasicBlock::Create(llvm::getGlobalContext(), "continue", context.function->raw);
-    context.pass->man->llvm->builder.CreateCondBr(context.pass->man->llvm->builder.CreateLoad(flagSaturation), blockExit, blockContinue);
-    
-    context.pass->man->llvm->builder.SetInsertPoint(blockContinue);
+    return result;
 }
 
-}}
\ No newline at end of file
+} } //namespace xreate
\ No newline at end of file
diff --git a/cpp/src/compilation/transformations.h b/cpp/src/compilation/transformations.h
index daec0bf..4350147 100644
--- a/cpp/src/compilation/transformations.h
+++ b/cpp/src/compilation/transformations.h
@@ -1,119 +1,111 @@
 /* 
- * File:   Transformations.h
- * Author: pgess
+ * File:   transformations.h
+ * Author: pgess <v.melnychenko@xreate.org>
  *
- * Created on June 18, 2016, 6:23 PM
+ * Created on March 25, 2017, 9:04 PM
  */
 
 #ifndef TRANSFORMATIONS_H
 #define TRANSFORMATIONS_H
 
-#include "ast.h"
 #include "pass/compilepass.h"
-#include "attachments.h"
-
-namespace llvm {
-    class BasicBlock;
-}
 
 namespace xreate {    namespace compilation {
-    
-    class Transformer{
-    public:
-        virtual llvm::Value* transform(const Expression& expression, llvm::Value* raw, const Context& ctx)=0;
-        virtual Expression transform(const Expression& expression, const Context& ctx){return expression;}
-        virtual bool isAcceptable(const Expression& expression)=0;
-        
-        virtual ~Transformer(){};
-    };
-    
-    class TransformerSaturation: public Transformer{
-    public:    
-        llvm::Value* transform(const Expression& expression, llvm::Value* raw, const Context& ctx);
-        bool isAcceptable(const Expression& expression);
 
-        TransformerSaturation(Transformations*);
-        llvm::BasicBlock* getBlock() const;
-        bool exists() const;
-        void inject(llvm::BasicBlock* blockAllocation, llvm::BasicBlock* blockExit, compilation::Context context);
-        
-    private:
-        llvm::BasicBlock* __block = nullptr;
-        Transformations* __man;
-    };
+template <class TransformerType> 
+struct TransformerInfo {
+    //static const unsigned int id = 1; (current vacant id)
+};
     
-    template <class TransformerType> 
-    struct TransformerInfo {
-        //static const int id = 1; (next vacant id)
-    };
+class Transformer{
+public:
+    virtual llvm::Value* transform(const Expression& expression, llvm::Value* raw, const Context& ctx)=0;
+    virtual ~Transformer(){};
+};
+
+class TransformationsManager {
+public:
+    std::list<Transformer*> getRelevantTransformers(const Expression& expression);
     
-    template <> 
-    struct TransformerInfo<TransformerSaturation> {
-        static const int id = 0;
-    };
     
-    class Transformations;
+    template<class TransformerType>
+    void registerTransformer(const std::string& annotation, TransformerType* t){
+        const int id = TransformerInfo<TransformerType>::id;
+
+        assert(!__transformers.count(id));
+        __transformers[id] = t;
+        __subscriptions.emplace(annotation, id);
+    }
     
-    struct SubscriberInfo{
-        bool flagSubscribed;
-        int subscriberId;
-    };
+    template<class TransformerType>
+    void unregisterTransformer(const std::string& annotation, TransformerType* t){
+        const unsigned int id = TransformerInfo<TransformerType>::id;
+
+        auto range = __subscriptions.equal_range(annotation);
+        const auto entry = make_pair(annotation, id);
+        __subscriptions.erase(std::find_if(range.first, range.second, [id](const auto& el){return el.second == id;}));
+        __transformers.erase(id);
+    }
     
-    class Transformations: public Transformer {
-    public:
-        xreate::CompilePass* pass;
-        
-        bool isAcceptable(const Expression& expression);
-        llvm::Value* transform(const Expression& expression, llvm::Value* raw, const Context& ctx) override;
-        Expression transform(const Expression& expression, const Context& ctx) override;
+    template<class TransformerType>
+    TransformerType* update(TransformerType* newInstance){
+        const int id = TransformerInfo<TransformerType>::id;
         
-        Transformations(CompilePass*);
-        void subscribe(const std::string& annotation, int handler);
+        Transformer* oldInstance = __transformers[id];
+        __transformers[id] = newInstance;
         
-        template<class TransformerType>
-        void registerTransformer(TransformerType* t){
-            const int id = TransformerInfo<TransformerType>::id;
-            
-            __transformers[id] = t;
-        }
+        return static_cast<TransformerType*>(oldInstance);
+    }
+    
+    template<class TransformerType>
+    bool exists(){
+        const int id = TransformerInfo<TransformerType>::id;
         
-        template<class Holder, class TransformerType>
-        static void  subscribe(const Holder& holder){
-            //assert(! Attachments::exists<Holder, Transformations>());
-            
-            const int id = TransformerInfo<TransformerType>::id;
-            
-            if (Attachments::exists<Holder, Transformations>(holder)){
-                const int idOld = Attachments::get<Holder, Transformations>(holder).subscriberId;
-                assert(idOld == id);
-                return;
-            }
+        return __transformers.count(id);
+    }
             
-            Attachments::put<Holder, Transformations>(holder, {true, id});
-        }
+    template <class TransformerType>
+    TransformerType* get(){
+        const int id = TransformerInfo<TransformerType>::id;
+        return static_cast<TransformerType*>(__transformers.at(id));
+    }    
+    
+private:
+    std::map<unsigned int, Transformer*> __transformers;
+    std::multimap<std::string, unsigned int> __subscriptions;
+};
 
-        template <class TransformerType>
-        TransformerType* get(){
-            const int id = TransformerInfo<TransformerType>::id;
-            return static_cast<TransformerType*>(__transformers.at(id));
-        }
+template <class Parent>
+class TransformationsScopeDecorator: public Transformer, public Parent {
+                // SCOPE DECORATOR PART
+public:    
+    TransformationsScopeDecorator(CodeScope* codeScope, FunctionUnit* f, CompilePass* compilePass)
+        : Parent(codeScope, f, compilePass){}
+    
+    virtual llvm::Value* 
+    process(const Expression& expr, const std::string& hintVarDecl=""){
+        llvm::Value* result = Parent::process(expr, hintVarDecl);
 
-    private:
-        std::map<int, Transformer*> __transformers;
-        std::multimap<std::string, int> __subscriptions;
+        return transform(expr, result, Context{this, Parent::function, Parent::pass});
+    }
+  
+                // TRANSFORMER PART
+public:
+    virtual llvm::Value* 
+    transform(const Expression& expression, llvm::Value* raw, const Context& ctx) {
+        llvm::Value* result = raw;
+        TransformationsManager* man = Parent::pass->managerTransformations;
         
-        std::list<Transformer*> getAppropriateTransformers(const Expression& expression);
-    };
-}}
-
-namespace xreate {
-    template<>
-    struct AttachmentsDict<compilation::Transformations>
-    {
-        typedef xreate::compilation::SubscriberInfo Data;
-        static const unsigned int key = 4;
-    };
-}
+        if (expression.tags.size())
+        for (Transformer* handler: man->getRelevantTransformers(expression)){
+            result = handler->transform(expression, result, ctx);
+        }
+        
+        return result;
+    }
+};
     
+} } 
+
 #endif /* TRANSFORMATIONS_H */
 
diff --git a/cpp/src/compilation/transformersaturation.cpp b/cpp/src/compilation/transformersaturation.cpp
new file mode 100644
index 0000000..4ea90d0
--- /dev/null
+++ b/cpp/src/compilation/transformersaturation.cpp
@@ -0,0 +1,77 @@
+/*
+ * transformersaturation.cpp
+ *
+ * Author: pgess <v.melnychenko@xreate.org>
+ * Created on March 25, 2017, 10:06 PM
+ */
+
+#include "transformersaturation.h"
+#include "llvmlayer.h"
+
+using namespace llvm;
+
+namespace xreate {    namespace compilation {
+
+TransformerSaturation::TransformerSaturation(llvm::BasicBlock* allocationBlock, TransformationsManager* manager)
+    :  man(manager), blockAllocation(allocationBlock){
+
+    llvm::Type* tyInt1 = llvm::Type::getInt1Ty(llvm::getGlobalContext());
+
+    constTrue = llvm::ConstantInt::get(tyInt1, 1);
+    constFalse = llvm::ConstantInt::get(tyInt1, 0);
+
+    if (man->exists<TransformerSaturation>()){
+        oldInstance = man->update(this);
+
+    } else {
+        man->registerTransformer("break", this);
+    }
+}
+
+TransformerSaturation::~TransformerSaturation(){
+    if (oldInstance) {
+        man->update(oldInstance);
+
+    } else {
+        man->unregisterTransformer("break", this);
+    }
+}
+
+llvm::Value*
+TransformerSaturation::transform(const Expression& expression, llvm::Value* raw, const Context& ctx){
+    processBreak(ctx);
+
+    return raw;
+}
+
+
+void
+TransformerSaturation::processBreak(const Context& ctx){
+    allocateFlag(ctx);
+
+    //show the saturation flag
+    llvm::IRBuilder<>& builder = ctx.pass->man->llvm->builder;
+    builder.CreateStore(constTrue, flagSaturation, true);
+}
+
+void
+TransformerSaturation::allocateFlag(const Context& ctx){
+        //allocation of saturation flag
+    llvm::Type* tyInt1 = llvm::Type::getInt1Ty(llvm::getGlobalContext());
+    IRBuilder<> builder(blockAllocation, blockAllocation->getFirstInsertionPt());
+
+    flagSaturation = builder.CreateAlloca(tyInt1, constTrue, "flagSaturation");
+    builder.CreateStore(constFalse, flagSaturation, true);
+}
+
+bool
+TransformerSaturation::insertSaturationChecks(llvm::BasicBlock* blockContinue, llvm::BasicBlock* blockExit, const Context& ctx){
+    if (!flagSaturation) return false;
+
+    llvm::IRBuilder<>& builder = ctx.pass->man->llvm->builder;
+    builder.CreateCondBr(builder.CreateLoad(flagSaturation), blockExit, blockContinue);
+
+    return true;
+}
+
+} }
\ No newline at end of file
diff --git a/cpp/src/compilation/transformersaturation.h b/cpp/src/compilation/transformersaturation.h
new file mode 100644
index 0000000..b4e368a
--- /dev/null
+++ b/cpp/src/compilation/transformersaturation.h
@@ -0,0 +1,46 @@
+/* 
+ * File:   transformersaturation.h
+ * Author: pgess <v.melnychenko@xreate.org>
+ *
+ * Created on March 25, 2017, 9:59 PM
+ */
+
+#ifndef TRANSFORMERSATURATION_H
+#define TRANSFORMERSATURATION_H
+
+#include "transformations.h"
+
+namespace xreate {    namespace compilation {
+    
+class TransformerSaturation: public Transformer{
+public:    
+    TransformerSaturation(llvm::BasicBlock* allocationBlock, TransformationsManager* manager);
+    ~TransformerSaturation();
+    
+    llvm::Value* transform(const Expression& expression, llvm::Value* raw, const Context& ctx) override;
+
+    void processBreak(const Context& ctx);
+    
+    void allocateFlag(const Context& ctx);
+    bool insertSaturationChecks(llvm::BasicBlock* blockContinue, llvm::BasicBlock* blockExit, const Context& ctx);
+
+private:
+    TransformationsManager* man;
+    TransformerSaturation* oldInstance = nullptr;
+    
+    llvm::BasicBlock* blockAllocation;
+    
+    llvm::Value* constTrue;
+    llvm::Value* constFalse;
+    llvm::Value* flagSaturation = nullptr;
+};
+
+template <> 
+struct TransformerInfo<TransformerSaturation> {
+    static const unsigned int id = 0;
+};
+
+} }
+
+#endif /* TRANSFORMERSATURATION_H */
+
diff --git a/cpp/src/compilation/versions.h b/cpp/src/compilation/versions.h
new file mode 100644
index 0000000..e1f9b0d
--- /dev/null
+++ b/cpp/src/compilation/versions.h
@@ -0,0 +1,127 @@
+
+/*
+ * versions.cpp
+ *
+ * Author: pgess <v.melnychenko@xreate.org>
+ * Created on January 21, 2017, 1:24 PM
+ */
+
+#include "pass/versionspass.h"
+#include "pass/compilepass.h"
+
+namespace xreate {
+
+class CompilePass;
+
+namespace compilation {
+
+class AbstractCodeScopeUnit;
+class FunctionUnit;
+
+template<class Parent>
+class VersionsScopeDecorator: public Parent{
+    typedef VersionsScopeDecorator<Parent> SELF;
+    
+public:
+    VersionsScopeDecorator(CodeScope* codeScope, FunctionUnit* f, CompilePass* compilePass): Parent(codeScope, f, compilePass){}
+
+    virtual llvm::Value* processSymbol(const Symbol& s, std::string hintSymbol=""){
+        if (Attachments::exists<VersionImposedDependency>(s)){
+            const std::list<Symbol> dependencies = Attachments::get<VersionImposedDependency>(s);
+
+            for(const Symbol& symbolDependent: dependencies){
+                processSymbol(symbolDependent);
+            }
+        }
+
+        llvm::Value* result = Parent::processSymbol(s, hintSymbol);
+        
+        if (s.identifier.version == VERSION_INIT){
+            llvm::Value* storage = SELF::processIntrinsicInit(result->getType(), hintSymbol);
+            setSymbolStorage(s, storage);
+            
+            processIntrinsicCopy(result, storage);
+            return AbstractCodeScopeUnit::pass->man->llvm->builder.CreateLoad(storage);
+            
+        } else if (s.identifier.version != VERSION_NONE){
+            Symbol symbolInitVersion = getSymbolInitVersion(s);
+            
+           llvm::Value* storage = getSymbolStorage(symbolInitVersion);
+           processIntrinsicCopy(result, storage);
+           
+           return AbstractCodeScopeUnit::pass->man->llvm->builder.CreateLoad(storage);
+        }
+        
+        return result;
+    }
+    
+    llvm::Value* 
+    processIntrinsicInit(llvm::Type* typeStorage, const std::string& hintVarDecl=""){
+        llvm::IntegerType* tyInt = llvm::Type::getInt32Ty(llvm::getGlobalContext());
+        llvm::ConstantInt* constOne = llvm::ConstantInt::get(tyInt, 1, false);
+        
+        return AbstractCodeScopeUnit::pass->man->llvm->builder.CreateAlloca(typeStorage, constOne, hintVarDecl);
+    }
+    
+    void
+    processIntrinsicCopy(llvm::Value* value, llvm::Value* storage){
+        AbstractCodeScopeUnit::pass->man->llvm->builder.CreateStore(value, storage);
+    }
+    
+private:
+    std::map<Symbol, llvm::Value*> __symbolStorage;
+    
+        static Symbol
+    getSymbolInitVersion(const Symbol& s){
+        return Symbol{ScopedSymbol{s.identifier.id, VERSION_INIT}, s.scope};
+    }
+    
+    llvm::Value*
+    getSymbolStorage(const Symbol& s){
+        return __symbolStorage.at(s);
+    }
+    
+    void setSymbolStorage(const Symbol& s, llvm::Value* storage){
+        __symbolStorage[s] = storage;
+    }
+
+};
+}   //end of compilation namespace
+} //end of xreate namespace
+
+
+//    llvm::Value*
+//    processIntrinsicInitAndCopy(){
+//         
+//    }
+
+//llvm::Value*
+//process(const Expression& expr, const std::string& hintVarDecl){
+//    case Operator::CALL_INTRINSIC: {
+//        enum INRINSIC{INIT, COPY};
+//        
+//        const ExpandedType& typSymbol = pass->man->root->expandType(expr.type);
+//
+//        INTRINSIC op = (INTRINSIC) expr.getValueDouble();
+//
+//        switch (op){
+//            case INIT: {
+//                llvm::Type* typSymbolRaw = l.toLLVMType(typSymbol);
+//                
+//
+//                return storage;
+//            }
+//
+//            case COPY: {
+//                llvm::Type* typSymbolRaw = l.toLLVMType(typSymbol);
+//                llvm::value* valueOriginal = process(expr.getOperands()[0], hintVarDecl);
+//                llvm::Value* storage = l.builder.CreateAlloca(typSymbolRaw, constOne, hintVarDecl);
+//                llvm::Value* valueCopy = l.builder.CreateStore(valueOriginal, storage);
+//
+//                return valueCopy;
+//            }
+//        }
+//        return;
+//    }
+//}
+//};
\ No newline at end of file
diff --git a/cpp/src/pass/abstractpass.cpp b/cpp/src/pass/abstractpass.cpp
index fc4e19f..ca6190a 100644
--- a/cpp/src/pass/abstractpass.cpp
+++ b/cpp/src/pass/abstractpass.cpp
@@ -1,35 +1,58 @@
 #include "abstractpass.h"
 #include "attachments.h"
 #include "passmanager.h"
 
 using namespace std;
 
 namespace xreate {
 
-    template<>
-    void defaultValue<void>(){}
+template<>
+void defaultValue<void>(){}
 
-    void AbstractPassBase::finish(){}
+void AbstractPassBase::finish(){}
 
-    AbstractPassBase::AbstractPassBase(PassManager *manager)
-            : man(manager) {
-    }
+AbstractPassBase::AbstractPassBase(PassManager *manager)
+        : man(manager) {
+}
+
+template<>
+void
+AbstractPass<void>::processSymbol(const Symbol& symbol, PassContext context, const std::string& hintSymbol)
+{
+    if (__visitedSymbols.isCached(symbol))
+        return;
 
-    template<>
-    void
-    AbstractPass<void>::processSymbol(const std::string& ident, PassContext context)
-    {
-        const Symbol& symbol = context.scope->findSymbol(ident);
+    __visitedSymbols.setCachedValue(symbol);
+    const Expression& declaration = CodeScope::getDeclaration(symbol);
 
-        if (__visitedSymbols.isCached(symbol))
-            return;
+    if (declaration.isDefined()){
+        PassContext context2 = context.updateScope(symbol.scope);
+        process(declaration, context2, hintSymbol);
+    }
+}
+
+template<>
+void
+AbstractPass<void>::process(const Expression& expression, PassContext context, const std::string& varDecl){
+    if (expression.__state == Expression::COMPOUND){
+        for (const Expression &op: expression.getOperands()) {
+            process(op, context);
+        }
 
-        __visitedSymbols.setCachedValue(symbol);
-        const Expression& declaration = CodeScope::findDeclaration(symbol);
+        for (CodeScope* scope: expression.blocks) {
+            process(scope, context);
+        }
 
-        if (declaration.isDefined()){
-            PassContext context2 = context.updateScope(symbol.scope);
-            process(declaration, context2, ident);
+        if (expression.op == Operator::CALL){
+            processExpressionCall(expression, context);
         }
+
+        return;
+    }
+
+    if (expression.__state == Expression::IDENT){
+        assert(context.scope);
+        processSymbol(Attachments::get<Symbol>(expression), context, expression.getValueString());
     }
+}
 }
\ No newline at end of file
diff --git a/cpp/src/pass/abstractpass.h b/cpp/src/pass/abstractpass.h
index 328a916..dfefc06 100644
--- a/cpp/src/pass/abstractpass.h
+++ b/cpp/src/pass/abstractpass.h
@@ -1,201 +1,194 @@
 #ifndef ABSTRACTPASS_H
 #define ABSTRACTPASS_H
 #include "ast.h"
 #include "passmanager.h"
 
 #include<iostream>
 namespace xreate
 {
     struct PassContext
     {
         CodeScope* scope = 0;
         ManagedFnPtr function;
         ManagedRulePtr rule;
         std::string varDecl;
 
         PassContext()
         {}
 
-        PassContext&& updateScope(CodeScope* scopeNew) {
+        PassContext updateScope(CodeScope* scopeNew) {
             PassContext context2{*this};
             context2.scope = scopeNew;
-            return std::move(context2);
+            return context2;
         }
 
         ~PassContext(){}
     };
 
     class AbstractPassBase {
     public:
         AbstractPassBase(PassManager* manager);
         virtual void run()=0;
         virtual void finish();
 
         PassManager* man;
     };
 
     template<class Output>
     Output defaultValue();
     
     template<>
     void defaultValue<void>();
 
     template<class Output>
     class SymbolCache: private std::map<Symbol, Output>{
         public:
             bool isCached(const Symbol& symbol){
                 return this->count(symbol);
             }
 
             Output setCachedValue(const Symbol& symbol, Output&& value){
                 (*this)[symbol] = value;
                 return value;
             }
 
             Output getCachedValue(const  Symbol& symbol){
                 assert(this->count(symbol));
                 return this->at(symbol);
             }
     };
 
     template<>
     class SymbolCache<void>: private std::set<Symbol>{
         public:
         bool isCached(const Symbol& symbol){
             bool result = this->count(symbol) > 0;
             return result;
         }
         void setCachedValue(const Symbol& symbol){
             this->insert(symbol);
         }
 
         void getCachedValue(const  Symbol& symbol){
         }
     };
 
-    template<class Output>
-    class AbstractPass: public AbstractPassBase    {
-        
-        SymbolCache<Output> __visitedSymbols;
-
-    protected:        
-        Output processSymbol(const std::string& ident, PassContext context){
-            const Symbol& symbol = context.scope->findSymbol(ident);
-
-            if (__visitedSymbols.isCached(symbol))
-                return __visitedSymbols.getCachedValue(symbol);
-
-            
-            const Expression& declaration = CodeScope::findDeclaration(symbol);
-            if (declaration.isDefined()){
-                PassContext context2 = context.updateScope(symbol.scope);
-                
-                Output&& result = process(declaration, context2, ident);
-                return __visitedSymbols.setCachedValue(symbol, std::move(result));
-            }
-            
-            return defaultValue<Output>();
-        }
-        
-        SymbolCache<Output>& getSymbolCache(){
-            return __visitedSymbols;
-        }
-        
-    public:
-        AbstractPass(PassManager* manager)
-            : AbstractPassBase(manager){}
-            
-        virtual Output processFnCall(ManagedFnPtr function, PassContext context){
-            return defaultValue<Output>();
-        }
+template<class Output>
+class AbstractPass: public AbstractPassBase    {
 
-        virtual void processFnCallUncertain(ManagedFnPtr function, PassContext context)
-        {}
+    SymbolCache<Output> __visitedSymbols;
 
-        virtual void process(ManagedRulePtr rule)
-        {}
+protected:        
+    virtual Output processSymbol(const Symbol& symbol, PassContext context, const std::string& hintSymbol=""){
+        if (__visitedSymbols.isCached(symbol))
+            return __visitedSymbols.getCachedValue(symbol);
 
-        virtual Output process(ManagedFnPtr function)
-        {
-            PassContext context;
-            context.function = function;
 
-            return process(function->getEntryScope(), context);
-        }    
+        const Expression& declaration = CodeScope::getDeclaration(symbol);
+        if (declaration.isDefined()){
+            PassContext context2 = context.updateScope(symbol.scope);
 
-        virtual Output process(CodeScope* scope, PassContext context, const std::string& hintBlockDecl=""){
-            context.scope = scope;
-            return process(scope->getBody(), context);
+            Output&& result = process(declaration, context2, hintSymbol);
+            return __visitedSymbols.setCachedValue(symbol, std::move(result));
         }
 
-        virtual Output process(const Expression& expression, PassContext context, const std::string& varDecl=""){
-            switch (expression.__state) {
-                case Expression::COMPOUND:
-                assert(expression.op != Operator::MAP || (expression.op == Operator::MAP && expression.blocks.size()));
-
-                //TODO there are discrepancies for SWITCH CASE scopes.case body parent scope differs from context.scope.
-                for (const Expression &op: expression.getOperands()) {
-                    process(op, context);
-                }
-
-                //
-                for (CodeScope* scope: expression.blocks) {
-                    process(scope, context);
-                }
-
-                if (expression.op == Operator::CALL) {
-                    const std::string &calleeName = expression.getValueString();
-                    std::list<ManagedFnPtr> callees = man->root->getFunctionVariants(calleeName);
-                    if (callees.size() == 1 && callees.front()){
-                    	processFnCall(callees.front(), context);
-                    } else {
-                    	for (const ManagedFnPtr& callee: callees){
-                    		processFnCallUncertain(callee, context);
-                    	}
-                    }
-                }
-                break;
-
-                case Expression::IDENT:
-                    assert(context.scope);
-                    return processSymbol(expression.getValueString(), context);
-
-                default:
-                break;
+        return defaultValue<Output>();
+    }
+
+    Output processExpressionCall(const Expression& expression, PassContext context){
+        const std::string &calleeName = expression.getValueString();
+        std::list<ManagedFnPtr> callees = man->root->getFunctionVariants(calleeName);
+        if (callees.size() == 1 && callees.front()){
+            return processFnCall(callees.front(), context);
+
+        } else {
+            for (const ManagedFnPtr& callee: callees){
+                processFnCallUncertain(callee, context);
             }
 
             return defaultValue<Output>();
         }
+    }
 
-        void run() {
-            ManagedRulePtr rule = man->root->begin<MetaRuleAbstract>();
-            while (rule.isValid()) {
-                process(rule);
-                ++rule;
-            }
+    SymbolCache<Output>& getSymbolCache(){
+        return __visitedSymbols;
+    }
 
-            ManagedFnPtr f = man->root->begin<Function>();
-            while (f.isValid()) {
-                process(f);
-                ++f;
-            }
+
+
+public:
+    AbstractPass(PassManager* manager)
+        : AbstractPassBase(manager){}
+
+    virtual Output processFnCall(ManagedFnPtr function, PassContext context){
+        return defaultValue<Output>();
+    }
+
+    virtual void processFnCallUncertain(ManagedFnPtr function, PassContext context)
+    {}
+
+    virtual void process(ManagedRulePtr rule)
+    {}
+
+    virtual Output process(ManagedFnPtr function)
+    {
+        PassContext context;
+        context.function = function;
+
+        return process(function->getEntryScope(), context);
+    }    
+
+    virtual Output process(CodeScope* scope, PassContext context, const std::string& hintBlockDecl=""){
+        context.scope = scope;
+
+        return processSymbol(Symbol{ScopedSymbol::RetSymbol, scope}, context);
+    }
+
+    virtual Output process(const Expression& expression, PassContext context, const std::string& varDecl=""){
+        if (expression.__state == Expression::IDENT){
+            assert(context.scope);
+            return processSymbol(Attachments::get<Symbol>(expression), context, expression.getValueString());
         }
-    };
 
-    template<>
-    void
-    AbstractPass<void>::processSymbol(const std::string& ident, PassContext context);
-}
+        assert(false);
+        return defaultValue<Output>();
+    }
+
+    void run() {
+        ManagedRulePtr rule = man->root->begin<MetaRuleAbstract>();
+        while (rule.isValid()) {
+            process(rule);
+            ++rule;
+        }
+
+        ManagedFnPtr f = man->root->begin<Function>();
+        while (f.isValid()) {
+            process(f);
+            ++f;
+        }
+    }
+
+};
+
+template<>
+void
+AbstractPass<void>::processSymbol(const Symbol& symbol, PassContext context, const std::string& hintSymbol);
+
+template<>
+void
+AbstractPass<void>::process(const Expression& expression, PassContext context, const std::string& hintSymbol);
+
+}    
 #endif
 
 //PROCESS FUNCTION:
 //    const Symbol& symbolFunction{0, function->getEntryScope()};
 //
 //    if (__visitedSymbols.isCached(symbolFunction))
 //        return __visitedSymbols.getCachedValue(symbolFunction);
 //
 //    PassContext context;
 //    context.function = function;
 //
 //    Output&& result = process(function->getEntryScope(), context);
 //    return __visitedSymbols.setCachedValue(symbolFunction, std::move(result));
\ No newline at end of file
diff --git a/cpp/src/pass/adhocpass.cpp b/cpp/src/pass/adhocpass.cpp
index 65cde19..35e3c50 100644
--- a/cpp/src/pass/adhocpass.cpp
+++ b/cpp/src/pass/adhocpass.cpp
@@ -1,81 +1,95 @@
 /*
  * adhoc.cpp
  *
  *  Created on: Nov 28, 2015
  *      Author: pgess
  */
 
 #include "pass/adhocpass.h"
 #include "query/context.h"
 
 namespace xreate {
-	AdhocScheme*
-	AdhocPass::determineForScope(CodeScope* entry){
-		const ScopePacked scopeId = man->clasp->pack(entry);
-		const Domain& domain = queryContext->getContext(scopeId);
-		AdhocScheme* scheme = nullptr;
-
-		for (const Expression& context: domain){
-			if (context.__state != Expression::IDENT) continue;
-
-			if (__schemes.count(context.getValueString())){
-				assert(!scheme && "ambiguous context");
-				scheme = __schemes.at(context.getValueString());
-			}
-		}
-
-		assert(scheme && "Appropriate context not found");
-		return scheme;
-	}
-
-	const TypeAnnotation&
-	AdhocScheme::getResultType(){
-		return __resultType;
-	}
-
-	CodeScope*
-	AdhocScheme::getImplementationForCommand(const std::string& comm) {
-		assert(__commands.count(comm) && "Adhoc not defined");
-		return 	__commands.at(comm);
-	}
-
-	AdhocScheme::AdhocScheme(const Expression& scheme):
-		__resultType(scheme.type), __context(scheme.getValueString()) {
-
-		Expression cases = scheme.getOperands()[0];
-		for (const Expression& exprCase: cases.getOperands()){
-			CodeScope* blockComm = exprCase.blocks.front();
-			std::string nameCase = blockComm->getBody().operands[0].getValueString();
-
-			CodeScope* blockImpl = *(++exprCase.blocks.begin());
-			__commands.emplace(nameCase, blockImpl);
-		}
-	}
-
-	const std::string&
-	AdhocScheme::getContext(){
-		return __context;
-	}
-
-	/*
-	void
-	AdhocPass::process(const Expression& expression, PassContext context, const std::string& varDecl=""){
-		if (expression == Exp)
-	}
-	*/
-
-	void
-	AdhocPass::run(){
-		queryContext = reinterpret_cast<ContextQuery*>(man->clasp->registerQuery(new ContextQuery(), QueryId::ContextQuery));
-
-		auto range = man->root->__interfacesData.equal_range(ASTInterface::Adhoc);
-		for (auto i=range.first; i!= range.second; ++i){
-			AdhocScheme* scheme = new AdhocScheme(i->second);
-			__schemes.emplace(scheme->getContext(), scheme);
-		}
-	}
+
+AdhocExpression::AdhocExpression(): Expression(Operator::ADHOC, {})
+{}
+
+AdhocExpression::AdhocExpression(const Expression& base): Expression(base)
+{}
+
+void
+AdhocExpression::setCommand(const Expression& comm){
+    this->addTags({Expression(Operator::CALL, {Atom<Identifier_t>("adhoc"), comm})});
+}
+
+Expression
+AdhocExpression::getCommand() const{
+    assert(this->tags.count("adhoc"));
+    return this->tags.at("adhoc").getOperands().at(0);
+}
+
+AdhocScheme*
+AdhocPass::findAssotiatedScheme(CodeScope* entry){
+    const ScopePacked scopeId = man->clasp->pack(entry);
+    const Domain& domain = queryContext->getContext(scopeId);
+    AdhocScheme* scheme = nullptr;
+
+    for (const Expression& context: domain){
+            if (context.__state != Expression::IDENT) continue;
+
+            if (__schemes.count(context.getValueString())){
+                    assert(!scheme && "Can't determine relevant scheme, ambiguous context");
+                    scheme = __schemes.at(context.getValueString());
+            }
+    }
+
+    assert(scheme && "Context doesn't define any ad hoc scheme");
+    return scheme;
+}
+
+const TypeAnnotation&
+AdhocScheme::getResultType(){
+    return __resultType;
+}
+
+CodeScope*
+AdhocScheme::getCommandImplementation(const Expression& comm) {
+    assert(comm.__state == Expression::IDENT);
+
+    const std::string commSerialized =  comm.getValueString();
+    assert(__commands.count(commSerialized) && "Command isn't defined for a selected scheme");
+    return __commands.at(commSerialized);
+}
+
+AdhocScheme::AdhocScheme(const Expression& scheme):
+    __resultType(scheme.type), __name(scheme.getValueString()) {
+
+    Expression exprCasesList = scheme.getOperands()[0];
+    for (const Expression& exprSingleCase: exprCasesList.getOperands()){
+        std::string command = exprSingleCase.tags.begin()->second.getValueString();
+
+        CodeScope* blockImpl = *(exprSingleCase.blocks.begin());
+        __commands.emplace(command, blockImpl);
+    }
+}
+
+const std::string&
+AdhocScheme::getName(){
+    return __name;
+}
+
+void
+AdhocPass::run(){
+    queryContext = reinterpret_cast<ContextQuery*>(man->clasp->registerQuery(new ContextQuery(), QueryId::ContextQuery));
+
+    auto range = man->root->__interfacesData.equal_range(ASTInterface::Adhoc);
+    for (auto i=range.first; i!= range.second; ++i){
+        AdhocScheme* scheme = new AdhocScheme(i->second);
+        __schemes.emplace(scheme->getName(), scheme);
+    }
+}
+
 }
 
 
 
 
diff --git a/cpp/src/pass/adhocpass.h b/cpp/src/pass/adhocpass.h
index 45877ad..561ebfa 100644
--- a/cpp/src/pass/adhocpass.h
+++ b/cpp/src/pass/adhocpass.h
@@ -1,50 +1,59 @@
 /*
  * adhoc.h
  *
  *  Created on: Nov 28, 2015
  *      Author: pgess
  */
 //SECTIONTAG adhoc pass
 #ifndef SRC_INSTRUCTIONS_ADHOC_H_
 #define SRC_INSTRUCTIONS_ADHOC_H_
 
 #include "abstractpass.h"
 
-#ifndef FRIEND_ADHOC_UNITTESTS
-	#define FRIEND_ADHOC_UNITTESTS
+#ifndef FRIENDS_ADHOC
+    #define FRIENDS_ADHOC
 #endif
 
 namespace xreate {
 
-	class ContextQuery;
+class ContextQuery;
+
+class AdhocScheme {
+public:
+    AdhocScheme(const Expression& scheme);
+    CodeScope* getCommandImplementation(const Expression& comm);
+    const TypeAnnotation& getResultType();
+    const std::string& getName();
+
+private:
+    TypeAnnotation __resultType;
+    std::string __name;
+    std::map<std::string, CodeScope*> __commands;
+};
+
+class AdhocExpression: public Expression{
+public:
+    AdhocExpression();
+    AdhocExpression(const Expression& base);
+    
+    void setCommand(const Expression& comm);
+    Expression getCommand() const;
+};
+
+class AdhocPass: public AbstractPass<void> {
+    FRIENDS_ADHOC
+
+public:
+    AdhocPass(PassManager* manager): AbstractPass(manager) {}
+    void run() override;
+    
+    AdhocScheme* findAssotiatedScheme(CodeScope* entry);
+    
+private:
+    std::map<std::string, AdhocScheme*> __schemes;
+    ContextQuery* queryContext;
+};
 
-	class AdhocScheme {
-	public:
-		AdhocScheme(const Expression& scheme);
-		CodeScope* getImplementationForCommand(const std::string& comm);
-		const TypeAnnotation& getResultType();
-		const std::string& getContext();
-
-	private:
-		TypeAnnotation __resultType;
-		std::string __context;
-		std::map<std::string, CodeScope*> __commands;
-	};
-
-	class AdhocPass: public AbstractPass<void> {
-		FRIEND_ADHOC_UNITTESTS
-
-		public:
-			AdhocPass(PassManager* manager): AbstractPass(manager) {}
-			AdhocScheme* determineForScope(CodeScope* entry);
-
-		//	virtual void process(const Expression& expression, PassContext context, const std::string& varDecl="");
-			void run() override;
-
-		private:
-			std::map<std::string, AdhocScheme*> __schemes;
-			ContextQuery* queryContext;
-	};
 }
 
 #endif /* SRC_INSTRUCTIONS_ADHOC_H_ */
diff --git a/cpp/src/pass/cfapass.cpp b/cpp/src/pass/cfapass.cpp
index c4afd00..07801b6 100644
--- a/cpp/src/pass/cfapass.cpp
+++ b/cpp/src/pass/cfapass.cpp
@@ -1,100 +1,100 @@
 #include "cfapass.h"
 #include "analysis/cfagraph.h"
 
 #include <boost/range/iterator_range_core.hpp>
 
 using namespace std;
 using namespace xreate;
 
 void
 CFAPass::initSignatures(){
-	auto range = man->root->__interfacesData.equal_range(CFA);
-	for (auto i = range.first; i!= range.second; ++i){
-		__signatures.emplace(i->second.op, i->second);
-	}
+    auto range = man->root->__interfacesData.equal_range(CFA);
+    for (auto i = range.first; i!= range.second; ++i){
+            __signatures.emplace(i->second.op, i->second);
+    }
 }
 
 void CFAPass::run(){
-	initSignatures();
+    initSignatures();
 
-	return AbstractPass::run();
+    return AbstractPass::run();
 }
 
 void
 CFAPass::finish()
 {
     man->clasp->setCFAData(move(__context.graph));
 
     return AbstractPass::finish();
 }
 
 void
 CFAPass::processFnCall(ManagedFnPtr function, PassContext context)
 {
-	ClaspLayer* clasp = man->clasp;
-	__context.graph->addCallConnection(clasp->pack(context.scope), function->getName());
+    ClaspLayer* clasp = man->clasp;
+    __context.graph->addCallConnection(clasp->pack(context.scope), function->getName());
 
-	return AbstractPass::processFnCall(function, context);
+    return AbstractPass::processFnCall(function, context);
 }
 
 void
 CFAPass::processFnCallUncertain(ManagedFnPtr function, PassContext context){
-	ClaspLayer* clasp = man->clasp;
-	__context.graph->addCallConnection(clasp->pack(context.scope), function->getName());
+    ClaspLayer* clasp = man->clasp;
+    __context.graph->addCallConnection(clasp->pack(context.scope), function->getName());
 
-	return AbstractPass::processFnCallUncertain(function, context);
+    return AbstractPass::processFnCallUncertain(function, context);
 }
 
 void
 CFAPass::process(CodeScope* scope, PassContext context, const std::string& hintBlockDecl){
-	ClaspLayer* clasp = man->clasp;
+    ClaspLayer* clasp = man->clasp;
 
-	CodeScope* scopeParent = context.scope;
-	ScopePacked scopeId = clasp->pack(scope);
+    CodeScope* scopeParent = context.scope;
+    ScopePacked scopeId = clasp->pack(scope);
 
-	if (scopeParent){
-		__context.graph->addParentConnection(scopeId, clasp->pack(scopeParent));
-	} else {
-		__context.graph->addParentConnection(scopeId, context.function->getName());
-	}
+    if (scopeParent){
+            __context.graph->addParentConnection(scopeId, clasp->pack(scopeParent));
+    } else {
+            __context.graph->addParentConnection(scopeId, context.function->getName());
+    }
 
-		//TOTEST scope annotations
-		//SECTIONTAG context gather scope annotations
-	__context.graph->addScopeAnnotations(scopeId, scope->tags);
+            //TOTEST scope annotations
+            //SECTIONTAG context gather scope annotations
+    __context.graph->addScopeAnnotations(scopeId, scope->tags);
 
-	__context.graph->addContextRules(scopeId, scope->contextRules);
+    __context.graph->addContextRules(scopeId, scope->contextRules);
 
-	return AbstractPass::process(scope, context, hintBlockDecl);
+    return AbstractPass::process(scope, context, hintBlockDecl);
 }
 
 //TOTEST scope annotations via scheme
 void
 CFAPass::process(const Expression& expression, PassContext context, const std::string& varDecl){
-	ClaspLayer* clasp = man->clasp;
+    ClaspLayer* clasp = man->clasp;
 
-	if (expression.__state == Expression::COMPOUND){
-		Operator  op= expression.op;
+    if (expression.__state == Expression::COMPOUND){
+            Operator  op= expression.op;
 
-		if (__signatures.count(op)) {
-			assert(expression.blocks.size());
+            if (__signatures.count(op)) {
+                    assert(expression.blocks.size());
 
-			for (const auto& scheme: boost::make_iterator_range(__signatures.equal_range(expression.op))) {
-					__context.graph->addScopeAnnotations(clasp->pack(expression.blocks.front()), scheme.second.getOperands());
-			}
-		}
-	}
+                    for (const auto& scheme: boost::make_iterator_range(__signatures.equal_range(expression.op))) {
+                                    __context.graph->addScopeAnnotations(clasp->pack(expression.blocks.front()), scheme.second.getOperands());
+                    }
+            }
+    }
 
-	return AbstractPass::process(expression, context, varDecl);
+    return AbstractPass::process(expression, context, varDecl);
 }
 
 void
 CFAPass::process(ManagedFnPtr function)
 {
-	__context.graph->addFunctionAnnotations(function->getName(), function->getTags());
-	return AbstractPass::process(function);
+    __context.graph->addFunctionAnnotations(function->getName(), function->getTags());
+    return AbstractPass::process(function);
 }
 
 CFAPass::CFAPass(PassManager* manager)
-	: AbstractPass(manager)
-          , __context{new xreate::analysis::CFAGraph(manager->clasp)}
-{}
+    : AbstractPass(manager)
+      , __context{new xreate::analysis::CFAGraph(manager->clasp)}
+{}
\ No newline at end of file
diff --git a/cpp/src/pass/compilepass.cpp b/cpp/src/pass/compilepass.cpp
index 78666b5..b1967c8 100644
--- a/cpp/src/pass/compilepass.cpp
+++ b/cpp/src/pass/compilepass.cpp
@@ -1,829 +1,765 @@
 #include "compilepass.h"
 #include "clasplayer.h"
 #include <ast.h>
 #include "llvmlayer.h"
 
 #include "query/containers.h"
 #include "query/context.h"
 #include "compilation/containers.h"
-#include "compilation/transformations.h"
 #include "compilation/latecontextcompiler2.h"
 #include "ExternLayer.h"
 #include "pass/adhocpass.h"
 #include "compilation/targetinterpretation.h"
+#include "pass/versionspass.h"
+#include "compilation/scopedecorators.h"
 
 #include <boost/optional.hpp>
 #include <memory>
 #include <iostream>
 
 using namespace std;
 using namespace xreate;
 using namespace xreate::compilation;
 using namespace llvm;
 
 //TODO use Scope<TargetLlvm>
 
 //SECTIONTAG types/convert implementation
 //TODO type conversion:
 //a)    automatically expand types int -> bigger int; int -> floating
 //b)    detect exact type of `num` based on max used numeral / function type
 //c)    warning if need to truncate (allow/dissalow based on annotations)
 
 namespace xreate {
 
 llvm::Value*
 doAutomaticTypeConversion(llvm::Value* source, llvm::Type* tyTarget, llvm::IRBuilder<>& builder){
     if (tyTarget->isIntegerTy() && source->getType()->isIntegerTy())
     {
             llvm::IntegerType* tyTargetInt = llvm::dyn_cast<IntegerType>(tyTarget);
             llvm::IntegerType* tySourceInt = llvm::dyn_cast<IntegerType>(source->getType());
 
             if (tyTargetInt->getBitWidth() < tySourceInt->getBitWidth()){
                     return builder.CreateCast(llvm::Instruction::Trunc, source, tyTarget);
             }
 
             if (tyTargetInt->getBitWidth() > tySourceInt->getBitWidth()){
                     return builder.CreateCast(llvm::Instruction::SExt, source, tyTarget);
             }
     }
 
     if (source->getType()->isIntegerTy() && tyTarget->isFloatingPointTy()){
         return builder.CreateCast(llvm::Instruction::SIToFP, source, tyTarget);
     }
 
     return source;
 }
 
 
 std::string
 BasicFunctionDecorator::prepareName(){
     AST* ast = FunctionUnit::pass->man->root;
 
     string name = ast->getFunctionVariants(FunctionUnit::function->__name).size() > 1?
         FunctionUnit::function->__name  + std::to_string(FunctionUnit::function.id()) :
         FunctionUnit::function->__name;
 
     return name;
 }
 
 std::vector<llvm::Type*>
 BasicFunctionDecorator::prepareArguments(){
     LLVMLayer* llvm = FunctionUnit::pass->man->llvm;
     AST* ast = FunctionUnit::pass->man->root;
     CodeScope* entry = FunctionUnit::function->__entry;
     std::vector<llvm::Type*> signature;
 
     std::transform(entry->__bindings.begin(), entry->__bindings.end(), std::inserter(signature, signature.end()),
             [llvm, ast, entry](const std::string &arg)->llvm::Type* {
                 assert(entry->__identifiers.count(arg));
 
-                VID argid = entry->__identifiers.at(arg);
+                ScopedSymbol argid{entry->__identifiers.at(arg), VERSION_NONE};
                 return llvm->toLLVMType(ast->expandType(entry->__declarations.at(argid).type));
     });
 
     return signature;
 }
 
 llvm::Type*
 BasicFunctionDecorator::prepareResult(){
     LLVMLayer* llvm = FunctionUnit::pass->man->llvm;
     AST* ast = FunctionUnit::pass->man->root;
     CodeScope* entry = FunctionUnit::function->__entry;
 
-    return llvm->toLLVMType(ast->expandType(entry->__declarations[0].type));
+    return llvm->toLLVMType(ast->expandType(entry->__declarations.at(ScopedSymbol::RetSymbol).type));
 }
 
 llvm::Function::arg_iterator
 BasicFunctionDecorator::prepareBindings(){
     CodeScope* entry = FunctionUnit::function->__entry;
-    CodeScopeUnit* entryCompilation = FunctionUnit::getScopeUnit(entry);
+    AbstractCodeScopeUnit* entryCompilation = FunctionUnit::getScopeUnit(entry);
     llvm::Function::arg_iterator fargsI = FunctionUnit::raw->arg_begin();
 
     for (std::string &arg : entry->__bindings) {
-        VID argid = entry->__identifiers[arg];
+        ScopedSymbol argid{entry->__identifiers[arg], VERSION_NONE};
 
-        entryCompilation->__rawVars[argid] = &*fargsI;
+        entryCompilation->bindArg(&*fargsI, argid);
         fargsI->setName(arg);
         ++fargsI;
     }
 
     return fargsI;
 }
 
 //SECTIONTAG late-context FunctionDecorator
 template<class Parent>
 class LateContextFunctionDecorator: public Parent{
 public:
     LateContextFunctionDecorator(ManagedFnPtr f, CompilePass* p)
         : Parent(f, p), contextCompiler(this, p)
     {}
 
 protected:
     std::vector<llvm::Type*>  prepareArguments(){
         std::vector<llvm::Type*>&& arguments = Parent::prepareArguments();
 
         size_t sizeLateContextDemand = contextCompiler.getFunctionDemandSize();
         if (sizeLateContextDemand) {
             llvm::Type* ty32 = llvm::Type::getInt32Ty(llvm::getGlobalContext());
             llvm::Type* tyDemand = llvm::ArrayType::get(ty32, sizeLateContextDemand);
 
             arguments.push_back(tyDemand);
         }
 
         return arguments;
     }
 
     llvm::Function::arg_iterator prepareBindings(){
         llvm::Function::arg_iterator fargsI = Parent::prepareBindings();
 
         size_t sizeLateContextDemand = contextCompiler.getFunctionDemandSize();
         if (sizeLateContextDemand){
             fargsI->setName("latecontext");
             contextCompiler.rawContextArgument = &*fargsI;
             ++fargsI;
         }
 
         return fargsI;
     }
 
 public:
     LateContextCompiler2 contextCompiler;
 
 };
 
 //SECTIONTAG adhoc FunctionDecorator
 template<class Parent>
 class AdhocFunctionDecorator: public Parent{
 public:
     AdhocFunctionDecorator(ManagedFnPtr f, CompilePass* p)
         : Parent(f, p)    {}
 
 protected:
     llvm::Type* prepareResult(){
         PassManager* man = Parent::pass->man;
         CodeScope* entry = Parent::function->__entry;
         LLVMLayer* llvm = Parent::pass->man->llvm;
         AST* ast = Parent::pass->man->root;
         AdhocPass* adhocpass = reinterpret_cast<AdhocPass*>(man->getPassById(PassId::AdhocPass));
 
         if (! Parent::function->isPrefunction){
             return Parent::prepareResult();
         }
 
-        adhocImplementation = adhocpass->determineForScope(entry);
+        adhocImplementation = adhocpass->findAssotiatedScheme(entry);
         return llvm->toLLVMType(ast->expandType(adhocImplementation->getResultType()));
     }
 
 public:
     AdhocScheme* adhocImplementation=nullptr;
 
 };
 
+//DEBT compiler rigidly depends on exact definition of DefaultFunctionUnit
 typedef LateContextFunctionDecorator<
         AdhocFunctionDecorator<
         BasicFunctionDecorator>> DefaultFunctionUnit;
 
 
-CodeScopeUnit::CodeScopeUnit(CodeScope* codeScope, FunctionUnit* f, CompilePass* compilePass)
-    : scope(codeScope), pass(compilePass), function(f)
+AbstractCodeScopeUnit::AbstractCodeScopeUnit(CodeScope* codeScope, FunctionUnit* f, CompilePass* compilePass)
+    : pass(compilePass), function(f), scope(codeScope)
 {}
 
 
 llvm::Value*
 CallStatementRaw::operator() (std::vector<llvm::Value *>&& args, const std::string& hintDecl) {
     llvm::Function* calleeInfo = dyn_cast<llvm::Function>(__callee);
 
     if (calleeInfo){
         auto argsFormal = calleeInfo->args();
 
         int pos=0;
         //SECTIONTAG types/convert function ret value
         for (auto argFormal = argsFormal.begin(); argFormal!=argsFormal.end(); ++argFormal, ++pos){
             args[pos] = doAutomaticTypeConversion(args[pos], argFormal->getType(), llvm->builder);
         }
     }
 
     return llvm->builder.CreateCall(__calleeTy, __callee, args, hintDecl);
 }
 
-//DEBT implement inlining
+//DESABLEDFEATURE implement inlining
 class CallStatementInline: public CallStatement{
 public:
 	CallStatementInline(FunctionUnit* caller, FunctionUnit* callee, LLVMLayer* l)
 		: __caller(caller), __callee(callee), llvm(l) {}
 
 	llvm::Value* operator() (std::vector<llvm::Value *>&& args, const std::string& hintDecl) {
 		//TOTEST inlining
 //            CodeScopeUnit* entryCompilation = outer->getScopeUnit(function->__entry);
 //            for(int i=0, size = args.size(); i<size; ++i) {
 //                entryCompilation->bindArg(args.at(i), string(entryCompilation->scope->__bindings.at(i)));
 //            }
 //
 //
 //            return entryCompilation->compile();
+
+            return nullptr;
 	}
 
 private:
 	FunctionUnit* __caller;
 	FunctionUnit* __callee;
         LLVMLayer* llvm;
 
         bool isInline(){
             // Symbol ret = Symbol{0, function->__entry};
             // bool flagOnTheFly = SymbolAttachments::get<IsImplementationOnTheFly>(ret, false);
             //TODO consider inlining
             return false;
         }
 };
 
-
 }
 
-void
-CodeScopeUnit::overrideDeclaration(const Symbol binding, Expression&& declaration){
-    function->getScopeUnit(binding.scope)->__declarationsOverriden.emplace(binding.identifier, move(declaration));
+BasicCodeScopeUnit::BasicCodeScopeUnit(CodeScope* codeScope, FunctionUnit* f, CompilePass* compilePass)
+    : AbstractCodeScopeUnit(codeScope, f, compilePass)
+{}
+
+llvm::Value*
+BasicCodeScopeUnit::processSymbol(const Symbol& s, std::string hintRetVar){
+    Expression declaration = CodeScope::getDeclaration(s);
+    CodeScope* scope = s.scope;
+    AbstractCodeScopeUnit* self = AbstractCodeScopeUnit::function->getScopeUnit(scope);
+
+    return self->process(declaration, hintRetVar);
 }
 
+
 //SECTIONTAG late-context find callee function
 //TOTEST static late context decisions
 //TOTEST dynamic late context decisions
-
 CallStatement*
-CodeScopeUnit::findFunction(const std::string& calleeName){
+BasicCodeScopeUnit::findFunction(const std::string& calleeName){
     LLVMLayer* llvm = pass->man->llvm;
     ClaspLayer* clasp = pass->man->clasp;
     DefaultFunctionUnit* function = dynamic_cast<DefaultFunctionUnit*>(this->function);
     ContextQuery* queryContext = pass->queryContext;
 
     const std::list<ManagedFnPtr>& specializations = pass->man->root->getFunctionVariants(calleeName);
 
     //if no specializations registered - check external function
     if (specializations.size()==0){
         llvm::Function* external = llvm->layerExtern->lookupFunction(calleeName);
 
         return new CallStatementRaw(external, llvm);
     }
 
     //no decisions required
     if (specializations.size()==1){
         if (!specializations.front()->guardContext.isValid()) {
             return new CallStatementRaw( pass->getFunctionUnit(specializations.front())->compile(), llvm);
         }
     }
 
     //TODO move dictSpecialization over to a separate function in order to perform cache, etc.
     //prepare specializations dictionary
     std::map<Expression, ManagedFnPtr> dictSpecializations;
 
     boost::optional<ManagedFnPtr> variantDefault;
     boost::optional<ManagedFnPtr> variant;
 
     for(const ManagedFnPtr& f: specializations){
         const Expression& guard = f->guardContext;
 
         //default case:
         if (!guard.isValid()){
                 variantDefault = f;
                 continue;
         }
 
         assert(dictSpecializations.emplace(guard, f).second && "Found several identical specializations");
     }
 
     //check static context
     ScopePacked scopeCaller = clasp->pack(this->scope);
     const string atomSpecialization = "specialization";
     const Expression topicSpecialization(Operator::CALL, {(Atom<Identifier_t>(string(atomSpecialization))), (Atom<Identifier_t>(string(calleeName))), (Atom<Number_t>(scopeCaller))});
 
     const Decisions& decisions = queryContext->getFinalDecisions(scopeCaller);
     if (decisions.count(topicSpecialization)){
         variant =  dictSpecializations.at(decisions.at(topicSpecialization));
     }
 
     //TODO check only demand for this particular topic.
     size_t sizeDemand = function->contextCompiler.getFunctionDemandSize();
 
     //decision made if static context found or no late context exists(and there is default variant)
     bool flagHasStaticDecision =  variant || (variantDefault && !sizeDemand);
 
     //if no late context exists
     if (flagHasStaticDecision) {
         FunctionUnit* calleeUnit = pass->getFunctionUnit(variant? *variant: *variantDefault);
 
             //inlining possible based on static decision only
 //        if (calleeUnit->isInline()) {
 //            return new CallStatementInline(function, calleeUnit);
 //        }
 
         return new CallStatementRaw(calleeUnit->compile(), llvm);
     }
 
     //require default variant if no static decision made
     assert(variantDefault);
 
     llvm::Function* functionVariantDefault = this->pass->getFunctionUnit(*variantDefault)->compile();
     llvm::Value* resultFn = function->contextCompiler.findFunction(calleeName, functionVariantDefault, scopeCaller);
     llvm::PointerType *resultPTy = cast<llvm::PointerType>(resultFn->getType());
     llvm::FunctionType *resultFTy = cast<llvm::FunctionType>(resultPTy->getElementType());
     return new CallStatementRaw(resultFn, resultFTy, llvm);
 }
 
-void
-CodeScopeUnit::bindArg(llvm::Value* value, std::string&& alias)
-{
-    //reset cached compiled value if any
-    raw = nullptr;
 
-    //ensure existing of an alias
-    assert(scope->__identifiers.count(alias));
 
-    //memorize new value for an alias
-    VID id = scope->__identifiers.at(alias);
-    __rawVars[id] = value;
-}
+//DISABLEDFEATURE transformations
+//    if (pass->transformations->isAcceptable(expr)){
+//        return pass->transformations->transform(expr, result, ctx);
+//    }
 
 llvm::Value*
-CodeScopeUnit::process(const Expression& expr, const std::string& hintVarDecl){
-
-    Context ctx{this, this->function, this->pass};
-
-    if (pass->targetInterpretation->isAcceptable(expr)){
-        return pass->targetInterpretation->compile(expr, ctx);
-    }
-
-    llvm::Value* result = processLowlevel(expr, hintVarDecl);
-
-    if (pass->transformations->isAcceptable(expr)){
-        return pass->transformations->transform(expr, result, ctx);
-    }
-
-    return result;
-}
-
-llvm::Value*
-CodeScopeUnit::processLowlevel(const Expression& expr, const std::string& hintVarDecl){
+BasicCodeScopeUnit::process(const Expression& expr, const std::string& hintVarDecl){
 #define DEFAULT(x) (hintVarDecl.empty()? x: hintVarDecl)
     llvm::Value *left; llvm::Value *right;
     LLVMLayer& l = *pass->man->llvm;
     xreate::compilation::Advanced instructions = xreate::compilation::Advanced({this, function, pass});
 
     switch (expr.op) {
         case Operator::ADD: case Operator::SUB: case Operator::MUL:
         case Operator::DIV: case Operator::EQU: case Operator::LSS:
         case Operator::GTR: case Operator::NE:  case Operator::LSE:
         case Operator::GTE:
 
             assert(expr.__state == Expression::COMPOUND);
             assert(expr.operands.size() == 2);
 
             left = process(expr.operands[0]);
             right = process(expr.operands[1]);
 
             //SECTIONTAG types/convert binary operation
            	right =	doAutomaticTypeConversion(right, left->getType(), l.builder);
             break;
 
         default:;
     }
 
     switch (expr.op) {
         case Operator::ADD:
             return l.builder.CreateAdd(left, right, DEFAULT("tmp_add"));
             break;
 
         case Operator::SUB:
             return l.builder.CreateSub(left, right, DEFAULT("tmp_sub"));
             break;
 
         case Operator::MUL:
             return l.builder.CreateMul(left, right, DEFAULT("tmp_mul"));
             break;
 
         case Operator::DIV:
             return l.builder.CreateSDiv(left, right, DEFAULT("tmp_div"));
             break;
 
         case Operator::EQU:
             if (left->getType()->isIntegerTy()) return l.builder.CreateICmpEQ(left, right, DEFAULT("tmp_equ"));
             if (left->getType()->isFloatingPointTy()) return l.builder.CreateFCmpOEQ(left, right, DEFAULT("tmp_equ"));
             break;
 
         case Operator::NE:
             return l.builder.CreateICmpNE(left, right, DEFAULT("tmp_ne"));
             break;
 
         case Operator::LSS:
             return l.builder.CreateICmpSLT(left, right, DEFAULT("tmp_lss"));
             break;
 
         case Operator::LSE:
             return l.builder.CreateICmpSLE(left, right, DEFAULT("tmp_lse"));
             break;
 
         case Operator::GTR:
             return l.builder.CreateICmpSGT(left, right, DEFAULT("tmp_gtr"));
             break;
 
         case Operator::GTE:
             return l.builder.CreateICmpSGE(left, right, DEFAULT("tmp_gte"));
             break;
 
         case Operator::NEG:
             left = process(expr.operands[0]);
             return l.builder.CreateNeg(left, DEFAULT("tmp_neg"));
             break;
 
         case Operator::CALL: {
             assert(expr.__state == Expression::COMPOUND);
 
             std::string nameCallee = expr.getValueString();
             shared_ptr<CallStatement> callee(findFunction(nameCallee));
 
             //prepare arguments
             std::vector<llvm::Value *> args;
             args.reserve(expr.operands.size());
 
             std::transform(expr.operands.begin(), expr.operands.end(), std::inserter(args, args.end()),
 				[this](const Expression &operand) {
 					return process(operand);
 				}
             );
 
             ScopePacked outerScopeId = pass->man->clasp->pack(this->scope);
 
             //TASK a) refactor CALL/ADHOC/find function
             //SECTIONTAG late-context propagation arg
             size_t calleeDemandSize = pass->queryContext->getFunctionDemand(nameCallee).size();
             if (calleeDemandSize){
                 DefaultFunctionUnit* function = dynamic_cast<DefaultFunctionUnit*>(this->function);
             	llvm::Value* argLateContext = function->contextCompiler.compileContextArgument(nameCallee, outerScopeId);
             	args.push_back(argLateContext);
             }
 
             return (*callee)(move(args), DEFAULT("res_"+nameCallee));
         }
 
         case Operator::IF:
         {
         	return instructions.compileIf(expr, DEFAULT("tmp_if"));
         }
 
         case Operator::SWITCH:
         {
         	return instructions.compileSwitch(expr, DEFAULT("tmp_switch"));
         }
 
         case Operator::LOOP_CONTEXT:
         {
-        	return instructions.compileLoopContext(expr, DEFAULT("tmp_loop"));
+            assert(false);
+            return nullptr;
+            //return instructions.compileLoopContext(expr, DEFAULT("tmp_loop"));
         }
 
         case Operator::LOGIC_AND: {
         	assert(expr.operands.size() == 1);
         	return process (expr.operands[0]);
         }
 
         case Operator::LIST:
         {
            return instructions.compileListAsSolidArray(expr, DEFAULT("tmp_list"));
         };
 
         case Operator::LIST_RANGE:
         {
             assert(false); //no compilation phase for a range list
           //  return InstructionList(this).compileConstantArray(expr, l, hintRetVar);
         };
 
         case Operator::LIST_NAMED:
         {
             typedef Expanded<TypeAnnotation> ExpandedType;
 
             ExpandedType tyRaw = l.ast->expandType(expr.type);
 
             const std::vector<string> fields = (tyRaw.get().__operator == TypeOperator::CUSTOM)?
                 l.layerExtern->getStructFields(l.layerExtern->lookupType(tyRaw.get().__valueCustom))
                 : tyRaw.get().fields;
 
             std::map<std::string, size_t> indexFields;
             for(size_t i=0, size = fields.size(); i<size; ++i){
                 indexFields.emplace(fields[i], i);
             }
 
             llvm::StructType* tyRecord = llvm::cast<llvm::StructType>(l.toLLVMType(tyRaw));
             llvm::Value* record = llvm::UndefValue::get(tyRecord);
 
             for (size_t i=0; i<expr.operands.size(); ++i){
                 const Expression& operand = expr.operands.at(i);
                 unsigned int fieldId = indexFields.at(expr.bindings.at(i));
 
                 llvm::Value* result = 0;
 
 //TODO Null ad hoc Llvm implementation
 //                if (operand.isNone()){
 //                    llvm::Type* tyNullField = tyRecord->getElementType(fieldId);
 //                    result = llvm::UndefValue::get(tyNullField);
 //
 //                } else {
                     result = process(operand);
 //                }
 
                 assert (result);
                 record = l.builder.CreateInsertValue(record, result, llvm::ArrayRef<unsigned>({fieldId}));
             }
 
             return record;
         };
 
 
 
         case Operator::MAP:
         {
             assert(expr.blocks.size());
             return instructions.compileMapSolidOutput(expr, DEFAULT("map"));
         };
 
         case Operator::FOLD:
         {
             return instructions.compileFold(expr, DEFAULT("fold"));
         };
 
         case Operator::FOLD_INF:
         {
             return instructions.compileFoldInf(expr, DEFAULT("fold"));
         };
 
         case Operator::INDEX:
         {
                 //TODO allow multiindex
-            assert(expr.operands.size()==1);
-            const std::string &ident = expr.getValueString();
-            Symbol s = scope->findSymbol(ident);
-            const TypeAnnotation& t = CodeScope::findDeclaration(s).type;
-            const ExpandedType& t2 = pass->man->root->expandType(t);
-            llvm::Value* aggr  = compileSymbol(s, ident);
+            assert(expr.operands.size()==2);
+            assert(expr.operands[0].__state == Expression::IDENT);
+
+            const std::string& hintIdent= expr.operands[0].getValueString();
+            Symbol s = Attachments::get<Symbol>(expr.operands[0]);
+            const ExpandedType& t2 = pass->man->root->expandType(CodeScope::getDeclaration(s).type);
+
+            llvm::Value* aggr  = processSymbol(s, hintIdent);
 
             switch (t2.get().__operator)
             {
                 case TypeOperator::STRUCT: case TypeOperator::CUSTOM:
                 {
-                    Expression idx = expr.operands.at(0);
+                    const Expression& idx = expr.operands.at(1);
                     assert(idx.__state == Expression::STRING);
                     std::string idxField = idx.getValueString();
 
                     return instructions.compileStructIndex(aggr, t2, idxField);
                 };
 
                 case TypeOperator::ARRAY: {
                     std::vector<llvm::Value*> indexes;
-                    std::transform(expr.operands.begin(), expr.operands.end(), std::inserter(indexes, indexes.end()),
-                                   [this] (const Expression& op){
-                                       return process(op);
-                                   }
+                    std::transform(++expr.operands.begin(), expr.operands.end(), std::inserter(indexes, indexes.end()),
+                        [this] (const Expression& op){
+                            return process(op);
+                        }
                     );
 
-                    return instructions.compileArrayIndex(aggr, indexes, DEFAULT(string("el_") + ident));
+                    return instructions.compileArrayIndex(aggr, indexes, DEFAULT(string("el_") + hintIdent));
                 };
 
                 default:
                     assert(false);
             }
         };
 
         	//SECTIONTAG adhoc actual compilation
                 //TODO a) make sure that it's correct: function->adhocImplementation built for Entry scope and used in another scope
         case Operator::ADHOC: {
             DefaultFunctionUnit* function = dynamic_cast<DefaultFunctionUnit*>(this->function);
             assert(function->adhocImplementation && "Adhoc implementation not found");
-            string comm = expr.operands[0].getValueString();
+            const Expression& comm = AdhocExpression(expr).getCommand();
 
-            CodeScope* scope = function->adhocImplementation->getImplementationForCommand(comm);
-            CodeScopeUnit* unitScope = function->getScopeUnit(scope);
+            CodeScope* scope = function->adhocImplementation->getCommandImplementation(comm);
+            AbstractCodeScopeUnit* unitScope = function->getScopeUnit(scope);
 
             //SECTIONTAG types/convert ADHOC ret convertation
             llvm::Type* resultTy = l.toLLVMType( pass->man->root->expandType(function->adhocImplementation->getResultType()));
             return doAutomaticTypeConversion(unitScope->compile(), resultTy, l.builder);
         };
 
-        case Operator::SEQUENCE: {
-        	assert (expr.getOperands().size());
+        case Operator::CALL_INTRINSIC:{
+            const std::string op = expr.getValueString();
 
-        	llvm::Value* result;
-        	for(const Expression &op: expr.getOperands()){
-        		result = process(op, "");
-        	}
+            if (op == "copy") {
+                llvm::Value* result = process(expr.getOperands().at(0));
 
-			return result;
+                auto decoratorVersions = Decorators<VersionsScopeDecoratorTag>::getInterface(this);
+                llvm::Value* storage = decoratorVersions->processIntrinsicInit(result->getType());
+                decoratorVersions->processIntrinsicCopy(result, storage);
+
+                return l.builder.CreateLoad(storage, hintVarDecl);
+            }
+
+            assert(false && "undefined intrinsic");
         }
 
         case Operator::NONE:
             assert(expr.__state != Expression::COMPOUND);
 
             switch (expr.__state) {
                 case Expression::IDENT: {
-                    const std::string &ident = expr.getValueString();
-                    Symbol s = scope->findSymbol(ident);
-                    return compileSymbol(s, ident);
+                    Symbol s = Attachments::get<Symbol>(expr);
+                    return processSymbol(s, expr.getValueString());
                 }
 
                 case Expression::NUMBER: {
+                    llvm::Type* typConst;
+
+                    if (expr.type.isValid()){
+                        typConst = l.toLLVMType(pass->man->root->expandType(expr.type));
+
+                    } else {
+                        typConst = llvm::Type::getInt32Ty(llvm::getGlobalContext());
+                    }
+
                     int literal = expr.getValueDouble();
-                    return llvm::ConstantInt::get(llvm::Type::getInt32Ty(llvm::getGlobalContext()), literal);
+                    return llvm::ConstantInt::get(typConst, literal);
                 }
 
                 case Expression::STRING: {
                     return instructions.compileConstantStringAsPChar(expr.getValueString(), DEFAULT("tmp_str"));
                 };
 
                 case Expression::VARIANT: {
                 	const ExpandedType& typVariant = pass->man->root->expandType(expr.type);
                 	llvm::Type* typRaw = l.toLLVMType(typVariant);
                 	int value = expr.getValueDouble();
                     return llvm::ConstantInt::get(typRaw, value);
                 }
 
                 default: {
                     break;
                 }
             };
 
             break;
 
         default: break;
 
     }
 
     assert(false);
     return 0;
 }
 
 llvm::Value*
-CodeScopeUnit::compile(const std::string& hintBlockDecl){
-    if (raw != nullptr) return raw;
-
-
+BasicCodeScopeUnit::compile(const std::string& hintBlockDecl){
     if (!hintBlockDecl.empty()) {
         llvm::BasicBlock *block = llvm::BasicBlock::Create(llvm::getGlobalContext(), hintBlockDecl, function->raw);
         pass->man->llvm->builder.SetInsertPoint(block);
     }
 
-    raw = process(scope->getBody());
-    return raw;
+    Symbol symbScope = Symbol{ScopedSymbol::RetSymbol, scope};
+    return processSymbol(symbScope);
 }
 
-llvm::Value*
-CodeScopeUnit::compileSymbol(const Symbol& s, std::string hintRetVar)
-{
-    CodeScope* scope = s.scope;
-    CodeScopeUnit* self = function->getScopeUnit(scope);
-
-    if (self->__rawVars.count(s.identifier))     {
-        return self->__rawVars[s.identifier];
-    }
-
-    //compilation transformations could override symbol declarations.
-    Expression declaration = CodeScope::findDeclaration(s);
-    if (!declaration.isDefined()){
-        if (self->__declarationsOverriden.count(s.identifier)){
-            declaration = self->__declarationsOverriden[s.identifier];
-
-        } else {
-            assert(false); //in case of bindings there should be raws already.
-        }
-    }
-
-    return self->__rawVars[s.identifier] = self->process(declaration, hintRetVar);
-}
-
-
-
 llvm::Function*
 FunctionUnit::compile(){
     if (raw != nullptr) return raw;
 
     LLVMLayer* llvm = pass->man->llvm;
     llvm::IRBuilder<>& builder = llvm->builder;
 
     string&& functionName = prepareName();
     std::vector<llvm::Type*>&& types = prepareArguments();
     llvm::Type* expectedResultType = prepareResult();
 
     llvm::FunctionType *ft = llvm::FunctionType::get(expectedResultType, types, false);
     raw = llvm::cast<llvm::Function>(llvm->module->getOrInsertFunction(functionName, ft));
     prepareBindings();
 
 
     const std::string&blockName =  "entry";
     llvm::BasicBlock* blockCurrent = builder.GetInsertBlock();
 
     llvm::Value* result =getScopeUnit(function->__entry)->compile(blockName);
     assert(result);
 
     //SECTIONTAG types/convert function ret value
     builder.CreateRet(doAutomaticTypeConversion(result, expectedResultType, llvm->builder));
 
     if (blockCurrent){
     	builder.SetInsertPoint(blockCurrent);
     }
 
     llvm->moveToGarbage(ft);
     return raw;
 }
 
-CodeScopeUnit*
+AbstractCodeScopeUnit*
 FunctionUnit::getScopeUnit(CodeScope* scope){
     if (!scopes.count(scope)){
-    	CodeScopeUnit* unit = new CodeScopeUnit(scope, this, pass);
-        scopes.emplace(scope, std::unique_ptr<CodeScopeUnit>(unit));
+    	AbstractCodeScopeUnit* unit = new DefaultScopeUnit(scope, this, pass);
+        scopes.emplace(scope, std::unique_ptr<AbstractCodeScopeUnit>(unit));
     }
 
     return scopes.at(scope).get();
 }
 
-CodeScopeUnit*
+AbstractCodeScopeUnit*
 FunctionUnit::getEntry(){
 	return getScopeUnit(function->getEntryScope());
 }
 
-CodeScopeUnit*
+AbstractCodeScopeUnit*
 FunctionUnit::getScopeUnit(ManagedScpPtr scope){
     return getScopeUnit(&*scope);
 }
 
 FunctionUnit*
 CompilePass::getFunctionUnit(const ManagedFnPtr& function){
 	unsigned int id = function.id();
 
     if (!functions.count(id)){
     	FunctionUnit* unit = new DefaultFunctionUnit(function, this);
         functions.emplace(id, unit);
         return unit;
     }
 
     return functions.at(id);
 }
 
 void
 CompilePass::run(){
-    transformations = new Transformations(this);
-    transformations->registerTransformer(new TransformerSaturation(transformations));
-
+    managerTransformations = new TransformationsManager();
     targetInterpretation = new TargetInterpretation(this->man->root, this);
-
     queryContext = reinterpret_cast<ContextQuery*> (man->clasp->getQuery(QueryId::ContextQuery));
 
     //Find out main function;
     ClaspLayer::ModelFragment model = man->clasp->query(Config::get("function-entry"));
     assert(model && "Error: No entry function found");
     assert(model->first != model->second && "Error: Ambiguous entry function");
 
     string nameMain = std::get<0>(ClaspLayer::parse<std::string>(model->first->second));
     FunctionUnit* unitMain = getFunctionUnit(man->root->findFunction(nameMain));
     entry = unitMain->compile();
 }
 
 llvm::Function*
 CompilePass::getEntryFunction(){
 	assert(entry);
 	return entry;
 }
 
 void
 CompilePass::prepareQueries(ClaspLayer* clasp){
 	clasp->registerQuery(new containers::Query(), QueryId::ContainersQuery);
 	clasp->registerQuery(new ContextQuery(), QueryId::ContextQuery);
-}
-
-//CODESCOPE COMPILATION PHASE
-
-
-//FIND SYMBOL(compilation phase):
-    //if (!forceCompile)
-    //{
-    //    return result;
-    //}
-
-    //    //search in already compiled vars
-    //if (__rawVars.count(vId))
-    //{
-    //    return result;
-    //}
-
-    //if (!__declarations.count(vId)) {
-    //    //error: symbol is uncompiled scope arg
-    //    assert(false);
-    //}
-
-    //const Expression& e = __declarations.at(vId);
-
-    //__rawVars[vId] = process(e, l, name);
-
-
-//FIND FUNCTION
-    //llvm::Function*
-    //CompilePass::findFunction(const std::string& name){
-    //    ManagedFnPtr calleeFunc = man->root->findFunction(name);
-    //    assert(calleeFunc.isValid());
-
-    //    return  nullptr;
-    //}
-
+}
\ No newline at end of file
diff --git a/cpp/src/pass/compilepass.h b/cpp/src/pass/compilepass.h
index 416de88..2c84988 100644
--- a/cpp/src/pass/compilepass.h
+++ b/cpp/src/pass/compilepass.h
@@ -1,155 +1,167 @@
 #ifndef COMPILEPASS_H
 #define COMPILEPASS_H
 
 #include "abstractpass.h"
+
 #include "llvm/IR/Function.h"
 
 namespace xreate {
 	class AdhocScheme;
 	class ClaspLayer;
 	class ContextQuery;
         class LLVMLayer;
 }
 
 //namespace llvm {
 //    class Function;
 //    class Value;
 //    class Type;
 //}
 
 namespace xreate {
 
 class CompilePass;
 
 namespace compilation {
 
-class CodeScopeUnit;
+class AbstractCodeScopeUnit;
 class FunctionUnit;
 
 class TargetInterpretation;
+class TransformationsManager;
 
 
 struct Context{
-    CodeScopeUnit* scope;
+    AbstractCodeScopeUnit* scope;
     FunctionUnit* function;
     CompilePass* pass;
 };
 
 class CallStatement {
 public:
     virtual llvm::Value* operator() (std::vector<llvm::Value *>&& args, const std::string& hintDecl="") = 0;
 };
 
 class CallStatementRaw: public CallStatement{
 public:
     CallStatementRaw(llvm::Function* callee, LLVMLayer* l)
         : __callee(callee), __calleeTy(callee->getFunctionType()), llvm(l) {}
     CallStatementRaw(llvm::Value* callee, llvm::FunctionType* ty, LLVMLayer* l)
         : __callee(callee), __calleeTy(ty), llvm(l) {}
     llvm::Value* operator() (std::vector<llvm::Value *>&& args, const std::string& hintDecl="");
         
 private:
     llvm::Value* __callee;        
     llvm::FunctionType* __calleeTy;
     
     LLVMLayer* llvm;
 };
 
-class CodeScopeUnit {
+class AbstractCodeScopeUnit{
 public:
-    CodeScopeUnit(CodeScope* codeScope, FunctionUnit* f, CompilePass* compilePass);
-
-    void bindArg(llvm::Value* value, std::string&& alias);
-    void overrideDeclaration(const Symbol binding, Expression&& declaration);
-    std::map<VID,llvm::Value*> __rawVars;
-
-    void reset(){raw = nullptr;}
-    llvm::Value* compile(const std::string& hintBlockDecl="");
-    llvm::Value* compileSymbol(const Symbol& s, std::string hintRetVar="");
-    llvm::Value* process(const Expression& expr, const std::string& hintVarDecl="");
-    llvm::Value* processLowlevel(const Expression& expr, const std::string& hintVarDecl="");
+    CompilePass* const pass;
+    FunctionUnit* const function;
+    CodeScope* const scope;
     
-    CodeScope* scope;
+    AbstractCodeScopeUnit(CodeScope* codeScope, FunctionUnit* f, CompilePass* compilePass);
+    ~AbstractCodeScopeUnit(){}
 
-private:
-    CompilePass* pass;
-    llvm::Value* raw = nullptr;
-    FunctionUnit* function;
-    std::unordered_map<VID, Expression> __declarationsOverriden;
+    virtual llvm::Value* compile(const std::string& hintBlockDecl="")=0;
+    virtual llvm::Value* processSymbol(const Symbol& s, std::string hintRetVar="")=0;
+    virtual llvm::Value* process(const Expression& expr, const std::string& hintVarDecl="")=0;
     
+    virtual void bindArg(llvm::Value* value, std::string&& alias)=0;
+    virtual void bindArg(llvm::Value* value, const ScopedSymbol& s)=0;
+
+protected:
+    virtual CallStatement* findFunction(const std::string& callee)=0;
+};
 
+class BasicCodeScopeUnit: public AbstractCodeScopeUnit{
+public:
+    BasicCodeScopeUnit(CodeScope* codeScope, FunctionUnit* f, CompilePass* compilePass);
+    ~BasicCodeScopeUnit(){}
+
+    llvm::Value* processSymbol(const Symbol& s, std::string hintRetVar="");
+    llvm::Value* process(const Expression& expr, const std::string& hintVarDecl="");
+    llvm::Value* compile(const std::string& hintBlockDecl="");
+    
+protected:
     CallStatement* findFunction(const std::string& callee);
 };
 
+
+
 class IFunctionDecorator {
 protected:
     virtual std::string prepareName() = 0;
     virtual std::vector<llvm::Type*>  prepareArguments() = 0;
     virtual llvm::Type* prepareResult() = 0;
     virtual llvm::Function::arg_iterator prepareBindings() = 0;
     virtual ~IFunctionDecorator(){}
 };
 
 class FunctionUnit: public IFunctionDecorator{
 public:
    FunctionUnit(ManagedFnPtr f, CompilePass* p)
     : function(f), pass(p) {}
 
     llvm::Function* compile();
 
-    CodeScopeUnit* getEntry();
-    CodeScopeUnit* getScopeUnit(CodeScope* scope);
-    CodeScopeUnit* getScopeUnit(ManagedScpPtr scope);
+    AbstractCodeScopeUnit* getEntry();
+    AbstractCodeScopeUnit* getScopeUnit(CodeScope* scope);
+    AbstractCodeScopeUnit* getScopeUnit(ManagedScpPtr scope);
 
     ManagedFnPtr function;
     llvm::Function* raw = nullptr;
     
 protected:
     CompilePass* pass=nullptr;
     
 private:
-    std::map<CodeScope*, std::unique_ptr<CodeScopeUnit>> scopes;
+    std::map<CodeScope*, std::unique_ptr<AbstractCodeScopeUnit>> scopes;
 };
 
 class BasicFunctionDecorator: public FunctionUnit{
 public:
     BasicFunctionDecorator(ManagedFnPtr f, CompilePass* p)
     : FunctionUnit(f, p) {}
 
 protected:
     std::string prepareName();
     virtual std::vector<llvm::Type*>  prepareArguments();
     virtual llvm::Type* prepareResult();
     virtual llvm::Function::arg_iterator prepareBindings();
 };
 
-    class Transformations;
 } // end of namespace `xreate::compilation`
 
 class CompilePass : public AbstractPass<void> {
-	friend class LateContextCompiler;
-	friend class LateContextCompiler2;
-	friend class compilation::CodeScopeUnit;
-	friend class compilation::FunctionUnit;
+    friend class LateContextCompiler;
+    friend class LateContextCompiler2;
+    friend class compilation::BasicCodeScopeUnit;
+    friend class compilation::FunctionUnit;
 
 public:
-    compilation::Transformations* transformations;
+    compilation::TransformationsManager* managerTransformations;
+    compilation::TargetInterpretation* targetInterpretation;
     
     CompilePass(PassManager* manager): AbstractPass<void>(manager) {}
     compilation::FunctionUnit* getFunctionUnit(const ManagedFnPtr& function);
     void run() override;
     llvm::Function* getEntryFunction();
     static void prepareQueries(ClaspLayer* clasp);
+    
+    
 private:
     //TODO free `functions` in destructor
     std::map<unsigned int, compilation::FunctionUnit*> functions;
     llvm::Function* entry = 0;
 
     ContextQuery* queryContext;
-    compilation::TargetInterpretation* targetInterpretation;
     
 };
 
 }
 
 #endif // COMPILEPASS_H
diff --git a/cpp/src/pass/dfapass.cpp b/cpp/src/pass/dfapass.cpp
index 7a019e1..49a957a 100644
--- a/cpp/src/pass/dfapass.cpp
+++ b/cpp/src/pass/dfapass.cpp
@@ -1,240 +1,262 @@
 #include "pass/dfapass.h"
 #include "analysis/dfagraph.h"
 
 #include "passmanager.h"
 #include "clasplayer.h"
 
 #include <boost/format.hpp>
 
 using namespace std;
 using namespace xreate::analysis;
 
-namespace xreate{
+namespace xreate {
 
-DFAPass::DFAPass(PassManager* manager)
-        : AbstractPass(manager)
-            , __context{new xreate::analysis::DFAGraph(manager->clasp)}
-            , clasp(manager->clasp)
-{}
+    class DfaExpressionProcessor {
+        std::vector<xreate::analysis::SymbolNode> operands;
+        std::vector<SymbolPacked> blocks;
 
-SymbolNode
-DFAPass::process(CodeScope* scope, PassContext context, const std::string& hintBlockDecl){
-	const SymbolNode& retActual = AbstractPass::process(scope, context, hintBlockDecl);
-	const SymbolPacked& retFormal{0, clasp->pack(scope)};
-	__context.graph->addConnection(retFormal, retActual, DFGConnection::STRONG);
+        const Expression expression;
+        xreate::analysis::SymbolNode result;
+        DFAPass * const pass;
+        const PassContext context;
 
-	return retFormal;
-}
-
-SymbolNode
-DFAPass::process(const Expression& expression, PassContext context, const std::string& decl)
-{
-    ExpressionCache cache;
-
-    if (!decl.empty()){
-        cache.result = clasp->pack(context.scope->findSymbol(decl), context.function->getName() + ":" + decl);
-
-    } else if (!expression.tags.empty()) {
-        cache.result = __context.graph->createAnonymousSymbol(clasp->pack(context.scope));
+    public:
+        DfaExpressionProcessor(const Expression& expr, SymbolNode resInitial, DFAPass * const p, const PassContext c)
+        : expression(expr), result(resInitial), pass(p), context(c) {
 
-    } else {
-        cache.result = SymbolTransient{{}, clasp->pack(context.scope)};
-    }
-
-    cache.operands.reserve(expression.getOperands().size());
-    for (const Expression &op: expression.getOperands()) {
-        cache.operands.push_back(process(op, context));
-    }
+            operands.reserve(expression.getOperands().size());
+            for (const Expression &op : expression.getOperands()) {
+                SymbolAnonymous symbOp(op.id);
 
-    cache.blocks.reserve(expression.blocks.size());
-    for (CodeScope* scope: expression.blocks) {
-        cache.blocks.push_back(process(scope, context));
-    }
+                operands.push_back(DfaExpressionProcessor(op, symbOp, pass, context).process());
+            }
 
-    if (expression.__state == Expression::COMPOUND) {
-        processCompoundOp(expression, context, cache, decl);
+            blocks.reserve(expression.blocks.size());
+            for (CodeScope* scope : expression.blocks) {
+                blocks.push_back(pass->process(scope, context));
+            }
+        }
 
-    } else {
-        processElementaryOp(expression, context, cache, decl);
-    }
+        SymbolNode
+        process() {
+            if (expression.__state == Expression::COMPOUND) {
+                processCompoundOp();
 
-    applyDependencies(expression, context, cache, decl);
-    applyStaticAnnotations(expression, context, cache, decl);
-    applySignatureAnnotations(expression, context, cache, decl);
-    applyInPlaceAnnotations(expression, context, cache, decl);
+            } else {
+                processElementaryOp();
+            }
 
-//TODO Null ad hoc DFG implementation
-//    if (expression.isNone()){
-//        return SymbolTransient{{Atom<Identifier_t>(Config::get("clasp.nonevalue"))}};
-//    }
+            applySignatureAnnotations();
+            applyInPlaceAnnotations();
 
-    //non initialized(SymbolInvalid) value
+            return result;
+        }
 
-    return cache.result;
-}
+    private:
+        void
+        processElementaryOp() {
+            switch (expression.__state) {
+                case Expression::IDENT:
+                {
+                    SymbolPacked symbFrom = pass->processSymbol(Attachments::get<Symbol>(expression), context, expression.getValueString());
 
+                    SymbolPacked* symbTo = boost::get<SymbolPacked>(&result);
+                    if (symbTo) {
+                        pass->__context.graph->addConnection(*symbTo, SymbolNode(symbFrom), DFGConnection::STRONG);
 
-void
-DFAPass::processElementaryOp(const Expression& expression, PassContext context, DFAPass::ExpressionCache& cache, const std::string& varDecl){
-    switch(expression.__state) {
-        case Expression::IDENT: {
-            std::string identifier = expression.getValueString();
+                    } else {
+                        result = SymbolNode(symbFrom);
+                    }
 
-            SymbolNode nodeFrom = AbstractPass::process(expression, context, identifier);
-            if (SymbolPacked* nodeTo = boost::get<SymbolPacked>(&cache.result)){
-                __context.graph->addConnection(*nodeTo, nodeFrom, DFGConnection::STRONG);
+                    break;
+                }
 
-            } else {
-     //           cache.result = nodeFrom;
+                default: break;
             }
-
-            break;
         }
 
-        default: break;
-    }
-}
-
-void
-DFAPass::processCompoundOp(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& varDecl){
-
-    switch(expression.op) {
-            //apply calling relation
-        case Operator::CALL: {
-            const string &nameCalleeFunction = expression.getValueString();
-
-            	//TODO implement processFnCall/Uncertain
-            list<ManagedFnPtr> variantsCalleeFunction = man->root->getFunctionVariants(nameCalleeFunction);
-            if (variantsCalleeFunction.size()!=1) return;
-            ManagedFnPtr function= variantsCalleeFunction.front();
-
-            	// set calling relations:
-            CodeScope *scopeRemote = function->getEntryScope();
-            std::vector<SymbolNode>::iterator nodeActual = cache.operands.begin();
-            for (const std::string &identFormal: scopeRemote->__bindings) {
-                const Symbol &symbolFormal = scopeRemote->findSymbol(identFormal);
-                __context.graph->addConnection(clasp->pack(symbolFormal, nameCalleeFunction + ":" + identFormal), *nodeActual, DFGConnection::WEAK);
-                ++nodeActual;
+        void
+        processCompoundOp() {
+            switch (expression.op) {
+
+                    //DEBT provide CALL processing
+                    //            case Operator::CALL: {
+                    //                const string &nameCalleeFunction = expression.getValueString();
+                    //
+                    //                    //TODO implement processFnCall/Uncertain
+                    //                list<ManagedFnPtr> variantsCalleeFunction = man->root->getFunctionVariants(nameCalleeFunction);
+                    //                if (variantsCalleeFunction.size()!=1) return;
+                    //                ManagedFnPtr function= variantsCalleeFunction.front();
+                    //
+                    //                    // set calling relations:
+                    //                CodeScope *scopeRemote = function->getEntryScope();
+                    //                std::vector<SymbolNode>::iterator nodeActual = cache.operands.begin();
+                    //                for (const std::string &identFormal: scopeRemote->__bindings){
+                    //                    const ScopedSymbol symbolFormal{scopeRemote->__identifiers.at(identFormal), VERSION_NONE};
+                    //
+                    //                    __context.graph->addConnection(clasp->pack(Symbol{symbolFormal, scopeRemote}, nameCalleeFunction + ":" + identFormal), *nodeActual, DFGConnection::WEAK);
+                    //                    ++nodeActual;
+                    //                }
+                    //
+                    //                //TODO add RET connection
+                    //                break;
+                    //            }
+
+                    //MAP processing: apply PROTOTYPE relation
+                case Operator::MAP:
+                {
+                    SymbolNode nodeFrom = operands.front();
+
+                    SymbolPacked* nodeTo = boost::get<SymbolPacked>(&result);
+                    assert(nodeTo);
+
+                    pass->__context.graph->addConnection(*nodeTo, nodeFrom, DFGConnection::PROTOTYPE);
+                    break;
+                }
+
+                default: break;
             }
-
-            	//TODO represent RET connection
-            break;
         }
 
-            //apply PROTOTYPE relation
-        case Operator::MAP: {
-            SymbolNode nodeFrom= cache.operands.front();
+        void
+        applySignatureAnnotations() {
+            if (pass->__signatures.count(expression.op)) {
+                const Expression &scheme = pass->__signatures.at(expression.op);
 
-            SymbolPacked* nodeFromPacked = boost::get<SymbolPacked>(&nodeFrom);
-            assert(nodeFromPacked);
 
-            SymbolPacked* nodeTo = boost::get<SymbolPacked>(&cache.result);
-            assert(nodeTo);
 
-            __context.graph->addConnection(*nodeTo, *nodeFromPacked, DFGConnection::PROTOTYPE);
-            break;
-        }
+                std::vector<SymbolNode>::iterator arg = operands.begin();
+                std::vector<Expression>::const_iterator tag = scheme.getOperands().begin();
 
-        default: break;
-    }
-}
+                //Assign scheme RET annotation
+                Expression retTag = *scheme.getOperands().begin();
+                if (retTag.__state != Expression::INVALID) {
+                    pass->__context.graph->addAnnotation(result, move(retTag));
+                }
 
-void
-DFAPass::applyDependencies(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl){
-    for (SymbolNode &op: cache.operands) {
-        __context.graph->addDependencyConnection(cache.result, op);
-    }
+                ++tag;
+                while (tag != scheme.getOperands().end()) {
+                    if (tag->__state != Expression::INVALID) {
+                        pass->__context.graph->addAnnotation(*arg, Expression(*tag));
+                    }
 
-    for (SymbolNode &block: cache.blocks) {
-        __context.graph->addDependencyConnection(cache.result, block);
-    }
+                    ++arg;
+                    ++tag;
+                }
+
+                //  TODO add possibility to have specific signature for a particular function
+                //        if (expression.op == Operator::CALL || expression.op == Operator::INDEX){
+                //            string caption = expression.getValueString();
+                //            operands.push_back(process(Expression(move(caption)), context, ""));
+                //        }
 
-    switch(expression.__state) {
-        case Expression::IDENT: {
-            const string& identName = expression.getValueString();
 
-            SymbolNode identSymbol = clasp->pack(context.scope->findSymbol(identName), context.function->getName() + ":" + identName);
-            __context.graph->addDependencyConnection(cache.result, identSymbol);
+            }
         }
 
-        default: break;
-    }
-}
+        void
+        applyInPlaceAnnotations() {
+            // write down in-place expression tags:
+            for (pair<std::string, Expression> tag : expression.tags) {
+                pass->__context.graph->addAnnotation(result, Expression(tag.second));
+            }
+        }
+    };
 
-void
-DFAPass::applyStaticAnnotations(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl){
 
-    switch(expression.__state) {
-        case Expression::NUMBER:
-        case Expression::STRING:
-            __context.graph->addAnnotation(cache.result, Expression(Atom<Identifier_t>("static")));
-            break;
+    DFAPass::DFAPass(PassManager* manager)
+    : AbstractPass(manager)
+    , __context{new xreate::analysis::DFAGraph(manager->clasp)}
+    , clasp(manager->clasp)
+    {}
 
-        default: break;
+    SymbolPacked
+    DFAPass::process(CodeScope* scope, PassContext context, const std::string& hintBlockDecl) {
+        const SymbolPacked& symbRet = AbstractPass::process(scope, context, hintBlockDecl);
+        return symbRet;
     }
-}
-
-void
-DFAPass::applySignatureAnnotations(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl){
-    if (__signatures.count(expression.op)) {
-        const Expression &scheme = __signatures.at(expression.op);
-
-        //TODO add possibility to specifi signature for a particular function
-//        if (expression.op == Operator::CALL || expression.op == Operator::INDEX){
-//            string caption = expression.getValueString();
-//            operands.push_back(process(Expression(move(caption)), context, ""));
-//        }
-
-        std::vector<SymbolNode>::iterator arg = cache.operands.begin();
-        std::vector<Expression>::const_iterator tag = ++scheme.getOperands().begin();
 
-        while (tag != scheme.getOperands().end()) {
-            if (tag->__state != Expression::INVALID) {
-                    __context.graph->addAnnotation(*arg, Expression(*tag));
-            }
-
-            ++arg; ++tag;
-        }
+    SymbolPacked
+    DFAPass::processSymbol(const Symbol& symbol, PassContext context, const std::string& hintSymbol) {
+        const Expression& declaration = CodeScope::getDeclaration(symbol);
+        const SymbolPacked& symbPacked = clasp->pack(symbol, hintSymbol);
+        DfaExpressionProcessor(declaration, symbPacked, this, context).process();
 
-        //TODO represent RET connection
-//        Expression retTag = *scheme.getOperands().begin();
-//        if (retTag.__state != Expression::INVALID) {
-//            __context.graph->addAnnotation(node, move(retTag));
-//        }
+        return symbPacked;
     }
-}
 
-void
-DFAPass::applyInPlaceAnnotations(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl){
-        // write down in-place expression tags:
-    for (pair<std::string, Expression> tag: expression.tags) {
-        __context.graph->addAnnotation(cache.result, Expression(tag.second));
+    void
+    DFAPass::run() {
+        init();
+        return AbstractPass::run();
     }
-}
-
-void
-DFAPass::run()
-{
-    init();
-    return AbstractPass::run();
-}
 
-void
-DFAPass::init()
-{
-    for (const Expression& scheme: man->root->__dfadata)
-    {
-        __signatures.emplace(scheme.op, scheme);
+    void
+    DFAPass::init() {
+        for (const Expression& scheme : man->root->__dfadata) {
+            __signatures.emplace(scheme.op, scheme);
+        }
     }
-}
 
-void DFAPass::finish()
-{
-    man->clasp->setDFAData(move(__context.graph));
-}
+    void
+    DFAPass::finish() {
+        clasp->setDFAData(move(__context.graph));
+    }
 
 template<>
-SymbolNode defaultValue(){return SymbolInvalid();};
-
+SymbolPacked defaultValue(){
+    assert(false);
 }
 
+} //xreate namespace
+
+
+
+    //DEBT represent VersionaPass in declarative form using applyDependencies
+    //    applyDependencies(expression, context, cache, decl);
+
+    //DEBT prepare static annotations and represent InterpretationPass in declarative form
+    //    applyStaticAnnotations(expression, context, cache, decl);
+
+
+
+    //TODO Null ad hoc DFG implementation/None symbol
+    //DISABLEDFEATURE None value
+    //    if (expression.isNone()){
+    //        return SymbolTransient{{Atom<Identifier_t>(Config::get("clasp.nonevalue"))}};
+    //    }
+
+    //   non initialized(SymbolInvalid) value
+
+    //void
+    //DFAPass::applyDependencies(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl){
+    //    for (SymbolNode &op: cache.operands) {
+    //        __context.graph->addDependencyConnection(cache.result, op);
+    //    }
+    //
+    //    for (SymbolNode &block: cache.blocks) {
+    //        __context.graph->addDependencyConnection(cache.result, block);
+    //    }
+    //
+    //    switch(expression.__state) {
+    //        case Expression::IDENT: {
+    //            SymbolNode identSymbol = clasp->pack(Attachments::get<Symbol>(expression), context.function->getName() + ":" + expression.getValueString());
+    //            __context.graph->addDependencyConnection(cache.result, identSymbol);
+    //        }
+    //
+    //        default: break;
+    //    }
+    //}
+
+    //void
+    //DFAPass::applyStaticAnnotations(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl){
+    //
+    //    switch(expression.__state) {
+    //        case Expression::NUMBER:
+    //        case Expression::STRING:
+    //            __context.graph->addAnnotation(cache.result, Expression(Atom<Identifier_t>("static")));
+    //            break;
+    //
+    //        default: break;
+    //    }
+    //}
\ No newline at end of file
diff --git a/cpp/src/pass/dfapass.h b/cpp/src/pass/dfapass.h
index cc26e8c..0bc50a4 100644
--- a/cpp/src/pass/dfapass.h
+++ b/cpp/src/pass/dfapass.h
@@ -1,49 +1,39 @@
 // Data Flow Graph determination pass
 
 #ifndef DFGPASS_H
 #define DFGPASS_H
 
 #include "abstractpass.h"
 #include "analysis/dfagraph.h"
 
 namespace xreate {
 
 class ClaspLayer;
+class DfaExpressionProcessor;
 
-class DFAPass : public AbstractPass<xreate::analysis::SymbolNode> {
+class DFAPass: public AbstractPass<SymbolPacked> {
+    friend class DfaExpressionProcessor;
+    
 public:
-    xreate::analysis::SymbolNode process(CodeScope* scope, PassContext context, const std::string& hintBlockDecl="") override;
-    xreate::analysis::SymbolNode process(const Expression& expression, PassContext context, const std::string& varDecl="") override;
-
     DFAPass(PassManager* manager);
+    
+    SymbolPacked processSymbol(const Symbol& symbol, PassContext context, const std::string& hintSymbol="") override;
+    SymbolPacked process(CodeScope* scope, PassContext context, const std::string& hintBlockDecl="") override;
 
     void init();
-    void run();
-    void finish();
+    void run() override;
+    void finish() override;
     
 private:
     struct 
     {
       xreate::analysis::DFAGraph* graph;
     } __context;
     
-    struct ExpressionCache{
-        std::vector<xreate::analysis::SymbolNode> operands;
-        std::vector<xreate::analysis::SymbolNode> blocks;
-        xreate::analysis::SymbolNode result;
-    };
-
     std::map<Operator, Expression> __signatures;		//DFA data for particular operators
     ClaspLayer* clasp;
-    
-    void processCompoundOp(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& varDecl="");
-    void processElementaryOp(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& varDecl="");
-    
-    void applyDependencies(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl);
-    void applyInPlaceAnnotations(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl);
-    void applySignatureAnnotations(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl);
-    void applyStaticAnnotations(const Expression& expression, PassContext context, ExpressionCache& cache, const std::string& decl);
-};
 };
 
+}; //end of xreate  namespace
+
 #endif
diff --git a/cpp/src/pass/interpretationpass.cpp b/cpp/src/pass/interpretationpass.cpp
index b4d399e..e75520f 100644
--- a/cpp/src/pass/interpretationpass.cpp
+++ b/cpp/src/pass/interpretationpass.cpp
@@ -1,406 +1,423 @@
 /*
  * File:   interpretationpass.cpp
  * Author: pgess
  *
  * Created on July 5, 2016, 5:21 PM
  */
 
 #include "pass/interpretationpass.h"
-#include "compilation/transformations.h"
+//#include "compilation/transformations.h"
 #include <compilation/targetinterpretation.h>
 #include "ast.h"
 //DEBT implement InterpretationPass purely in clasp
 //DEBT represent InterpretationPass as general type inference
 
 using namespace std;
 
 namespace xreate{
 
 enum InterpretationQuery{QUERY_INTR_ONLY, QUERY_CMPL_ONLY};
 
 template<>
 InterpretationResolution
 defaultValue<InterpretationResolution>(){
     return CMPL_ONLY;
 }
 
 InterpretationResolution
 unify(InterpretationResolution flag) {
     return flag;
 }
 
 template<typename FLAG_A, typename FLAG_B, typename... FLAGS>
 InterpretationResolution
 unify(FLAG_A flagA, FLAG_B flagB, FLAGS... flags) {
 
     if (flagA== ANY){
         return unify(flagB, flags...);
     }
 
     if (flagB == ANY) {
         return unify(flagA, flags...);
     }
 
     assert(flagA == flagB);
     return flagA;
 }
 
 namespace detail {
     template<InterpretationQuery FLAG_REQUIRED>
     bool checkConstraints(InterpretationResolution flag) {
         return (   (flag==INTR_ONLY && FLAG_REQUIRED == QUERY_INTR_ONLY)
                 || (flag==CMPL_ONLY && FLAG_REQUIRED == QUERY_CMPL_ONLY));
     }
 }
 
 template<InterpretationQuery FLAG_REQUIRED>
 bool checkConstraints(std::vector<InterpretationResolution>&& flags) {
     assert(flags.size());
 
     InterpretationResolution flag = flags.front();
     return detail::checkConstraints<FLAG_REQUIRED>(flag);
 }
 
 template<InterpretationQuery FLAG_REQUIRED_A, InterpretationQuery FLAG_REQUIRED_B, InterpretationQuery... FLAGS>
 bool checkConstraints(std::vector<InterpretationResolution>&& flags) {
     assert(flags.size());
 
     InterpretationResolution flag = flags.front();
     flags.pop_back();
 
     if (detail::checkConstraints<FLAG_REQUIRED_A>(flag)){
         return checkConstraints<FLAG_REQUIRED_B, FLAGS...>(move(flags));
     }
 
     return false;
 }
 
+bool
+InterpretationData::isDefault() const{
+    return (resolution == ANY && op == NONE);
+}
+
 namespace details {
     InterpretationResolution
     recognizeTags(const map<std::string, Expression>& tags){
         auto i = tags.find("interpretation");
         if (i== tags.end()){
             return ANY;
         }
 
         assert(i->second.op == Operator::CALL);
         const string& cmd = i->second.operands.at(0).getValueString();
 
         //TODO make consistent names  of annotation and resolution
         if        (cmd == "force"){
             return INTR_ONLY;
 
         } else if (cmd == "suppress"){
             return CMPL_ONLY;
         }
 
         return ANY;
     }
 }
 
 
 void
 recognizeTags(const Expression& e){
     InterpretationData tag{details::recognizeTags(e.tags), NONE};
-    Attachments::put<Expression, InterpretationData>(e, tag);
+    if (!tag.isDefault())
+        Attachments::put<InterpretationData>(e, tag);
 }
 
 InterpretationResolution
 recognizeTags(const ManagedFnPtr& f){
     return details::recognizeTags(f->getTags());
 }
 
 InterpretationPass::InterpretationPass(PassManager* manager)
-        : AbstractPass(manager) {}
+    : AbstractPass(manager) {
+
+    Attachments::init<FunctionInterpretationData>();
+    Attachments::init<InterpretationData>();
+}
 
 void InterpretationPass::run(){
     ManagedFnPtr f = man->root->begin<Function>();
     auto& visitedSymbols = getSymbolCache();
 
     while (f.isValid()) {
-        const Symbol& symbolFunction{0, f->getEntryScope()};
+        const Symbol& symbolFunction{ScopedSymbol::RetSymbol, f->getEntryScope()};
 
         if (!visitedSymbols.isCached(symbolFunction)){
             visitedSymbols.setCachedValue(symbolFunction, process(f));
         }
 
         ++f;
     }
 }
 
 InterpretationResolution
 InterpretationPass::process(const Expression& expression, PassContext context, const std::string& decl){
     recognizeTags(expression);
 
     InterpretationResolution resolution = ANY;
     InterpretationOperator op = NONE;
 
     switch (expression.__state){
 
+        case Expression::VARIANT:
         case Expression::NUMBER:
         case Expression::STRING: {
             break;
         }
 
         case Expression::IDENT: {
-            resolution = Parent::processSymbol(expression.getValueString(), context);
+            resolution = Parent::processSymbol(Attachments::get<Symbol>(expression), context);
             break;
         }
 
         case Expression::COMPOUND:
             break;
 
-        default: { resolution = INTR_ONLY; break;}
+        default: { resolution = CMPL_ONLY; break;}
     }
 
     if (expression.__state == Expression::COMPOUND)
     switch(expression.op){
         case Operator::EQU:
         case Operator::NE: {
             InterpretationResolution left =  process(expression.operands[0], context);
             InterpretationResolution right = process(expression.operands[1], context);
 
             resolution = unify(left, right);
             break;
         }
 
         case Operator::LOGIC_AND: {
             assert(expression.operands.size() == 1);
             resolution = process (expression.operands[0], context);
             break;
         }
 
         case Operator::CALL: {
             //TODO cope with static/dynamic context
             //TODO BUG here: if several variants they all are processed as CMPL careless of signature
             list<ManagedFnPtr> callees = man->root->getFunctionVariants(expression.getValueString());
             if (callees.size()!=1){
                 resolution = CMPL_ONLY;
                 break;
             }
 
             ManagedFnPtr callee = callees.front();
-            const Symbol& symbCalleeFunc{0, callee->getEntryScope()};
+            const Symbol& symbCalleeFunc{ScopedSymbol::RetSymbol, callee->getEntryScope()};
 
             //recursion-aware processing:
             //  - skip self recursion
-            const Symbol& symbSelfFunc{0, context.function->getEntryScope()};
+            const Symbol& symbSelfFunc{ScopedSymbol::RetSymbol, context.function->getEntryScope()};
             if (!(symbSelfFunc == symbCalleeFunc)){
                 InterpretationResolution resCallee = processFnCall(callee, context);
                 assert(resCallee != FUNC_POSTPONED && "Indirect recursion detected: can't decide on interpretation resolution");
 
                 resolution = unify(resolution, resCallee);
             }
 
             //check arguments compatibility
-            const FunctionInterpretationData& sig = FunctionInterpretationHelper::getSignature(callee);
+            const FunctionInterpretationData& calleeSignature = FunctionInterpretationHelper::getSignature(callee);
             for (size_t op=0, size = expression.operands.size(); op < size; ++op){
                 const Expression &operand = expression.operands[op];
                 InterpretationResolution argActual =  process(operand, context);
-                if (argActual == ANY) continue;
+                InterpretationResolution argExpected =  calleeSignature.signature[op];
 
-                assert(sig.signature[op] == argActual);
+                //TODO use args unification result to properly process function call
+                unify(argActual, argExpected);
             }
 
             if (FunctionInterpretationHelper::needPartialInterpretation(callee)){
                 op= CALL_INTERPRET_PARTIAL;
             }
 
             break;
         }
 
         case Operator::IF:{
             InterpretationResolution flagCondition = process(expression.getOperands()[0], context);
             InterpretationResolution flagScope1 = Parent::process(expression.blocks.front(), context);
             InterpretationResolution flagScope2 = Parent::process(expression.blocks.back(), context);
 
             //special case: IF_INTERPRET_CONDITION
             if (checkConstraints<QUERY_INTR_ONLY>({flagCondition})){
                 op= IF_INTERPRET_CONDITION;
                 flagCondition = ANY;
             }
 
             resolution = unify(flagCondition, flagScope1, flagScope2);
             break;
         }
 
         case Operator::FOLD: {
             InterpretationResolution flagInput = process(expression.getOperands()[0], context);
             InterpretationResolution flagAccumInit = process(expression.getOperands()[1], context);
 
             CodeScope* scopeBody = expression.blocks.front();
             const std::string& nameEl = expression.bindings[0];
-            getSymbolCache().setCachedValue(scopeBody->findSymbol(nameEl), InterpretationResolution(flagInput));
+            Symbol symbEl{ScopedSymbol{scopeBody->__identifiers.at(nameEl), VERSION_NONE}, scopeBody};
+            getSymbolCache().setCachedValue(symbEl, InterpretationResolution(flagInput));
 
             const std::string& nameAccum = expression.bindings[1];
-            getSymbolCache().setCachedValue(scopeBody->findSymbol(nameAccum), InterpretationResolution(flagAccumInit));
+            Symbol symbAccum{ScopedSymbol{scopeBody->__identifiers.at(nameAccum), VERSION_NONE}, scopeBody};
+            getSymbolCache().setCachedValue(symbAccum, InterpretationResolution(flagAccumInit));
 
             InterpretationResolution flagBody = Parent::process(expression.blocks.front(), context);
 
             //special case: FOLD_INTERPRET_INPUT
             if (checkConstraints<QUERY_INTR_ONLY>({flagInput})){
                 op= FOLD_INTERPRET_INPUT;
                 flagInput = ANY;
             }
 
             resolution = unify(flagInput, flagAccumInit, flagBody);
             break;
         }
 
         case Operator::INDEX: {
             resolution = unify(
                 process(expression.operands[0], context),
-                Parent::processSymbol(expression.getValueString(), context)
+                process(expression.operands[1], context)
             );
 
             break;
         }
 
         case Operator::SWITCH: {
             InterpretationResolution flagCondition = process(expression.operands[0], context);
             bool hasDefaultCase = expression.operands[1].op == Operator::CASE_DEFAULT;
 
 
             //determine conditions resolution
             InterpretationResolution flagHeaders = flagCondition;
             for (size_t size = expression.operands.size(), i= hasDefaultCase? 2: 1; i<size; ++i){
                 const Expression& exprCase = expression.operands[i];
 
                 flagHeaders = unify(flagHeaders, Parent::process(exprCase.blocks.front(), context));
             }
 
             if (checkConstraints<QUERY_INTR_ONLY>({flagHeaders})){
                 op= SWITCH_INTERPRET_CONDITION;
                 flagHeaders = ANY;
             }
 
             //determine body resolutions
             resolution = flagHeaders;
             for (size_t size = expression.operands.size(), i= 1; i<size; ++i){
                 const Expression& exprCase = expression.operands[i];
 
                 resolution = unify(resolution, Parent::process(exprCase.blocks.back(), context));
             }
 
             break;
         }
 
         case Operator::LIST:
         case Operator::LIST_NAMED: {
             for (const Expression &op: expression.getOperands()) {
                 resolution = unify(resolution, process(op, context));
             }
 
             break;
         }
 
         default: {
             resolution = CMPL_ONLY;
-            Parent::process(expression, context, decl);
+
+            for (const Expression &op: expression.getOperands()) {
+                process(op, context);
+            }
+
+            for (CodeScope* scope: expression.blocks) {
+                Parent::process(scope, context);
+            }
+
             break;
         }
     }
 
-    InterpretationResolution resolutionExpected = Attachments::get<Expression, InterpretationData>(expression, {ANY, NONE})
-            .resolution;
+    InterpretationResolution resolutionExpected =
+            Attachments::get<InterpretationData>(expression, {ANY, NONE}).resolution;
 
     resolution = unify(resolution, resolutionExpected);
-    if (op!=NONE || resolution == INTR_ONLY ){
-        Attachments::put<Expression, InterpretationData>(expression, {resolution, op});
-    }
-
-    if (resolution == INTR_ONLY){
-        compilation::Transformations::subscribe<Expression, compilation::TargetInterpretation>(expression);
+    if (resolution != resolutionExpected && (op!=NONE || resolution == INTR_ONLY)){
+        Attachments::put<InterpretationData>(expression, {resolution, op});
     }
 
     return resolution;
 }
 
     InterpretationResolution
     InterpretationPass::processFnCall(ManagedFnPtr function, PassContext context){
-        const Symbol& symbolFunction{0, function->getEntryScope()};
+        const Symbol symbolFunction{ScopedSymbol::RetSymbol, function->getEntryScope()};
         auto& visitedSymbols = getSymbolCache();
 
         if (visitedSymbols.isCached(symbolFunction))
             return visitedSymbols.getCachedValue(symbolFunction);
 
         PassContext context2;
         context2.function = function;
 
         return visitedSymbols.setCachedValue(symbolFunction,
                 Parent::process(function->getEntryScope(), context2));
     }
 
     InterpretationResolution
     InterpretationPass::process(ManagedFnPtr function){
         CodeScope* entry = function->getEntryScope();
         std::vector<std::string> arguments = entry->__bindings;
-        const Symbol& symbSelfFunc{0, function->getEntryScope()};
+        const Symbol& symbSelfFunc{ScopedSymbol::RetSymbol, function->getEntryScope()};
         auto& cache = getSymbolCache();
 
-        const FunctionInterpretationData& dataIntrpr = FunctionInterpretationHelper::getSignature(function);
-        InterpretationResolution resExpected = details::recognizeTags(function->getTags());
+        const FunctionInterpretationData& fnSignature = FunctionInterpretationHelper::getSignature(function);
+        InterpretationResolution fnResolutionExpected = details::recognizeTags(function->getTags());
 
         //mark preliminary function resolution as expected
-        if (resExpected != ANY){
-            cache.setCachedValue(symbSelfFunc, move(resExpected));
+        if (fnResolutionExpected != ANY){
+            cache.setCachedValue(symbSelfFunc, move(fnResolutionExpected));
 
         } else {
             //  - in order to recognize indirect recursion mark this function resolution as POSTPONED
             cache.setCachedValue(symbSelfFunc, FUNC_POSTPONED);
         }
 
         //set resolution for function arguments as expected
         for (int argNo = 0, size = arguments.size(); argNo< size; ++argNo){
-            Symbol symbArg = entry->findSymbol(arguments[argNo]);
-            cache.setCachedValue(symbArg, InterpretationResolution(dataIntrpr.signature[argNo]));
+            Symbol symbArg{ScopedSymbol{entry->__identifiers.at(arguments[argNo]), VERSION_NONE}, entry};
+            cache.setCachedValue(symbArg, InterpretationResolution(fnSignature.signature[argNo]));
         }
 
-        InterpretationResolution resActual  = Parent::process(function);
-        return unify(resActual, resExpected);
+        PassContext context;
+        context.function = function;
+        context.scope = entry;
+        InterpretationResolution resActual  = process(CodeScope::getDeclaration(symbSelfFunc), context);
+        resActual =  unify(resActual, fnResolutionExpected);
+        return cache.setCachedValue(symbSelfFunc, move(resActual));
     }
 
     const FunctionInterpretationData
     FunctionInterpretationHelper::getSignature(ManagedFnPtr function){
-        const Symbol& symbFunc{0, function->getEntryScope()};
-
-        if (Attachments::exists<Symbol, FunctionInterpretationData>(symbFunc)){
-            return Attachments::get<Symbol, FunctionInterpretationData>(symbFunc);
+        if (Attachments::exists<FunctionInterpretationData>(function)){
+            return Attachments::get<FunctionInterpretationData>(function);
         }
 
         FunctionInterpretationData&& data = recognizeSignature(function);
-        Attachments::put<Symbol, FunctionInterpretationData>(symbFunc, data);
+        Attachments::put<FunctionInterpretationData>(function, data);
         return data;
     }
 
     FunctionInterpretationData
     FunctionInterpretationHelper::recognizeSignature(ManagedFnPtr function){
         CodeScope* entry = function->__entry;
         FunctionInterpretationData result;
         result.signature.reserve(entry->__bindings.size());
 
         bool flagPartialInterpretation = false;
         for(size_t no=0, size=entry->__bindings.size(); no < size; ++no){
             const std::string& argName = entry->__bindings[no];
-            const Expression& arg = entry->findDeclaration(entry->findSymbol(argName));
+            Symbol symbArg{ScopedSymbol{entry->__identifiers.at(argName), VERSION_NONE}, entry};
+
+            const Expression& arg = CodeScope::getDeclaration(symbArg);
 
             InterpretationResolution argResolution = details::recognizeTags(arg.tags);
             flagPartialInterpretation |= (argResolution == INTR_ONLY);
 
             result.signature.push_back(argResolution);
         }
         result.flagPartialInterpretation = flagPartialInterpretation;
         return result;
     }
 
     bool FunctionInterpretationHelper::needPartialInterpretation(ManagedFnPtr function){
         const FunctionInterpretationData& data = getSignature(function);
         return data.flagPartialInterpretation;
     }
 }
 
-//if (res != INTR_ONLY){
-//            argumentsActual.insert(no);
-//}
-
-
diff --git a/cpp/src/pass/interpretationpass.h b/cpp/src/pass/interpretationpass.h
index 0d6ba84..a6434e6 100644
--- a/cpp/src/pass/interpretationpass.h
+++ b/cpp/src/pass/interpretationpass.h
@@ -1,78 +1,80 @@
 /* 
  * File:   interpretationpass.h
  * Author: pgess
  *
  * Created on July 5, 2016, 5:21 PM
  */
 
 #ifndef INTERPRETATIONPASS_H
 #define INTERPRETATIONPASS_H
 
 #include "abstractpass.h"
 #include <map>
 
 namespace xreate {
     
     enum InterpretationResolution{ANY, INTR_ONLY, CMPL_ONLY, FUNC_POSTPONED};
     enum InterpretationOperator{NONE, IF_INTERPRET_CONDITION, FOLD_INTERPRET_INPUT, SWITCH_INTERPRET_CONDITION, CALL_INTERPRET_PARTIAL};
     
     struct InterpretationData{
         InterpretationResolution resolution;
         InterpretationOperator  op;
+        
+        bool isDefault() const;
     };
     
     template<>
     InterpretationResolution 
     defaultValue<InterpretationResolution>();
 
     struct FunctionInterpretationData{
         typedef std::vector<InterpretationResolution> Signature;
         Signature signature;
         bool flagPartialInterpretation;
     };
 
     template<>
     struct AttachmentsDict<FunctionInterpretationData>
     {
         typedef FunctionInterpretationData Data;
         static const unsigned int key = 5;
     };
     
     class FunctionInterpretationHelper {
     public:
         static const FunctionInterpretationData
         getSignature(ManagedFnPtr function);
         
         static bool needPartialInterpretation(ManagedFnPtr function);
         
     private:    
         static FunctionInterpretationData recognizeSignature(ManagedFnPtr function);
     };
     
     template<>
     struct AttachmentsDict<InterpretationData>
     {
         typedef InterpretationData Data;
         static const unsigned int key = 3;
     };
     
     class InterpretationPass: public AbstractPass<InterpretationResolution> {
         typedef AbstractPass<InterpretationResolution> Parent;
     
     public:
         InterpretationResolution process(const Expression& expression, PassContext context, const std::string& varDecl="") override;
         InterpretationResolution process(ManagedFnPtr function);
         InterpretationResolution processFnCall(ManagedFnPtr function, PassContext context);
         
         InterpretationPass(PassManager* manager);
         void run();
     };
     
     namespace details {
         InterpretationResolution recognizeTags(const std::map<std::string, Expression>& tags);
     }
 }
 
 
 #endif /* INTERPRETATIONPASS_H */
 
diff --git a/cpp/src/pass/loggerpass.cpp b/cpp/src/pass/loggerpass.cpp
deleted file mode 100644
index f4471c8..0000000
--- a/cpp/src/pass/loggerpass.cpp
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * logging.cpp
- *
- *  Created on: Jun 23, 2015
- *      Author: pgess
- */
-
-#include <pass/loggerpass.h>
-#include "compilation/containers.h"
-#include "utils.h"
-
-using namespace std;
-using namespace llvm;
-namespace xreate {
-
-
-void LoggerPass::init(ClaspLayer* clasp){
-	auto model = clasp->query(Config::get("logging.id"));
-	if(!model) return;
-
-	for (ClaspLayer::ModelIterator rec = model->first; rec!=model->second; ++rec){
-		std::tuple<SymbolPacked> _v =ClaspLayer::parse<SymbolPacked>(rec->second);
-		Symbol v = clasp->unpack(get<0>(_v));
-
-		Attachments::put<Symbol, IsLogging>(v, true);
-	}
-}
-
-void
-LoggerPass::process(const Expression& expression, PassContext context, const std::string& varDecl){
-	if (varDecl.size()){
-		Symbol v = context.scope->findSymbol(varDecl);
-		if (Attachments::get<Symbol, IsLogging>(v, false)){
-				compilation::FunctionUnit* func =  compiler->getFunctionUnit(context.function);
-				compilation::CodeScopeUnit* scope = func->getScopeUnit(context.scope);
-
-				compilation::Context compilationContext{scope, func, compiler};
-				inject(v, compilationContext);
-		}
-	}
-
-	return AbstractPass<void>::process(expression, context, varDecl);
-}
-
-void LoggerPass::inject(const Symbol& symbol, const compilation::Context& context){
-    //TODO fix log injection
-
-//	llvm::Value* source = context.scope->compileSymbol(symbol);
-//	ExpandedType typSource = man->root->expandType(CodeScope::findDefinition(symbol).type);
-//	string format = "";
-//	switch (typSource->__value) {
-//	case TypePrimitive::Int : case TypePrimitive::Num : case TypePrimitive::I32: case TypePrimitive::I8:
-//		format = "%d\n";
-//		break;
-//
-//	case TypePrimitive::String:
-//		format = "%s\n";
-//		break;
-//
-//	default:
-//		assert(false && "No appropriate type for logging");
-//	}
-//
-//	xreate::compilation::Advanced instructions(context);
-//
-//	LLVMLayer* llvm = context.pass->man->llvm;
-//	llvm->builder.SetInsertPoint(llvm->builder.GetInsertBlock(), *source->use_begin());
-//	llvm::Value* formatRaw = instructions.compileConstantStringAsPChar(format, "logformat");
-//
-//	llvm->builder.CreateCall2(refPrintf, formatRaw, source);
-}
-
-void
-LoggerPass::initOutput(){
-	LLVMLayer* llvm = man->llvm;
-	refPrintf = llvm->module->getFunction("printf");
-
-	 if (!refPrintf) {
-		 PointerType* typPtrI8 = PointerType::get(IntegerType::get(llvm->module->getContext(), 8), 0);
-		 std::vector<Type*>argsPrintf{typPtrI8};
-		 FunctionType* signaturePrintf = FunctionType::get(
-		  /*Result=*/IntegerType::get(llvm->module->getContext(), 32),
-		  /*Params=*/argsPrintf,
-		  /*isVarArg=*/true);
-
-		 refPrintf = llvm::Function::Create(
-	  /*Type=*/signaturePrintf,
-	  /*Linkage=*/GlobalValue::ExternalLinkage,
-	  /*Name=*/"printf", llvm->module); // (external, no body)
-
-		 refPrintf->setCallingConv(CallingConv::C);
-	 }
-}
-
-LoggerPass::LoggerPass(PassManager* manager)
-	: AbstractPass<void>(manager)
-{
-	initOutput();
-	init(man->clasp);
-}
-
-void
-LoggerPass::initDependencies(CompilePass* pass){
-	compiler = pass;
-}
-
-
-} /* namespace xreate */
diff --git a/cpp/src/pass/loggerpass.h b/cpp/src/pass/loggerpass.h
deleted file mode 100644
index 252e9c8..0000000
--- a/cpp/src/pass/loggerpass.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * logging.h
- *
- *  Created on: Jun 23, 2015
- *      Author: pgess
- */
-
-#ifndef SRC_LOGGING_H_
-#define SRC_LOGGING_H_
-
-#include "ast.h"
-#include <llvm/IR/Value.h>
-#include "pass/compilepass.h"
-#include "pass/abstractpass.h"
-#include "clasplayer.h"
-
-namespace xreate {
-
-class LoggerPass:public AbstractPass<void>, public IQuery {
-public:
-	void inject(const Symbol& symbol, const compilation::Context& context);
-	LoggerPass(PassManager* manager);
-
-	virtual void init(ClaspLayer* clasp);
-	void initDependencies(CompilePass* pass);
-	virtual void process(const Expression& expression, PassContext context, const std::string& varDecl="");
-
-private:
-	CompilePass* compiler = nullptr;
-	llvm::Function* refPrintf;
-	void initOutput();
-};
-
-struct IsLogging{};
-
-template<>
-struct AttachmentsDict<IsLogging> {
-   typedef bool Data;
-   static const unsigned int key = 2;
-};
-
-} /* namespace xreate */
-
-#endif /* SRC_LOGGING_H_ */
diff --git a/cpp/src/pass/rulespass.cpp b/cpp/src/pass/rulespass.cpp
deleted file mode 100644
index a30c100..0000000
--- a/cpp/src/pass/rulespass.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "rulespass.h"
-
-using namespace xreate;
-
-RulesPass::RulesPass(PassManager* manager)
-    : ASTPass(manager)
-{
-    man->registerFilter(this, PassFilter::RULE);
-}
-
-void
-RulesPass::process(MetaRuleAbstract* rule, PassContext context)
-{
-    rule->compile(*man->clasp);
-}
-
diff --git a/cpp/src/pass/rulespass.h b/cpp/src/pass/rulespass.h
deleted file mode 100644
index fefd760..0000000
--- a/cpp/src/pass/rulespass.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifndef RULESPASS_H
-#define RULESPASS_H
-#include "passmanager.h"
-
-namespace xreate {
-class RulesPass : public ASTPass
-{
-public:
-    void process(MetaRuleAbstract* rule, PassContext context);
-    RulesPass(PassManager* manager);
-}; }
-
-#endif // RULESPASS_H
diff --git a/cpp/src/pass/versionspass.cpp b/cpp/src/pass/versionspass.cpp
new file mode 100644
index 0000000..65c6853
--- /dev/null
+++ b/cpp/src/pass/versionspass.cpp
@@ -0,0 +1,377 @@
+/*
+ * versionspass.cpp
+ *
+ * Author: pgess <v.melnychenko@xreate.org>
+ * Created on January 4, 2017, 3:13 PM
+ */
+
+#include <boost/optional/optional.hpp>
+
+#include "pass/versionspass.h"
+
+namespace std{
+    std::size_t
+    hash<xreate::SymbolOrPlaceholder>::operator()(xreate::SymbolOrPlaceholder const& s) const
+    {return std::hash<xreate::Symbol>()(s.symbol) + (s.flagEndOfLifePlaceholder? 9849 : 1);}
+
+    bool
+    equal_to<xreate::SymbolOrPlaceholder>::operator()(const xreate::SymbolOrPlaceholder& __x, const xreate::SymbolOrPlaceholder& __y) const
+    { return __x.flagEndOfLifePlaceholder == __y.flagEndOfLifePlaceholder && __x.symbol == __y.symbol; }
+
+    size_t
+    hash<xreate::Symbol>::operator()(xreate::Symbol const& s) const{
+        return hash<xreate::ScopedSymbol>()(s.identifier) ^ ((long int) s.scope << 1);
+    }
+
+    bool
+    equal_to<xreate::Symbol>::operator()(const xreate::Symbol& __x, const xreate::Symbol& __y) const{
+      return __x == __y;
+    };
+}
+
+using namespace std;
+
+namespace xreate {
+
+template<>
+std::list<Symbol>
+defaultValue<std::list<Symbol>>(){
+    return std::list<Symbol>();
+};
+
+inline std::string
+printSymbol(const SymbolOrPlaceholder& s){
+    switch(s.flagEndOfLifePlaceholder){
+        case SYMBOL: return string("(") + std::to_string(s.symbol.identifier.id) + ", "+ std::to_string(s.symbol.identifier.version) + ")";
+        case PLACEHOLDER: return string("(") + std::to_string(s.symbol.identifier.id) + ", "+ std::to_string(s.symbol.identifier.version) + ")+";
+    }
+
+    return "";
+}
+
+void
+VersionsGraph::__debug_print(std::ostream& output) const{
+    for(auto entry: __inferiors){
+        output << printSymbol(entry.second) << " <-" << printSymbol(entry.first) << "\n";
+    }
+}
+
+void
+VersionsGraph::defineEndOfLife(const Symbol& symbol, const Symbol& symbolSuccessor){
+    if(__dictSuccessors.count(symbol)){
+        assert("No version branches allowed yet" && false);
+    }
+
+    const SymbolOrPlaceholder& placeholder = getEndOfLife(symbol);
+
+    auto inferiorsDeferred = __inferiors.equal_range(placeholder);
+    std::unordered_multimap<SymbolOrPlaceholder, SymbolOrPlaceholder> inferiorsReassigned;
+
+    for (const auto& inf: boost::make_iterator_range(inferiorsDeferred)){
+        inferiorsReassigned.emplace(SymbolOrPlaceholder{SYMBOL, symbolSuccessor}, inf.second);
+    }
+
+    __inferiors.erase(placeholder);
+    __inferiors.insert(inferiorsReassigned.begin(), inferiorsReassigned.end());
+    __inferiors.emplace(SymbolOrPlaceholder{SYMBOL, symbolSuccessor}, SymbolOrPlaceholder{SYMBOL, symbol});
+
+    __dictSuccessors.emplace(symbol, symbolSuccessor);
+}
+
+SymbolOrPlaceholder
+VersionsGraph::getEndOfLife(const Symbol& s){
+    if (__dictSuccessors.count(s)){
+        return SymbolOrPlaceholder{SYMBOL, __dictSuccessors.at(s)};    }
+
+
+    return SymbolOrPlaceholder{PLACEHOLDER, s};
+}
+
+void
+VersionsGraph::applyNatualDependencies(const Symbol& symbol, const std::list<Symbol>& dependencies){
+    for (const Symbol& right: dependencies){
+        __inferiorsNatural.emplace(symbol, right);
+    }
+}
+
+void
+VersionsGraph::applyDependentEndOfLife(const SymbolOrPlaceholder& symbol, const list<Symbol>& dependencies){
+    for (const Symbol& right: dependencies){
+        auto rightEOF = getEndOfLife(right);
+
+        __inferiors.emplace(rightEOF, symbol);
+    }
+}
+
+bool
+VersionsGraph::tryEliminateEofAliases(const std::list<SymbolOrPlaceholder>& aliases){
+
+    if (aliases.size()==1){
+        return true;
+    }
+
+    boost::optional<Symbol> symbolActualEoF;
+    for(const SymbolOrPlaceholder alias: aliases){
+        switch(alias.flagEndOfLifePlaceholder){
+            case SYMBOL:
+                if(symbolActualEoF){
+                    return false;
+                }
+
+                symbolActualEoF = alias.symbol;
+                break;
+
+            case PLACEHOLDER:
+                continue;
+        }
+    }
+
+    if(!symbolActualEoF){
+        return false;
+    }
+
+    for(const SymbolOrPlaceholder alias: aliases){
+        switch(alias.flagEndOfLifePlaceholder){
+            case SYMBOL:
+                continue;
+
+            case PLACEHOLDER:
+                defineEndOfLife(alias.symbol, symbolActualEoF.get());
+                break;
+        }
+    }
+
+    return true;
+}
+
+std::list<SymbolOrPlaceholder>
+VersionsGraph::extractCycle(const Path& path, const SymbolOrPlaceholder& symbolBeginning){
+    unsigned int posBeginning = path.at(symbolBeginning);
+
+    std::list<SymbolOrPlaceholder> result;
+
+    auto i=path.begin();
+    while(true){
+        i = std::find_if(i, path.end(), [&posBeginning](const auto& el){return el.second >=posBeginning;});
+
+        if (i!= path.end()){
+            result.push_back(i->first);
+            ++i;
+
+        } else {break; }
+    }
+
+    return result;
+}
+
+
+bool
+VersionsGraph::validateCycles(const SymbolOrPlaceholder& s,
+                            std::unordered_multimap<SymbolOrPlaceholder, SymbolOrPlaceholder>& graph,
+                            std::unordered_set<SymbolOrPlaceholder>& symbolsVisited,
+                            Path& path)
+{
+    if (symbolsVisited.count(s)) return true;
+
+    symbolsVisited.insert(s);
+    path.emplace(s, path.size());
+
+    if (graph.count(s)){
+        //iterate over imposed dependencies
+        auto candidates = graph.equal_range(s);
+        for (auto candidate = candidates.first; candidate != candidates.second; ++candidate){
+            if (path.count(candidate->second)) {
+                std::list<SymbolOrPlaceholder> cycle = extractCycle(path, candidate->second);
+                if (!tryEliminateEofAliases(cycle)) return false;
+                continue;
+            }
+
+            if(!validateCycles(candidate->second, graph, symbolsVisited, path)) return false;
+        }
+    }
+
+        //iterate over natural dependencies
+    if (s.flagEndOfLifePlaceholder == SYMBOL) {
+        auto candidates = __inferiorsNatural.equal_range(s.symbol);
+        for (auto candidate = candidates.first; candidate != candidates.second; ++candidate){
+            if (path.count(SymbolOrPlaceholder{SYMBOL, candidate->second})){
+                return false;
+            }
+
+            if(!validateCycles(SymbolOrPlaceholder{SYMBOL,candidate->second}, graph, symbolsVisited, path)) return false;
+        }
+    }
+
+        //check previous version
+    if (s.flagEndOfLifePlaceholder == PLACEHOLDER){
+        const Symbol& candidate = s.symbol;
+
+        if (path.count(SymbolOrPlaceholder{SYMBOL, candidate})){
+            std::list<SymbolOrPlaceholder> cycle = extractCycle(path, SymbolOrPlaceholder{SYMBOL, candidate});
+            if (!tryEliminateEofAliases(cycle)) return false;
+        }
+
+        if(!validateCycles(SymbolOrPlaceholder{SYMBOL,candidate}, graph, symbolsVisited, path)) return false;
+    }
+
+    path.erase(s);
+    return true;
+}
+
+bool
+VersionsGraph::validateCycles(){
+    std::unordered_set<SymbolOrPlaceholder> symbolsVisited;
+    Path path;
+    std::unordered_multimap<SymbolOrPlaceholder, SymbolOrPlaceholder> graph(__inferiors);
+
+    std::unordered_multimap<SymbolOrPlaceholder, SymbolOrPlaceholder>::const_iterator s;
+    for (s = graph.begin(); s != graph.end(); ++s){
+        if(!validateCycles(s->first, graph, symbolsVisited, path)) return false;
+    }
+
+    return true;
+}
+
+bool
+VersionsGraph::validate(){
+    return validateCycles();
+}
+
+std::list<Symbol>
+VersionsGraph::expandPlaceholder(const SymbolOrPlaceholder& symbol, const Symbol& symbolPrev) const{
+    std::list<Symbol> result;
+
+    switch (symbol.flagEndOfLifePlaceholder){
+        case SYMBOL:
+            //skip self-loops
+            if (symbol.symbol == symbolPrev) return {};
+
+            return {symbol.symbol};
+
+        case PLACEHOLDER:
+            for (const auto& entry: boost::make_iterator_range(__inferiors.equal_range(symbol))){
+                list<Symbol>&& childResult = expandPlaceholder(entry.second, symbolPrev);
+                result.insert(result.end(), childResult.begin(), childResult.end());
+            }
+
+            if (__dictSuccessors.count(symbol.symbol)){
+                Symbol knownSuccessor = __dictSuccessors.at(symbol.symbol);
+
+                //skip alias loop
+                if (knownSuccessor == symbolPrev) return {};
+
+                for (const auto& entry: boost::make_iterator_range(__inferiors.equal_range(SymbolOrPlaceholder{SYMBOL, knownSuccessor}))){
+                    list<Symbol>&& childResult = expandPlaceholder(entry.second, knownSuccessor);
+                    result.insert(result.end(), childResult.begin(), childResult.end());
+                }
+            }
+
+            break;
+    }
+
+    return result;
+}
+
+AttachmentsContainerDefault<std::list<Symbol>>*
+VersionsGraph::representAsAttachments() const {
+    AttachmentsContainerDefault<std::list<Symbol>>* container =  new AttachmentsContainerDefault<std::list<Symbol>>();
+
+    std::map<Symbol, std::list<Symbol>> containerData;
+
+    for(const auto& entry: __inferiors){
+        if(entry.first.flagEndOfLifePlaceholder == PLACEHOLDER) continue;
+
+        list<Symbol>& infs = containerData[entry.first.symbol];
+        list<Symbol>&& infsExpanded = expandPlaceholder(entry.second, entry.first.symbol);
+        infs.insert(infs.begin(), infsExpanded.begin(), infsExpanded.end());
+    }
+
+    for(const auto& entry: containerData){
+        container->put(entry.first, entry.second);
+    }
+
+    return container;
+}
+
+std::list<Symbol>
+VersionsPass::process(const Expression& expression, PassContext context, const std::string& hintSymbol){
+    if (expression.__state == Expression::COMPOUND){
+        std::list<Symbol> resultDependencies;
+
+        for (const Expression &op: expression.getOperands()) {
+            std::list<Symbol> deps = process(op, context);
+
+            resultDependencies.insert(resultDependencies.end(), deps.begin(), deps.end());
+        }
+
+        for (CodeScope* scope: expression.blocks) {
+            std::list<Symbol> deps = Parent::process(scope, context);
+
+            resultDependencies.insert(resultDependencies.end(), deps.begin(), deps.end());
+        }
+
+        return resultDependencies;
+    }
+
+    if (expression.__state == Expression::IDENT){
+        const Symbol symb = Attachments::get<Symbol>(expression);
+
+        return processSymbol(symb, context, expression.getValueString());
+    }
+
+    return {};
+}
+
+//TODO versions, check (declaration.isDefined()) before processing declaration
+list<Symbol>
+VersionsPass::processSymbol(const Symbol& symbol, PassContext context, const std::string& hintSymbol){
+    list<Symbol> result{symbol};
+
+    if (__symbolsVisited.exists(symbol)){
+        return result;
+    }
+    enum {MODE_ALIAS, MODE_COPY } mode = MODE_ALIAS;
+
+    const Expression& declaration = CodeScope::getDeclaration(symbol);
+
+    if (declaration.op == Operator::CALL_INTRINSIC){
+        if (declaration.getValueString() == "copy"){
+            mode = MODE_COPY;
+        }
+    }
+
+    if (symbol.identifier.version != VERSION_NONE){
+        mode = MODE_COPY;
+
+        if (symbol.identifier.version > 0){
+            Symbol versionPrev = Symbol{ScopedSymbol{symbol.identifier.id, symbol.identifier.version-1}, symbol.scope};
+            __graph.defineEndOfLife(versionPrev, symbol);
+        }
+    }
+
+    PassContext context2 = context.updateScope(symbol.scope);
+    std::list<Symbol> dependencies = process(declaration, context2, hintSymbol);
+
+    switch (mode) {
+        case MODE_COPY: __graph.applyDependentEndOfLife(SymbolOrPlaceholder{SYMBOL, symbol}, dependencies); break;
+        case MODE_ALIAS: __graph.applyDependentEndOfLife(__graph.getEndOfLife(symbol), dependencies); break;
+    }
+
+    __graph.applyNatualDependencies(symbol, dependencies);
+    __symbolsVisited.put(symbol, true);
+    return list<Symbol>{symbol};
+}
+
+VersionsGraph&
+VersionsPass::getResultGraph(){
+    return __graph;
+}
+
+void
+VersionsPass::finish(){
+    assert(__graph.validate() && "Can't validate versions graph");
+
+    Attachments::init<VersionImposedDependency>(__graph.representAsAttachments());
+}
+
+}
\ No newline at end of file
diff --git a/cpp/src/pass/versionspass.h b/cpp/src/pass/versionspass.h
new file mode 100644
index 0000000..e13c62b
--- /dev/null
+++ b/cpp/src/pass/versionspass.h
@@ -0,0 +1,115 @@
+/* 
+ * File:   versionspass.h
+ * Author: v.melnychenko@xreate.org
+ *
+ * Created on January 4, 2017, 3:09 PM
+ */
+
+#ifndef VERSIONSPASS_H
+#define VERSIONSPASS_H
+
+#include "pass/abstractpass.h"
+#include <list>
+#include  <functional>
+
+namespace xreate {
+    
+    enum PlaceholderFlag {SYMBOL, PLACEHOLDER};
+
+    struct SymbolOrPlaceholder {
+        PlaceholderFlag flagEndOfLifePlaceholder;
+        Symbol symbol;
+    };
+
+
+} namespace std {
+    
+    template<>
+    struct hash<xreate::SymbolOrPlaceholder>{
+        std::size_t operator()(xreate::SymbolOrPlaceholder const& s) const;
+    };
+
+    template<>
+    struct equal_to<xreate::SymbolOrPlaceholder>{
+      bool operator()(const xreate::SymbolOrPlaceholder& __x, const xreate::SymbolOrPlaceholder& __y) const;
+    };
+    
+    template<>
+    struct hash<xreate::Symbol>{
+        size_t operator()(xreate::Symbol const& s) const;
+    };
+
+    template<>
+    struct equal_to<xreate::Symbol>{
+      bool operator()(const xreate::Symbol& __x, const xreate::Symbol& __y) const;
+    };
+    
+} namespace xreate {
+
+struct VersionImposedDependency{};
+
+template<>
+struct AttachmentsDict<VersionImposedDependency>
+{
+    typedef std::list<Symbol> Data;
+    static const unsigned int key = 8;
+};
+    
+class VersionsGraph{
+    public:
+        //processing API:
+        void applyNatualDependencies(const Symbol& symbol, const std::list<Symbol>& dependencies);
+        void applyDependentEndOfLife(const SymbolOrPlaceholder& symbol, const std::list<Symbol>& dependencies);
+        
+        void defineEndOfLife(const Symbol& symbol, const Symbol& symbolSuccessor);
+        SymbolOrPlaceholder getEndOfLife(const Symbol& s);
+        
+        bool validate();
+
+        //examination API:
+        AttachmentsContainerDefault<std::list<Symbol>>* representAsAttachments() const;
+        void __debug_print(std::ostream& output) const;
+        
+    private:
+        typedef std::unordered_map<SymbolOrPlaceholder, unsigned int> Path;
+
+        std::unordered_multimap<Symbol, Symbol> __inferiorsNatural;
+        std::unordered_multimap<SymbolOrPlaceholder, SymbolOrPlaceholder> __inferiors;
+        std::unordered_map<Symbol, Symbol> __dictSuccessors;
+
+        std::list<Symbol> expandPlaceholder(const SymbolOrPlaceholder& symbol, const Symbol& symbolPrev) const;
+        std::list<SymbolOrPlaceholder> extractCycle(const Path& path, const SymbolOrPlaceholder& symbolBeginning);
+        bool tryEliminateEofAliases(const std::list<SymbolOrPlaceholder>& aliases);
+        bool validateCycles();
+        bool validateCycles(const SymbolOrPlaceholder& s, 
+                            std::unordered_multimap<SymbolOrPlaceholder, SymbolOrPlaceholder>& graph,
+                            std::unordered_set<SymbolOrPlaceholder>& symbolsVisited, 
+                            Path& path);
+};
+        
+template<>
+std::list<Symbol>
+defaultValue<std::list<Symbol>>();
+
+class VersionsPass: public AbstractPass<std::list<Symbol>> {
+    typedef AbstractPass<std::list<Symbol>> Parent;
+    
+public:
+    VersionsPass(PassManager* manager): AbstractPass<std::list<Symbol>>(manager){}
+    std::list<Symbol> process(const Expression& expression, PassContext context, const std::string& hintSymbol="") override;
+    VersionsGraph& getResultGraph();
+    virtual void finish();
+    
+protected:
+    std::list<Symbol> processSymbol(const Symbol& symbol, PassContext context, const std::string& hintSymbol="") override;
+    
+private:
+    VersionsGraph __graph;
+    
+    AttachmentsContainerDefault<bool> __symbolsVisited;
+};
+
+}   //end of xreate
+
+#endif /* VERSIONSPASS_H */
+
diff --git a/cpp/src/passmanager.cpp b/cpp/src/passmanager-bare.cpp
similarity index 63%
rename from cpp/src/passmanager.cpp
rename to cpp/src/passmanager-bare.cpp
index ccc9338..48c2715 100644
--- a/cpp/src/passmanager.cpp
+++ b/cpp/src/passmanager-bare.cpp
@@ -1,120 +1,84 @@
-#include <pass/abstractpass.h>
-#include <pass/loggerpass.h>
-#include "query/containers.h"
-#include "passmanager.h"
-#include "pass/compilepass.h"
-#include "pass/adhocpass.h"
 
+#include "passmanager.h"
+#include <pass/abstractpass.h>
 #include "Parser.h"
-#include "pass/cfapass.h"
-#include "pass/dfapass.h"
+#include "clasplayer.h"
+
 #include <list>
 #include <stdio.h>
 
 using namespace xreate;
 using namespace std;
 
 PassManager*
 PassManager::prepareForCode(std::string&& code){
       Scanner scanner(reinterpret_cast<const unsigned char*>(code.c_str()), code.size());
       return prepareForCode(&scanner);
 }
 
 PassManager*
 PassManager::prepareForCode(FILE* code){
       Scanner scanner(code);
       return prepareForCode(&scanner);
 }
 
 PassManager*
 PassManager::prepareForCode(Scanner* code){
     Parser parser(code);
     parser.Parse();
     assert(!parser.errors->count && "Parser errors");
 
     PassManager* man = new PassManager;
     AST* ast = new AST(parser.root);
 
     man->root = ast;
     man->clasp = new ClaspLayer();
 
     man->clasp->ast = man->root;
     man->llvm = new LLVMLayer(man->root);
 
-    CompilePass::prepareQueries(man->clasp);
     return man;
 }
 
 void
 PassManager::registerPass(AbstractPassBase* pass, const PassId& id, AbstractPassBase* parent)
 {
     __passes.emplace(id, pass);
     __passDependencies.emplace(parent, pass);
 }
 
 AbstractPassBase*
 PassManager::getPassById(const PassId& id){
 	assert(__passes.count(id));
 	return __passes[id];
 }
 
 bool
 PassManager::isPassRegistered(const PassId& id){
     return __passes.count(id);
 }
 
 void
 PassManager::executePasses(){
     std::list<AbstractPassBase*> passes{nullptr};
     while (passes.size()){
         AbstractPassBase* parent = passes.front();
 
         auto range = __passDependencies.equal_range(parent);
 
         for (auto i=range.first; i!=range.second; ++i){
             AbstractPassBase* pass = i->second;
 
             pass->run();
             pass->finish();
 
             passes.push_back(pass);
         }
 
         passes.pop_front();
     }
 }
 
-void*
-PassManager::run()
-{
-    runWithoutCompilation();
 
-    CompilePass* compiler = new CompilePass(this);
-    compiler->run();
-
-    		//Compiler Dependents:
-    LoggerPass* logger = new LoggerPass(this);
-	logger->initDependencies(compiler);
-	logger->run();
-
-    llvm->print();
-    llvm->initJit();
-    return llvm->getFunctionPointer(compiler->getEntryFunction());
-}
-
-void PassManager::runWithoutCompilation(){
-    if (flagIsProcessed) return;
-    
-    CFAPass* passCFG = new CFAPass(this);
-
-        //TODO is it really DFGPass needs CFGpass?
-    this->registerPass(new DFAPass(this), PassId::DFGPass, passCFG);
-    this->registerPass(passCFG, PassId::CFGPass);
-    this->registerPass(new AdhocPass(this), PassId::AdhocPass);
-    
-    this->executePasses();
-    clasp->run();
-    flagIsProcessed = true;
-}
 
 PassManager::~PassManager(){}
diff --git a/cpp/src/passmanager-full.cpp b/cpp/src/passmanager-full.cpp
new file mode 100644
index 0000000..5bb70b2
--- /dev/null
+++ b/cpp/src/passmanager-full.cpp
@@ -0,0 +1,49 @@
+/*
+ * passmanager-full.cpp
+ *
+ * Author: Volodymyr Melnychenko <v.melnychenko@xreate.org>
+ * Created on January 27, 2017, 7:10 PM
+ */
+
+#include "passmanager.h"
+#include "llvmlayer.h"
+#include "pass/compilepass.h"
+#include "pass/adhocpass.h"
+#include "pass/cfapass.h"
+#include "pass/dfapass.h"
+#include "pass/interpretationpass.h"
+#include "pass/versionspass.h"
+
+using namespace xreate;
+
+void PassManager::runWithoutCompilation(){
+    if (flagIsProcessed) return;
+
+    CFAPass* passCFG = new CFAPass(this);
+
+        //TODO is it really DFGPass needs CFGpass?
+    this->registerPass(new DFAPass(this), PassId::DFGPass, passCFG);
+    this->registerPass(passCFG, PassId::CFGPass);
+    this->registerPass(new AdhocPass(this), PassId::AdhocPass);
+    this->registerPass(new InterpretationPass(this), PassId::InterpretationPass);
+    this->registerPass(new VersionsPass(this), PassId::VersionsPass);
+
+    this->executePasses();
+
+    CompilePass::prepareQueries(clasp);
+    clasp->run();
+    flagIsProcessed = true;
+}
+
+void*
+PassManager::run()
+{
+    runWithoutCompilation();
+
+    CompilePass* compiler = new CompilePass(this);
+    compiler->run();
+
+    llvm->print();
+    llvm->initJit();
+    return llvm->getFunctionPointer(compiler->getEntryFunction());
+}
\ No newline at end of file
diff --git a/cpp/src/passmanager.h b/cpp/src/passmanager.h
index cb55967..0e67ba0 100644
--- a/cpp/src/passmanager.h
+++ b/cpp/src/passmanager.h
@@ -1,56 +1,57 @@
 #ifndef  PASSMANAGER_H
 #define PASSMANAGER_H
 
 #include <string>
 #include <map>
 
 //stdio external
 struct _IO_FILE;
 typedef struct _IO_FILE FILE;
 
 class Scanner;
 
 namespace xreate {
 class AbstractPassBase;
 class ClaspLayer;
 class LLVMLayer;
 class AST;
 
 enum class PassId {
 	CFGPass,
 	CompilePass,
 	DFGPass,
 	EnvironmentTestsPass,
 	LoggerPass,
 	AdhocPass,
 	RulesPass,
-        InterpretationPass
+        InterpretationPass,
+        VersionsPass
 };
 
 class PassManager
 {
 public:
     ~PassManager();
     void*run();
     void runWithoutCompilation();
     void executePasses();
     void registerPass(AbstractPassBase* pass, const PassId& id, AbstractPassBase* prerequisite=nullptr);
     AbstractPassBase* getPassById(const PassId& id);
     bool isPassRegistered(const PassId& id);
     static PassManager* prepareForCode(std::string&& code);
     static PassManager* prepareForCode(FILE* code);
 
     ClaspLayer* clasp;
     LLVMLayer* llvm;
     AST* root;
 private:
     //typedef std::multimap<PassFilter, ASTPass*> FILTERS_STORAGE;
     //FILTERS_STORAGE __filters;
     std::map<PassId, AbstractPassBase*> __passes;
     std::multimap<AbstractPassBase*,  AbstractPassBase*> __passDependencies;
     bool flagIsProcessed = false;
 
     static PassManager* prepareForCode(Scanner* code);
 }; }
 
 #endif
diff --git a/cpp/src/query/containers.cpp b/cpp/src/query/containers.cpp
index 8f37165..1243cff 100644
--- a/cpp/src/query/containers.cpp
+++ b/cpp/src/query/containers.cpp
@@ -1,164 +1,165 @@
 //
 // Created by pgess on 3/14/15.
 //
 
 #include <clasplayer.h>
 #include "query/containers.h"
 
 using namespace std;
 using namespace xreate::containers;
 using namespace xreate;
 
-
-
 Implementation
 Query::queryImplementation(xreate::Symbol const &s) {
-    typedef Attachments attach;
-
-    if (attach::exists<Symbol, Implementation>(s))
+    if (Attachments::exists<Implementation>(s))
     {
-        return attach::get<Symbol, Implementation>(s);
+        return Attachments::get<Implementation>(s);
     }
 
     return  Implementation::create(s);
 }
 
+
+Query::Query(){
+    Attachments::init<Implementation>();
+}
+
 void
 Query::init(ClaspLayer* clasp)
 {
     if (flagIsDataLoaded) return;
 
     map<Symbol, Symbol> prototypes;
     map<Symbol, string> roots;
 
         //read all proto data
     auto range = clasp->query(Config::get("containers.id.prototypes"));
     if (range)
     for(ClaspLayer::ModelIterator atom = range->first; atom != range->second; ++atom) {
         auto data =  ClaspLayer::parse<SymbolPacked, SymbolPacked>(atom->second);
         Symbol root = clasp->unpack(get<0> (data));
         Symbol prototype = clasp->unpack(get<1> (data));
 
         prototypes[root] = prototype;
     }
 
         // fill implementation data for a data sources:
     range = clasp->query(Config::get("containers.id.implementations"));
     if (range)
     for(ClaspLayer::ModelIterator atom = range->first; atom != range->second; ++atom)
     {
         auto data = ClaspLayer::parse<SymbolPacked, string>(atom->second);
 
         Symbol var  = clasp->unpack(get<0>(data));
         string implSerialized  = get<1>(data);
 
             //data source, has no prototypes:
         if (!prototypes.count(var))
         {
             Implementation impl = Implementation::create(var);
-            Attachments::put<Symbol, Implementation>(var, move(impl));
+            Attachments::put<Implementation>(var, move(impl));
             continue;
         }
 
         roots.emplace(move(var), move(implSerialized));
     }
 
         //fill implementation data for a cluster roots
     for (const pair<Symbol, string> &  root: roots)
     {
         Symbol prototype = prototypes[root.first];
 
         while (prototypes.count(prototype))        {
             prototype = prototypes.at(prototype);
         }
 
-        Attachments::put<Symbol, Implementation>(root.first, Implementation(Attachments::get<Symbol, Implementation>(prototype)));
+        Attachments::put<Implementation>(root.first, Implementation(Attachments::get<Implementation>(prototype)));
     }
 
     // read cluster data and fill implementation data for cluster members
     range = clasp->query(Config::get("containers.id.clusters"));
     if (range)
     for(ClaspLayer::ModelIterator atom = range->first; atom != range->second; ++atom)
     {
         auto info = ClaspLayer::parse<SymbolPacked, SymbolPacked>(atom->second);
 
         Symbol root =  clasp->unpack(get<0>(info));
         Symbol child =  clasp->unpack(get<1>(info));
 
-        if (!(child == root)) {
-            Implementation rootImpl = Attachments::get<Symbol, Implementation>(root);
-            Attachments::put<Symbol, Implementation>(child, move(rootImpl));
+        if (!(child == root) && (Attachments::exists<Implementation>(root))) {
+            Implementation rootImpl = Attachments::get<Implementation>(root);
+            Attachments::put<Implementation>(child, move(rootImpl));
         }
     }
 
     flagIsDataLoaded = true;
 }
 
 //static ImplementationData* create(Symbol var, std::string implSerialized, const ImplementationData* implPrototype);
 
 Implementation
 Implementation::create(const Symbol &var)
 {
     //TODO review implementation determination strategy
-    Expression varDecl = CodeScope::findDeclaration(var);
+    Expression varDecl = CodeScope::getDeclaration(var);
     switch (varDecl.op)
     {
         case Operator::LIST_RANGE: {
             ImplementationRec<ON_THE_FLY> rec{var};
             return {ON_THE_FLY, rec};
         }
 
         case Operator::LIST: {
             return {SOLID, ImplementationRec<SOLID> {varDecl.getOperands().size()}};
         }
 
         default: break;
     };
 
     ImplementationLinkedList ill(var);
     if (ill){
     	return ill.getImplementationData();
     }
 
     assert(false && "Unable to determine proper implementation for the symbol");
 }
 
 Implementation
 Implementation::create(const Symbol& var, const std::string& implSerialized)
 {
-    Expression varDecl = CodeScope::findDeclaration(var);
+    Expression varDecl = CodeScope::getDeclaration(var);
     if (implSerialized == Config::get("containers.impl.solid"))
     {
         return {SOLID, ImplementationRec<SOLID>{varDecl.operands.size()}};
 
     } else if (implSerialized == Config::get("containers.impl.onthefly")) {
         return {ON_THE_FLY, ImplementationRec<ON_THE_FLY>{var}};
     }
 
     assert(false && "unable to determine proper implementation for the symbol");
 }
 
 
 ImplementationLinkedList::ImplementationLinkedList(const Symbol& source)
         :    flagIsValid(false), s(source){
 
-	const Expression& sourceExpr = CodeScope::findDeclaration(source);
+	const Expression& sourceExpr = CodeScope::getDeclaration(source);
 
 	if (sourceExpr.tags.count(Config::get("containers.id.linkedlist"))){
         flagIsValid = true;
 
         Expression tagLinkedlist = sourceExpr.tags.at(Config::get("containers.id.linkedlist"));
 		assert(tagLinkedlist.operands.size() == 2);
 		fieldPointer = tagLinkedlist.operands.at(0).getValueString();
 		terminator = tagLinkedlist.operands.at(1);
 	}
 }
 
 ImplementationLinkedList:: operator bool () const{
     return flagIsValid;
 }
 
 Implementation
 ImplementationLinkedList::getImplementationData() const {
 	return {ON_THE_FLY, ImplementationRec<ON_THE_FLY>{s}};
 }
diff --git a/cpp/src/query/containers.h b/cpp/src/query/containers.h
index ec474d0..35db039 100644
--- a/cpp/src/query/containers.h
+++ b/cpp/src/query/containers.h
@@ -1,83 +1,84 @@
 //
 // Created by pgess on 3/14/15.
 //
 
 #ifndef _XREATE_CONTAINERSQUERY_H_
 #define _XREATE_CONTAINERSQUERY_H_
 
 
 #include "passmanager.h"
 #include "clasplayer.h"
 
 #include <boost/variant.hpp>
 
 namespace xreate {
 namespace containers {
 
     enum ImplementationType {SOLID,  ON_THE_FLY, LINKED_LIST};
 
     template<ImplementationType I>
     struct ImplementationRec;
 
     template<>
     struct ImplementationRec<SOLID> {
         size_t size;
     };
 
     template<>
     struct ImplementationRec<ON_THE_FLY>{
         Symbol source;
     };
 
     struct Implementation;
     struct ImplementationLinkedList {
         bool flagIsValid;
         std::string fieldPointer;
         Expression terminator;
 
         ImplementationLinkedList(const Symbol& source);
         operator bool() const;
         Implementation getImplementationData() const;
 
     private:
         Symbol s;
     };
 
     struct Implementation {
         typedef boost::variant<ImplementationRec<SOLID>, ImplementationRec<ON_THE_FLY>> Variant;
         const ImplementationType  impl;
         Variant data;
 
         static Implementation create(const Symbol &var);
         static Implementation create(const Symbol& var, const std::string &implSerialized);
         static Implementation create(const Symbol& var, const Implementation& proto);
 
         template<ImplementationType I>
         const ImplementationRec<I>& extract() const{
             const ImplementationRec<I>& rec = boost::get<ImplementationRec<I>>(data);
             return rec;
         }
     };
 
     class Query : public xreate::IQuery {
     public:
         static  Implementation queryImplementation(xreate::Symbol const &s);
         void init(ClaspLayer* clasp);
 
+        Query();
         ~Query(){}
     private:
         bool flagIsDataLoaded = false;
         PassManager *man;
     };
 
 
 }
 
      template<>
     struct AttachmentsDict<containers::Implementation> {
         typedef containers::Implementation Data;
         static const unsigned int key = 1;
     };
 }
 
 #endif //_XREATE_CONTAINERSQUERY_H_
diff --git a/cpp/src/serialization/expressionserializer.cpp b/cpp/src/serialization/expressionserializer.cpp
index 53d6ee5..447c7d1 100644
--- a/cpp/src/serialization/expressionserializer.cpp
+++ b/cpp/src/serialization/expressionserializer.cpp
@@ -1,316 +1,318 @@
 /*
  * expressionserializer.cpp
  *
  *  Created on: Jan 4, 2016
  *      Author: pgess
  */
 
 #include "serialization/expressionserializer.h"
 #include <boost/utility.hpp>
+#include <boost/utility/in_place_factory.hpp>
+
 #include <cmath>
 
 using namespace std;
 //using namespace boost::bimaps;
 namespace xreate {
 
 struct Index {
     string name;
     size_t degree; //count of parameters
     unsigned char level; //level in expression tree (depth of tree layer)
 
     bool operator< (const Index other) const{
             if (name != other.name) return name < other.name;
             if (degree != other.degree) return degree < other.degree;
             if (name != other.name) return level < other.level;
             return false;
     }
 };
 
 class ExpressionSerializerPrivate {
 	//boost::bimap<Index, multiset_of<size_t>> __registry;
     struct {
             map<Index,size_t> left;
     } __registry;
     map<unsigned char, size_t> __range;
 
 public:
     void pack(const Expression& e, unsigned char level, OptionalPackedExpression& target){
         if (!target) return;
         switch (e.op){
             case Operator::NONE: {
                 switch (e.__state) {
                         case Expression::NUMBER:
                         case Expression::STRING:
                         case Expression::IDENT : {
 
                             Index index;
                             if ((e.__state == Expression::NUMBER))
                                 index = {std::to_string(e.getValueDouble()), 0, level};
                                 else index = {e.getValueString(), 0, level};
 
                             if (!__registry.left.count(index)){
                                     target = boost::none;
                                     return;
                             }
 
                             size_t id = __registry.left.at(index);
                             size_t range = __range[level];
                             (*target) << make_pair(id, range);
                             return;
                         }
                         default: break;
                 }
             break;
             }
 
             case Operator::CALL: {
                 Index index{e.getValueString(), e.operands.size(), level};
                 if(!__registry.left.count(index)){
                         target = boost::none;
                         return;
                 }
 
                 size_t id = __registry.left.at(index);
                 size_t range = __range[level];
                 (*target) << make_pair(id, range);
 
                 for (const Expression& operand: e.operands){
                         pack(operand, level+1, target);
                 }
                 return;
             }
             default: break;
         }
 
         assert(false && "Expression too complicate for serialization");
     }
 
     void registerExpression(const Expression&e, unsigned char level){
         switch (e.op){
             case Operator::CALL: {
                 Index index{e.getValueString(), e.operands.size(), level};
                 if (__registry.left.insert(make_pair(index, __range[level])).second){
                         __range[level]++;
                 }
 
                 for (const Expression& operand: e.operands){
                         registerExpression(operand, level+1);
                 }
             return;
             }
 
             case Operator::NONE: {
                 Index index;
 
                 switch (e.__state) {
                     case Expression::STRING:
                     case Expression::IDENT: {
                             index = {e.getValueString(), 0, level};
                             if (__registry.left.insert(make_pair(index, __range[level])).second){
                                     __range[level]++;
                             }
                     return;
                     }
 
                     case Expression::NUMBER: {
                         index = {std::to_string(e.getValueDouble()), 0, level};
                         if (__registry.left.insert(make_pair(index, __range[level])).second){
                                 __range[level]++;
                         }
                         return;
                     }
 
                     default: break;
                 }
             break;
             }
 
             default: break;
         }
 
         assert(false && "Expression too complicate for serialization");
     }
 };
 
 ExpressionSerializer::ExpressionSerializer()
 	: strategy(new ExpressionSerializerPrivate()){
 }
 
 ExpressionSerializer::~ExpressionSerializer() {
 	delete strategy;
 }
 
 void
 ExpressionSerializer::registerExpression(const Expression&e){
 	if (e.isValid())
 	strategy->registerExpression(e, 0);
 }
 
 PackedExpression
 ExpressionSerializer::getId(const Expression& e){
 	OptionalPackedExpression result(boost::in_place());
         //move(PackedExpression())
 
 	strategy->pack(e, 0, result);
 	assert(result);
 	return move(*result);
 }
 
 OptionalPackedExpression
 ExpressionSerializer::getIdOptional(const Expression& e) const{
         OptionalPackedExpression result(boost::in_place());
         //move(PackedExpression())
 
 	strategy->pack(e, 0, result);
 	return result;
 }
 
 ExpressionSerializerIntegral::ExpressionSerializerIntegral():serializer(*this){}
 
 ExpressionSerializerIntegral::ExpressionSerializerIntegral(const std::vector<Expression>&& expressions)
 	: std::vector<Expression>(move(expressions)), serializer(*this){
 
 	size_t id =0;
 	for (const Expression& e: expressions){
 			__registry.emplace(serializer.getId(e), id++);
 	}
 }
 
 size_t
 ExpressionSerializerIntegral::size() const{
 	return  PARENT::size();
 }
 
 size_t
 ExpressionSerializerIntegral::count(const Expression& e) const {
 	return (getIdOptional(e)? 1: 0);
 }
 
 ExpressionSerializerIntegral::const_iterator
 ExpressionSerializerIntegral::begin() const {
 	return PARENT::begin();
 }
 
 ExpressionSerializerIntegral::const_iterator
 ExpressionSerializerIntegral::end() const {
 	return PARENT::end();
 }
 
 size_t
 ExpressionSerializerIntegral::getId(const Expression& e) const{
 	const OptionalPackedExpression exprPacked = serializer.getIdOptional(e);
 	assert(exprPacked);
 
 	return __registry.at(*exprPacked);
 }
 
 boost::optional<size_t>
 ExpressionSerializerIntegral::getIdOptional(const Expression& e) const{
 	const OptionalPackedExpression exprPacked = serializer.getIdOptional(e);
 	if (!exprPacked){
 		return boost::none;
 	}
 
 	return __registry.at(*exprPacked);
 }
 
 const Expression&
 ExpressionSerializerIntegral::get(size_t id) const{
 	return at(id);
 }
 
 
 void
 PackedExpression::operator<< (const std::pair<size_t, size_t>& value){
 	static const size_t sizeSizeT = sizeof(size_t);
 
 	const size_t& id = value.first;
 	const size_t& range = value.second;
 
 	int countSufficientBits =  range <=1? 0 : ceil(log2(range));
 
 	if (0 < countRemainedBits  && countRemainedBits < countSufficientBits) {
 		size_t* tail = reinterpret_cast<size_t*>(__storage + size- sizeSizeT);
 		(*tail)  +=  id >> (countSufficientBits - countRemainedBits);
 		countSufficientBits-=countRemainedBits;
 		countRemainedBits = 0;
 	}
 
 	if (countRemainedBits == 0) {
 		if (countSufficientBits == 0) return;
 
 		char* __storageNew = new char[size+sizeSizeT];
 		std::memcpy (__storageNew, __storage, size);
 		std::memset(__storageNew + size, 0, sizeSizeT);
 
 		delete[] __storage;
 		__storage = __storageNew;
 
 		size += sizeSizeT;
 		countRemainedBits = 8 * sizeSizeT;
 	}
 
 	if (countRemainedBits >= countSufficientBits) {
 		size_t* tail = reinterpret_cast<size_t*>(__storage + size- sizeSizeT);
 		(*tail)  +=  id << (countRemainedBits - countSufficientBits);
 		countRemainedBits -= countSufficientBits;
 		return;
 	}
 
 	assert("Unreachable block");
 }
 
 	#if BOOST_VERSION <= 105500
 PackedExpression::PackedExpression(const PackedExpression& other){
 	__storage = other.__storage;
 	size = other.size;
 	countRemainedBits = other.countRemainedBits;
 }
 	#endif
 
 PackedExpression::PackedExpression(PackedExpression&& other){
 	__storage = other.__storage;
 	size = other.size;
 	countRemainedBits = other.countRemainedBits;
 
 	other.__storage = nullptr;
 }
 
 bool
 PackedExpression::operator==(const PackedExpression& other) const{
 	if (size == other.size && countRemainedBits == other.countRemainedBits){
 		return std::memcmp(__storage, other.__storage, size) == 0 ;
 	}
 
 	return false;
 }
 
 bool
 PackedExpression::operator<(const PackedExpression& other) const{
 	if (size <  other.size) { return true; }
 	if (countRemainedBits < other.countRemainedBits) return true;
 
 	if (size == other.size && countRemainedBits == other.countRemainedBits){
 		return std::memcmp(__storage, other.__storage, size) < 0 ;
 	}
 
 	return false;
 }
 
 bool
 PackedExpression::operator!=(const PackedExpression& other) const{
 	return ! ((*this) == other);
 }
 
 PackedExpression::~PackedExpression() {
 	delete[] __storage;
 }
 
 //PackedExpression::PackedExpression (const PackedExpression& other)
 //	: size(other.size), countRemainedBits(other.countRemainedBits)
 //{
 //	__storage = new char[size];
 //	std::memcpy (__storage, other.__storage, size);
 //}
 
 } /* namespace xreate */
\ No newline at end of file
diff --git a/cpp/src/serialization/expressionserializer2.cpp b/cpp/src/serialization/expressionserializer2.cpp
deleted file mode 100644
index 5c63641..0000000
--- a/cpp/src/serialization/expressionserializer2.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * ExpressionSerializer2.cpp
- *
- *  Created on: 9 февр. 2016
- *      Author: pgess
- */
-
-#include "expressionserializer2.h"
-
-using namespace std;
-
-namespace xreate {
-
-typedef size_t ElementId;
-struct Element{
-	string name;
-	unsigned char degree;
-	ElementId terminal = 0;
-	std::list<ElementId> childs;
-
-	bool operator< (const Element& other) {
-		int cmp = name.compare(other.name);
-		if (cmp !=0) return (cmp < 0);
-		return (degree < other.degree);
-	}
-
-	bool operator== (const Element& other) {
-		int cmp = name.compare(other.name);
-		if (cmp != 0) return false;
-		return degree == other.degree;
-	}
-
-	Element(string nameElement, unsigned int degreeElement)
-		: name(nameElement), degree(degreeElement) {}
-};
-
-const Element End{"", 0};
-
-class ExpressionSerializerStrategyB {
-	vector<Element> __registry;
-
-	ElementId push(const Element& e, ElementId rootId){
-		typedef list<ElementId>::iterator ElementIt;
-
-		list<ElementId>& elements =  __registry[rootId].childs;
-		list<ElementId>::iterator pos = std::__lower_bound(elements.begin(), elements.end(), e,
-				[this](const ElementIt& testIt, const Element& value){return __registry[*testIt] < value;});
-
-		if (!(__registry[*pos] == e)) {
-			__registry.push_back(e);
-			ElementId result = __registry.size()-1;
-			elements.insert(pos, result);
-			return result;
-		}
-
-		return *pos;
-	}
-
-	ElementId registerExpression(const Expression& e, ElementId rootId) {
-		switch(e.op){
-			case Operator::NONE: {
-				switch (e.__state) {
-					case Expression::STRING:
-					case Expression::IDENT: {
-						const string& name = e.getValueString();
-						Element element(name, 0);
-						ElementId rootId = push(element, rootId);
-						return rootId;
-					}
-
-					default: {
-						break;
-					}
-				}
-			break;
-			}
-
-			case Operator::CALL: {
-				const string& name = e.getValueString();
-				Element element(name, e.operands.size());
-				ElementId rootId = push(element, rootId);
-
-				for (const Expression& op: e.operands){
-					Element element(op.getValueString(), op.operands.size());
-					rootId = push(element, rootId);
-				}
-
-				return rootId;
-			}
-
-			default: break;
-		}
-
-		assert(false && "Expression too complicate for serialization");
-	}
-};
-
-} /* namespace xreate */
diff --git a/cpp/src/serialization/expressionserializer2.h b/cpp/src/serialization/expressionserializer2.h
deleted file mode 100644
index 3b29756..0000000
--- a/cpp/src/serialization/expressionserializer2.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * ExpressionSerializer2.h
- *
- *  Created on: 9 февр. 2016
- *      Author: pgess
- */
-
-#ifndef EXPRESSIONSERIALIZER2_H_
-#define EXPRESSIONSERIALIZER2_H_
-
-#include <ast.h>
-
-namespace xreate {
-
-class ExpressionSerializer2 {
-public:
-	ExpressionSerializer2();
-	virtual ~ExpressionSerializer2();
-
-	void registerExpression(const Expression& e);
-};
-
-} /* namespace xreate */
-
-#endif /* EXPRESSIONSERIALIZER2_H_ */
diff --git a/cpp/src/utils.cpp b/cpp/src/utils.cpp
index 693a00e..134ea62 100644
--- a/cpp/src/utils.cpp
+++ b/cpp/src/utils.cpp
@@ -1,9 +1,24 @@
 #include "utils.h"
+#include <boost/locale/encoding_utf.hpp>
 
 using namespace xreate;
 
 Config Config::__self = Config();
 
 Config::Config()
 : __storage{json_file{ "config/default.json" }}
 {}
+
+using boost::locale::conv::utf_to_utf;
+
+std::wstring
+utf8_to_wstring(const std::string& str)
+{
+    return utf_to_utf<wchar_t>(str.c_str(), str.c_str() + str.size());
+}
+
+std::string
+wstring_to_utf8(const std::wstring& str)
+{
+    return utf_to_utf<char>(str.c_str(), str.c_str() + str.size());
+}
\ No newline at end of file
diff --git a/cpp/src/utils.h b/cpp/src/utils.h
index a2f9b28..95bb82a 100644
--- a/cpp/src/utils.h
+++ b/cpp/src/utils.h
@@ -1,134 +1,159 @@
 #ifndef UTILS_H
 #define UTILS_H
 
 #include "jeayeson/jeayeson.hpp"
 
 //TODO use type mark to mark dirty/mutable members
 
 /*
 template<class T>
 struct DdesctructableClass<T> {
 
 }
 */
 /*
 template<class OriginalType>
 struct TagUpdatable{
     TagUpdatable(const OriginalType& source)
             : __source(source)
     {}
 
     TagUpdatable() = delete;
 
     const OriginalType& __source;
 };
 
 
 struct Updatable;
 
 template <class Tag, class OT>
 struct TagsDictionary
 {};
 
 template<class OT>
 struct TagsDictionary<Updatable, OT>
 {
     typedef TagUpdatable<OT> TagName;
 };
 
 template<class Tag, class OT>
 struct awareOf
 {
     awareOf(OT& dest)
         : __dest(dest)
     {}
 
     awareOf<Tag, OT>&
         operator= (const typename TagsDictionary<Tag, OT>::TagName& source)
     {
         __dest = source.__source;
     }
 
 private:
     OT& __dest;
 };
 
 template<class Tag<OT>>
 const OT&
 awareOf(const Tag<OT>& holder)
 {
     return std::forward<OT>(holder.__source);
 }
 
  */
 
 namespace xreate {
     template<class Tag, class Source>
     struct AddTag {
 
         explicit
         AddTag(const Source &src)
                 : __src(src) { }
 
         explicit
         AddTag(Source &&src)
                 : __src(std::move(src)) { }
 
         operator const Source&() const{
             return __src;
         }
 
         const Source& get() const{
             return __src;
         }
 
         const Source*
         operator->() const {
         	return &__src;
         }
 
     private:
         Source __src;
     };
 
     struct Expand_t{};
     template<class Source>
     using Expanded = AddTag<Expand_t, Source>;
     
 
 
  //DEBT move to resources compiler. https://github.com/markusfisch/cpprc
     class Config {
     private: 
       json_map __storage;
       static Config __self;
       Config();
       
     public: 
        static std::string get(std::string key) {
         return __self.__storage.get_for_path<json_value>(key).get<std::string>();
       }
     };
+    
+    /**
+     *  Decorators support
+     */
+    template<class DecoratorTag>
+    struct DecoratorsDict{
+        //typedef ConcreteDecoratorForTag result;
+    };
+    
+    template<class DecoratorTag>
+    struct Decorators{
+        typedef typename DecoratorsDict<DecoratorTag>::result Instance;
+
+        template<class Base>
+        static Instance* getInterface(Base* obj){
+            return dynamic_cast< Instance* > (obj);
+        }
+    };
 }
 
+std::wstring
+utf8_to_wstring(const std::string& str);
+
+std::string
+wstring_to_utf8(const std::wstring& str);
+
+
 #define RST  "\x1B[0m"
 #define KRED  "\x1B[31m"
 #define KGRN  "\x1B[32m"
 #define KYEL  "\x1B[33m"
 #define KBLU  "\x1B[34m"
 #define KMAG  "\x1B[35m"
 #define KCYN  "\x1B[36m"
 #define KWHT  "\x1B[37m"
 
 #define FRED(x) KRED << x << RST
 #define FGRN(x) KGRN <<x << RST
 #define FYEL(x) KYEL << x << RST
 #define FBLU(x) KBLU << x << RST
 #define FMAG(x) KMAG x RST
 #define FCYN(x) KCYN x RST
 #define FWHT(x) KWHT x RST
 
 #define BOLD(x) "\x1B[1m" x RST
 #define UNDL(x) "\x1B[4m" x RST
 
 #endif // UTILS_H
diff --git a/cpp/tests/CMakeLists.txt b/cpp/tests/CMakeLists.txt
index 25f9a64..ac038d2 100644
--- a/cpp/tests/CMakeLists.txt
+++ b/cpp/tests/CMakeLists.txt
@@ -1,25 +1,50 @@
 cmake_minimum_required(VERSION 2.8.11)
 project(xreate-tests)
 
 find_package(GTest REQUIRED)
 INCLUDE_DIRECTORIES(${GTEST_INCLUDE_DIRS})
 INCLUDE_DIRECTORIES("/usr/include/libxml2")
 INCLUDE_DIRECTORIES($<TARGET_PROPERTY:xreate,INCLUDE_DIRECTORIES>)
 
 
 #       TESTS
 #=========================
 FIND_PACKAGE (LLVM REQUIRED)
 message("LLVM_LIBRARY_DIRS: " ${LLVM_LIBRARY_DIRS})
 link_directories(${LLVM_LIBRARY_DIRS})
 
 set (LIBCLASP_PATH ${POTASSCO_PATH}/build/debug)
 link_directories(${LIBCLASP_PATH})
 
-aux_source_directory(. TEST_FILES)
+#aux_source_directory(. TEST_FILES)
+set(TEST_FILES
+    main.cpp
+    adhoc.cpp
+    attachments.cpp
+    ast.cpp
+    cfa.cpp
+    dfa.cpp
+    compilation.cpp
+    ExpressionSerializer.cpp
+    externc.cpp
+    context.cpp
+    types.cpp
+    vendorAPI/clangAPI.cpp
+    vendorAPI/xml2.cpp
+    vendorAPI/json.cpp
+    
+    containers.cpp
+    context.cpp
+    interpretation.cpp
+    loops.cpp
+
+    #supplemental/versions-algorithm-data_dependency.cpp
+    effects-versions.cpp
+)
+    
 add_executable(${PROJECT_NAME} ${TEST_FILES})
 target_link_libraries(${PROJECT_NAME} xreate ${GTEST_LIBRARIES} pthread xml2 gcov)
 
 add_custom_target (coverage
     COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/src/code-coverage.sh
     WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
diff --git a/cpp/tests/adhoc.cpp b/cpp/tests/adhoc.cpp
index eb9bafb..55b586e 100644
--- a/cpp/tests/adhoc.cpp
+++ b/cpp/tests/adhoc.cpp
@@ -1,160 +1,196 @@
 /*
  * adhoc-exceptions.cpp
 
  *
  *  Created on: Nov 19, 2015
  *      Author: pgess
  */
 
 class Adhoc_pass_Adhoc1_Test;
-#define FRIEND_ADHOC_UNITTESTS \
-	friend class ::Adhoc_pass_Adhoc1_Test;
+#define FRIENDS_ADHOC \
+    friend class ::Adhoc_pass_Adhoc1_Test;
 
 
 #include "ast.h"
 #include "passmanager.h"
 
 #include "gtest/gtest.h"
 #include <stdio.h>
 #include <memory>
 #include <sstream>
 #include <stdlib.h>
 
 
 #include "pass/adhocpass.h"
 #include "pass/compilepass.h"
 #include "llvmlayer.h"
 
 using namespace xreate;
 using namespace std;
 
 TEST(Adhoc, ast_operatorAdhoc1){
-	PassManager* man = PassManager::prepareForCode (
-		"		test = "
-		"function:: int {\n"
-		"			ad hoc Exception(NonImplemented)\n"
-		"		}"
-	);
-
-	Expression subject = man->root->findFunction("test")->getEntryScope()->getBody();
-	ASSERT_EQ(Operator::ADHOC, subject.op);
-	ASSERT_EQ(1, subject.getOperands().size());
-
-	Expression exception = subject.getOperands()[0];
-	ASSERT_EQ("Exception", exception.getValueString());
+    PassManager* man = PassManager::prepareForCode (
+    "test = function:: int {\n"
+    "   ad hoc exception(nonImplemented)\n"
+    "}");
+
+    Expression subject = man->root->findFunction("test")->getEntryScope()->getBody();
+    ASSERT_EQ(Operator::ADHOC, subject.op);
+
+    Expression exception = AdhocExpression(subject).getCommand();
+    ASSERT_EQ("exception", exception.getValueString());
 }
 
 TEST(Adhoc, ast_schemeAdhoc1){
-	PassManager* man = PassManager::prepareForCode (
-	"interface(adhoc){\n"
-	"		pre function expectNoErrors:: bool {\n"
-	"			case Error  {false}\n"
-	"			case Success {true}\n"
-	"		}\n"
-	"	}");
-
-	assert(man->root->__interfacesData.count(ASTInterface::Adhoc));
-	Expression adhocData = man->root->__interfacesData.find(ASTInterface::Adhoc)->second;
-	ASSERT_EQ(Operator::SWITCH, adhocData.operands[0].op);
+    PassManager* man = PassManager::prepareForCode (
+    "interface(adhoc){\n"
+    "		pre function expectNoErrors:: bool {\n"
+    "			case (Error)  {false}\n"
+    "			case (Success) {true}\n"
+    "		}\n"
+    "	}");
+
+    assert(man->root->__interfacesData.count(ASTInterface::Adhoc));
+    Expression adhocData = man->root->__interfacesData.find(ASTInterface::Adhoc)->second;
+    ASSERT_EQ(Operator::SWITCH, adhocData.operands[0].op);
 }
 
 TEST(Adhoc, pass_Adhoc1){
-	PassManager* man = PassManager::prepareForCode (
-		"interface(adhoc){\n"
-		"		pre function expectNoErrors:: bool {\n"
-		"			case Error  {false}\n"
-		"			case Success {true}\n"
-		"		}\n"
-		"}\n"
-
-                "main = function::int; entry {0} \n"
-                );
-
-	man->runWithoutCompilation();
-	AdhocPass* pass = reinterpret_cast<AdhocPass* >(man->getPassById(PassId::AdhocPass));
-	EXPECT_TRUE(pass->__schemes.size() > 0);
-
-	AdhocScheme* scheme =  pass->__schemes.begin()->second;
-	EXPECT_EQ("expectNoErrors", scheme->getContext());
+    PassManager* man = PassManager::prepareForCode (
+    "interface(adhoc){\n"
+    "   pre function expectNoErrors:: bool {\n"
+    "       case (Error)  {false}\n"
+    "       case (Success) {true}\n"
+    "   }\n"
+    "}\n"
+
+    "main = function::int; entry {0} \n"
+    );
+
+    man->runWithoutCompilation();
+    AdhocPass* pass = reinterpret_cast<AdhocPass* >(man->getPassById(PassId::AdhocPass));
+    EXPECT_TRUE(pass->__schemes.size() > 0);
+
+    AdhocScheme* scheme =  pass->__schemes.begin()->second;
+    EXPECT_EQ("expectNoErrors", scheme->getName());
 }
 
 TEST(Adhoc, full_1){
-	PassManager* man = PassManager::prepareForCode (
-		"	import raw (\"core/control-context.lp\")"
-
-		"	interface(adhoc){\n"
-		"		pre function expectNoErrors:: bool {\n"
-		"			case Error  {0}\n"
-		"			case Success {1}\n"
-		"		}\n"
-		"	}"
-
-		"	test1 = pre function {\n"
-		"		context:: expectNoErrors."
-		"		ad hoc \"Success\"\n"
-		"	}"
-
-		"main = function::bool;entry {\n"
-		"			test1()\n"
-		"		}");
-
-	bool (*main)() = (bool (*)()) man->run();
-	bool result = main();
-	ASSERT_EQ(true, result);
+    PassManager* man = PassManager::prepareForCode (
+    "	import raw (\"core/control-context.lp\")\n"
+
+    "	interface(adhoc){\n"
+    "		pre function expectNoErrors:: bool {\n"
+    "			case (error)  {false}\n"
+    "			case (success) {true}\n"
+    "		}\n"
+    "	}\n"
+
+    "	test1 = pre function {\n"
+    "		context:: expectNoErrors."
+    "		ad hoc success\n"
+    "	}"
+
+    "main = function::bool;entry {\n"
+    "			test1()\n"
+    "		}");
+
+    bool (*main)() = (bool (*)()) man->run();
+    bool result = main();
+    ASSERT_EQ(true, result);
+}
+
+TEST(Adhoc, full_2){
+    PassManager* man = PassManager::prepareForCode (
+    "	import raw (\"core/control-context.lp\")\n"
+
+    "	interface(adhoc){\n"
+    "		pre function expectNoErrors:: bool {\n"
+    "			case (error)  {false}\n"
+    "			case (success) {true}\n"
+    "		}\n"
+
+    "		pre function expectErrors:: bool {\n"
+    "			case (error)  {true}\n"
+    "			case (success) {false}\n"
+    "		}\n"
+
+    "	}\n"
+
+    "	test1 = pre function {\n"
+    "		context:: expectNoErrors."
+    "		ad hoc success\n"
+    "	}\n"
+
+    "	test2 = pre function {\n"
+    "		context:: expectErrors."
+    "		ad hoc success\n"
+    "	}"
+
+    "main = function::bool;entry {\n"
+    "   test1() != test2()\n"
+    "}");
+
+    bool (*main)() = (bool (*)()) man->run();
+    bool result = main();
+    ASSERT_EQ(true, result);
 }
 
+//TODO adhoc type. FDecl sets wrong type in prefunc case(invalid type))
 TEST(Adhoc, full_contextExpectNoErrrors){
-	PassManager* man = PassManager::prepareForCode (
-	"import raw (\"core/control-context.lp\")\n"
-
-	"interface(extern-c){\n"
-	"  xml2 = library:: pkgconfig(\"libxml-2.0\").\n"
-	"  \n"
-	"  include {\n"
-	"    xml2 = [\"stdlib.h\"]\n"
-	"  }.\n"
-	"}"
-
-	"interface(adhoc){\n"
-	"	pre function expectNoErrors:: bool {\n"
-	"		case Error  {0}\n"
-	"		case Success {1}\n"
-	"	}\n"
-	"}\n"
-
-	"expectErrorCode = pre function(x::int){\n"
-	"	if (x==0)::bool {ad hoc \"Success\"}\n"
-	"	else {ad hoc \"Error\"}\n"
-	"}\n"
-
-	"main = function::bool; entry {\n"
-	"		context:: expectNoErrors."
-	"		expectErrorCode(system(\"ls -la\"))\n"
-	"}"	);
-
-	int (*main)() = (int (*)()) man->run();
-	ASSERT_EQ(1, main());
+    PassManager* man = PassManager::prepareForCode (
+    "import raw (\"core/control-context.lp\")\n"
+
+    "interface(extern-c){\n"
+    "  xml2 = library:: pkgconfig(\"libxml-2.0\").\n"
+    "  \n"
+    "  include {\n"
+    "    xml2 = [\"stdlib.h\"]\n"
+    "  }.\n"
+    "}"
+
+    "interface(adhoc){\n"
+    "	pre function expectNoErrors:: bool {\n"
+    "		case (error)  {false}\n"
+    "		case (success) {true}\n"
+    "	}\n"
+    "}\n"
+
+    "expectErrorCode = pre function(x::int){\n"
+    "	if (x==0)::undef {ad hoc success}\n"
+    "	else {ad hoc error}\n"
+    "}\n"
+
+    "main = function::bool; entry {\n"
+    "		context:: expectNoErrors."
+    "		expectErrorCode(system(\"ls -la\"))\n"
+    "}"	);
+
+    int (*main)() = (int (*)()) man->run();
+    ASSERT_EQ(1, main());
 }
 
+//DEBT Implement compilation of switch adhoc
 TEST(Adhoc, ast_switchAdhoc1){
-	PassManager* man = PassManager::prepareForCode (
-	"test1 = function:: bool {\n"
-	"		switch ad hoc (x:: errors)\n"
-	"			case ERROR {0}\n"
-	"			case SUCCESS {1}\n"
-	"		\n"
-	"	}"
-	);
-
-	Expression eSwitch = man->root->findFunction("test1")->getEntryScope()->getBody();
-	EXPECT_EQ(Operator::SWITCH_ADHOC, eSwitch.op);
-	EXPECT_EQ(3, eSwitch.operands.size());
-
-	EXPECT_EQ(1, eSwitch.tags.size());
-	EXPECT_EQ("errors", eSwitch.tags.begin()->first);
-
-	Expression eCondition = eSwitch.getOperands()[0];
-	EXPECT_EQ("x", eCondition.getValueString());
+    PassManager* man = PassManager::prepareForCode (
+        "test1 = function:: bool {\n"
+        "   x = 0. \n"
+        "   switch ad hoc (x:: errors)\n"
+        "       case (error) {0}\n"
+        "	case (success) {1}\n"
+        "\n"
+        "}"
+    );
+
+    Expression eSwitch = man->root->findFunction("test1")->getEntryScope()->getBody();
+    EXPECT_EQ(Operator::SWITCH_ADHOC, eSwitch.op);
+    EXPECT_EQ(3, eSwitch.operands.size());
+
+    EXPECT_EQ(1, eSwitch.tags.size());
+    EXPECT_EQ("errors", eSwitch.tags.begin()->first);
+
+    Expression eCondition = eSwitch.getOperands()[0];
+    EXPECT_EQ("x", eCondition.getValueString());
 }
 
 
diff --git a/cpp/tests/ast.cpp b/cpp/tests/ast.cpp
index 46c637d..144a1f6 100644
--- a/cpp/tests/ast.cpp
+++ b/cpp/tests/ast.cpp
@@ -1,48 +1,68 @@
 /*
  * ast.cpp
  *
  *  Created on: Jun 11, 2015
  *      Author: pgess
  */
 
 #include "gtest/gtest.h"
 #include "passmanager.h"
 #include "Parser.h"
 
 using namespace std;
 using namespace xreate;
 
 TEST(AST, Containers1){
 	FILE* input = fopen("scripts/testspass/Containers_Implementation_LinkedList1.xreate","r");
 	Scanner scanner(input);
     Parser parser(&scanner);
     parser.Parse();
     assert(!parser.errors->count && "Parser errors");
 
     fclose(input);
 }
 
 TEST(AST, InterfacesDataCFA) {
 	PassManager* man = PassManager::prepareForCode
 				("interface(cfa){\n"
 				"    operator map :: annotation1.\n"
 				"}");
 
 	auto answer = man->root->__interfacesData.equal_range(CFA);
 	EXPECT_EQ(1, std::distance(answer.first, answer.second));
 
 	Expression&& scheme = move(answer.first->second);
 
 	EXPECT_EQ(Operator::MAP, scheme.op);
 	EXPECT_EQ("annotation1", scheme.getOperands().at(0).getValueString());
 }
 
+TEST(AST, syntax_recognizeIdentifiers){
+    PassManager* man = PassManager::prepareForCode(R"Code(
+            test= function(a:: num):: num; entry {
+                a = b:: int.
+                b = 8:: int.
+
+                a
+            }
+    )Code");
+}
+
+TEST(AST, syntax_operatorIndex){
+    PassManager* man = PassManager::prepareForCode(R"Code(
+            test= function(a:: num):: num; entry {
+                b = a[1].
+                b
+            }
+    )Code");
+}
+
 TEST(AST, DISABLED_InterfacesDataDFA){
 
 }
 
 TEST(AST, DISABLED_InterfacesDataExtern){
 
 }
 
 //TODO xreate.atg: replace all Type<> as ExprAnnotations<>
diff --git a/cpp/tests/attachments.cpp b/cpp/tests/attachments.cpp
new file mode 100644
index 0000000..54b8bba
--- /dev/null
+++ b/cpp/tests/attachments.cpp
@@ -0,0 +1,26 @@
+/*
+ * attachments.cpp
+ *
+ * Author: pgess <v.melnychenko@xreate.org>
+ * Created on January 22, 2017, 12:16 PM
+ */
+
+
+
+#include "attachments.h"
+#include "ast.h"
+
+#include "gtest/gtest.h"
+
+using namespace xreate;
+
+TEST(Attachments, basic1){
+    AttachmentsContainerDefault<bool>* c = new AttachmentsContainerDefault<bool>();
+
+    Expression expTest(Atom<Number_t>(10));
+    c->put<Expression>(expTest, true);
+
+    Expression expTest2(Atom<Number_t>(11));
+
+    ASSERT_FALSE(c->exists<Expression>(expTest2));
+}
\ No newline at end of file
diff --git a/cpp/tests/basic.cpp b/cpp/tests/basic.cpp
deleted file mode 100644
index 0deb63b..0000000
--- a/cpp/tests/basic.cpp
+++ /dev/null
@@ -1,26 +0,0 @@
-
-#include "gtest/gtest.h"
-#include "passmanager.h"
-#include "Scanner.h"
-#include "Parser.h"
-#include <iostream>
-#include <llvm/Support/DynamicLibrary.h>
-
-using namespace std;
-using namespace xreate;
-
-TEST(Basic, functionEntry1){
-    std::unique_ptr<PassManager> program(PassManager::prepareForCode(
-        "func1 = function(a:: int):: int {a+8} \
-         func2 = function::int; entry {12 + func1(4)}      \
-        "));
-
-    void* entryPtr = program->run();
-    int (*entry)() = (int (*)())(intptr_t)entryPtr;
-
-    int answer = entry();
-    ASSERT_EQ(24, answer);
-}
-
-
-
diff --git a/cpp/tests/cfa.cpp b/cpp/tests/cfa.cpp
index f01028c..42f7c4f 100644
--- a/cpp/tests/cfa.cpp
+++ b/cpp/tests/cfa.cpp
@@ -1,119 +1,119 @@
 /*
  * testsCFG.cpp
  *
  *  Created on: Jul 17, 2015
  *      Author: pgess
  */
 
 #include "passmanager.h"
 #include "pass/dfapass.h"
 #include "pass/cfapass.h"
 
 #include "analysis/DominatorsTreeAnalysisProvider.h"
 
 #include "gtest/gtest.h"
 
 #include <boost/scoped_ptr.hpp>
 #include <boost/smart_ptr/scoped_array.hpp>
 
 using namespace xreate;
 using namespace std;
 
 TEST(CFA, testFunctionAnnotationsClasp){
     string&& program =
         "f2 = function::int; annotationF2 {\n"
         "    0\n"
         "}\n"
         "\n"
         "f1 = function:: int; entry; annotationF1 {\n"
         "    f2() + 10\n"
         "}";
 
 
     PassManager* man = PassManager::prepareForCode(move(program));
     man->runWithoutCompilation();
 
     ClaspLayer::ModelFragment answer = man->clasp->query("annotationF1");
     int countNoneValue = 0;
     if (answer) countNoneValue = std::distance(answer->first, answer->second);
     EXPECT_EQ(1, countNoneValue);
 
     answer = man->clasp->query("annotationF2");
     countNoneValue = 0;
     if (answer) countNoneValue = std::distance(answer->first, answer->second);
 
     EXPECT_EQ(1, countNoneValue);
 }
 
 TEST(CFA, testLoopContextExists){
     PassManager* man = PassManager::prepareForCode (
         "interface(cfa){\n"
         "    operator fold:: annotation1.\n"
         "}\n"
         "\n"
         "main = function:: int; entry {\n"
         "    x = [1..10]:: [int].\n"
         "    sum = loop fold (x->el:: int, 0->sum):: int {\n"
         "        el + sum + f1()\n"
         "    }.  \n"
         "    sum\n"
         "}"
         "case context:: annotation1 {"
         " f1 = function::int {\n"
         "  	x = 0:: int.		 "
         "       x\n"
         " }"
         "}"
     );
 
     man->runWithoutCompilation();
     ClaspLayer::ModelFragment model = man->clasp->query("annotation1");
     ScopePacked scopeIdActual = std::get<0>(ClaspLayer::parse<ScopePacked>(model->first->second));
 
     CodeScope* scopeEntry = man->root->findFunction("main")->getEntryScope();
-    Symbol symbSum = man->root->findFunction("main")->getEntryScope()->findSymbol("sum");
-    CodeScope* scopeExpected = scopeEntry->findDeclaration(symbSum).blocks.front();
+    const Expression& exprSum = scopeEntry->getDeclaration(scopeEntry->getSymbol("sum"));
+    CodeScope* scopeExpected = exprSum.blocks.front();
 
     ScopePacked scopeIdExpected = man->clasp->pack(scopeExpected);
     ASSERT_EQ(scopeIdExpected, scopeIdActual);
 }
 
 TEST(CFA, CFGRoots){
     std::string program =
 R"CODE(
     main = function::int{a()+ b()}
     a= function::int {c1() + c2()}
     b= function::int {c2()}
     c1=function::int{0}
     c2=function::int{0}
 )CODE";
 
     boost::scoped_ptr<PassManager> manager
         (PassManager::prepareForCode(move(program)));
 
     manager->registerPass(new CFAPass(manager.get()) , PassId::CFGPass);
     manager->executePasses();
     manager->clasp->run();
 
     DominatorsTreeAnalysisProvider domProvider;
     domProvider.run(manager->clasp);
 
     DominatorsTreeAnalysisProvider::Dominators expectedFDom= {
          {0, {0, 9}}
         ,{1, {1, 4}}
         ,{2, {7, 8}}
         ,{3, {2, 3}}
         ,{4, {5, 6}}
     };
 
     DominatorsTreeAnalysisProvider::Dominators expectedPostDom= {
          {0, {5, 6}}
         ,{1, {3, 4}}
         ,{2, {8, 9}}
         ,{3, {1, 2}}
         ,{4, {7, 10}}
     };
 
     ASSERT_EQ(expectedFDom, domProvider.getForwardDominators());
     ASSERT_EQ(expectedPostDom, domProvider.getPostDominators());
 }
diff --git a/cpp/tests/compilation.cpp b/cpp/tests/compilation.cpp
index e5371df..95b96b6 100644
--- a/cpp/tests/compilation.cpp
+++ b/cpp/tests/compilation.cpp
@@ -1,80 +1,37 @@
 #include "passmanager.h"
 #include "gtest/gtest.h"
 using namespace xreate;
 //DEBT implement no pkgconfig ways to link libs
 
 //TOTEST FunctionUnit::compileInline
 TEST(Compilation, DISABLED_functionInline1){
 }
 
-TEST(Compilation, Sequence1){
-    PassManager* man = PassManager::prepareForCode(
-        "interface(extern-c){\n"
-        "  libFake = library:: pkgconfig(\"libxml-2.0\").\n"
-        "  \n"
-        "  include {\n"
-        "    libFake = [\"stdio.h\", \"stdlib.h\"]\n"
-        "  }.\n"
-        "}"
-
-        "main = function:: int; entry {\n"
-        "	sequence ["
-        "		printf(\"FIRST-\"),\n"
-        "		printf(\">SECOND\")\n"
-        "	]"
-        "}"
-    );
-
-    int (*main)() = (int (*)()) man->run();
-
-    testing::internal::CaptureStdout();
-    main();
-    std::string output = testing::internal::GetCapturedStdout();
-
-    ASSERT_STREQ("FIRST->SECOND", output.c_str());
-}
-
-TEST(Compilation, Sequence2){
-    PassManager* man = PassManager::prepareForCode(
-        "interface(extern-c){\n"
-        "  libFake = library:: pkgconfig(\"libxml-2.0\").\n"
-        "  \n"
-        "  include {\n"
-        "    libFake = [\"stdio.h\", \"stdlib.h\"]\n"
-        "  }.\n"
-        "}"
+TEST(Compilation, functionEntry1){
+    std::unique_ptr<PassManager> program(PassManager::prepareForCode(
+        "func1 = function(a:: int):: int {a+8} \
+         func2 = function::int; entry {12 + func1(4)}      \
+        "));
 
-        "main = function:: int; entry {\n"
-        "	context:: expectNoErrors.  "
-        "	buf1 = \"aaaaa\"::string.\n"
-        "	buf2 = \"aaaaa\"::string.\n"
-        "	sequence ["
-        "		sprintf(buf1, \"%d\", system(\"bazaar --version\")),"
-        "		sprintf(buf2, \"%d\", system(\"svn --version\")),"
-        "		printf(buf1),\n"
-        "		printf(buf2)\n"
-                "]"
-        "}"
-    );
+    void* entryPtr = program->run();
+    int (*entry)() = (int (*)())(intptr_t)entryPtr;
 
-    int (*main)() = (int (*)()) man->run();
-    main();
+    int answer = entry();
+    ASSERT_EQ(24, answer);
 }
 
-
 TEST(Compilation, full_IFStatementWithVariantType){
     PassManager* man = PassManager::prepareForCode(
-        "COLORS = type variant (RED, BLUE, GREEN).\n"
+        "Color = type variant (RED, BLUE, GREEN).\n"
         "\n"
-        "   main = function(x::int):: int; entry {\n"
-        "       color = if (x == 0 )::COLORS {RED} else {BLUE}.\n"
-        "       if (color == BLUE)::int {1} else {0}\n"
+        "   main = function(x::int):: bool; entry {\n"
+        "       color = if (x == 0 )::Color {RED} else {BLUE}.\n"
+        "       if (color == BLUE)::bool {true} else {false}\n"
         "   }"
     );
 
-    int (*main)(int) = (int (*)(int)) man->run();
-    ASSERT_EQ(0, main(0));
-    ASSERT_EQ(1, main(1));
+    bool (*main)(int) = (bool (*)(int)) man->run();
+    ASSERT_FALSE(main(0));
+    ASSERT_TRUE(main(1));
 }
 
-
diff --git a/cpp/tests/containers.cpp b/cpp/tests/containers.cpp
index 9d044d5..a9f3c2b 100644
--- a/cpp/tests/containers.cpp
+++ b/cpp/tests/containers.cpp
@@ -1,96 +1,109 @@
 /*
  * containers.cpp
  *
  *  Created on: Jun 9, 2015
- *      Author: pgess
+ *  Author: pgess
  */
 
 #include "passmanager.h"
 #include "query/containers.h"
 #include "Parser.h"
 #include "gtest/gtest.h"
 
 using namespace std;
 using namespace xreate;
 using namespace containers;
 
 TEST(Containers, ListAsArray){
     PassManager* man = PassManager::prepareForCode(
 
 R"Code(
     main = function(x:: int):: int;entry {
             a = [1, 2, 3]:: [int].
             a[x]
     }
 )Code"          );
 
     void* mainPtr = man->run();
     int (*main)(int) = (int (*)(int))mainPtr;
     ASSERT_EQ(2, main(1));
 
     delete man;
 }
 
 TEST(Containers, ListAsArray2){
     PassManager* man = PassManager::prepareForCode(
 
 R"Code(
+                        // CONTAINERS
+    interface(dfa) {
+      operator map::  (op(seqaccess)) -> impl(solid).
+      operator list_range:: ()->impl(on_the_fly).
+      operator list:: ()->impl(solid).
+      operator fold:: (op(seqaccess)).
+      operator index:: (op(randaccess)).
+    }
+
+    import raw("core/containers.lp")
+
     main = function:: int;entry {
+
+
             a= [1, 2, 3]:: [int].
             b= loop map(a->el:: int):: [int]{
                 2 * el
             }.
 
             sum = loop fold(b->el:: int, 0->acc):: int {
                 acc + el
             }.
 
             sum
     }
 )Code"          );
 
     void* mainPtr = man->run();
     int (*main)() = (int (*)())mainPtr;
-    ASSERT_EQ(0, main());
+    ASSERT_EQ(12, main());
 
     delete man;
 }
 
 TEST(Containers, ContanierLinkedList1){
 	FILE* input = fopen("scripts/testspass/Containers_Implementation_LinkedList1.xreate","r");
 	assert(input != nullptr);
 
 	Scanner scanner(input);
 	Parser parser(&scanner);
 	parser.Parse();
 
 	AST& ast = parser.root;
 	CodeScope* body = ast.findFunction("test")->getEntryScope();
-	Symbol symb_chilrenRaw = body->findSymbol("childrenRaw");
+	const Symbol symb_chilrenRaw{body->getSymbol("childrenRaw"), body};
 
 	containers::ImplementationLinkedList iLL(symb_chilrenRaw);
 
 	ASSERT_EQ(true, static_cast<bool>(iLL));
 	ASSERT_EQ("next", iLL.fieldPointer);
 
 	Implementation impl = Implementation::create(symb_chilrenRaw);
 	ASSERT_NO_FATAL_FAILURE(impl.extract<ON_THE_FLY>());
 
 	ImplementationRec<ON_THE_FLY> recOnthefly = impl.extract<ON_THE_FLY>();
 	ASSERT_EQ(symb_chilrenRaw, recOnthefly.source);
 }
 
 TEST(Containers, Implementation_LinkedListFull){
 	FILE* input = fopen("scripts/testspass/Containers_Implementation_LinkedList1.xreate","r");
 	assert(input != nullptr);
 
     std::unique_ptr<PassManager> program(PassManager::prepareForCode(input));
 	void* mainPtr = program->run();
 	int (*main)() = (int (*)())(intptr_t)mainPtr;
 
 	int answer = main();
 	ASSERT_EQ(17, answer);
 
 	fclose(input);
 }
 
diff --git a/cpp/tests/context.cpp b/cpp/tests/context.cpp
index 847dab1..796fee1 100644
--- a/cpp/tests/context.cpp
+++ b/cpp/tests/context.cpp
@@ -1,495 +1,496 @@
 /*
  * frame-context.cpp
  *
  *  Created on: Dec 3, 2015
  *      Author: pgess
  */
 
 #include "passmanager.h"
 #include "query/context.h"
 
 #include "gtest/gtest.h"
 #include <iostream>
 #include <boost/scoped_ptr.hpp>
 
 using namespace xreate;
 
 TEST(Context, frame_Context1){
 	PassManager* man = PassManager::prepareForCode(
 		"	import raw (\"core/control-context.lp\")\n"
 		"	compute = function::int {\n"
 		"		0\n"
 		"	}\n"
 
 		"	computeFast = function:: int {\n"
 		"		context:: computation(fast).\n"
 
 		"		compute()\n"
 		"	}\n"
 
 		"	computePrecisely = function:: int {\n"
 		"		context:: computation(precise). \n"
 
 		"		compute()\n"
 		"	}\n"
 
                 "test = function(cmnd:: int):: int; entry {\n"
                 "   context:: arithmetic(iee754). \n"
 
                 "   if (cmnd > 0)::int {computePrecisely()} else {computeFast()} \n"
                 "}\n"
 	);
 
 	ContextQuery* query = (ContextQuery*) man->clasp->registerQuery(new ContextQuery(), QueryId::ContextQuery);
 	man->runWithoutCompilation();
 
 	CodeScope* scopeTestC = man->root->findFunction("compute")->getEntryScope();
 	const Domain& context = query->getContext(man->clasp->pack(scopeTestC));
 
 	int contextSize = context.size();
 	EXPECT_EQ(1, contextSize); //arithmetic(iee754)
 }
 
 TEST(Context, contextAsRequirementSuccessful1){
 	PassManager* man = PassManager::prepareForCode(
 		"       import raw (\"core/control-context.lp\")\n"
 
                 "       case context::safe {\n"
 		"	funcSensitive = function::int {\n"
 		"		0\n"
 		"	}}\n"
 
 		"	test = function:: int; entry {\n"
 		"		context:: safe; test.\n"
 
 		"		funcSensitive()\n"
 		"	}\n"
 	);
 
 	int (*main)() = (int (*)()) man->run();
 	ASSERT_EQ(0, main());
 }
 
 TEST(Context, contextAsRequirementFailed){
 	PassManager* man = PassManager::prepareForCode(
 		"       import raw (\"core/control-context.lp\")\n"
 
                 "       case context::safe {\n"
 		"	funcSensitive = function::int {\n"
 		"		0\n"
 		"	}}\n"
 
 		"	test = function:: int; entry {\n"
 		"		context:: non_safe; test.\n"
 
 		"		funcSensitive()\n"
 		"	}\n"
 	);
 
 	ASSERT_DEATH(man->run(), "findFunction");
 }
 
 TEST(Context, ContextPropagationNested){
 	PassManager* man = PassManager::prepareForCode(
 		"       import raw (\"core/control-context.lp\")\n"
 
                 "       case context::safe {\n"
 		"	square = function(x:: int) ::int {\n"
 		"		x * x\n"
 		"	}}\n"
 
 		"	test = function:: int; entry {\n"
 		"		context:: safe; test.\n"
 
                 "               range = [1..10]:: [int].   \n"
                 "               loop fold(range->x::int, 0->acc):: int {   \n"
                 "                   acc + square(x)    \n"
                 "               }  \n"
                 "       }\n"
 	);
 
 	int (*main)() = (int (*)()) man->run();
 	ASSERT_EQ(385, main());
 }
 
 TEST(Context, ContextPropagationNestedInterfunction){
 
 	PassManager* man = PassManager::prepareForCode(
         "	import raw (\"core/control-context.lp\")\n"
 	"	case context::toMillimeters {\n"
 	"		convertConcrete = function(source:: num)::num {\n"
 	"			10 * source \n"
 	"		}\n"
 	"	}\n"
 
 	"	case context::toInches {\n"
 	"		convertConcrete = function(source:: num)::num {\n"
 	"			2 * source \n"
 	"		}\n"
 	"	}\n"
 
         "convert= function(source:: num):: num { \n"
                 "convertConcrete(source) \n"
         "} \n"
 
 	"test = function(source:: num):: num; entry {\n"
 	"	context:: toMillimeters.\n"
 	"	convert(1)\n"
 	"}\n" );
 
 	int (*main)(int) = (int (*)(int)) man->run();
 	ASSERT_EQ(10, main(1));
 }
 
 TEST(Context, full_ContextBasedFunctionSpecialization){
 
 	PassManager* man = PassManager::prepareForCode(
         "	import raw (\"core/control-context.lp\")\n"
 	"	case context::toMillimeters {\n"
 	"		convert = function(source:: num)::num {\n"
 	"					10 * source \n"
 	"		}\n"
 	"	}\n"
 
 	"	case context::toInches {\n"
 	"		convert = function(source:: num)::num {\n"
 	"			2 * source \n"
 	"		}\n"
 	"	}\n"
 
 	"test = function(vrnt:: int)::int; entry {\n"
 	"		switch(vrnt):: int\n"
-	"		case 0 {\n"
+	"		case (0) {\n"
 	"			context:: toMillimeters.\n"
 	"			convert(1)\n"
 	"		}\n"
 	"\n"
-	"		case 1 {\n"
+	"		case (1) {\n"
 	"			context:: toInches.\n"
 	"			convert(1)\n"
 	"		}\n"
 	"		case default {0}\n"
 	"	}" );
 
 	int (*main)(int) = (int (*)(int)) man->run();
 	ASSERT_EQ(10, main(0));
 	ASSERT_EQ(2, main(1));
 }
 
-//TOODO recover context loop and enable the test
-TEST(Context, full_LoopContext){
-
-	PassManager* man = PassManager::prepareForCode(
-        "	import raw (\"core/control-context.lp\")\n"
-        "       case context:: a {\n"
-	"	print = function:: string {\n"
-	"		\"a\"\n"
-	"	}}\n"
-	"\n"
-	"	case context:: b {\n"
-	"	print = function:: string {\n"
-	"		\"b\"\n"
-	"	}}\n"
-	"\n"
-	"	case context:: c {\n"
-	"	print = function:: string {\n"
-	"		\"c\"\n"
-	"	}}\n"
-	"\n"
-	"	case context:: d {\n"
-	"	print = function:: string {\n"
-	"		\"d\"\n"
-	"	}}\n"
-	"\n"
-	"	start = function(command::int)::string; entry {\n"
-	"		switch (command) :: string \n"
-	"		case 0 {\n"
-	"			context:: print(a); print(b); print(d).\n"
-	"\n"
-	"			loop context (\"print\") {\n"
-	"				print()\n"
-	"			}\n"
-	"		}\n"
-	"\n"
-	"		case default {\n"
-	"			context:: print(c).\n"
-	"			loop context (\"print\") {\n"
-	"				print()\n"
-	"			}\n"
-	"		}\n"
-	"	}");
-
-
-	char* (*main)(int)  =(char* (*)(int)) man->run();
-	ASSERT_STREQ("c", main(1));
-	ASSERT_STREQ("a", main(0));
-}
-
 TEST(Context, full_RuleContext){
 	/*
 	"rule context:: childs(Child)\n"
 	"	case artefact(Item)\n"
 	"	{\n"
 	"		artefact_depends(Item, Child)\n"
 	"	}";
 	*/
 
 	PassManager* man = PassManager::prepareForCode(
                 "	import raw (\"core/control-context.lp\")\n"
 		"	case context:: toMilli {\n"
 		"		convert = function(length::int)::int{\n"
 		"			10 * length\n"
 		"		}\n"
 		"	}\n"
 		"\n"
 		"	case context:: toCenti {\n"
 		"		convert = function(length::int)::int{\n"
 		"			length\n"
 		"		}\n"
 		"	}\n"
 		"\n"
 		"	main=function::int; entry {\n"
 		"		context:: output(milli).\n"
 		"\n"
 		"		rule context::toMilli\n"
-		"		case output(milli) {true}\n"
+		"		case (output(milli)) {truth}\n"
 		"\n"
 		"		convert(1)\n"
 		"	}" );
 
-	man->clasp->addRawScript("true.");
+	man->clasp->addRawScript("truth.");
 	int (*entry)() = (int (*)()) man->run();
 	ASSERT_EQ(10, entry());
 }
 
 TEST(Context, full_InheritedRuleContext){
     PassManager* man = PassManager::prepareForCode(
 "	import raw (\"core/control-context.lp\") \n"
 
 "	case context:: toMilli {\n"
 "		convert = function(length::int)::int{\n"
 "			10 * length\n"
 "		}\n"
 "	}\n"
 
 "	case context:: toCenti {\n"
 "		convert = function(length::int)::int{\n"
 "			length\n"
 "		}\n"
 "	}\n"
 "\n"
 
 "main = function(comm:: num)::num; entry{\n"
-"		rule context::X case output(X) {true}\n"
+"		rule context::X case (output(X)) {truth}\n"
 "\n"
 "		switch (comm)::num \n"
-"			case 0 {\n"
+"			case (0) {\n"
 "				context:: output(toMilli).\n"
 "				convert(1)\n"
 "			}\n"
 "			case default {\n"
 "				context:: output(toCenti).\n"
 "				convert(1)\n"
 "			}\n"
 "	}");
 
-    man->clasp->addRawScript("true.");
+    man->clasp->addRawScript("truth.");
     int (*entry)(int) = (int (*)(int)) man->run();
     ASSERT_EQ(10, entry(0));
     ASSERT_EQ(1, entry(1));
 }
 
 
 
 TEST(Context, full_LateContext){
 	PassManager* man = PassManager::prepareForCode(
 		"import raw (\"core/control-context.lp\")\n"
 
 		"    convert = function(length:: num)::num{\n"
 		"        0\n"
 		"    }\n"
 
 		"case context:: milli {\n"
 		"    convert = function(length:: num)::num{\n"
 		"        1000 * length\n"
 		"    }\n"
 		"}\n"
 		"\n"
 		"case context:: centi {\n"
 		"    convert = function(length:: num)::num{\n"
 		"        100 * length\n"
 		"    }\n"
 		"}\n"
 		"\n"
 		"calculate = function(length:: num)::num {\n"
 		"    convert(length)\n"
 		"}\n"
 		"\n"
 		"main = function(com:: num):: num; entry {\n"
 			"    switch (com):: num \n"
-			"    case 0 {\n"
+			"    case (0) {\n"
 			"        context:: milli.\n"
 			"        calculate(1)\n"
 			"    }\n"
 			"\n"
 			"    case default{\n"
 			"        context:: centi. \n"
 			"        calculate(1)\n"
 			"    }\n"
 		"}");
 
 	man->runWithoutCompilation();
 	ContextQuery* queryContext = reinterpret_cast<ContextQuery*>(man->clasp->getQuery(QueryId::ContextQuery));
 	Expression exprSwitch = man->root->findFunction("main")->__entry->getBody();
 	CodeScope* blockDefault = man->root->findFunction("main")->__entry->getBody().operands[1].blocks.front();
 	ScopePacked blockDefaultId = man->clasp->pack(blockDefault);
 	const Domain& domDefault = queryContext->getContext(blockDefaultId);
 	ASSERT_EQ(1, domDefault.count(Expression(Atom<Identifier_t>("centi"))));
 
 	std::list<ManagedFnPtr> variants = man->root->getFunctionVariants("convert");
 	for (ManagedFnPtr f: variants){
 		const Expression guard = f->guardContext;
 		bool result = (guard.getValueString() == "centi" || guard.getValueString() == "milli" || !guard.isValid());
 		ASSERT_TRUE(result);
 	}
 
 	const FunctionDemand& demMain = queryContext->getFunctionDemand("main");
 	ASSERT_EQ(0, demMain.size());
 
 	const FunctionDemand& demCalculate = queryContext->getFunctionDemand("calculate");
 	ASSERT_EQ(1, demCalculate.size());
 
 	int (*entry)(int) = (int (*)(int)) man->run();
 	ASSERT_EQ(1000, entry(0));
 	ASSERT_EQ(100, entry(1));
 }
 
 TEST(Context, loopContextExists){
     PassManager* man = PassManager::prepareForCode (
         "import raw (\"core/control-context.lp\")\n"
 
         "interface(cfa){\n"
         "    operator fold:: annotation1.\n"
         "}\n"
         "\n"
         "main = function:: int; entry {\n"
         "    x = [1..10]:: [int].\n"
         "    sum = loop fold (x->el:: int, 0->sum):: int {\n"
         "        el + sum + f1()\n"
         "    }.  \n"
         "    sum\n"
         "}"
         "case context:: annotation1 {"
         " f1 = function::int {\n"
         "  	x = 0:: int.		 "
         "       x\n"
         " }"
         "}"
     );
 
     man->run();
 }
 
 TEST(Context, pathDependentContext){
     std::string program =
 R"CODE(
 import raw("core/control-context.lp")
 
 convert = function(length:: num) :: num {
     0
 }
 
 case context:: convert(milli, meters) {
     convert = function(length:: num) :: num {
         1000 * length
     }
 }
 
 case context:: convert(centi, meters) {
     convert = function(length:: num) :: num {
         100 * length
     }
 }
 
 case context:: convert(centi, kilo) {
     convert = function(length:: num) :: num {
         100000 * length
     }
 }
 
 case context:: convert(milli, kilo) {
     convert = function(length:: num) :: num {
         1000000 * length
     }
 }
 
 main = function(value::num, unitsInput::num, unitsOutput::num)::num; entry{
     switch (unitsInput)::num
-    case 0 {
+    case (0) {
         test_fromMilli(value, unitsOutput)
     }
-    case 1 {
+    case (1) {
         test_fromCenti(value, unitsOutput)
     }
 
     case default {0}
 }
 
 test_fromCenti = function(value::num, output::num)::num{
     context:: input(centi).
 
     switch(output):: num
-    case 0  {
+    case (0)  {
         toMeters(value)
     }
 
-    case 1 {
+    case (1) {
         toKilo(value)
     }
 
     case default {0}
 }
 
 test_fromMilli = function(value::num, output::num)::num{
     context:: input(milli).
 
     switch(output):: num
-    case 0  {
+    case (0)  {
         toMeters(value)
     }
 
-    case 1 {
+    case (1) {
         toKilo(value)
     }
 
     case default {0}
 }
 
 toMeters = function(value::num)::num {
-        rule context:: convert(X, meters) case input(X) {true}
+        rule context:: convert(X, meters) case (input(X)) {truth}
 
         doConvert(value)
 }
 
 toKilo = function(value::num)::num {
-        rule context:: convert(X, kilo) case input(X) {true}
+        rule context:: convert(X, kilo) case (input(X)) {truth}
 
         doConvert(value)
 }
 
 doConvert = function(value::num)::num{
    convert(value)
 })CODE";
 
     boost::scoped_ptr<PassManager> man(PassManager::prepareForCode(move(program)));
+    man->clasp->addRawScript("truth.");
     man->runWithoutCompilation();
 
     int (*test)(int, int, int) = (int (*)(int, int, int))man->run();
 
     enum {INPUT_MILLI, INPUT_CENTI};
     enum {OUTPUT_METERS, OUTPUT_KILO};
 
     ASSERT_EQ(1000000, test(1, INPUT_MILLI, OUTPUT_KILO));
     ASSERT_EQ(200, test(2, INPUT_CENTI, OUTPUT_METERS));
 }
 
+//TODO recover context loop and enable the test
+TEST(Context, DISABLED_full_LoopContext){
+
+	PassManager* man = PassManager::prepareForCode(
+        "	import raw (\"core/control-context.lp\")\n"
+        "       case context:: a {\n"
+	"	print = function:: string {\n"
+	"		\"a\"\n"
+	"	}}\n"
+	"\n"
+	"	case context:: b {\n"
+	"	print = function:: string {\n"
+	"		\"b\"\n"
+	"	}}\n"
+	"\n"
+	"	case context:: c {\n"
+	"	print = function:: string {\n"
+	"		\"c\"\n"
+	"	}}\n"
+	"\n"
+	"	case context:: d {\n"
+	"	print = function:: string {\n"
+	"		\"d\"\n"
+	"	}}\n"
+	"\n"
+	"	start = function(command::int)::string; entry {\n"
+	"		switch (command) :: string \n"
+	"		case (0) {\n"
+	"			context:: print(a); print(b); print(d).\n"
+	"\n"
+	"			loop context (\"print\") {\n"
+	"				print()\n"
+	"			}\n"
+	"		}\n"
+	"\n"
+	"		case default {\n"
+	"			context:: print(c).\n"
+	"			loop context (\"print\") {\n"
+	"				print()\n"
+	"			}\n"
+	"		}\n"
+	"	}");
+
+
+	char* (*main)(int)  =(char* (*)(int)) man->run();
+	ASSERT_STREQ("c", main(1));
+	ASSERT_STREQ("a", main(0));
+}
+
diff --git a/cpp/tests/effects-versions.cpp b/cpp/tests/effects-versions.cpp
new file mode 100644
index 0000000..3ca9fb4
--- /dev/null
+++ b/cpp/tests/effects-versions.cpp
@@ -0,0 +1,276 @@
+/*
+ *  Created on: Dec 16, 2016
+ *      Author: pgess
+ */
+
+#include "pass/versionspass.h"
+#include "passmanager.h"
+
+#include "gtest/gtest.h"
+
+using namespace xreate;
+
+TEST(Effects, syntax_versions_1){
+    PassManager* man = PassManager::prepareForCode(R"Code(
+            test= function(a:: num):: num; entry {
+                x= b[8].
+                b = 5:: num.
+                x{1} = a:: num.
+
+                x{1} + a
+            }
+    )Code");
+}
+
+TEST(Effects, analysis_versions_1){
+    PassManager* man = PassManager::prepareForCode(
+    R"Code(
+            test= function:: num; entry {
+                x{0}= 3:: int.
+                x{1} = x{0} + 1.
+
+                x{1}
+            }
+    )Code");
+
+    VersionsPass* pass = new VersionsPass(man);
+    pass->run();
+
+    VersionsGraph graph = pass->getResultGraph();
+    ASSERT_TRUE(graph.validate());
+}
+
+TEST(Effects, analysis_versions_2){
+    PassManager* man = PassManager::prepareForCode(
+    R"Code(
+            test= function(a:: num):: num; entry {
+                x{0}= 3:: int.
+                b = [1, 2, x{0}].
+                x{1} = b[2].
+
+                x{1} + a
+            }
+    )Code");
+
+    VersionsPass* pass = new VersionsPass(man);
+    pass->run();
+
+    VersionsGraph graph = pass->getResultGraph();
+    ASSERT_TRUE(graph.validate());
+}
+
+TEST(Effects, analysis_versions_2_1_fail){
+    PassManager* man = PassManager::prepareForCode(
+    R"Code(
+            test= function(a:: num):: num; entry {
+                x{0}= 5:: int.
+                b = x{0}.
+                x{1} = 2.
+
+                b + x{1}
+            }
+    )Code");
+
+    VersionsPass* pass = new VersionsPass(man);
+    pass->run();
+
+    VersionsGraph graph = pass->getResultGraph();
+    graph.__debug_print(std::cout);
+    ASSERT_FALSE(graph.validate());
+}
+
+TEST(Effects, analysis_versions_2_2){
+    PassManager* man = PassManager::prepareForCode(
+    R"Code(
+            test= function(a:: num):: num; entry {
+                x{0}= 5:: int.
+                b = intrinsic copy(x{0}).
+                x{1} = 2.
+
+                b + x{1}
+            }
+    )Code");
+
+    VersionsPass* pass = new VersionsPass(man);
+    pass->run();
+
+    VersionsGraph graph = pass->getResultGraph();
+    graph.__debug_print(std::cout);
+    ASSERT_TRUE(graph.validate());
+}
+
+TEST(Effects, analysis_versions_3){
+    PassManager* man = PassManager::prepareForCode(
+    R"Code(
+            test= function:: num; entry {
+                x{0}= 3:: int.
+                a = x{0}:: int.
+                b = a :: int.
+                x{1} = b.
+
+                x{1}
+            }
+    )Code");
+
+    VersionsPass* pass = new VersionsPass(man);
+    pass->run();
+
+    VersionsGraph graph = pass->getResultGraph();
+    graph.__debug_print(std::cout);
+    ASSERT_TRUE(graph.validate());
+    std::cout << "========================\n";
+    graph.__debug_print(std::cout);
+    AttachmentsContainerDefault<std::list<Symbol>>* attachmentsDependency = graph.representAsAttachments();
+
+    CodeScope* scope = man->root->findFunction("test")->getEntryScope();
+    const std::list<Symbol>& dependenciesX1  = attachmentsDependency->get(Symbol{ScopedSymbol{1, 1}, scope});
+    ASSERT_EQ(3, dependenciesX1.size());
+}
+
+TEST(Effects, compilation_versions_1){
+    PassManager* man = PassManager::prepareForCode(
+    R"Code(
+    test= function:: num; entry {
+        x{1} = b.
+        b = a :: int.
+        a = x{0}:: int.
+        x{0}= 3:: int.
+
+        x{1}
+    }
+    )Code");
+
+    man->runWithoutCompilation();
+    if (!man->isPassRegistered(PassId::VersionsPass)){
+            VersionsPass* pass = new VersionsPass(man);
+            pass->run();
+            pass->finish();
+    }
+
+    int (*body)() = (int (*)())man->run();
+    int answer = body();
+
+    ASSERT_EQ(3, answer);
+}
+
+TEST(Effects, compilation_versions_versionInit1){
+    PassManager* man = PassManager::prepareForCode(
+    R"Code(
+    test= function:: num; entry {
+        x{0} = 3.
+
+        x{0}
+    }
+    )Code");
+
+    man->runWithoutCompilation();
+    if (!man->isPassRegistered(PassId::VersionsPass)){
+            VersionsPass* pass = new VersionsPass(man);
+            pass->run();
+            pass->finish();
+    }
+
+    int (*body)() = (int (*)())man->run();
+    int answer = body();
+
+    ASSERT_EQ(3, answer);
+}
+
+TEST(Effects, compilation_versions_versionNext1){
+    PassManager* man = PassManager::prepareForCode(
+    R"Code(
+    test= function:: num; entry {
+        x{0} = 5.
+        x{1} = x{0} - 2.
+
+        x{1}
+    }
+    )Code");
+
+    man->runWithoutCompilation();
+    if (!man->isPassRegistered(PassId::VersionsPass)){
+            VersionsPass* pass = new VersionsPass(man);
+            pass->run();
+            pass->finish();
+    }
+
+    int (*body)() = (int (*)())man->run();
+    int answer = body();
+
+    ASSERT_EQ(3, answer);
+}
+
+TEST(Effects, compilation_versions_IntrinsicCopy1){
+    PassManager* man = PassManager::prepareForCode(
+    R"Code(
+    test= function:: num; entry {
+        x{0} = 5.
+        b = intrinsic copy (x{0}).
+        x{1} = 2.
+
+        b - x{1}
+    }
+    )Code");
+
+    man->runWithoutCompilation();
+    if (!man->isPassRegistered(PassId::VersionsPass)){
+            VersionsPass* pass = new VersionsPass(man);
+            pass->run();
+            pass->finish();
+    }
+
+    int (*body)() = (int (*)())man->run();
+    int answer = body();
+
+    ASSERT_EQ(3, answer);
+}
+
+TEST(Effects, compilation_versions_varexchange){
+    PassManager* man = PassManager::prepareForCode(
+    R"Code(
+    test= function:: num; entry {
+            a{0} = 3.
+            b{0} = 5.
+            tmp = intrinsic copy (a{0}).
+            a{1} = b{0}.
+            b{1} = tmp.
+
+            b{1}
+    }
+    )Code");
+
+    man->runWithoutCompilation();
+    if (!man->isPassRegistered(PassId::VersionsPass)){
+            VersionsPass* pass = new VersionsPass(man);
+            pass->run();
+            pass->finish();
+    }
+
+    int (*body)() = (int (*)())man->run();
+    int answer = body();
+
+    ASSERT_EQ(3, answer);
+}
+
+
+
+
+
+/*
+TEST(Effects, analysis_versions_copy){
+
+}
+
+TEST(Effects, syntax_references1){
+
+}
+
+TEST(Effects, syntax_scope_versions1){
+
+}
+
+TEST(Effects, DynamicVersions_analysis){
+
+}
+ */
+
diff --git a/cpp/tests/externc.cpp b/cpp/tests/externc.cpp
index 2542a4e..b8f9536 100644
--- a/cpp/tests/externc.cpp
+++ b/cpp/tests/externc.cpp
@@ -1,108 +1,106 @@
 #include "gtest/gtest.h"
 #include "passmanager.h"
 #include "Scanner.h"
 #include "Parser.h"
 #include <iostream>
 #include <llvm/Support/DynamicLibrary.h>
 
 using namespace std;
 
 TEST(InterfaceExternC, testAST) {
     std::string code = "											\
 			interface(extern-c){									\
 			  xml2 = library:: pkgconfig(\"libxml-2.0\").				\
 			  	  	  	  	  	  	  	  	  	  	  	  	  	  	\
 			  include {												\
 			    xml2 = [\"libxml/tree.h\"]							\
 			  }.													\
 			}   													\
 			";
 
     Scanner scanner(reinterpret_cast<const unsigned char*> (code.c_str()), code.size());
     Parser parser(&scanner);
     parser.Parse();
 
     ASSERT_EQ(1, parser.root.__externdata.size());
 
     for (const ExternEntry& lib : parser.root.__externdata) {
         ASSERT_EQ("libxml-2.0", lib.package);
         ASSERT_EQ(1, lib.headers.size());
         ASSERT_EQ("libxml/tree.h", lib.headers.at(0));
     }
 }
 
 TEST(InterfaceExternC, testfetchPackageHeaders) {
     ExternEntry entry{"libxml-2.0",
         {}};
 
     vector<string> args = ExternLayer::fetchPackageFlags(entry);
     ASSERT_EQ(1, args.size());
     ASSERT_EQ("-I/usr/include/libxml2", args.at(0));
 }
 
 TEST(InterfaceExternC, testfetchPackageLibs) {
     ExternEntry entry{"libxml-2.0",
         {}};
 
     vector<string> args = ExternLayer::fetchPackageLibs(entry);
     ASSERT_EQ(1, args.size());
     ASSERT_EQ("xml2", args.at(0));
 
 }
 
 TEST(InterfaceExternC, testLoadLib) {
     std::string msgErr;
     if (!llvm::sys::DynamicLibrary::LoadLibraryPermanently("-lpcre -lxml2", &msgErr)) {
         cout << msgErr;
         ASSERT_EQ("", msgErr);
     }
 
     ASSERT_TRUE(true);
 }
 
 TEST(InterfaceExternC, testBSD1) {
     std::string code = "                            \n\
         interface(extern-c){                        \n\
           libbsd = library:: pkgconfig(\"libbsd\"). \n\
                                                     \n\
           include {                                 \n\
             libbsd = [\"bsd/stdlib.h\"]             \n\
           }.                                        \n\
         }                                           \n"
 
         "main= function:: int; entry{arc4random_uniform(24) }";
 
     std::unique_ptr<PassManager> program(PassManager::prepareForCode(move(code)));
 
     void* entryPtr = program->run();
     int (*entry)() = (int (*)())(intptr_t) entryPtr;
 
     int answer = 24;
     answer = entry();
     cout << answer;
     ASSERT_LT(answer, 24);
 }
 
 TEST(InterfaceExternC, testStructFields1) {
     FILE* input = fopen("scripts/testspass/Containers_Implementation_LinkedList1.xreate", "r");
     assert(input != nullptr);
 
     Scanner scanner(input);
     Parser parser(&scanner);
     parser.Parse();
 
     AST& ast = parser.root;
     CodeScope* body = ast.findFunction("test")->getEntryScope();
 
-    Symbol symbTree = body->findSymbol("tree");
-
-    const TypeAnnotation& tTree = CodeScope::findDeclaration(symbTree).type;
+    const TypeAnnotation& tTree = body->getDeclaration(body->getSymbol("tree")).type;
     const ExpandedType& t2Tree = ast.expandType(tTree);
     LLVMLayer llvm(&ast);
     TypeUtils utils(&llvm);
 
     std::vector<std::string>fields = utils.getStructFields(t2Tree);
 
     auto field = std::find(fields.begin(), fields.end(), "children");
     ASSERT_TRUE(field != fields.end());
 }
diff --git a/cpp/tests/interpretation.cpp b/cpp/tests/interpretation.cpp
index 615ad92..8d0ade4 100644
--- a/cpp/tests/interpretation.cpp
+++ b/cpp/tests/interpretation.cpp
@@ -1,340 +1,369 @@
 #include "attachments.h"
 
 using namespace xreate;
 
 #include "passmanager.h"
 #include "compilation/targetinterpretation.h"
 
 #include "gtest/gtest.h"
 #include "boost/scoped_ptr.hpp"
 
 #define private public
 #include "Parser.h"
 #include "pass/interpretationpass.h"
 
 using namespace xreate;
 using namespace xreate::compilation;
 
 TEST(Interpretation, Analysis_StatementIF_1){
     PassManager* man = PassManager::prepareForCode(
 
 R"Code(
-    main = function::int {
+    main = function::bool {
         x = "a":: string.
 
-        y = if (x=="b"):: string; interpretation(force) {
-            1
+        y = if (x=="b"):: bool; interpretation(force) {
+            true
 
         } else {
-            0
+            false
         }.
 
         y
     }
 )Code"          );
 
-    InterpretationPass* pass;
-    if (man->isPassRegistered(PassId::InterpretationPass)){
-        pass = (InterpretationPass*) man->getPassById(PassId::InterpretationPass);
-    } else {
-        pass = new InterpretationPass(man);
-        pass->run();
-    }
-    Symbol symbolY = man->root->findFunction("main")->__entry->findSymbol("y");
-    InterpretationData& dataSymbolY = Attachments::get<Symbol, InterpretationData>(symbolY);
+    InterpretationPass* pass = new InterpretationPass(man);
+    pass->run();
+
+    CodeScope* scopeEntry = man->root->findFunction("main")->getEntryScope();
+    Symbol symbolY{scopeEntry->getSymbol("y"), scopeEntry};
+    InterpretationData& dataSymbolY = Attachments::get<InterpretationData>(symbolY);
 
     ASSERT_EQ(INTR_ONLY, dataSymbolY.resolution);
 }
 
 TEST(Interpretation, Compilation_StatementIF_1){
     PassManager* man = PassManager::prepareForCode(
 
 R"Code(
     main = function::int; entry {
         x = "a":: string.
 
         y = if (x=="b"):: string; interpretation(force) {
             1
 
         } else {
             0
         }.
 
         y
     }
 )Code"          );
 
     man->runWithoutCompilation();
 
     InterpretationPass* pass;
     if (man->isPassRegistered(PassId::InterpretationPass)){
         pass = (InterpretationPass*) man->getPassById(PassId::InterpretationPass);
     } else {
         pass = new InterpretationPass(man);
         pass->run();
     }
 
 
     int (*main)() = (int (*)())man->run();
     int result = main();
 
     ASSERT_EQ(0, result);
 }
 
 TEST(Interpretation, Analysis_StatementIF_InterpretCondition_1){
     PassManager* man = PassManager::prepareForCode(
 
 R"Code(
     main = function(x:: int):: int {
-        comm= "inc":: string.
+        comm= "inc":: string; interpretation(force).
 
-		y = if (comm == "inc") {x+1} else {x}.
-		y
+        y = if (comm == "inc")::int {x+1} else {x}.
+        y
     }
-)Code"          );
+)Code" );
 
-    InterpretationPass* pass;
-    if (man->isPassRegistered(PassId::InterpretationPass)){
-        pass = (InterpretationPass*) man->getPassById(PassId::InterpretationPass);
-    } else {
-        pass = new InterpretationPass(man);
-        pass->run();
-    }
+    InterpretationPass* pass = new InterpretationPass(man);
+    pass->run();
 
-    Symbol symbolY = man->root->findFunction("main")->__entry->findSymbol("y");
-    InterpretationData& dataSymbolY = Attachments::get<Symbol, InterpretationData>(symbolY);
+    CodeScope* scopeEntry = man->root->findFunction("main")->getEntryScope();
+    Symbol symbolY{scopeEntry->getSymbol("y"), scopeEntry};
+    InterpretationData& dataSymbolY = Attachments::get<InterpretationData>(symbolY);
 
-    ASSERT_EQ(ANY, dataSymbolY.resolution);
+    ASSERT_EQ(CMPL_ONLY, dataSymbolY.resolution);
     ASSERT_EQ(IF_INTERPRET_CONDITION, dataSymbolY.op);
 }
 
 TEST(Interpretation, Compilation_StatementIF_InterpretCondition_1){
     PassManager* man = PassManager::prepareForCode(
 
 R"Code(
     main = function(x:: int):: int; entry {
         comm= "inc":: string; interpretation(force).
 
-        y = if (comm == "inc") {x+1} else {x}.
+        y = if (comm == "inc")::int {x+1} else {x}.
         y
     }
 )Code"          );
 
     man->runWithoutCompilation();
 
     InterpretationPass* pass;
     if (man->isPassRegistered(PassId::InterpretationPass)){
         pass = (InterpretationPass*) man->getPassById(PassId::InterpretationPass);
     } else {
         pass = new InterpretationPass(man);
         pass->run();
     }
 
     int (*main)(int) = (int (*)(int))man->run();
     int result = main(1);
 
     ASSERT_EQ(2, result);
 }
 
 TEST(Interpretation, Compilation_StatementFOLD_INTERPRET_INPUT_1){
     PassManager* man = PassManager::prepareForCode(
 
 R"Code(
     main = function(x:: int):: int; entry {
         commands = ["inc", "double", "dec"]:: [string]; interpretation(force).
 
         loop fold(commands->comm::string, x->operand):: int{
             switch(comm)::int
 
             case ("inc"){
                 operand + 1
             }
 
             case ("dec"){
                 operand - 1
             }
 
             case ("double"){
                 operand * 2
             }
         }
     }
 )Code"          );
 
     man->runWithoutCompilation();
 
     InterpretationPass* pass;
     if (man->isPassRegistered(PassId::InterpretationPass)){
         pass = (InterpretationPass*) man->getPassById(PassId::InterpretationPass);
     } else {
         pass = new InterpretationPass(man);
         pass->run();
     }
 
+    const ManagedFnPtr& funcMain = man->root->findFunction("main");
+    InterpretationData& dataBody = Attachments::get<InterpretationData>(funcMain);
+    ASSERT_EQ(FOLD_INTERPRET_INPUT, dataBody.op);
+
     int (*main)(int) = (int (*)(int))man->run();
     int result = main(10);
 
     ASSERT_EQ(21, result);
 }
 
 TEST(Interpretation, StatementCall_RecursionNo_1){
     PassManager* man = PassManager::prepareForCode(
 R"Code(
     unwrap = function(data::undef, keys::undef):: undef; interpretation(force){
         loop fold(keys->key::string, data->a):: undef {
            a[key]
         }
     }
 
     start = function::num; entry{
         result = unwrap(
             {
                 a = {
                         b =
                         {
                             c = "core"
                         }
                     }
             }, ["a", "b", "c"])::undef.
 
         result == "core"
     }
 )Code" );
 
     man->runWithoutCompilation();
 
     InterpretationPass* pass;
     if (man->isPassRegistered(PassId::InterpretationPass)){
         pass = (InterpretationPass*) man->getPassById(PassId::InterpretationPass);
     } else {
         pass = new InterpretationPass(man);
         pass->run();
     }
 
     int (*main)() = (int (*)())man->run();
     int result = main();
 
     ASSERT_EQ(1, result);
 }
 
 TEST(Interpretation, StatementCall_RecursionDirect_1){
     PassManager* man = PassManager::prepareForCode(
 R"Code(
     unwrap = function(data:: X):: Y {
         if (data[0] == "a")::Y {0} else {unwrap(data[0])}
     }
 
     entry = function:: i8; entry {
         unwrap([[[["a"]]]]):: i8; interpretation(force)
     }
 )Code" );
 
     man->runWithoutCompilation();
 
     InterpretationPass* pass;
     if (man->isPassRegistered(PassId::InterpretationPass)){
         pass = (InterpretationPass*) man->getPassById(PassId::InterpretationPass);
     } else {
         pass = new InterpretationPass(man);
         pass->run();
     }
 
     InterpretationResolution resolutionActual = pass->process(man->root->findFunction("unwrap"));
     ASSERT_EQ(ANY, resolutionActual);
 
     int (*main)() = (int (*)())man->run();
     int result = main();
 
     ASSERT_EQ(0, result);
 }
 
 TEST(Interpretation, StatementCall_RecursionIndirect_1){
         PassManager* man = PassManager::prepareForCode(
 R"Code(
     funcA = function(data:: X):: Y {
         if (data == "a")::Y {0} else {funcB(data)}
     }
 
     funcB = function(data:: X):: Y {
         if (data == "b")::Y {1} else {funcA(data)}
     }
 
     entry = function:: i8; entry {
         funcA(""):: i8; interpretation(force)
     }
 )Code" );
 
     InterpretationPass* pass = new InterpretationPass(man);
     ASSERT_DEATH(pass->run(), "Indirect recursion detected");
 }
 
 TEST(Interpretation, PartialIntr_1){
     PassManager* man = PassManager::prepareForCode(
 R"Code(
     evaluate= function(argument:: num, code:: string; interpretation(force)):: num {
         switch(code)::int
          case ("inc")    {argument + 1}
          case ("dec")    {argument - 1}
          case ("double") {argument * 2}
     }
 
     main = function::int; entry {
         commands= ["inc", "double", "dec"]:: [string]; interpretation(force).
 
         loop fold(commands->comm::string, 10->operand):: int{
             evaluate(operand, comm)
         }
     }
 )Code" );
 
     InterpretationPass* pass = new InterpretationPass(man);
     pass->run();
 
     ManagedFnPtr fnEvaluate = man->root->findFunction("evaluate");
     InterpretationResolution resFnEvaluate= pass->process(fnEvaluate);
     ASSERT_EQ(CMPL_ONLY, resFnEvaluate);
     ASSERT_TRUE(FunctionInterpretationHelper::needPartialInterpretation(fnEvaluate));
 
     const Expression& exprLoop = man->root->findFunction("main")->__entry->getBody();
-    Symbol symbCallEv{0, exprLoop.blocks.front()};
-    InterpretationData dataCallEv = Attachments::get<Symbol, InterpretationData>(symbCallEv);
+    Symbol symbCallEv{{0, VERSION_NONE}, exprLoop.blocks.front()};
+    InterpretationData dataCallEv = Attachments::get<InterpretationData>(symbCallEv);
     ASSERT_EQ(CMPL_ONLY, dataCallEv.resolution);
     ASSERT_EQ(CALL_INTERPRET_PARTIAL, dataCallEv.op);
 }
 
-TEST(Interpretation, PartialIntr_2){
+TEST(Interpretation, Compilation_PartialIntr_2){
     PassManager* man = PassManager::prepareForCode(
 R"Code(
     evaluate= function(argument:: num, code:: string; interpretation(force)):: num {
         switch(code)::int
-         case ("inc")    {argument + 1}
-         case ("dec")    {argument - 1}
-         case ("double") {argument * 2}
-         case default {argument}
+        case ("inc")    {argument + 1}
+        case ("dec")    {argument - 1}
+        case ("double") {argument * 2}
+        case default {argument}
     }
 
     main = function::int; entry {
         commands= ["inc", "double", "dec"]:: [string]; interpretation(force).
 
         loop fold(commands->comm::string, 10->operand):: int{
             evaluate(operand, comm)
         }
     }
 )Code" );
 
-    InterpretationPass* pass = new InterpretationPass(man);
-    pass->run();
+    man->runWithoutCompilation();
+    if (!man->isPassRegistered(PassId::InterpretationPass)){
+        InterpretationPass* pass = new InterpretationPass(man);
+        pass->run();
+    }
 
     int (*main)() = (int (*)())man->run();
     int result = main();
 
     ASSERT_EQ(21, result);
 }
 
-//TOTEST call indirect recursion(w/o tags)
-//TASK implement and test Loop Inf (fix acc types in coco grammar)
+TEST(Interpretation, PartialIntr_3){
+    PassManager* man = PassManager::prepareForCode(
+R"Code(
+    Command= type variant (INC, DEC, DOUBLE).
 
+    evaluate= function(argument:: num, code:: Command; interpretation(force)):: num {
+        switch(code)::int
+        case (INC)    {argument + 1}
+        case (DEC)    {argument - 1}
+        case (DOUBLE) {argument * 2}
+        case default {argument}
+    }
 
+    main = function::int; entry {
+        commands= [INC, DOUBLE, DEC]:: [Command]; interpretation(force).
 
+        loop fold(commands->comm::Command, 10->operand):: int{
+            evaluate(operand, comm)
+        }
+    }
+)Code" );
 
+    man->runWithoutCompilation();
+    if (!man->isPassRegistered(PassId::InterpretationPass)){
+        InterpretationPass* pass = new InterpretationPass(man);
+        pass->run();
+    }
 
+    int (*main)() = (int (*)())man->run();
+    int result = main();
+
+    ASSERT_EQ(21, result);
+}
+
+//TOTEST call indirect recursion(w/o tags)
+//TASK implement and test Loop Inf (fix acc types in coco grammar)
\ No newline at end of file
diff --git a/cpp/tests/loops.cpp b/cpp/tests/loops.cpp
index efa66a5..be08250 100644
--- a/cpp/tests/loops.cpp
+++ b/cpp/tests/loops.cpp
@@ -1,59 +1,178 @@
 #include "passmanager.h"
 
 #include "gtest/gtest.h"
 
 using namespace std;
 
+TEST(Loop, SimpleLoop1){
+    string code =
+R"CODE(
+    main = function:: int; entry {
+        input  = [1..5]:: [int].
+
+        loop fold(input->el::int, 0->sum)::int
+        {
+            sum + el
+        }
+    }
+
+)CODE";
+
+    xreate::PassManager* man = xreate::PassManager::prepareForCode(move(code));
+    int (*funcMain)() = (int (*)()) man->run();
+
+    int answerActual = funcMain();
+    ASSERT_EQ(15, answerActual);
+}
+
 TEST(Loop, Break1){
     string code =
 R"CODE(
     main = function:: int; entry {
-        input  = [0..10]:: [int].
+        input  = [1..10]:: [int].
 
-        loop fold(input->el::int, 0->a)::[int]
+        loop fold(input->el::int, 0->sum)::int
         {
-            if (a>=5)::int {
-                5:: int; break
+            if (sum>5)::int {
+                sum:: int; break
 
-            } else {a+el}
+            } else {sum+el}
         }
     }
 
 )CODE";
 
     xreate::PassManager* man = xreate::PassManager::prepareForCode(move(code));
     int (*funcMain)() = (int (*)()) man->run();
 
     int answerActual = funcMain();
-    ASSERT_EQ(5, answerActual);
+    ASSERT_EQ(6, answerActual);
+}
+
+TEST(Loop, NestedLoopsSimple1){
+    string code =
+R"CODE(
+    main = function:: int; entry {
+        listX  = [1..5]:: [int].
+        loop fold(listX->x::int, 0->acc)::int
+        {
+            listY  = [1..5]:: [int].
+
+            row = loop fold(listY->y::int, 1->acc):: int {
+                acc * ( y + x)
+            }.
+
+            acc + row
+        }
+    }
+
+)CODE";
+
+    xreate::PassManager* man = xreate::PassManager::prepareForCode(move(code));
+    int (*funcMain)() = (int (*)()) man->run();
+    int answerActual = funcMain();
+
+    ASSERT_EQ(55320, answerActual);
+}
+
+TEST(Loop, NestedLoopsBreak1){
+    string code =
+R"CODE(
+    main = function:: int; entry {
+        listX  = [1..5]:: [int].
+        loop fold(listX->x::int, 0->acc)::int
+        {
+            listY  = [1..5]:: [int].
+            row = loop fold(listY->y::int, 1->acc):: int {
+                res = acc * ( y + x) :: int.
+
+                if (res > 20):: int {
+                    20:: int; break
+
+                } else {
+                    res
+                }
+            }.
+
+            acc + row
+        }
+    }
+
+)CODE";
+
+    xreate::PassManager* man = xreate::PassManager::prepareForCode(move(code));
+    int (*funcMain)() = (int (*)()) man->run();
+    int answerActual = funcMain();
+
+    ASSERT_EQ(100, answerActual);
+}
+
+TEST(Loop, NestedLoopsBreak2){
+    string code =
+R"CODE(
+    main = function:: int; entry {
+        listX  = [1..3]:: [int].
+        loop fold(listX->x::int, 0->acc)::int
+        {
+            listY  = [1..5]:: [int].
+            row = loop fold(listY->y::int, 1->acc):: int {
+                res = acc * y :: int.
+
+                if (res > 24):: int {
+                    24:: int; break
+
+                } else {
+                    res
+                }
+            }.
+
+            if (x==3)::int{
+                acc:: int; break
+
+            } else {
+                acc + row
+            }
+        }
+    }
+
+)CODE";
+
+    xreate::PassManager* man = xreate::PassManager::prepareForCode(move(code));
+    int (*funcMain)() = (int (*)()) man->run();
+    int answerActual = funcMain();
+
+    ASSERT_EQ(48, answerActual);
 }
 
+//TEST nested loop breaks.
+//TEST 2 breaks^ outer loop break, inner loop break
+
 TEST(Loop, InfiniteLoop1){
 
     string code =
 R"Code(
     fac = function(x:: int):: int{
         range = [2..x] :: [int].
 
         loop fold(range->i::int, 1->acc)::int {
             acc * i
         }
     }
 
     main = function:: int; entry {
         loop fold inf(2->state) :: int {
             if (fac(state)==120)::int {
                 state::int; break
 
             } else {state + 1}
         }
     }
 
 )Code" ;
 
     xreate::PassManager* man = xreate::PassManager::prepareForCode(move(code));
     int (*funcMain)() = (int (*)()) man->run();
 
     int answerActual = funcMain();
     ASSERT_EQ(5, answerActual);
 }
\ No newline at end of file
diff --git a/cpp/tests/main.cpp b/cpp/tests/main.cpp
index 66078a2..2385205 100644
--- a/cpp/tests/main.cpp
+++ b/cpp/tests/main.cpp
@@ -1,136 +1,15 @@
 #include "utils.h"
 #include <gtest/gtest.h>
 
 using namespace std;
 using namespace xreate;
 
 int main(int argc, char **argv) {
     testing::GTEST_FLAG(color) = "yes";
 
     string testsTemplate = Config::get("tests.template");
     string testsFilter = Config::get(string("tests.templates.") + testsTemplate);
     testing::GTEST_FLAG(filter) = testsFilter;
     testing::InitGoogleTest(&argc, argv);
     return RUN_ALL_TESTS();
 }
-
-//TODO adopt useful tests
-
-//void testParser_1()
-//{
-//    shared_ptr<Scanner> scanner(new Scanner(L"scripts/input.xreate"));
-//    shared_ptr<Parser> parser(new Parser(scanner.get()));
-//    parser->Parse();
-//    flush(cout);
-
-//    AST& root =  parser->root;
-//    LLVMLayer l(&root);
-
-//    root.compile(l);
-//    root.run(l);
-//}
-
-//void testClasp2()
-//{
-//    shared_ptr<Scanner> scanner(new Scanner(L"scripts/input.xreate"));
-//    shared_ptr<Parser> parser(new Parser(scanner.get()));
-//    parser->Parse();
-//    flush(cout);
-
-//    if (parser->errors->count)
-//    {
-//        cout << "Found " << parser->errors->count << " errors. Stop" << endl;
-//        exit(1);
-//    }
-
-//    AST& root =  parser->root;
-//    ClaspLayer clasp;
-
-//        /*
-//    FunctionTagsPass(root).run(clasp);
-//    RulesPass(root).run(clasp);
-
-//    CFGPass(&clasp).run();
-
-//    clasp.1
-//    run();
-//        */
-//}
-
-//void testUnsafeCode1()
-//{
-//    shared_ptr<Scanner> scanner(new Scanner(L"scripts/cases/bugs-code.xreate"));
-//    shared_ptr<Parser> parser(new Parser(scanner.get()));
-//    parser->Parse();
-//    flush(cout);
-
-//    if (parser->errors->count)
-//    {
-//        cout << "Found " << parser->errors->count << " errors. Stop" << endl;
-//        exit(1);
-//    }
-
-//    AST& root =  parser->root;
-//    ClaspLayer clasp;
-
-//        /*
-//    FunctionTagsPass(root).run(clasp);
-//    RulesPass(root).run(clasp);
-
-//    CFGPass(&clasp).run();
-//    //clasp.addRule(":- call(X, Y), tag(Y, unsafe), not tag(X, unsafe), function(X), function(Y).");
-
-//    clasp.run();
-//        */
-//}
-
-//void test_DFG_1()
-//{
-//    shared_ptr<Scanner> scanner(new Scanner(L"scripts/input.xreate"));
-//    shared_ptr<Parser> parser(new Parser(scanner.get()));
-//    parser->Parse();
-//    flush(cout);
-
-//    if (parser->errors->count)
-//    {
-//        cout << "Found " << parser->errors->count << " errors. Stop" << endl;
-//        exit(1);
-//    }
-
-//    PassManager m;
-//    m.clasp = new ClaspLayer();
-
-//    m.llvm = new LLVMLayer(&parser->root);
-//    m.root = & parser->root;
-//    m.clasp->ast = m.root;
-
-//    m.registerPass(new DFAPass(&m));
-//    m.run();
-
-//    m.clasp->run();
-//    m.root->compile(*m.llvm);
-//    m.root->run(*m.llvm);
-//}
-
-//void test_Xml_1()
-//{
-//    shared_ptr<Scanner> scanner(new Scanner(L"scripts/input.xreate"));
-//    shared_ptr<Parser> parser(new Parser(scanner.get()));
-//    parser->Parse();
-//    flush(cout);
-
-//    if (parser->errors->count)
-//    {
-//        cout << "Found " << parser->errors->count << " errors. Stop" << endl;
-//        exit(1);
-//    }
-
-//    PassManager m;
-//    m.root = & parser->root;
-//    m.clasp = new ClaspLayer();
-//    m.clasp->ast = m.root;
-//    m.llvm = new LLVMLayer(&parser->root);
-
-//    m.registerPass(new DFAPass(&m));
-//    m.run();
-//}
diff --git a/cpp/tests/supplemental/versions-algorithm-data_dependency.cpp b/cpp/tests/supplemental/versions-algorithm-data_dependency.cpp
new file mode 100644
index 0000000..7a4612d
--- /dev/null
+++ b/cpp/tests/supplemental/versions-algorithm-data_dependency.cpp
@@ -0,0 +1,296 @@
+
+/*
+ * File: algorithm-data_dependency
+ * Date: Dec 23, 2016
+ * Author: pgess <v.melnychenko@xreate.org>
+ */
+
+#include <unordered_set>
+#include <unordered_map>
+#include <string>
+#include <map>
+#include "gtest/gtest.h"
+#include <initializer_list>
+#include <cstdio>
+
+
+const int V_NOVERSION = -2;
+const int V_ENDOFLIFE = -1;
+
+struct Symbol {
+    std::string name;
+    int version;
+
+    Symbol getNextVersion() const{
+        return Symbol{name, version+1};
+    }
+};
+
+namespace std
+{
+    template<>
+    struct hash<Symbol>
+    {
+        typedef Symbol argument_type;
+        typedef std::size_t result_type;
+        result_type operator()(argument_type const& s) const
+        {
+            result_type const h1 ( std::hash<std::string>()(s.name) );
+            return h1 ^ (s.version << 1); // or use boost::hash_combine
+        }
+    };
+
+    template<>
+    struct equal_to<Symbol>
+    {
+      typedef Symbol argument_type;
+
+      bool operator()(const argument_type& __x, const argument_type& __y) const
+      { return __x.name == __y.name && __x.version == __y.version; }
+    };
+}
+
+//Ограничения:
+// - точно знаем следующую версию на этапе декл. (C.NV.1)
+
+class DDSolver{
+public:
+
+    void l1_applyLowerBound(const Symbol& left, const std::initializer_list<Symbol>& dependencies){
+        for (Symbol right: dependencies){
+                //lower bound:
+            __infs.emplace(left, right);
+            __sups.emplace(right, left);
+        }
+    }
+
+    void l1_applyOwnUpperBound(const Symbol& left){
+                //own upper bound:
+                //C.NV.1
+        __infs.emplace(left.getNextVersion(), left);
+        __sups.emplace(left, left.getNextVersion());
+    }
+
+    void l1_applyDependentUpperBound(const Symbol& left, const std::initializer_list<Symbol>& dependencies){
+            // additionally apply dependent upper bound
+        for (Symbol right: dependencies){
+            auto right2 = right.getNextVersion();
+
+            __infs.emplace(right2, left);
+            __sups.emplace(left, right2);
+        }
+    }
+
+    void addVariable(const Symbol& left, const std::initializer_list<Symbol>& dependencies){
+        l1_applyLowerBound(left, dependencies);
+        l1_applyOwnUpperBound(left);
+
+        //initialization upper bound
+        l1_applyDependentUpperBound(left, dependencies);
+
+    }
+
+    //TODO assert: only aliases allowed
+    void addAlias(const Symbol& left, const std::initializer_list<Symbol>& dependencies){
+        l1_applyLowerBound(left, dependencies);
+        l1_applyOwnUpperBound(left);
+
+        //lifetime upper bound
+        l1_applyDependentUpperBound(left.getNextVersion(), dependencies);
+    }
+
+
+    bool checkCyclicComponent(const Symbol& s, std::unordered_set<Symbol>& symbolsVisited, std::unordered_set<Symbol>& symbolsSups){
+        if (symbolsVisited.count(s)) return false;
+
+        symbolsVisited.insert(s);
+        symbolsSups.insert(s);
+
+        auto rangeInf = __infs.equal_range(s);
+        if (__infs.count(s))
+        for (auto sInf = rangeInf.first; sInf != rangeInf.second; ++sInf){
+            if (symbolsSups.count(sInf->second)) {
+                __flagCycle = std::make_pair(sInf->second, s);
+                return true;
+            }
+            if(checkCyclicComponent(sInf->second, symbolsVisited, symbolsSups)) return true;
+        }
+
+        symbolsSups.erase(s);
+        return false;
+    }
+
+    bool checkCyclicFull(){
+        std::unordered_set<Symbol> symbolsVisited, symbolsSups;
+
+        std::unordered_multimap<Symbol, Symbol>::iterator s;
+        for (s = __infs.begin(); s != __infs.end(); ++s){
+            if(checkCyclicComponent(s->first, symbolsVisited, symbolsSups)) return true;
+        }
+
+        return false;
+    }
+
+    bool validate(){
+        return !checkCyclicFull();
+    }
+
+    void solve(){
+        std::unordered_set<Symbol> binEnabled, binFrontier;
+
+        //seed
+        for (auto edge: __sups){
+            if (! __infs.count(edge.first)){
+                binEnabled.insert(edge.first);
+                binFrontier.insert(edge.first);
+            }
+        }
+
+        while (binFrontier.size()){
+            const Symbol& node= *binFrontier.begin();
+
+            //print node:
+            std:: printf("put (%s, %d)\n",  node.name.c_str(), node.version);
+
+            auto rangeSups = __sups.equal_range(node);
+            for(auto sup=rangeSups.first; sup != rangeSups.second; ++sup){
+                bool flagEnabled = true;
+
+                auto rangeInfs = __infs.equal_range(sup->second);
+                for (auto inf=rangeInfs.first; inf != rangeInfs.second; ++inf){
+                    if (!binEnabled.count(inf->second)){
+                        flagEnabled = false;
+                        break;
+                    }
+                }
+
+                if (flagEnabled){
+                    binEnabled.insert(sup->second);
+                    binFrontier.insert(sup->second);
+                }
+            }
+
+            binFrontier.erase(node);
+        }
+    }
+
+    void solve2(Symbol nodeEntry, std::unordered_set<Symbol>& binPreviousNodes, std::unordered_set<Symbol>& binEnabledNodes){
+        binPreviousNodes.insert(nodeEntry);
+
+        auto rangeChilds = __infs.equal_range(nodeEntry);
+        for(auto node=rangeChilds.first; node != rangeChilds.second; ++node){
+            if (binEnabledNodes.count(node->second)) continue;
+
+            auto nodeError =  binPreviousNodes.find(node->second);
+            if (nodeError != binPreviousNodes.end()){
+                std:: printf("(%s, %d) - (%s, %d)",
+                    nodeError->name.c_str(), nodeError->version,
+                    node->second.name.c_str(), node->second.version);
+                assert(false);
+            }
+
+            solve2(node->second, binPreviousNodes, binEnabledNodes);
+        }
+
+        std:: printf("put (%s, %d)\n",  nodeEntry.name.c_str(), nodeEntry.version);
+        binEnabledNodes.insert(nodeEntry);
+        binPreviousNodes.erase(nodeEntry);
+
+//        auto rangeParents = __sups.equal_range(nodeEntry);
+//        for(auto node=rangeParents.first; node != rangeParents.second; ++node){
+//            std::unordered_set<Symbol> binEmpty;
+//            solve2(node->second, binEmpty, binEnabledNodes);
+//        }
+    }
+
+    void __debug_printGraph(){
+        for (auto edge: __infs){
+             std:: printf("(%s, %d) <- (%s, %d) \n",
+                edge.second.name.c_str(), edge.second.version,
+                edge.first.name.c_str(), edge.first.version);
+        }
+    }
+
+private:
+    std::unordered_multimap<Symbol, Symbol> __sups;
+    std::unordered_multimap<Symbol, Symbol> __infs;
+
+public:
+    std::pair<Symbol, Symbol> __flagCycle;
+};
+
+TEST(Datadependency, test1){
+    DDSolver solver;
+
+    solver.addAlias(Symbol{"c", V_NOVERSION}, {Symbol{"a", 0}});
+    solver.addVariable(Symbol{"a", 1}, {Symbol{"b", 0}});
+    solver.addVariable(Symbol{"b", 1}, {Symbol{"c", V_NOVERSION}});
+
+    solver.__debug_printGraph();
+
+    ASSERT_FALSE(solver.validate());
+
+    std:: printf("(%s, %d) - (%s, %d)",
+        solver.__flagCycle.first.name.c_str(), solver.__flagCycle.first.version,
+        solver.__flagCycle.second.name.c_str(), solver.__flagCycle.second.version);
+}
+
+TEST(Datadependency, test2){
+    DDSolver solver;
+
+    solver.addVariable(Symbol{"c", V_NOVERSION}, {Symbol{"a", 0}});
+    solver.addVariable(Symbol{"a", 1}, {Symbol{"b", 0}});
+    solver.addVariable(Symbol{"b", 1}, {Symbol{"c", V_NOVERSION}});
+
+    ASSERT_TRUE(solver.validate());
+
+    solver.solve();
+}
+
+TEST(Datadependency, test3){
+    DDSolver solver;
+
+    solver.addVariable(Symbol{"c", V_NOVERSION}, {Symbol{"a", 0}});
+    solver.addVariable(Symbol{"a", 1}, {Symbol{"b", 0}});
+    solver.addVariable(Symbol{"b", 1}, {Symbol{"c", V_NOVERSION}});
+
+    std::unordered_set<Symbol> binPreviousNodes, binEnabledNodes;
+    solver.solve2(Symbol{"b", 1}, binPreviousNodes, binEnabledNodes);
+    ASSERT_TRUE(true);
+}
+
+TEST(Datadependency, test4){
+    DDSolver solver;
+
+    solver.addVariable(Symbol{"c", V_NOVERSION}, {Symbol{"a", 0}});
+    solver.addVariable(Symbol{"a", 1}, {Symbol{"b", 0}});
+    solver.addVariable(Symbol{"b", 1}, {Symbol{"c", V_NOVERSION}});
+
+    std::unordered_set<Symbol> binPreviousNodes, binEnabledNodes;
+    solver.solve2(Symbol{"b", 1}, binPreviousNodes, binEnabledNodes);
+    ASSERT_TRUE(true);
+}
+
+TEST(Datadependency, test5){
+    DDSolver solver;
+
+    solver.addAlias(Symbol{"b", V_NOVERSION}, {Symbol{"a", 0}});
+    solver.addVariable(Symbol{"a", 1}, {Symbol{"b", V_NOVERSION}});
+
+            std:: printf("(%s, %d) - (%s, %d)",
+        solver.__flagCycle.first.name.c_str(), solver.__flagCycle.first.version,
+        solver.__flagCycle.second.name.c_str(), solver.__flagCycle.second.version);
+
+    ASSERT_TRUE(solver.validate());
+}
+
+TEST(Datadependency, test6){
+    DDSolver solver;
+
+    solver.addVariable(Symbol{"a", 1}, {Symbol{"a", 0}});
+
+    std::unordered_set<Symbol> binPreviousNodes, binEnabledNodes;
+    solver.solve2(Symbol{"a", 1}, binPreviousNodes, binEnabledNodes);
+
+    ASSERT_TRUE(solver.validate());
+}
\ No newline at end of file
diff --git a/cpp/tests/testClangAPI.h b/cpp/tests/testClangAPI.h
deleted file mode 100644
index aab7ee5..0000000
--- a/cpp/tests/testClangAPI.h
+++ /dev/null
@@ -1,9 +0,0 @@
-//
-// Created by pgess on 4/16/15.
-//
-
-#ifndef XREATE_TESTCLANGAPI_H
-#define XREATE_TESTCLANGAPI_H
-
-void testClang1();
-#endif //XREATE_TESTCLANGAPI_H
diff --git a/cpp/tests/types.cpp b/cpp/tests/types.cpp
index d90a673..b9d3e96 100644
--- a/cpp/tests/types.cpp
+++ b/cpp/tests/types.cpp
@@ -1,167 +1,163 @@
 /*
  * types.cpp
  *
  *  Created on: Jun 4, 2015
  *      Author: pgess
  */
 
 #include "gtest/gtest.h"
 #include "passmanager.h"
 #include "llvmlayer.h"
 #include "Parser.h"
 
 using namespace std;
 using namespace xreate;
 
 TEST(Types, DependantTypes1) {
 	string&& code = "XmlNode = type alias {\n"
 			"        tag:: string,\n"
 			"       /* attrs:: [string],*/\n"
 			"        content:: string\n"
 			"}.\n";
 
 	std::unique_ptr<PassManager> program(PassManager::prepareForCode(move(code)));
 	ExpandedType typeXmlNode = program->root->findType("XmlNode");
 
 	ASSERT_EQ(TypeOperator::STRUCT, typeXmlNode->__operator);
 	ASSERT_EQ(2, typeXmlNode->__operands.size());
 	ASSERT_EQ(TypePrimitive::String, typeXmlNode->__operands.at(0).__value);
 	ASSERT_EQ(TypePrimitive::String, typeXmlNode->__operands.at(1).__value);
 }
 
 TEST(Types, DependantTypes2) {
 	string&& code = "XmlNode = type alias {\n"
 			"        tag:: string,\n"
 			"       /* attrs:: [string],*/\n"
 			"        content:: string\n"
 			"}.\n"
 			""
 			"Template = type Template(Leaf) [Leaf, [Leaf[content]]]."
 			"Concrete = type alias Template(XmlNode).";
 
 	std::unique_ptr<PassManager> program(PassManager::prepareForCode(move(code)));
 	ExpandedType typeConcrete = program->root->findType("Concrete");
 
 
 	ASSERT_EQ(TypeOperator::TUPLE, typeConcrete->__operator);
 	ASSERT_EQ(2, typeConcrete->__operands.size());
 	ASSERT_EQ(TypeOperator::STRUCT, typeConcrete->__operands.at(0).__operator);
 
 	ASSERT_EQ(TypeOperator::ARRAY, typeConcrete->__operands.at(1).__operator);
 	ASSERT_EQ(TypePrimitive::String, typeConcrete->__operands.at(1).__operands.at(0).__value);
 }
 
 TEST(Types, TreeType1) {
 	string&& code = "XmlNode = type alias {\n"
 			"        tag:: string,\n"
 			"       /* attrs:: [string],*/\n"
 			"        content:: string\n"
 			"}.\n"
 			""
 			"Tree = type Tree(Leaf) [Leaf, [Tree(Leaf)]]."
 			"Concrete = type alias Tree(XmlNode).";
 
 	std::unique_ptr<PassManager> program(PassManager::prepareForCode(move(code)));
 	ExpandedType typeConcrete = program->root->findType("Concrete");
 
 	ASSERT_EQ(TypeOperator::TUPLE, typeConcrete->__operator);
 	ASSERT_EQ(2, typeConcrete->__operands.size());
 	ASSERT_EQ(TypeOperator::STRUCT, typeConcrete->__operands.at(0).__operator);
 
 	ASSERT_EQ(TypeOperator::ARRAY, typeConcrete->__operands.at(1).__operator);
 
 	auto typeLink = typeConcrete->__operands.at(1).__operands.at(0);
 	ASSERT_EQ(TypeOperator::LINK, typeLink.__operator);
 	ASSERT_EQ(typeConcrete->conjuctionId,typeLink.conjuctionId);
 }
 
 TEST(Types, TreeType1LLvm){
 	string&& code = "XmlNode = type alias {\n"
 			"        tag:: string,\n"
 			"       /* attrs:: [string],*/\n"
 			"        content:: string\n"
 			"}.\n"
 			""
 			"Tree = type Tree(Leaf) [Leaf, [Tree(Leaf)]]."
 			"Concrete = type alias Tree(XmlNode).";
 
 	std::unique_ptr<PassManager> program(PassManager::prepareForCode(move(code)));
 	ExpandedType typeConcrete = program->root->findType("Concrete");
 
 	llvm::Type* raw = program->llvm->toLLVMType(typeConcrete);
 }
 
 TEST(Types, ArrayOfExternal1){
-	FILE* input = fopen("scripts/testspass/Containers_Implementation_LinkedList1.xreate","r");
-	assert(input != nullptr);
+    FILE* input = fopen("scripts/testspass/Containers_Implementation_LinkedList1.xreate","r");
+    assert(input != nullptr);
 
-	Scanner scanner(input);
-	Parser parser(&scanner);
-	parser.Parse();
+    Scanner scanner(input);
+    Parser parser(&scanner);
+    parser.Parse();
 
-	AST& ast = parser.root;
-	CodeScope* body = ast.findFunction("test")->getEntryScope();
+    AST& ast = parser.root;
+    CodeScope* body = ast.findFunction("test")->getEntryScope();
 
-	Symbol symb = body->findSymbol("childrenRaw");
-
-    const TypeAnnotation& t = CodeScope::findDeclaration(symb).type;
+    const TypeAnnotation& t = body->getDeclaration(body->getSymbol("childrenRaw")).type;
     const ExpandedType& t2 = ast.expandType(t);
     EXPECT_EQ(t2->__operator, TypeOperator::ARRAY);
 }
 
 TEST(Types, ExternType1){
 	FILE* input = fopen("scripts/testspass/Containers_Implementation_LinkedList1.xreate","r");
 	assert(input != nullptr);
 
 	Scanner scanner(input);
 	Parser parser(&scanner);
 	parser.Parse();
 
 	AST& ast = parser.root;
 	CodeScope* body = ast.findFunction("test")->getEntryScope();
 
-	Symbol symbTree = body->findSymbol("tree");
-
-    const TypeAnnotation& t = CodeScope::findDeclaration(symbTree).type;
+    const TypeAnnotation& t = body->getDeclaration(body->getSymbol("tree")).type;
     const ExpandedType& t2 = ast.expandType(t);
     EXPECT_EQ(t2->__operator, TypeOperator::CUSTOM);
 }
 
 TEST(Types, ast_VariantType1){
 	string&& code =
 			"	colors = type variant (RED, BLUE, GREEN).\n"
 			"	test = function:: colors; entry {GREEN}";
 
 	std::unique_ptr<PassManager> program(PassManager::prepareForCode(move(code)));
 
 	ExpandedType typ = program->root->findType("colors");
 	EXPECT_EQ(TypeOperator::VARIANT, typ->__operator);
 
 	Expression eRed = program->root->findFunction("test")->getEntryScope()->getBody();
 	EXPECT_EQ(Expression::VARIANT, eRed.__state);
 
 	const ExpandedType& typ2 = program->root->expandType(eRed.type);
 	EXPECT_EQ(TypeOperator::VARIANT, typ2->__operator);
 
 	program->run();
 }
 
 TEST(Types, full_VariantType_Switch1){
 	string&& code =
 			"	colors = type variant (RED, BLUE, GREEN).   \n"
 			"	test = function:: colors {GREEN}            \n"
 
 			"main = function:: int; entry {         \n"
 			"	switch(test()):: int    \n"
-			"	case GREEN {0}                  \n"
+			"	case (GREEN) {0}                  \n"
 			"	case default {1}                \n"
 			"}";
 
 	PassManager* man = PassManager::prepareForCode(move(code));
 	int (*main)() = (int (*)()) man->run();
 
 	EXPECT_EQ(0, main());
 }
 
 
 //TOTEST string type
diff --git a/scripts/dsl/regexps.xreate b/scripts/dsl/regexps.xreate
deleted file mode 100644
index b02d3e1..0000000
--- a/scripts/dsl/regexps.xreate
+++ /dev/null
@@ -1,81 +0,0 @@
-===========================
-        DATA
-        
-patternAB = {
-    sequence: [
-        {zeroOrMore: 'a'},
-        {text: 'b'},
-    ]
-}
-
-mod sequence{
-[
-        mod zeroOrMore (text("a")),
-        matcher text("b")
-]
-)
-
-
-==========================
-        HANDLERS
-
-    case matcher:: mod sequence 
-match = function(text, matcher) {
-    loop fold(node-> matcher, 0->pos){
-        n = match(matcher, mid(text, pos, length(text))).// <-- every time length?
-        
-        if (pos == pos_FAIL || n == pos_FAIL){
-            pos_FAIL:: break
-        } else {
-            pos+n
-        }
-    }
-}
-
-    case matcher:: mod zeroOrMore (Dereferenced)
-match= function(text, matcher){
-    matcherChild = matcher:: Dereferenced.               //<---         extract child(unification)
-    
-    loop fold inf(0->pos, n==pos_FAIL){                              //<---         infinite loop?
-        n = match(matcherChild, mid(text, pos, length(text))).
-        
-        if (n == pos_FAIL:: break){
-            pos
-            
-        } else {
-            pos+n
-        }
-    }
-}
-
-    case matcher:: matcher text
-match = function(text, matcher) {
-    pattern = matcher:: string. 
-    
-    if (length(text)>0 &&
-        length(pattern) <= length(text) &&
-        mid(text, 0, length(pattern)) == pattern)
-    {
-        length(pattern);
-        
-    } else {
-        pos_FAIL;
-    }
-}
-
-match = function(text::string, pattern::string)::string{
-     n= match(pattern, text).
-     
-     if (n != pos_FAIL)
-        {mid(text, 0, n)}
-    else 
-        {text_FAIL}
-}
-
-=================================
-    CLIENT
-    
-test = function(){
-    match(patternAB, "aaaaab").
-    match(patternAB, "baaaaa").
-}    
diff --git a/scripts/testspass/Containers_Implementation_LinkedList1.xreate b/scripts/testspass/Containers_Implementation_LinkedList1.xreate
index 2966ef4..8340f56 100644
--- a/scripts/testspass/Containers_Implementation_LinkedList1.xreate
+++ b/scripts/testspass/Containers_Implementation_LinkedList1.xreate
@@ -1,47 +1,47 @@
 
           // EXTERN INCLUDES
 interface(extern-c){
   xml2 = library:: pkgconfig("libxml-2.0").
   
   include {
     xml2 = ["libxml/tree.h"]
   }.
 } 
 
           // CONTAINERS
 interface(dfa) {
   operator map::  (op(seqaccess)) -> impl(solid).
   operator list_range:: ()->impl(on_the_fly).
   operator list:: ()->impl(solid).
   operator fold:: (op(seqaccess)).
-  operator index:: (op(randaccess)).
+  /* operator index:: (op(randaccess)). - BREAKS THE ANALYSIS. MAKE tree VIEWED AS COLLECTION */ 
   /* operator map:  (op(seqaccess)) -> impl(llvm_array | on_the_fly); */
 }
 
 import raw("core/containers.lp")
 
 
           // PROGRAM
 XmlNode = type alias {
         tag:: string,
        /* attrs:: [string],*/
         content:: string
 }.
 
 Tree = type Tree(Leaf) [Leaf, [Tree(Leaf)]].
 XmlTree = type alias Tree(XmlNode).
 
 
 test= function:: num; entry {
     filename = "scripts/testspass/Containers_Implementation_LinkedList1-data.xml" :: string.
     docRaw = xmlParseFile(filename) :: xmlDocPtr.
     tree= xmlDocGetRootElement(docRaw) :: xmlNodePtr.
-    childrenRaw = tree["children"]:: [xmlNodePtr]; containers:linkedlist(next, null).
+    childrenRaw = tree["children"]:: [xmlNodePtr]; linkedlist(next, null).
     size = loop fold(childrenRaw->child:: xmlNodePtr, 0->count):: int {
       count +1::int
     }.
       
     size
 }