diff --git a/src/core/utils.jl b/src/core/utils.jl
index 976b5aae0e487530127a786b660cfb5d1d51e338..25d1b1d69f1b21cf1a2035d459f64f2272435518 100644
--- a/src/core/utils.jl
+++ b/src/core/utils.jl
@@ -165,6 +165,10 @@ A utility function to make sure that a number is within a given set of bounds.
 Returns `max`/`min` if `x` is greater/less than this.
 """
 function bounds(x::Number; max::Number=Inf, min::Number=0)
+    if unit(x) != NoUnits
+        max = max*unit(x)
+        min = min*unit(x)
+    end
     x > max ? max :
         x < min ? min :
         x
diff --git a/src/farm/farm.jl b/src/farm/farm.jl
index 7a3ad80b1af1cf697508a8fba0dc9daa9f54ae2f..5d024dd08696cf9b5280d26b788ef3b7ce99d084 100644
--- a/src/farm/farm.jl
+++ b/src/farm/farm.jl
@@ -3,6 +3,31 @@
 ### This file is responsible for managing the farm module(s).
 ###    
 
+
+## GENERIC TYPES AND FUNCTIONS
+
+"This is the agent type for the farm ABM."
+abstract type Farmer <: ModelAgent end
+
+stepagent!(f::Farmer, model::SimulationModel) =
+    @error "Farmer type $(typeof(f)) has no stepagent!() method."
+
+"""
+    initfarms!(model)
+
+Initialise the model with a set of farm agents, depending on the configured farm model.
+"""
+function initfarms!(model::SimulationModel)
+    if @param(farm.farmmodel) == "BasicFarmer"
+        initbasicfarms!(model)
+    else
+        Base.error("Farm model $(@param(farm.farmmodel)) doesn't exist.")
+    end
+end
+
+
+## BASIC FARM MODEL
+
 #XXX Initially, we're only working with a single simple crop rotation.
 # Later on, we need to figure out how to integrate several.
 const CROPROTATION = ["winter rape", "winter wheat", "maize", "winter barley"]
@@ -10,12 +35,11 @@ const CROPROTATION = ["winter rape", "winter wheat", "maize", "winter barley"]
 #FIXME Currently, this is specific to the ALMaSS model. We need to figure out how to generalise it.
 
 """
-    Farmer
+    BasicFarmer
 
-This is the agent type for the farm ABM.
+The BasicFarmer type simply applies a set crop rotation to his fields and keeps track of income.
 """
-mutable struct Farmer <: ModelAgent
-    #XXX make this into an abstract type and create subtypes for different farm submodels? (#69)
+mutable struct BasicFarmer <: Farmer
     const id::Int64
     # farmplots owned by this farmer and their associated crop rotations and next sowing date
     fields::Vector{Int64}
@@ -29,7 +53,7 @@ end
 
 Update a farmer by one day. Cycle through all fields and see what management is needed.
 """
-function stepagent!(farmer::Farmer, model::SimulationModel)
+function stepagent!(farmer::BasicFarmer, model::SimulationModel)
     for f in farmer.fields
         field = model.farmplots[f]
         ctype = croptype(field)
@@ -50,13 +74,13 @@ function stepagent!(farmer::Farmer, model::SimulationModel)
 end
 
 """
-    initfarms!(model)
+    initbasicfarms!(model)
 
-Initialise the model with a set of farm agents.
+Initialise the basic farm model. All fields are controlled by a single farmer actor
+and are assigned as grassland, set-aside, or arable land with a crop rotation.
 """
-function initfarms!(model::SimulationModel)
-    #XXX initially, we only have one farmer controlling all fields in the region
-    farmer = Farmer(1, collect(1:length(model.farmplots)), Dict(), Dict(), 0)
+function initbasicfarms!(model::SimulationModel)
+    farmer = BasicFarmer(1, collect(1:length(model.farmplots)), Dict(), Dict(), 0)
     model.farmers = [farmer]
     setasides = findsetasides(farmer, model)
     for field in model.farmplots
@@ -83,7 +107,7 @@ end
 Return a vector of field IDs that this farmer should keep fallow to satisfy the configured
 set-aside rules.
 """
-function findsetasides(farmer::Farmer, model::SimulationModel)
+function findsetasides(farmer::BasicFarmer, model::SimulationModel)
     @param(farm.setaside) == 0 && return []
     croparea = @areaof(sum(f -> isgrassland(f, model) ? 0 : length(f.pixels),
                            model.farmplots[farmer.fields]))
diff --git a/src/nature/ecologicaldata.jl b/src/nature/ecologicaldata.jl
index 3a1e53803bd7623d2620dd3773b08213af607852..15527ca69f0f1894d479151abdd96b173dc8d513 100644
--- a/src/nature/ecologicaldata.jl
+++ b/src/nature/ecologicaldata.jl
@@ -69,7 +69,7 @@ function initskylarkdata(model::SimulationModel)
     newdataoutput!(model, "skylark_abundance",
                    ["Date", "TotalAbundance", "Mating", "Breeding",
                     "Nonbreeding", "Juvenile", "Migrants"],
-                   "daily", skylarkabundance, skylarkpopulation)
+                   @param(nature.popoutfreq), skylarkabundance, skylarkpopulation)
     # newdataoutput!(model, "skylark_territories", ["Date", "ID", "X", "Y"],
     #                skylarkterritories, "monthly") #TODO add plotting function
     newdataoutput!(model, "skylark_breeding",