     end)
   end
 
-  def postprocess_soil_height(%{soil_height: true} = needs) do
-    Map.put(needs, :z, SpecialValue.soil_height(needs))
-  end
-
   def postprocess_soil_height(needs), do: needs
 
   def do_perform_movement(%{safe_z: true} = needs) do

    extract_variables(body, better_params)
    |> preprocess_lua(better_params)
    |> calculate_movement_needs()
    |> postprocess_soil_height()
    |> do_perform_movement()
  end


    needs
  end

  # Creates a list of operations that will look something like
  # this:
  #
  # [
  #   {:x, :=, 0.0},
  #   {:y, :=, 0.0},
  #   {:speed_x, :=, 100},
  #   {:speed_y, :=, 100},
  #   {:y, :=, 80.0},
  #   {:x, :=, 0.0},
  #   {:y, :=, 3},
  #   {:y, :+, 2.0},
  #   {:speed_y, :=, 50},
  #   {:z, :=, 0.0},
  #   {:speed_z, :=, 100},
  #   {:safe_z, :=, false},
  #   {:z, :=, 0.0},
  #   {:z, :=, {:skip, :soil_height}},
  #   {:z, :+, -21},
  #   {:safe_z, :=, true}
  # ]
  #
  # These operations are fed into a reducer function that creates
  # a proper x/y/z/speed map that we can use for move_abs calls.
  #
  # A few things to keep in mind:
  #  * ORDER MATTERS: Each operation will change the shape of
  #                   the final output map. This means we can't
  #                   arbitrarily sort operations for readability,
  #                   uniqueness, etc..
  #  * Z AXIS LAST:   The Z axis operations are special. They
  #                   require all X/Y operations to be completed
  #                   first. This is because `soil_height`
  #                   interpolation relies on X/Y data to calculate
  #                   Z height. If X/Y values were to change, it
  #                   would invalidate the Z height calculation.
  def create_list_of_operations(body) do
    mapper = &FarmbotCeleryScript.Compiler.Move.mapper/1
    # Move X/Y operations to the front of the list and move
    # Z operations to the back, but DO NOT SORT!:
    {xy, z} = initial_state() ++ Enum.map(body, mapper)
         |> Enum.split_with(fn
      {:safe_z, _, _}  ->
        false
      {:speed_z, _, _} ->
        false
      {:z, _, _} ->
        false
      _ ->
        true
    end)

    xy ++ z
  end

  def calculate_movement_needs(body) do
    body
    |> create_list_of_operations()
    |> Enum.reduce(%{}, &reducer/2)
  end

  def reducer({_, _, {:skip, :soil_height}}, state) do
    z = state
    |> Map.take([:x, :y])
    |> SpecialValue.soil_height()

    Map.put(state, :z, z)
  end

  def reducer({key, :+, value}, state) do
