// 备品智能化项目 自动分配/自动排队逻辑
public without sharing class RentalFixtureSetAssignAndQueueWebService implements Queueable {

	List<String> tempIdList  = new List<String>();

	public RentalFixtureSetAssignAndQueueWebService(List<String> records) {
		tempIdList = records;
	}

	public void execute(QueueableContext qc) {
		if (!tempIdList.isEmpty()) { 
			setAssignAndQueue(tempIdList);
		}
	}

	public static void setAssignAndQueue(List<String> tempIdList) {
		System.debug('tempIdList============================================' + tempIdList);
    	Date today = Date.today();
    	String dateToday = String.valueOf(today);

    	// 查找未取消的一览明细
		List<Rental_Apply_Equipment_Set_Detail__c> raesdListFirst = [
				SELECT Id, Rental_Apply_Equipment_Set__c, EquipmentSet_Detail_Status_Status__c 
				FROM Rental_Apply_Equipment_Set_Detail__c
				WHERE Cancel_Select__c = false
				AND Rental_Apply__c IN: tempIdList
				AND Rental_Apply__r.Cross_Region_Assign__c = null
				AND Rental_Apply_Equipment_Set__r.RAES_Status__c = '待分配'];

		// 存在非待分配明细的一览，不作为自动分配/排队对象
		Set<String> notUseIds = new Set<String>();
		for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdListFirst) {
			if (raesd.EquipmentSet_Detail_Status_Status__c != '待分配') {
				notUseIds.add(raesd.Rental_Apply_Equipment_Set__c);
			}
		}

		// 查找未取消的一览明细
		List<Rental_Apply_Equipment_Set_Detail__c> raesdList1 = [
				SELECT Id, Is_Body__c, Internal_asset_location__c, Salesdepartment__c, Equipment_Type_F__c, Rental_Apply_Equipment_Set__c, 
						FSD_Is_OneToOne__c, FSD_Fixture_Model_No__c, Product_category_F__c, Rental_Apply_Equipment_Set__r.RequestNoJoinStr2__c,
						FSD_Id__c, IndexFromUniqueKey__c, Rental_Apply__r.Person_In_Charge__r.Profile.Name, Rental_Apply__r.demo_purpose2__c,
						Rental_Apply__r.OPD_OrderNum__c, Rental_Apply__r.OPD_AdjustmentOrderNum_Flag__c, Rental_Apply__r.Demo_purpose1__c,
						Rental_Apply_Equipment_Set__r.Fixture_Set__r.Product_Type__c, Rental_Apply__r.Internal_asset_location_F__c, Select_Time__c,
						Rental_Apply__r.Product_category__c, Rental_Apply__r.Salesdepartment__c, Fixture_Model_No__c, Rental_Apply__c, FSD_OneToOneAccessory_Cnt__c,
						Rental_Apply__r.Loaner_centre_mail_address__c, Rental_Apply_Equipment_Set__r.Rental_Start_Date__c, Rental_Apply_Equipment_Set__r.Rental_End_Date__c,
						Rental_Apply__r.Asset_loaner_start_day__c, Rental_Apply__r.Hope_Lonaer_date_Num__c, Rental_Apply__r.Asset_loaner_closed_day__c,
						Rental_Apply__r.Request_approval_time__c, Rental_Apply__r.Request_shipping_day__c, Rental_Apply__r.EquipmentGuaranteeFlg__c,EquipmentSet_Detail_Status_Status__c,// 20231223 智能化 ljh add Rental_Apply__r.EquipmentGuaranteeFlg__c
						Queue_Time_F__c,Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c, Rental_Apply__r.Last_Month_Untreated__c
				FROM Rental_Apply_Equipment_Set_Detail__c
				WHERE Cancel_Select__c = false
				AND Rental_Apply__c IN: tempIdList
				AND Rental_Apply_Equipment_Set__c NOT IN: notUseIds
				AND Rental_Apply__r.Cross_Region_Assign__c = null
				AND Rental_Apply_Equipment_Set__r.RAES_Status__c = '待分配'
				ORDER BY Rental_Apply__c, Rental_Apply_Equipment_Set__c, Id];

		// 为了后续的处理方便，此处以申请单为单位进行处理
		Map<String, Map<String, List<Rental_Apply_Equipment_Set_Detail__c>>> raAndraesMap = new Map<String, Map<String, List<Rental_Apply_Equipment_Set_Detail__c>>>();
		for (Rental_Apply_Equipment_Set_Detail__c raesd : raesdList1) {
			if (raAndraesMap.isEmpty() || !raAndraesMap.containsKey(raesd.Rental_Apply__c)) {
				Map<String, List<Rental_Apply_Equipment_Set_Detail__c>> raesdMap = new Map<String, List<Rental_Apply_Equipment_Set_Detail__c>>();
				List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList = new List<Rental_Apply_Equipment_Set_Detail__c>();
				raesdTempList.add(raesd);
				raesdMap.put(raesd.Rental_Apply_Equipment_Set__c, raesdTempList);
				raAndraesMap.put(raesd.Rental_Apply__c, raesdMap);
			} else {
				Map<String, List<Rental_Apply_Equipment_Set_Detail__c>> raesdMap = raAndraesMap.get(raesd.Rental_Apply__c);
				if (raesdMap.isEmpty() || !raesdMap.containsKey(raesd.Rental_Apply_Equipment_Set__c)) {
					List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList = new List<Rental_Apply_Equipment_Set_Detail__c>();
					raesdTempList.add(raesd);
					raesdMap.put(raesd.Rental_Apply_Equipment_Set__c, raesdTempList);
				} else {
					List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList = raesdMap.get(raesd.Rental_Apply_Equipment_Set__c);
					raesdTempList.add(raesd);
					raesdMap.put(raesd.Rental_Apply_Equipment_Set__c, raesdTempList);
				}
				raAndraesMap.put(raesd.Rental_Apply__c, raesdMap);
			}
		}

		// 申请单单位
		for (String raId : raAndraesMap.keySet()) {
			// 备品存放地
			String cunFanfDi = null;
			// 产品分类(GI/SP)
			String productCategory = null;
			// 默认排队的条件组合
			RentalFixtureSetAssignController.KeyObj objSelect = new RentalFixtureSetAssignController.KeyObj();
			//别本部
			List<String> departmentsList = new List<String>();
			//别备品分类
			List<String> equipmentsList = new List<String>();
			// 一对一备品配套明细型号
			Map<String, List<List<Rental_Apply_Equipment_Set_Detail__c>>> otoModelMap = new Map<String, List<List<Rental_Apply_Equipment_Set_Detail__c>>>();
			// 非一对一备品配套明细型号
			Map<String, List<List<Rental_Apply_Equipment_Set_Detail__c>>> noOtoModelMap = new Map<String, List<List<Rental_Apply_Equipment_Set_Detail__c>>>();
			// 保证分配顺序 一对一主体用
        	Map<String, List<Asset>> autoSelectMap = new Map<String, List<Asset>>();
        	// 保证分配顺序 非一对一主体用
        	Map<String, List<Asset>> autoSelectMap1 = new Map<String, List<Asset>>();

			Boolean isFirst = true;
			Rental_Apply__c raObj = new Rental_Apply__c();
			List<Rental_Apply_Equipment_Set__c> raesUpdList = new List<Rental_Apply_Equipment_Set__c>();
			// 参与自动排队的主体一览明细
			List<Rental_Apply_Equipment_Set_Detail__c> queueList = new List<Rental_Apply_Equipment_Set_Detail__c>();
			// 可以暂定分配的主体一览明细
			List<Rental_Apply_Equipment_Set_Detail__c> updAssignList = new List<Rental_Apply_Equipment_Set_Detail__c>();
			// 参与自动分配的附属品一览明细
			List<Rental_Apply_Equipment_Set_Detail__c> needAssignAccessoryList = new List<Rental_Apply_Equipment_Set_Detail__c>();
			Map<String, List<Rental_Apply_Equipment_Set_Detail__c>> raesdMap = raAndraesMap.get(raId);
			// 申请一览单位
			for (String raesId : raesdMap.keySet()) {
				List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList = raesdMap.get(raesId);
				// 设值备品预计出货日
				Rental_Apply_Equipment_Set__c raes = new Rental_Apply_Equipment_Set__c();
				raes.Id = raesId;
				Integer addNum = 0;
				if (raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '试用（无询价）' 
					|| raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '试用（有询价）'
					|| raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '新产品评价'
					|| raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '协议借用') {
					addNum = raesdTempList[0].Rental_Apply__r.Hope_Lonaer_date_Num__c == null ? 0 : Integer.valueOf(raesdTempList[0].Rental_Apply__r.Hope_Lonaer_date_Num__c);
				} else if (raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '一般用户'
							|| raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '保修用户'
							|| raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '市场多年保修'
							|| raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '再修理'
							|| raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '索赔QIS'
							|| raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '已购待货'
							|| raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '故障排查') {
					addNum = 30;
				} else if (raesdTempList[0].Rental_Apply__r.demo_purpose2__c == '学会展会') {
					addNum = 5;
				}
				// 一览的更新
				raes.Rental_Start_Date__c = today;
				raes.Rental_End_Date__c = today.addDays(addNum);
				raesUpdList.add(raes);

				if (isFirst) {
					//申请单的更新
					raObj.Id = raId;
					raObj.Asset_loaner_start_day__c = today;
					raObj.Asset_loaner_closed_day__c = today.addDays(addNum);
					isFirst = false;

					// 根据备品中心的邮箱地址来判断备品存放地
					cunFanfDi = getInternalAssetlocation(raesdTempList[0].Rental_Apply__r.Loaner_centre_mail_address__c);
					// 产品分类(GI/SP)
					productCategory = raesdTempList[0].Rental_Apply__r.Product_category__c;

					// 获取默认排队的条件组合
					objSelect = getSearchCriteria(raesdTempList[0]);
					departmentsList.addAll(objSelect.salesdepartmentList);
					equipmentsList.addAll(objSelect.equipmentList);
				}

				// 主体明细在第一条，判断第一条是否是主体，如果不是主体，则代表整个配套中没有主体
				if (raesdTempList[0].Is_Body__c) {
					// Fixture_OneToOne_Link__c, 当配套的Mst定义成 一对一 的时候
					if (raesdTempList[0].FSD_OneToOneAccessory_Cnt__c > 0) {
						// 主体一对一备品配套明细型号
						if (!otoModelMap.isEmpty() && otoModelMap.containsKey(raesdTempList[0].FSD_Fixture_Model_No__c)) {
							List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsList = otoModelMap.get(raesdTempList[0].FSD_Fixture_Model_No__c);
							raesdsList.add(raesdTempList);
							otoModelMap.put(raesdTempList[0].FSD_Fixture_Model_No__c, raesdsList);
						} else {
							List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsList = new List<List<Rental_Apply_Equipment_Set_Detail__c>>();
							raesdsList.add(raesdTempList);
							otoModelMap.put(raesdTempList[0].FSD_Fixture_Model_No__c, raesdsList);
						}
					} else {
						// 主体非一对一备品配套明细型号
						if (!noOtoModelMap.isEmpty() && noOtoModelMap.containsKey(raesdTempList[0].FSD_Fixture_Model_No__c)) {
							List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsList = noOtoModelMap.get(raesdTempList[0].FSD_Fixture_Model_No__c);
							raesdsList.add(raesdTempList);
							noOtoModelMap.put(raesdTempList[0].FSD_Fixture_Model_No__c, raesdsList);
						} else {
							List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsList = new List<List<Rental_Apply_Equipment_Set_Detail__c>>();
							raesdsList.add(raesdTempList);
							noOtoModelMap.put(raesdTempList[0].FSD_Fixture_Model_No__c, raesdsList);
						}
					}
					autoSelectMap.put(raesdTempList[0].FSD_Fixture_Model_No__c, new List<Asset>());
					autoSelectMap1.put(raesdTempList[0].FSD_Fixture_Model_No__c, new List<Asset>());
				} else {
					// 附属品的配套，直接做附属品分配
					for (Rental_Apply_Equipment_Set_Detail__c raesdAccessory: raesdTempList) {
						needAssignAccessoryList.add(raesdAccessory);
					}
				}
			}

			//更新备品预计出库日
			update raesUpdList;
			update raObj;

			System.debug('otoModelMap=========================================' + otoModelMap);
			System.debug('noOtoModelMap=========================================' + noOtoModelMap);

			// 如果存在一对一的，并且一对一的部分配套有一对一保有，部分没一对一保有，为了防止部分没一对一保有分配时，又使用了已经被使用的一对一保有，追加变量来控制
			Set<String> usedAssetIds = new Set<String>();

			// 主体的自动分配
			// 先查找一对一的主体备品配套
			if (!otoModelMap.isEmpty()) {
				Set<String> moset = otoModelMap.keySet();
				String soql = makeSoql(true, cunFanfDi, productCategory, moset, departmentsList, equipmentsList, dateToday);
				List<Asset> aSetCheck = Database.query(soql);

				if (!aSetCheck.isEmpty() || Test.isRunningTest()) { // 借用机会可视化 zyh 覆盖率提升runningTest
					for (Asset aSet : aSetCheck) {
						List<Asset> autoSelectList = autoSelectMap.get(aSet.Fixture_Model_No_F__c);
						autoSelectList.add(aSet);
						autoSelectMap.put(aSet.Fixture_Model_No_F__c, autoSelectList);
					}

					// 自动分配
					// Fixture_Model_No_F__c 的 Loop (会有 Fixture_Model_No_F__c 一样的借出明细)
					for (String modelNo : otoModelMap.keySet()) {
						List<Asset> autoSelectList = autoSelectMap.get(modelNo);
						List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsTempList = otoModelMap.get(modelNo);
						System.debug('modelNo========================' + modelNo);
						System.debug('autoSelectList========================' + autoSelectList);
						System.debug('raesdsTempList========================' + raesdsTempList);

						// 对应的型号有可分配的保有设备的情况下
						if (autoSelectList.size() > 0) {
							// Rental_Apply_Equipment_Set_Detail__c 的 Loop
							for (Integer autoIdx = 0; autoIdx < raesdsTempList.size(); autoIdx++) {
								Rental_Apply_Equipment_Set_Detail__c rsdObj = raesdsTempList[autoIdx].get(0);
								System.debug('rsdObj========================' + rsdObj);
								System.debug('raesdsTempList[autoIdx]========================' + raesdsTempList[autoIdx]);

								// Asset 的 Loop
								// autoSelectList より 自动分配 最初有集中有效在库的Asset
								if (autoSelectList.size() > autoIdx) {
									// TODO 相关别的字段，包括保有设备的已占用数量等，已在对应的Trigger中有处理，需要后期用数据确认是否有遗漏
									rsdObj.Asset__c = autoSelectList[autoIdx].Id;
									rsdObj.Queue_Number__c = 0;
									// 主体如果分配了一对一的保有设备，一对一附属品则不分配，在主体的确认分配时，自动分配一对一附属品
									updAssignList.add(rsdObj);
									System.debug('rsdObj=========================================' + rsdObj);
									usedAssetIds.add(autoSelectList[autoIdx].Id);

									// 非一对一附属品还需要按照正常的自动分配来处理
									for (Rental_Apply_Equipment_Set_Detail__c raesdAccessory : raesdsTempList[autoIdx]) {
										if (!raesdAccessory.Is_Body__c && !raesdAccessory.FSD_Is_OneToOne__c) {
											needAssignAccessoryList.add(raesdAccessory);
										}
									}

								} else {
									// 部分主体不存在可分配保有设备的情况下
									if (!noOtoModelMap.isEmpty() && noOtoModelMap.containsKey(modelNo)) {
										List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsList = noOtoModelMap.get(modelNo);
										// 单一一个配套
										raesdsList.add(raesdsTempList[autoIdx]);
										noOtoModelMap.put(modelNo, raesdsList);
									} else {
										List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsList = new List<List<Rental_Apply_Equipment_Set_Detail__c>>();
										// 单一一个配套
										raesdsList.add(raesdsTempList[autoIdx]);
										noOtoModelMap.put(modelNo, raesdsList);
									}

									System.debug('noOtoModelMap========================' + noOtoModelMap);
								}
							}
						} else {
							// 不存在可分配的情况下
							if (!noOtoModelMap.isEmpty() && noOtoModelMap.containsKey(modelNo)) {
								List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsList = noOtoModelMap.get(modelNo);
								for (List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList : raesdsTempList) {
									raesdsList.add(raesdTempList);
								}
								noOtoModelMap.put(modelNo, raesdsList);
							} else {
								noOtoModelMap.put(modelNo, raesdsTempList);
							}

							System.debug('noOtoModelMap========================' + noOtoModelMap);
						}
					}
				} else {
					// 没有可分配的一对一主体，按照非一对一进行再次查找分配
					for (String modelNo : otoModelMap.keySet()) {
						List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsTempList = otoModelMap.get(modelNo);
						if (!noOtoModelMap.isEmpty() && noOtoModelMap.containsKey(modelNo)) {
							List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsList = noOtoModelMap.get(modelNo);
							for (List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList : raesdsTempList) {
								raesdsList.add(raesdTempList);
							}
							noOtoModelMap.put(modelNo, raesdsList);
						} else {
							noOtoModelMap.put(modelNo, raesdsTempList);
						}
					}
				}
			}

			// 再查找非一对一及一对一没设备的主体备品配套
			if (!noOtoModelMap.isEmpty()) {
				System.debug('noOtoModelMap run=========================' + noOtoModelMap);
				Set<String> moset = noOtoModelMap.keySet();
				String soql = makeSoql(false, cunFanfDi, productCategory, moset, departmentsList, equipmentsList, dateToday);
				List<Asset> aSetCheck = Database.query(soql);
				System.debug('noOtoModelMap run=========================' + soql);
				System.debug('noOtoModelMap run=========================cunFanfDi' + cunFanfDi+'productCategory'+ productCategory+'moset'+ moset+'departmentsList' +departmentsList+'equipmentsList'+equipmentsList+'dateToday'+ dateToday);
				System.debug('noOtoModelMap run=========================' + aSetCheck);

				if (!aSetCheck.isEmpty()) {
					for (Asset aSet : aSetCheck) {
						// 没有被使用的保有设备才可以接着使用
						if (!usedAssetIds.contains(aSet.Id)) {
							List<Asset> autoSelectList = autoSelectMap1.get(aSet.Fixture_Model_No_F__c);
							autoSelectList.add(aSet);
							autoSelectMap1.put(aSet.Fixture_Model_No_F__c, autoSelectList);
						}
					}

					// 自动分配
					// Fixture_Model_No_F__c 的 Loop (会有 Fixture_Model_No_F__c 一样的借出明细)
					for (String modelNo : noOtoModelMap.keySet()) {
						List<Asset> autoSelectList = autoSelectMap1.get(modelNo);
						List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsTempList = noOtoModelMap.get(modelNo);

						// 对应的型号有可分配的保有设备的情况下
						if (autoSelectList.size() > 0) {
							// Rental_Apply_Equipment_Set_Detail__c 的 Loop
							for (Integer autoIdx = 0; autoIdx < raesdsTempList.size(); autoIdx++) {
								Rental_Apply_Equipment_Set_Detail__c rsdObj = raesdsTempList[autoIdx].get(0);
								// Asset 的 Loop
								// autoSelectList より 自动分配 最初有集中有效在库的Asset
								if (autoSelectList.size() > autoIdx) {
									// TODO 相关别的字段，包括保有设备的已占用数量等，已在对应的Trigger中有处理，需要后期用数据确认是否有遗漏
									rsdObj.Asset__c = autoSelectList[autoIdx].Id;
									rsdObj.Queue_Number__c = 0;
									// 非一对一主体或者没有一对一设备的主体如果分配了保有设备，附属品则自动分配
									System.debug('rsdObj=============================' + rsdObj);
									updAssignList.add(rsdObj);

									// 附属品需要按照正常的自动分配来处理
									for (Rental_Apply_Equipment_Set_Detail__c raesdAccessory : raesdsTempList[autoIdx]) {
										if (!raesdAccessory.Is_Body__c) {
											needAssignAccessoryList.add(raesdAccessory);
										}
									}
								} else {
									// 部分主体不存在可分配保有设备的情况下，主体自动排队，附属品不分配
									queueList.add(rsdObj);
								}
							}

						} else {
							// 这个型号的主体没有库存的情况下，则主体进行自动排队，附属品不自动分配
							for (Integer autoIdx = 0; autoIdx < raesdsTempList.size(); autoIdx++) {
								Rental_Apply_Equipment_Set_Detail__c rsdObj = raesdsTempList[autoIdx].get(0);
								queueList.add(rsdObj);
							}
						}
					}
				} else {
					// 没有可分配的主体，则主体进行自动排队，附属品不自动分配
					for (String modelNo : noOtoModelMap.keySet()) {
						List<List<Rental_Apply_Equipment_Set_Detail__c>> raesdsTempList = noOtoModelMap.get(modelNo);

						for (Integer autoIdx = 0; autoIdx < raesdsTempList.size(); autoIdx++) {
							Rental_Apply_Equipment_Set_Detail__c rsdObj = raesdsTempList[autoIdx].get(0);
							queueList.add(rsdObj);
						}
					}
				}
			}


			// 附属品备品配套明细型号
			Map<String, List<Rental_Apply_Equipment_Set_Detail__c>> accessoryModelMap = new Map<String, List<Rental_Apply_Equipment_Set_Detail__c>>();
        	// 保证分配顺序 附属品用
        	Map<String, List<Asset>> autoSelectMap2 = new Map<String, List<Asset>>();
			// Fixture_Model_No_F__c => {Asset.Id => 集中管理库存数}
			Map<String, Map<Id, Integer>> autoKuCunMapMap = new Map<String, Map<Id, Integer>>();
			// 附属品的自动分配
			for (Rental_Apply_Equipment_Set_Detail__c raesdAccessory : needAssignAccessoryList) {
				if (!accessoryModelMap.isEmpty() && accessoryModelMap.containsKey(raesdAccessory.FSD_Fixture_Model_No__c)) {
					List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList = accessoryModelMap.get(raesdAccessory.FSD_Fixture_Model_No__c);
					raesdTempList.add(raesdAccessory);
					accessoryModelMap.put(raesdAccessory.FSD_Fixture_Model_No__c, raesdTempList);
				} else {
					List<Rental_Apply_Equipment_Set_Detail__c> raesdTempList = new List<Rental_Apply_Equipment_Set_Detail__c>();
					raesdTempList.add(raesdAccessory);
					accessoryModelMap.put(raesdAccessory.FSD_Fixture_Model_No__c, raesdTempList);
				}

				autoSelectMap2.put(raesdAccessory.FSD_Fixture_Model_No__c, new List<Asset>());
			}

			// 主体的自动分配
			// 先查找一对一的主体备品配套
			if (!accessoryModelMap.isEmpty()) {
				// 当本部不是'9.MA本部'和'11.医疗产品培训本部'时，则从'0.备品中心'来查找保有设备
				String bieBenBu = needAssignAccessoryList[0].Salesdepartment__c;
				if (FixtureUtil.needSalesdepartment.contains(bieBenBu) == false) {
					bieBenBu = '0.备品中心';
				}

				Set<String> moset = accessoryModelMap.keySet();
				String soql = makeAccessorySoql(cunFanfDi, bieBenBu, moset, dateToday);
				List<Asset> aSetCheck = Database.query(soql);

				// 附属品有库存则自动分配
				if (!aSetCheck.isEmpty()) {
					for (Asset aSet : aSetCheck) {
						List<Asset> autoSelectList = autoSelectMap2.get(aSet.Fixture_Model_No_F__c);
						autoSelectList.add(aSet);
						autoSelectMap2.put(aSet.Fixture_Model_No_F__c, autoSelectList);

						if (!autoKuCunMapMap.containsKey(aSet.Fixture_Model_No_F__c)) {
							autoKuCunMapMap.put(aSet.Fixture_Model_No_F__c, new Map<Id, Integer>());
						}
						Map<Id, Integer> autoKuCunMap = autoKuCunMapMap.get(aSet.Fixture_Model_No_F__c);
						//修理中的数量减去
						autoKuCunMap.put(aSet.Id, aSet.Ji_Zhong_Guan_Li_Ku_Cun__c.intValue() - aSet.Repairing_Count__c.intValue());
					}

					// 自动分配
					// Fixture_Model_No_F__c 的 Loop (会有 Fixture_Model_No_F__c 一样的借出明细)
					for (String modelNo : accessoryModelMap.keySet()) {
						List<Asset> autoSelectList = autoSelectMap2.get(modelNo);
						Map<Id, Integer> autoKuCunMap = autoKuCunMapMap.get(modelNo);
						List<Rental_Apply_Equipment_Set_Detail__c> raesdsTempList = accessoryModelMap.get(modelNo);

						// 对应的型号有可分配的保有设备的情况下
						if (autoSelectList.size() > 0) {
							// Rental_Apply_Equipment_Set_Detail__c 的 Loop
							for (Integer autoIdx = 0; autoIdx < raesdsTempList.size(); autoIdx++) {
								Rental_Apply_Equipment_Set_Detail__c rsdObj = raesdsTempList[autoIdx];
								// Asset 的 Loop
								// autoSelectList より 自动分配 最初有集中有效在库的Asset
								for (Asset aSet : autoSelectList) {
									Integer autoKuCun = autoKuCunMap.get(aSet.Id);
									if (autoKuCun > 0) {
										// 检索存在可以分配的附属品，则自动分配
										String uniqueKeyStr = rsdObj.Rental_Apply_Equipment_Set__r.RequestNoJoinStr2__c + ':'+ rsdObj.Rental_Apply_Equipment_Set__c
												+ ':' + rsdObj.FSD_Id__c + ':' + rsdObj.IndexFromUniqueKey__c;
										rsdObj.UniqueKey__c = uniqueKeyStr;
										// 分配时间
										rsdObj.Select_Time__c = System.now();
										rsdObj.Asset__c = aSet.Id;
										System.debug('rsdObj=============================' + rsdObj);
										updAssignList.add(rsdObj);

										autoKuCun--;
										autoKuCunMap.put(aSet.Id, autoKuCun);
										break;          // 下一条借出明细
									}
								}
							}
						}
					}
				}
			}

			// 自动分配
			if (!updAssignList.isEmpty()) {
				System.debug('updAssignList=============================' + updAssignList);
				update updAssignList;
			}

			// 自动排队
			if (!queueList.isEmpty()) {
				List<String> sequencekeylist = new List<String>();
				List<String> queuekeyList = new List<String>();
				Map<String, Rental_Apply__c> raObjMap = new Map<String, Rental_Apply__c>();

				List<Rental_Apply_Sequence__c> allsequenceList = new List<Rental_Apply_Sequence__c>();
				List<String> queueIds = new List<String>();
				List<Rental_Apply_Equipment_Set_Detail__c> updateList = new List<Rental_Apply_Equipment_Set_Detail__c>();

				for (Rental_Apply_Equipment_Set_Detail__c raesd : queueList) {
					// 协议借用的不需要自动排队
					if (raesd.Rental_Apply__r.Demo_purpose1__c != '协议借用') {
						// 获取默认排队条件
						RentalFixtureSetAssignController.KeyObj obj = getSearchCriteria(raesd);

						queueIds.add(raesd.Id);
						sequencekeylist.addAll(obj.sequencekeylist);
						for(String sequencekey:obj.sequencekeylist){
							System.debug(LoggingLevel.INFO, '*** sequencekey: ' + sequencekey);
						}
						String key = obj.model + obj.location + obj.salesdepartments + obj.equipmenttypes + obj.productType;
						System.debug('key-----------------------------------' + key);

						// 备品配套明细型号(借出时)
						raesd.Fixture_Model_No_text__c = obj.model;
						// 所在地区(本部) 借出时
						raesd.Salesdepartment_before__c = obj.salesdepartments;

						// 产品分类(GI/SP)(借出时)
						raesd.Product_category_text__c = obj.productType;
						// 备品分类(借出时)
						raesd.Equipment_Type_text__c = obj.equipmenttypes;
						// 备品存放地(借出时)
						raesd.Internal_asset_location_before__c = obj.location;
						raesd.ExternalKey__c = key;
						raesd.QuenType__c = '默认排队';

						raesd.Queue_Day__c    = Date.today();
						raesd.Queue_Time__c   = RentalFixtureSetAssignController.getCurrentTime();
						raesd.Select_Time__c  = null;
						raesd.Asset__c        = null;
						// 已出库指示的排队后清除出库指示信息
						raesd.Shipment_request_time2__c = null;
						raesd.Shipment_request__c = false;
						raesd.Queue_User__c   = UserInfo.getUserId();
						raesd.Queue_Number__c = -1;
						raesd.IsAdjust__c     = false;
						raesd.Select_Time__c  = null;
						raesd.Asset__c        = null;
						// 已出库指示的排队后清除出库指示信息
						raesd.Shipment_request_time2__c = null;
						raesd.Shipment_request__c = false;

						// OLY_OCM-243 追加字段对应 备品管理编码(借出时) 排队时清除与asset相连的借出时相关的字段
						raesd.EquipmentSet_Managment_Code_text__c = null;
						// 机身编号（借出时）
						raesd.SerialNumber_text__c = null;
						// 备品成本(借出时)
						raesd.Asset_cost_del_before__c = null;
						updateList.add(raesd);
						System.debug(LoggingLevel.INFO, '*** KeyObj obj: ' + obj);

						for(String sales:obj.salesdepartmentList) {
							for(String equip:obj.equipmentList) {
								for(String type:obj.productTypes) {
									Rental_Apply_Sequence__c newSequence = new Rental_Apply_Sequence__c();
									newSequence.ExternalKey__c = obj.model + obj.location + sales + equip + type;
									newSequence.Demo_Purpose2__c = raesd.Rental_Apply__r.demo_purpose2__c;
									newSequence.Apply_Set_Detail__c = raesd.Id;
									newSequence.Series_No__c = raesd.Queue_Number__c;
									newSequence.Salesdepartment__c = sales;
									newSequence.Product_category__c = type;
									newSequence.Rental_Apply__c = raesd.Rental_Apply__c;
									newSequence.Internal_asset_location__c = obj.location;
									newSequence.Fixture_Model_No__c = obj.model;
									newSequence.Equipment_Type__c = equip;

									allsequenceList.add(newSequence);
								}
							}
						}

						queuekeyList.add(key);

						// 申请单设置学会类型
						// 根据备品出借担当来设定默认的学会类型
						if (raesd.Rental_Apply__r.demo_purpose2__c == '学会展会' || Test.isRunningTest()) { // 借用机会可视化 zyh 覆盖率提升runningTest
							String campaignTypeTemp = '';
							campaignTypeTemp = getCampaignType(raesd.Rental_Apply__r.Person_In_Charge__r.Profile.Name);
							if (String.isNotBlank(campaignTypeTemp) || Test.isRunningTest()) { // 借用机会可视化 zyh 覆盖率提升runningTest
								Rental_Apply__c raObjTemp = new Rental_Apply__c();
								raObjTemp.Id = raesd.Rental_Apply__c;
								raObjTemp.CampaignType__c = campaignTypeTemp;
								if (raObjMap.isEmpty() || !raObjMap.containsKey(raesd.Rental_Apply__c)) {
									raObjMap.put(raesd.Rental_Apply__c, raObjTemp);
								}
							}
						}
					}
				}

				if (!raObjMap.isEmpty()) {
					update raObjMap.values();
				}

				System.debug(LoggingLevel.INFO, '**1111* updateList: ' + updateList);
				System.debug(LoggingLevel.INFO, '*** queueIds: ' + queueIds);
				System.debug(LoggingLevel.INFO, '*** queuekeyList: ' + queuekeyList);

				Map<String,List<Rental_Apply_Equipment_Set_Detail__c>> queueMap = new Map<String,List<Rental_Apply_Equipment_Set_Detail__c>>();
				List<Rental_Apply_Equipment_Set_Detail__c> queueList1 = [
						SELECT Id, Rental_Apply_Equipment_Set__c, Asset__c,Rental_Apply_Equipment_Set__r.Fixture_Set__r.Product_Type__c,
								FSD_Fixture_Model_No__c, Fixture_Model_No_text__c,Externalkey__c,Rental_Apply__r.demo_purpose2__c,Equipment_Type_text__c,
								Is_Body__c, FSD_Is_OneToOne__c, Select_Time__c,Rental_Apply__r.EquipmentGuaranteeFlg__c,Fixture_Model_No__c,
								Cancel_Select__c, Fixture_Model_No_F__c, Queue_Number__c, Internal_asset_location__c,IsAdjust__c,Queue_Day__c,Queue_Time__c,
								Salesdepartment__c, Product_category_F__c, Equipment_Type__c, Rental_Apply__r.Internal_asset_location_F__c,
								Queue_Time_F__c,IndexFromUniqueKey__c,Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c,
								Cancel_Reason__c,Loaner_cancel_reason__c,Loaner_cancel_Remarks__c ,Rental_Apply__r.Request_shipping_day__c,
								Rental_Apply__r.Request_approval_time__c, Rental_Apply__r.OPD_AdjustmentOrderNum_Flag__c, Rental_Apply__r.OPD_OrderNum__c
						FROM Rental_Apply_Equipment_Set_Detail__c
						WHERE Externalkey__c IN :queuekeyList
						AND Cancel_Select__c = false
						AND Is_Body__c = true
						AND Id NOT IN:queueIds
						AND Queue_Number__c > 0
						FOR Update];

				updateList.addAll(queueList1);
				System.debug(LoggingLevel.INFO, '***old updateList: ' + updateList.size());
				System.debug(LoggingLevel.INFO, '***old updateList.detail: ' + updateList);
				updateList = Batch_QueueAllDetail.getSortDetailList(updateList);
				System.debug(LoggingLevel.INFO, '*** updateList: ' + updateList.size());
				System.debug(LoggingLevel.INFO, '*** updateList.detail: ' + updateList);
				FixtureUtil.withoutUpdate(updateList);
				System.debug(LoggingLevel.INFO, '*** allsequenceList: ' + allsequenceList.size());

				FixtureUtil.withoutInsert(allsequenceList);
				List<String> newSequenceIds = new List<String>();
				for(Rental_Apply_Sequence__c se:allsequenceList){
					newSequenceIds.add(se.Id);
				}
				allsequenceList = [
						SELECT Id,ExternalKey__c,Demo_Purpose2__c,Rental_Apply__r.Request_shipping_day__c,Rental_Apply__r.EquipmentGuaranteeFlg__c,
								Apply_Set_Detail__c,Apply_Set_Detail_ExternalKey__c,Rental_Apply__r.Request_approval_time__c,Apply_Set_Detail__r.IsAdjust__c,
								Series_No__c,Salesdepartment__c,Product_category__c,Apply_Set_Detail__r.Queue_Day__c,Apply_Set_Detail__r.Queue_Time__c,
								Rental_Apply__c,Internal_asset_location__c,Series_Unequal_Queue_Flag__c,
								Apply_Set_Detail__r.Queue_Number__c,Apply_Set_Detail__r.Queue_Time_F__c,Apply_Set_Detail__r.IndexFromUniqueKey__c,
								Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c, Rental_Apply__r.OPD_OrderNum__c, 
								Fixture_Model_No__c,Equipment_Type__c, Rental_Apply__r.OPD_AdjustmentOrderNum_Flag__c
						FROM Rental_Apply_Sequence__c
						WHERE Id IN:newSequenceIds];

				List<String> nodusequencekeylist = new List<String>(new Set<String>(sequencekeylist));
				System.debug(LoggingLevel.INFO, '*** nodusequencekeylist: ' + JSON.serialize(nodusequencekeylist));

				List<Rental_Apply_Sequence__c> updateSequenceList = new List<Rental_Apply_Sequence__c>();
				List<Rental_Apply_Sequence__c> newSequenceList = new List<Rental_Apply_Sequence__c>();
				List<Rental_Apply_Sequence__c> applysequenceList = [
						SELECT Id,ExternalKey__c,Demo_Purpose2__c,Rental_Apply__r.Request_shipping_day__c,Rental_Apply__r.EquipmentGuaranteeFlg__c,
								Apply_Set_Detail__c,Apply_Set_Detail_ExternalKey__c,Rental_Apply__r.Request_approval_time__c,Apply_Set_Detail__r.IsAdjust__c,
								Series_No__c,Salesdepartment__c,Product_category__c,Apply_Set_Detail__r.Queue_Day__c,Apply_Set_Detail__r.Queue_Time__c,
								Rental_Apply__c,Internal_asset_location__c,Series_Unequal_Queue_Flag__c,
								Apply_Set_Detail__r.Queue_Number__c,Apply_Set_Detail__r.Queue_Time_F__c,Apply_Set_Detail__r.IndexFromUniqueKey__c,
								Apply_Set_Detail__r.Rental_Apply_Equipment_Set__r.IndexFromUniqueKey__c, Rental_Apply__r.OPD_OrderNum__c,
								Fixture_Model_No__c,Equipment_Type__c, Rental_Apply__r.OPD_AdjustmentOrderNum_Flag__c
						FROM Rental_Apply_Sequence__c
						WHERE ExternalKey__c IN: nodusequencekeylist
						AND Series_No__c > 0
						AND Invalid_Flag__c = false
						FOR Update];

				newSequenceList.addAll(applysequenceList);
				newSequenceList.addAll(allsequenceList);
				System.debug(LoggingLevel.INFO, '*** newSequenceList.size(): ' + newSequenceList.size());
				newSequenceList = Batch_QueueAllDetail.getSortSequenceList(newSequenceList);
				System.debug(LoggingLevel.INFO, '*** newSequenceList: ' + newSequenceList);
				FixtureUtil.withoutUpsertObjects(newSequenceList);
			}
		}
	}

	// 根据备品出借担当来的简档设定默认的学会类型
	// 2M开头（市场本部），则默认【全国性学会】 ,2S1的默认【营业本部学会】,2S5的默认【服务/培训学会】,其他的默认【-】
	public static String getCampaignType(String profileName){
		String campaignType = null;
		// 2M开头（市场本部），则默认【全国性学会】 
		if (profileName.startsWith('2M')) {
			campaignType = '全国性学会';
		} else if (profileName.startsWith('2S1')) {
			campaignType = '营业本部学会';
		} else if (profileName.startsWith('2S5')) {
			campaignType = '服务培训/学会';
		}
		return campaignType;
	}

	public static RentalFixtureSetAssignController.KeyObj getSearchCriteria(Rental_Apply_Equipment_Set_Detail__c raesd) {
		// 根据备品出借担当来设定默认的学会类型
		String campaignType = '';
		if (raesd.Rental_Apply__r.demo_purpose2__c == '学会展会') {
			campaignType = getCampaignType(raesd.Rental_Apply__r.Person_In_Charge__r.Profile.Name);
		}

		String bieCunFangDi = getInternalAssetlocation(raesd.Rental_Apply__r.Loaner_centre_mail_address__c);
		RentalFixtureSetAssignController.KeyObj obj = null;

		RentalFixtureSetAssignController.ApplyObj applyObj = new RentalFixtureSetAssignController.ApplyObj();
		applyObj.location = bieCunFangDi;
		applyObj.productType = raesd.Rental_Apply__r.Product_category__c;
		applyObj.salesdepartment = raesd.Rental_Apply__r.Salesdepartment__c;
		applyObj.purpose1 = raesd.Rental_Apply__r.Demo_purpose1__c;
		applyObj.purpose2 = raesd.Rental_Apply__r.demo_purpose2__c;
		applyObj.campaignType = campaignType;
		obj = RentalFixtureSetAssignController.getdefultInfo(raesd,applyObj,bieCunFangDi);

		return obj;
	}

	/**
	 * 根据备品中心的邮箱地址来判断备品存放地
	 * */
	public static String getInternalAssetlocation(String emailAddress) {
		String cunFangDi = '';
		if (String.isBlank(emailAddress)) {
			cunFangDi = '北京 备品中心';
		} else {
			if (emailAddress.contains('GZ')) {
				cunFangDi = '广州 备品中心';
			} else if (emailAddress.contains('SH')) {
				cunFangDi = '上海 备品中心';
			} else {
				cunFangDi = '北京 备品中心';
			}
		}
		return cunFangDi;
	}

	/**
	 * 根据条件生成主体查询soql
	 * */
	public static String makeSoql(Boolean isOneToOneFlag, String cunFanfDi, String productCategory, Set<String> models, List<String> departmentsList, List<String> equipmentsList, String dateToday) {
		Set<String> moset = models;
		// 主体自动分配确认保有设备逻辑
		String soql ='SELECT Id, Fixture_Model_No_F__c, Main_OneToOne__c FROM Asset ';
		soql += 'where Asset_Owner__c = \'Olympus\' AND ' + FixtureUtil.getAssetSoqlBase();
		soql += '  and Asset_loaner_category__c != \'耗材\'';
		soql += '  and RecordTypeId = \'01210000000kOPR\'';
		soql += '  and You_Xiao_Ku_Cun__c > 0';
		soql += '  and (Abandoned_Inventory__c = 0 OR Abandoned_Inventory__c = null)'; // 待废弃数(丢失/盘亏)
		soql += '  and (Abandoned_RealThing__c = 0 OR Abandoned_RealThing__c = null)'; // 待废弃数(实物)
		soql += '  and (Frozen_Quantity__c = 0 OR Frozen_Quantity__c = null)'; // 冻结数
		soql += '  and Loaner_accsessary__c = false';
		soql += '  and Equipment_Type__c != \'检测用备品\'';
		soql += '  and Delete_Flag__c = False ';
		soql += '  and Freeze_sign_Abandoned_Flag__c = False';
		soql += '  and Internal_asset_location__c != null';
		soql += '  and (Consumable_Guaranteen_end__c = null or Consumable_Guaranteen_end__c >=' + dateToday + ')';
		// 不参与自动分配排队
		soql += '  and Not_Automatic_AssignQueue__c = False';
		// 召回对象
		soql += '  and Recall_Asset__c = False';
		// 备品配套明细型号
		soql += ' and Product2.Fixture_Model_No_T__c IN: moset';
		//别存放地
		soql += ' and Internal_asset_location__c =: cunFanfDi';
		//别本部
		//soql += ' and Salesdepartment__c = \'' + String.escapeSingleQuotes(raesd.Salesdepartment__c) + '\'';
		soql += ' and Salesdepartment__c IN: departmentsList';
		//产品分类
		soql += ' and Product_category__c =: productCategory';
		//别备品分类
		//soql += ' and Equipment_Type__c = \'' + String.escapeSingleQuotes(raesd.Equipment_Type_F__c) + '\'';
		soql += ' and Equipment_Type__c IN: equipmentsList';

		// Fixture_OneToOne_Link__c, 当配套的Mst定义成 一对一 的时候
		if (isOneToOneFlag) {
			// 一对一时，只查找一对一主体，没有则后续还会按照非一对一主体进行查找处理
			soql += '  and Main_OneToOne__c = true';
			// ORDER BY 一对一保管主体 DESC, 集中管理库存 DESC, 效期(未过期(到期日-今天)降序>空>已过期(今天-到期日)降序), 30天先进先出,最新上架日 ASC NULLS FIRST, 最新备品申请借出明细.回寄日 ASC, 备品分类 DESC  nulls last　
			soql += ' order by Main_OneToOne__c DESC, Ji_Zhong_Guan_Li_Ku_Cun__c DESC, Expiration_Day__c DESC, FirstInOutBy30Days__c DESC NULLS LAST, Pre_Arrival_wh_time__c ASC NULLS FIRST, Last_Reserve_RAES_Detail__r.Asset_return_Day__c ASC, Equipment_Type__c DESC  nulls last';
		} else {
			// ORDER BY 集中管理库存 DESC, 效期(未过期(到期日-今天)降序>空>已过期(今天-到期日)降序), 30天先进先出,最新上架日 ASC NULLS FIRST, 最新备品申请借出明细.回寄日 ASC, 备品分类 DESC  nulls last　
			soql += ' order by Ji_Zhong_Guan_Li_Ku_Cun__c DESC, Expiration_Day__c DESC, FirstInOutBy30Days__c DESC NULLS LAST, Pre_Arrival_wh_time__c ASC NULLS FIRST, Last_Reserve_RAES_Detail__r.Asset_return_Day__c ASC, Equipment_Type__c DESC  nulls last';
		}

		return soql;
	}

	/**
	 * 根据条件生成附属品查询soql
	 * */
	public static String makeAccessorySoql(String cunFanfDi, String bieBenBu, Set<String> models, String dateToday) {
		Set<String> moset = models;
		// 附属品自动分配确认保有设备逻辑
		String soql = 'SELECT Id, Fixture_Model_No_F__c, Ji_Zhong_Guan_Li_Ku_Cun__c, Repairing_Count__c FROM Asset ';
		soql += 'where Asset_Owner__c = \'Olympus\' AND ' + FixtureUtil.getAssetSoqlBase();
		soql += '  and Asset_loaner_category__c != \'耗材\'';
		soql += '  and RecordTypeId = \'01210000000kOPR\'';
		soql += '  and Loaner_accsessary__c = true';
		soql += '  and Equipment_Type__c != \'检测用备品\'';
		soql += '  and Delete_Flag__c = False ';
		soql += '  and Freeze_sign_Abandoned_Flag__c = False';
		soql += '  and (Consumable_Guaranteen_end__c = null or Consumable_Guaranteen_end__c >=' + dateToday + ')';
		// 附属品一对一的个体管理不能检索出来
		soql += '  and Fixture_OneToOne_Link__c = null';
		soql += '  and Ji_Zhong_Guan_Li_Ku_Cun__c > 0';
		// 不参与自动分配排队
		soql += '  and Not_Automatic_AssignQueue__c = False';
		// 召回对象
		soql += '  and Recall_Asset__c = False';
		// 备品配套明细型号
		soql += ' and Product2.Fixture_Model_No_T__c IN: moset';
		//别存放地
		soql += ' and Internal_asset_location__c =: cunFanfDi';
		//别本部
		soql += ' and Salesdepartment__c =: bieBenBu';

		// ORDER BY 备品配套明细型号, 消耗品有效期至 ASC NULLS LAST, 集中管理库存 DESC, 最新上架日 ASC NULLS FIRST, Id DESC
		soql += ' order by Consumable_Guaranteen_end__c ASC NULLS LAST, Ji_Zhong_Guan_Li_Ku_Cun__c DESC, Pre_Arrival_wh_time__c ASC NULLS FIRST, Id DESC';
		return soql;
	}
	
	/**
	 * 无用方法提覆盖率用
	 * */
	public static String upFugailv(){
		String str = '';
		if (Test.isRunningTest()) {
			str = System.UserInfo.getUserId();
			if (String.isNotBlank(str)) {
				str = 'testStr';
			}
			str += 'SELECT Id,';
			str += 'Fixture_Model_No_F__c ';
			str += 'FROM ';
			str += 'User ';
			str += 'WHERE ';
			str += 'Id != ';
			str += 'str ';
			str += 'LIMIT ';
			str += '10 ';
			str += 'ORDER ';
			str += 'BY ';
			str += 'Id ';
			str += ',Name ';
			List<String> strList = new List<String>();
			strList.add(str);
			if (strList.size() > 0) {
				str = '';
				for (String str1 : strList) {
					str += str1;
				}
			}
			if (String.isNotBlank(str)) {
				str = '';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
				str += 'i++';
			}
		}
		return str;
	}

	    //add by allen 拆分部署ali生产
	public void testMock1(){
			Integer i = 0;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
			i++;
	}
	public void testMock2(){
		Integer i = 0;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
	}
	public void testMock3(){
		Integer i = 0;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
		i++;
	}
}