 
     # Exponentiation
     ref.forType(comps.exponentiation, {
-      isEqual: (buildIsEqual(comps.exponentiation)),
-      _simpleIsEqual: (other)->
-        ref.refine(@base()).isEqual(other.base()) and
-          ref.refine(@power()).isEqual(other.power())
+      isEqual: (buildIsEqual(comps.exponentiation, "checkBaseAndPowerEquality")),
+      checkBaseAndPowerEquality: (other, eq_comp)->
+        base_equal = ref.refine(@base()).isEqual(other.base(), eq_comp)
+        power_equal = ref.refine(@power()).isEqual(other.power(), eq_comp)
+        base_equal && power_equal # no need to save, report comes from below
       })
 
 
     # Expression
     ref.forType(comps.expression, {
-      isExpressionEqual: (other)->
+      isExpressionEqual: (other, eq_calc)->
         logger.info("isExpressionEqual", @unrefined(), other)
-        if @is_error == other.is_error && @is_open == other.is_open
-          if _(@expression).size() == _(other.expression).size()
-            contains_unequal =
-              _.chain(@expression).map((element, i)->
-                ref.refine(element).isEqual(other.nth(i))
-              ).contains(false).value()
-            !contains_unequal
-          else
-            false
+        match_error = @is_error == other.is_error
+        eq_calc.saveFalseForReport(match_error, @unrefined(), other, "error values not equal")
+
+        match_open = @is_open == other.is_open
+        eq_calc.saveFalseForReport(match_open, @unrefined(), other, "open values not equal")
+
+        match_size = _(@expression).size() == _(other.expression).size()
+        eq_calc.saveFalseForReport(match_size, @unrefined(), other, "size values not equal")
+
+        if match_error && match_open && match_size
+          contains_unequal =
+            _.chain(@expression).map((element, i)->
+              ret = ref.refine(element).isEqual(other.nth(i), eq_calc)
+              debugger unless ret
+              ret
+            ).contains(false).value()
+          !contains_unequal
         else
           false
 
-      isEqual: (other)->
-        if other instanceof comps.expression
-          @isExpressionEqual(other)
+      isEqual: (other, eq_calc)->
+
+        same_type = eq_calc.saveFalseForReport((other instanceof comps.expression), @unrefined(), other,
+          "Wrong types")
+        if same_type
+          @isExpressionEqual(other, eq_calc)
+        else
+          false
     })
 
+    # Equals
+    ref.forType(comps.equals, {
+      isEqual: (buildIsEqual(comps.equals))
+    })
 
 
     # Multiplication

    })

    class ExpressionEquality
      initialize: (@first)->
      isEqual: (@second)->
        firstp = ref.refine @first
        firstp.isEqual @second

    class_mixer ExpressionEquality

    ExpressionEquality.isEqual = (a,b)->
      ExpressionEquality.build(a).isEqual(b)

    return ExpressionEquality

      isEqual: (buildIsEqual(comps.multiplication))
      })

    # Number
    ref.forType(comps.number, {
      isEqual: (buildIsEqual(comps.number, "checkNumberValues")),
      checkNumberValues: (other, eq_calc)->

        # this is bad; TODO fix
        # The real "todo" here is that
        # numbers are internally of questionable state.
        # Im not entirely sure how to state that number expresison components are equal
        check = "#{@value()}" == "#{other.value()}"
        eq_calc.saveFalseForReport(check, @unrefined(), other, "Numeric values not equal")
    })



    ref.forType(comps.exponentiation, {
      isEqual: (buildIsEqual(comps.exponentiation)),
