diff --git a/data/country_codes3.csv b/data/country_codes3.csv
deleted file mode 100644
index 5c5f90384582f1f3895595c64bd3cdadb7e7fc3b..0000000000000000000000000000000000000000
--- a/data/country_codes3.csv
+++ /dev/null
@@ -1 +0,0 @@
-Country,CountryCode,Region,IncomeGroup,numCode
Aruba,ABW,Latin America & Caribbean,High income: nonOECD,533
Afghanistan,AFG,South Asia,Low income,4
Angola,AGO,Sub-Saharan Africa,Upper middle income,24
Albania,ALB,Europe & Central Asia,Upper middle income,8
Andorra,AND,Europe & Central Asia,High income: nonOECD,20
United Arab Emirates,ARE,Middle East & North Africa,High income: nonOECD,784
Argentina,ARG,Latin America & Caribbean,Upper middle income,32
Armenia,ARM,Europe & Central Asia,Lower middle income,51
American Samoa,ASM,East Asia & Pacific,Upper middle income,16
Antigua and Barbuda,ATG,Latin America & Caribbean,High income: nonOECD,28
Australia,AUS,East Asia & Pacific,High income: OECD,36
Austria,AUT,Europe & Central Asia,High income: OECD,40
Azerbaijan,AZE,Europe & Central Asia,Upper middle income,31
Burundi,BDI,Sub-Saharan Africa,Low income,108
Belgium,BEL,Europe & Central Asia,High income: OECD,56
Benin,BEN,Sub-Saharan Africa,Low income,204
Burkina Faso,BFA,Sub-Saharan Africa,Low income,854
Bangladesh,BGD,South Asia,Low income,50
Bulgaria,BGR,Europe & Central Asia,Upper middle income,100
Bahrain,BHR,Middle East & North Africa,High income: nonOECD,48
Bahamas,BHS,Latin America & Caribbean,High income: nonOECD,44
Bosnia and Herzegovina,BIH,Europe & Central Asia,Upper middle income,70
Belarus,BLR,Europe & Central Asia,Upper middle income,112
Belize,BLZ,Latin America & Caribbean,Upper middle income,84
Bermuda,BMU,North America,High income: nonOECD,60
Bolivia (Plurinational State of),BOL,Latin America & Caribbean,Lower middle income,68
Brazil,BRA,Latin America & Caribbean,Upper middle income,76
Barbados,BRB,Latin America & Caribbean,High income: nonOECD,52
Brunei Darussalam,BRN,East Asia & Pacific,High income: nonOECD,96
Bhutan,BTN,South Asia,Lower middle income,64
Botswana,BWA,Sub-Saharan Africa,Upper middle income,72
Central African Republic,CAF,Sub-Saharan Africa,Low income,140
Canada,CAN,North America,High income: OECD,124
Switzerland,CHE,Europe & Central Asia,High income: OECD,756
Chile,CHL,Latin America & Caribbean,High income: OECD,152
China,CHN,East Asia & Pacific,Upper middle income,156
Cote d'Ivoire,CIV,Sub-Saharan Africa,Lower middle income,384
Cameroon,CMR,Sub-Saharan Africa,Lower middle income,120
Democratic Republic of the Congo,COD,Sub-Saharan Africa,Low income,180
Congo,COG,Sub-Saharan Africa,Lower middle income,178
Colombia,COL,Latin America & Caribbean,Upper middle income,170
Comoros,COM,Sub-Saharan Africa,Low income,174
Cabo Verde,CPV,Sub-Saharan Africa,Lower middle income,132
Costa Rica,CRI,Latin America & Caribbean,Upper middle income,188
Cuba,CUB,Latin America & Caribbean,Upper middle income,192
Cayman Islands,CYM,Latin America & Caribbean,High income: nonOECD,136
Cyprus,CYP,Europe & Central Asia,High income: nonOECD,196
Czech Republic,CZE,Europe & Central Asia,High income: OECD,203
Germany,DEU,Europe & Central Asia,High income: OECD,276
Djibouti,DJI,Middle East & North Africa,Lower middle income,262
Dominica,DMA,Latin America & Caribbean,Upper middle income,212
Denmark,DNK,Europe & Central Asia,High income: OECD,208
Dominican Republic,DOM,Latin America & Caribbean,Upper middle income,214
Algeria,DZA,Middle East & North Africa,Upper middle income,12
Ecuador,ECU,Latin America & Caribbean,Upper middle income,218
Egypt,EGY,Middle East & North Africa,Lower middle income,818
Eritrea,ERI,Sub-Saharan Africa,Low income,232
Spain,ESP,Europe & Central Asia,High income: OECD,724
Estonia,EST,Europe & Central Asia,High income: OECD,233
Ethiopia,ETH,Sub-Saharan Africa,Low income,231
Finland,FIN,Europe & Central Asia,High income: OECD,246
Fiji,FJI,East Asia & Pacific,Upper middle income,242
France,FRA,Europe & Central Asia,High income: OECD,250
Faroe Islands,FRO,Europe & Central Asia,High income: nonOECD,234
Micronesia (Federated States of),FSM,East Asia & Pacific,Lower middle income,583
Gabon,GAB,Sub-Saharan Africa,Upper middle income,266
United Kingdom,GBR,Europe & Central Asia,High income: OECD,826
Georgia,GEO,Europe & Central Asia,Lower middle income,268
Ghana,GHA,Sub-Saharan Africa,Lower middle income,288
Guinea,GIN,Sub-Saharan Africa,Low income,324
Gambia,GMB,Sub-Saharan Africa,Low income,270
Guinea-Bissau,GNB,Sub-Saharan Africa,Low income,624
Equatorial Guinea,GNQ,Sub-Saharan Africa,High income: nonOECD,226
Greece,GRC,Europe & Central Asia,High income: OECD,300
Grenada,GRD,Latin America & Caribbean,Upper middle income,308
Greenland,GRL,Europe & Central Asia,High income: nonOECD,304
Guatemala,GTM,Latin America & Caribbean,Lower middle income,320
Guam,GUM,East Asia & Pacific,High income: nonOECD,316
Guyana,GUY,Latin America & Caribbean,Lower middle income,328
Hong Kong,HKG,East Asia & Pacific,High income: nonOECD,344
Honduras,HND,Latin America & Caribbean,Lower middle income,340
Croatia,HRV,Europe & Central Asia,High income: nonOECD,191
Haiti,HTI,Latin America & Caribbean,Low income,332
Hungary,HUN,Europe & Central Asia,Upper middle income,348
Indonesia,IDN,East Asia & Pacific,Lower middle income,360
India,IND,South Asia,Lower middle income,356
Ireland,IRL,Europe & Central Asia,High income: OECD,372
Iran (Islamic Republic of),IRN,Middle East & North Africa,Upper middle income,364
Iraq,IRQ,Middle East & North Africa,Upper middle income,368
Iceland,ISL,Europe & Central Asia,High income: OECD,352
Israel,ISR,Middle East & North Africa,High income: OECD,376
Italy,ITA,Europe & Central Asia,High income: OECD,380
Jamaica,JAM,Latin America & Caribbean,Upper middle income,388
Jordan,JOR,Middle East & North Africa,Upper middle income,400
Japan,JPN,East Asia & Pacific,High income: OECD,392
Kazakhstan,KAZ,Europe & Central Asia,Upper middle income,398
Kenya,KEN,Sub-Saharan Africa,Low income,404
Kyrgyzstan,KGZ,Europe & Central Asia,Low income,417
Cambodia,KHM,East Asia & Pacific,Low income,116
Kiribati,KIR,East Asia & Pacific,Lower middle income,296
Saint Kitts and Nevis,KNA,Latin America & Caribbean,High income: nonOECD,659
Republic of Korea,KOR,East Asia & Pacific,High income: OECD,410
Kosovo,KSV,Europe & Central Asia,Lower middle income,410
Kuwait,KWT,Middle East & North Africa,High income: nonOECD,414
Lao People's Democratic Republic,LAO,East Asia & Pacific,Lower middle income,418
Lebanon,LBN,Middle East & North Africa,Upper middle income,422
Liberia,LBR,Sub-Saharan Africa,Low income,430
Libya,LBY,Middle East & North Africa,Upper middle income,434
Saint Lucia,LCA,Latin America & Caribbean,Upper middle income,662
Liechtenstein,LIE,Europe & Central Asia,High income: nonOECD,438
Sri Lanka,LKA,South Asia,Lower middle income,144
Lesotho,LSO,Sub-Saharan Africa,Lower middle income,426
Lithuania,LTU,Europe & Central Asia,High income: nonOECD,440
Luxembourg,LUX,Europe & Central Asia,High income: OECD,442
Latvia,LVA,Europe & Central Asia,High income: nonOECD,428
Macau,MAC,East Asia & Pacific,High income: nonOECD,446
Morocco,MAR,Middle East & North Africa,Lower middle income,504
Monaco,MCO,Europe & Central Asia,High income: nonOECD,492
Republic of Moldova,MDA,Europe & Central Asia,Lower middle income,498
Madagascar,MDG,Sub-Saharan Africa,Low income,450
Maldives,MDV,South Asia,Upper middle income,462
Mexico,MEX,Latin America & Caribbean,Upper middle income,484
Marshall Islands,MHL,East Asia & Pacific,Upper middle income,584
The former Yugoslav Republic of Macedonia,MKD,Europe & Central Asia,Upper middle income,807
Mali,MLI,Sub-Saharan Africa,Low income,466
Malta,MLT,Middle East & North Africa,High income: nonOECD,470
Myanmar,MMR,East Asia & Pacific,Low income,104
Montenegro,MNE,Europe & Central Asia,Upper middle income,499
Mongolia,MNG,East Asia & Pacific,Lower middle income,496
Northern Mariana Islands,MNP,East Asia & Pacific,High income: nonOECD,580
Mozambique,MOZ,Sub-Saharan Africa,Low income,508
Mauritania,MRT,Sub-Saharan Africa,Lower middle income,478
Mauritius,MUS,Sub-Saharan Africa,Upper middle income,480
Malawi,MWI,Sub-Saharan Africa,Low income,454
Malaysia,MYS,East Asia & Pacific,Upper middle income,458
Namibia,NAM,Sub-Saharan Africa,Upper middle income,516
New Caledonia,NCL,East Asia & Pacific,High income: OECD,540
Niger,NER,Sub-Saharan Africa,Low income,562
Nigeria,NGA,Sub-Saharan Africa,Lower middle income,566
Nicaragua,NIC,Latin America & Caribbean,Lower middle income,558
Netherlands,NLD,Europe & Central Asia,High income: OECD,528
Norway,NOR,Europe & Central Asia,High income: OECD,578
Nepal,NPL,South Asia,Low income,524
New Zealand,NZL,East Asia & Pacific,High income: OECD,554
Oman,OMN,Middle East & North Africa,High income: nonOECD,512
Pakistan,PAK,South Asia,Lower middle income,586
Panama,PAN,Latin America & Caribbean,Upper middle income,591
Peru,PER,Latin America & Caribbean,Upper middle income,604
Philippines,PHL,East Asia & Pacific,Lower middle income,608
Palau,PLW,East Asia & Pacific,Upper middle income,585
Papua New Guinea,PNG,East Asia & Pacific,Lower middle income,598
Poland,POL,Europe & Central Asia,High income: OECD,616
Puerto Rico,PRI,Latin America & Caribbean,High income: nonOECD,630
Democratic People's Republic of Korea,PRK,East Asia & Pacific,Low income,408
Portugal,PRT,Europe & Central Asia,High income: OECD,620
Paraguay,PRY,Latin America & Caribbean,Lower middle income,600
Occupied Palestinian Territory,PSE,Middle East & North Africa,Lower middle income,275
Pacific island small states,PSS,,,275
French Polynesia,PYF,East Asia & Pacific,High income: nonOECD,258
Qatar,QAT,Middle East & North Africa,High income: nonOECD,634
Romania,ROU,Europe & Central Asia,Upper middle income,642
Russian Federation,RUS,Europe & Central Asia,High income: nonOECD,643
Rwanda,RWA,Sub-Saharan Africa,Low income,646
Saudi Arabia,SAU,Middle East & North Africa,High income: nonOECD,682
Sudan,SDN,Sub-Saharan Africa,Lower middle income,729
Senegal,SEN,Sub-Saharan Africa,Lower middle income,686
Singapore,SGP,East Asia & Pacific,High income: nonOECD,702
Solomon Islands,SLB,East Asia & Pacific,Lower middle income,90
Sierra Leone,SLE,Sub-Saharan Africa,Low income,694
El Salvador,SLV,Latin America & Caribbean,Lower middle income,222
San Marino,SMR,Europe & Central Asia,High income: nonOECD,674
Somalia,SOM,Sub-Saharan Africa,Low income,706
Serbia,SRB,Europe & Central Asia,Upper middle income,688
Sao Tome and Principe,STP,Sub-Saharan Africa,Lower middle income,678
Suriname,SUR,Latin America & Caribbean,Upper middle income,740
Slovakia,SVK,Europe & Central Asia,High income: OECD,703
Slovenia,SVN,Europe & Central Asia,High income: OECD,705
Sweden,SWE,Europe & Central Asia,High income: OECD,752
Swaziland,SWZ,Sub-Saharan Africa,Lower middle income,748
Seychelles,SYC,Sub-Saharan Africa,Upper middle income,690
Syrian Arab Republic,SYR,Middle East & North Africa,Lower middle income,760
Turks and Caicos Islands,TCA,Latin America & Caribbean,High income: nonOECD,796
Chad,TCD,Sub-Saharan Africa,Low income,148
Togo,TGO,Sub-Saharan Africa,Low income,768
Thailand,THA,East Asia & Pacific,Upper middle income,764
Tajikistan,TJK,Europe & Central Asia,Low income,762
Turkmenistan,TKM,Europe & Central Asia,Upper middle income,795
Timor-Leste,TLS,East Asia & Pacific,Lower middle income,626
Tonga,TON,East Asia & Pacific,Upper middle income,776
Trinidad and Tobago,TTO,Latin America & Caribbean,High income: nonOECD,780
Tunisia,TUN,Middle East & North Africa,Upper middle income,788
Turkey,TUR,Europe & Central Asia,Upper middle income,792
Tuvalu,TUV,East Asia & Pacific,Upper middle income,798
United Republic of Tanzania,TZA,Sub-Saharan Africa,Low income,834
Uganda,UGA,Sub-Saharan Africa,Low income,800
Ukraine,UKR,Europe & Central Asia,Lower middle income,804
Uruguay,URY,Latin America & Caribbean,High income: nonOECD,858
United States of America,USA,North America,High income: OECD,840
Uzbekistan,UZB,Europe & Central Asia,Lower middle income,860
Saint Vincent and the Grenadines,VCT,Latin America & Caribbean,Upper middle income,670
Venezuela (Bolivarian Republic of),VEN,Latin America & Caribbean,Upper middle income,862
United States Virgin Islands,VIR,Latin America & Caribbean,High income: nonOECD,850
Viet Nam,VNM,East Asia & Pacific,Lower middle income,704
Vanuatu,VUT,East Asia & Pacific,Lower middle income,548
Samoa,WSM,East Asia & Pacific,Lower middle income,882
Yemen,YEM,Middle East & North Africa,Lower middle income,887
South Africa,ZAF,Sub-Saharan Africa,Upper middle income,710
Zambia,ZMB,Sub-Saharan Africa,Lower middle income,894
Zimbabwe,ZWE,Sub-Saharan Africa,Low income,716
Czechoslovakia,CZEF,Europe & Central Asia,High income: OECD,203
Ethiopia PDR,ETHF,Sub-Saharan Africa,Low income,231
Sudan (former),SDNF,Sub-Saharan Africa,Lower middle income,729
Western Sahara,WSAF,Sub-Saharan Africa,Lower middle income,876
Yugoslav SFR,YUGF,Europe & Central Asia,High income: OECD,887
Belgium-Luxembourg,BELF,Europe & Central Asia,High income: OECD,56
Serbia and Montenegro,SRBF,Europe & Central Asia,Upper middle income,688
Falkland Islands (Malvinas),FALF,Latin America & Caribbean,High income: nonOECD,231
South Sudan,SSUF,Sub-Saharan Africa,Lower middle income,728
USSR,USSR,Europe & Central Asia,High income: nonOECD,999
\ No newline at end of file
diff --git a/src/ac/ed/lurg/InternationalMarket.java b/src/ac/ed/lurg/InternationalMarket.java
index de86cf01f466c747989be0dd55f5a3db03c6d693..8e5a01a5c9c1455c5db2103dfd3a1003e7aebdb9 100644
--- a/src/ac/ed/lurg/InternationalMarket.java
+++ b/src/ac/ed/lurg/InternationalMarket.java
@@ -7,7 +7,7 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 
-import ac.ed.lurg.country.CountryAgent;
+import ac.ed.lurg.country.AbstractCountryAgent;
 import ac.ed.lurg.country.GlobalPrice;
 import ac.ed.lurg.country.StockReader;
 import ac.ed.lurg.landuse.CropUsageData;
@@ -47,10 +47,10 @@ public class InternationalMarket {
 		return initialStockLevels;
 	}
 
-	void determineInternationalTrade(Collection<CountryAgent> countryAgents, double gen2EcDDemand, Timestep timestep) {
+	void determineInternationalTrade(Collection<AbstractCountryAgent> countryAgents, double gen2EcDDemand, Timestep timestep) {
 		CropToDoubleMap totalImportCommodities = new CropToDoubleMap();
 		CropToDoubleMap totalExportCommodities = new CropToDoubleMap();
-		for (CountryAgent ca : countryAgents) {
+		for (AbstractCountryAgent ca : countryAgents) {
 
 			// Get values for world input costs
 			Map<CropType, CropUsageData> cropUsage = ca.getCropUsageData();
diff --git a/src/ac/ed/lurg/ModelMain.java b/src/ac/ed/lurg/ModelMain.java
index 0e3570057bf695d4b9e1bb9565f8515257617bf4..5cc4effdea3d25270f39dfc2ea7a9af4cc1f8f16 100644
--- a/src/ac/ed/lurg/ModelMain.java
+++ b/src/ac/ed/lurg/ModelMain.java
@@ -8,15 +8,13 @@ import java.io.FileWriter;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
-import java.nio.file.FileSystems;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
 import java.util.Collection;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import ac.ed.lurg.country.AbstractCountryAgent;
 import ac.ed.lurg.country.AnimalRateManager;
 import ac.ed.lurg.country.CompositeCountry;
 import ac.ed.lurg.country.CompositeCountryManager;
@@ -63,7 +61,7 @@ import ac.sac.raster.RasterSet;
 
 public class ModelMain {
 
-	private Collection<CountryAgent> countryAgents;
+	private Collection<AbstractCountryAgent> countryAgents;
 	private CountryBoundaryRaster countryBoundaryRaster;
 	private AbstractDemandManager demandManager;
 	private SubsidyRateManager subsidyRateManager;
@@ -135,44 +133,38 @@ public class ModelMain {
 		double gen2EcDDemand = demandManager.getSecondGenBioenergyDemand(ModelConfig.IS_CALIBRATION_RUN ? new Timestep(1) : timestep);
 		double gen2Increase = (gen2EcDDemand>previousGen2EcDDemand) ? gen2EcDDemand - previousGen2EcDDemand : 0.0;
 
-		for (CountryAgent ca : countryAgents) {
-
-			LogWriter.println("Country " + ca.getCountry());
-			Collection<RasterKey> countryKeys = countryBoundaryRaster.getKeysFor(ca.getCountry());
-			YieldRaster countryYieldSurfaces = yieldSurfaces.createSubsetForKeys(countryKeys);
-			RasterSet<IrrigationItem> irrigData = currentIrrigationData.createSubsetForKeys(countryKeys);
+		for (AbstractCountryAgent aca : countryAgents) {
+			LogWriter.println("Country " + aca.getCountry());
 			
-			// do the optimization
-			try {
-				ca.determineProduction(timestep, countryYieldSurfaces, irrigData, internationalMarket.getWorldPrices(), gen2Increase);
-			} catch (Exception e) {
-				LogWriter.printlnError("Exception processing " + ca.getCountry() + " will continue with other countries");
-				LogWriter.print(e);
-				continue;
-			}
-
-			// some hacky code for debug purposes that keeps each gams gdx file
-			// for one country
-			if (ModelConfig.GAMS_COUNTRY_TO_SAVE != null && ca.getCountry().getName().equals(ModelConfig.GAMS_COUNTRY_TO_SAVE)) {
+			if (aca instanceof CountryAgent) {
+				CountryAgent ca = (CountryAgent)aca;
+			
+				Collection<RasterKey> countryKeys = countryBoundaryRaster.getKeysFor(ca.getCountry());
+				YieldRaster countryYieldSurfaces = yieldSurfaces.createSubsetForKeys(countryKeys);
+				RasterSet<IrrigationItem> irrigData = currentIrrigationData.createSubsetForKeys(countryKeys);
+				
+				// do the optimization
 				try {
-					Files.copy(
-							FileSystems.getDefault().getPath(ModelConfig.TEMP_DIR + File.separator + "_gams_java_gdb1.gdx"),
-							FileSystems.getDefault().getPath(ModelConfig.TEMP_DIR + File.separator + ModelConfig.GAMS_COUNTRY_TO_SAVE + timestep.getYear() + ".gdx"),
-							StandardCopyOption.REPLACE_EXISTING);
-				} catch (IOException e) {
+					ca.determineProduction(timestep, countryYieldSurfaces, irrigData, internationalMarket.getWorldPrices(), gen2Increase);
+				} catch (Exception e) {
+					LogWriter.printlnError("Exception processing " + ca.getCountry() + " will continue with other countries");
 					LogWriter.print(e);
+					continue;
 				}
+	
+				// update global rasters
+				globalLandUseRaster.putAll(ca.getLandUses());
+	
+				// if first timestep and calibration get the clustering info, which
+				// doesn't change through time
+				if (ModelConfig.GENERATE_NEW_YIELD_CLUSTERS && timestep.isInitialTimestep())
+					clusterIdRaster.putAll(ca.getYieldClusters());
+				
+				if (ca.getCountry().getName().equals("United Kingdom"))	 writeUKLandCoverFile(timestep, ca);	
+			}
+			else {
+				LogWriter.print("Not a CountryAgent class agent: " + aca);
 			}
-
-			// update global rasters
-			globalLandUseRaster.putAll(ca.getLandUses());
-
-			// if first timestep and calibration get the clustering info, which
-			// doesn't change through time
-			if (ModelConfig.GENERATE_NEW_YIELD_CLUSTERS && timestep.isInitialTimestep())
-				clusterIdRaster.putAll(ca.getYieldClusters());
-			
-			if (ca.getCountry().getName().equals("United Kingdom"))	 writeUKLandCoverFile(timestep, ca);			
 		}
 		
 		internationalMarket.determineInternationalTrade(countryAgents, gen2EcDDemand, timestep);
@@ -249,7 +241,7 @@ public class ModelMain {
 					stockChange = priceQuantity.getStockChange();
 				}
 				
-				for (CountryAgent ca : countryAgents) {
+				for (AbstractCountryAgent ca : countryAgents) {
 					Map<CropType, CropUsageData> allCropUsage = ca.getCropUsageData();
 					CropUsageData cropUsage = allCropUsage.get(crop);
 					if (cropUsage != null) {
@@ -298,7 +290,7 @@ public class ModelMain {
 			for (CommodityType comm : CommodityType.getAllItems()) {
 				double demandAmount = 0;
 
-				for (CountryAgent country : countryAgents) {
+				for (AbstractCountryAgent country : countryAgents) {
 					Double d = country.getCurrentProjectedDemand().get(comm);
 					if (d != null) {
 						demandAmount += d.doubleValue();
@@ -325,7 +317,7 @@ public class ModelMain {
 			BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.DOMESTIC_OUTPUT_FILE, sbHeadings.toString());
 
 			for (CropType crop : CropType.getAllItems()) {
-				for (CountryAgent country : countryAgents) {
+				for (AbstractCountryAgent country : countryAgents) {
 					
 					Map<CropType, CropUsageData> cropUsageAllCrops = country.getCropUsageData();
 					CropUsageData cropUsage = cropUsageAllCrops.get(crop);
@@ -404,7 +396,7 @@ public class ModelMain {
 			StringBuffer sbHeadings = new StringBuffer("Year, Country, Commodity, Demand");
 			BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.COUNTRY_DEMAND_FILE, sbHeadings.toString());
 
-			for (CountryAgent country : countryAgents) {
+			for (AbstractCountryAgent country : countryAgents) {
 				for (CommodityType commodity : CommodityType.getAllItems()) {
 
 					double  demand =  country.getCurrentProjectedDemand().get(commodity);
@@ -429,7 +421,7 @@ public class ModelMain {
 			StringBuffer sbHeadings = new StringBuffer("Year,Country,FAOItem,Heads(M)");
 			BufferedWriter outputFile = getFileWriter(timestep, ModelConfig.ANIMAL_NUMBERS_OUTPUT_FILE, sbHeadings.toString());
 		
-			for (CountryAgent country : countryAgents) {
+			for (AbstractCountryAgent country : countryAgents) {
 				Map<CropType, CropUsageData> cropUsageAllCrops = country.getCropUsageData();
 				for (CropType crop : CropType.getMeatTypes()) {
 					double prod = cropUsageAllCrops.get(crop).getProduction();
@@ -552,8 +544,8 @@ public class ModelMain {
 		return countryBoundaries;
 	}
 
-	public Collection<CountryAgent> createCountryAgents(Collection<CompositeCountry> countryGrouping) {
-		Collection<CountryAgent> countryAgents = new HashSet<CountryAgent>();
+	public Collection<AbstractCountryAgent> createCountryAgents(Collection<CompositeCountry> countryGrouping) {
+		Collection<AbstractCountryAgent> countryAgents = new HashSet<AbstractCountryAgent>();
 		Map<CompositeCountry, Map<CropType, CropUsageData>> cropUsageDataMap = new CropUsageReader(compositeCountryManager).getCommodityData();
 		RasterSet<LandUseItem> initLU = getInitialLandUse();
 
diff --git a/src/ac/ed/lurg/country/AbstractCountryAgent.java b/src/ac/ed/lurg/country/AbstractCountryAgent.java
new file mode 100644
index 0000000000000000000000000000000000000000..0f0b1b9fd627cacfde32883a34ec15928452cfc5
--- /dev/null
+++ b/src/ac/ed/lurg/country/AbstractCountryAgent.java
@@ -0,0 +1,58 @@
+package ac.ed.lurg.country;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import ac.ed.lurg.Timestep;
+import ac.ed.lurg.demand.AbstractDemandManager;
+import ac.ed.lurg.landuse.CropUsageData;
+import ac.ed.lurg.types.CommodityType;
+import ac.ed.lurg.types.CropType;
+
+public abstract class AbstractCountryAgent {
+
+	protected AbstractDemandManager demandManager;
+	protected CompositeCountry country;
+	protected Map<CropType, Double> tradeBarriers;
+	private Map<CommodityType, Double> currentProjectedDemand;
+	private Map<CropType, CountryPrice> currentCountryPrices;
+
+	public AbstractCountryAgent(AbstractDemandManager demandManager,CompositeCountry country, Map<CropType, Double> tradeBarriers) {
+
+		this.demandManager = demandManager;
+		this.country = country;
+		this.tradeBarriers = tradeBarriers;
+	}
+
+	public CompositeCountry getCountry() {
+		return country;
+	}
+	
+	Map<CropType, CountryPrice> calculateCountryPrices(Map<CropType, GlobalPrice> worldPrices, Timestep timestep){
+		Map<CropType, CountryPrice> countryPrices = new HashMap <CropType, CountryPrice>();
+
+		for (CropType c : CropType.getImportedTypes()) {
+			GlobalPrice worldPrice = worldPrices.get(c);
+			CountryPrice prices = new CountryPrice(worldPrice.getCountryImportPrice(tradeBarriers.get(c), timestep), worldPrice.getExportPrice());
+			countryPrices.put(c, prices);
+		}
+
+		currentCountryPrices = countryPrices;
+		return currentCountryPrices;
+	}
+	
+	protected Map<CommodityType, Double> calculateDemand(Timestep timestep) {
+		currentProjectedDemand = demandManager.getDemand(country, timestep.getYear());
+		return currentProjectedDemand;
+	}
+	
+	public Map<CommodityType, Double> getCurrentProjectedDemand() {
+		return currentProjectedDemand;
+	}
+	
+	public Map<CropType, CountryPrice> getCurrentCountryPrices() {
+		return currentCountryPrices;
+	}
+	
+	abstract public Map<CropType, CropUsageData> getCropUsageData();
+}
diff --git a/src/ac/ed/lurg/country/CountryAgent.java b/src/ac/ed/lurg/country/CountryAgent.java
index f2c40d678e2a79b24d6c30c7c2065c9cafd22839..8f982a351f6fcf41cc51fa186936ba8be108f060 100644
--- a/src/ac/ed/lurg/country/CountryAgent.java
+++ b/src/ac/ed/lurg/country/CountryAgent.java
@@ -1,5 +1,10 @@
 package ac.ed.lurg.country;
 
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.StandardCopyOption;
 import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -30,36 +35,27 @@ import ac.sac.raster.IntegerRasterItem;
 import ac.sac.raster.RasterKey;
 import ac.sac.raster.RasterSet;
 
-public class CountryAgent {
-
-	private AbstractDemandManager demandManager;
-	private CompositeCountry country;
+public class CountryAgent extends AbstractCountryAgent {
 
 	private GamsRasterOutput previousGamsRasterOutput;
 	private Timestep currentTimestep;
-	private Map<CommodityType, Double> currentProjectedDemand;
-	private Map<CropType, CountryPrice> currentCountryPrices;
-	private Map<CropType, Double> tradeBarriers;
 	private RasterSet<IntegerRasterItem> yieldClusters;
 	private double animalFeedFromOtherSources;
 	private Map<CropType, Double> subsidyRates;
+	private boolean saveGamsGdxFiles;
 
 	public CountryAgent(AbstractDemandManager demandManager,CompositeCountry country, RasterSet<LandUseItem> cropAreaRaster,
 			Map<CropType, CropUsageData> cropUsageData, Map<CropType, Double> tradeBarriers, RasterSet<IntegerRasterItem> yieldClusters,
 			Map<CropType, Double> subsidyRates) {
 
-		this.demandManager = demandManager;
-		this.country = country;
-		this.tradeBarriers = tradeBarriers;
+		super(demandManager, country, tradeBarriers);
 		this.yieldClusters = yieldClusters;
 		this.subsidyRates = subsidyRates;
 
 		GamsRasterOutput initialData = new GamsRasterOutput(cropAreaRaster, cropUsageData);
 		previousGamsRasterOutput = initialData;
-	}
-
-	public CompositeCountry getCountry() {
-		return country;
+		
+		saveGamsGdxFiles = (ModelConfig.GAMS_COUNTRY_TO_SAVE != null && country.getName().equals(ModelConfig.GAMS_COUNTRY_TO_SAVE));
 	}
 
 	public RasterSet<IntegerRasterItem> getYieldClusters() {
@@ -110,15 +106,15 @@ public class CountryAgent {
 		currentTimestep = timestep;
 
 		// get projected demand
-		currentProjectedDemand = demandManager.getDemand(country, timestep.getYear());
+		Map<CommodityType, Double> projectedDemand = calculateDemand(timestep);
 		if (currentTimestep.isInitialTimestep()) {
-			double totalAnimalProductDemand = currentProjectedDemand.get(CommodityType.MONOGASTRICS) + currentProjectedDemand.get(CommodityType.RUMINANTS);
+			double totalAnimalProductDemand = projectedDemand.get(CommodityType.MONOGASTRICS) + projectedDemand.get(CommodityType.RUMINANTS);
 			animalFeedFromOtherSources = totalAnimalProductDemand * ModelConfig.ANIMAL_FEED_FROM_OTHER_SOURCES_RATE;
 		}
 			
-		currentCountryPrices = calculateCountryPrices(worldPrices);
+		calculateCountryPrices(worldPrices, currentTimestep);
 			
-		if (currentProjectedDemand.size() == 0) {
+		if (projectedDemand.size() == 0) {
 			LogWriter.printlnError("No demand for country " + country + " so skipping it");
 		}
 		else if (countryYieldSurfaces.size() == 0 ) {
@@ -142,12 +138,26 @@ public class CountryAgent {
 				updateNetImportsFromProdAndDemand(countryInput.getProjectedDemand(), countryInput.getMinCerealFraction(), result.getCropUsageData());
 			}
 			
+			if (saveGamsGdxFiles) saveGDXFile();
+			
 			previousGamsRasterOutput = result;
 			return result;
 		}
 
 		throw new RuntimeException("Skipping optimisation of country " + country);
 	}
+	
+	private void saveGDXFile() {
+		// some hacky code for debug purposes that keeps each gams gdx file
+		try {
+			Files.copy(
+					FileSystems.getDefault().getPath(ModelConfig.TEMP_DIR + File.separator + "_gams_java_gdb1.gdx"),
+					FileSystems.getDefault().getPath(ModelConfig.TEMP_DIR + File.separator + ModelConfig.GAMS_COUNTRY_TO_SAVE + currentTimestep.getYear() + ".gdx"),
+					StandardCopyOption.REPLACE_EXISTING);
+		} catch (IOException e) {
+			LogWriter.print(e);
+		}
+	}
 
 	private void updateNetImportsFromProdAndDemand(Map<CommodityType, Double> demands, Map<CropType, Double> minCerealFracts, Map<CropType, CropUsageData> cropUsages) {
 
@@ -209,14 +219,6 @@ public class CountryAgent {
 		} 
 	}
 
-	public Map<CommodityType, Double> getCurrentProjectedDemand() {
-		return currentProjectedDemand;
-	}
-	
-	public Map<CropType, CountryPrice> getCurrentCountryPrices() {
-		return currentCountryPrices;
-	}
-
 	private GamsRasterInput getGamsRasterInput(RasterSet<IrrigationItem> irrigData, YieldRaster countryYieldSurfaces, double gen2EcIncrease) {
 		double allowedImportChange;
 
@@ -269,7 +271,7 @@ public class CountryAgent {
 
 		Map<CropType, Double> minCerealFract = getMinCerealFraction(currentTimestep);
 
-		GamsCountryInput countryLevelInputs = new GamsCountryInput(country, currentProjectedDemand, currentCountryPrices, importConstraints, 
+		GamsCountryInput countryLevelInputs = new GamsCountryInput(country, getCurrentProjectedDemand(), getCurrentCountryPrices(), importConstraints, 
 				previousGamsRasterOutput.getCropUsageData(), minCerealFract, animalFeedFromOtherSources, subsidyRates);	
 		GamsRasterInput input = new GamsRasterInput(currentTimestep, countryYieldSurfaces, previousGamsRasterOutput.getLandUses(), irrigData, countryLevelInputs);
 
@@ -287,18 +289,6 @@ public class CountryAgent {
 		return minCerealFraction;
 	}
 
-	private Map<CropType, CountryPrice> calculateCountryPrices(Map<CropType, GlobalPrice> worldPrices){
-		Map<CropType, CountryPrice> countryPrices = new HashMap <CropType, CountryPrice>();
-
-		for (CropType c : CropType.getImportedTypes()) {
-			GlobalPrice worldPrice = worldPrices.get(c);
-			CountryPrice prices = new CountryPrice(worldPrice.getCountryImportPrice(tradeBarriers.get(c), currentTimestep), worldPrice.getExportPrice());
-			countryPrices.put(c, prices);
-		}
-
-		return countryPrices;
-	}
-
 	public RasterSet<LandUseItem> getLandUses() {
 		return previousGamsRasterOutput.getLandUses();
 	}
diff --git a/src/ac/ed/lurg/country/CraftyCountryAgent.java b/src/ac/ed/lurg/country/CraftyCountryAgent.java
new file mode 100644
index 0000000000000000000000000000000000000000..f07b8882993a9f6afe6bbc348a2ece378d181190
--- /dev/null
+++ b/src/ac/ed/lurg/country/CraftyCountryAgent.java
@@ -0,0 +1,24 @@
+package ac.ed.lurg.country;
+
+import java.util.Map;
+
+import ac.ed.lurg.demand.AbstractDemandManager;
+import ac.ed.lurg.landuse.CropUsageData;
+import ac.ed.lurg.types.CropType;
+
+/** 
+ * Country agent that is interface over data transferred to and from CRAFTY.
+ * 
+ * Data sent: initially country prices for each crop
+ * Data received: production quantities for each crop, think we also need to know feed usage (or production net of feed use).
+ * 
+ * */
+public class CraftyCountryAgent extends AbstractCountryAgent {
+	public CraftyCountryAgent(AbstractDemandManager demandManager,CompositeCountry country, Map<CropType, Double> tradeBarriers) {
+		super(demandManager, country, tradeBarriers);
+	}
+
+	public Map<CropType, CropUsageData> getCropUsageData() {
+		return null;
+	}
+}