diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms
index ec4b52772d7201aa8ae46d395d4a1d04af5c8526..c915b7dee1440e64c07afdc8a7d574f22948995e 100644
--- a/GAMS/IntExtOpt.gms
+++ b/GAMS/IntExtOpt.gms
@@ -60,7 +60,7 @@
  SCALAR maxLandExpansionRate                 max rate of country land expansion;
 
  PARAMETER previousLandCoverArea(land_cover, location) land cover area in Mha;
-* PARAMETER minimumLandCoverArea(land_cover, location) minimum land cover area to constrain conversion;
+ PARAMETER minimumLandCoverArea(land_cover, location) minimum land cover area to constrain conversion;
  PARAMETER carbonFluxRate(land_cover_before, land_cover_after, location) carbon flux - MtC-eq per Mha;
  PARAMETER woodYield(land_cover_before, land_cover_after, location)      wood yield - MtC-eq per Mha;
  SCALAR carbonPrice                                 price of carbon - $ per tonne or million$ per Mt;
@@ -74,7 +74,7 @@ $load yieldNone, yieldFertOnly, yieldIrrigOnly, yieldBoth, yieldShock
 $load fertParam, irrigParam, otherIParam, exportPrices, importPrices, maxNetImport, minNetImport, unhandledCropRate, setAsideRate, maxLandExpansionRate, subsidyRate
 $load meatEfficency, otherICost, irrigCost, irrigMaxRate, irrigConstraint, fertiliserUnitCost, domesticPriceMarkup, minDemandPerCereal, minDemandPerOilcrop, seedAndWasteRate
 $load previousLandCoverArea, carbonFluxRate, woodYield, carbonPrice, woodPrice
-*$load minimumLandCoverArea
+$load minimumLandCoverArea
 $gdxin
 
 * convert units from $/t to billion$/Mt
@@ -190,7 +190,7 @@ $gdxin
        PASTURE_TOTAL_CHANGE_CONSTRAINT(location)
        CROPLAND_LAND_COVER_CALC(location) cropland area equals sum of all crop areas
        PASTURE_LAND_COVER_CALC(location)  pasture area (land cover) equals pasture area (land use)
-*       MINIMUM_LAND_COVER_CONSTRAINT(location) constraint on land cover conversion
+       MINIMUM_LAND_COVER_CONSTRAINT(location) constraint on land cover conversion
        LAND_COVER_CHANGE_CALC(land_cover, location)
        LAND_COVER_CHANGE_CONSTRAINT(land_cover, location)
        LAND_COVER_SELF_CHANGE_CONSTRAINT(land_cover, location)
@@ -254,7 +254,7 @@ $gdxin
 
  PASTURE_LAND_COVER_CALC(location) .. landCoverArea('pasture', location) =E= cropArea('pasture', location);
 
-* MINIMUM_LAND_COVER_CONSTRAINT(location, land_cover) .. landCoverArea(land_cover, location)) =G= minimumLandCover(land_cover_after, location);
+ MINIMUM_LAND_COVER_CONSTRAINT(location, land_cover) .. landCoverArea(land_cover, location)) =G= minimumLandCover(land_cover_after, location);
 
  LAND_COVER_CHANGE_CALC(land_cover, location) .. landCoverArea(land_cover, location) =E= previousLandCoverArea(land_cover, location) +
                      sum(land_cover_before, landCoverChange(land_cover_before, land_cover, location)) - sum(land_cover_after, landCoverChange(land_cover, land_cover_after, location));
diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java
index a723454c430cae6b289d5997ea2920ce30a92610..bb23039660c15bc996c58ba1bbaada2bb5625aec 100644
--- a/src/ac/ed/lurg/country/CountryAgent.java
+++ b/src/ac/ed/lurg/country/CountryAgent.java
@@ -25,7 +25,9 @@ import ac.ed.lurg.landuse.WoodYieldItem;
 import ac.ed.lurg.types.CommodityType;
 import ac.ed.lurg.types.CropType;
 import ac.ed.lurg.types.LandCoverType;
+import ac.ed.lurg.utils.DoubleMap;
 import ac.ed.lurg.utils.LogWriter;
+import ac.ed.lurg.utils.TripleMap;
 import ac.ed.lurg.utils.cluster.Cluster;
 import ac.ed.lurg.utils.cluster.KMeans;
 import ac.ed.lurg.yield.YieldClusterPoint;
@@ -41,6 +43,7 @@ public class CountryAgent extends AbstractCountryAgent {
 	private RasterSet<IntegerRasterItem> yieldClusters;
 	private Map<CropType, Double> subsidyRates;
 	private boolean saveGamsGdxFiles;
+	private TripleMap<Integer, Integer, LandCoverType, Double> minimumLandCover; //<Year, Location, LandCoverType, Area>
 
 	public CountryAgent(AbstractDemandManager demandManager,CompositeCountry country, RasterSet<LandUseItem> cropAreaRaster,
 			Map<CropType, CropUsageData> cropUsageData, Map<CropType, Double> tradeBarriers, RasterSet<IntegerRasterItem> yieldClusters,
@@ -49,6 +52,8 @@ public class CountryAgent extends AbstractCountryAgent {
 		super(demandManager, country, tradeBarriers);
 		this.yieldClusters = yieldClusters;
 		this.subsidyRates = subsidyRates;
+		
+		minimumLandCover = new TripleMap<Integer, Integer, LandCoverType, Double>(); // TODO how to intialise?
 
 		GamsRasterOutput initialData = new GamsRasterOutput(cropAreaRaster, cropUsageData);
 		previousGamsRasterOutput = initialData;
@@ -104,7 +109,8 @@ public class CountryAgent extends AbstractCountryAgent {
 	}
 	
 	public GamsRasterOutput determineProduction(YieldRaster countryYieldSurfaces, RasterSet<IrrigationItem> irrigData, 
-			Map<CropType, GlobalPrice> worldPrices, double globalGen2EcIncrease, RasterSet<CarbonFluxItem> carbonFluxData, RasterSet<WoodYieldItem> woodYieldData) {
+			Map<CropType, GlobalPrice> worldPrices, double globalGen2EcIncrease, RasterSet<CarbonFluxItem> carbonFluxData, 
+			RasterSet<WoodYieldItem> woodYieldData) {
 
 		// project demand
 		calculateCountryPricesAndDemand(worldPrices, false);
@@ -123,9 +129,11 @@ public class CountryAgent extends AbstractCountryAgent {
 		else {			
 			if (yieldClusters==null)
 				yieldClusters = calcYieldClusters(irrigData, countryYieldSurfaces);  // this should only be on the first timestep
+			
+
 
 			// optimize areas and intensity 
-			GamsRasterInput input = getGamsRasterInput(irrigData, countryYieldSurfaces, globalGen2EcIncrease, carbonFluxData, woodYieldData);
+			GamsRasterInput input = getGamsRasterInput(irrigData, countryYieldSurfaces, globalGen2EcIncrease, carbonFluxData, woodYieldData, minimumLandCover);
 			GamsRasterOptimiser opti = new GamsRasterOptimiser(input, yieldClusters);
 			LogWriter.println("Running " + country.getName() + ", currentTimestep " + currentTimestep);
 
@@ -135,6 +143,7 @@ public class CountryAgent extends AbstractCountryAgent {
 				saveGDXFile("landuse");
 			
 			previousGamsRasterOutput = result;
+			updateMinimumLandCover();
 			return result;
 		}
 
@@ -158,7 +167,8 @@ public class CountryAgent extends AbstractCountryAgent {
 	}
 
 	private GamsRasterInput getGamsRasterInput(RasterSet<IrrigationItem> irrigData, YieldRaster countryYieldSurfaces, double gen2EcIncrease,
-			RasterSet<CarbonFluxItem> carbonFluxData, RasterSet<WoodYieldItem> woodYieldData) {
+			RasterSet<CarbonFluxItem> carbonFluxData, RasterSet<WoodYieldItem> woodYieldData, 
+			TripleMap<Integer, Integer, LandCoverType, Double> minimumLandCover) {
 		double allowedImportChange;
 
 		if (currentTimestep.isInitialTimestep() || (ModelConfig.IS_CALIBRATION_RUN && currentTimestep.getTimestep() <= ModelConfig.END_FIRST_STAGE_CALIBRATION)) {  // initialisation time-step
@@ -200,11 +210,24 @@ public class CountryAgent extends AbstractCountryAgent {
 
 			importConstraints.put(crop, new TradeConstraint(baseTrade - changeDown, baseTrade + changeUp));
 		}
+		
+		// Aggregate minimum land cover for current timestep
+		DoubleMap<Integer, LandCoverType, Double> minimumLandCoverForTimestep = new DoubleMap<Integer, LandCoverType, Double>();
+		
+		for (Entry<Integer, DoubleMap<Integer, LandCoverType, Double>> yearMap : minimumLandCover.getMap().entrySet()) {
+			if (yearMap.getKey() < currentTimestep.getYear()) {
+				for (Entry<Integer, Map<LandCoverType, Double>> locMap : yearMap.getValue().getMap().entrySet()) {
+					for (Entry<LandCoverType, Double> coverMap : locMap.getValue().entrySet()) {
+						minimumLandCoverForTimestep.addTo(locMap.getKey(), coverMap.getKey(), coverMap.getValue());
+					}
+				}
+			}
+		}
 
 		GamsCountryInput countryLevelInputs = new GamsCountryInput(country, currentProjectedDemand, currentCountryPrices, importConstraints, 
 				previousGamsRasterOutput.getCropUsageData(), currentMinDemandFract, subsidyRates);	
 		GamsRasterInput input = new GamsRasterInput(currentTimestep, countryYieldSurfaces, previousGamsRasterOutput.getLandUses(), irrigData, 
-				carbonFluxData, woodYieldData, countryLevelInputs);
+				carbonFluxData, woodYieldData, minimumLandCoverForTimestep, countryLevelInputs);
 
 		return input;
 	}
@@ -291,4 +314,8 @@ public class CountryAgent extends AbstractCountryAgent {
 		}
 		
 	}
+	
+	private void updateMinimumLandCover() {
+		//TODO
+	}
 }
\ No newline at end of file
diff --git a/src/ac/ed/lurg/country/gams/GamsLocationInput.java b/src/ac/ed/lurg/country/gams/GamsLocationInput.java
index d00a90bf138a6dcba29b47d22609e582b5ec0c61..899e6e3324e1c3e3f95c6f913ba45e2354bdf532 100644
--- a/src/ac/ed/lurg/country/gams/GamsLocationInput.java
+++ b/src/ac/ed/lurg/country/gams/GamsLocationInput.java
@@ -7,6 +7,8 @@ import ac.ed.lurg.landuse.CarbonFluxItem;
 import ac.ed.lurg.landuse.IrrigationItem;
 import ac.ed.lurg.landuse.LandUseItem;
 import ac.ed.lurg.landuse.WoodYieldItem;
+import ac.ed.lurg.types.LandCoverType;
+import ac.ed.lurg.utils.DoubleMap;
 import ac.ed.lurg.yield.YieldResponsesItem;
 
 public class GamsLocationInput {
@@ -17,11 +19,12 @@ public class GamsLocationInput {
 	private Map<Integer, ? extends IrrigationItem> irrigationCosts;
 	private Map<Integer, ? extends CarbonFluxItem> carbonFluxes;
 	private Map<Integer, ? extends WoodYieldItem> woodYields;
+	private DoubleMap<Integer, LandCoverType, Double> minimumLandCover;
 	private GamsCountryInput countryInput;
 	
 	public GamsLocationInput(Timestep timestep, Map<Integer, ? extends YieldResponsesItem> yields, Map<Integer, ? extends LandUseItem> previousLandUse,
 			Map<Integer, ? extends IrrigationItem> irrigationCosts, Map<Integer, ? extends CarbonFluxItem> carbonFluxes, 
-			Map<Integer, ? extends WoodYieldItem> woodYields, GamsCountryInput countryInput) {
+			Map<Integer, ? extends WoodYieldItem> woodYields, DoubleMap<Integer, LandCoverType, Double> minimumLandCover, GamsCountryInput countryInput) {
 		super();
 		this.timestep = timestep;
 		this.yields = yields;
@@ -30,6 +33,7 @@ public class GamsLocationInput {
 		this.carbonFluxes = carbonFluxes;
 		this.woodYields = woodYields;
 		this.countryInput = countryInput;
+		this.minimumLandCover = minimumLandCover;
 	}
 		
 	public Map<Integer, ? extends YieldResponsesItem> getYields() {
@@ -52,6 +56,10 @@ public class GamsLocationInput {
 		return woodYields;
 	}
 	
+	public DoubleMap<Integer, LandCoverType, Double> getMinimumLandCover() {
+		return minimumLandCover;
+	}
+	
 	public GamsCountryInput getCountryInput() {
 		return countryInput;
 	}
diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
index 26eaa91fa082a1d09e1c95647206adbd35cbd0fa..2786437bb0ef3b756a59a4e666513c1bcda8439f 100644
--- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
+++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
@@ -27,7 +27,6 @@ import ac.ed.lurg.landuse.CarbonFluxItem;
 import ac.ed.lurg.landuse.CropUsageData;
 import ac.ed.lurg.landuse.Intensity;
 import ac.ed.lurg.landuse.IrrigationItem;
-import ac.ed.lurg.landuse.LandCoverChangeItem;
 import ac.ed.lurg.landuse.LandUseItem;
 import ac.ed.lurg.landuse.WoodYieldItem;
 import ac.ed.lurg.types.CommodityType;
@@ -36,6 +35,7 @@ import ac.ed.lurg.types.GamsLandCoverType;
 import ac.ed.lurg.types.LandCoverType;
 import ac.ed.lurg.types.Parameter;
 import ac.ed.lurg.types.YieldType;
+import ac.ed.lurg.utils.DoubleMap;
 import ac.ed.lurg.utils.LazyHashMap;
 import ac.ed.lurg.utils.LogWriter;
 import ac.ed.lurg.utils.TripleMap;
@@ -399,6 +399,21 @@ public class GamsLocationOptimiser {
 			
 		}
 		
+		// Minimum land covers
+		GAMSParameter minimumLandCover = inDB.addParameter("minimumLandCover", 2);
+		
+		for (Entry<Integer, Map<LandCoverType, Double>> locMap : inputData.getMinimumLandCover().getMap().entrySet()) {
+			Integer locationId = locMap.getKey();
+			String locString = Integer.toString(locationId);
+			
+			for (Entry<LandCoverType, Double> coverMap : locMap.getValue().entrySet()) {
+				Vector<String> v = new Vector<String>();
+				v.add(coverMap.getKey().getName());
+				v.add(locString);
+				setGamsParamValue(minimumLandCover.addRecord(v), coverMap.getValue(), 3);
+			}
+		}
+		
 	}
 
 	private void addScalar(GAMSDatabase gamsDb, String recordName, double val, int places) {
@@ -430,8 +445,9 @@ public class GamsLocationOptimiser {
 			GAMSGlobals.SolveStat.lookup((int) outDB.getParameter("ss").findRecord().getValue()));
         LogWriter.println("\n" + contextString);
 
-		if (modelStatus != ModelStat.OPTIMAL_LOCAL) 
+		if (modelStatus != ModelStat.OPTIMAL_LOCAL) {
 			LogWriter.printlnError("Critical!!! Land use incorrectly solved. " + contextString);
+		}
 		
 		GAMSVariable varAreas = outDB.getVariable("cropArea");
 		GAMSVariable varFertIntensities = outDB.getVariable("fertI");
@@ -566,6 +582,11 @@ public class GamsLocationOptimiser {
 		
 		TripleMap<Integer, LandCoverType, LandCoverType, Double> landCoverChanges = new TripleMap<Integer, LandCoverType, LandCoverType, Double>();
 		
+		/*
+		if (inputData.getCountryInput().getCountry().getName().equals("Peru & Ecuador")) {
+			LogWriter.println("foo");
+		}
+		*/
 		
 		for (GAMSVariableRecord rec : varLandCoverChange) {
 			String fromLC = rec.getKeys()[0];
@@ -575,11 +596,15 @@ public class GamsLocationOptimiser {
 			
 			double change = rec.getLevel();
 			
+			/*
 			if (change == 0.0) {
 				continue;
 			} 
+			*/
 			
-			if (fromLC.equals("natural")) {
+			if (fromLC.equals("natural") && toLC.equals("natural")) {
+				continue;
+			} else if (fromLC.equals("natural")) {
 				double prevUnmanagedForestProp = getPrevUnmanagedForestProp(locId);
 				landCoverChanges.put(locId, LandCoverType.UNMANAGED_FOREST, LandCoverType.getForName(toLC), change * prevUnmanagedForestProp);
 				landCoverChanges.put(locId, LandCoverType.OTHER_NATURAL, LandCoverType.getForName(toLC), change * (1 - prevUnmanagedForestProp));			
@@ -590,11 +615,25 @@ public class GamsLocationOptimiser {
 			} else {
 				landCoverChanges.put(locId, LandCoverType.getForName(fromLC), LandCoverType.getForName(toLC), change);
 			}
-			// Potential case where fromLC = natural and toLC = natural unaccounted for but should never happen due to GAMS constraint (LAND_COVER_SELF_CHANGE_CONTRAINT).
+			
 					
 		}
+		
+		// Minimum land cover additions. Need to keep track of new forest areas to restrict conversion
+		DoubleMap<Integer, LandCoverType, Double> minimumLandCoverAdditions = new DoubleMap<Integer, LandCoverType, Double>();
+		
+		for (Entry<Integer, DoubleMap<LandCoverType, LandCoverType, Double>> locMap : landCoverChanges.getMap().entrySet()) {
+			Integer locId = locMap.getKey();
+			DoubleMap<LandCoverType, LandCoverType, Double> changeMap = locMap.getValue();
+			for (LandCoverType fromLC : LandCoverType.getConvertibleTypes()) {
+				minimumLandCoverAdditions.addTo(locId, LandCoverType.TIMBER_FOREST, changeMap.get(fromLC, LandCoverType.TIMBER_FOREST));
+				minimumLandCoverAdditions.addTo(locId, LandCoverType.CARBON_FOREST, changeMap.get(fromLC, LandCoverType.CARBON_FOREST));
+			}
+			
+		}
+		
 
-		GamsLocationOutput results = new GamsLocationOutput(modelStatus, landUses, cropUsageData, landCoverChanges);
+		GamsLocationOutput results = new GamsLocationOutput(modelStatus, landUses, cropUsageData, landCoverChanges, minimumLandCoverAdditions);
 		return results;
 	}
 	
diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOutput.java b/src/ac/ed/lurg/country/gams/GamsLocationOutput.java
index 258064949b97f96c58357e0115a45fdea64f659d..a30c9d2deb5988673fabe9e7191318d7fec4f7e7 100644
--- a/src/ac/ed/lurg/country/gams/GamsLocationOutput.java
+++ b/src/ac/ed/lurg/country/gams/GamsLocationOutput.java
@@ -7,6 +7,7 @@ import com.gams.api.GAMSGlobals.ModelStat;
 import ac.ed.lurg.landuse.CropUsageData;
 import ac.ed.lurg.landuse.LandUseItem;
 import ac.ed.lurg.types.CropType;
+import ac.ed.lurg.utils.DoubleMap;
 import ac.ed.lurg.utils.TripleMap;
 import ac.ed.lurg.types.LandCoverType;
 
@@ -15,19 +16,20 @@ public class GamsLocationOutput {
 	
 	Map<Integer, LandUseItem> landUses;  // data mapped from id (not raster)
 	private Map<CropType, CropUsageData> cropUsageData;
-	//Map<Integer, DoubleMap<LandCoverType, LandCoverType, Double>> landCoverChange;
-	//LandCoverChangeItem landCoverChange;
 	TripleMap<Integer, LandCoverType, LandCoverType, Double> landCoverChanges;
+	DoubleMap<Integer, LandCoverType, Double> minimumLandCover;
 	
 	public GamsLocationOutput(ModelStat status, 
 			Map<Integer, LandUseItem> landUses, 
 			Map<CropType, CropUsageData> cropUsageData,
-			TripleMap<Integer, LandCoverType, LandCoverType, Double> landCoverChange) {
+			TripleMap<Integer, LandCoverType, LandCoverType, Double> landCoverChange,
+			DoubleMap<Integer, LandCoverType, Double> minimumLandCover) {
 		super();
 		this.status = status;
 		this.landUses = landUses;
 		this.cropUsageData = cropUsageData;
 		this.landCoverChanges = landCoverChange;
+		this.minimumLandCover = minimumLandCover;
 	}
 	
 	public ModelStat getStatus() {
@@ -44,4 +46,8 @@ public class GamsLocationOutput {
 	public TripleMap<Integer, LandCoverType, LandCoverType, Double> getLandCoverChanges() {
 		return landCoverChanges;
 	}
+	
+	public DoubleMap<Integer, LandCoverType, Double> getMinimumLandCover() {
+		return minimumLandCover;
+	}
 }
diff --git a/src/ac/ed/lurg/country/gams/GamsRasterInput.java b/src/ac/ed/lurg/country/gams/GamsRasterInput.java
index f6ef7f850b2255c10d3ad162a66dc8d5cfd9e117..1f6557762e44cbf3413ee3acd58d230590194181 100644
--- a/src/ac/ed/lurg/country/gams/GamsRasterInput.java
+++ b/src/ac/ed/lurg/country/gams/GamsRasterInput.java
@@ -3,6 +3,9 @@ package ac.ed.lurg.country.gams;
 import ac.ed.lurg.Timestep;
 import ac.ed.lurg.landuse.LandUseItem;
 import ac.ed.lurg.landuse.WoodYieldItem;
+import ac.ed.lurg.types.LandCoverType;
+import ac.ed.lurg.utils.DoubleMap;
+import ac.ed.lurg.utils.TripleMap;
 import ac.ed.lurg.landuse.CarbonFluxItem;
 import ac.ed.lurg.landuse.IrrigationItem;
 import ac.ed.lurg.yield.YieldRaster;
@@ -16,10 +19,12 @@ public class GamsRasterInput {
 	private RasterSet<IrrigationItem> irrigationCost;
 	private RasterSet<CarbonFluxItem> carbonFluxes;
 	private RasterSet<WoodYieldItem> woodYields;
+	private DoubleMap<Integer, LandCoverType, Double> minimumLandCover;
 	private GamsCountryInput countryInput;
 
 	public GamsRasterInput(Timestep timestep, YieldRaster yields, RasterSet<LandUseItem> previousLandsUses, RasterSet<IrrigationItem> irrigationCost, 
-			RasterSet<CarbonFluxItem> carbonFluxes, RasterSet<WoodYieldItem> woodYields, GamsCountryInput countryInput) {
+			RasterSet<CarbonFluxItem> carbonFluxes, RasterSet<WoodYieldItem> woodYields, DoubleMap<Integer, LandCoverType, Double> minimumLandCover,
+			GamsCountryInput countryInput) {
 		super();
 		this.timestep = timestep;
 		this.yields = yields;
@@ -27,6 +32,7 @@ public class GamsRasterInput {
 		this.irrigationCost = irrigationCost;
 		this.carbonFluxes = carbonFluxes;
 		this.woodYields = woodYields;
+		this.minimumLandCover = minimumLandCover;
 		this.countryInput = countryInput;
 	}
 
@@ -50,6 +56,10 @@ public class GamsRasterInput {
 		return woodYields;
 	}
 	
+	public DoubleMap<Integer, LandCoverType, Double> getMinimumLandCover() {
+		return minimumLandCover;
+	}
+	
 	public GamsCountryInput getCountryInput() {
 		return countryInput;
 	}
diff --git a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java
index a520bf68552b8a25b8078899ab796e4d94964a49..60b4cb5d4f8694e608904b3775f5252fde5b3a36 100644
--- a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java
+++ b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java
@@ -9,7 +9,6 @@ import ac.ed.lurg.ModelConfig;
 import ac.ed.lurg.landuse.CarbonFluxItem;
 import ac.ed.lurg.landuse.Intensity;
 import ac.ed.lurg.landuse.IrrigationItem;
-import ac.ed.lurg.landuse.LandCoverChangeItem;
 import ac.ed.lurg.landuse.LandUseItem;
 import ac.ed.lurg.landuse.WoodYieldItem;
 import ac.ed.lurg.types.CropType;
@@ -19,7 +18,6 @@ import ac.ed.lurg.types.YieldType;
 import ac.ed.lurg.utils.DoubleMap;
 import ac.ed.lurg.utils.LazyTreeMap;
 import ac.ed.lurg.utils.LogWriter;
-import ac.ed.lurg.utils.TripleMap;
 import ac.ed.lurg.yield.YieldRaster;
 import ac.ed.lurg.yield.YieldResponsesItem;
 import ac.sac.raster.IntegerRasterItem;
@@ -56,7 +54,7 @@ public class GamsRasterOptimiser {
 	private GamsRasterOutput convertToRaster(GamsLocationInput gamsInput, GamsLocationOutput gamsOutput) {		
 		RasterSet<LandUseItem> newIntensityRaster = allocAreas(gamsInput.getPreviousLandUse(), gamsOutput, gamsInput.getTimestep().getYear());
 
-		return new GamsRasterOutput(gamsOutput.getStatus(), newIntensityRaster, gamsOutput.getCommoditiesData());
+		return new GamsRasterOutput(gamsOutput.getStatus(), newIntensityRaster, gamsOutput.getCommoditiesData(), gamsOutput.getMinimumLandCover());
 	}
 
 	private RasterSet<LandUseItem> createWithSameLandCovers(RasterSet<LandUseItem> toCopy) {
@@ -103,8 +101,6 @@ public class GamsRasterOptimiser {
 
 		//checkedTotalAreas(rasterInputData.getPreviousAreas(), "old");
 		//checkedTotalAreas(newAreaRaster, "new");
-		
-		//TripleMap<Integer, LandCoverType, LandCoverType, Double> landCoverChanges = gamsOutput.getLandCoverChanges();
 
 		for (Map.Entry<Integer, LandUseItem> entry : gamsOutput.getLandUses().entrySet()) {
 			Integer locId = entry.getKey();
@@ -119,9 +115,13 @@ public class GamsRasterOptimiser {
 					keys.add(mapEntry.getKey());
 			}
 			
-
+			
 			RasterSet<LandUseItem> landUseItemsForLocation = newLandUseRaster.createSubsetForKeys(keys);
 			
+			if (rasterInputData.getCountryInput().getCountry().getName().equals("Peru & Ecuador")) {
+				LogWriter.println("foo");
+			}
+			
 			DoubleMap<LandCoverType, LandCoverType, Double> landCoverChange = gamsOutput.getLandCoverChanges().getInnerMap(locId);
 			
 			/*
@@ -204,7 +204,7 @@ public class GamsRasterOptimiser {
 				
 				double totalNaturalArea = newLandUseAggItem.getTotalNatural();
 				
-				
+				// Add protected area changes to GAMS changes
 				for (LandCoverType lc : LandCoverType.getProtectibleTypes()) {
 					double fraction = newLandUseAggItem.getLandCoverArea(lc) / totalNaturalArea;
 					landCoverChange.addTo(lc, LandCoverType.CROPLAND, protectedAreasCroplandChange * fraction);
@@ -549,7 +549,7 @@ public class GamsRasterOptimiser {
 		checkedTotalAreas(landUseRaster, "before");
 		checkedTotalAreas(aggregatedAreas, "after");
 		return new GamsLocationInput(rasterInputData.getTimestep(), aggregatedYields, aggregatedAreas, aggregatedIrrigCosts, 
-				aggregatedCarbonFluxes, aggregatedWoodYields, rasterInputData.getCountryInput());
+				aggregatedCarbonFluxes, aggregatedWoodYields, rasterInputData.getMinimumLandCover(), rasterInputData.getCountryInput());
 	}
 
 	private void logWarningWithCoord(String message, RasterKey key, YieldRaster yieldRaster, CropType crop) {
diff --git a/src/ac/ed/lurg/country/gams/GamsRasterOutput.java b/src/ac/ed/lurg/country/gams/GamsRasterOutput.java
index 33e021825cda6bb6983f9df3c5954fa199260fa6..78bbbfefd903a86d6dee4ce44e3c4f69d496166e 100644
--- a/src/ac/ed/lurg/country/gams/GamsRasterOutput.java
+++ b/src/ac/ed/lurg/country/gams/GamsRasterOutput.java
@@ -7,6 +7,8 @@ import com.gams.api.GAMSGlobals.ModelStat;
 import ac.ed.lurg.landuse.CropUsageData;
 import ac.ed.lurg.landuse.LandUseItem;
 import ac.ed.lurg.types.CropType;
+import ac.ed.lurg.types.LandCoverType;
+import ac.ed.lurg.utils.DoubleMap;
 import ac.sac.raster.RasterSet;
 
 public class GamsRasterOutput {
@@ -14,16 +16,19 @@ public class GamsRasterOutput {
 	private ModelStat status;
 	private RasterSet<LandUseItem> landUses;
 	private Map<CropType, CropUsageData> cropUsageData;
+	private DoubleMap<Integer, LandCoverType, Double> minimumLandCoverAdditions;
 
 	public GamsRasterOutput(RasterSet<LandUseItem> landUses, Map<CropType, CropUsageData> cropUsageData) {
 		super();
 		this.landUses = landUses;
-        this.cropUsageData = cropUsageData;
+        this.cropUsageData = cropUsageData; 
 	}
 
-	public GamsRasterOutput(ModelStat status, RasterSet<LandUseItem> intensityRaster, Map<CropType, CropUsageData> cropUsageData) {
+	public GamsRasterOutput(ModelStat status, RasterSet<LandUseItem> intensityRaster, Map<CropType, CropUsageData> cropUsageData,
+			DoubleMap<Integer, LandCoverType, Double> minimumLandCoverAdditions) {
 		this(intensityRaster, cropUsageData);
 		this.status = status;
+		this.minimumLandCoverAdditions = minimumLandCoverAdditions;
 	}
 	
 	public ModelStat getStatus() {
@@ -37,4 +42,8 @@ public class GamsRasterOutput {
 	public Map<CropType, CropUsageData> getCropUsageData() {
 		return cropUsageData;
 	}
+	
+	public DoubleMap<Integer, LandCoverType, Double> getMinimumLandCoverAdditions() {
+		return minimumLandCoverAdditions;
+	}
 }
diff --git a/src/ac/ed/lurg/landuse/LandUseItem.java b/src/ac/ed/lurg/landuse/LandUseItem.java
index dff462d47d8a7cabf0baa1baf370673572bb9940..b6e60f8233ff54bae7fc8e1d37037b1b8dcc9cff 100644
--- a/src/ac/ed/lurg/landuse/LandUseItem.java
+++ b/src/ac/ed/lurg/landuse/LandUseItem.java
@@ -11,6 +11,7 @@ import ac.ed.lurg.ModelConfig;
 import ac.ed.lurg.types.CropToDouble;
 import ac.ed.lurg.types.CropType;
 import ac.ed.lurg.types.LandCoverType;
+import ac.ed.lurg.utils.DoubleMap;
 import ac.ed.lurg.utils.Interpolator;
 import ac.sac.raster.InterpolatingRasterItem;
 
@@ -19,12 +20,12 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 	
 	private Map<CropType, Intensity> intensityMap = new HashMap<CropType, Intensity>();
 	private Map<CropType, Double> cropFractions = new HashMap<CropType, Double>();
-	private Map<LandCoverType, Double> landCoverAreas = new HashMap<LandCoverType, Double>();
-	private Map<LandCoverType, Double> unprotectedAreas = new HashMap<LandCoverType, Double>();
-	private Map<LandCoverType, Map<Integer, Double>> minimumLandCover = new HashMap<LandCoverType, Map<Integer, Double>>(); // Minimum land cover by year of expiry
+	private Map<LandCoverType, Double> landCoverAreas = new HashMap<LandCoverType, Double>(); //Mha
+	private Map<LandCoverType, Double> unprotectedAreas = new HashMap<LandCoverType, Double>(); //Mha
+	//private DoubleMap<LandCoverType, Integer, Double> minimumLandCover = new DoubleMap<LandCoverType, Integer, Double>(); //Minimum land cover by year of expiry (Mha)
 	private double protectedArea; //protected area in Mha
 	private double unavailableArea; //area unavailable due to altitude etc 
-	private double suitableArea;
+	private double suitableArea; //Mha
 	
 	public LandUseItem() {}
 	
@@ -435,9 +436,10 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 		return total;
 	}
 	
+	/*
 	public double getMinimumLandCover(LandCoverType lcType, Integer year) {
 		double area = 0;
-		Map<Integer, Double> yearMap = minimumLandCover.get(lcType);
+		Map<Integer, Double> yearMap = minimumLandCover.getInnerMap(lcType);
 		for (Entry<Integer, Double> entry : yearMap.entrySet()) {
 			if (entry.getKey() > year) {
 				area += entry.getValue();
@@ -445,6 +447,7 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 		}
 		return area;
 	}
+	*/
 	
 	@Override
 	public String toString() {
diff --git a/src/ac/ed/lurg/utils/DoubleMap.java b/src/ac/ed/lurg/utils/DoubleMap.java
index 9c2762b3a7ea918cd876a173527655af034d5e2c..c94b232b25ccf0c1cd25a3a9355484dfb68b7f78 100644
--- a/src/ac/ed/lurg/utils/DoubleMap.java
+++ b/src/ac/ed/lurg/utils/DoubleMap.java
@@ -3,12 +3,13 @@ package ac.ed.lurg.utils;
 import java.util.HashMap;
 import java.util.Map;
 
-public class DoubleMap<K, L, V extends Double> {
+public class DoubleMap<K, L, V> {
 	
-	Map<K, Map<L, Double>> theMap = new HashMap<K, Map<L, Double>>(); 
+	// Stores a double mapped by two consecutive keys
+	Map<K, Map<L, Double>> theMap; 
 	
 	public DoubleMap() {
-		
+		this.theMap = new HashMap<K, Map<L, Double>>(); 
 	}
 	
 	public void put(K key1, L key2, double value) {
diff --git a/src/ac/ed/lurg/utils/NestedMap.java b/src/ac/ed/lurg/utils/NestedMap.java
index 54f72c9b9a326241846770277ffe9878286debe8..397f686f9c72616d2ad5d7016933090b9a016a9b 100644
--- a/src/ac/ed/lurg/utils/NestedMap.java
+++ b/src/ac/ed/lurg/utils/NestedMap.java
@@ -5,47 +5,35 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.List;
 
-public class NestedMap {
+public class NestedMap<K, V> {
 
-	Map<Object, Object> theMap;
-	Integer depth;
+	private final HashMap<K, NestedMap> node;
+	private V value;
 	
-	NestedMap() {
-		theMap = new HashMap<Object, Object>();		
+	public NestedMap() {
+		node = new HashMap<>();
+		value = null;
 	}
 	
-	public void put(List<Object> keys, Object value) {
-		
-		
-		
-		Collections.reverse(keys);
-		theMap.put(keys.get(keys.size() - 1), createNestedMap(keys.subList(0, keys.size() - 1), value));	
+	public void makeNode(K key) {
+		this.node.put(key, new NestedMap());
 	}
-		
-	private Map<Object, Object> createNestedMap(List<Object> keys, Object value) {
-		Map<Object, Object> valueMap = new HashMap<Object, Object>();
-		valueMap.put(keys.get(0), value);	
-		Map<Object, Object> higherMap;
-		if (keys.size() > 1) {
-			higherMap = createNestedMap(keys.subList(1, keys.size()), valueMap);
-			return higherMap;
-		} else {
-			return valueMap;
-		}
+	
+	public NestedMap<K, V> getNode(K key) {
+		return this.node.get(key);
 	}
-	/*
-	private Map<Object, Object> getLowestLevel(List<Object> keys) {
-		if (theMap.containsKey(keys.get(0))) {
-			getLowestLevel(keys.subList(1, keys.size()));
-		} else {
-			return theMap.get(key);
-		}
+	
+	public boolean hasNode(K key) {
+		return this.node.containsKey(key);
 	}
-	*/
-	/*
-	private Map<Object, Object> getMapForKeys(List<Object> keys) {
-		Map<Object, Object> map = new HashMap<Object, Object>();
-		
+	
+	public void setValue(V value) {
+		this.value = value;
 	}
-	*/
+	
+	public V getValue() {
+		return value;
+	}
+	
+
 }
diff --git a/src/ac/ed/lurg/utils/TripleMap.java b/src/ac/ed/lurg/utils/TripleMap.java
index 78a0dbb9136a1ec786771786055c6f024e4d85b7..11c6cf37136d7f1119c7a11490b29e14bef21d1a 100644
--- a/src/ac/ed/lurg/utils/TripleMap.java
+++ b/src/ac/ed/lurg/utils/TripleMap.java
@@ -3,7 +3,7 @@ package ac.ed.lurg.utils;
 import java.util.HashMap;
 import java.util.Map;
 
-public class TripleMap<K, L, M, V extends Double> {
+public class TripleMap<K, L, M, V> {
 	
 	Map<K, DoubleMap<L, M, V >> theMap = new HashMap<K, DoubleMap<L, M, V>>(); 
 	
@@ -34,4 +34,8 @@ public class TripleMap<K, L, M, V extends Double> {
 		return theMap.get(key);
 
 	}
+	
+	public Map<K, DoubleMap<L, M, V >> getMap() {
+		return theMap;
+	}
 }