gt: 							composite = new Composite(scrollComposite, SWT.None);
context:  
  package org.bbaw.bts.ui.corpus.parts;
  
  import java.lang.reflect.InvocationTargetException;
  import java.util.ArrayList;
  import java.util.Arrays;
  import java.util.Collections;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.Vector;
  
  import javax.annotation.PostConstruct;
  import javax.annotation.PreDestroy;
  import javax.inject.Inject;
  import javax.inject.Named;
  
  import org.bbaw.bts.btsmodel.BTSComment;
  import org.bbaw.bts.btsmodel.BTSConfig;
  import org.bbaw.bts.btsmodel.BTSConfigItem;
  import org.bbaw.bts.btsmodel.BTSObject;
  import org.bbaw.bts.commons.BTSConstants;
  import org.bbaw.bts.core.commons.BTSCoreConstants;
  import org.bbaw.bts.core.commons.comparator.BTSObjectTempSortKeyComparator;
  import org.bbaw.bts.core.commons.corpus.CorpusUtils;
  import org.bbaw.bts.core.controller.generalController.PermissionsAndExpressionsEvaluationController;
  import org.bbaw.bts.core.corpus.controller.partController.AnnotationPartController;
  import org.bbaw.bts.corpus.btsCorpusModel.BTSAnnotation;
  import org.bbaw.bts.corpus.btsCorpusModel.BTSCorpusObject;
  import org.bbaw.bts.corpus.btsCorpusModel.BTSText;
  import org.bbaw.bts.searchModel.BTSModelUpdateNotification;
  import org.bbaw.bts.ui.commons.corpus.events.BTSRelatingObjectsFilterEvent;
  import org.bbaw.bts.ui.commons.corpus.events.BTSRelatingObjectsLoadingEvent;
  import org.bbaw.bts.ui.commons.corpus.events.BTSTextSelectionEvent;
  import org.bbaw.bts.ui.commons.utils.BTSUIConstants;
  import org.bbaw.bts.ui.corpus.parts.annotationsPart.RelatedObjectGroup;
  import org.bbaw.bts.ui.corpus.parts.annotationsPart.RelatedObjectGroupAnnotation;
  import org.bbaw.bts.ui.corpus.parts.annotationsPart.RelatedObjectGroupComment;
  import org.bbaw.bts.ui.corpus.parts.annotationsPart.RelatedObjectGroupImpl;
  import org.bbaw.bts.ui.corpus.parts.annotationsPart.RelatedObjectGroupRubrum;
  import org.bbaw.bts.ui.corpus.parts.annotationsPart.RelatedObjectGroupSubtext;
  import org.eclipse.core.runtime.IProgressMonitor;
  import org.eclipse.e4.core.contexts.ContextInjectionFactory;
  import org.eclipse.e4.core.contexts.IEclipseContext;
  import org.eclipse.e4.core.di.annotations.Optional;
  import org.eclipse.e4.core.di.extensions.EventTopic;
  import org.eclipse.e4.core.di.extensions.Preference;
  import org.eclipse.e4.core.services.log.Logger;
  import org.eclipse.e4.ui.di.Persist;
  import org.eclipse.e4.ui.di.UIEventTopic;
  import org.eclipse.e4.ui.di.UISynchronize;
  import org.eclipse.e4.ui.model.application.commands.MCommand;
  import org.eclipse.e4.ui.model.application.commands.MCommandsFactory;
  import org.eclipse.e4.ui.model.application.commands.MParameter;
  import org.eclipse.e4.ui.model.application.ui.basic.MPart;
  import org.eclipse.e4.ui.model.application.ui.menu.ItemType;
  import org.eclipse.e4.ui.model.application.ui.menu.MHandledMenuItem;
  import org.eclipse.e4.ui.model.application.ui.menu.MMenu;
  import org.eclipse.e4.ui.model.application.ui.menu.MMenuElement;
  import org.eclipse.e4.ui.model.application.ui.menu.MMenuFactory;
  import org.eclipse.e4.ui.services.IServiceConstants;
  import org.eclipse.e4.ui.services.internal.events.EventBroker;
  import org.eclipse.e4.ui.workbench.modeling.EPartService;
  import org.eclipse.jface.dialogs.ProgressMonitorDialog;
  import org.eclipse.jface.operation.IRunnableWithProgress;
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.custom.ScrolledComposite;
  import org.eclipse.swt.events.ControlAdapter;
  import org.eclipse.swt.events.ControlEvent;
  import org.eclipse.swt.graphics.Rectangle;
  import org.eclipse.swt.layout.GridData;
  import org.eclipse.swt.layout.GridLayout;
  import org.eclipse.swt.widgets.Display;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.Listener;
  import org.eclipse.swt.widgets.Shell;
  import org.eclipse.wb.swt.SWTResourceManager;
  import org.osgi.service.event.Event;
  import org.osgi.service.event.EventHandler;
  
  public class AnnotationsPart implements EventHandler {
  	
  	private static final int MAX_RELATED_OBJECTS = 40;
  
  	@Inject
  	@Preference(value = "locale_lang", nodePath = "org.bbaw.bts.app")
  	private String lang;
  	
  	@Inject
  	private AnnotationPartController annotationPartController;
  	
  	@Inject
  	private UISynchronize sync;
  	@Inject
  	private EventBroker eventBroker;
  	
  	@Inject
  	private IEclipseContext context;
  	
  	@Inject
  	private Logger logger;
  
  	@Inject
  	private PermissionsAndExpressionsEvaluationController permissionsController;
  
  	
  	/** The part service. */
  	@Inject
  	private EPartService partService;
  	
  	private Composite composite;
  	private ScrolledComposite scrollComposite;
  
  	private Map<BTSObject, RelatedObjectGroup> objectWidgetMap = new HashMap<BTSObject, RelatedObjectGroup>();
  
  	private List<RelatedObjectGroup> highlightedGroups = new Vector<RelatedObjectGroup>(2);
  
  	private BTSTextSelectionEvent textSelectionEvent;
  
  	private Listener selectionListener;
  
  	private String queryId;
  
  	private Map<String, List<BTSObject>> relatingObjectsQueryIDMap = new HashMap<String, List<BTSObject>>();
  
  	private Listener resizeListener;
  
  	protected boolean selfselection;
  
  	private BTSCorpusObject currentCorpusObject;
  
  	private boolean allRelatedObjectsShowed;
  
  	// boolean if gui is constructed
  	private boolean constructed;
  
  	/** The part. */
  	private MPart part;
  
  	private BTSRelatingObjectsLoadingEvent relatingObjectsEvent;
  
  	@Inject
  	public AnnotationsPart() {
  		//
  	}
  
  	@PostConstruct
  	public void postConstruct(Composite parent) {
  		GridLayout gl_parent = new GridLayout(1, false);
  		gl_parent.verticalSpacing = 0;
  		gl_parent.marginWidth = 0;
  		gl_parent.marginHeight = 0;
  		gl_parent.horizontalSpacing = 0;
  		parent.setLayout(gl_parent);
  		
  		part = partService
  				.findPart("org.bbaw.bts.ui.corpus.part.AnnotationsPart");
  		resizeListener = new Listener() {
  
  			@Override
  			public void handleEvent(
  					org.eclipse.swt.widgets.Event event) {
  				Rectangle r = scrollComposite
  						.getClientArea();
  				composite.layout();
  				scrollComposite.setMinSize(composite
  						.computeSize(r.width, SWT.DEFAULT));
  			}
  
  		};
  
  		selectionListener = new Listener() {
  
  			@Override
  			public void handleEvent(
  					org.eclipse.swt.widgets.Event event) {
  				RelatedObjectGroup roGroup = (RelatedObjectGroup) event.widget;
  				selfselection = true;
  				setSelectedInternal(new Vector<>(Arrays.asList(roGroup)), true);
  				selfselection = false;
  			}
  
  		};
  		
  		scrollComposite = new ScrolledComposite(parent,
  				SWT.V_SCROLL | SWT.H_SCROLL);
  		scrollComposite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
  		scrollComposite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
  		scrollComposite.setMinWidth(100);
  		scrollComposite.setMinHeight(400);
  		composite = new Composite(scrollComposite, SWT.BORDER);
  		scrollComposite.setExpandHorizontal(true);
  
  		scrollComposite.setExpandVertical(true);
  		scrollComposite.addControlListener(new ControlAdapter() {
  			@Override
  			public void controlResized(ControlEvent e) {
  				Rectangle r = scrollComposite.getClientArea();
  				scrollComposite.setMinSize(composite.computeSize(r.width,
  						SWT.DEFAULT));
  			}
  		});
  		composite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
  		composite.setLayout(new GridLayout(1, false));
  		((GridLayout)composite.getLayout()).marginHeight = 0;
  		((GridLayout)composite.getLayout()).marginWidth = 0;
  		((GridLayout)composite.getLayout()).verticalSpacing = 0;
  
  		// populate extended annotation filter menu and initialize context node
  		extendAnnotationsFilterMenu();
  
  		scrollComposite.setContent(composite);
  		constructed = true;
  		// request input from text editor
  		eventBroker.post(BTSUIConstants.EVENT_EGY_TEXT_EDITOR_INPUT_REQUESTED+"annotations_part", relatingObjectsEvent);
  	}
  
  
  	/**
  	 * Retrieves the annotation part's view menu, where menu items correspond to related object
  	 * types that are either to be shown or to be filtered out. Based on the check states of these
  	 * menu items, the related object type filter state flag map gets initiated.<br/><br/>
  	 * 
  	 * Next, annotation type and subtype definitions are retrieved from the active project configuration.
  	 * Each type and subtype gets a corresponding checkable menu item in a multi-level submenu.
  	 */
  	private void extendAnnotationsFilterMenu() {
  		// initialize filters from fragment model definition
  		HashMap<String, Boolean> filters = new HashMap<String, Boolean>();
  		// retrieve annotations part viewmenu
  		MMenu viewmenu = null;
  		for (MMenu m : part.getMenus()) {
  			if (m.getTags().contains("ViewMenu")) {
  				viewmenu = m;
  			}
  		}
  		if (viewmenu != null) {
  			/* first go through default annotation types defined in application model
  			this is being done so that the annotation part filter dictionary can be initialized
  			the respective filter keys corresponding to these built-in view menu
  			entries are defined by their `annotationsPartFilterParam` parameters */
  			MMenu submenu = null;
  			MCommand menuFilterCommand = null;
  			// save menu item selection flags from application model to context
  			for (MMenuElement mi : viewmenu.getChildren()) {
  				if (mi instanceof MHandledMenuItem) {
  					for (MParameter p : ((MHandledMenuItem) mi).getParameters()) {
  						if (p.getName().equals("annotationsPartFilterParam")) {
  							filters.put(p.getValue(), ((MHandledMenuItem)mi).isSelected());
  						}
  					}
  					// retrieve filter command in order to handle possible submenu entries
  					menuFilterCommand = ((MHandledMenuItem) mi).getCommand();
  				}
  
  				if (mi.getElementId().
  						equals("org.bbaw.bts.ui.corpus.part.annotations.viewmenu.showType.annotation.type")) {
  					submenu = (MMenu) mi;
  				}
  			}
  
  			/* now to the good part: the "annotation" menu entry in the aforementioned part view menu needs to be 
  			expanded into a submenu and populated with annotation types and subtypes from the active BTS configuration */
  			// remove submenu if already there
  			if (submenu != null) {
  				submenu.setToBeRendered(false);
  			}
  			// populate menu items for annotation types
  			// retrieve configuration elements for object type annotation
  			BTSConfigItem typeConf = null;
  			try {
  				typeConf = annotationPartController.getAnnoTypesConfigItem();
  			} catch (Exception e) {
  				logger.error(e, "Annotation type configurations could not be obtained.");
  			};
  
  			if (typeConf != null && !typeConf.getChildren().isEmpty()) {
  				// initialize submenu for annotation types
  				submenu = MMenuFactory.INSTANCE.createMenu();
  				submenu.setElementId("org.bbaw.bts.ui.corpus.part.annotations.viewmenu.show.annotation.type");
  				submenu.setLabel("Annotation Types");
  
  				// traverse annotation types configuration branch
  				for (BTSConfig c : typeConf.getChildren()) {
  					if (c instanceof BTSConfigItem) {
  						BTSConfigItem confItem = (BTSConfigItem)c;
  						if (CorpusUtils.ANNOTATION_RUBRUM_TYPE.equals(confItem.getValue())) continue;
  						MMenuElement menuItemType = null;
  
  						// retrieve subtype definition from configuration node
  						BTSConfigItem subtypeConf = null;
  						try {
  							subtypeConf = annotationPartController.getAnnoSubtypesConfigItem(confItem);
  						} catch (Exception e) {
  							logger.warn(e, "Annotation subtypes configurations could not be obtained for type "+
  									confItem.get_id()+" ("+confItem.getLabel()+")");
  						};
  						List<BTSConfigItem> subTypeConfItems = new Vector<BTSConfigItem>();
  						if (subtypeConf != null) {
  							// filter attached subtype definition nodes
  							for (BTSConfig cc : subtypeConf.getChildren()) {
  								if (cc instanceof BTSConfigItem && ((BTSConfigItem)cc).getValue() != null) {
  										subTypeConfItems.add((BTSConfigItem)cc);
  								}
  							}
  						}
  						// if subtypes definitions exist, nest in submenu
  						String key = CorpusUtils.getTypeIdentifier(BTSConstants.ANNOTATION, confItem, null);
  						if (!subTypeConfItems.isEmpty()) {
  							// create submenu
  							menuItemType = MMenuFactory.INSTANCE.createMenu();
  
  							// first entry controls the type alone, without any subtype
  							MHandledMenuItem menuItemTypeWithoutSubtype = newFilterMenuItem(key);
  							((MHandledMenuItem)menuItemTypeWithoutSubtype).setCommand(menuFilterCommand);
  							menuItemTypeWithoutSubtype.setLabel(confItem.getLabel().getTranslation(lang));
  							((MMenu)menuItemType).getChildren().add(menuItemTypeWithoutSubtype);
  							filters.put(key, ((MHandledMenuItem)menuItemTypeWithoutSubtype).isSelected());
  							((MMenu)menuItemType).getChildren().add(MMenuFactory.INSTANCE.createMenuSeparator());
  							
  
  							// go through subtypes
  							for (BTSConfigItem subTypeConfItem : subTypeConfItems) {
  								// retrieve subtype key from configuration
  								key = CorpusUtils.getTypeIdentifier(BTSConstants.ANNOTATION, confItem, subTypeConfItem);
  								
  								// create annotation subtype menu entry and append to type submenu
  								MHandledMenuItem menuItemSubType = newFilterMenuItem(key);
  								menuItemSubType.setCommand(menuFilterCommand);
  								menuItemSubType.setLabel(subTypeConfItem.getLabel().getTranslation(lang));
  								((MMenu)menuItemType).getChildren().add(menuItemSubType);
  								// init subtype filter state
  								filters.put(key, ((MHandledMenuItem)menuItemSubType).isSelected());
  							}
  						} else { // create checkable menu entry for types that don't have subtypes
  							menuItemType = newFilterMenuItem(key);
  							((MHandledMenuItem)menuItemType).setCommand(menuFilterCommand);
  							// init type filter state
  							filters.put(key, ((MHandledMenuItem)menuItemType).isSelected());
  						}
  						// label annotation type menu entry and append to submenu
  						menuItemType.setLabel(confItem.getLabel().getTranslation(lang));
  						submenu.getChildren().add(menuItemType);
  					}
  				}
  				viewmenu.getChildren().add(submenu);
  			}
  		}
  		// save related object filter states to context
  		context.set("org.bbaw.bts.corpus.annotationsPart.filter", filters);
  		eventBroker.post("event_anno_filters/anno_part", new BTSRelatingObjectsFilterEvent(filters));
  	}
  
  
  	/**
  	 * Creates a new menu item with a checked checkmark corresponding to the key passed a parameter.
  	 * The newly created menu item also gets equipped with an attached menu parameter of type <code>annotationsPartFilterParam</code>,
  	 * where the specified key gets stored in.
  	 * @param key An identifier for the boolean filter flag.
  	 * @return A new {@link MHandledMenuItem} instance.
  	 * @see ItemType#CHECK
  	 */
  	private MHandledMenuItem newFilterMenuItem(String key) {
  		MHandledMenuItem menuItem = MMenuFactory.INSTANCE.createHandledMenuItem();
  		menuItem.setElementId("org.bbaw.bts.ui.corpus.part.annotations.viewmenu.showType.annotation.type." + key);
  		menuItem.setSelected(true);
  		menuItem.setType(ItemType.CHECK);
  		MParameter menuFilterParam = MCommandsFactory.INSTANCE.createParameter();
  		menuFilterParam.setName("annotationsPartFilterParam");
  		menuFilterParam.setValue(key);
  		menuItem.getParameters().add(menuFilterParam);
  		return menuItem;
  	}
  
  
  	@Inject
  	@Optional
  	void eventReceivedRelatingObjectsLoaded(
  			@EventTopic("event_text_relating_objects/*") final BTSRelatingObjectsLoadingEvent event) {
  		if (event != null) {
  			setCorpusObject(event.getObject());
  			this.relatingObjectsEvent = event;
  			sync.syncExec(new Runnable() {
  				public void run() {
  					loadRelatingObjects(event);
  				}
  			});
  
  		}
  	}
  	
  	private void clearRelatingObjects(BTSCorpusObject selection) {
  		if (currentCorpusObject == null || selection.equals(currentCorpusObject)) {
  			return;
  		}
  		part.setLabel("Annotations");
  		part.setTooltip("Annotations");
  		relatingObjectsQueryIDMap.clear();
  		objectWidgetMap.clear();
  		highlightedGroups = new Vector<>();
  		if (composite != null)
  		{
  			composite.dispose();
  		}
  		composite = null;
  		composite = new Composite(scrollComposite, SWT.None);
  		composite.setBackground(SWTResourceManager.getColor(SWT.COLOR_WHITE));
  		composite.setLayout(new GridLayout(1, false));
  		((GridLayout)composite.getLayout()).marginHeight = 0;
  		((GridLayout)composite.getLayout()).marginWidth = 0;
  		((GridLayout)composite.getLayout()).verticalSpacing = 0;
  		composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
  		scrollComposite.setContent(composite);
  
  		Rectangle r = scrollComposite.getClientArea();
  		composite.layout();
  		scrollComposite.setMinSize(composite.computeSize(r.width,
  				SWT.DEFAULT));
  		setCorpusObject(selection);
  
  	}
  
  	
  	private void loadRelatingObjects(final BTSRelatingObjectsLoadingEvent event) {
  		try {
  			IRunnableWithProgress op = new IRunnableWithProgress() {
  
  				@Override
  				public void run(final IProgressMonitor monitor)
  						throws InvocationTargetException, InterruptedException {
  					monitor.setTaskName("Load annotations, comments and glosses.");
  					relatingObjectsQueryIDMap.put(queryId, event.getRelatingObjects());
  					final List<BTSObject> list = filterAndCutRelatingObjects(event
  							.getRelatingObjects(), monitor);
  					sync.asyncExec(new Runnable() {
  						public void run() {
  							if (composite != null) {
  								composite.dispose();
  							}
  							composite = null;
  							objectWidgetMap.clear();
  							
  							try {
  								part.setLabel(event.getObject().getName());
  							} catch (Exception e) {
  							}							
  