diff --git a/GAMS/IntExtOpt.gms b/GAMS/IntExtOpt.gms
index 3fd99c4d56922feb671289b1d880827d58116fd7..4fa6d2381d6b4f5624865a90dd6845dad7d7fefd 100644
--- a/GAMS/IntExtOpt.gms
+++ b/GAMS/IntExtOpt.gms
@@ -142,7 +142,9 @@ $gdxin
        pastureDecrease(location)
        landCoverArea(land_cover, location)  land cover area in Mha
        landCoverChange(land_cover_before, land_cover_after, location) land cover change
-       prematureDeforestationCost(location)
+       deforestedArea(forest, location) area of forest cut down
+       reservedAreaDeforested(forest, location) area of reserved (minimumLandCoverArea) forest cut down
+       prematureDeforestationCost
        woodHarvest(location)              total wood harvested
        carbonFlux(location)               total carbon flux
        totalFeedDM
@@ -187,10 +189,12 @@ $gdxin
        PASTURE_LAND_COVER_CALC(location)  pasture area (land cover) equals pasture area (land use)
 *       MINIMUM_LAND_COVER_CONSTRAINT(land_cover, location) constraint on land cover conversion
        LAND_COVER_CHANGE_CALC(land_cover, location)
-       LAND_COVER_CHANGE_CONSTRAINT(land_cover, location) can't convert more land than was previously available
-       LAND_COVER_SELF_CHANGE_CONSTRAINT(land_cover, location) calculate no change area (e.g. cropland to cropland)
+       LAND_COVER_CHANGE_CONSTRAINT(land_cover, location) conservation of land area
+*       LAND_COVER_SELF_CHANGE_CONSTRAINT(land_cover, location) calculate no change area (e.g. cropland to cropland)
        FOREST_EXPANSION_CONSTRAINT
-       PREMATURE_DEFORESTATION_COST_CALC(location)
+       DEFORESTED_AREA_CALC(forest, location)
+       RESERVED_AREA_DEFORESTED_CALC(forest, location)
+       PREMATURE_DEFORESTATION_COST_CALC
        WOOD_HARVEST_CALC(location)                          calc wood harvested
        CARBON_FLUX_CALC(location)                           calc carbon flux
        COST_EQ                                        total cost objective function;
@@ -254,20 +258,29 @@ $gdxin
 
  PASTURE_LAND_COVER_CALC(location) .. landCoverArea('pasture', location) =E= cropArea('pasture', location);
 
+* landCoverChange(A, A, location) defined as unchanged land cover
  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));
+                                                                                         sum(land_cover_before, landCoverChange(land_cover_before, land_cover, location)) -
+                                                                                         sum(land_cover_after, landCoverChange(land_cover, land_cover_after, location));
 
- LAND_COVER_CHANGE_CONSTRAINT(land_cover, location) .. sum(land_cover_after, landCoverChange(land_cover, land_cover_after, location)) =L= previousLandCoverArea(land_cover, location);
+ LAND_COVER_CHANGE_CONSTRAINT(land_cover, location) .. sum(land_cover_after, landCoverChange(land_cover, land_cover_after, location)) =E= previousLandCoverArea(land_cover, location);
 
- LAND_COVER_SELF_CHANGE_CONSTRAINT(land_cover, location) .. landCoverChange(land_cover, land_cover, location) =E= previousLandCoverArea(land_cover, location) -
-                                                            sum(land_cover_after$[not sameAs(land_cover, land_cover_after)], landCoverChange(land_cover, land_cover_after, location));
 
- FOREST_EXPANSION_CONSTRAINT .. sum((non_forest, forest, location), landCoverChange(non_forest, forest, location)) =L= sum(location, suitableLandArea(location)) * forestExpansionMaxRate;
+ FOREST_EXPANSION_CONSTRAINT .. sum((non_forest, forest, location), landCoverChange(non_forest, forest, location)) =L= sum((non_forest, location), previousLandCoverArea(non_forest, location)) * forestExpansionMaxRate;
 
 * MINIMUM_LAND_COVER_CONSTRAINT(land_cover, location) .. landCoverChange(land_cover, land_cover, location) =G= minimumLandCoverArea(land_cover, location);
 
- PREMATURE_DEFORESTATION_COST_CALC(location) .. prematureDeforestationCost(location) =E= sum(forest, (sum((land_cover_after)$[not sameAs(forest, land_cover_after)], landCoverChange(forest, land_cover_after, location)) -
-                                                         previousLandCoverArea(forest, location) - minimumLandCoverArea(forest, location))) * 1000;
+* PREMATURE_DEFORESTATION_COST_CALC(location) .. prematureDeforestationCost(location) =E= sum(forest, (sum((land_cover_after)$[not sameAs(forest, land_cover_after)], landCoverChange(forest, land_cover_after, location)) -
+*                                                         previousLandCoverArea(forest, location) - minimumLandCoverArea(forest, location)));
+
+ DEFORESTED_AREA_CALC(forest, location) .. deforestedArea(forest, location) =E= sum((land_cover_after)$[not sameAs(forest, land_cover_after)], landCoverChange(forest, land_cover_after, location));
+
+* Equivalent to MAX(0, deforestedArea(forest, location) - minimumLandCoverArea(forest, location)) https://www.gams.com/latest/docs/UG_NLP_GoodFormulations.html#UG_NLP_GoodFormulations_ReformulatingDNLPModels
+ RESERVED_AREA_DEFORESTED_CALC(forest, location) .. reservedAreaDeforested(forest, location) =E= [(deforestedArea(forest, location) - [previousLandCoverArea(forest, location) - minimumLandCoverArea(forest, location)] + delta) +
+                                                                                          sqrt(sqr(deforestedArea(forest, location) - [previousLandCoverArea(forest, location) - minimumLandCoverArea(forest, location)] + delta)) +
+                                                                                               sqr(delta)] / 2;
+
+ PREMATURE_DEFORESTATION_COST_CALC .. prematureDeforestationCost =E= sum((forest, location), reservedAreaDeforested(forest, location) * 100);
 
  WOOD_HARVEST_CALC(location) .. woodHarvest(location) =E= sum((land_cover_before, land_cover_after), landCoverChange(land_cover_before, land_cover_after, location) * woodYield(land_cover_before, land_cover_after, location));
 
@@ -292,7 +305,8 @@ $gdxin
                SUM(location, carbonFlux(location) * carbonPrice) - SUM(location, woodHarvest(location) * woodPrice) +
 
                SUM(import_crop, importAmount(import_crop) * importPrices(import_crop) - exportAmount(import_crop) * exportPrices(import_crop)) +
-                 SUM(location, prematureDeforestationCost(location))
+
+               prematureDeforestationCost
          );
 
  MODEL LAND_USE /ALL/ ;
diff --git a/src/ac/ed/lurg/ModelConfig.java b/src/ac/ed/lurg/ModelConfig.java
index 0bf741dd8d49f38122b66723f647f51c8f81be49..ef6786e06d55f47001e901026750d7fb349d4a55 100755
--- a/src/ac/ed/lurg/ModelConfig.java
+++ b/src/ac/ed/lurg/ModelConfig.java
@@ -425,6 +425,6 @@ public class ModelConfig {
 	// Forestry parameters
 	public static final double CARBON_PRICE = getDoubleProperty("CARBON_PRICE", 10.0); // $/tC-eq
 	public static final double WOOD_PRICE = getDoubleProperty("WOOD_PRICE", 50.0); // $/tC-eq
-	public static final int FOREST_LOCKIN_PERIOD = getIntProperty("FOREST_LOCKIN_PERIOD", 20); // cannot convert forest after planting for this many years
+	public static final int FOREST_LOCKIN_PERIOD = getIntProperty("FOREST_LOCKIN_PERIOD", 30); // cannot convert forest after planting for this many years
 	
 }
diff --git a/src/ac/ed/lurg/Timestep.java b/src/ac/ed/lurg/Timestep.java
index fe6b49ecb9fa126d1d59ba2e9e393c796752eec4..48b7c7b2e40b63c9bf24e53fcf8b438f8b505bcb 100644
--- a/src/ac/ed/lurg/Timestep.java
+++ b/src/ac/ed/lurg/Timestep.java
@@ -21,6 +21,14 @@ public class Timestep {
 		return ModelConfig.TIMESTEP_SIZE * (timestep - ModelConfig.START_TIMESTEP) + ModelConfig.BASE_YEAR;
 	}
 	
+	public int getPreviousYear() {
+		if (timestep == ModelConfig.START_TIMESTEP)
+			throw new RuntimeException("Can't getPreviousYear for " + timestep);
+		
+		return ModelConfig.TIMESTEP_SIZE * (getPreviousTimestep().getTimestep() - ModelConfig.START_TIMESTEP) + ModelConfig.BASE_YEAR;
+	}
+	
+	
 	public int getYieldYear() {
 		if (isInitialTimestep()) {
 			return ModelConfig.BASE_YEAR;
diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java
index 6c55218a66b3c0a6d2609957a404f2578bfc9666..421a98a332e418afbb07e18fe0910315f618f4bf 100644
--- a/src/ac/ed/lurg/country/CountryAgent.java
+++ b/src/ac/ed/lurg/country/CountryAgent.java
@@ -5,11 +5,14 @@ import java.io.IOException;
 import java.nio.file.FileSystems;
 import java.nio.file.Files;
 import java.nio.file.StandardCopyOption;
+import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 
 import ac.ed.lurg.ModelConfig;
 import ac.ed.lurg.country.gams.GamsCountryInput;
@@ -225,11 +228,28 @@ public class CountryAgent extends AbstractCountryAgent {
 				}
 			}
 		}
+		
+		// Logged timberForest area - to be converted to otherNatural
+		DoubleMap<Integer, LandCoverType, Double> loggedForest = new DoubleMap<Integer, LandCoverType, Double>(); //<Location, LandCoverType, Area>
+		
+		if (currentTimestep.getTimestep() != ModelConfig.START_TIMESTEP) {
+			for (Entry<Integer, DoubleMap<Integer, LandCoverType, Double>> yearMap : minimumLandCover.getMap().entrySet()) {
+				if (yearMap.getKey() <= currentTimestep.getYear() && yearMap.getKey() > currentTimestep.getPreviousYear()) {
+					for (Entry<Integer, Map<LandCoverType, Double>> locMap : yearMap.getValue().getMap().entrySet()) {
+						for (Entry<LandCoverType, Double> coverMap : locMap.getValue().entrySet()) {
+							loggedForest.put(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, minimumLandCoverForTimestep, countryLevelInputs);
+				carbonFluxData, woodYieldData, minimumLandCoverForTimestep, loggedForest, countryLevelInputs);
 
 		return input;
 	}
@@ -349,5 +369,30 @@ public class CountryAgent extends AbstractCountryAgent {
 				 minimumLandCover.put(expiryYear, locId, lcChange.getKey(), lcChange.getValue());
 			 }
 		 }
+		 // Remove deforested area from minimum area requirement
+		 DoubleMap<Integer, LandCoverType, Double> reservedDeforested = previousGamsRasterOutput.getReservedDeforested();
+		 if (!reservedDeforested.getMap().isEmpty()) {
+			 for (Entry<Integer, Map<LandCoverType, Double>> locMap : reservedDeforested.getMap().entrySet()) {
+				 int locId = locMap.getKey();
+				 for (Entry<LandCoverType, Double> coverMap : locMap.getValue().entrySet()) {
+					 LandCoverType forestType = coverMap.getKey();
+					 double deforestedArea = coverMap.getValue();
+					 List<Integer> expiryYearsFound = new ArrayList<Integer>(minimumLandCover.getMap().keySet()) ; 
+					 Collections.sort(expiryYearsFound); // ascending order, remove area from most mature forest
+					 while (deforestedArea > 0) {
+						 for (int year : expiryYearsFound) {
+							 if (year > currentTimestep.getYear()) {
+								 double currentMinimumArea = minimumLandCover.get(year, locId, forestType);
+								 if (currentMinimumArea <= 0) 
+									 LogWriter.printlnError("currentMinimumArea is <=0");
+								 double areaToSubtract = Math.min(currentMinimumArea, deforestedArea);
+								 minimumLandCover.put(year, locId, forestType, currentMinimumArea - areaToSubtract);
+								 deforestedArea -= areaToSubtract;
+							 }
+						 }
+					 }
+				 }
+			 } 
+		 }
 	}
 }
\ No newline at end of file
diff --git a/src/ac/ed/lurg/country/CountryAgentManager.java b/src/ac/ed/lurg/country/CountryAgentManager.java
index a7395b36a0018b1cc50abb63610d71cce5ccbf28..66eb021b7abb48b15ddbcb29c3803517ad7492ee 100644
--- a/src/ac/ed/lurg/country/CountryAgentManager.java
+++ b/src/ac/ed/lurg/country/CountryAgentManager.java
@@ -126,7 +126,7 @@ public class CountryAgentManager {
 					clusterIdRaster.putAll(ca.getYieldClusters());
 				
 			} catch (Exception e) {
-				LogWriter.printlnError("Exception processing " + ca.getCountry() + " will continue with other countries");
+ 				LogWriter.printlnError("Exception processing " + ca.getCountry() + " will continue with other countries");
 				LogWriter.print(e);
 			}
 		}
diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
index 6844c309a2e982dfde3329a5413c80c2f8183e94..815eb0979f33dbf9b3111cb8e3c83bc558fb30bc 100644
--- a/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
+++ b/src/ac/ed/lurg/country/gams/GamsLocationOptimiser.java
@@ -535,42 +535,7 @@ public class GamsLocationOptimiser {
 		LogWriter.println(String.format("\n%s %s: Total area= %.1f (crop=%.1f, pasture %.1f)", 
 				inputData.getCountryInput().getCountry(), inputData.getTimestep().getYear(), 
 				totalCropArea+totalPastureArea, totalCropArea, totalPastureArea));
-		
-		
-/*		
-		// Land cover areas (exc. cropland and pasture)
-		GAMSVariable varLandCoverArea = outDB.getVariable("landCoverArea");
-		double landCoverArea;
-				
-		for (GAMSVariableRecord rec : varLandCoverArea) {
-			String lc = rec.getKeys()[0];
-			String locationName = rec.getKeys()[1];
-			int locId = Integer.parseInt(locationName);
-			
-			landCoverArea = rec.getLevel();
 			
-			LandUseItem landUseItem = landUses.lazyGet(locId);
-			
-			switch(lc) {
-			case "forestT":
-				landUseItem.setLandCoverArea(LandCoverType.TIMBER_FOREST, landCoverArea);
-				break;
-			case "forestC":
-				landUseItem.setLandCoverArea(LandCoverType.CARBON_FOREST, landCoverArea);
-				break;
-			case "natural":
-				
-				double prevOtherNaturalArea = inputData.getPreviousLandUse().get(locId).getLandCoverArea(LandCoverType.OTHER_NATURAL);
-				double prevUnmanagedForestArea = inputData.getPreviousLandUse().get(locId).getLandCoverArea(LandCoverType.UNMANAGED_FOREST);
-				double prevUnmanagedForestProp = (prevOtherNaturalArea + prevUnmanagedForestArea) != 0 ? prevUnmanagedForestArea / (prevUnmanagedForestArea + prevOtherNaturalArea) : 0;
-				
-				landUseItem.setLandCoverArea(LandCoverType.UNMANAGED_FOREST, landCoverArea * prevUnmanagedForestProp); // TODO Split into unmanaged forest and other natural
-				landUseItem.setLandCoverArea(LandCoverType.OTHER_NATURAL, landCoverArea * (1 - prevUnmanagedForestProp)); // TODO Split into unmanaged forest and other natural
-				break;
-			}
-							
-		}
-*/		
 		// Land cover change
 		GAMSVariable varLandCoverChange = outDB.getVariable("landCoverChange");
 		
@@ -587,27 +552,6 @@ public class GamsLocationOptimiser {
 			if (!fromLC.equals(toLC)) { //Important as don't want to include unchanged land cover
 				landCoverChanges.put(locId, LandCoverType.getForName(fromLC), LandCoverType.getForName(toLC), change);
 			}
-			/*
-			if (change == 0.0) {
-				continue;
-			} 
-			*/
-			
-			/*
-			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));			
-			} else if (toLC.equals("natural")) {
-				double prevUnmanagedForestProp = getPrevUnmanagedForestProp(locId);
-				landCoverChanges.put(locId, LandCoverType.getForName(fromLC), LandCoverType.UNMANAGED_FOREST, change * prevUnmanagedForestProp);
-				landCoverChanges.put(locId, LandCoverType.getForName(fromLC), LandCoverType.OTHER_NATURAL, change * (1 - prevUnmanagedForestProp));
-			} else {
-				landCoverChanges.put(locId, LandCoverType.getForName(fromLC), LandCoverType.getForName(toLC), change);
-			}
-			*/
 						
 		}
 		
@@ -628,8 +572,24 @@ public class GamsLocationOptimiser {
 				*/
 			}	
 		}
+		
+		// reserved Forest which was deforested
+		GAMSVariable varReservedDeforested = outDB.getVariable("reservedAreaDeforested");
+		DoubleMap<Integer, LandCoverType, Double> reservedDeforested = new DoubleMap<Integer, LandCoverType, Double>();
+		
+		for (GAMSVariableRecord rec : varReservedDeforested) {
+			String landCover = rec.getKeys()[0];
+			String locationName = rec.getKeys()[1];
+			int locId = Integer.parseInt(locationName);
+			
+			double deforestedArea = rec.getLevel();
+			
+			if (deforestedArea > 0.00001) {
+				reservedDeforested.put(locId, LandCoverType.getForName(landCover), deforestedArea);
+			}							
+		}
 
-		GamsLocationOutput results = new GamsLocationOutput(modelStatus, landUses, cropUsageData, landCoverChanges, minimumLandCoverAdditions);
+		GamsLocationOutput results = new GamsLocationOutput(modelStatus, landUses, cropUsageData, landCoverChanges, minimumLandCoverAdditions, reservedDeforested);
 		return results;
 	}
 	
diff --git a/src/ac/ed/lurg/country/gams/GamsLocationOutput.java b/src/ac/ed/lurg/country/gams/GamsLocationOutput.java
index a30c9d2deb5988673fabe9e7191318d7fec4f7e7..05a7a54f845b4a81d56c8ceec43a03bc290f80fb 100644
--- a/src/ac/ed/lurg/country/gams/GamsLocationOutput.java
+++ b/src/ac/ed/lurg/country/gams/GamsLocationOutput.java
@@ -18,18 +18,21 @@ public class GamsLocationOutput {
 	private Map<CropType, CropUsageData> cropUsageData;
 	TripleMap<Integer, LandCoverType, LandCoverType, Double> landCoverChanges;
 	DoubleMap<Integer, LandCoverType, Double> minimumLandCover;
+	DoubleMap<Integer, LandCoverType, Double> reservedDeforested;
 	
 	public GamsLocationOutput(ModelStat status, 
 			Map<Integer, LandUseItem> landUses, 
 			Map<CropType, CropUsageData> cropUsageData,
 			TripleMap<Integer, LandCoverType, LandCoverType, Double> landCoverChange,
-			DoubleMap<Integer, LandCoverType, Double> minimumLandCover) {
+			DoubleMap<Integer, LandCoverType, Double> minimumLandCover,
+			DoubleMap<Integer, LandCoverType, Double> reservedDeforested) {
 		super();
 		this.status = status;
 		this.landUses = landUses;
 		this.cropUsageData = cropUsageData;
 		this.landCoverChanges = landCoverChange;
 		this.minimumLandCover = minimumLandCover;
+		this.reservedDeforested = reservedDeforested;
 	}
 	
 	public ModelStat getStatus() {
@@ -50,4 +53,8 @@ public class GamsLocationOutput {
 	public DoubleMap<Integer, LandCoverType, Double> getMinimumLandCover() {
 		return minimumLandCover;
 	}
+	
+	public DoubleMap<Integer, LandCoverType, Double> getReservedDeforested() {
+		return reservedDeforested;
+	}
 }
diff --git a/src/ac/ed/lurg/country/gams/GamsRasterInput.java b/src/ac/ed/lurg/country/gams/GamsRasterInput.java
index 759107b3a3ddaf1836a4fedf684af1ac540310a8..e4e1171b2666853e2d71cba009cf5b7f1ce1661d 100644
--- a/src/ac/ed/lurg/country/gams/GamsRasterInput.java
+++ b/src/ac/ed/lurg/country/gams/GamsRasterInput.java
@@ -19,11 +19,12 @@ public class GamsRasterInput {
 	private RasterSet<CarbonFluxItem> carbonFluxes;
 	private RasterSet<WoodYieldItem> woodYields;
 	private DoubleMap<Integer, LandCoverType, Double> minimumLandCover;
+	private DoubleMap<Integer, LandCoverType, Double> loggedForest;
 	private GamsCountryInput countryInput;
 
 	public GamsRasterInput(Timestep timestep, YieldRaster yields, RasterSet<LandUseItem> previousLandsUses, RasterSet<IrrigationItem> irrigationCost, 
 			RasterSet<CarbonFluxItem> carbonFluxes, RasterSet<WoodYieldItem> woodYields, DoubleMap<Integer, LandCoverType, Double> minimumLandCover,
-			GamsCountryInput countryInput) {
+			DoubleMap<Integer, LandCoverType, Double> loggedForest, GamsCountryInput countryInput) {
 		super();
 		this.timestep = timestep;
 		this.yields = yields;
@@ -32,6 +33,7 @@ public class GamsRasterInput {
 		this.carbonFluxes = carbonFluxes;
 		this.woodYields = woodYields;
 		this.minimumLandCover = minimumLandCover;
+		this.loggedForest = loggedForest;
 		this.countryInput = countryInput;
 	}
 
@@ -59,6 +61,10 @@ public class GamsRasterInput {
 		return minimumLandCover;
 	}
 	
+	public DoubleMap<Integer, LandCoverType, Double> getLoggedForest() {
+		return loggedForest;
+	}
+	
 	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 74fe24d22d6fa318166433c231d91087c1cce6d5..b7dcecdafb4266639cf34ecfa994d8ccf40e1e0d 100644
--- a/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java
+++ b/src/ac/ed/lurg/country/gams/GamsRasterOptimiser.java
@@ -53,7 +53,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(), gamsOutput.getMinimumLandCover());
+		return new GamsRasterOutput(gamsOutput.getStatus(), newIntensityRaster, gamsOutput.getCommoditiesData(), gamsOutput.getMinimumLandCover(), gamsOutput.getReservedDeforested());
 	}
 
 	private RasterSet<LandUseItem> createWithSameLandCovers(RasterSet<LandUseItem> toCopy) {
@@ -98,19 +98,9 @@ public class GamsRasterOptimiser {
 	private RasterSet<LandUseItem> allocAreas(Map<Integer, ? extends LandUseItem> prevAreasAgg, GamsLocationOutput gamsOutput, int year) {
 		RasterSet<LandUseItem> newLandUseRaster = createWithSameLandCovers(rasterInputData.getPreviousLandUses());
 
-		//checkedTotalAreas(rasterInputData.getPreviousAreas(), "old");
-		//checkedTotalAreas(newAreaRaster, "new");
-
 		for (Map.Entry<Integer, LandUseItem> entry : gamsOutput.getLandUses().entrySet()) {
 			Integer locId = entry.getKey();
 			LandUseItem newLandUseAggItem = entry.getValue();
-//			LandUseItem prevLandUseAggItem = prevAreasAgg.get(locId);
-			
-			/*
-			for (Entry<RasterKey, IntegerRasterItem> foo : mapping.entrySet()) {
-				LogWriter.println(foo.getKey() + "|" + foo.getValue().getInt());
-			}
-			*/
 
 			Set<RasterKey> keys = new HashSet<RasterKey>();
 			for (Entry<RasterKey, IntegerRasterItem> mapEntry : mapping.entrySet()) {
@@ -120,104 +110,10 @@ 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);
 			
-			/*
-			if (landCoverChange == null) {
-				landCoverChange = new DoubleMap<LandCoverType, LandCoverType, Double>();
-			}
-			*/
-			
-			double prevTimberForest = 0, prevCarbonForest = 0, prevUnmanagedForest = 0, prevNatural = 0;
-			double protectedAreasPastureChange = 0, protectedAreasCroplandChange = 0;  
-
-			for (LandUseItem luItem: landUseItemsForLocation.values()) {
-				prevTimberForest += luItem.getUnprotectedLandCoverArea(LandCoverType.TIMBER_FOREST);
-				prevCarbonForest += luItem.getUnprotectedLandCoverArea(LandCoverType.CARBON_FOREST);
-				prevUnmanagedForest += luItem.getUnprotectedLandCoverArea(LandCoverType.UNMANAGED_FOREST);
-				prevNatural += luItem.getTotalUnprotectedNatural();
-			}
-
-			double prevForestTotal = prevTimberForest + + prevCarbonForest + prevUnmanagedForest;
-			double prevForestToNaturalFraction = (prevNatural > 0) ? prevForestTotal / prevNatural : 0;
-			double prevForestTimberFraction = (prevForestTotal > 0) ? prevTimberForest / prevForestTotal : 0;
-			double prevForestCarbonFraction = (prevForestTotal > 0) ? prevCarbonForest / prevForestTotal : 0;
-			double prevForestUnmanagedFraction = (prevForestTotal > 0) ? prevUnmanagedForest / prevForestTotal : 0;
-			
-			// Floating point errors
-			if(prevForestToNaturalFraction > 1.0) prevForestToNaturalFraction = 1.0;
-			if(prevForestTimberFraction > 1.0) prevForestTimberFraction = 1.0;
-			if(prevForestCarbonFraction > 1.0) prevForestCarbonFraction = 1.0;
-			if(prevForestUnmanagedFraction > 1.0) prevForestUnmanagedFraction = 1.0;
-			
-			
-			//this tries to honour spatial distribution of protected areas, force removal of pasture and cropland from protected areas 
-			if (ModelConfig.FORCE_PROTECTED_AREAS && year >= ModelConfig.FORCE_PROTECTED_AREAS_START_YEAR) {
-				double protectedLandShortfall = 0;
-
-				for (LandUseItem luItem: landUseItemsForLocation.values()) {
-
-					double suitableLand = luItem.getSuitableArea();
-					double prevCropland = luItem.getLandCoverArea(LandCoverType.CROPLAND);
-					double prevPasture = luItem.getLandCoverArea(LandCoverType.PASTURE);
-
-					//if we have more agricultural land in this cell than we should, remove it and add it to land needing reallocated 
-					if (suitableLand < (prevCropland + prevPasture)) {
-
-						double excessAgriculture = prevCropland + prevPasture - suitableLand;
-						double prevPastureFract = prevPasture / (prevCropland + prevPasture);
-						double pastureShortfall = excessAgriculture * prevPastureFract;
-						double croplandShortfall = excessAgriculture * (1 - prevPastureFract);
-
-						protectedLandShortfall += luItem.moveAreas(LandCoverType.TIMBER_FOREST, LandCoverType.PASTURE,
-								pastureShortfall * prevForestToNaturalFraction * prevForestTimberFraction);
-						protectedLandShortfall += luItem.moveAreas(LandCoverType.TIMBER_FOREST, LandCoverType.PASTURE,
-								pastureShortfall * prevForestToNaturalFraction * prevForestCarbonFraction);
-						protectedLandShortfall += luItem.moveAreas(LandCoverType.UNMANAGED_FOREST, LandCoverType.PASTURE,
-								pastureShortfall * prevForestToNaturalFraction * prevForestUnmanagedFraction);
-						protectedLandShortfall += luItem.moveAreas(LandCoverType.OTHER_NATURAL, LandCoverType.PASTURE,
-								pastureShortfall * (1 - prevForestToNaturalFraction));
-						protectedLandShortfall += luItem.moveAreas(LandCoverType.TIMBER_FOREST, LandCoverType.CROPLAND,
-								croplandShortfall * prevForestToNaturalFraction * prevForestTimberFraction);
-						protectedLandShortfall += luItem.moveAreas(LandCoverType.CARBON_FOREST, LandCoverType.CROPLAND,
-								croplandShortfall * prevForestToNaturalFraction * prevForestCarbonFraction);
-						protectedLandShortfall += luItem.moveAreas(LandCoverType.UNMANAGED_FOREST, LandCoverType.CROPLAND,
-								croplandShortfall * prevForestToNaturalFraction * prevForestUnmanagedFraction);
-						protectedLandShortfall += luItem.moveAreas(LandCoverType.OTHER_NATURAL, LandCoverType.CROPLAND,
-								croplandShortfall * (1 - prevForestToNaturalFraction));
-
-						protectedAreasPastureChange+= pastureShortfall;
-						protectedAreasCroplandChange+= croplandShortfall;
-					}
-
-				}
-
-				if(protectedLandShortfall > 0.00001) {
-					LogWriter.printlnWarning("locID " + locId + " Not able to incorporate all protected area changes " + protectedLandShortfall + " remains unprotected.");
-				}
-
-				if (DEBUG) {
-					LogWriter.println("protectedAreasPastureChange " + protectedAreasPastureChange + " protectedAreasCroplandChange " + protectedAreasCroplandChange);
-				}
-				
-				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);
-					landCoverChange.addTo(lc, LandCoverType.PASTURE, protectedAreasPastureChange * fraction);
-				}
-
-			}	
-			
 			// Allocate land cover change to grid cells
 			for (Entry<LandCoverType, Map<LandCoverType, Double>> fromMap: landCoverChange.getMap().entrySet()) {
 				LandCoverType fromLC = fromMap.getKey();
@@ -235,7 +131,6 @@ public class GamsRasterOptimiser {
 						newLandUseItem.setCropFraction(crop, newLandUseAggItem.getCropFraction(crop));
 						newLandUseItem.setIntensity(crop, newLandUseAggItem.getIntensity(crop)); // intensities constant over single aggregated land category
 					}
-
 				}
 			}
 			
@@ -278,12 +173,13 @@ public class GamsRasterOptimiser {
 		}
 
 		for (RasterKey key : keys) {
-			//if (DEBUG) LogWriter.println("  Processing raster key " + key);
+			//if (DEBUG) LogWriter.println("Processing raster key " + key);
 			LandUseItem newLandUseItem = newLandUseRaster.get(key);
 
 			if (newLandUseItem!=null) {
-				double cellChange = (fromType.isProtectable() && totalUnprotectedLC > 0) ? change * newLandUseItem.getUnprotectedLandCoverArea(fromType)/totalUnprotectedLC : change / keys.size();
+				double cellChange = (totalUnprotectedLC > 0) ? change * newLandUseItem.getUnprotectedLandCoverArea(fromType)/totalUnprotectedLC : change / keys.size();
 				double shortfall = newLandUseItem.moveAreas(toType, fromType, cellChange);
+				shortfall += newLandUseItem.moveUnprotectedArea(toType, fromType, cellChange);
 				if (shortfall == 0)
 					keysWithSpace.add(key);
 				else
@@ -293,12 +189,6 @@ public class GamsRasterOptimiser {
 			}
 		}
 
-		// Now we check for unprotected areas, I think this is redundant.  However, it does cause a problem so leaving just in case it is needed.
-		if (totalShortfall > 0 & keysWithSpace.size() > 0) {  // more to allocate and some free areas to allocate into
-			if (DEBUG) LogWriter.println("A total land cover of " + totalShortfall + " is unallocated, so trying again with areas with space");
-			totalShortfall = allocAllLandCrops(newLandUseRaster, keysWithSpace, toType, fromType, totalShortfall);
-		}
-
 		if (DEBUG) LogWriter.println("allocAllLandCrops: from " + fromType + " to " + toType + " change " + change + " totalShortfall " + totalShortfall);
 		return totalShortfall;
 	}
@@ -309,43 +199,11 @@ public class GamsRasterOptimiser {
 		YieldRaster yieldRaster = rasterInputData.getYields();
 		RasterSet<LandUseItem> landUseRaster = rasterInputData.getPreviousLandUses();
 
-		//	LandUseItem test = landUseRaster.getFromCoordinates(71.25, 35.25);
-
-		/*	new RasterOutputer<AreasItem>(cropAreaRaster, "BeforeLandCover") {
-			@Override
-			public Double getValue(RasterKey location) {
-				AreasItem area = results.get(location);
-				if (area == null)
-					return null;
-
-				int count = 0;
-				double maxLC = 0;
-				int maxId = 0;
-				for (LandCoverType l : LandCoverType.values()) {
-					count++;
-					if (maxLC < area.getLandCoverArea(l)) {
-						maxLC = area.getLandCoverArea(l);
-						maxId = count;
-					}
-				}
-				return (double)maxId;
-			}
-
-			@Override
-			public int convertToPixelValue(double value) {
-				return (int) (1 + value * 2);
-			}
-		}.writeOutput(true); */
-
-
 		RasterSet<IrrigationItem> irrigRaster = rasterInputData.getIrrigationData();
 		
 		RasterSet<CarbonFluxItem> carbonFluxRaster = rasterInputData.getCarbonFluxes();
 		
 		RasterSet<WoodYieldItem> woodYieldRaster = rasterInputData.getWoodYields();
-		
-		//	YieldResponsesItem yresp = yieldRaster.get(new RasterKey(40,38));//getFromCoordinates(-118.0, -33.0);
-		//	LogWriter.printlnError("Test key2: " + yresp.getYieldMax(CropType.WHEAT)  + ", " + yresp.getYieldFertOnly(CropType.WHEAT) + ", " + yresp.getYieldIrrigOnly(CropType.WHEAT));
 
 		// look for inconsistencies
 		for (Entry<RasterKey, YieldResponsesItem> entry : yieldRaster.entrySet()) {
@@ -359,6 +217,7 @@ public class GamsRasterOptimiser {
 			}
 		}
 
+		// Aggregation
 		LazyTreeMap<Integer, YieldResponsesItem> aggregatedYields = new LazyTreeMap<Integer, YieldResponsesItem>() { 
 			protected YieldResponsesItem createValue() { return new YieldResponsesItem(); }
 		};
@@ -375,7 +234,6 @@ public class GamsRasterOptimiser {
 			protected WoodYieldItem createValue() { return new WoodYieldItem(); }
 		};
 
-
 		int countFound = 0, countMissing = 0;
 
 		for (Entry<RasterKey, YieldResponsesItem> entry : yieldRaster.entrySet()) {
@@ -410,7 +268,14 @@ public class GamsRasterOptimiser {
 				CarbonFluxItem aggCFlux = aggregatedCarbonFluxes.lazyGet(clusterId);
 				WoodYieldItem aggWYield = aggregatedWoodYields.lazyGet(clusterId);
 				
-				landUseItem.updateSuitableArea(rasterInputData.getTimestep().getYear());
+				/*
+				if (clusterId == 4 && rasterInputData.getTimestep().getYear() == 2011) {
+					int foo = 1;
+				}
+				*/
+				
+				// TODO disabled protected area update
+				//landUseItem.updateSuitableArea(rasterInputData.getTimestep().getYear());
 				double suitableAreaThisTime  = landUseItem.getSuitableArea();
 				double suitableAreaSoFar = aggLandUse.getSuitableArea();
 				
@@ -514,47 +379,33 @@ public class GamsRasterOptimiser {
 				
 			}
 		}	
-/*
-		for (Entry<RasterKey, LandUseItem> entry : rasterInputData.getPreviousLandUses().entrySet()) {
-			LandUseItem landUseItem = entry.getValue();
-			RasterKey key = entry.getKey();
-			int clusterId = mapping.get(key).getInt();
-			LandUseItem aggLandUse = aggregatedAreas.lazyGet(clusterId);
-			
-			// Land covers areas
-			for (LandCoverType landType : LandCoverType.values()) {
-				double areaThisTime = landUseItem.getUnprotectedLandCoverArea(landType);
-				double areaSoFar = aggLandUse.getUnprotectedLandCoverArea(landType);
-			
-				aggLandUse.setLandCoverArea(landType, areaSoFar + areaThisTime);
-			}
-		}
-*/
-/*
-		if (rasterInputData.getCountryInput().getCountry().getName().equals("Central America")) {
-			LogWriter.println("foo");
-		}
-*/
+
 		LogWriter.println("YieldResponsesItem: " + rasterInputData.getCountryInput().getCountry() + ", countFound=" + countFound + ", countMissing=" + countMissing);
-		
-		
-		//	for (Map.Entry<Integer, Set<RasterKey>> e : mapping.entrySet()) {
-		//	LogWriter.println(e.getKey() + " zone has " + e.getValue().size() + " raster areas");
-
-		/*	CropType[] cs = {CropType.WHEAT, CropType.MAIZE};
-			for (CropType c : cs) {
-				for (RasterKey key : e.getValue()) {
-					YieldResponsesItem yri = yieldRaster.get(key);
-					LogWriter.println(String.format("\t%s: x=%.1f y=%.1f: %s yields (none,fmid,fmax,irrig,both) %.1f, %.1f, %.1f, %.1f, %.1f", 
-							key, yieldRaster.getXCoordin(key), yieldRaster.getYCoordin(key), c.getGamsName(),
-							yri.getYieldNone(c), yri.getYieldMidFertOnly(c), yri.getYieldFertOnly(c), yri.getYieldIrrigOnly(c), yri.getYieldMax(c)));
-				}
-				LogWriter.println("");
-			} */
-		//	}
 
 		checkedTotalAreas(landUseRaster, "before");
 		checkedTotalAreas(aggregatedAreas, "after");
+			
+		// Auto convert timberForest to otherNatural once matured and cut down
+		if (!rasterInputData.getLoggedForest().getMap().isEmpty()) {
+			for (Entry<Integer, Map<LandCoverType, Double>> locMap : rasterInputData.getLoggedForest().getMap().entrySet()) {
+				int locId = locMap.getKey();
+				
+				Set<RasterKey> keys = new HashSet<RasterKey>();
+				for (Entry<RasterKey, IntegerRasterItem> mapEntry : mapping.entrySet()) {
+					IntegerRasterItem iri = mapEntry.getValue();
+					if (iri != null && locId == iri.getInt())
+						keys.add(mapEntry.getKey());
+				}
+				
+				for (Entry<LandCoverType, Double> coverMap : locMap.getValue().entrySet()) {
+					// move land for GAMS input
+					aggregatedAreas.get(locId).moveUnprotectedArea(LandCoverType.OTHER_NATURAL, coverMap.getKey(), coverMap.getValue());
+					// move land for raster
+					allocAllLandCropsTop(rasterInputData.getPreviousLandUses(), keys, LandCoverType.OTHER_NATURAL, coverMap.getKey(), coverMap.getValue(), locId);
+				}
+			}
+		}
+		
 		return new GamsLocationInput(rasterInputData.getTimestep(), aggregatedYields, aggregatedAreas, aggregatedIrrigCosts, 
 				aggregatedCarbonFluxes, aggregatedWoodYields, rasterInputData.getMinimumLandCover(), rasterInputData.getCountryInput());
 	}
diff --git a/src/ac/ed/lurg/country/gams/GamsRasterOutput.java b/src/ac/ed/lurg/country/gams/GamsRasterOutput.java
index 78bbbfefd903a86d6dee4ce44e3c4f69d496166e..b141c061d57eb6cbb8c882b5a7e44ff8114843e1 100644
--- a/src/ac/ed/lurg/country/gams/GamsRasterOutput.java
+++ b/src/ac/ed/lurg/country/gams/GamsRasterOutput.java
@@ -17,6 +17,7 @@ public class GamsRasterOutput {
 	private RasterSet<LandUseItem> landUses;
 	private Map<CropType, CropUsageData> cropUsageData;
 	private DoubleMap<Integer, LandCoverType, Double> minimumLandCoverAdditions;
+	DoubleMap<Integer, LandCoverType, Double> reservedDeforested;
 
 	public GamsRasterOutput(RasterSet<LandUseItem> landUses, Map<CropType, CropUsageData> cropUsageData) {
 		super();
@@ -25,10 +26,11 @@ public class GamsRasterOutput {
 	}
 
 	public GamsRasterOutput(ModelStat status, RasterSet<LandUseItem> intensityRaster, Map<CropType, CropUsageData> cropUsageData,
-			DoubleMap<Integer, LandCoverType, Double> minimumLandCoverAdditions) {
+			DoubleMap<Integer, LandCoverType, Double> minimumLandCoverAdditions, DoubleMap<Integer, LandCoverType, Double> reservedDeforested) {
 		this(intensityRaster, cropUsageData);
 		this.status = status;
 		this.minimumLandCoverAdditions = minimumLandCoverAdditions;
+		this.reservedDeforested = reservedDeforested;
 	}
 	
 	public ModelStat getStatus() {
@@ -46,4 +48,8 @@ public class GamsRasterOutput {
 	public DoubleMap<Integer, LandCoverType, Double> getMinimumLandCoverAdditions() {
 		return minimumLandCoverAdditions;
 	}
+	
+	public DoubleMap<Integer, LandCoverType, Double> getReservedDeforested() {
+		return reservedDeforested;
+	}
 }
diff --git a/src/ac/ed/lurg/landuse/LandUseItem.java b/src/ac/ed/lurg/landuse/LandUseItem.java
index 07541d8f566be62968d43de8518629314fb25c8b..1e6c5cb692c667277810c0a3c40bc8dbeb0d3d0f 100644
--- a/src/ac/ed/lurg/landuse/LandUseItem.java
+++ b/src/ac/ed/lurg/landuse/LandUseItem.java
@@ -9,6 +9,7 @@ import ac.ed.lurg.types.CropToDouble;
 import ac.ed.lurg.types.CropType;
 import ac.ed.lurg.types.LandCoverType;
 import ac.ed.lurg.utils.Interpolator;
+import ac.ed.lurg.utils.LogWriter;
 import ac.sac.raster.InterpolatingRasterItem;
 
 public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serializable {
@@ -80,7 +81,8 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 	
 	
 	public void setUnavailableArea(double unavailF) {
-		unavailableArea = unavailF*getTotalLandCoverArea();
+		// subtract BARREN from unavailableArea, set to 0 if negative
+		unavailableArea = Math.max(unavailF*getTotalLandCoverArea() - getLandCoverArea(LandCoverType.BARREN), 0.0);
 	}
 	
 	public double getUnavailableArea() {
@@ -194,15 +196,39 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 
         double prevTo = getLandCoverArea(toType);
         double prevFrom = getLandCoverArea(fromType);
-        double availLC = fromType.isProtectable() ? Math.min(prevFrom, unprotectedAreas.get(fromType)) : prevFrom;  // if protected can not go past protected area
         
-        double actuallyChanged = Math.min(availLC, changeReq);
+        double actuallyChanged = Math.min(prevFrom, changeReq);
+        
+        /*
+        if (changeReq - actuallyChanged > 0) {
+        	throw new RuntimeException("Move area shortfall. Should not happen due to GAMS constraint.");
+        }*/
 
         setLandCoverArea(toType, prevTo + actuallyChanged);
         setLandCoverArea(fromType, prevFrom - actuallyChanged);
-
+        
         return changeReq - actuallyChanged;
     }
+    
+	public double moveUnprotectedArea(LandCoverType toType, LandCoverType fromType, double area) {
+		
+        double prevTo = getUnprotectedLandCoverArea(toType);
+        double prevFrom = getUnprotectedLandCoverArea(fromType);
+        double areaMoved;
+       
+        areaMoved = Math.min(area, prevFrom);
+
+        unprotectedAreas.put(toType, prevTo + areaMoved);
+        unprotectedAreas.put(fromType, prevFrom - areaMoved);
+        
+        /*
+        if (area - areaMoved > 0) {
+        	throw new RuntimeException("Move unprotected area shortfall. Should not happen due to GAMS constraint.");
+        }
+        */
+        
+        return area - areaMoved;
+	}
 
 	public double getCropArea(CropType c) {
 		Double d = getLandCoverArea(LandCoverType.CROPLAND) * getCropFraction(c);
@@ -279,7 +305,7 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 	}
 	
 	public double getTotalNatural() {
-		double totalNatural = getLandCoverArea(LandCoverType.OTHER_NATURAL) + getLandCoverArea(LandCoverType.TIMBER_FOREST) + getLandCoverArea(LandCoverType.CARBON_FOREST) + getLandCoverArea(LandCoverType.UNMANAGED_FOREST);
+		double totalNatural = getLandCoverArea(LandCoverType.OTHER_NATURAL) + getLandCoverArea(LandCoverType.UNMANAGED_FOREST);
 		return totalNatural;
 	}
 	
@@ -304,18 +330,25 @@ public class LandUseItem implements InterpolatingRasterItem<LandUseItem>, Serial
 	}
 
 	private double getProtectedandUnavailable() {
-		double totalSuitableLandCover = getTotalLandCoverArea()-getLandCoverArea(LandCoverType.BARREN)-getLandCoverArea(LandCoverType.URBAN);
-		if (totalSuitableLandCover <=0)
-			return 0;
-		double minAndProtectedA = getUnavailableArea() + getProtectedArea() + totalSuitableLandCover * ModelConfig.MIN_NATURAL_RATE;
-		return Math.min(totalSuitableLandCover, minAndProtectedA);
+		double totalSuitableLandCover = getTotalLandCoverArea() - getLandCoverArea(LandCoverType.BARREN) - getLandCoverArea(LandCoverType.URBAN);
+		if (totalSuitableLandCover < 0)
+			throw new RuntimeException("totalSuitableLandCover < 0");
+			//return 0;
+		// Protected area should be at least MIN_NATURAL_RATE
+		double desiredProtectedArea = Math.max(getProtectedArea(), totalSuitableLandCover * ModelConfig.MIN_NATURAL_RATE);
+		// if desired protected is more than suitable then protect all suitable
+		if (desiredProtectedArea + getUnavailableArea() > totalSuitableLandCover) {
+			LogWriter.printlnWarning("Desired protected area exceeds total suitable area");
+		}
+		return Math.min(totalSuitableLandCover, desiredProtectedArea + getUnavailableArea()); 
 	}
 	
 	/** averages protected areas across land cover types */
 	private void updateUnprotectedAreas() {
 		double desiredProtected = getProtectedandUnavailable();
 		double totalNatural = getTotalNatural();
-		double unprotectedNat = Math.max(0, totalNatural - desiredProtected);  // if we are already using more than is protected then the unprotectedArea is 0
+		double unprotectedNat = Math.max(0, totalNatural - desiredProtected); // if desiredProtected more than total Natural then protect all
+		
 		double unprotectedFract = (totalNatural > 0) ? unprotectedNat/totalNatural : 0;
 		
 		for (LandCoverType landType : LandCoverType.values()) {