package iitb.cfilt.cpost.dmstemmer;
import java.util.*;
import iitb.cfilt.cpost.lexicon.*;
import iitb.cfilt.cpost.*;

public class NewStemmer {
	LexReader lr;// = new LexReader();
	LexRuleReader lrr;// = new LexRuleReader();
	public NewStemmer() {
		// TODO Auto-generated constructor stub
		lr = new LexReader();
		lrr = new LexRuleReader();
	}
	public NewStemmer(LexReader lr, LexRuleReader lrr){
		this.lr = lr;
		this.lrr = lrr;
	}
	//public StemmedToken stem(String token){
	public MAResult stem(String token){
		token  = lr.normalizeHindiString(token);
		//StemmedToken retVal = new StemmedToken(token);
		MAResult retVal = new MAResult(token);
		//Vector<StemmedResult> stemmedOutputs = new Vector<StemmedResult>();	
		Vector<MorphOutput> morphOutputs = new Vector<MorphOutput>();
		Vector<MorphOutput2> morphs = new Vector<MorphOutput2>();
		String stem;		
		for(int suffixIter=0; suffixIter<lrr.suffixes.size(); suffixIter++){
				String suffix = lrr.suffixes.get(suffixIter);				
				if(suffix.equals("Null")){
					//System.out.println("Here it is");
					stem = token;
				}
				else if(token.endsWith(suffix)){
					stem = token.replaceAll(suffix+"$", "");				
				}
				else{
					continue;
				}
				//if(lr.checkInLex(stem)){
//				 FOR NOUNS //	check if noun exists.
				Vector<Lex> lexVector = lr.getLexResults(stem,"noun");
					//System.out.println("I am in with : " + lexVector.size());
					//check for constraints
				Vector<NNSuffixRule> srv = lrr.suffixRuleNNHash.get(suffix);
				if(lexVector != null && !lexVector.isEmpty() && srv != null && !srv.isEmpty()){
					for(int lv = 0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						StemmerResult srt = new StemmerResult(lex.getRoot(),"",suffix,"noun",lex.getFeatures().getEnding());
						Vector<MorphResult> mrv = new Vector<MorphResult>();
						for(int s=0; s<srv.size(); s++){
							NNSuffixRule sr = srv.get(s);
							/*lex.getFeatures().print();
							sr.getFeatures().print();*/
							boolean chk = lex.getFeatures().isEqual(sr.getFeatures());
							if(chk){
								//StemmedResult str = new StemmedResult(stem,lex.getFeatures(),sr.getMorphAnalysis(),suffix,"noun");								
								MorphResult mr = sr.getMorphResult();
								mr.setGender(lex.getFeatures().getGenderString());
								mrv.add(mr);
								//MorphOutput2 mo2 = new MorphOutput2(srt,mr,(SuffixMorphsPair)null);
								//morphs.add(mo2);
				//				stemmedOutputs.add(str);
							}
							else if(suffix.equals("Null")){
								//StemmedResult str = new StemmedResult(stem,lex.getFeatures(),"",suffix,"noun");								
								//MorphOutput2 mo2 = new MorphOutput2(srt,(MorphResult)null,(SuffixMorphsPair)null);
								MorphResult mr = new MorphResult();
								mr.setGender(lex.getFeatures().getGenderString());
								mrv.add(mr);
								//morphs.add(mo2);
				//				stemmedOutputs.add(str);
							}
						}
						if(mrv.size()>0){
							MorphOutput2 mo2 = new MorphOutput2(srt,mrv,(SuffixMorphsPair)null);
							morphs.add(mo2);
						}
					}
				}
				//else{
					if(lrr.reAdjustmentRuleNNHash.containsKey(suffix)){
						Vector<NNReadjustmentRule> rrv = lrr.reAdjustmentRuleNNHash.get(suffix);
						for(int r=0; r<rrv.size(); r++){
							NNReadjustmentRule rr = rrv.get(r);
							//System.out.println("Stem : " + stem + ", suffix to delete : " + rr.getSuffixToDelete());
							String tempStem = stem.replaceAll(rr.getSuffixToDelete()+"$", "");
							//System.out.println("Stem : " + tempStem);
							tempStem = tempStem + rr.getSuffixToAdd();
							//System.out.println("Stem : " + tempStem);
							if(lr.checkInLex(tempStem)){								
								//Vector<Lex> lexVector = lr.getLexResults(tempStem);
								lexVector = lr.getLexResults(tempStem,"noun");
								//check for constraints
								//System.out.println("lex result size : " + lexVector.size());
								if(lexVector != null && !lexVector.isEmpty()){									
									for(int lv = 0; lv<lexVector.size(); lv++){
										Lex lex = lexVector.get(lv);
										StemmerResult srt = new StemmerResult(lex.getRoot(),"",suffix,"noun",lex.getFeatures().getEnding());
										//Vector<MorphResult> mrv = new Vector<MorphResult>();
										boolean chk = lex.getFeatures().isEqual(rr.getFeatures());
										if(chk){	
											String morphAnalysis = "";
											Vector<MorphResult> mrv = new Vector<MorphResult>();
											for(int s=0; s<srv.size(); s++){
												NNSuffixRule sr = srv.get(s);										
												chk = sr.getFeatures().isEqual(rr.getFeatures());
												if(chk){
													morphAnalysis = sr.getMorphAnalysis();
													MorphResult mr = sr.getMorphResult();
													mrv.add(mr);
												}
											}
											//StemmedResult str = new StemmedResult(tempStem,lex.getFeatures(),morphAnalysis,suffix,"noun");//suffix,lex.getFeatures());
					//						stemmedOutputs.add(str);
											MorphOutput2 mo2 = new MorphOutput2(srt,mrv,(SuffixMorphsPair)null);
											morphs.add(mo2);
										}					
									}
								}
							}
						}					
					//}
					}
				//}
					// FOR ADJECTIVES //
					if(lrr.adjRuleHash.containsKey(suffix)){
						Vector<LexGeneralRule> adjRules = lrr.adjRuleHash.get(suffix);
						if(adjRules != null && !adjRules.isEmpty()){
							for(int r=0; r<adjRules.size(); r++){
								
								LexGeneralRule adjRule = adjRules.get(r);
								String tempStem = token.replaceAll(adjRule.getSuffixToDelete()+"$", "");
								tempStem = tempStem + adjRule.getSuffixToAdd();
								if(lr.checkInLex(tempStem)){							
									lexVector = lr.getLexResults(tempStem,"adjective");
									if(lexVector != null && !lexVector.isEmpty()){
										for(int lv = 0; lv<lexVector.size(); lv++){
											Lex lex = lexVector.get(lv);
											StemmerResult srt = new StemmerResult(lex.getRoot(),"",suffix,"adjective",lex.getFeatures().getEnding());
											boolean chk = lex.getFeatures().getClas() == adjRule.getClas();
											if(chk){
												String morphAnalysis = adjRule.getMorphAnalysis();
												String parts[] = morphAnalysis.split(":");
												if(parts[0].startsWith("[")){
													parts[0] = parts[0].replaceAll("^\\[", "");
												}
												if(parts[1].endsWith("]")){
													parts[1] = parts[1].replaceAll("\\]"+"$", "");
												}
												/*char gender;
												if(parts[0].trim().startsWith("+")){
													gender = 'M';
												}else{
													gender = 'F';
												}*/
												String[] mparts = parts[1].split(",");
												morphAnalysis = "< " + parts[1].trim() + " >"; 
												MorphResult mr = new MorphResult(parts[0].trim(),mparts[1].trim(),"x",mparts[0].trim(),"x","x","x");
												MorphOutput2 mo2 = new MorphOutput2(srt,mr,(SuffixMorphsPair)null);
												morphs.add(mo2);
							//					StemmedResult str = new StemmedResult(tempStem,lex.getFeatures(),morphAnalysis,suffix,"adjective");//suffix,lex.getFeatures());
								//				str.setGender(gender);
						//						stemmedOutputs.add(str);
											}							
										}
									}
								}
							}
						}
					}
					// FOR Quantifiers/Intensifiers
					if(lrr.QnfInfRuleHash.containsKey(suffix)){
						Vector<LexGeneralRule> qnfInfRules = lrr.QnfInfRuleHash.get(suffix);
						if(qnfInfRules != null && !qnfInfRules.isEmpty()){
							for(int r=0; r<qnfInfRules.size(); r++){
								
								LexGeneralRule qnfInfRule = qnfInfRules.get(r);
								String tempStem = token.replaceAll(qnfInfRule.getSuffixToDelete()+"$", "");
								tempStem = tempStem + qnfInfRule.getSuffixToAdd();
								if(lr.checkInLex(tempStem)){
									String[] cats = {"quantifier","intensifier"};
									for(int i = 0; i<cats.length; i++){
										String cat = cats[i];
										lexVector = lr.getLexResults(tempStem,cat);
										if(lexVector != null && !lexVector.isEmpty()){
											for(int lv = 0; lv<lexVector.size(); lv++){
												Lex lex = lexVector.get(lv);
												StemmerResult srt = new StemmerResult(lex.getRoot(),"",suffix,cat,lex.getFeatures().getEnding());
												boolean chk = lex.getFeatures().getClas() == qnfInfRule.getClas();
												if(chk){	
													String morphAnalysis = qnfInfRule.getMorphAnalysis();
													String parts[] = morphAnalysis.split(":");
													if(parts[0].startsWith("[")){
														parts[0] = parts[0].replaceAll("^\\[", "");
													}
													if(parts[1].endsWith("]")){
														parts[1] = parts[1].replaceAll("\\]"+"$", "");
													}
													char gender;
													if(parts[0].trim().startsWith("+")){
														gender = 'M';
													}
													else{
														gender = 'F';
													}													
													String[] mparts = parts[1].split(",");
													morphAnalysis = "< " + parts[1].trim() + " >"; 
													MorphResult mr = new MorphResult(parts[0].trim(),mparts[1].trim(),"x",mparts[0].trim(),"x","x","x");
													MorphOutput2 mo2 = new MorphOutput2(srt,mr,(SuffixMorphsPair)null);
													morphs.add(mo2);
													StemmedResult str = new StemmedResult(tempStem,lex.getFeatures(),morphAnalysis,suffix,cat);//suffix,lex.getFeatures());
													str.setGender(gender);
							//						stemmedOutputs.add(str);
												}							
											}
										}
									}
								}
							}
						}
					}
					
					// FOR ORDINALS
					if(lrr.OrdinalRuleHash.containsKey(suffix)){
						Vector<LexGeneralRule> ordinalRules = lrr.OrdinalRuleHash.get(suffix);
						if(ordinalRules != null && !ordinalRules.isEmpty()){
							for(int r=0; r<ordinalRules.size(); r++){
								
								LexGeneralRule ordinalRule = ordinalRules.get(r);
								String tempStem = token.replaceAll(ordinalRule.getSuffixToDelete()+"$", "");
								tempStem = tempStem + ordinalRule.getSuffixToAdd();
								if(lr.checkInLex(tempStem)){							
									lexVector = lr.getLexResults(tempStem,"ordinal");
									if(lexVector != null && !lexVector.isEmpty()){
										for(int lv = 0; lv<lexVector.size(); lv++){
											Lex lex = lexVector.get(lv);
											StemmerResult srt = new StemmerResult(lex.getRoot(),"",suffix,"ordinal",lex.getFeatures().getEnding());
											boolean chk = lex.getFeatures().getClas() == ordinalRule.getClas();
											if(chk){	
												String morphAnalysis = ordinalRule.getMorphAnalysis();
												String parts[] = morphAnalysis.split(":");
												if(parts[0].startsWith("[")){
													parts[0] = parts[0].replaceAll("^\\[", "");
												}
												if(parts[1].endsWith("]")){
													parts[1] = parts[1].replaceAll("\\]"+"$", "");
												}
												char gender;
												if(parts[0].trim().startsWith("+")){
													gender = 'M';
												}
												else{
													gender = 'F';
												}
												String[] mparts = parts[1].split(",");
												morphAnalysis = "< " + parts[1].trim() + " >"; 
												MorphResult mr = new MorphResult(parts[0].trim(),mparts[1].trim(),"x",mparts[0].trim(),"x","x","x");
												MorphOutput2 mo2 = new MorphOutput2(srt,mr,(SuffixMorphsPair)null);
												morphs.add(mo2);												
												StemmedResult str = new StemmedResult(tempStem,lex.getFeatures(),morphAnalysis,suffix,"ordinal");//suffix,lex.getFeatures());
												str.setGender(gender);
								//				stemmedOutputs.add(str);
											}							
										}
									}
								}
							}
						}
					}
					// FOR VERBS 
					/* 
					 *  Here the steps are :
					 *  1. Imperative
					 *  	1.1 Readjustment
					 *  2. Conjunctive
					 *  3. Perfective
					 *  	3.1 Readjustment
					 *  4. AGR 2 					 *  	
					 *  	4.1 Future
					 *  		4.1.1 Subjunctive
					 *  			4.1.1.1 Readjustment
					 *  	4.2 Conditional / Infinitive
					 *  5. Subjunctive
					 *  	5.1 Readjustment
					 *  6. Readjustment					 *  
					 */					
				}
		// For Verbs ::
		HashMap<String, Vector<VerbRule>> verbRulesImperativeHash = lrr.verbRuleHash.get("Imperative");
		HashMap<String, Vector<VerbRule>> verbRulesPerfectiveHash = lrr.verbRuleHash.get("Perfective");
		HashMap<String, Vector<VerbRule>> verbRulesConjunctiveHash = lrr.verbRuleHash.get("Conjunctive");
		HashMap<String, Vector<VerbRule>> verbRulesAGR2Hash = lrr.verbRuleHash.get("AGR2");
		HashMap<String, Vector<VerbRule>> verbRuleFutureHash = lrr.verbRuleHash.get("Future");
		HashMap<String, Vector<VerbRule>> verbRuleSubjunctiveHash = lrr.verbRuleHash.get("Subjunctive");
		HashMap<String, Vector<VerbRule>> verbRuleConditionalHash = lrr.verbRuleHash.get("Conditional");
		HashMap<String, Vector<VerbRule>> verbRuleInfinitiveHash = lrr.verbRuleHash.get("Infinitive");
		HashMap<String, Vector<VerbRule>> verbRuleVauxHash = lrr.verbRuleHash.get("VAUX");
		//HashMap<String, Vector<VerbRule>> verbRulesImperativeHash = lrr.verbRuleHash.get("Imperative");
		
		// step 1 : Imperative		
		Set<String> suffixes = verbRulesImperativeHash.keySet();
		Iterator<String> suffixIter = suffixes.iterator();		
		while(suffixIter.hasNext()){
			String suffix = suffixIter.next().trim();
			//boolean hasSuffix = 
			if(suffix.equals("Null")){
				stem = token;
			}
			else if(token.endsWith(suffix)){
				stem = token.replaceAll(suffix+"$", "");				
			}
			else{
				continue;
			}
			Vector<Lex> lexVector = lr.getLexResults(stem,"verb");
			Vector<VerbRule> vrv = verbRulesImperativeHash.get(suffix);
			if(lexVector != null && !lexVector.isEmpty() && vrv != null && !vrv.isEmpty()){
				for(int rv = 0; rv<vrv.size(); rv++){
					VerbRule vr = vrv.get(rv);
					// lex and constraint check
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						if(vr.getConstraint().contains(lex.getFeatures().getEnding()) || vr.getConstraint().contains("X")){
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, vr.getMorphValues().get(0),null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,vr.getMorphValues(),(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);							
						}
					}
				}
			}
			lexVector = lr.getLexResults(stem,"verb_aux");			
			if(lexVector != null && !lexVector.isEmpty() && vrv != null && !vrv.isEmpty()){
				for(int rv = 0; rv<vrv.size(); rv++){
					VerbRule vr = vrv.get(rv);
					// lex and constraint check
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						if(vr.getConstraint().contains(lex.getFeatures().getEnding()) || vr.getConstraint().contains("X")){
							VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
							MorphResult mr = vr.getMorphValues().get(0).getMergedResult(vrVaux.getMorphValues().get(0));
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, mr,null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);							
						}
					}
				}
			}
			// step 1.1 : Readjustment
			Vector<VerbReadjustmentRule> vrrv = lrr.verbReadjustmentRuleHash.get("others");
			Vector<VerbReadjustmentRule> vrrv2 = lrr.verbReadjustmentRuleHash.get("agr1");
			if(vrrv2!=null && vrrv2.size()>0){
				vrrv.addAll(vrrv2);
			}
			String stem2 = "";;
			for(int rv = 0; rv < vrrv.size(); rv ++){
				VerbReadjustmentRule vrr = vrrv.get(rv);
				if(vrr.getSuffixToDelete().equals("Null")){
					stem2 = stem;
				}
				else if(stem.endsWith(vrr.getSuffixToDelete())){
					stem2 = stem.replaceAll(vrr.getSuffixToDelete()+"$", "");				
				}
				else{
					continue;
				}
				if(!vrr.getSuffixToAdd().equals("Null")){						
					stem2 = stem2 + vrr.getSuffixToAdd();						
				}
				lexVector = lr.getLexResults(stem2,"verb");
				if(lexVector != null && !lexVector.isEmpty()){
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);					
						if(vrr.getConstraints().contains(lex.getFeatures().getEnding())){
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, vrv.get(0).getMorphValues().get(0),null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,vrv.get(0).getMorphValues(),(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);
						}
					}
				}
				lexVector = lr.getLexResults(stem,"verb_aux");			
				if(lexVector != null && !lexVector.isEmpty()){					
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						if(vrr.getConstraints().contains(lex.getFeatures().getEnding())){
							VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
							MorphResult mr = vrv.get(0).getMorphValues().get(0).getMergedResult(vrVaux.getMorphValues().get(0));
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, mr,null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);					
						}					
					}
				}
			}
		}
		// step 2 : Conjunctive  :  currentlly only one rule : for "KAR"  look in Verb_New_Rules file
		suffixes = verbRulesConjunctiveHash.keySet();
		suffixIter = suffixes.iterator();		
		while(suffixIter.hasNext()){
			String suffix = suffixIter.next().trim();
			//boolean hasSuffix = 
			if(suffix.equals("Null")){
				stem = token;
			}
			else if(token.endsWith(suffix)){
				stem = token.replaceAll(suffix+"$", "");				
			}
			else{
				continue;
			}			
			Vector<VerbRule> vrv = verbRulesConjunctiveHash.get(suffix);
			Vector<Lex> lexVector = lr.getLexResults(stem,"verb");
			Vector<Lex> lexVectorVaux = lr.getLexResults(stem,"verb_aux");
			if(vrv != null && !vrv.isEmpty()){
				for(int rv = 0; rv<vrv.size(); rv++){
					VerbRule vr = vrv.get(rv);
					// lex and constraint check
					if(lexVector != null && !lexVector.isEmpty()){
						for(int lv=0; lv<lexVector.size(); lv++){
							Lex lex = lexVector.get(lv);
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, vr.getMorphValues().get(0),null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,vr.getMorphValues(),(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);						
						}
					}
					if(lexVectorVaux != null && !lexVectorVaux.isEmpty()){
						for(int lv=0; lv<lexVectorVaux.size(); lv++){
							Lex lex = lexVectorVaux.get(lv);
							VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
							MorphResult mr = vr.getMorphValues().get(0).getMergedResult(vrVaux.getMorphValues().get(0));
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, mr,null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);						
						}
					}
				}
			}
		}
		
		// step 3 : Perfective	
		suffixes = verbRulesPerfectiveHash.keySet();
		suffixIter = suffixes.iterator();		
		while(suffixIter.hasNext()){
			String suffix = suffixIter.next().trim();			 
			if(suffix.equals("Null")){
				stem = token;
			}
			else if(token.endsWith(suffix)){
				stem = token.replaceAll(suffix+"$", "");				
			}
			else{
				continue;
			}
			Vector<VerbRule> vrv = verbRulesPerfectiveHash.get(suffix);
			Vector<Lex> lexVector = lr.getLexResults(stem,"verb");
			Vector<Lex> lexVectorVaux = lr.getLexResults(stem,"verb_aux");
			if(vrv != null && !vrv.isEmpty()){
				for(int rv = 0; rv<vrv.size(); rv++){
					VerbRule vr = vrv.get(rv);
					// lex and constraint check
					if(lexVector != null && !lexVector.isEmpty()){
						for(int lv=0; lv<lexVector.size(); lv++){
							Lex lex = lexVector.get(lv);
							if(vr.getConstraint().contains(lex.getFeatures().getEnding()) || vr.getConstraint().contains("X")){
								StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
								MorphOutput mo = new MorphOutput(sr, vr.getMorphValues().get(0),null,null);
								MorphOutput2 mo2 = new MorphOutput2(sr,vr.getMorphValues(),(SuffixMorphsPair)null);
								morphs.add(mo2);
								morphOutputs.add(mo);
							}
						}
					}
					if(lexVectorVaux != null && !lexVectorVaux.isEmpty()){
						for(int lv=0; lv<lexVectorVaux.size(); lv++){
							Lex lex = lexVectorVaux.get(lv);
							VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
							MorphResult mr = vr.getMorphValues().get(0).getMergedResult(vrVaux.getMorphValues().get(0));
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, mr,null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);						
						}
					}					
				}
			}
			// step 3.1 : Readjustment
			Vector<VerbReadjustmentRule> vrrv = lrr.verbReadjustmentRuleHash.get("others");
			Vector<VerbReadjustmentRule> vrrv2 = lrr.verbReadjustmentRuleHash.get("agr1");
			if(vrrv2!=null && vrrv2.size()>0){
				vrrv.addAll(vrrv2);
			}
			String stem2 = "";
			for(int rv = 0; rv < vrrv.size(); rv ++){
				VerbReadjustmentRule vrr = vrrv.get(rv);
				if(vrr.getSuffixToDelete().equals("Null")){
					stem2 = stem;
				}
				else if(stem.endsWith(vrr.getSuffixToDelete())){
					stem2 = stem.replaceAll(vrr.getSuffixToDelete()+"$", "");				
				}
				else{
					continue;
				}
				if(!vrr.getSuffixToAdd().equals("Null")){						
					stem2 = stem2 + vrr.getSuffixToAdd();						
				}
				lexVector = lr.getLexResults(stem2,"verb");
				if(lexVector != null && !lexVector.isEmpty()){
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						if(vrr.getConstraints().contains(lex.getFeatures().getEnding())){
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, vrv.get(0).getMorphValues().get(0),null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,vrv.get(0).getMorphValues(),(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);
						}
					}
				}
				lexVector = lr.getLexResults(stem2,"verb_aux");
				if(lexVector != null && !lexVector.isEmpty()){
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						if(vrr.getConstraints().contains(lex.getFeatures().getEnding())){
							VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
							MorphResult mr = vrv.get(0).getMorphValues().get(0).getMergedResult(vrVaux.getMorphValues().get(0));
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, mr,null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);
						}
					}
				}
			}
			vrrv = lrr.verbReadjustmentRuleHash.get("perfective");
			for(int rv = 0; rv < vrrv.size(); rv ++){
				VerbReadjustmentRule vrr = vrrv.get(rv);				
				if(stem.equals(vrr.getSuffixToDelete())){
					stem2 = vrr.getSuffixToAdd();
				}
				else{
					continue;
				}
				System.out.println("Stem : " + stem2);
				lexVector = lr.getLexResults(stem2,"verb");
				VerbRule vr = vrv.get(0);
				MorphResult mr = new MorphResult(vr.getMorphValues().get(0));
				if(lexVector != null && !lexVector.isEmpty()){					
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						if(vrr.getMorphValue()!=null){						
							 mr = vr.getMorphValues().get(0).getMergedResult(vrr.getMorphValue());
						}
						StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
						MorphOutput mo = new MorphOutput(sr, mr, null, null);
						MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
						morphs.add(mo2);
						morphOutputs.add(mo);
					}
				}
				lexVector = lr.getLexResults(stem2,"verb_aux");
				if(lexVector != null && !lexVector.isEmpty()){
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						if(vrr.getMorphValue()!=null){						
							 mr = vr.getMorphValues().get(0).getMergedResult(vrr.getMorphValue());
						}
						if(verbRuleVauxHash.get(lex.getRoot()) == null){ System.out.println("Null hash value.." + lex.getRoot());}
						VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
						mr = mr.getMergedResult(vrVaux.getMorphValues().get(0));
						StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
						MorphOutput mo = new MorphOutput(sr, mr, null, null);
						MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
						morphs.add(mo2);
						morphOutputs.add(mo);
					}
				}
			}
		}
		
		// step 4 : AGR 2	
		suffixes = verbRulesAGR2Hash.keySet();
		suffixIter = suffixes.iterator();		
		while(suffixIter.hasNext()){
			String suffix = suffixIter.next().trim();
			VerbRule agr2Rule = verbRulesAGR2Hash.get(suffix).get(0);
			if(suffix.equals("Null")){
				stem = token;
			}
			else if(token.endsWith(suffix)){
				stem = token.replaceAll(suffix+"$", "");	
			}
			else{
				continue;
			}
			SuffixMorphsPair smpAgr2 = new SuffixMorphsPair(suffix, agr2Rule.getMorphValues());
			// Readjustment rule for AGR2
			Vector<VerbReadjustmentRule> vrrv = lrr.verbReadjustmentRuleHash.get("agr2");
			String stem2 = "";
			for(int rv = 0; rv < vrrv.size(); rv ++){
				VerbReadjustmentRule vrr = vrrv.get(rv);
				if(stem.equals(vrr.getSuffixToDelete())){
					stem2 = vrr.getSuffixToAdd();
				}
				else{
					continue;
				}
				Vector<Lex> lexVector = lr.getLexResults(stem2,"verb");
				if(lexVector != null && !lexVector.isEmpty()){
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						//if(vrr.getConstraints().contains(lex.getFeatures().getEnding())){
							MorphResult mr = agr2Rule.getMorphValues().get(0).getMergedResult(vrr.getMorphValue());
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, mr,null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);
						//}
					}
				}
				lexVector = lr.getLexResults(stem2,"verb_aux");
				if(lexVector != null && !lexVector.isEmpty()){
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						//if(vrr.getConstraints().contains(lex.getFeatures().getEnding())){
							MorphResult mr = agr2Rule.getMorphValues().get(0).getMergedResult(vrr.getMorphValue());
							VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
							mr = mr.getMergedResult(vrVaux.getMorphValues().get(0));
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, mr,null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);
						//}
					}
				}
			}
			// step 4.1 : Future
			String suffix1 = suffix;
			Set<String> fSuffixes = verbRuleFutureHash.keySet();
			Iterator<String> fSuffixIter = fSuffixes.iterator();
			while(fSuffixIter.hasNext()){
				Vector<SuffixMorphsPair> smpv = new Vector<SuffixMorphsPair>();			
				smpv.add(smpAgr2);
				String fSuffix = fSuffixIter.next().trim();
				Vector<VerbRule> vrfv = verbRuleFutureHash.get(fSuffix);
				if(vrfv != null && vrfv.size()>0 && stem.endsWith(fSuffix)){
					suffix = fSuffix + suffix;
					MorphResult mrF = agr2Rule.getMorphValues().get(0).getMergedResult(vrfv.get(0).getMorphValues().get(0));
					stem2 = stem.replaceAll(fSuffix+"$", "");
					SuffixMorphsPair smpFuture = new SuffixMorphsPair(fSuffix, vrfv.get(0).getMorphValues());
					smpv.add(smpFuture);
					Vector<Lex> lexVector1 = lr.getLexResults(stem2,"verb");
					if(lexVector1 != null && !lexVector1.isEmpty()){
						for(int lv=0; lv<lexVector1.size(); lv++){
							Lex lex = lexVector1.get(lv);
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, mrF, null, null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mrF,smpv);
							morphs.add(mo2);
							morphOutputs.add(mo);
						}
					}
					lexVector1 = lr.getLexResults(stem2,"verb_aux");
					if(lexVector1 != null && !lexVector1.isEmpty()){
						for(int lv=0; lv<lexVector1.size(); lv++){
							Lex lex = lexVector1.get(lv);
							VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
							MorphResult mrAux = mrF.getMergedResult(vrVaux.getMorphValues().get(0));
							MorphOutput mo = new MorphOutput(sr, mrAux, null, null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mrAux,smpv);
							morphs.add(mo2);
							morphOutputs.add(mo);
						}
					}
					// Readjustment
					Vector<VerbReadjustmentRule> vrrfv = lrr.verbReadjustmentRuleHash.get("future");
					String stem3 = "";
					for(int r = 0; r < vrrfv.size(); r ++){
						VerbReadjustmentRule vrr = vrrfv.get(r);
						if(stem2.equals(vrr.getSuffixToDelete())){
							stem3 = vrr.getSuffixToAdd();
						}
						else{
							continue;
						}
						MorphResult mrF2 = mrF.getMergedResult(vrr.getMorphValue());
						lexVector1 = lr.getLexResults(stem3,"verb");
						if(lexVector1 != null && !lexVector1.isEmpty()){
							for(int lv=0; lv<lexVector1.size(); lv++){
								Lex lex = lexVector1.get(lv);
								StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
								MorphOutput mo = new MorphOutput(sr, mrF2, null, null);
								MorphOutput2 mo2 = new MorphOutput2(sr,mrF,smpv);
								morphs.add(mo2);
								morphOutputs.add(mo);
							}
						}
						lexVector1 = lr.getLexResults(stem3,"verb_aux");
						if(lexVector1 != null && !lexVector1.isEmpty()){
							for(int lv=0; lv<lexVector1.size(); lv++){
								Lex lex = lexVector1.get(lv);
								VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
								StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
								MorphResult mrAux = mrF2.getMergedResult(vrVaux.getMorphValues().get(0));
								MorphOutput mo = new MorphOutput(sr, mrAux, null, null);
								MorphOutput2 mo2 = new MorphOutput2(sr,mrAux,smpv);
								morphs.add(mo2);
								morphOutputs.add(mo);
							}
						}
					}
					// step 4.1.1 : Subjunctive
					Set<String> subSuffixes = verbRuleSubjunctiveHash.keySet();
					Iterator<String> subSuffixIter = subSuffixes.iterator();
					while(subSuffixIter.hasNext()){
						String subSuffix = subSuffixIter.next().trim();
						Vector<VerbRule> vrsv = verbRuleSubjunctiveHash.get(subSuffix);
						if(stem2.endsWith(subSuffix)){
							suffix = subSuffix + suffix ;
							Vector<MorphResult> mrv = new Vector<MorphResult>();
							for(int m=0; m<vrsv.get(0).getMorphValues().size(); m++){
								MorphResult mrSub = mrF.getMergedResult(vrsv.get(0).getMorphValues().get(m));
								mrv.add(mrSub);
							}
							stem3 = stem2.replaceAll(subSuffix+"$", "");
							SuffixMorphsPair smpSub = new SuffixMorphsPair(subSuffix, vrsv.get(0).getMorphValues());
							smpv.add(smpSub);
							Vector<Lex> lexVector = lr.getLexResults(stem3,"verb");
							if(lexVector != null && !lexVector.isEmpty()){
								for(int lv=0; lv<lexVector.size(); lv++){
									Lex lex = lexVector.get(lv);
									if(vrsv.get(0).getConstraint().contains(lex.getFeatures().getEnding())){
										StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
										MorphOutput mo = new MorphOutput(sr, mrF, null, null);
										MorphOutput2 mo2 = new MorphOutput2(sr,mrv,smpv);
										morphs.add(mo2);
										morphOutputs.add(mo);
									}
								}
							}
							lexVector = lr.getLexResults(stem3,"verb_aux");
							if(lexVector != null && !lexVector.isEmpty()){
								for(int lv=0; lv<lexVector.size(); lv++){
									Lex lex = lexVector.get(lv);
									if(vrsv.get(0).getConstraint().contains(lex.getFeatures().getEnding())){
										StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
										VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
										Vector<MorphResult> mrvNew = new Vector<MorphResult>();
										for(int mri=0; mri<mrv.size(); mri++){
											MorphResult mr = mrv.get(mri);
											mr = mr.getMergedResult(vrVaux.getMorphValues().get(0));
											mrvNew.add(mr);
										}
										MorphOutput mo = new MorphOutput(sr, mrF, null, null);
										MorphOutput2 mo2 = new MorphOutput2(sr,mrvNew,smpv);
										morphs.add(mo2);
										morphOutputs.add(mo);
									}
								}
							}							
							// step 4.1.1.1 : Readjustment with constraints carried forward by Subjunctive rule.
							Vector<VerbReadjustmentRule> vrrvOthers = lrr.verbReadjustmentRuleHash.get("others");
							Vector<VerbReadjustmentRule> vrrv2 = lrr.verbReadjustmentRuleHash.get("agr1");
							if(vrrv2!=null && vrrv2.size()>0){
								vrrvOthers.addAll(vrrv2);
							}
							String stem4 = "";
							for(int rv = 0; rv < vrrvOthers.size(); rv ++){
								VerbReadjustmentRule vrr = vrrvOthers.get(rv);
								if(vrr.getSuffixToDelete().equals("Null")){
									stem4 = stem3;
								}
								else if(stem.endsWith(vrr.getSuffixToDelete())){
									stem4 = stem3.replaceAll(vrr.getSuffixToDelete()+"$", "");				
								}
								else{
									continue;
								}
								if(!vrr.getSuffixToAdd().equals("Null")){						
									stem4 = stem4 + vrr.getSuffixToAdd();						
								}
								lexVector = lr.getLexResults(stem4,"verb");
								if(lexVector != null && !lexVector.isEmpty()){
									for(int lv=0; lv<lexVector.size(); lv++){
										Lex lex = lexVector.get(lv);
										if(vrr.getConstraints().contains(lex.getFeatures().getEnding())){
											StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
											MorphOutput mo = new MorphOutput(sr, mrF,null,null);
											MorphOutput2 mo2 = new MorphOutput2(sr,mrv,(SuffixMorphsPair)null);
											morphs.add(mo2);
											morphOutputs.add(mo);
										}
									}
								}
								lexVector = lr.getLexResults(stem4,"verb_aux");
								if(lexVector != null && !lexVector.isEmpty()){
									for(int lv=0; lv<lexVector.size(); lv++){
										Lex lex = lexVector.get(lv);
										if(vrsv.get(0).getConstraint().contains(lex.getFeatures().getEnding())){
											StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
											VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
											Vector<MorphResult> mrvNew = new Vector<MorphResult>();
											for(int mri=0; mri<mrv.size(); mri++){
												MorphResult mr = mrv.get(mri);
												mr = mr.getMergedResult(vrVaux.getMorphValues().get(0));
												mrvNew.add(mr);
											}
											MorphOutput mo = new MorphOutput(sr, mrF, null, null);
											MorphOutput2 mo2 = new MorphOutput2(sr,mrvNew,smpv);
											morphs.add(mo2);
											morphOutputs.add(mo);
										}
									}
								}
							}							
						}
					}
				}
			}
			// step 4.2 : Conditional
			suffix = suffix1;
			Set<String> cSuffixes = verbRuleConditionalHash.keySet();
			Iterator<String> cSuffixIter = cSuffixes.iterator();
			while(cSuffixIter.hasNext()){
				String cSuffix = cSuffixIter.next().trim();
				Vector<VerbRule> vrcv = verbRuleConditionalHash.get(cSuffix);
				if(vrcv != null && vrcv.size()>0 && stem.endsWith(cSuffix)){
					suffix = cSuffix + suffix;
					Vector<SuffixMorphsPair> smpv = new Vector<SuffixMorphsPair>();			
					smpv.add(smpAgr2);
					Vector<MorphResult> mrv = new Vector<MorphResult>();
					//MorphResult mrC = agr2Rule.getMorphValues().get(0).getMergedResult(vrcv.get(0).getMorphValues().get(0));
					for(int m=0; m<vrcv.get(0).getMorphValues().size(); m++){
						MorphResult mrSub = agr2Rule.getMorphValues().get(0).getMergedResult(vrcv.get(0).getMorphValues().get(m));
						mrv.add(mrSub);
					}					
					stem2 = stem.replaceAll(cSuffix+"$", "");
					SuffixMorphsPair smpConditional = new SuffixMorphsPair(cSuffix, vrcv.get(0).getMorphValues());
					smpv.add(smpConditional);
					Vector<Lex> lexVector = lr.getLexResults(stem2,"verb");
					if(lexVector != null && !lexVector.isEmpty()){
						for(int lv=0; lv<lexVector.size(); lv++){
							Lex lex = lexVector.get(lv);
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, agr2Rule.getMorphValues().get(0), null, null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mrv,smpv);
							morphs.add(mo2);
							morphOutputs.add(mo);
						}
					}
					lexVector = lr.getLexResults(stem2,"verb_aux");
					if(lexVector != null && !lexVector.isEmpty()){
						for(int lv=0; lv<lexVector.size(); lv++){
							Lex lex = lexVector.get(lv);
							VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
							Vector<MorphResult> mrvNew = new Vector<MorphResult>();
							for(int mri=0; mri<mrv.size(); mri++){
								MorphResult mr = mrv.get(mri);
								//mr.print();
								mr = mr.getMergedResult(vrVaux.getMorphValues().get(0));
								//mr.print();
								mrvNew.add(mr);
							}
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, agr2Rule.getMorphValues().get(0), null, null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mrvNew,smpv);
							//mo2.printDetail();
							morphs.add(mo2);
							morphOutputs.add(mo);
						}
					}
				}
			}
			// step 4.3 : Infinitive
			suffix = suffix1;
			Set<String> iSuffixes = verbRuleInfinitiveHash.keySet();
			Iterator<String> iSuffixIter = iSuffixes.iterator();
			while(iSuffixIter.hasNext()){
				String iSuffix = iSuffixIter.next().trim();
				Vector<VerbRule> vriv = verbRuleInfinitiveHash.get(iSuffix);
				if(vriv != null && vriv.size()>0 && stem.endsWith(iSuffix)){
					suffix = iSuffix + suffix;
					Vector<SuffixMorphsPair> smpv = new Vector<SuffixMorphsPair>();			
					smpv.add(smpAgr2);				
					MorphResult mrI = agr2Rule.getMorphValues().get(0).getMergedResult(vriv.get(0).getMorphValues().get(0));
					stem2 = stem.replaceAll(iSuffix+"$", "");
					SuffixMorphsPair smpInfinitive = new SuffixMorphsPair(iSuffix, vriv.get(0).getMorphValues());
					smpv.add(smpInfinitive);
					Vector<Lex> lexVector = lr.getLexResults(stem2,"verb");
					if(lexVector != null && !lexVector.isEmpty()){
						for(int lv=0; lv<lexVector.size(); lv++){
							Lex lex = lexVector.get(lv);
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, mrI, null, null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mrI,smpv);
							morphs.add(mo2);
							morphOutputs.add(mo);
						}
					}
					lexVector = lr.getLexResults(stem2,"verb_aux");
					if(lexVector != null && !lexVector.isEmpty()){
						for(int lv=0; lv<lexVector.size(); lv++){
							Lex lex = lexVector.get(lv);
							VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
							mrI = mrI.getMergedResult(vrVaux.getMorphValues().get(0));
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",suffix,"verb_aux",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, mrI, null, null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mrI,smpv);
							morphs.add(mo2);
							morphOutputs.add(mo);
						}
					}
				}
			}			
		}
		
		// step 5 : Subjunctive
		Set<String> subSuffixes = verbRuleSubjunctiveHash.keySet();
		Iterator<String> subSuffixIter = subSuffixes.iterator();		
		while(subSuffixIter.hasNext()){
			String subSuffix = subSuffixIter.next().trim();
			//Vector<VerbRule> vrsv = verbRuleSubjunctiveHash.get(subSuffix);
			VerbRule vrs = verbRuleSubjunctiveHash.get(subSuffix).get(0);
			if(subSuffix.equals("Null")){
				stem = token;
			}
			else if(token.endsWith(subSuffix)){
				stem = token.replaceAll(subSuffix+"$", "");	
			}
			else{
				continue;
			}			
			Vector<Lex> lexVector = lr.getLexResults(stem,"verb");
			if(lexVector != null && !lexVector.isEmpty()){
				for(int lv=0; lv<lexVector.size(); lv++){
					Lex lex = lexVector.get(lv);
					if(vrs.getConstraint().contains(lex.getFeatures().getEnding())){
						StemmerResult sr = new StemmerResult(lex.getRoot(),"",subSuffix,"verb",lex.getFeatures().getEnding());
						MorphOutput mo = new MorphOutput(sr, vrs.getMorphValues().get(0),null,null);
						MorphOutput2 mo2 = new MorphOutput2(sr,vrs.getMorphValues(),(SuffixMorphsPair)null);
						morphs.add(mo2);
						morphOutputs.add(mo);
					}					
				}
			}
			lexVector = lr.getLexResults(stem,"verb_aux");
			if(lexVector != null && !lexVector.isEmpty()){
				for(int lv=0; lv<lexVector.size(); lv++){
					Lex lex = lexVector.get(lv);
					if(vrs.getConstraint().contains(lex.getFeatures().getEnding())){
						VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
						MorphResult mr = vrs.getMorphValues().get(0).getMergedResult(vrVaux.getMorphValues().get(0));
						StemmerResult sr = new StemmerResult(lex.getRoot(),"",subSuffix,"verb_aux",lex.getFeatures().getEnding());
						MorphOutput mo = new MorphOutput(sr, mr,null,null);
						MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
						morphs.add(mo2);
						morphOutputs.add(mo);
					}					
				}
			}
			// step 5.1 : Readjustment with constraints carried forward by Subjunctive rule.
			Vector<VerbReadjustmentRule> vrrvOthers = lrr.verbReadjustmentRuleHash.get("others");
			Vector<VerbReadjustmentRule> vrrv2 = lrr.verbReadjustmentRuleHash.get("agr1");
			if(vrrv2!=null && vrrv2.size()>0){
				vrrvOthers.addAll(vrrv2);
			}
			String stem2 = "";
			for(int rv = 0; rv < vrrvOthers.size(); rv ++){
				VerbReadjustmentRule vrr = vrrvOthers.get(rv);
				if(vrr.getSuffixToDelete().equals("Null")){
					stem2 = stem;
				}
				else if(stem.endsWith(vrr.getSuffixToDelete())){
					stem2 = stem.replaceAll(vrr.getSuffixToDelete()+"$", "");				
				}
				else{
					continue;
				}
				if(!vrr.getSuffixToAdd().equals("Null")){						
					stem2 = stem2 + vrr.getSuffixToAdd();						
				}
				lexVector = lr.getLexResults(stem2,"verb");
				if(lexVector != null && !lexVector.isEmpty()){
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						if(vrs.getConstraint().contains(lex.getFeatures().getEnding())){
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",subSuffix,"verb",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, vrs.getMorphValues().get(0),null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,vrs.getMorphValues(),(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);
						}					
					}
				}
				lexVector = lr.getLexResults(stem2,"verb_aux");
				if(lexVector != null && !lexVector.isEmpty()){
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						if(vrs.getConstraint().contains(lex.getFeatures().getEnding())){
							VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
							MorphResult mr = vrs.getMorphValues().get(0).getMergedResult(vrVaux.getMorphValues().get(0));
							StemmerResult sr = new StemmerResult(lex.getRoot(),"",subSuffix,"verb_aux",lex.getFeatures().getEnding());
							MorphOutput mo = new MorphOutput(sr, mr,null,null);
							MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
							morphs.add(mo2);
							morphOutputs.add(mo);
						}					
					}
				}				
			}
		}
		
		// step 6 : Readjustment
		Vector<VerbReadjustmentRule> vrrv = lrr.verbReadjustmentRuleHash.get("direct");
		Vector<VerbReadjustmentRule> vrrv2 = lrr.verbReadjustmentRuleHash.get("future");
		if(vrrv2!=null && vrrv2.size()>0){
			vrrv.addAll(vrrv2);
		}
		for(int rv = 0; rv < vrrv.size(); rv ++){
			VerbReadjustmentRule vrr = vrrv.get(rv);			
			if(vrr.getSuffixToDelete().equals(token.trim())){
				stem = vrr.getSuffixToAdd();
				MorphResult mr = new MorphResult(vrr.getMorphValue());
				Vector<Lex> lexVector = lr.getLexResults(stem,"verb");				
				if(lexVector != null && !lexVector.isEmpty()){
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);						
						StemmerResult sr = new StemmerResult(lex.getRoot(),"","","verb",lex.getFeatures().getEnding());
						MorphOutput mo = new MorphOutput(sr, mr, null, null);
						MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
						morphs.add(mo2);
						morphOutputs.add(mo);
					}
				}
				lexVector = lr.getLexResults(stem,"verb_aux");				
				if(lexVector != null && !lexVector.isEmpty()){
					for(int lv=0; lv<lexVector.size(); lv++){
						Lex lex = lexVector.get(lv);
						VerbRule vrVaux = verbRuleVauxHash.get(lex.getRoot()).get(0);
						mr = mr.getMergedResult(vrVaux.getMorphValues().get(0));
						StemmerResult sr = new StemmerResult(lex.getRoot(),"","","verb_aux",lex.getFeatures().getEnding());
						MorphOutput mo = new MorphOutput(sr, mr, null, null);
						MorphOutput2 mo2 = new MorphOutput2(sr,mr,(SuffixMorphsPair)null);
						morphs.add(mo2);
						morphOutputs.add(mo);
					}
				}
			}
		}
						
		//retVal.addAllStemmerOutputs(stemmedOutputs);
		retVal.setMorphOutputs(morphs);
		return retVal;
	}
		
	
	public static void main(String args[]){
		System.out.println("Starting..");
		ConfigReader.read(args[0]);
		NewStemmer stemmer = new NewStemmer();
		String sentence = "किया गया";//कर";//सकती";//"माँ को अपने बेटे और किसान को अपने लहलहाते खेत देखकर जो आनंद आता है , वही आनंद बाबा भारती को अपना घोड़ा";//लड़का लड़कियाँ लड़के जीतना";
		//sentence = "मारे";//लें";//सकेगा";//दीजिये जलाएँगे बनाएंगे होंगे";//लिया";//आएगा";// होंगे";//लगाया थे"//होगा खेलेगी";//खेलेंगे";//था";//करने";//करना";//पड़";//लगता";//है";//पाँचवीं";//पांचवीं";//काफी उतना उतने";// खिलाड़ी खिलाड़ी";//घोड़े";//घोड़ा";//बहुएँ बहुएं बहुयें";//माताएं माताएँ मातायें";//बहुएँ धमाके";//बच्चों//अंधेरा";//अंगूरी";//छापे ";//नालों";//दौरे";//;
		String words[] = sentence.split(" ");
		MAResult mar;
		for(int i =0; i<words.length; i++){
			String word = words[i].trim(); 
			if(words[i].equals("") || words.equals(" ")){
				continue;
			}
			//st = stemmer.stem(word);
			//st.print();
			mar = stemmer.stem(word);
			//mar.printDetail();
			System.out.println("\n-------------------Final output---------------------- ");
			mar.printDetail();
			System.out.println();
		}
		
	}
	
}
