private static AssignmentElement MoveVariableToLhs(AssignmentElement equals, string variable, out Element varEl)
 {
     if (ReferenceEquals(equals, null)) throw new MissingAssignmentException();
     varEl = equals.Elements.Lhs.FindVariable(variable);
     if (!ReferenceEquals(varEl, null)) return equals;
     varEl = equals.Elements.Rhs.FindVariable(variable);
     if (ReferenceEquals(varEl, null)) throw new UnrecognisedVariableException(variable);
     // Swap lhs/rhs
     return new AssignmentElement(equals.Elements.Swap());
 }
 private Element Rearrange(AssignmentElement root, Element targetVar)
 {
     while (true)
     {
         // Check for no rearrange necessary
         if (root.Elements.Lhs == targetVar) return root.Elements.Rhs;
         // Rearrange first part of tree
         var targetPath = root.Elements.Lhs.FindPath(targetVar).ToArray();
         var lastOperation = targetPath.First();
         var varBranch = targetPath.Skip(1).FirstOrDefault() ?? targetVar;
         var newRoot = root.Replace(lastOperation, varBranch) as AssignmentElement;
         var inversion = lastOperation.Invert(varBranch, newRoot.Elements.Rhs);
         root = newRoot.Replace(newRoot.Elements.Rhs, inversion) as AssignmentElement;
     }
 }