Remove ConstantBase/Constant/VectorConstant/TensorConstant classes,
and add ufl_type class decorator to all types currently doing nothing.
Add missing @ufl_type applications.
Enable large parts of the ufl_type class decorator design from uflcore prototype.
Rename ._uflclass -> ._ufl_class_ for consistency with new type traits.
Rename ._classid -> ._ufl_typecode_ for consistency with new type traits.
Rename ._handlername -> ._ufl_handler_name_ for consistency with new type traits.
Remove unused code in classes.py.
Use expr._ufl_is_terminal_ instead of isinstance(expr, Terminal), slightly faster operation for proof of concept.
Add properties ufl_operands, ufl_shape, ufl_free_indices,
ufl_index_dimensions to Expr hierarchy.
Replace .operands() with .ufl_operands everywhere.
Need to implement all these directly in all types to get the speed advantage.
Store operands in ufl_operands tuple for all Operator types.

Terminal types automatically refer to Terminal.ufl_operands, no
storage required.
Replace .shape() with .ufl_shape everywhere. Most places ufl_shape is a @property and as such no faster than the old function.
Bugfix in Expr.__nonzero.__.
Add options to ufl_type to inherit shape and/or free indices from a
given operand. This allows removing a bunch of free_indices() and
index_dimensions() implementations since they are now attached to the
class in ufl_type. This will make refactoring to
ufl_free_indices/ufl_index_dimensions easier because only the
functions that actually do something are left so it's easier to get an overview.
Simplify ListTensor constructor.
Non-intrusive preparations for free index refactoring.
Initial thoughts on what's needed for free index refactoring.
Go through __getnewargs__ implementations and fix bug in listtensor caught by pickle test.
New non-recursive implementation of expr_equals, 25% faster in a complex test case.
Make ufl_type check for missing methods and attributes of Expr
subclasses. Streamline implementation of __hash__, cached in _hash for
all Expr types and computed with _ufl_compute_hash_.
Annotate some types with the special functions they correspond to.

Not (yet?) used in ufl_type but could replace the exproperators.py
wrappers in a more compact and robust way.

Removed some unused code and comments as well.