diff --git a/ExprPrimaryNodes.py b/ExprPrimaryNodes.py
index da0eca1b286a4bcec3ace7274b5e971996a23bb9..07860ef5d8f1cf5b26f5465995fdaf14f86ee03e 100644
--- a/ExprPrimaryNodes.py
+++ b/ExprPrimaryNodes.py
@@ -93,16 +93,22 @@ def helperDisambigName(node):
 # args exprs, exprs expr COMMA exprs
 class ArgsNode(ASTNode):
     # always list all fields in the init method to show the class structure
-    def __init__(self, parseTree, typeName):
+    def __init__(self, parseTree, typeName, exprs = []):
         self.parseTree = parseTree
         self.exprs = []  # a list of expressions
         self.env = None
         self.children = []
         self.typeName = typeName # the type (class/interface) this node belongs under
 
-        exprs = getParseTreeNodes(['expr'], parseTree)
-        for e in exprs:
-            self.exprs.append(makeNodeFromExpr(e, typeName))
+        if exprs == []:
+            exprs = getParseTreeNodes(['expr'], parseTree)
+            for e in exprs:
+                self.exprs.append(makeNodeFromExpr(e, typeName))
+        else:
+            # manually induce exprs
+            # for converting string concatenation to a method call
+            # see ExprPrimaryNodes:ExprNode on string concat
+            self.exprs = exprs
 
         self.children.extend(self.exprs)
 
@@ -562,6 +568,48 @@ class ExprNode(ASTNode):
         or (self.right.myType.name =='java.lang.String' and self.left.myType.name not in ['void'])) and self.op == '+':
             self.myType = TypeStruct('java.lang.String', self.env.getNode('java.lang.String', 'type'))
             self.myType.link(self.env)
+
+            # var1 + var2 === String.valueOf(var1).concat( String.valueOf(var2) )
+            
+            # methodInvoc name LPAREN args RPAREN (because it's static)
+            # MethodInvNode
+            # ID = NameNode
+            #       - name = "String.valueOf"
+            # args = ArgsNode
+            #       - exprs = [self.left]
+
+            # create MethodInvNode to call String.valueOf(left) and String.valueOf(right)
+            # 1. Make NameNode for String.valueOf
+            valueOfNameNode = NameNode(self.parseTree, True, self.typeName, "String.valueOf")
+            valueOfNameNode.env = self.env
+            # 2. Make ArgsNode for left and right
+            leftArg = ArgsNode(self.parseTree, self.typeName, [self.left])
+            rightArg = ArgsNode(self.parseTree, self.typeName, [self.right])
+            # 3. Put it all together
+            self.valueOfMethodInvLeft = MethodInvNode(self.parseTree, self.typeName, valueOfNameNode, leftArg)
+            self.valueOfMethodInvRight = MethodInvNode(self.parseTree, self.typeName, valueOfNameNode, rightArg)
+            # 4. Check type to be safe
+            self.valueOfMethodInvLeft.checkType()
+            self.valueOfMethodInvRight.checkType()
+
+            
+            # methodInvoc primary PERIOD ID LPAREN args RPAREN
+            # MethodInvNode
+            # primary = self.left
+            # ID = NameNode
+            #       - name = "concat"
+            # args = ArgsNode
+            #       - exprs = [self.right]
+
+            # create MethodInvNode to call left.concat(right)
+            # 1. Make NameNode for String.concat (name = "concat")
+            concatNameNode = NameNode(self.parseTree, True, self.typeName, "concat")
+            # 2. Make ArgsNode for right (already have from above!)
+            # 3. Put it all together
+            self.concatMethodInv = MethodInvNode(self.parseTree, self.typeName, concatNameNode, rightArg, self.left)
+            # 4. Check type to be safe
+            self.concatMethodInv.checkType()
+            
             return
 
         raise Exception("ERROR: Incompatible types. Left of {} type can't be used with right of {} type on operation {}".format(self.left.myType.name, self.right.myType.name, self.op))
@@ -905,7 +953,7 @@ class FieldAccessNode(ASTNode):
 # methodInvoc
 class MethodInvNode(ASTNode):
     # always list all fields in the init method to show the class structure
-    def __init__(self, parseTree, typeName):
+    def __init__(self, parseTree, typeName, ID = '', args = None, primary = None):
         self.parseTree = parseTree
         self.primary = None  # can be empty
         self.ID = '' # can be either ID or compID
@@ -915,12 +963,23 @@ class MethodInvNode(ASTNode):
         self.method = None
         self.typeName = typeName # the type (class/interface) this node belongs under
 
-        # input parse tree is either: methodInvoc primary PERIOD ID LPAREN args RPAREN
-        #  methodInvoc name LPAREN args RPAREN
-        self.ID = NameNode(parseTree.children[-4], True, typeName)
-        self.args = ArgsNode(parseTree.children[-2], typeName)
-        if parseTree.children[0].name == 'primary':
-            self.primary = makeNodeFromAllPrimary(parseTree.children[0], typeName)
+        if ID == '' or args is None:
+            # input parse tree is either: methodInvoc primary PERIOD ID LPAREN args RPAREN
+            #  methodInvoc name LPAREN args RPAREN
+            self.ID = NameNode(parseTree.children[-4], True, typeName)
+            self.args = ArgsNode(parseTree.children[-2], typeName)
+            if parseTree.children[0].name == 'primary':
+                self.primary = makeNodeFromAllPrimary(parseTree.children[0], typeName)
+            self.override = False
+        else:
+            # manually induce ID and args
+            # for converting string concatenation to a method call
+            # see ExprPrimaryNodes:ExprNode on string concat
+            self.ID = ID
+            self.args = args
+            if primary is not None:
+                self.primary = primary
+            self.override = True
 
         self.children.append(self.primary)
         self.children.append(self.args)
@@ -963,7 +1022,7 @@ class MethodInvNode(ASTNode):
         if m:
 
             # check static
-            if (not self.ID.shouldBeStatic) and 'static' in m.mods:
+            if (not self.ID.shouldBeStatic and not self.override) and 'static' in m.mods:
                 raise Exception("ERROR: Non-static access of static method {}.".format(m.name))
 
             # check protected
diff --git a/NameNode.py b/NameNode.py
index 859f25fdeb799941053e0a70b25754de7ab09056..70ce82cf4de5bb8c57ac120ea9f530274ac48b5b 100644
--- a/NameNode.py
+++ b/NameNode.py
@@ -19,7 +19,7 @@ from codeGenNodes import genNameNode
 
 
 class NameNode(ASTNode):
-    def __init__(self, parseTree, methodInvoke, typeName):
+    def __init__(self, parseTree, methodInvoke, typeName, name = ""):
 
         self.parseTree = parseTree
         self.name = "" # str: stores original lex of the name (ID/COMPID)
@@ -40,7 +40,14 @@ class NameNode(ASTNode):
         self.staticField = None
         self.prefixNodes = [] # stores the past prefix links so we can evaluate them one by one
 
-        self.name = getParseTreeNodes(["ID", "COMPID"], parseTree)[0].lex
+        if name == "":
+            self.name = getParseTreeNodes(["ID", "COMPID"], parseTree)[0].lex
+        else:
+            # manually induce name
+            # for converting string concatenation to a method call
+            # see ExprPrimaryNodes:ExprNode on string concat
+            self.name = name
+
         self.IDs = self.name.split(".")
 
     # Updates the resolved/identified prefix
diff --git a/UnitNodes.py b/UnitNodes.py
index 606114766223e0f486d3e7238a877ad841611c2f..9490a010792631522fe581dac850809ecb1cd354 100644
--- a/UnitNodes.py
+++ b/UnitNodes.py
@@ -55,7 +55,7 @@ class LiteralNode(ASTNode):
                 self.code += p("mov", "eax", "0", " set to literal false")
                 return
 
-        # char TODO
+        # char
         if self.name == 'char':
             self.code += p("mov", "eax", str(self.getConstant()), " set to literal char")
             return