docs: protected void handleParentheses( TokenList tokens, Sequence sequence ) {
          // have a list to handle embedded parentheses, e.g. (((((a)))))
          List<TokenList.Token> left = new ArrayList<TokenList.Token>();
  
          // find all of them
          TokenList.Token t = tokens.first;
          while( t != null ) {
              TokenList.Token next = t.next;
              if( t.getType() == Type.SYMBOL ) {
                  if( t.getSymbol() == Symbol.PAREN_LEFT  )
                      left.add(t);
                  else if( t.getSymbol() == Symbol.PAREN_RIGHT ) {
                      if( left.isEmpty() )
                          throw new ParseError(") found with no matching (");
  
                      TokenList.Token a = left.remove(left.size()-1);
  
                      // remember the element before so the new one can be inserted afterwards
                      TokenList.Token before = a.previous;
  
                      TokenList sublist = tokens.extractSubList(a,t);
                      // remove parentheses
                      sublist.remove(sublist.first);
                      sublist.remove(sublist.last);
  
                      // if its a function before () then the () indicates its an input to a function
                      if( before != null && before.getType() == Type.FUNCTION ) {
                          List<TokenList.Token> inputs = parseParameterCommaBlock(sublist, sequence);
                          if (inputs.isEmpty())
                              throw new ParseError("Empty function input parameters");
                          else {
                              createFunction(before, inputs, tokens, sequence);
                          }
                      } else if( before != null && before.getType() == Type.VARIABLE &&
                              before.getVariable().getType() == VariableType.MATRIX ) {
                          // if it's a variable then that says it's a sub-matrix
                          TokenList.Token extract = parseSubmatrixToExtract(before,sublist, sequence);
                          // put in the extract operation
                          tokens.insert(before,extract);
                          tokens.remove(before);
                      } else {
                          // if null then it was empty inside
                          TokenList.Token output = parseBlockNoParentheses(sublist,sequence, false);
                          if (output != null)
                              tokens.insert(before, output);
                      }
                  }
              }
              t = next;
          }
  
          if( !left.isEmpty())
              throw new ParseError("Dangling ( parentheses");
      }