Salve,mi viene dato java.lang.IndexOutOfBoundsException nel metodo ordina lista della classe contenitorePigEwu,precisamente nelle righe con commento errore,non riesco a capire il perchè...help mee

codice:


class MainStatico{
	
	public static void main(String args[]) throws IOException{
	    MaterialePerK matPerK[]= new MaterialePerK[16];
		   //ricordarsi di impostare le celle boggle! 
	        
	        int Adiac0 []={1,4,5};
		     matPerK[0]= new MaterialePerK(new CellaBoggle(0, 0),Adiac0 );
			
		    int Adiac1[]={0,4,5,6,2};
			 matPerK[1]= new MaterialePerK(new CellaBoggle(0, 1),Adiac1 );

			 int Adiac2[]={1,5,6,3,7};	
			 matPerK[2]= new MaterialePerK(new CellaBoggle(0, 2),Adiac2 );
			 
			 int Adiac3[]={2,6,7};
			  matPerK[3]= new MaterialePerK(new CellaBoggle(0, 3),Adiac3 );
		
			 int Adiac4[]= {0,1,5,9,8};
			   matPerK[4]= new MaterialePerK(new CellaBoggle(1, 0),Adiac4 );

			   
			 int Adiac5[]= {4,0,1,2,6,10,9,8};
			 matPerK[5]= new MaterialePerK(new CellaBoggle(1, 1),Adiac5 );	
			 
			 int Adiac6[]={5,1,2,3,7,11,10,9};
			 matPerK[6]= new MaterialePerK(new CellaBoggle(1, 2),Adiac6 );	
			 
	 		 int Adiac7[]={3,2,6,10,11};
			 matPerK[7]= new MaterialePerK(new CellaBoggle(1, 3),Adiac7 );	
			 
			 int Adiac8[]={4,5,9,13,12};		 
			 matPerK[8]= new MaterialePerK(new CellaBoggle(2, 0),Adiac8 );	
			 
			 int Adiac9[]={8,4,5,6,10,14,13,12};		
			 matPerK[9]= new MaterialePerK(new CellaBoggle(2, 1),Adiac9);	
			 
			 int Adiac10[]={9,5,6,7,11,15,14,13};
			 matPerK[10]= new MaterialePerK(new CellaBoggle(2, 2),Adiac10);
			 
			 int Adiac11[]={7,6,10,14,15};
			 matPerK[11]= new MaterialePerK(new CellaBoggle(2, 3),Adiac11);
			 
	         int Adiac12[]={8,9,13};		 
	         matPerK[12]= new MaterialePerK(new CellaBoggle(3, 0),Adiac12);
			 
	         int Adiac13[]={12,8,9,10,14};	
	         matPerK[13]= new MaterialePerK(new CellaBoggle(3, 1),Adiac13);
			 
	         int Adiac14[]={13,9,10,11,15};	
	         matPerK[14]= new MaterialePerK(new CellaBoggle(3, 2),Adiac14);
	 		   
	         int Adiac15[]={11,10,14};
	         matPerK[15]= new MaterialePerK(new CellaBoggle(3,3),Adiac15);
            
	         ContenitorePigEwu C= new ContenitorePigEwu();
	         GrafoBoggle Gr= new GrafoBoggle(matPerK,C);
	         LeggiPreparaM L= new LeggiPreparaM(Gr);
	          L.LeggiRigheM();
}	

 static class CellaBoggle {
    private int Righe,Col;
	
	public CellaBoggle(int r,int c){
       Righe=r;  Col=c;		
	}
	int getRiga(){ return Righe;  }
	int getCol(){  return Col;    }
	
	void setRiga(int r){Righe=r;  }
	void setCol(int c){ Col=c;    }
 }

 static class MaterialePerK {
	    private int NodiAdiacenti[];
		private CellaBoggle C;
		
		public MaterialePerK(CellaBoggle cb,int adiac[]) {
	      C=cb; 
		   NodiAdiacenti= adiac;
		}
		
		CellaBoggle getCellaBoggle(){ 
			return C; }
		

		void setArrayAdiac(int ind,int val){
			NodiAdiacenti[ind]=val;
		}

	    int [] getArrayAdiac(){
	    	return NodiAdiacenti;
	    }

	}


 static class LeggiPreparaM {
   
 	private GrafoBoggle Gr;
 	private String Riga;	
 	private char B1[][];
     private char B2[][];
     private StringTokenizer st;
     private BufferedReader In_Str;
     private String pattern = "([A-Z] ){3}[A-Z]{1}(\t)+([A-Z] ){3}[A-Z]";
     private Pattern p = Pattern.compile(pattern);
     
    LeggiPreparaM(GrafoBoggle G) {
     Riga="";    B1=new char[4][4];    B2=new char[4][4];   st=null;   
     In_Str = new BufferedReader(new InputStreamReader(System.in));  Gr=G;
 	}

 	 char[][] getB1() {
 		return B1;
 	}
 	
 	 char[][] getB2() {
 		return B2;
 	}
 	
     void LeggiRigheM()throws IOException{
       int R;   boolean cicla=true;
 	  while(true){	
 		    	R=0;
 			    while(R<4){
                      try{
 			    	   Riga=In_Str.readLine();
                    	
 			    	   if(Riga.equals("#") )
                               return ;   
                   
                      }catch (IOException e) {
  					     return ;
                      }
 	    					    System.out.println();
          						    st= new StringTokenizer(Riga," 	");
 						      AssegnaRiga(B1,R,0);
 						      AssegnaRiga(B2,R,0);
 			    R++;
 			    }
 		          Gr.TrovaParolePigEwu(getB1(),false);
 		             Gr.getContenitoreParole().ordinaVettore();
 		           if(Gr.TrovaParolePigEwu(getB2(),true))
 		        	   Gr.getContenitoreParole().stampaParoleInComune();
      		       else{
 		               System.out.println("There are no common words for this pair of boggle boards");
  		               System.out.println();  
 	        	       }  
 		     
 		        Gr.getContenitoreParole().rimuoviVettore();   
                Gr.getContenitoreParole().allocaVettore();
                Gr.getContenitoreParole().setCiSonoComuni(false);
 	  }	
  }

         void AssegnaRiga(char B[][],int R,int C1){
 		   while(st.hasMoreTokens() && C1<4){
         	         B[R][C1] = st.nextToken().charAt(0);
         	C1++;
            }
             return ;
 	}

 	
 }
  
  static class ParolaPigEwu{

		private String parola;
		private boolean stampare;

		ParolaPigEwu(String p) {
	        stampare=false;
	        parola=p;
		}
		
		 String getParola() {
			return parola;
		}
		 void setParola(String parola) {
			this.parola = parola;
		}
	    
		 void setStampare(boolean stampare) {
		this.stampare = stampare;
	    }
		 
		boolean getStampare(){
			return stampare;
		}             
	 
  }
 
  

  static class ContenitorePigEwu {
  	private Vector<ArrayList<ParolaPigEwu>>  parole = new Vector<ArrayList<ParolaPigEwu>>(30); 
  	private boolean ciSonoComuni;
  	private ArrayList<ParolaPigEwu>  copiaParole;
  	private ArrayList<ParolaPigEwu>  p;
  
  	 ContenitorePigEwu(){
  		for(int i=0 ; i<30 ;i++)
  	       parole.insertElementAt(new ArrayList<ParolaPigEwu>(),i);
  	   ciSonoComuni=false;
  	 }
  	
  	 boolean ciSonoComuni(){
  		 return ciSonoComuni;
  	 }
  	 
  	 void setCiSonoComuni(boolean p){
  	     	 ciSonoComuni=p;
  	 }

  	 void rimuoviVettore(){
  		for(int i=0 ;i<parole.size();i++)
  		     parole.remove(i);
  	}

  	void allocaVettore(){
  		for(int i=0 ; i<30 ;i++)
   	       parole.insertElementAt(new ArrayList<ParolaPigEwu>(),i);
  	}

  	void inserInOrdineParolaDatoUnaCella(String parola){
     	 int indVett= parola.charAt(0)-66;
  	    parole.get(indVett).add(new ParolaPigEwu(parola));
  	}
  	
  	void ordinaVettore(){
	       for(int i=0 ;i< parole.size() ; i++){
	  		 p=parole.get(i);
	  	   copiaParole= new ArrayList<ParolaPigEwu>(p.size());
	  	        ordinaLista(0, p.size());  
	  	        p.clear(); copiaParole.clear();
	       }
  	}
  	
  //*******************************  java.lang.IndexOutOfBoundsException 
  	void ordinaLista(int inizio,int fine){
  	  System.out.println("* inizio * "+inizio +" *  fine  *"+fine);
  		
  		if(inizio<fine){
        	 int meta=(inizio+fine)/2;
        	 ordinaLista(inizio,meta); //ERRORRE
        	 ordinaLista(meta+1, fine);//ERRORE
        	 fusione(inizio,meta,fine);//ERRORE
         }
  		
  	}
  	
   void fusione(int low, int middle, int high) {
				for (int i = low; i <= high; i++) {
					copiaParole.add(i, p.get(i));
				}
				
		int i = low;
		int j = middle + 1;
		int k = low;
                 
		while (i <= middle && j<= high){
			    if((copiaParole.get(i).getParola()).compareTo(p.get(j).getParola())<0){
                   p.set(k,copiaParole.get(i));			
			       i++;
			    }
			    else{
			        p.set(k,copiaParole.get(j));			
				    	j++;
			    }
				k++;
		}
		   	
		while (i <= middle) {
			p.set(k, copiaParole.get(i)) ;
			k++;
			i++;
		}
	   
		   
	   
   }//

void cercaComuni(String parola2matr){
		  int indVett= parola2matr.charAt(0)-66;
	    if(parole.get(indVett).size()!=0){
		  int left, right; 
	         left = 0; 
			    right =parole.get(indVett).size();
	         
			    while (left!=right-1) {
			    	int m = (right+left)/2  ; 
			 
			    	String sm = parole.get(indVett).get(m).getParola();
			     
			    	if(sm.compareTo(parola2matr)<0) 
			            left = m; 
			        
			        else if (sm.compareTo(parola2matr)>0) 
			         right = m; 
			        else { //(4) 
			         left = m;  
			         right = m+1; 
			           }
			   }
	         
			    if(parola2matr.equals(parole.get(indVett).get(left).getParola()) ){
			    	parole.get(indVett).get(left).setStampare(true);
			    	ciSonoComuni=true;
		 	    } 
		}
	    
   }
      

   void stampaParoleInComune(){
  	     for(int i=0 ; i<parole.size() ; i++ ){
  	    	  for( int k=0; k<parole.get(i).size();k++){
	  	    		  if(parole.get(i).get(k).getStampare()==true){
	  	    		     System.out.println(parole.get(i).get(k).getParola());
	  	    			    System.out.println();
	  	    		  }	    
  	    	  }
  	    	 
  	     } 
    }
  	
   
   
   
   
   
  }

  
   static class GrafoBoggle {

     private   HashMap<Integer,MaterialePerK> GrafoTavola =new HashMap<Integer, MaterialePerK>(16, 16) ;
     private MaterialePerK matPerK[];
     private  ContenitorePigEwu contenitoreParole;
   
    GrafoBoggle(MaterialePerK mater[],ContenitorePigEwu cp){
    	contenitoreParole=cp;
              matPerK=mater;
              for(int k=0 ;k<16 ; k++) 
    	          GrafoTavola.put(k, matPerK[k]);
        
    }
        
    public ContenitorePigEwu getContenitoreParole() {
		return contenitoreParole;
	}

    boolean TrovaParolePigEwu(char B[][],boolean ConfrontoP){
     	int contaVoc;
     	int Nodo_K=0; 
         	while(Nodo_K<16){
         		contaVoc=0;
         		
           if(! CeVocaleAlNodo(Nodo_K,B) ){
         	
        	   for(int i=0; i<GrafoTavola.get(Nodo_K).getArrayAdiac().length;i++) {
         			int Nodo_K2=GrafoTavola.get(Nodo_K).getArrayAdiac()[i];
             			if(CeVocaleAlNodo(Nodo_K2,B)) contaVoc++;
         				 
 				             for(int u=0; u< GrafoTavola.get(Nodo_K2).getArrayAdiac().length;u++) {
 				        	       int Nodo_K3 = GrafoTavola.get(Nodo_K2).getArrayAdiac()[u];  				    	
 				        	           if(CeVocaleAlNodo(Nodo_K3,B)) contaVoc++;
 				        	        
 				        	       if(Nodo_K3!=Nodo_K ) {   
 				        	    	   
    				    	                  for(int y=0 ; y< GrafoTavola.get(Nodo_K3).getArrayAdiac().length;  y++){
 				    	            	
    				    	                	  int Nodo_K4= GrafoTavola.get(Nodo_K3).getArrayAdiac()[y];  				    	
 				    	            	          if(CeVocaleAlNodo(Nodo_K3,B)) contaVoc++;
 				    	            	             if(contaVoc!=3){ 
 						        	   	                if( Nodo_K4!=Nodo_K2 && Nodo_K4!=Nodo_K){
 						        	   	                	
 						   	String s = new StringBuilder().append(ConvertiNodoLettera(Nodo_K, B)).append(ConvertiNodoLettera(Nodo_K2, B)).
 						    append(ConvertiNodoLettera(Nodo_K3, B)).append(ConvertiNodoLettera(Nodo_K4, B)).toString();	 
 						        	   	 
 						        	   	                   if(!ConfrontoP)  
 						        	   	contenitoreParole.inserInOrdineParolaDatoUnaCella(s);
 						        	   	                	   else{
 						        	   	contenitoreParole.cercaComuni(s);   
 						        	   	                	   }
 						        	   	                }
 				    	                  
 				    	            	             }
    				    	                  
    				    	                  }
 					                 }
 					  
 				            }
 					     
         		}
           } 		    
         		
       		  Nodo_K++;
             }
        if(contenitoreParole.ciSonoComuni()) 
        	return true; 
        return false;
         	
    }	
    
         char ConvertiNodoLettera(int kN,char B[][]){
 	       CellaBoggle Cb= GrafoTavola.get(kN).getCellaBoggle();
 	         int R=Cb.getRiga();  int C=Cb.getCol();
 			    return B[R][C];
      	 }

    boolean CeVocaleAlNodo(int Nodo_K,char B[][]){
 	   CellaBoggle Cb=	GrafoTavola.get(Nodo_K).getCellaBoggle();
 	     int R=Cb.getRiga();  int C=Cb.getCol();
 	     
 	     switch( B[R][C] ){
 				   	  case 'A': return true ;
 				   	  case 'Y': return true;
 				   	  case 'E': return true;
 				   	  case 'O': return true;
 				   	  case 'I': return true;
 				   	  case 'U': return true;
 	     };
            return false;
    }
 

 }
		
}