Skip to main content
summaryrefslogblamecommitdiffstats
blob: 29264acf1cc86aa78b281c9ae1267cfa00628ee5 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
                                                                                
                                                       









                                                                                 
                               

                           
                                   
                                

                               

                          




                                
                                              

                                                 

                                             
                                       
                                         
                                                             




                                              

                                            
                                                     
                                                   
                                                        


                                                

                                                         
                                      
                                                  

                                                   
                                             


                                                    

                                                    
                                            
                                            
                                                              


                                                                         




                                                               

                                                                  
                                                  








                                                           
                           
                                         










                                                
                                    




                                                  
                                       
                                  
                                       
                                    
                                          
                                                




                                                             
                                                
                                             
                                                             
                                     



                                                                   
                                              





                                                                
                                                  


                                                               
                                                       
                                                                           
                                                                  
                                                                         
                                                                      
                                                                   
                                                                              
                                                                                  
                                                                      
                                                                    
                                                                         
                                                  









                                                                       
                                                            


                                                                 

                                                                                   
                                                                                     
                                                                              



                                                                    
                                                                     
                                                                 



                                                                              
                                                                     
                                                                         
                                                                                 
                                                                                
                                                                       
                                                                                           
                                                                                      
                                                                                                    
                                                                  

                                                                      
                                                                               
                                                                          
 
   











                                                                               

   
                                                      




                                                                           















                                                                                          

                                                                                                    




































                                                                                                                      
 
                                                                                 

                                                                           
                                                                    




                                                                                           
                                                                    
                                                              




                                                                  
                                                                   
























                                                                                             
                                                                                                       
                                                                         
                                 

                                             


                                                                                                                       

                                 




























                                                                                                             

                              


































































                                                                                                             

















                                                                                                                             

                                                                                                     
                                                                                                            


                                                                                             
                                                                                                    
                                                 



                                                                                               




























                                                                                                                                                                                                               
                                               





                                                                                                                                
                                                                                      
                                                                  

                                                                                                         
                                                                   
                                                                                           

                                                                                                                     






                                                                                                                                                                    



                                                                                                             

















                                                                                                                                                                                               

                                                                         








                                                                                                    
                                                                       





                                                                            












                                                                                  





                                                                            
                                                                                                                 





                                                                                      


                                                                                                                                    
 







                                                                                                                                           

                         









                                                                                                                                           


                                                         
                                                                                      

                                                                                                    
 









                                                                                                                              


                                                                                                             


                                                                                   

                                                                                                








                                                                                                                                                     
                                                                                                       
                                                 

                                         

                                                                                
                                 
                                                               


                                                  
                                                                                                               






                                                           
                                                                      


                                                   
                                                               


                                              
                                                                              


                                                  













































































































































































































                                                                                                                                                                                 


                         

                                                                  


                                                                        


                                                                                       

                                                 
 
                                                                                                                           
                                                         
                                                                             



                                                                                                                                           


























                                                                                                                                            
                                                                   












                                                                          



                                                                 





                                                                                                                  








                                                                                                                                  



                                         







                                                                                 
                                                                              






                                                                                                                               
                                                                            





                                                                                                   


                                                                          






                                                                                                                               

                 








                                                                          




                                                              










                                                                                                        
                         
                                      













                                                                                                    
 



                                                                 

                                                                              



                                                                                     











                                                                                                                  





                                                                                                                                               














                                                                                                                                          



                                                                 
                                                                                           
                                                                      

                                                                                             






                                                                                                                                               



                                                                                     






                                                                                                                                       


                                                 
                                                         
                                                                                                                                     
                                         
                                 

                                       
                 



                                                                   


                                                
                                   





                                                                                               
                 
 



                                              
                                                                         


                                                                                                          
                                                
                 
 



                                             

                                                                             
                 

         
           
























































































































                                                                                                                                                                                     

                                                 
                                                                                
 
                                                          


                                                 
                                                              
                                                                                                                                       
                                                                                                       
                              
                                                                                                                                  


                                                 
                                                                                    


                                                 
                                                                              


                                                 
                                                                                      
 



                                                                                                                                                       
                                                                                                                                     
                                                                                                     
 
                                                                   
                                   
                                                                                                                 
 


                                                                                                                                                       

                                                
 





                                                  

                                                             
                                        
                                        
                                                            
                                                                       
                                           
                                                 

                                                                



                                                                       
                                                      
                                      




                                                             
                                                                         
 
                                                     
                                                  
                                                                        



                                                            
                                                    

                                                   

                                                           
                                               

                        
 

                                            
                                    



                                                 
 


                                                
                                       



                                                 





                                                                
                                                                                  
                                                                               
                                                                                 






                                                                                



                                                                                                                           
                                                                                                                


                                                                                                                 

                      

                                                                                                                
 
                                                   
                                                                                                      

                                                                                                                                     










                                                                                                                                                                                                      
                                                                                               









                                                                                                                                                 
                                                                                               

         
                                                                       


                                                                                          

                      












                                                                                                          

 
           
                                  


                                                 
           
                                         








                                                                       












                                                                                










                                                                             



                                                                    

                                               



                                                                            




                                                                      

                      







                                                                                                       

                              




                                                  










































                                                                                                                            
           
                                                                     
           
                                                       





                                                                                                                                                                                         








                                                                                                                                                            
                                                                                                                                                          





                                                                      
                                                                                  
                                                                                                          




                                                                
                                                                                                                                           

                                                                                
                                                                                         





                                                               
                                                                                                                                        

                                                                                  
                                                                                           






                                                                  
                                                                                                                                          

                                                                                   
                                                                                            


                                                                
                                                                                                                                                                                                     
                                                                                                                                                                                                  





                                                                                                              
                                                                                                                                                                                                          
                                                                                         





                                                                                                                          
                                                                                                                                                                                                                                           





                                                                                                                                    
                                                                                                                                                                                     





                                                                                                            
                                                                                                                                                                                           
                                                                                      






                                                                                                                      
                                                                                                                                                                                                         
                                                                                           



                                                                                                                             


                                                                                     
                                                                              
                                                                          






                                                                              
                                                                                                                                                                  


                                                                                             

                                                 
                                                                   
                                                                                

         
                                                       





































                                                                                                                         
                                                                                                



                                                                                                           
                                                                                 



                                                                                                  
                                                                                                                                                       



                           















                                                                                                                                                                                 




                                                     

                        

                                                                                 
               

                                                                                                                          

                                                         
                                                             

                                                                                       
                                                                                                          
                                                                             
                 


                                                


                                                                                     







                                                                                                          












                                                                                                                                          
         
 




                                                                                                  
                                                                                                                                                     









                                                                                 
                                                  



                                                                                                  


                                                                                                                         

                                                                                   
                                                                              
                                                                                  
                                                                          



















                                                                           

                                                                        


                                                                                                  
                                                                                                                          


                                                                         
                                                                                 
                 
                                                   
                     
                                                                                                                                    




                                                 

                                                                                                                                   




                                                         

                                                                                                                                   
                                                         

                         









                                                                                                                                

                 













                                                                                                                

                                                                          



                                                                                                  

                                                                                                                                                           


                                                                      

                                                                                          
                 
                           

         



                                                                                                                             














                                                                                                                                               



                                                       


                                                                                                                 
                                                                                               




                                                                                                                      





                                                        
                                               




                                                    










                                                            




                                                






                                                              

















                                                                                              






                                                                   


                                                                                                                               
                                                                                                   

                 


                                                                                    



                                                                                         
 










                                                                                                                                

                                              














                                                                   
 

                                                                                                                



                        


                                                                                               
                                                                                                                     
                                                           
                                           


                                                





                                                                               
                                                    


                                     



                                                                       


                                        
                                                                              
                                                          





                                                                                               
 



                                   




                                                                                              
                                                              
                     
                                           
                                                
                                                      

                         
                                     
                 

         






                                                                                                    









                                                                                                    
                                                                                                             




                                                                   


                                                                                                                             

                         
                                                      
                                                                             




                                                                                                            

                              
                                                                                 
                                                                                  

                                                                                                                                            



                                                                              
                                                                         






                                                                        
                                                         



                                                                                                                  
                         
 


                                                                     

                                                              

                                                 








                                                                        


                                                                     














                                                                     

                                                            






                                                               
                               


                                                 
           
                                       






                                                                            















                                                                                      

                      















                                                                                          




                                                                               
                                                  
                                                                                               



                                                                   
                                                                    

                                                         

                                                                                
                                                                                                         





                                                                                                                                  
                                                                                                                          
                                                                          
                                                                    


                                                                                                                                    







                                                                                                      




                                                                   
                                                                        
                                                                                     


                                                                                                                                                    

                                                                                                                              



                                                                               
                 


                                                                                     
                                                                          
                                                                

                                                                           
                                                                       

                                                                    
                                                             
                 




                                                                               
                      

                                                                            




                                                                    
                                                                                               



                                                               
                                                                                               






                                                                                                                      
                                                   
                                                      
                                                 
                                                                                                
                 



                                                                                                                                                                           











                                                                                                                                                

                      




                                                     
 



                                                              







                                                 





                                            


                                                                                   
                 
                                                 

         
                                             


                                        






                                                                                       
           





                                                         





                                                                                  

                                            

                                                                      
                                                                                                                                                             




                                                 

                                                                                      

                                                                                                                       
                                                    

                              
                                                                                                    
                                                                         


                                                                                                                                            

                                                                 
                                                            
                                 
                         


                                                                                        


                                                                           



















                                                                                             
 




                                                                              
                                     
                                                                      

                                         
 




                                                                            



                                                                                         
                                                                                                                     







                                                            


                                                                                


                                                 






                                                                




                                                                                          




                                                                                              







                                                                                                                                     
                                                                                         

                                              















                                                                                                                              


                                                          



                                       





                                                                           





                                                                                         

                      



                                                








                                                     
                                                                                    


                                                              




                                                                                     
                                                                        






                                                                     




                                                                                        
















                                                                                           
                                                                



                                                                           



                                                                                               

                                     












                                                                                       
                                                                              

         




                                                                                  







                                                                                                                                                                   





                                                                                   



                                                                                    

         







                                                                            




                                                                               


                                                            
                                                  

         































                                                                                                                                       
           







                                                                             
                                                                                          

         
                                                                    











                                                                                                                                                                                                                                 
















                                                                                                                       
                                                                                                                                                               


                                                                                                                      






















                                                                                          

                         



                                                         
           



                                                                     

                                         



                                                                          


                                          
 
           







                                                      


           



                                                                     

                                        



                                                                          






                                                                                               




                                                                                                                               
                                                                       

                                                        









                                                                                                              



                                                                                                                                                                                                             

                                                                                                        


                                                                                                                             
                         
                                                                 
                 


           






                                                                                






                                                                                                                





                                                          
           



                                                                                  




                                                                                                                      
                                           
                                                                                           
                 


                                                                                                                                                
                      



                                                         








                                                             




                                                           
                                                   
           
                                                     
           
                                                          
                                                                                                                              
                                               
                                                                               
                                                                                                                               





                                                                                                   
                                                                                                                            

                                                                                                






                                                                  













                                                                                       



                                                                                            


                 




                                                                   





                                                                      
                                                                      

                      





                                                    

                                                              



                                                                            
           
                                                                              
                   


                                                 

                              
                                                                                                     
                                                                                              
                                                                                              


                                                                                                                                                


                                                                                                                
                                                                                                   
                 



                                                           
                                                  



                                                                                                             
 
                                             


















                                                                   







































                                                                                                                                                 
                                                                                                                                                                    



















                                                                                                                                               

                                                                                            



                                                                                          
                                              
                                       


                                                                                        
                                                                           
                                                                                                                  



                                                                

                                               










                                                                                       


                 



















                                                                                                                    























                                                                                                                              

                                      


                                                                                                                                                          

                            



                                                                                                          
                                       


































































                                                                                                                                                                        

                                                                                                                              





                                                                                                           
                                                          
                                             

                                                                                                                 
                                                                                        
                                                                                          






                                                                                                                       
                                                                                                
                                                    
                         
                 
                                    





                                                                                                                                                                


































                                                                                                                             






                                                                                                                                         
                                                                                                                                                            





                                                                                                                                       
                                                        
                                                                                         

                                                                                      


                                            

                                                                     


                                                       
                                                                                    

                                                                                       
                                                               
                                                                    
                                          

                      
                                                                                       
                                                                                                          
                                                                                        
                                                                     
                                                                                 

                                                                            
                                                  
                         
                 
 
                                                



                                                                                    



                                                                                                                                         



                                                                                                                                                                           
                 

         













                                                                                                       
                                                                                                                             
                                    
                                                                                                 



                                                                                 
 
/*******************************************************************************
 * Copyright (c) 2001, 2005 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *     Jens Lukowski/Innoopract - initial renaming/restructuring
 *     
 *******************************************************************************/
package org.eclipse.wst.sse.ui;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.ResourceBundle;
import java.util.Timer;
import java.util.TimerTask;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.ui.actions.IToggleBreakpointsTarget;
import org.eclipse.emf.common.command.Command;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.GroupMarker;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultInformationControl;
import org.eclipse.jface.text.DocumentEvent;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.IDocumentListener;
import org.eclipse.jface.text.IInformationControl;
import org.eclipse.jface.text.IInformationControlCreator;
import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ISelectionValidator;
import org.eclipse.jface.text.ITextHover;
import org.eclipse.jface.text.ITextOperationTarget;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.ITextViewerExtension;
import org.eclipse.jface.text.ITextViewerExtension2;
import org.eclipse.jface.text.ITextViewerExtension4;
import org.eclipse.jface.text.ITextViewerExtension5;
import org.eclipse.jface.text.TextSelection;
import org.eclipse.jface.text.TextUtilities;
import org.eclipse.jface.text.contentassist.IContentAssistant;
import org.eclipse.jface.text.information.IInformationProvider;
import org.eclipse.jface.text.information.IInformationProviderExtension2;
import org.eclipse.jface.text.information.InformationPresenter;
import org.eclipse.jface.text.source.ICharacterPairMatcher;
import org.eclipse.jface.text.source.ISourceViewer;
import org.eclipse.jface.text.source.IVerticalRuler;
import org.eclipse.jface.text.source.LineChangeHover;
import org.eclipse.jface.text.source.SourceViewerConfiguration;
import org.eclipse.jface.text.source.projection.ProjectionSupport;
import org.eclipse.jface.text.source.projection.ProjectionViewer;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.IPostSelectionProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorActionBarContributor;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.IPageLayout;
import org.eclipse.ui.IPathEditorInput;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.IStorageEditorInput;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.editors.text.ITextEditorHelpContextIds;
import org.eclipse.ui.editors.text.TextEditor;
import org.eclipse.ui.help.IWorkbenchHelpSystem;
import org.eclipse.ui.part.IShowInTargetList;
import org.eclipse.ui.progress.IWorkbenchSiteProgressService;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.ui.texteditor.ChainedPreferenceStore;
import org.eclipse.ui.texteditor.DefaultRangeIndicator;
import org.eclipse.ui.texteditor.IAbstractTextEditorHelpContextIds;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.IStatusField;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.texteditor.ITextEditorActionConstants;
import org.eclipse.ui.texteditor.ITextEditorActionDefinitionIds;
import org.eclipse.ui.texteditor.IUpdate;
import org.eclipse.ui.texteditor.IWorkbenchActionDefinitionIds;
import org.eclipse.ui.texteditor.SourceViewerDecorationSupport;
import org.eclipse.ui.texteditor.TextEditorAction;
import org.eclipse.ui.texteditor.TextOperationAction;
import org.eclipse.ui.views.contentoutline.IContentOutlinePage;
import org.eclipse.ui.views.properties.IPropertySheetPage;
import org.eclipse.wst.sse.core.StructuredModelManager;
import org.eclipse.wst.sse.core.internal.document.IDocumentCharsetDetector;
import org.eclipse.wst.sse.core.internal.encoding.EncodingMemento;
import org.eclipse.wst.sse.core.internal.provisional.IModelStateListener;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.IndexedRegion;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredDocument;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredPartitioning;
import org.eclipse.wst.sse.core.internal.provisional.text.ITextRegion;
import org.eclipse.wst.sse.core.internal.text.IExecutionDelegatable;
import org.eclipse.wst.sse.core.internal.undo.IStructuredTextUndoManager;
import org.eclipse.wst.sse.core.utils.StringUtils;
import org.eclipse.wst.sse.ui.internal.ExtendedConfigurationBuilder;
import org.eclipse.wst.sse.ui.internal.ExtendedEditorActionBuilder;
import org.eclipse.wst.sse.ui.internal.ExtendedEditorDropTargetAdapter;
import org.eclipse.wst.sse.ui.internal.IExtendedContributor;
import org.eclipse.wst.sse.ui.internal.IModelProvider;
import org.eclipse.wst.sse.ui.internal.IPopupMenuContributor;
import org.eclipse.wst.sse.ui.internal.Logger;
import org.eclipse.wst.sse.ui.internal.ReadOnlyAwareDropTargetAdapter;
import org.eclipse.wst.sse.ui.internal.SSEUIMessages;
import org.eclipse.wst.sse.ui.internal.SSEUIPlugin;
import org.eclipse.wst.sse.ui.internal.StorageModelProvider;
import org.eclipse.wst.sse.ui.internal.StructuredLineChangeHover;
import org.eclipse.wst.sse.ui.internal.StructuredTextViewer;
import org.eclipse.wst.sse.ui.internal.UnknownContentTypeDialog;
import org.eclipse.wst.sse.ui.internal.actions.ActionDefinitionIds;
import org.eclipse.wst.sse.ui.internal.actions.StructuredTextEditorActionConstants;
import org.eclipse.wst.sse.ui.internal.contentoutline.ConfigurableContentOutlinePage;
import org.eclipse.wst.sse.ui.internal.correction.CorrectionAssistantProvider;
import org.eclipse.wst.sse.ui.internal.debug.BreakpointRulerAction;
import org.eclipse.wst.sse.ui.internal.debug.EditBreakpointAction;
import org.eclipse.wst.sse.ui.internal.debug.ManageBreakpointAction;
import org.eclipse.wst.sse.ui.internal.debug.ToggleBreakpointAction;
import org.eclipse.wst.sse.ui.internal.debug.ToggleBreakpointsTarget;
import org.eclipse.wst.sse.ui.internal.derived.HTMLTextPresenter;
import org.eclipse.wst.sse.ui.internal.editor.EditorModelUtil;
import org.eclipse.wst.sse.ui.internal.editor.IHelpContextIds;
import org.eclipse.wst.sse.ui.internal.editor.StructuredModelDocumentProvider;
import org.eclipse.wst.sse.ui.internal.extension.BreakpointProviderBuilder;
import org.eclipse.wst.sse.ui.internal.hyperlink.OpenHyperlinkAction;
import org.eclipse.wst.sse.ui.internal.preferences.EditorPreferenceNames;
import org.eclipse.wst.sse.ui.internal.projection.IStructuredTextFoldingProvider;
import org.eclipse.wst.sse.ui.internal.properties.ConfigurablePropertySheetPage;
import org.eclipse.wst.sse.ui.internal.properties.ShowPropertiesAction;
import org.eclipse.wst.sse.ui.internal.provisional.extensions.ConfigurationPointCalculator;
import org.eclipse.wst.sse.ui.internal.provisional.extensions.ISourceEditingTextTools;
import org.eclipse.wst.sse.ui.internal.provisional.extensions.breakpoint.NullSourceEditingTextTools;
import org.eclipse.wst.sse.ui.internal.selection.SelectionHistory;
import org.eclipse.wst.sse.ui.internal.text.DocumentRegionEdgeMatcher;
import org.eclipse.wst.sse.ui.internal.util.Assert;
import org.eclipse.wst.sse.ui.views.contentoutline.ContentOutlineConfiguration;
import org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration;

/**
 * A Text Editor for editing structured models and structured documents.
 * <p>
 * This class is not meant to be subclassed.<br />
 * New content types may associate source viewer, content outline, and
 * property sheet configurations to extend the existing functionality.
 * </p>
 * 
 * @see org.eclipse.wst.sse.ui.StructuredTextViewerConfiguration
 * @see org.eclipse.wst.sse.ui.views.contentoutline.ContentOutlineConfiguration
 * @see org.eclipse.wst.sse.ui.views.properties.PropertySheetConfiguration
 * 
 * @since 1.0
 */

public class StructuredTextEditor extends TextEditor {


	// ISSUE: This use case is not clear to me.
	// Is this listner and dance with dirty state for non-editor driven
	// updates?
	class InternalDocumentListener implements IDocumentListener {
		// This is for the IDocumentListener interface
		public void documentAboutToBeChanged(DocumentEvent event) {
			fDirtyBeforeDocumentEvent = isDirty();
		}

		// This is for the IDocumentListener interface
		public void documentChanged(DocumentEvent event) {
			if (isEditorInputReadOnly()) {
				// stop listening to document event
				// caused by the undo after validateEdit
				final int offset = event.getOffset() + event.getLength();
				final IStructuredModel internalModel = getInternalModel();
				fCurrentRunnable = new Runnable() {
					public void run() {
						if (!fEditorDisposed) {
							boolean status = validateEditorInputState();
							if (!status) {
								if (internalModel != null) {
									internalModel.getUndoManager().undo();
									getSourceViewer().setSelectedRange(offset, 0);
									if (!fDirtyBeforeDocumentEvent) {
										// reset dirty state if
										// model not dirty before
										// document event
										internalModel.setDirtyState(false);
									}
								}
							}
						}
						fCurrentRunnable = null;
					}
				};
				/*
				 * We need to ensure that this is run via 'asyncExec' since
				 * these notifications can come from a non-ui thread.
				 * 
				 * The non-ui thread call would occur when creating a new file
				 * under ClearCase (or other library) control. The creation of
				 * the new file would trigger a validateEdit call, on another
				 * thread, that would prompt the user to add the new file to
				 * version control.
				 */
				Display display = getDisplay();
				if (display != null) {
					if (Thread.currentThread() != display.getThread())
						// future_TODO: there's probably a better
						// way than relying on asycnExec
						display.asyncExec(fCurrentRunnable);
					else
						fCurrentRunnable.run();
				}
			}
		}
	}

	private class InternalModelStateListener implements IModelStateListener {
		public void modelAboutToBeChanged(IStructuredModel model) {
			if (getTextViewer() != null) {
				// getTextViewer().setRedraw(false);
			}
		}

		public void modelAboutToBeReinitialized(IStructuredModel structuredModel) {
			if (getTextViewer() != null) {
				// getTextViewer().setRedraw(false);
				getTextViewer().unconfigure();
			}
		}

		public void modelChanged(IStructuredModel model) {
			if (getTextViewer() != null) {
				// getTextViewer().setRedraw(true);
				// Since the model can be changed on a background
				// thread, we will update menus on display thread,
				// if we are not already on display thread,
				// and if there is not an update already pending.
				// (we can get lots of 'modelChanged' events in rapid
				// succession, so only need to do one.
				if (!fUpdateMenuTextPending) {
					runOnDisplayThreadIfNeededed(new Runnable() {
						public void run() {
							updateMenuText();
							fUpdateMenuTextPending = false;
						}
					});
				}

			}
		}

		public void modelDirtyStateChanged(IStructuredModel model, boolean isDirty) {
			// do nothing
		}

		public void modelReinitialized(IStructuredModel structuredModel) {
			try {
				if (getSourceViewer() != null) {
					SourceViewerConfiguration cfg = getSourceViewerConfiguration();
					getSourceViewer().configure(cfg);
				}
			}
			catch (Exception e) {
				// https://w3.opensource.ibm.com/bugzilla/show_bug.cgi?id=1166
				// investigate each error case post beta
				Logger.logException("problem trying to configure after model change", e); //$NON-NLS-1$
			}
			finally {
				// so we don't freeze workbench (eg. during page language or
				// content type change)
				((ITextViewerExtension) getSourceViewer()).setRedraw(true);
			}
		}

		// Note: this one should probably be used to
		// control viewer
		// instead of viewer having its own listener
		public void modelResourceDeleted(IStructuredModel model) {
			// do nothing
		}

		public void modelResourceMoved(IStructuredModel originalmodel, IStructuredModel movedmodel) {
			// do nothing
		}

		/**
		 * This 'Runnable' should be very brief, and should not "call out" to
		 * other code especially if it depends on the state of the model.
		 * 
		 * @param r
		 */
		private void runOnDisplayThreadIfNeededed(Runnable r) {
			// if there is no Display at all (that is, running headless),
			// or if we are already running on the display thread, then
			// simply execute the runnable.
			if (getDisplay() == null || (Thread.currentThread() == getDisplay().getThread())) {
				r.run();
			}
			else {
				// otherwise force the runnable to run on the display thread.
				getDisplay().asyncExec(r);
			}
		}
	}

	class MouseTracker extends MouseTrackAdapter implements MouseMoveListener {
		/** The tracker's subject control. */
		private Control fSubjectControl;

		/**
		 * Creates a new mouse tracker.
		 */
		public MouseTracker() {
			// do nothing
		}

		public void mouseHover(MouseEvent event) {
			// System.out.println("hover: "+event.x + "x" + event.y);
			hoverX = event.x;
			hoverY = event.y;
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see org.eclipse.swt.events.MouseMoveListener#mouseMove(org.eclipse.swt.events.MouseEvent)
		 */
		public void mouseMove(MouseEvent e) {
			hoverX = e.x;
			hoverY = e.y;
		}

		/**
		 * Starts this mouse tracker. The given control becomes this tracker's
		 * subject control. Installs itself as mouse track listener on the
		 * subject control.
		 * 
		 * @param subjectControl
		 *            the subject control
		 */
		public void start(Control subjectControl) {
			fSubjectControl = subjectControl;
			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				fSubjectControl.addMouseMoveListener(this);
				fSubjectControl.addMouseTrackListener(this);
				fSubjectControl.addDisposeListener(new DisposeListener() {
					public void widgetDisposed(DisposeEvent e) {
						stop();
					}
				});
			}
		}

		/**
		 * Stops this mouse tracker. Removes itself as mouse track, mouse
		 * move, and shell listener from the subject control.
		 */
		public void stop() {
			if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
				fSubjectControl.removeMouseMoveListener(this);
				fSubjectControl.removeMouseTrackListener(this);
				fSubjectControl = null;
			}
		}
	}

	/**
	 * Listens to double-click and selection from the outline page
	 */
	private class OutlinePageListener implements IDoubleClickListener, ISelectionChangedListener {
		public void doubleClick(DoubleClickEvent event) {
			if (event.getSelection().isEmpty())
				return;

			int start = -1;
			int length = 0;
			if (event.getSelection() instanceof IStructuredSelection) {
				ISelection currentSelection = getSelectionProvider().getSelection();
				if (currentSelection instanceof IStructuredSelection) {
					Object current = ((IStructuredSelection) currentSelection).toArray();
					Object newSelection = ((IStructuredSelection) event.getSelection()).toArray();
					if (!current.equals(newSelection)) {
						IStructuredSelection selection = (IStructuredSelection) event.getSelection();
						Object o = selection.getFirstElement();
						if (o instanceof IndexedRegion) {
							start = ((IndexedRegion) o).getStartOffset();
							length = ((IndexedRegion) o).getEndOffset() - start;
						}
						else if (o instanceof ITextRegion) {
							start = ((ITextRegion) o).getStart();
							length = ((ITextRegion) o).getEnd() - start;
						}
						else if (o instanceof IRegion) {
							start = ((ITextRegion) o).getStart();
							length = ((ITextRegion) o).getLength();
						}
					}
				}
			}
			else if (event.getSelection() instanceof ITextSelection) {
				start = ((ITextSelection) event.getSelection()).getOffset();
				length = ((ITextSelection) event.getSelection()).getLength();
			}
			if (start > -1) {
				getSourceViewer().setRangeIndication(start, length, false);
				selectAndReveal(start, length);
			}
		}

		public void selectionChanged(SelectionChangedEvent event) {
			/*
			 * Do not allow selection from other parts to affect selection in
			 * the text widget if it has focus, or if we're still firing a
			 * change of selection. Selection events "bouncing" off of other
			 * parts are all that we can receive if we have focus (since we
			 * forwarded our selection to the service just a moment ago), and
			 * only the user should affect selection if we have focus.
			 */

			/* The isFiringSelection check only works if a selection listener */
			if (event.getSelection().isEmpty() || fStructuredSelectionProvider.isFiringSelection())
				return;

			if (getSourceViewer() != null && getSourceViewer().getTextWidget() != null && !getSourceViewer().getTextWidget().isDisposed() && !getSourceViewer().getTextWidget().isFocusControl()) {
				int start = -1;
				int length = 0;
				if (event.getSelection() instanceof IStructuredSelection) {
					ISelection current = getSelectionProvider().getSelection();
					if (current instanceof IStructuredSelection) {
						Object[] currentSelection = ((IStructuredSelection) current).toArray();
						Object[] newSelection = ((IStructuredSelection) event.getSelection()).toArray();
						if (!Arrays.equals(currentSelection, newSelection)) {
							if (newSelection.length > 0) {
								/*
								 * No ordering is guaranteed for multiple
								 * selection
								 */
								Object o = newSelection[0];
								if (o instanceof IndexedRegion) {
									start = ((IndexedRegion) o).getStartOffset();
									int end = ((IndexedRegion) o).getEndOffset();
									if (newSelection.length > 1) {
										for (int i = 1; i < newSelection.length; i++) {
											start = Math.min(start, ((IndexedRegion) newSelection[i]).getStartOffset());
											end = Math.max(end, ((IndexedRegion) newSelection[i]).getEndOffset());
										}
										length = end - start;
									}
								}
								else if (o instanceof ITextRegion) {
									start = ((ITextRegion) o).getStart();
									int end = ((ITextRegion) o).getEnd();
									if (newSelection.length > 1) {
										for (int i = 1; i < newSelection.length; i++) {
											start = Math.min(start, ((ITextRegion) newSelection[i]).getStart());
											end = Math.max(end, ((ITextRegion) newSelection[i]).getEnd());
										}
										length = end - start;
									}
								}
								else if (o instanceof IRegion) {
									start = ((IRegion) o).getOffset();
									int end = start + ((IRegion) o).getLength();
									if (newSelection.length > 1) {
										for (int i = 1; i < newSelection.length; i++) {
											start = Math.min(start, ((IRegion) newSelection[i]).getOffset());
											end = Math.max(end, ((IRegion) newSelection[i]).getOffset() + ((IRegion) newSelection[i]).getLength());
										}
										length = end - start;
									}
								}
							}
						}
					}
				}
				else if (event.getSelection() instanceof ITextSelection) {
					start = ((ITextSelection) event.getSelection()).getOffset();
				}
				if (start > -1) {
					updateRangeIndication(event.getSelection());
					selectAndReveal(start, length);
				}
			}
		}
	}

	private class ShowInTargetListAdapter implements IShowInTargetList {
		/**
		 * Array of ID Strings that define the default show in targets for
		 * this editor.
		 * 
		 * @see org.eclipse.ui.part.IShowInTargetList#getShowInTargetIds()
		 * @return the array of ID Strings that define the default show in
		 *         targets for this editor.
		 */
		public String[] getShowInTargetIds() {
			return fShowInTargetIds;
		}
	}

	/**
	 * A post selection provider that wraps the provider implemented in
	 * AbstractTextEditor to provide a StructuredTextSelection to post
	 * selection listeners. Listens to selection changes from the source
	 * viewer.
	 */
	private static class StructuredSelectionProvider implements IPostSelectionProvider, ISelectionValidator {
		/**
		 * A "hybrid" text and structured selection class. Converts the source
		 * viewer text selection to a generic "getIndexedRegion"-derived
		 * structured selection, allowing selection changed listeners to
		 * possibly not need to reference the model directly.
		 */
		private static class StructuredTextSelection extends TextSelection implements IStructuredSelection, ITextSelection {
			private WeakReference weakSelectedStructured;
			private InternalTextSelection fInternalTextSelection;

			StructuredTextSelection(ITextSelection selection, IDocument document, IStructuredModel model) {
				// note: we do not currently use super class at all, but, only
				// subclass TextSelection,
				// because some infrastructure code uses "instanceof
				// TextSelection" instead of ITextSelection.
				super(selection.getOffset(), selection.getLength());
				fInternalTextSelection = new InternalTextSelection(document, selection.getOffset(), selection.getLength());
				weakSelectedStructured = new WeakReference(initializeInferredSelectedObjects(selection, model));
			}

			StructuredTextSelection(ITextSelection selection, Object[] selectedObjects, IDocument document) {
				super(selection.getOffset(), selection.getLength());
				fInternalTextSelection = new InternalTextSelection(document, selection.getOffset(), selection.getLength());
				weakSelectedStructured = new WeakReference(selectedObjects);
			}

			StructuredTextSelection(IDocument document, int offset, int length, Object[] selectedObjects) {
				super(offset, length);
				fInternalTextSelection = new InternalTextSelection(document, offset, length);
				weakSelectedStructured = new WeakReference(selectedObjects);
			}

			public Object getFirstElement() {
				Object[] selectedStructures = getSelectedStructures();
				return selectedStructures.length > 0 ? selectedStructures[0] : null;
			}

			private Object[] getSelectedStructures() {
				Object[] selectedStructures = (Object[]) weakSelectedStructured.get();
				if (selectedStructures == null) {
					selectedStructures = new Object[0];
				}
				return selectedStructures;
			}

			private Object[] initializeInferredSelectedObjects(ITextSelection selection, IStructuredModel model) {
				Object[] localSelectedStructures = null;
				if (model != null) {
					IndexedRegion region = model.getIndexedRegion(selection.getOffset());
					int end = selection.getOffset() + selection.getLength();
					if (region != null) {
						if (end <= region.getEndOffset()) {
							// single selection
							localSelectedStructures = new Object[1];
							localSelectedStructures[0] = region;
						}
						else {
							// multiple selection
							int maxLength = model.getStructuredDocument().getLength();
							List structures = new ArrayList(2);
							while (region != null && region.getEndOffset() <= end && region.getEndOffset() < maxLength) {
								structures.add(region);
								region = model.getIndexedRegion(region.getEndOffset() + 1);
							}
							localSelectedStructures = structures.toArray();
						}
					}
				}
				if (localSelectedStructures == null) {
					localSelectedStructures = new Object[0];
				}
				return localSelectedStructures;
			}

			public boolean isEmpty() {
				return fInternalTextSelection.isEmpty() && getSelectedStructures().length == 0;
			}

			public Iterator iterator() {
				return toList().iterator();
			}

			public int size() {
				return getSelectedStructures().length;
			}

			public Object[] toArray() {
				return getSelectedStructures();
			}

			public List toList() {
				return Arrays.asList(getSelectedStructures());
			}

			public String toString() {
				return fInternalTextSelection.getOffset() + ":" + fInternalTextSelection.getLength() + "@" + getSelectedStructures(); //$NON-NLS-1$ //$NON-NLS-2$
			}


			private static class InternalTextSelection implements ITextSelection {


				private WeakReference weakDocument;

				/** Offset of the selection */
				private int fOffset;
				/** Length of the selection */
				private int fLength;


				/**
				 * Creates an empty text selection.
				 */
				private InternalTextSelection() {
					this(null, -1, -1);
				}

				/**
				 * Creates a text selection for the given range. This
				 * selection object describes generically a text range and is
				 * intended to be an argument for the
				 * <code>setSelection</code> method of selection providers.
				 * 
				 * @param offset
				 *            the offset of the range
				 * @param length
				 *            the length of the range
				 */
				InternalTextSelection(int offset, int length) {
					this(null, offset, length);
				}

				/**
				 * Creates a text selection for the given range of the given
				 * document. This selection object is created by selection
				 * providers in responds <code>getSelection</code>.
				 * 
				 * @param document
				 *            the document whose text range is selected in a
				 *            viewer
				 * @param offset
				 *            the offset of the selected range
				 * @param length
				 *            the length of the selected range
				 */
				InternalTextSelection(IDocument document, int offset, int length) {
					weakDocument = new WeakReference(document);
					fOffset = offset;
					fLength = length;
				}

				/**
				 * 
				 * Returns true if the offset and length are smaller than 0. A
				 * selection of length 0, is a valid text selection as it
				 * describes, e.g., the cursor position in a viewer.
				 * 
				 * @return <code>true</code> if this selection is empty
				 * @see org.eclipse.jface.viewers.ISelection#isEmpty()
				 */
				public boolean isEmpty() {
					return fOffset < 0 || fLength < 0;
				}

				/*
				 * @see org.eclipse.jface.text.ITextSelection#getOffset()
				 */
				public int getOffset() {
					return fOffset;
				}

				/*
				 * @see org.eclipse.jface.text.ITextSelection#getLength()
				 */
				public int getLength() {
					return fLength;
				}

				/*
				 * @see org.eclipse.jface.text.ITextSelection#getStartLine()
				 */
				public int getStartLine() {

					IDocument document = (IDocument) weakDocument.get();
					try {
						if (document != null)
							return document.getLineOfOffset(fOffset);
					}
					catch (BadLocationException x) {
					}

					return -1;
				}

				/*
				 * @see org.eclipse.jface.text.ITextSelection#getEndLine()
				 */
				public int getEndLine() {
					IDocument document = (IDocument) weakDocument.get();
					try {
						if (document != null) {
							int endOffset = fOffset + fLength;
							if (fLength != 0)
								endOffset--;
							return document.getLineOfOffset(endOffset);
						}
					}
					catch (BadLocationException x) {
					}

					return -1;
				}

				/*
				 * @see org.eclipse.jface.text.ITextSelection#getText()
				 */
				public String getText() {
					IDocument document = (IDocument) weakDocument.get();
					try {
						if (document != null)
							return document.get(fOffset, fLength);
					}
					catch (BadLocationException x) {
					}

					return null;
				}

				/*
				 * @see java.lang.Object#equals(Object)
				 */
				public boolean equals(Object obj) {
					if (obj == this)
						return true;

					if (obj == null || getClass() != obj.getClass())
						return false;

					InternalTextSelection s = (InternalTextSelection) obj;
					boolean sameRange = (s.fOffset == fOffset && s.fLength == fLength);
					if (sameRange) {

						IDocument document = (IDocument) weakDocument.get();
						IDocument sDocument = s.getDocument();

						// ISSUE: why does not IDocument .equals suffice?
						if (sDocument == null && document == null)
							return true;
						if (sDocument == null || document == null)
							return false;

						try {
							// ISSUE: pricey! (a cached hash might be in order, if this 
							// was ever really ever used very often.
							String sContent = sDocument.get(fOffset, fLength);
							String content = document.get(fOffset, fLength);
							return sContent.equals(content);
						}
						catch (BadLocationException x) {
							// return false, can not be equal
						}
					}

					return false;
				}

				/*
				 * @see java.lang.Object#hashCode()
				 */
				public int hashCode() {
					IDocument document = (IDocument) weakDocument.get();
					int low = document != null ? document.hashCode() : 0;
					return (fOffset << 24) | (fLength << 16) | low;
				}

				private IDocument getDocument() {
					if (weakDocument == null)
						return null;
					return (IDocument) weakDocument.get();
				}
			}

			public int getOffset() {
				return fInternalTextSelection.getOffset();
			}


			public int getLength() {
				return fInternalTextSelection.getLength();
			}

			public int getStartLine() {
				return fInternalTextSelection.getStartLine();
			}

			public int getEndLine() {
				return fInternalTextSelection.getEndLine();
			}

			public String getText() {
				return fInternalTextSelection.getText();
			}
		}

		private WeakReference weakDocument;
		private ISelectionProvider fParentProvider = null;
		private boolean isFiringSelection = false;
		private ListenerList listeners = new ListenerList();
		private ListenerList postListeners = new ListenerList();
		private ISelection fLastSelection = null;
		private ISelectionProvider fLastSelectionProvider = null;
		private SelectionChangedEvent fLastUpdatedSelectionChangedEvent = null;
		private WeakReference weakEditor;


		StructuredSelectionProvider(ISelectionProvider parentProvider, StructuredTextEditor structuredTextEditor) {
			fParentProvider = parentProvider;
			weakEditor = new WeakReference(structuredTextEditor);
			IDocument document = structuredTextEditor.getDocumentProvider().getDocument(structuredTextEditor.getEditorInput());
			if (document != null) {
				setDocument(document);
			}
			fParentProvider.addSelectionChangedListener(new ISelectionChangedListener() {
				public void selectionChanged(SelectionChangedEvent event) {
					handleSelectionChanged(event);
				}
			});
			if (fParentProvider instanceof IPostSelectionProvider) {
				((IPostSelectionProvider) fParentProvider).addPostSelectionChangedListener(new ISelectionChangedListener() {
					public void selectionChanged(SelectionChangedEvent event) {
						handlePostSelectionChanged(event);
					}
				});
			}
		}

		public void addPostSelectionChangedListener(ISelectionChangedListener listener) {
			postListeners.add(listener);
		}

		public void addSelectionChangedListener(ISelectionChangedListener listener) {
			listeners.add(listener);
		}

		private void fireSelectionChanged(final SelectionChangedEvent event, ListenerList listenerList) {
			Object[] listeners = listenerList.getListeners();
			isFiringSelection = true;
			for (int i = 0; i < listeners.length; ++i) {
				final ISelectionChangedListener l = (ISelectionChangedListener) listeners[i];
				SafeRunner.run(new SafeRunnable() {
					public void run() {
						l.selectionChanged(event);
					}
				});
			}
			isFiringSelection = false;
		}

		private ISelectionProvider getParentProvider() {
			return fParentProvider;
		}

		public ISelection getSelection() {
			fLastSelection = null;
			fLastSelectionProvider = null;
			fLastUpdatedSelectionChangedEvent = null;

			/*
			 * When a client explicitly asks for selection, provide the hybrid
			 * result.
			 */
			ISelection selection = getParentProvider().getSelection();
			if (!(selection instanceof IStructuredSelection) && selection instanceof ITextSelection) {
				IStructuredModel model = null;
				StructuredTextEditor localEditor = getStructuredTextEditor();
				if (localEditor != null) {
					model = localEditor.getModel();
					selection = new StructuredTextSelection((ITextSelection) selection, getDocument(), model);
				}
				else {
					selection = new StructuredTextSelection((ITextSelection) selection, getDocument(), null);
				}
			}
			return selection;
		}

		private StructuredTextEditor getStructuredTextEditor() {
			StructuredTextEditor editor = null;
			if (weakEditor != null) {
				editor = (StructuredTextEditor) weakEditor.get();
			}
			return editor;
		}

		void handlePostSelectionChanged(SelectionChangedEvent event) {
			SelectionChangedEvent updatedEvent = null;
			if (fLastSelection == event.getSelection() && fLastSelectionProvider == event.getSelectionProvider()) {
				updatedEvent = fLastUpdatedSelectionChangedEvent;
			}
			else {
				updatedEvent = updateEvent(event);
			}
			// only update the range indicator on post selection
			StructuredTextEditor localEditor = (StructuredTextEditor) weakEditor.get();

			if (localEditor != null) {
				localEditor.updateRangeIndication(updatedEvent.getSelection());
				fireSelectionChanged(updatedEvent, postListeners);
			}
		}

		void handleSelectionChanged(SelectionChangedEvent event) {
			SelectionChangedEvent updatedEvent = event;
			if (fLastSelection != event.getSelection() || fLastSelectionProvider != event.getSelectionProvider()) {
				fLastSelection = event.getSelection();
				fLastSelectionProvider = event.getSelectionProvider();
				fLastUpdatedSelectionChangedEvent = updatedEvent = updateEvent(event);
			}
			fireSelectionChanged(updatedEvent, listeners);
		}

		IDocument getDocument() {
			IDocument document = null;
			if (weakDocument != null) {
				document = (IDocument) weakDocument.get();
			}
			return document;
		}


		boolean isFiringSelection() {
			return isFiringSelection;
		}

		public boolean isValid(ISelection selection) {
			// ISSUE: is not clear default behavior should be true?
			// But not clear is this default would apply for our editor.
			boolean result = true;
			// if editor is "gone", can not be valid
			StructuredTextEditor e = getStructuredTextEditor(); 
			if (e == null || e.fEditorDisposed) {
				result = false;
			}
			// else defer to parent
			else if (getParentProvider() instanceof ISelectionValidator) {
				result = ((ISelectionValidator) getParentProvider()).isValid(selection);
			}
			return result;
		}

		public void removePostSelectionChangedListener(ISelectionChangedListener listener) {
			postListeners.remove(listener);
		}

		public void removeSelectionChangedListener(ISelectionChangedListener listener) {
			listeners.remove(listener);
		}

		public void setSelection(ISelection selection) {
			if (isFiringSelection()) {
				return;
			}

			fLastSelection = null;
			fLastSelectionProvider = null;
			fLastUpdatedSelectionChangedEvent = null;

			ISelection textSelection = updateSelection(selection);
			getParentProvider().setSelection(textSelection);
			StructuredTextEditor localEditor = getStructuredTextEditor();
			if (localEditor != null) {
				localEditor.updateRangeIndication(textSelection);
			}
		}

		/**
		 * Create a corresponding event that contains a
		 * StructuredTextselection
		 * 
		 * @param event
		 * @return
		 */
		private SelectionChangedEvent updateEvent(SelectionChangedEvent event) {
			ISelection selection = event.getSelection();
			if (selection instanceof ITextSelection && !(selection instanceof IStructuredSelection)) {
				IStructuredModel structuredModel = null;
				StructuredTextEditor localEditor = getStructuredTextEditor();
				if (localEditor != null) {
					structuredModel = localEditor.getInternalModel();
				}
				selection = new StructuredTextSelection((ITextSelection) event.getSelection(), getDocument(), structuredModel);
			}
			SelectionChangedEvent newEvent = new SelectionChangedEvent(event.getSelectionProvider(), selection);
			return newEvent;
		}

		/**
		 * Create a corresponding StructuredTextselection
		 * 
		 * @param selection
		 * @return
		 */
		private ISelection updateSelection(ISelection selection) {
			ISelection updated = selection;
			if (selection instanceof IStructuredSelection && !(selection instanceof ITextSelection) && !selection.isEmpty()) {
				Object[] selectedObjects = ((IStructuredSelection) selection).toArray();
				if (selectedObjects.length > 0) {
					int start = -1;
					int length = 0;

					// no ordering is guaranteed for multiple selection
					Object o = selectedObjects[0];
					if (o instanceof IndexedRegion) {
						start = ((IndexedRegion) o).getStartOffset();
						int end = ((IndexedRegion) o).getEndOffset();
						if (selectedObjects.length > 1) {
							for (int i = 1; i < selectedObjects.length; i++) {
								start = Math.min(start, ((IndexedRegion) selectedObjects[i]).getStartOffset());
								end = Math.max(end, ((IndexedRegion) selectedObjects[i]).getEndOffset());
							}
							length = end - start;
						}
					}
					else if (o instanceof ITextRegion) {
						start = ((ITextRegion) o).getStart();
						int end = ((ITextRegion) o).getEnd();
						if (selectedObjects.length > 1) {
							for (int i = 1; i < selectedObjects.length; i++) {
								start = Math.min(start, ((ITextRegion) selectedObjects[i]).getStart());
								end = Math.max(end, ((ITextRegion) selectedObjects[i]).getEnd());
							}
							length = end - start;
						}
					}

					if (start > -1) {
						updated = new StructuredTextSelection(getDocument(), start, length, selectedObjects);
					}
				}
			}
			return updated;
		}

		public void setDocument(IDocument document) {
			weakDocument = new WeakReference(document);
		}
	}

	class TimeOutExpired extends TimerTask {
		public void run() {
			getDisplay().syncExec(new Runnable() {
				public void run() {
					if (getDisplay() != null && !getDisplay().isDisposed())
						endBusyStateInternal();
				}
			});
		}

	}

	private class ConfigurationAndTarget {
		private String fTargetId;
		private StructuredTextViewerConfiguration fConfiguration;

		public ConfigurationAndTarget(String targetId, StructuredTextViewerConfiguration config) {
			fTargetId = targetId;
			fConfiguration = config;
		}

		public String getTargetId() {
			return fTargetId;
		}

		public StructuredTextViewerConfiguration getConfiguration() {
			return fConfiguration;
		}
	}

	/**
	 * This action behaves in two different ways: If there is no current text
	 * hover, the javadoc is displayed using information presenter. If there
	 * is a current text hover, it is converted into a information presenter
	 * in order to make it sticky.
	 * 
	 * @see org.eclipse.jdt.internal.ui.javaeditor.JavaEditor#InformationDispatchAction
	 */
	class InformationDispatchAction extends TextEditorAction {

		/** The wrapped text operation action. */
		private final TextOperationAction fTextOperationAction;

		/**
		 * Creates a dispatch action.
		 * 
		 * @param resourceBundle
		 *            the resource bundle
		 * @param prefix
		 *            the prefix
		 * @param textOperationAction
		 *            the text operation action
		 */
		public InformationDispatchAction(ResourceBundle resourceBundle, String prefix, final TextOperationAction textOperationAction) {
			super(resourceBundle, prefix, StructuredTextEditor.this);
			if (textOperationAction == null)
				throw new IllegalArgumentException();
			fTextOperationAction = textOperationAction;
		}

		/*
		 * @see org.eclipse.jface.action.IAction#run()
		 */
		public void run() {
			ISourceViewer sourceViewer = getSourceViewer();
			if (sourceViewer == null) {
				fTextOperationAction.run();
				return;
			}

			if (sourceViewer instanceof ITextViewerExtension4) {
				ITextViewerExtension4 extension4 = (ITextViewerExtension4) sourceViewer;
				if (extension4.moveFocusToWidgetToken())
					return;
			}

			if (!(sourceViewer instanceof ITextViewerExtension2)) {
				fTextOperationAction.run();
				return;
			}

			ITextViewerExtension2 textViewerExtension2 = (ITextViewerExtension2) sourceViewer;

			// does a text hover exist?
			ITextHover textHover = textViewerExtension2.getCurrentTextHover();
			if (textHover == null) {
				fTextOperationAction.run();
				return;
			}

			Point hoverEventLocation = textViewerExtension2.getHoverEventLocation();
			int offset = computeOffsetAtLocation(sourceViewer, hoverEventLocation.x, hoverEventLocation.y);
			if (offset == -1) {
				fTextOperationAction.run();
				return;
			}

			try {
				// get the text hover content
				String contentType = TextUtilities.getContentType(sourceViewer.getDocument(), IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING, offset, true);

				IRegion hoverRegion = textHover.getHoverRegion(sourceViewer, offset);
				if (hoverRegion == null)
					return;

				String hoverInfo = textHover.getHoverInfo(sourceViewer, hoverRegion);

				IInformationControlCreator controlCreator = null;
				if (textHover instanceof IInformationProviderExtension2)
					controlCreator = ((IInformationProviderExtension2) textHover).getInformationPresenterControlCreator();

				IInformationProvider informationProvider = new InformationProvider(hoverRegion, hoverInfo, controlCreator);

				fInformationPresenter.setOffset(offset);
				fInformationPresenter.setDocumentPartitioning(IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING);
				fInformationPresenter.setInformationProvider(informationProvider, contentType);
				fInformationPresenter.showInformation();

			}
			catch (BadLocationException e) {
				// No good information to display
			}
		}

		// modified version from TextViewer
		private int computeOffsetAtLocation(ITextViewer textViewer, int x, int y) {

			StyledText styledText = textViewer.getTextWidget();
			IDocument document = textViewer.getDocument();

			if (document == null)
				return -1;

			try {
				int widgetLocation = styledText.getOffsetAtLocation(new Point(x, y));
				if (textViewer instanceof ITextViewerExtension5) {
					ITextViewerExtension5 extension = (ITextViewerExtension5) textViewer;
					return extension.widgetOffset2ModelOffset(widgetLocation);
				}
				else {
					IRegion visibleRegion = textViewer.getVisibleRegion();
					return widgetLocation + visibleRegion.getOffset();
				}
			}
			catch (IllegalArgumentException e) {
				return -1;
			}

		}
	}

	/**
	 * Not API. May be removed in the future.
	 */
	protected final static char[] BRACKETS = {'{', '}', '(', ')', '[', ']'};

	private static final long BUSY_STATE_DELAY = 1000;
	/**
	 * Not API. May be removed in the future.
	 */
	protected static final String DOT = "."; //$NON-NLS-1$
	private static final String EDITOR_CONTEXT_MENU_ID = "org.eclipse.wst.sse.ui.StructuredTextEditor.EditorContext"; //$NON-NLS-1$
	private static final String EDITOR_CONTEXT_MENU_SUFFIX = ".source.EditorContext"; //$NON-NLS-1$
	/** Non-NLS strings */
	private static final String EDITOR_KEYBINDING_SCOPE_ID = "org.eclipse.wst.sse.ui.structuredTextEditorScope"; //$NON-NLS-1$
	/**
	 * Not API. May be removed in the future.
	 */
	public static final String GROUP_NAME_ADDITIONS = "additions"; //$NON-NLS-1$
	/**
	 * Not API. May be removed in the future.
	 */
	public static final String GROUP_NAME_FORMAT = "Format"; //$NON-NLS-1$
	/**
	 * Not API. May be removed in the future.
	 */
	public static final String GROUP_NAME_FORMAT_EXT = "Format.ext"; //$NON-NLS-1$

	private static final String REDO_ACTION_DESC = SSEUIMessages.Redo___0___UI_; //$NON-NLS-1$ = "Redo: {0}."
	private static final String REDO_ACTION_DESC_DEFAULT = SSEUIMessages.Redo_Text_Change__UI_; //$NON-NLS-1$ = "Redo Text Change."
	private static final String REDO_ACTION_TEXT = SSEUIMessages._Redo__0___Ctrl_Y_UI_; //$NON-NLS-1$ = "&Redo {0} @Ctrl+Y"
	private static final String REDO_ACTION_TEXT_DEFAULT = SSEUIMessages._Redo_Text_Change__Ctrl_Y_UI_; //$NON-NLS-1$ = "&Redo Text Change @Ctrl+Y"
	private static final String RULER_CONTEXT_MENU_ID = "org.eclipse.wst.sse.ui.StructuredTextEditor.RulerContext"; //$NON-NLS-1$
	private static final String RULER_CONTEXT_MENU_SUFFIX = ".source.RulerContext"; //$NON-NLS-1$

	private final static String UNDERSCORE = "_"; //$NON-NLS-1$
	/** Translatable strings */
	private static final String UNDO_ACTION_DESC = SSEUIMessages.Undo___0___UI_; //$NON-NLS-1$ = "Undo: {0}."

	private static final String UNDO_ACTION_DESC_DEFAULT = SSEUIMessages.Undo_Text_Change__UI_; //$NON-NLS-1$ = "Undo Text Change."
	private static final String UNDO_ACTION_TEXT = SSEUIMessages._Undo__0___Ctrl_Z_UI_; //$NON-NLS-1$ = "&Undo {0} @Ctrl+Z"
	private static final String UNDO_ACTION_TEXT_DEFAULT = SSEUIMessages._Undo_Text_Change__Ctrl_Z_UI_; //$NON-NLS-1$ = "&Undo Text Change @Ctrl+Z"
	// development time/debug variables only
	private int adapterRequests;

	private long adapterTime;
	private boolean fBackgroundJobEnded;
	private boolean fBusyState;
	private Timer fBusyTimer;
	Runnable fCurrentRunnable = null;
	boolean fDirtyBeforeDocumentEvent = false;
	private ExtendedEditorDropTargetAdapter fDropAdapter;
	private DropTarget fDropTarget;
	boolean fEditorDisposed = false;
	private IEditorPart fEditorPart;
	private IDocumentListener fInternalDocumentListener;
	private InternalModelStateListener fInternalModelStateListener;
	private MouseTracker fMouseTracker;
	private IContentOutlinePage fOutlinePage;

	private OutlinePageListener fOutlinePageListener = null;
	/** This editor's projection model updater */
	private IStructuredTextFoldingProvider fProjectionModelUpdater;
	/** This editor's projection support */
	private ProjectionSupport fProjectionSupport;
	private IPropertySheetPage fPropertySheetPage;
	private String fRememberTitle;
	/** The ruler context menu to be disposed. */
	private Menu fRulerContextMenu;
	/** The ruler context menu manager to be disposed. */
	private MenuManager fRulerContextMenuManager;

	String[] fShowInTargetIds = new String[]{IPageLayout.ID_RES_NAV};

	private IAction fShowPropertiesAction = null;
	private IStructuredModel fStructuredModel;
	StructuredSelectionProvider fStructuredSelectionProvider = null;
	/** The text context menu to be disposed. */
	private Menu fTextContextMenu;
	/** The text context menu manager to be disposed. */
	private MenuManager fTextContextMenuManager;
	private String fViewerConfigurationTargetId;
	/** The selection history of the editor */
	private SelectionHistory fSelectionHistory;
	/** The information presenter. */
	private InformationPresenter fInformationPresenter;
	private boolean fUpdateMenuTextPending;
	int hoverX = -1;
	int hoverY = -1;

	private boolean shouldClose = false;
	private long startPerfTime;
	private boolean fisReleased;
	/**
	 * The action group for folding.
	 */
	private FoldingActionGroup fFoldingGroup;

	/**
	 * Creates a new Structured Text Editor.
	 */
	public StructuredTextEditor() {
		super();
		initializeDocumentProvider(null);
	}

	private void aboutToSaveModel() {
		if (getInternalModel() != null) {
			getInternalModel().aboutToChangeModel();
		}
	}

	private void abstractTextEditorContextMenuAboutToShow(IMenuManager menu) {
		menu.add(new Separator(ITextEditorActionConstants.GROUP_UNDO));
		menu.add(new GroupMarker(ITextEditorActionConstants.GROUP_SAVE));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_COPY));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_PRINT));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_EDIT));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_FIND));
		menu.add(new Separator(IWorkbenchActionConstants.GROUP_ADD));
		menu.add(new Separator(ITextEditorActionConstants.GROUP_REST));
		menu.add(new Separator(IWorkbenchActionConstants.MB_ADDITIONS));

		if (isEditable()) {
			addAction(menu, ITextEditorActionConstants.GROUP_UNDO, ITextEditorActionConstants.UNDO);
			addAction(menu, ITextEditorActionConstants.GROUP_UNDO, ITextEditorActionConstants.REVERT_TO_SAVED);
			addAction(menu, ITextEditorActionConstants.GROUP_SAVE, ITextEditorActionConstants.SAVE);
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.CUT);
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.COPY);
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.PASTE);
		}
		else {
			addAction(menu, ITextEditorActionConstants.GROUP_COPY, ITextEditorActionConstants.COPY);
		}

		// from AbstractDecoratedTextEditor
		IAction preferencesAction = getAction(ITextEditorActionConstants.CONTEXT_PREFERENCES);
		menu.appendToGroup(IWorkbenchActionConstants.MB_ADDITIONS, new Separator(ITextEditorActionConstants.GROUP_SETTINGS));
		menu.appendToGroup(ITextEditorActionConstants.GROUP_SETTINGS, preferencesAction);
	}

	protected void addContextMenuActions(IMenuManager menu) {
		// Only offer actions that affect the text if the viewer allows
		// modification and supports any of these operations
		IAction formatAll = getAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT);
		IAction formatSelection = getAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS);
		IAction cleanupAll = getAction(StructuredTextEditorActionConstants.ACTION_NAME_CLEANUP_DOCUMENT);
		boolean enableFormatMenu = (formatAll != null && formatAll.isEnabled()) || (formatSelection != null && formatSelection.isEnabled()) || (cleanupAll != null && cleanupAll.isEnabled());

		if (getSourceViewer().isEditable() && enableFormatMenu) {
			String label = SSEUIMessages.FormatMenu_label; //$NON-NLS-1$ = "Format"
			MenuManager subMenu = new MenuManager(label, GROUP_NAME_FORMAT);
			subMenu.add(new GroupMarker(GROUP_NAME_FORMAT_EXT));
			addAction(subMenu, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT);
			addAction(subMenu, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS);
			subMenu.add(new GroupMarker(GROUP_NAME_ADDITIONS));
			addAction(menu, ITextEditorActionConstants.GROUP_EDIT, StructuredTextEditorActionConstants.ACTION_NAME_CLEANUP_DOCUMENT);
			menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, subMenu);
		}

		// Some Design editors (DTD) rely on this view for their own uses
		menu.appendToGroup(IWorkbenchActionConstants.GROUP_ADD, fShowPropertiesAction);
	}

	private void addExtendedContextMenuActions(IMenuManager menu) {
		IEditorActionBarContributor c = getEditorSite().getActionBarContributor();
		if (c instanceof IPopupMenuContributor) {
			((IPopupMenuContributor) c).contributeToPopupMenu(menu);
		}
		else {
			ExtendedEditorActionBuilder builder = new ExtendedEditorActionBuilder();
			IExtendedContributor pmc = builder.readActionExtensions(getConfigurationPoints());
			if (pmc != null) {
				pmc.setActiveEditor(this);
				pmc.contributeToPopupMenu(menu);
			}
		}
	}

	protected void addExtendedRulerContextMenuActions(IMenuManager menu) {
		// none at this level
	}



	/**
	 * Starts background mode.
	 * <p>
	 * Not API. May be removed in the future.
	 * </p>
	 */
	void beginBackgroundOperation() {
		fBackgroundJobEnded = false;
		// if already in busy state, no need to do anything
		// and, we only start, or reset, the timed busy
		// state when we get the "endBackgroundOperation" call.
		if (!inBusyState()) {
			beginBusyStateInternal();
		}
	}

	private void beginBusyStateInternal() {

		fBusyState = true;
		startBusyTimer();

		ISourceViewer viewer = getSourceViewer();
		if (viewer instanceof StructuredTextViewer) {
			((StructuredTextViewer) viewer).beginBackgroundUpdate();

		}
		showBusy(true);
	}

	// private void addFindOccurrencesAction(String matchType, String
	// matchText, IMenuManager menu) {
	//
	// AbstractFindOccurrencesAction action = new
	// AbstractFindOccurrencesAction(getFileInEditor(), new
	// SearchUIConfiguration(), (IStructuredDocument) getDocument(),
	// matchType, matchText, getProgressMonitor());
	// action.setText("Occurrences of \"" + matchText + "\" in File");
	// menu.appendToGroup(ITextEditorActionConstants.GROUP_EDIT, action);
	// }

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.ITextEditor#close(boolean)
	 */
	public void close(final boolean save) {
		/*
		 * Instead of us closing directly, we have to close with our
		 * containing (multipage) editor, if it exists.
		 */
		if (getSite() == null) {
			// if site hasn't been set yet, then we're not
			// completely open
			// so set a flag not to open
			shouldClose = true;
		}
		else {
			if (getEditorPart() != null) {
				Display display = getSite().getShell().getDisplay();
				display.asyncExec(new Runnable() {

					public void run() {
						getSite().getPage().closeEditor(getEditorPart(), save);
					}
				});
			}
			else {
				super.close(save);
			}
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#collectContextMenuPreferencePages()
	 */
	protected String[] collectContextMenuPreferencePages() {
		List allIds = new ArrayList(0);

		// get contributed preference pages
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] configurationIds = getConfigurationPoints();
		for (int i = 0; i < configurationIds.length; i++) {
			String[] definitions = builder.getDefinitions("preferencepages", configurationIds[i]); //$NON-NLS-1$
			for (int j = 0; j < definitions.length; j++) {
				String someIds = definitions[j];
				if (someIds != null && someIds.length() > 0) {
					// supports multiple comma-delimited page IDs in one
					// element
					String[] ids = StringUtils.unpack(someIds);
					for (int k = 0; k < ids.length; k++) {
						// trim, just to keep things clean
						String id = ids[k].trim();
						if (!allIds.contains(id)) {
							allIds.add(id);
						}
					}
				}
			}
		}

		// add pages contributed by super
		String[] superPages = super.collectContextMenuPreferencePages();
		for (int m = 0; m < superPages.length; m++) {
			// trim, just to keep things clean
			String id = superPages[m].trim();
			if (!allIds.contains(id)) {
				allIds.add(id);
			}
		}

		return (String[]) allIds.toArray(new String[0]);
	}

	/**
	 * Compute and set double-click action for the vertical ruler
	 */
	private void computeAndSetDoubleClickAction() {
		/*
		 * Make double-clicking on the ruler toggle a breakpoint instead of
		 * toggling a bookmark. For lines where a breakpoint won't be created,
		 * create a bookmark through the contributed RulerDoubleClick action.
		 */
		setAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK, new ToggleBreakpointAction(this, getVerticalRuler(), getAction(ITextEditorActionConstants.RULER_DOUBLE_CLICK)));
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.ExtendedTextEditor#configureSourceViewerDecorationSupport(org.eclipse.ui.texteditor.SourceViewerDecorationSupport)
	 */
	protected void configureSourceViewerDecorationSupport(SourceViewerDecorationSupport support) {
		support.setCharacterPairMatcher(createCharacterPairMatcher());
		support.setMatchingCharacterPainterPreferenceKeys(EditorPreferenceNames.MATCHING_BRACKETS, EditorPreferenceNames.MATCHING_BRACKETS_COLOR);

		super.configureSourceViewerDecorationSupport(support);
	}

	protected void createActions() {
		super.createActions();
		ResourceBundle resourceBundle = SSEUIMessages.getResourceBundle();
		IWorkbenchHelpSystem helpSystem = SSEUIPlugin.getDefault().getWorkbench().getHelpSystem();
		// TextView Action - moving the selected text to
		// the clipboard
		// override the cut/paste/delete action to make
		// them run on read-only
		// files
		Action action = new TextOperationAction(resourceBundle, "Editor_Cut_", this, ITextOperationTarget.CUT, true); //$NON-NLS-1$
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.CUT);
		setAction(ITextEditorActionConstants.CUT, action);
		helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.CUT_ACTION);
		// TextView Action - inserting the clipboard
		// content at the current
		// position
		// override the cut/paste/delete action to make
		// them run on read-only
		// files
		action = new TextOperationAction(resourceBundle, "Editor_Paste_", this, ITextOperationTarget.PASTE, true); //$NON-NLS-1$
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.PASTE);
		setAction(ITextEditorActionConstants.PASTE, action);
		helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.PASTE_ACTION);
		// TextView Action - deleting the selected text or
		// if selection is
		// empty the character at the right of the current
		// position
		// override the cut/paste/delete action to make
		// them run on read-only
		// files
		action = new TextOperationAction(resourceBundle, "Editor_Delete_", this, ITextOperationTarget.DELETE, true); //$NON-NLS-1$
		action.setActionDefinitionId(IWorkbenchActionDefinitionIds.DELETE);
		setAction(ITextEditorActionConstants.DELETE, action);
		helpSystem.setHelp(action, IAbstractTextEditorHelpContextIds.DELETE_ACTION);
		// SourceView Action - requesting information at
		// the current insertion
		// position
		action = new TextOperationAction(SSEUIMessages.getResourceBundle(), StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION + UNDERSCORE, this, ISourceViewer.INFORMATION, true);
		action = new InformationDispatchAction(SSEUIMessages.getResourceBundle(), StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION + UNDERSCORE, (TextOperationAction) action);
		action.setActionDefinitionId(ActionDefinitionIds.INFORMATION);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_INFORMATION, true);
		// SourceView Action - requesting content assist to
		// show completetion
		// proposals for the current insert position
		action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS + UNDERSCORE, this, ISourceViewer.CONTENTASSIST_PROPOSALS, true);
		helpSystem.setHelp(action, IHelpContextIds.CONTMNU_CONTENTASSIST_HELPID);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_PROPOSALS);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS, true);
		// SourceView Action - requesting content assist to
		// show the content
		// information for the current insert position
		action = new TextOperationAction(SSEUIMessages.getResourceBundle(), StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION + UNDERSCORE, this, ISourceViewer.CONTENTASSIST_CONTEXT_INFORMATION);
		action.setActionDefinitionId(ITextEditorActionDefinitionIds.CONTENT_ASSIST_CONTEXT_INFORMATION);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_CONTEXT_INFORMATION, true);
		// StructuredTextViewer Action - requesting
		// correction assist to show
		// correction proposals for the current position
		action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX + UNDERSCORE, this, StructuredTextViewer.QUICK_FIX, true);
		action.setActionDefinitionId(ActionDefinitionIds.QUICK_FIX);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_QUICK_FIX, true);
		// StructuredTextViewer Action - requesting format
		// of the whole
		// document
		action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT + UNDERSCORE, this, StructuredTextViewer.FORMAT_DOCUMENT);
		helpSystem.setHelp(action, IHelpContextIds.CONTMNU_FORMAT_DOC_HELPID);
		action.setActionDefinitionId(ActionDefinitionIds.FORMAT_DOCUMENT);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, true);
		markAsSelectionDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_DOCUMENT, true);
		// StructuredTextViewer Action - requesting format
		// of the active
		// elements
		action = new TextOperationAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS + UNDERSCORE, this, StructuredTextViewer.FORMAT_ACTIVE_ELEMENTS);
		helpSystem.setHelp(action, IHelpContextIds.CONTMNU_FORMAT_ELEMENTS_HELPID);
		action.setActionDefinitionId(ActionDefinitionIds.FORMAT_ACTIVE_ELEMENTS);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, action);
		markAsStateDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, true);
		markAsSelectionDependentAction(StructuredTextEditorActionConstants.ACTION_NAME_FORMAT_ACTIVE_ELEMENTS, true);

		// StructuredTextEditor Action - add breakpoints (falling back to the
		// current double-click if they can't be added)
		action = new ToggleBreakpointAction(this, getVerticalRuler());
		setAction(ActionDefinitionIds.TOGGLE_BREAKPOINTS, action);
		// StructuredTextEditor Action - manage breakpoints
		action = new ManageBreakpointAction(this, getVerticalRuler());
		setAction(ActionDefinitionIds.MANAGE_BREAKPOINTS, action);
		// StructuredTextEditor Action - edit breakpoints
		action = new EditBreakpointAction(this, getVerticalRuler());
		setAction(ActionDefinitionIds.EDIT_BREAKPOINTS, action);
		// StructuredTextViewer Action - open file on selection
		action = new OpenHyperlinkAction(resourceBundle, StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE + UNDERSCORE, this, getSourceViewer());
		action.setActionDefinitionId(ActionDefinitionIds.OPEN_FILE);
		setAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE, action);

		computeAndSetDoubleClickAction();

		fShowPropertiesAction = new ShowPropertiesAction();
		fFoldingGroup = new FoldingActionGroup(this, getSourceViewer());
	}

	protected LineChangeHover createChangeHover() {
		return new StructuredLineChangeHover();
	}

	protected ICharacterPairMatcher createCharacterPairMatcher() {
		ICharacterPairMatcher matcher = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; matcher == null && i < ids.length; i++) {
			matcher = (ICharacterPairMatcher) builder.getConfiguration(DocumentRegionEdgeMatcher.ID, ids[i]);
		}
		if (matcher == null) {
			matcher = new ICharacterPairMatcher() {

				public void clear() {
				}

				public void dispose() {
				}

				public int getAnchor() {
					return ICharacterPairMatcher.LEFT;
				}

				public IRegion match(IDocument iDocument, int i) {
					return null;
				}
			};
		}
		return matcher;
	}

	/**
	 * Create a preference store that combines the source editor preferences
	 * with the base editor's preferences.
	 * 
	 * @return IPreferenceStore
	 */
	private IPreferenceStore createCombinedPreferenceStore() {
		IPreferenceStore sseEditorPrefs = SSEUIPlugin.getDefault().getPreferenceStore();
		IPreferenceStore baseEditorPrefs = EditorsUI.getPreferenceStore();
		return new ChainedPreferenceStore(new IPreferenceStore[]{sseEditorPrefs, baseEditorPrefs});
	}

	private ContentOutlineConfiguration createContentOutlineConfiguration() {
		ContentOutlineConfiguration cfg = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; cfg == null && i < ids.length; i++) {
			cfg = (ContentOutlineConfiguration) builder.getConfiguration(ExtendedConfigurationBuilder.CONTENTOUTLINECONFIGURATION, ids[i]);
		}
		return cfg;
	}

	/**
	 * Only gets the correction assistant associted with the current source
	 * viewer configuration.
	 * 
	 * @return IContentAssistant or null
	 */
	private IContentAssistant createCorrectionAssistant() {
		IContentAssistant assist = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		CorrectionAssistantProvider provider = (CorrectionAssistantProvider) builder.getConfiguration("correctionassistant", fViewerConfigurationTargetId); //$NON-NLS-1$
		if (provider != null) {
			assist = provider.getCorrectionAssistant(getSourceViewer());
		}
		return assist;
	}

	protected void createModelDependentFields() {
		// none at this level
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Use StructuredTextViewerConfiguration if a viewerconfiguration has not
	 * already been set. Also initialize StructuredTextViewer.
	 * </p>
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#createPartControl(org.eclipse.swt.widgets.Composite)
	 */
	public void createPartControl(Composite parent) {
		if (getSourceViewerConfiguration() == null) {
			ConfigurationAndTarget cat = createSourceViewerConfiguration();
			fViewerConfigurationTargetId = cat.getTargetId();
			StructuredTextViewerConfiguration newViewerConfiguration = cat.getConfiguration();
			setSourceViewerConfiguration(newViewerConfiguration);
		}

		super.createPartControl(parent);

		// instead of calling setInput twice, use initializeSourceViewer() to
		// handle source viewer initialization previously handled by setInput
		initializeSourceViewer();

		// update editor context menu, vertical ruler context menu, infopop
		if (getInternalModel() != null) {
			updateEditorControlsForContentType(getInternalModel().getContentTypeIdentifier());
		}
		else {
			updateEditorControlsForContentType(null);
		}

		// used for Show Tooltip Description
		IInformationControlCreator informationControlCreator = new IInformationControlCreator() {
			public IInformationControl createInformationControl(Shell shell) {
				boolean cutDown = false;
				int style = cutDown ? SWT.NONE : (SWT.V_SCROLL | SWT.H_SCROLL);
				return new DefaultInformationControl(shell, SWT.RESIZE | SWT.TOOL, style, new HTMLTextPresenter(cutDown));
			}
		};

		fInformationPresenter = new InformationPresenter(informationControlCreator);
		fInformationPresenter.setSizeConstraints(60, 10, true, true);
		fInformationPresenter.install(getSourceViewer());
	}

	protected PropertySheetConfiguration createPropertySheetConfiguration() {
		PropertySheetConfiguration cfg = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; cfg == null && i < ids.length; i++) {
			cfg = (PropertySheetConfiguration) builder.getConfiguration(ExtendedConfigurationBuilder.PROPERTYSHEETCONFIGURATION, ids[i]);
		}
		return cfg;
	}

	/**
	 * Loads the Show In Target IDs from the Extended Configuration extension
	 * point.
	 * 
	 * @return
	 */
	private String[] createShowInTargetIds() {
		List allIds = new ArrayList(0);
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] configurationIds = getConfigurationPoints();
		for (int i = 0; i < configurationIds.length; i++) {
			String[] definitions = builder.getDefinitions("showintarget", configurationIds[i]); //$NON-NLS-1$
			for (int j = 0; j < definitions.length; j++) {
				String someIds = definitions[j];
				if (someIds != null && someIds.length() > 0) {
					String[] ids = StringUtils.unpack(someIds);
					for (int k = 0; k < ids.length; k++) {
						// trim, just to keep things clean
						String id = ids[k].trim();
						if (!allIds.contains(id)) {
							allIds.add(id);
						}
					}
				}
			}
		}

		if (!allIds.contains(IPageLayout.ID_RES_NAV)) {
			allIds.add(IPageLayout.ID_RES_NAV);
		}
		if (!allIds.contains(IPageLayout.ID_OUTLINE)) {
			allIds.add(IPageLayout.ID_OUTLINE);
		}
		return (String[]) allIds.toArray(new String[0]);
	}

	/**
	 * @return
	 */
	private ISourceEditingTextTools createSourceEditingTextTools() {
		ISourceEditingTextTools tools = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; tools == null && i < ids.length; i++) {
			tools = (ISourceEditingTextTools) builder.getConfiguration(NullSourceEditingTextTools.ID, ids[i]);
		}
		if (tools == null) {
			tools = NullSourceEditingTextTools.getInstance();
			((NullSourceEditingTextTools) tools).setTextEditor(this);
		}
		Method method = null; //$NON-NLS-1$
		try {
			method = tools.getClass().getMethod("setTextEditor", new Class[]{StructuredTextEditor.class}); //$NON-NLS-1$
		}
		catch (NoSuchMethodException e) {
		}
		if (method == null) {
			try {
				method = tools.getClass().getMethod("setTextEditor", new Class[]{ITextEditor.class}); //$NON-NLS-1$
			}
			catch (NoSuchMethodException e) {
			}
		}
		if (method == null) {
			try {
				method = tools.getClass().getMethod("setTextEditor", new Class[]{IEditorPart.class}); //$NON-NLS-1$
			}
			catch (NoSuchMethodException e) {
			}
		}
		if (method != null) {
			if (!method.isAccessible()) {
				method.setAccessible(true);
			}
			try {
				method.invoke(tools, new Object[]{this});
			}
			catch (Exception e) {
				Logger.logException("Problem creating ISourceEditingTextTools implementation", e); //$NON-NLS-1$
			}
		}

		return tools;
	}

	/**
	 * Creates the source viewer to be used by this editor
	 */
	protected ISourceViewer createSourceViewer(Composite parent, IVerticalRuler verticalRuler, int styles) {
		fAnnotationAccess = createAnnotationAccess();
		fOverviewRuler = createOverviewRuler(getSharedColors());
		StructuredTextViewer sourceViewer = createStructedTextViewer(parent, verticalRuler, styles);
		initSourceViewer(sourceViewer);
		return sourceViewer;
	}

	private ConfigurationAndTarget createSourceViewerConfiguration() {
		ConfigurationAndTarget cat = null;
		StructuredTextViewerConfiguration cfg = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; cfg == null && i < ids.length; i++) {
			cfg = (StructuredTextViewerConfiguration) builder.getConfiguration(ExtendedConfigurationBuilder.SOURCEVIEWERCONFIGURATION, ids[i]);
			cat = new ConfigurationAndTarget(ids[i], cfg);
		}
		if (cfg == null) {
			cfg = new StructuredTextViewerConfiguration();
			String targetid = getClass().getName() + "#default"; //$NON-NLS-1$
			cat = new ConfigurationAndTarget(targetid, cfg);
		}
		return cat;
	}

	protected StructuredTextViewer createStructedTextViewer(Composite parent, IVerticalRuler verticalRuler, int styles) {
		return new StructuredTextViewer(parent, verticalRuler, getOverviewRuler(), isOverviewRulerVisible(), styles);
	}

	protected void createUndoRedoActions() {
		// overridden to add icons to actions
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=111877
		super.createUndoRedoActions();
		IAction action = getAction(ITextEditorActionConstants.UNDO);
		if (action != null) {
			action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_UNDO));
		}

		action = getAction(ITextEditorActionConstants.REDO);
		if (action != null) {
			action.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().getImageDescriptor(ISharedImages.IMG_TOOL_REDO));
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IWorkbenchPart#dispose()
	 */
	public void dispose() {
		Logger.trace("Source Editor", "StructuredTextEditor::dispose entry"); //$NON-NLS-1$ //$NON-NLS-2$
		if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) {
			System.out.println("Total calls to getAdapter: " + adapterRequests); //$NON-NLS-1$
			System.out.println("Total time in getAdapter: " + adapterTime); //$NON-NLS-1$
			System.out.println("Average time per call: " + (adapterTime / adapterRequests)); //$NON-NLS-1$
		}

		// dispose of information presenter
		if (fInformationPresenter != null) {
			fInformationPresenter.dispose();
			fInformationPresenter = null;
		}

		// dispose of selection history
		if (fSelectionHistory != null) {
			fSelectionHistory.dispose();
			fSelectionHistory = null;
		}

		// dispose of document folding support
		if (fProjectionModelUpdater != null) {
			fProjectionModelUpdater.uninstall();
			fProjectionModelUpdater = null;
		}

		if (fProjectionSupport != null) {
			fProjectionSupport.dispose();
			fProjectionSupport = null;
		}

		if (fFoldingGroup != null) {
			fFoldingGroup.dispose();
			fFoldingGroup = null;
		}

		// subclass may not have mouse tracker created
		// need to check for null before stopping
		if (fMouseTracker != null) {
			fMouseTracker.stop();
			fMouseTracker = null;
		}

		// dispose of menus that were being tracked
		if (fTextContextMenu != null) {
			fTextContextMenu.dispose();
		}
		if (fRulerContextMenu != null) {
			fRulerContextMenu.dispose();
		}
		if (fTextContextMenuManager != null) {
			fTextContextMenuManager.removeMenuListener(getContextMenuListener());
			fTextContextMenuManager.removeAll();
			fTextContextMenuManager.dispose();
		}
		if (fRulerContextMenuManager != null) {
			fRulerContextMenuManager.removeMenuListener(getContextMenuListener());
			fRulerContextMenuManager.removeAll();
			fRulerContextMenuManager.dispose();
		}

		// added this 2/20/2004 based on probe results --
		// seems should be handled by setModel(null), but
		// that's a more radical change.
		// and, technically speaking, should not be needed,
		// but makes a memory leak
		// less severe.
		if (fStructuredModel != null) {
			if (fStructuredModel.getStructuredDocument() != null) {
				fStructuredModel.getStructuredDocument().removeDocumentListener(getInternalDocumentListener());
			}
			fStructuredModel.removeModelStateListener(getInternalModelStateListener());
		}

		IDocument doc = getDocumentProvider().getDocument(getEditorInput());
		if (doc != null) {
			doc.removeDocumentListener(getInternalDocumentListener());
			if (doc instanceof IExecutionDelegatable) {
				((IExecutionDelegatable) doc).setExecutionDelegate(null);
			}
		}

		// some things in the configuration need to clean
		// up after themselves
		if (fOutlinePage != null) {
			if (fOutlinePage instanceof ConfigurableContentOutlinePage && fOutlinePageListener != null) {
				((ConfigurableContentOutlinePage) fOutlinePage).removeDoubleClickListener(fOutlinePageListener);
			}
			if (fOutlinePageListener != null) {
				fOutlinePage.removeSelectionChangedListener(fOutlinePageListener);
			}
		}

		fEditorDisposed = true;
		disposeModelDependentFields();

		if (fDropTarget != null)
			fDropTarget.dispose();

		setPreferenceStore(null);

		// strictly speaking, but following null outs
		// should not be needed,
		// but in the event of a memory leak, they make the
		// memory leak less
		// severe
		fDropAdapter = null;
		fDropTarget = null;

		super.dispose();

		Logger.trace("Source Editor", "StructuredTextEditor::dispose exit"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#disposeDocumentProvider()
	 */
	protected void disposeDocumentProvider() {
		if (fStructuredModel != null && !fisReleased && !(getDocumentProvider() instanceof IModelProvider)) {
			fStructuredModel.releaseFromEdit();
			fisReleased = true;
		}
		super.disposeDocumentProvider();
	}

	/**
	 * Disposes model specific editor helpers such as statusLineHelper.
	 * Basically any code repeated in update() & dispose() should be placed
	 * here.
	 */
	private void disposeModelDependentFields() {
		// none at this level
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.ITextEditor#doRevertToSaved()
	 */
	public void doRevertToSaved() {
		super.doRevertToSaved();
		if (fOutlinePage != null && fOutlinePage instanceof IUpdate) {
			((IUpdate) fOutlinePage).update();
		}
		// reset undo
		IDocument doc = getDocumentProvider().getDocument(getEditorInput());
		if (doc instanceof IStructuredDocument) {
			((IStructuredDocument) doc).getUndoManager().getCommandStack().flush();
		}

		// update menu text
		updateMenuText();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.ISaveablePart#doSave(org.eclipse.core.runtime.IProgressMonitor)
	 */
	public void doSave(IProgressMonitor progressMonitor) {
		try {
			aboutToSaveModel();
			updateEncodingMemento();
			super.doSave(progressMonitor);
		}
		finally {
			savedModel();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#doSetInput(org.eclipse.ui.IEditorInput)
	 */
	protected void doSetInput(IEditorInput input) throws CoreException {
		try {
			// TODO: if opened in more than one editor, this will cause
			// problems.
			IEditorInput oldInput = getEditorInput();
			if (oldInput != null) {
				IDocument olddoc = getDocumentProvider().getDocument(oldInput);
				if (olddoc != null && olddoc instanceof IExecutionDelegatable) {
					((IExecutionDelegatable) olddoc).setExecutionDelegate(null);
				}
			}

			if (fStructuredModel != null && !(getDocumentProvider() instanceof IModelProvider)) {
				fStructuredModel.releaseFromEdit();
			}

			super.doSetInput(input);

			IDocument newDocument = getDocumentProvider().getDocument(input);
			if (newDocument instanceof IExecutionDelegatable) {
				((IExecutionDelegatable) newDocument).setExecutionDelegate(new EditorExecutionContext(this));
			}

			IStructuredModel model = null;
			// if we have a Model provider, get the model from it
			if (getDocumentProvider() instanceof IModelProvider) {
				model = ((IModelProvider) getDocumentProvider()).getModel(getEditorInput());
				if (!model.isShared()) {
					EditorModelUtil.addFactoriesTo(model);
				}
			}
			else {
				if (newDocument instanceof IStructuredDocument) {
					// corresponding releaseFromEdit occurs in
					// dispose()
					model = StructuredModelManager.getModelManager().getModelForEdit((IStructuredDocument) newDocument);
					EditorModelUtil.addFactoriesTo(model);
				}

				else {
					logUnexpectedDocumentKind(input);
				}
			}

			if (fStructuredModel != null || model != null) {
				setModel(model);
			}

			if (getInternalModel() != null) {
				updateEditorControlsForContentType(getInternalModel().getContentTypeIdentifier());
			}
			else {
				updateEditorControlsForContentType(null);
			}

			if (fProjectionModelUpdater != null)
				fProjectionModelUpdater.initialize();

			// start editor with smart insert mode
			setInsertMode(SMART_INSERT);
		}
		catch (CoreException exception) {
			// dispose editor
			dispose();

			throw new CoreException(exception.getStatus());
		}
	}

	/**
	 * Sets up this editor's context menu before it is made visible.
	 * <p>
	 * Not API. May be reduced to protected method in the future.
	 * </p>
	 * 
	 * @param menu
	 *            the menu
	 */
	public void editorContextMenuAboutToShow(IMenuManager menu) {
		// To be consistant with the Java Editor, we want
		// to remove
		// ShiftRight and ShiftLeft from the context menu.
		//
		// ShiftRight and ShiftLeft were added in the super
		// implemenation of
		// this method. We want to skip it and call
		// AbstractTextEditor's
		// implementation directly. The easiest way is to
		// copy the method here.

		// super.editorContextMenuAboutToShow(menu);
		abstractTextEditorContextMenuAboutToShow(menu);

		addContextMenuActions(menu);
		addExtendedContextMenuActions(menu);
	}

	/**
	 * End background mode.
	 * <p>
	 * Not API. May be removed in the future.
	 * </p>
	 */
	void endBackgroundOperation() {
		fBackgroundJobEnded = true;
		// note, we don't immediately end our 'internal busy' state,
		// since we may get many calls in a short period of
		// time. We always wait for the time out.
		resetBusyState();
	}

	/**
	 * Note this method can be called indirectly from background job operation
	 * ... but expected to be gaurded there with ILock, plus, can be called
	 * directly from timer thread, so the timer's run method guards with ILock
	 * too.
	 */
	private void endBusyStateInternal() {
		if (fBackgroundJobEnded) {
			fBusyTimer.cancel();
			showBusy(false);

			ISourceViewer viewer = getSourceViewer();
			if (viewer instanceof StructuredTextViewer) {
				((StructuredTextViewer) viewer).endBackgroundUpdate();
			}
			fBusyState = false;
		}
		else {
			// we will only be in this branch for a back ground job that is
			// taking
			// longer than our normal time-out period (meaning we got notified
			// of
			// the timeout "inbetween" calls to 'begin' and
			// 'endBackgroundOperation'.
			// (which, remember, can only happen since there are many calls to
			// begin/end in a short period of time, and we only "reset" on the
			// 'ends').
			// In this event, there's really nothing to do, we're still in
			// "busy state"
			// and should start a new reset cycle once endBackgroundjob is
			// called.
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
	 */
	public Object getAdapter(Class required) {
		if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) {
			startPerfTime = System.currentTimeMillis();
		}
		Object result = null;
		// text editor
		IStructuredModel internalModel = getInternalModel();
		if (ITextEditor.class.equals(required)) {
			result = this;
		}
		else if (IWorkbenchSiteProgressService.class.equals(required)) {
			return getEditorPart().getSite().getAdapter(IWorkbenchSiteProgressService.class);
		}
		// content outline page
		else if (IContentOutlinePage.class.equals(required)) {
			if (fOutlinePage == null || fOutlinePage.getControl() == null || fOutlinePage.getControl().isDisposed()) {
				ContentOutlineConfiguration cfg = createContentOutlineConfiguration();
				if (cfg != null) {
					ConfigurableContentOutlinePage outlinePage = new ConfigurableContentOutlinePage();
					outlinePage.setConfiguration(cfg);
					if (internalModel != null) {
						outlinePage.setInputContentTypeIdentifier(internalModel.getContentTypeIdentifier());
						outlinePage.setInput(internalModel);
					}

					if (fOutlinePageListener == null) {
						fOutlinePageListener = new OutlinePageListener();
					}

					outlinePage.addSelectionChangedListener(fOutlinePageListener);
					outlinePage.addDoubleClickListener(fOutlinePageListener);

					fOutlinePage = outlinePage;
				}
			}
			result = fOutlinePage;
		}
		// property sheet page, but only if the input's editable
		else if (IPropertySheetPage.class.equals(required) && isEditable()) {
			if (fPropertySheetPage == null || fPropertySheetPage.getControl() == null || fPropertySheetPage.getControl().isDisposed()) {
				PropertySheetConfiguration cfg = createPropertySheetConfiguration();
				if (cfg != null) {
					ConfigurablePropertySheetPage propertySheetPage = new ConfigurablePropertySheetPage();
					propertySheetPage.setConfiguration(cfg);
					fPropertySheetPage = propertySheetPage;
				}
			}
			result = fPropertySheetPage;
		}
		else if (IDocument.class.equals(required)) {
			result = getDocumentProvider().getDocument(getEditorInput());
		}
		else if (ISourceEditingTextTools.class.equals(required)) {
			result = createSourceEditingTextTools();
		}
		else if (IToggleBreakpointsTarget.class.equals(required)) {
			result = ToggleBreakpointsTarget.getInstance();
		}
		else if (IShowInTargetList.class.equals(required)) {
			return new ShowInTargetListAdapter();
		}
		else if (SelectionHistory.class.equals(required)) {
			if (fSelectionHistory == null)
				fSelectionHistory = new SelectionHistory(this);
			return fSelectionHistory;
		}
		else {
			if (result == null && internalModel != null) {
				result = internalModel.getAdapter(required);
			}
			// others
			if (result == null)
				result = super.getAdapter(required);
		}
		if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) {
			long stop = System.currentTimeMillis();
			adapterRequests++;
			adapterTime += (stop - startPerfTime);
		}
		if (org.eclipse.wst.sse.core.internal.util.Debug.perfTestAdapterClassLoading) {
			System.out.println("Total calls to getAdapter: " + adapterRequests); //$NON-NLS-1$
			System.out.println("Total time in getAdapter: " + adapterTime); //$NON-NLS-1$
			System.out.println("Average time per call: " + (adapterTime / adapterRequests)); //$NON-NLS-1$
		}
		return result;
	}

	private String[] getConfigurationPoints() {
		String contentTypeIdentifierID = null;
		if (getInternalModel() != null) {
			contentTypeIdentifierID = getInternalModel().getContentTypeIdentifier();
		}
		return ConfigurationPointCalculator.getConfigurationPoints(this, contentTypeIdentifierID, ConfigurationPointCalculator.SOURCE, StructuredTextEditor.class);
	}

	/**
	 * added checks to overcome bug such that if we are shutting down in an
	 * error condition, then viewer will have already been disposed.
	 */
	protected String getCursorPosition() {
		String result = null;
		// this may be too expensive in terms of
		// performance, to do this check
		// every time, just to gaurd against error
		// condition.
		// perhaps there's a better way?
		if (getSourceViewer() != null && getSourceViewer().getTextWidget() != null && !getSourceViewer().getTextWidget().isDisposed()) {
			result = super.getCursorPosition();
		}
		else {
			result = "0:0"; //$NON-NLS-1$
		}
		return result;
	}


	Display getDisplay() {
		return PlatformUI.getWorkbench().getDisplay();
	}

	/**
	 * Returns this editor part.
	 * <p>
	 * Not API. May be removed in the future.
	 * </p>
	 * 
	 * @return this editor part
	 */
	public IEditorPart getEditorPart() {
		if (fEditorPart == null)
			return this;
		return fEditorPart;
	}

	private IDocumentListener getInternalDocumentListener() {
		if (fInternalDocumentListener == null) {
			fInternalDocumentListener = new InternalDocumentListener();
		}
		return fInternalDocumentListener;
	}

	IStructuredModel getInternalModel() {
		return fStructuredModel;
	}

	private InternalModelStateListener getInternalModelStateListener() {
		if (fInternalModelStateListener == null) {
			fInternalModelStateListener = new InternalModelStateListener();
		}
		return fInternalModelStateListener;
	}

	/**
	 * Returns this editor's StructuredModel.
	 * <p>
	 * Not API. Will be removed in the future.
	 * </p>
	 * 
	 * @return returns this editor's IStructuredModel
	 * @deprecated - This method allowed for uncontrolled access to the model
	 *             instance and will be removed in the future. It is
	 *             recommended that the current document provider be asked for
	 *             the current document and the IModelManager then asked for
	 *             the corresponding model with
	 *             getExistingModelFor*(IDocument).
	 */
	public IStructuredModel getModel() {
		if (getDocumentProvider() == null) {
			// this indicated an error in startup sequence
			Logger.trace(getClass().getName(), "Program Info Only: document provider was null when model requested"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		boolean initialModelNull = false;
		if (fStructuredModel == null)
			initialModelNull = true;
		if (fStructuredModel == null) {
			// lazily set the model instance, although this is an ABNORMAL
			// CODE PATH
			if (getDocumentProvider() instanceof IModelProvider) {
				fStructuredModel = ((IModelProvider) getDocumentProvider()).getModel(getEditorInput());
				fisReleased = false;
			}
			else {
				IDocument doc = getDocumentProvider().getDocument(getEditorInput());
				if (doc instanceof IStructuredDocument) {
					IStructuredModel model = StructuredModelManager.getModelManager().getExistingModelForEdit(doc);
					if (model == null) {
						model = StructuredModelManager.getModelManager().getModelForEdit((IStructuredDocument) doc);
					}
					fStructuredModel = model;
					fisReleased = false;
				}
			}

			// ISSUE: this looks bad ... edit-time factories not initialized
			// unless someone calls getModel?
			// factories will not be re-added if already exists
			EditorModelUtil.addFactoriesTo(fStructuredModel);

			if (initialModelNull && fStructuredModel != null) {
				/*
				 * DMW: 9/1/2002 -- why is update called here? No change has
				 * been indicated? I'd like to remove, but will leave for now
				 * to avoid breaking this hack. Should measure/breakpoint to
				 * see how large the problem is. May cause performance
				 * problems.
				 * 
				 * DMW: 9/8/2002 -- not sure why this was here initially, but
				 * the intent/hack must have been to call update if this was
				 * the first time fStructuredModel was set. So, I added the
				 * logic to check for that "first time" case. It would appear
				 * we don't really need. may remove in future when can test
				 * more.
				 */
				update();
			}
		}
		return fStructuredModel;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.IWorkbenchPartOrientation#getOrientation()
	 */
	public int getOrientation() {
		// https://bugs.eclipse.org/bugs/show_bug.cgi?id=88714
		return SWT.LEFT_TO_RIGHT;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.ITextEditor#getSelectionProvider()
	 */
	public ISelectionProvider getSelectionProvider() {
		if (fStructuredSelectionProvider == null) {
			ISelectionProvider parentProvider = super.getSelectionProvider();
			if (parentProvider != null) {
				fStructuredSelectionProvider = new StructuredSelectionProvider(parentProvider, this);
			}
		}
		if (fStructuredSelectionProvider == null) {
			return super.getSelectionProvider();
		}
		return fStructuredSelectionProvider;
	}

	/**
	 * Returns the editor's source viewer. This method was created to expose
	 * the protected final getSourceViewer() method.
	 * <p>
	 * Not API. May be removed in the future.
	 * </p>
	 * 
	 * @return the editor's source viewer
	 */
	public StructuredTextViewer getTextViewer() {
		return (StructuredTextViewer) getSourceViewer();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#handleCursorPositionChanged()
	 */
	protected void handleCursorPositionChanged() {
		super.handleCursorPositionChanged();
		updateStatusField(StructuredTextEditorActionConstants.STATUS_CATEGORY_OFFSET);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#handlePreferenceStoreChanged(org.eclipse.jface.util.PropertyChangeEvent)
	 */
	protected void handlePreferenceStoreChanged(PropertyChangeEvent event) {
		String property = event.getProperty();

		if (EditorPreferenceNames.EDITOR_TEXT_HOVER_MODIFIERS.equals(property)) {
			updateHoverBehavior();
		}

		if (IStructuredTextFoldingProvider.FOLDING_ENABLED.equals(property)) {
			if (getSourceViewer() instanceof ProjectionViewer) {
				// install projection support if it has not even been
				// installed yet
				if (isFoldingEnabled() && (fProjectionSupport == null) && (fProjectionModelUpdater == null)) {
					installProjectionSupport();
				}
				ProjectionViewer pv = (ProjectionViewer) getSourceViewer();
				if (pv.isProjectionMode() != isFoldingEnabled()) {
					if (pv.canDoOperation(ProjectionViewer.TOGGLE))
						pv.doOperation(ProjectionViewer.TOGGLE);
				}
			}
			return;
		}
		super.handlePreferenceStoreChanged(event);
	}

	private boolean inBusyState() {
		return fBusyState;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.IEditorPart#init(org.eclipse.ui.IEditorSite,
	 *      org.eclipse.ui.IEditorInput)
	 */
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		// if we've gotten an error elsewhere, before
		// we've actually opened, then don't open.
		if (shouldClose) {
			setSite(site);
			close(false);
		}
		else {
			super.init(site, input);
		}
	}

	/**
	 * Set the document provider for this editor.
	 * <p>
	 * Not API. May be removed in the future.
	 * </p>
	 * 
	 * @param documentProvider
	 *            documentProvider to initialize
	 */
	public void initializeDocumentProvider(IDocumentProvider documentProvider) {
		if (documentProvider != null) {
			setDocumentProvider(documentProvider);
		}
	}

	protected void initializeDrop(ITextViewer textViewer) {
		int operations = DND.DROP_COPY | DND.DROP_MOVE;
		fDropTarget = new DropTarget(textViewer.getTextWidget(), operations);
		fDropAdapter = new ReadOnlyAwareDropTargetAdapter(true);
		fDropAdapter.setTargetEditor(this);
		fDropAdapter.setTargetIDs(getConfigurationPoints());
		fDropAdapter.setTextViewer(textViewer);
		fDropTarget.setTransfer(fDropAdapter.getTransfers());
		fDropTarget.addDropListener(fDropAdapter);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#initializeEditor()
	 */
	protected void initializeEditor() {
		super.initializeEditor();
		// FIXME: here's where to add back in our custom encoding support
		fEncodingSupport = null;
		setPreferenceStore(createCombinedPreferenceStore());

		setRangeIndicator(new DefaultRangeIndicator());
		setEditorContextMenuId(EDITOR_CONTEXT_MENU_ID);
		initializeDocumentProvider(null);
		// set the infopop for source viewer
		String helpId = getHelpContextId();
		// no infopop set or using default text editor help, use default
		if (helpId == null || ITextEditorHelpContextIds.TEXT_EDITOR.equals(helpId))
			helpId = IHelpContextIds.XML_SOURCE_VIEW_HELPID;
		setHelpContextId(helpId);
		// defect 203158 - disable ruler context menu for
		// beta
		// setRulerContextMenuId(RULER_CONTEXT_MENU_ID);
		configureInsertMode(SMART_INSERT, true);

		// enable the base source editor activity when editor opens
		try {
			// FIXME: - commented out to avoid minor dependancy during
			// transition to org.eclipse
			// WTPActivityBridge.getInstance().enableActivity(CORE_SSE_ACTIVITY_ID,
			// true);
		}
		catch (Exception t) {
			// if something goes wrong with enabling activity, just log the
			// error but dont
			// have it break the editor
			Logger.log(Logger.WARNING_DEBUG, t.getMessage(), t);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.editors.text.TextEditor#initializeKeyBindingScopes()
	 */
	protected void initializeKeyBindingScopes() {
		setKeyBindingScopes(new String[]{EDITOR_KEYBINDING_SCOPE_ID});
	}

	/**
	 * Initializes the editor's source viewer and other items that were source
	 * viewer-dependent.
	 */
	private void initializeSourceViewer() {
		IAction contentAssistAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS);
		if (contentAssistAction instanceof IUpdate) {
			((IUpdate) contentAssistAction).update();
		}
		IAction openHyperlinkAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE);
		if (openHyperlinkAction instanceof OpenHyperlinkAction) {
			((OpenHyperlinkAction) openHyperlinkAction).setHyperlinkDetectors(getSourceViewerConfiguration().getHyperlinkDetectors(getSourceViewer()));
		}

		// do not even install projection support until folding is actually
		// enabled
		if (isFoldingEnabled()) {
			installProjectionSupport();
		}

		// initialize source viewer's correction assistant
		IContentAssistant correctionAssistant = createCorrectionAssistant();
		getTextViewer().setCorrectionAssistant(correctionAssistant);
	}

	protected void initSourceViewer(StructuredTextViewer sourceViewer) {
		// ensure decoration support is configured
		getSourceViewerDecorationSupport(sourceViewer);
		fMouseTracker = new MouseTracker();
		fMouseTracker.start(sourceViewer.getTextWidget());
		initializeDrop(sourceViewer);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.editors.text.TextEditor#installEncodingSupport()
	 */
	protected void installEncodingSupport() {
		// TODO: install our custom support that can
		// update document appropriately
		// super.installEncodingSupport();
	}

	/**
	 * Install everything necessary to get document folding working and enable
	 * document folding
	 */
	private void installProjectionSupport() {
		ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();

		fProjectionSupport = new ProjectionSupport(projectionViewer, getAnnotationAccess(), getSharedColors());
		fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.error"); //$NON-NLS-1$
		fProjectionSupport.addSummarizableAnnotationType("org.eclipse.ui.workbench.texteditor.warning"); //$NON-NLS-1$
		fProjectionSupport.setHoverControlCreator(new IInformationControlCreator() {
			public IInformationControl createInformationControl(Shell parent) {
				return new DefaultInformationControl(parent);
			}
		});
		fProjectionSupport.install();

		IStructuredTextFoldingProvider updater = null;
		ExtendedConfigurationBuilder builder = ExtendedConfigurationBuilder.getInstance();
		String[] ids = getConfigurationPoints();
		for (int i = 0; updater == null && i < ids.length; i++) {
			updater = (IStructuredTextFoldingProvider) builder.getConfiguration(IStructuredTextFoldingProvider.ID, ids[i]);
		}

		fProjectionModelUpdater = updater;
		if (fProjectionModelUpdater != null)
			fProjectionModelUpdater.install(projectionViewer);

		if (isFoldingEnabled())
			projectionViewer.doOperation(ProjectionViewer.TOGGLE);
	}

	/**
	 * Return whether document folding should be enabled according to the
	 * preference store settings.
	 * 
	 * @return <code>true</code> if document folding should be enabled
	 */
	private boolean isFoldingEnabled() {
		IPreferenceStore store = getPreferenceStore();
		// check both preference store and vm argument
		return (store.getBoolean(IStructuredTextFoldingProvider.FOLDING_ENABLED));
	}

	private void logUnexpectedDocumentKind(IEditorInput input) {
		// display a dialog informing user of uknown content type
		if (SSEUIPlugin.getDefault().getPreferenceStore().getBoolean(EditorPreferenceNames.SHOW_UNKNOWN_CONTENT_TYPE_MSG)) {
			Job job = new UIJob(SSEUIMessages.StructuredTextEditor_0) {
				public IStatus runInUIThread(IProgressMonitor monitor) {
					UnknownContentTypeDialog dialog = new UnknownContentTypeDialog(getSite().getShell(), SSEUIPlugin.getDefault().getPreferenceStore(), EditorPreferenceNames.SHOW_UNKNOWN_CONTENT_TYPE_MSG);
					dialog.open();
					return Status.OK_STATUS;
				}
			};
			job.schedule();
		}

		Logger.log(Logger.WARNING, "StructuredTextEditor being used without StructuredDocument"); //$NON-NLS-1$
		String name = null;
		if (input != null) {
			name = input.getName();
		}
		else {
			name = "input was null"; //$NON-NLS-1$
		}
		Logger.log(Logger.WARNING, "         Input Name: " + name); //$NON-NLS-1$
		String implClass = null;
		IDocument document = getDocumentProvider().getDocument(input);
		if (document != null) {
			implClass = document.getClass().getName();
		}
		else {
			implClass = "document was null"; //$NON-NLS-1$
		}
		Logger.log(Logger.WARNING, "        Unexpected IDocumentProvider implementation: " + getDocumentProvider().getClass().getName()); //$NON-NLS-1$
		Logger.log(Logger.WARNING, "        Unexpected IDocument implementation: " + implClass); //$NON-NLS-1$
	}

	/*
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#performRevert()
	 */
	protected void performRevert() {
		ProjectionViewer projectionViewer = (ProjectionViewer) getSourceViewer();
		projectionViewer.setRedraw(false);
		try {

			boolean projectionMode = projectionViewer.isProjectionMode();
			if (projectionMode) {
				projectionViewer.disableProjection();
				if (fProjectionModelUpdater != null)
					fProjectionModelUpdater.uninstall();
			}

			super.performRevert();

			if (projectionMode) {
				if (fProjectionModelUpdater != null)
					fProjectionModelUpdater.install(projectionViewer);
				projectionViewer.enableProjection();
			}

		}
		finally {
			projectionViewer.setRedraw(true);
		}
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Not API. May be reduced to protected method in the future.
	 * </p>
	 */
	public void rememberSelection() {
		/*
		 * This method was made public for use by editors that use
		 * StructuredTextEditor (like some clients)
		 */
		super.rememberSelection();
	}


	/**
	 * both starts and resets the busy state timer
	 */
	private void resetBusyState() {
		// reset the "busy" timeout
		if (fBusyTimer != null) {
			fBusyTimer.cancel();
		}
		startBusyTimer();
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Not API. May be reduced to protected method in the future.
	 * </p>
	 */
	public void restoreSelection() {
		/*
		 * This method was made public for use by editors that use
		 * StructuredTextEditor (like some clients)
		 */
		// catch odd case where source viewer has no text
		// widget (defect
		// 227670)
		if ((getSourceViewer() != null) && (getSourceViewer().getTextWidget() != null))
			super.restoreSelection();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#rulerContextMenuAboutToShow(org.eclipse.jface.action.IMenuManager)
	 */
	protected void rulerContextMenuAboutToShow(IMenuManager menu) {
		super.rulerContextMenuAboutToShow(menu);

		IMenuManager foldingMenu = new MenuManager(SSEUIMessages.Folding, "projection"); //$NON-NLS-1$
		menu.appendToGroup(ITextEditorActionConstants.GROUP_RULERS, foldingMenu);

		IAction action = getAction("FoldingToggle"); //$NON-NLS-1$
		foldingMenu.add(action);
		action = getAction("FoldingExpandAll"); //$NON-NLS-1$
		foldingMenu.add(action);
		action = getAction("FoldingCollapseAll"); //$NON-NLS-1$
		foldingMenu.add(action);

		IStructuredModel internalModel = getInternalModel();
		if (internalModel != null) {
			boolean debuggingAvailable = BreakpointProviderBuilder.getInstance().isAvailable(internalModel.getContentTypeIdentifier(), BreakpointRulerAction.getFileExtension(getEditorInput()));
			if (debuggingAvailable) {
				// append actions to "debug" group (created in
				// AbstractDecoratedTextEditor.rulerContextMenuAboutToShow(IMenuManager)
				menu.appendToGroup("debug", getAction(ActionDefinitionIds.TOGGLE_BREAKPOINTS)); //$NON-NLS-1$
				menu.appendToGroup("debug", getAction(ActionDefinitionIds.MANAGE_BREAKPOINTS)); //$NON-NLS-1$
				menu.appendToGroup("debug", getAction(ActionDefinitionIds.EDIT_BREAKPOINTS)); //$NON-NLS-1$
			}
			addExtendedRulerContextMenuActions(menu);
		}
	}

	/**
	 * {@inheritDoc}
	 * <p>
	 * Overridden to expose part activation handling for multi-page editors.
	 * </p>
	 * <p>
	 * Not API. May be reduced to protected method in the future.
	 * </p>
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractTextEditor#safelySanityCheckState(org.eclipse.ui.IEditorInput)
	 */
	public void safelySanityCheckState(IEditorInput input) {
		super.safelySanityCheckState(input);
	}

	private void savedModel() {
		if (getInternalModel() != null) {
			getInternalModel().changedModel();
		}
	}

	/**
	 * Ensure that the correct IDocumentProvider is used. For direct models, a
	 * special provider is used. For StorageEditorInputs, use a custom
	 * provider that creates a usable ResourceAnnotationModel. For everything
	 * else, use the base support.
	 * 
	 * @see org.eclipse.ui.texteditor.AbstractDecoratedTextEditor#setDocumentProvider(org.eclipse.ui.IEditorInput)
	 */
	protected void setDocumentProvider(IEditorInput input) {
		if (input instanceof IStructuredModel) {
			// largely untested
			setDocumentProvider(StructuredModelDocumentProvider.getInstance());
		}
		else if (input instanceof IStorageEditorInput && !(input instanceof IFileEditorInput) && !(input instanceof IPathEditorInput)) {
			setDocumentProvider(StorageModelProvider.getInstance());
		}
		else {
			super.setDocumentProvider(input);
		}
	}

	/**
	 * Set editor part associated with this editor.
	 * <p>
	 * Not API. May be removed in the future.
	 * </p>
	 * 
	 * @param editorPart
	 *            editor part associated with this editor
	 */
	public void setEditorPart(IEditorPart editorPart) {
		fEditorPart = editorPart;
	}

	/**
	 * Sets the model field within this editor.
	 * 
	 * @deprecated - can eventually be eliminated
	 */
	private void setModel(IStructuredModel newModel) {
		Assert.isNotNull(getDocumentProvider(), "document provider can not be null when setting model"); //$NON-NLS-1$
		if (fStructuredModel != null) {
			if (fStructuredModel.getStructuredDocument() != null) {
				fStructuredModel.getStructuredDocument().removeDocumentListener(getInternalDocumentListener());
			}
			fStructuredModel.removeModelStateListener(getInternalModelStateListener());
		}
		fStructuredModel = newModel;
		if (fStructuredModel != null) {
			if (fStructuredModel.getStructuredDocument() != null) {
				fStructuredModel.getStructuredDocument().addDocumentListener(getInternalDocumentListener());
			}
			fStructuredModel.addModelStateListener(getInternalModelStateListener());
		}
		// update() should be called whenever the model is
		// set or changed
		update();
	}

	/**
	 * Sets the editor's source viewer configuration which it uses to
	 * configure it's internal source viewer. This method was overwritten so
	 * that viewer configuration could be set after editor part was created.
	 */
	protected void setSourceViewerConfiguration(SourceViewerConfiguration config) {
		super.setSourceViewerConfiguration(config);
		StructuredTextViewer stv = getTextViewer();
		if (stv != null) {
			// there should be no need to unconfigure
			// before configure because
			// configure will
			// also unconfigure before configuring
			stv.unconfigure();
			stv.configure(config);

			// update source viewer's correction assistant as well
			IContentAssistant correctionAssistant = createCorrectionAssistant();
			stv.setCorrectionAssistant(correctionAssistant);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.ui.part.WorkbenchPart#showBusy(boolean)
	 */
	public void showBusy(boolean busy) {
		if (busy) {
			fRememberTitle = getPartName();
			// update title and/or fonts and/or background
			//
			// temp solution, for testing, uses "busy"
			setPartName(SSEUIMessages.busy); //$NON-NLS-1$
		}
		else {
			// reset to what it was
			setPartName(fRememberTitle);
		}
	}

	private void startBusyTimer() {
		// TODO: we need a resettable timer, so not so
		// many are created
		fBusyTimer = new Timer(true);
		fBusyTimer.schedule(new TimeOutExpired(), BUSY_STATE_DELAY);
	}

	/**
	 * Update should be called whenever the model is set or changed (as in
	 * swapped)
	 * <p>
	 * Not API. May be removed in the future.
	 * </p>
	 */
	public void update() {
		if (fOutlinePage != null && fOutlinePage instanceof ConfigurableContentOutlinePage) {
			ContentOutlineConfiguration cfg = createContentOutlineConfiguration();
			((ConfigurableContentOutlinePage) fOutlinePage).setConfiguration(cfg);
			IStructuredModel internalModel = getInternalModel();
			((ConfigurableContentOutlinePage) fOutlinePage).setInputContentTypeIdentifier(internalModel.getContentTypeIdentifier());
			((ConfigurableContentOutlinePage) fOutlinePage).setInput(internalModel);
		}
		if (fPropertySheetPage != null && fPropertySheetPage instanceof ConfigurablePropertySheetPage) {
			PropertySheetConfiguration cfg = createPropertySheetConfiguration();
			((ConfigurablePropertySheetPage) fPropertySheetPage).setConfiguration(cfg);
		}
		disposeModelDependentFields();

		fShowInTargetIds = createShowInTargetIds();

		updateSourceViewerConfiguration();
		
		if (fStructuredSelectionProvider != null) {
			fStructuredSelectionProvider.setDocument(getInternalModel().getStructuredDocument());
		}

		createModelDependentFields();
	}

	/**
	 * Updates all content dependent actions.
	 */
	protected void updateContentDependentActions() {
		super.updateContentDependentActions();
		// super.updateContentDependentActions only updates
		// the enable/disable
		// state of all
		// the content dependent actions.
		// StructuredTextEditor's undo and redo actions
		// have a detail label and
		// description.
		// They needed to be updated.
		if (!fEditorDisposed)
			updateMenuText();
	}


	/**
	 * Updates the editor context menu by creating a new context menu with the
	 * given menu id
	 * 
	 * @param contextMenuId
	 *            Cannot be null
	 */
	private void updateEditorContextMenuId(String contextMenuId) {
		// update editor context menu id if updating to a new id or if context
		// menu is not already set up
		if (!contextMenuId.equals(getEditorContextMenuId()) || (fTextContextMenu == null)) {
			setEditorContextMenuId(contextMenuId);

			if (getSourceViewer() != null) {
				StyledText styledText = getSourceViewer().getTextWidget();
				if (styledText != null) {
					// dispose of previous context menu
					if (fTextContextMenu != null) {
						fTextContextMenu.dispose();
					}
					if (fTextContextMenuManager != null) {
						fTextContextMenuManager.removeMenuListener(getContextMenuListener());
						fTextContextMenuManager.removeAll();
						fTextContextMenuManager.dispose();
					}

					fTextContextMenuManager = new MenuManager(getEditorContextMenuId(), getEditorContextMenuId());
					fTextContextMenuManager.setRemoveAllWhenShown(true);
					fTextContextMenuManager.addMenuListener(getContextMenuListener());

					fTextContextMenu = fTextContextMenuManager.createContextMenu(styledText);
					styledText.setMenu(fTextContextMenu);

					getSite().registerContextMenu(getEditorContextMenuId(), fTextContextMenuManager, getSelectionProvider());

					// also register this menu for source page part and
					// structured text editor ids
					String partId = getSite().getId();
					if (partId != null) {
						getSite().registerContextMenu(partId + EDITOR_CONTEXT_MENU_SUFFIX, fTextContextMenuManager, getSelectionProvider());
					}
					getSite().registerContextMenu(EDITOR_CONTEXT_MENU_ID, fTextContextMenuManager, getSelectionProvider());
				}
			}
		}
	}

	/**
	 * Updates editor context menu, vertical ruler menu, help context id for
	 * new content type
	 * 
	 * @param contentType
	 */
	private void updateEditorControlsForContentType(String contentType) {
		if (contentType == null) {
			updateEditorContextMenuId(EDITOR_CONTEXT_MENU_ID);
			updateRulerContextMenuId(RULER_CONTEXT_MENU_ID);
			updateHelpContextId(ITextEditorHelpContextIds.TEXT_EDITOR);
		}
		else {
			updateEditorContextMenuId(contentType + EDITOR_CONTEXT_MENU_SUFFIX);
			updateRulerContextMenuId(contentType + RULER_CONTEXT_MENU_SUFFIX);
			updateHelpContextId(contentType + "_source_HelpId"); //$NON-NLS-1$
		}
	}

	private void updateEncodingMemento() {
		boolean failed = false;
		IStructuredModel internalModel = getInternalModel();
		if (internalModel != null) {
			IStructuredDocument doc = internalModel.getStructuredDocument();
			EncodingMemento memento = doc.getEncodingMemento();
			IDocumentCharsetDetector detector = internalModel.getModelHandler().getEncodingDetector();
			if (memento != null && detector != null)
				detector.set(doc);
			try {
				detector.getEncoding();
			}
			catch (IOException e) {
				failed = true;
			}
			// be sure to use the new instance
			// but only if no exception occurred.
			// (we may find cases we need to do more error recover there)
			// should be near impossible to get IOException from processing
			// the
			// *document*
			if (!failed) {
				doc.setEncodingMemento(memento);
			}
		}
	}

	/**
	 * Updates the help context of the editor with the given help context id
	 * 
	 * @param helpContextId
	 *            Cannot be null
	 */
	private void updateHelpContextId(String helpContextId) {
		if (!helpContextId.equals(getHelpContextId())) {
			setHelpContextId(helpContextId);

			if (getSourceViewer() != null) {
				StyledText styledText = getSourceViewer().getTextWidget();
				if (styledText != null) {
					IWorkbenchHelpSystem helpSystem = PlatformUI.getWorkbench().getHelpSystem();
					helpSystem.setHelp(styledText, getHelpContextId());
				}
			}
		}
	}

	/*
	 * Update the hovering behavior depending on the preferences.
	 */
	private void updateHoverBehavior() {
		SourceViewerConfiguration configuration = getSourceViewerConfiguration();
		String[] types = configuration.getConfiguredContentTypes(getSourceViewer());

		for (int i = 0; i < types.length; i++) {

			String t = types[i];

			ISourceViewer sourceViewer = getSourceViewer();
			if (sourceViewer instanceof ITextViewerExtension2) {
				// Remove existing hovers
				((ITextViewerExtension2) sourceViewer).removeTextHovers(t);

				int[] stateMasks = configuration.getConfiguredTextHoverStateMasks(getSourceViewer(), t);

				if (stateMasks != null) {
					for (int j = 0; j < stateMasks.length; j++) {
						int stateMask = stateMasks[j];
						ITextHover textHover = configuration.getTextHover(sourceViewer, t, stateMask);
						((ITextViewerExtension2) sourceViewer).setTextHover(textHover, t, stateMask);
					}
				}
				else {
					ITextHover textHover = configuration.getTextHover(sourceViewer, t);
					((ITextViewerExtension2) sourceViewer).setTextHover(textHover, t, ITextViewerExtension2.DEFAULT_HOVER_STATE_MASK);
				}
			}
			else
				sourceViewer.setTextHover(configuration.getTextHover(sourceViewer, t), t);
		}
	}

	private void updateMenuText() {
		if (fStructuredModel != null && !fStructuredModel.isModelStateChanging() && getTextViewer().getTextWidget() != null) {
			// performance: don't force an update of the action bars unless
			// required as it is expensive
			String previousUndoText = null;
			String previousUndoDesc = null;
			String previousRedoText = null;
			String previousRedoDesc = null;
			boolean updateActions = false;
			IAction undoAction = getAction(ITextEditorActionConstants.UNDO);
			IAction redoAction = getAction(ITextEditorActionConstants.REDO);
			if (undoAction != null) {
				previousUndoText = undoAction.getText();
				previousUndoDesc = undoAction.getDescription();
				updateActions = updateActions || previousUndoText == null || previousUndoDesc == null;
				undoAction.setText(UNDO_ACTION_TEXT_DEFAULT);
				undoAction.setDescription(UNDO_ACTION_DESC_DEFAULT);
			}
			if (redoAction != null) {
				previousRedoText = redoAction.getText();
				previousRedoDesc = redoAction.getDescription();
				updateActions = updateActions || previousRedoText == null || previousRedoDesc == null;
				redoAction.setText(REDO_ACTION_TEXT_DEFAULT);
				redoAction.setDescription(REDO_ACTION_DESC_DEFAULT);
			}
			if (fStructuredModel.getUndoManager() != null) {
				IStructuredTextUndoManager undoManager = fStructuredModel.getUndoManager();
				// get undo command
				Command undoCommand = undoManager.getUndoCommand();
				// set undo label and description
				undoAction.setEnabled(undoManager.undoable());
				if (undoCommand != null) {
					String label = undoCommand.getLabel();
					if (label != null) {
						String customText = MessageFormat.format(UNDO_ACTION_TEXT, new String[]{label});
						updateActions = updateActions || customText == null || previousUndoText == null || !customText.equals(previousUndoText);
						undoAction.setText(customText);
					}
					String desc = undoCommand.getDescription();
					if (desc != null) {
						String customDesc = MessageFormat.format(UNDO_ACTION_DESC, new String[]{desc});
						updateActions = updateActions || customDesc == null || previousRedoDesc == null || !customDesc.equals(previousUndoDesc);
						undoAction.setDescription(customDesc);
					}
				}
				// get redo command
				Command redoCommand = undoManager.getRedoCommand();
				// set redo label and description
				redoAction.setEnabled(undoManager.redoable());
				if (redoCommand != null) {
					String label = redoCommand.getLabel();
					if (label != null) {
						String customText = MessageFormat.format(REDO_ACTION_TEXT, new String[]{label});
						updateActions = updateActions || customText == null || previousRedoText == null || !customText.equals(previousRedoText);
						redoAction.setText(customText);
					}
					String desc = redoCommand.getDescription();
					if (desc != null) {
						String customDesc = MessageFormat.format(REDO_ACTION_DESC, new String[]{desc});
						updateActions = updateActions || customDesc == null || previousRedoDesc == null || !customDesc.equals(previousRedoDesc);
						redoAction.setDescription(customDesc);
					}
				}
			}
			// tell the action bars to update
			if (updateActions) {
				if (getEditorSite().getActionBars() != null) {
					getEditorSite().getActionBars().updateActionBars();
				}
				else if (getEditorPart() != null && getEditorPart().getEditorSite().getActionBars() != null) {
					getEditorPart().getEditorSite().getActionBars().updateActionBars();
				}
			}
		}
	}

	void updateRangeIndication(ISelection selection) {
		boolean rangeUpdated = false;
		if (selection instanceof IStructuredSelection && !((IStructuredSelection) selection).isEmpty()) {
			Object[] objects = ((IStructuredSelection) selection).toArray();
			if (objects.length > 0 && objects[0] instanceof IndexedRegion) {
				int start = ((IndexedRegion) objects[0]).getStartOffset();
				int end = ((IndexedRegion) objects[0]).getEndOffset();
				if (objects.length > 1) {
					for (int i = 1; i < objects.length; i++) {
						start = Math.min(start, ((IndexedRegion) objects[i]).getStartOffset());
						end = Math.max(end, ((IndexedRegion) objects[i]).getEndOffset());
					}
				}
				getSourceViewer().setRangeIndication(start, end - start, false);
				rangeUpdated = true;
			}
		}
		if (!rangeUpdated) {
			if (selection instanceof ITextSelection) {
				getSourceViewer().setRangeIndication(((ITextSelection) selection).getOffset(), ((ITextSelection) selection).getLength(), false);
			}
			else {
				getSourceViewer().removeRangeIndication();
			}
		}
	}


	/**
	 * Updates the editor vertical ruler menu by creating a new vertical ruler
	 * context menu with the given menu id
	 * 
	 * @param rulerMenuId
	 *            Cannot be null
	 */
	private void updateRulerContextMenuId(String rulerMenuId) {
		// update ruler context menu id if updating to a new id or if context
		// menu is not already set up
		if (!rulerMenuId.equals(getRulerContextMenuId()) || (fRulerContextMenu == null)) {
			setRulerContextMenuId(rulerMenuId);

			if (getVerticalRuler() != null) {
				// dispose of previous ruler context menu
				if (fRulerContextMenu != null) {
					fRulerContextMenu.dispose();
				}
				if (fRulerContextMenuManager != null) {
					fRulerContextMenuManager.removeMenuListener(getContextMenuListener());
					fRulerContextMenuManager.removeAll();
					fRulerContextMenuManager.dispose();
				}

				fRulerContextMenuManager = new MenuManager(getRulerContextMenuId(), getRulerContextMenuId());
				fRulerContextMenuManager.setRemoveAllWhenShown(true);
				fRulerContextMenuManager.addMenuListener(getContextMenuListener());

				Control rulerControl = getVerticalRuler().getControl();
				fRulerContextMenu = fRulerContextMenuManager.createContextMenu(rulerControl);
				rulerControl.setMenu(fRulerContextMenu);

				getSite().registerContextMenu(getRulerContextMenuId(), fRulerContextMenuManager, getSelectionProvider());

				// also register this menu for source page part and structured
				// text editor ids
				String partId = getSite().getId();
				if (partId != null) {
					getSite().registerContextMenu(partId + RULER_CONTEXT_MENU_SUFFIX, fRulerContextMenuManager, getSelectionProvider());
				}
				getSite().registerContextMenu(RULER_CONTEXT_MENU_ID, fRulerContextMenuManager, getSelectionProvider());
			}
		}
	}

	private void updateSourceViewerConfiguration() {
		SourceViewerConfiguration configuration = getSourceViewerConfiguration();
		// no need to update source viewer configuration if one does not exist
		// yet
		if (configuration == null) {
			return;
		}
		// do not configure source viewer configuration twice
		boolean configured = false;

		// structuredtextviewer only works with
		// structuredtextviewerconfiguration
		if (!(configuration instanceof StructuredTextViewerConfiguration)) {
			ConfigurationAndTarget cat = createSourceViewerConfiguration();
			fViewerConfigurationTargetId = cat.getTargetId();
			configuration = cat.getConfiguration();
			setSourceViewerConfiguration(configuration);
			configured = true;
		}
		else {
			ConfigurationAndTarget cat = createSourceViewerConfiguration();
			StructuredTextViewerConfiguration newViewerConfiguration = cat.getConfiguration();
			if (!(cat.getTargetId().equals(fViewerConfigurationTargetId))) {
				// d282894 use newViewerConfiguration
				fViewerConfigurationTargetId = cat.getTargetId();
				configuration = newViewerConfiguration;
				setSourceViewerConfiguration(configuration);
				configured = true;
			}
		}

		if (getSourceViewer() != null) {
			// not sure if really need to reconfigure when input changes
			// (maybe only need to reset viewerconfig's document)
			if (!configured)
				getSourceViewer().configure(configuration);
			IAction contentAssistAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_CONTENTASSIST_PROPOSALS);
			if (contentAssistAction instanceof IUpdate) {
				((IUpdate) contentAssistAction).update();
			}
			IAction openHyperlinkAction = getAction(StructuredTextEditorActionConstants.ACTION_NAME_OPEN_FILE);
			if (openHyperlinkAction instanceof OpenHyperlinkAction) {
				((OpenHyperlinkAction) openHyperlinkAction).setHyperlinkDetectors(getSourceViewerConfiguration().getHyperlinkDetectors(getSourceViewer()));
			}
		}
	}

	protected void updateStatusField(String category) {
		super.updateStatusField(category);

		if (category == null)
			return;

		if (StructuredTextEditorActionConstants.STATUS_CATEGORY_OFFSET.equals(category)) {
			IStatusField field = getStatusField(category);
			if (field != null) {
				Point selection = getTextViewer().getTextWidget().getSelection();
				int offset1 = widgetOffset2ModelOffset(getSourceViewer(), selection.x);
				int offset2 = widgetOffset2ModelOffset(getSourceViewer(), selection.y);
				String text = null;
				if (offset1 != offset2)
					text = "[" + offset1 + "-" + offset2 + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
				else
					text = "[ " + offset1 + " ]"; //$NON-NLS-1$ //$NON-NLS-2$
				field.setText(text == null ? fErrorLabel : text);
			}
		}
	}
}

Back to the top