           })
 
         ref.forType(comps.classes.expression, {
-          toString: (wrap_with_parentheses=true)->
-            ret = @mapconcatWithMethod('toString')
-            @maybeWrapWithParentheses(ret, wrap_with_parentheses)
+          toString: (opts={})->
+            opts = @optsWithDefaults(opts)
+            ret = @mapconcatWithMethod('toString', opts)
+            @maybeWrapWithParentheses(ret, opts)
 
-          toHTMLString: (wrap_with_parentheses=true)->
-            ret = @mapconcatWithMethod('toHTMLString')
-            @maybeWrapWithParentheses(ret, wrap_with_parentheses)
+          toHTMLString: (opts={})->
+            opts = @optsWithDefaults(opts)
+            ret = @mapconcatWithMethod('toHTMLString', opts)
+            @maybeWrapWithParentheses(ret, opts)
 
-          mapconcatWithMethod: (method)->
+          mapconcatWithMethod: (method, opts)->
             _(@expression).map((it)-> ref.refine(it)[method]()).join(' ')
 
-          maybeWrapWithParentheses: (str, do_wrap)->
-            if do_wrap and @decideWrap()
-              opening_paren = "( "
-              closing_paren = if @isOpen() then "" else " )"
+          maybeWrapWithParentheses: (str, opts)->
+            if !opts.skip_parentheses # ie this is the "root" expression
+              opening_paren = if @isOpen()
+                "( "
+              else if (@expression.length > 1)
+                "( "
+              else if opts.include_parentheses_if_single and @expression.length == 1
+                "( "
+              else
+                ""
+
+              closing_paren = if !@isOpen(opts)
+                if @expression.length > 1
+                  " )"
+                else if opts.include_parentheses_if_single and @expression.length == 1
+                  " )"
+                else
+                  ""
+              else
+                ""
               "#{opening_paren}#{str}#{closing_paren}"
             else
               str
 
-          decideWrap: ->
-            @expression.length > 1
+          decideWrap: (opts)->
 
+
+          optsWithDefaults: (opts={})->
+            ttm.defaults(opts, {skip_parentheses: false, include_parentheses_if_single: true})
           });
 
         ref.forType(comps.classes.blank, {


        ref.forType(comps.classes.exponentiation, {
          base: ->
            ref.refine(@unrefined().base()).toString()
          power: ->
            ref.refine(@unrefined().power()).toString()
          toString: ->
            "#{@base()} ^ #{@power()}"
          toHTMLString: ->
            "#{@base()} &circ; #{@power()}"
          });

          })

      toString: ->
        @ref.refine(@expression).toString(skip_parentheses: true)
      toHTMLString: ->
        @ref.refine(@expression).toHTMLString(skip_parentheses: true)

    class_mixer ExpressionToString

