You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ctakes.apache.org by ja...@apache.org on 2012/10/31 06:26:55 UTC

svn commit: r1403989 [2/28] - in /incubator/ctakes/branches/SHARPn-cTAKES: Constituency Parser/src/org/chboston/cnlp/ctakes/parser/ Constituency Parser/src/org/chboston/cnlp/ctakes/parser/uima/ae/ Constituency Parser/src/org/chboston/cnlp/ctakes/parser...

Modified: incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextAnnotator.java
URL: http://svn.apache.org/viewvc/incubator/ctakes/branches/SHARPn-cTAKES/NE%20contexts/src/edu/mayo/bmi/uima/context/ContextAnnotator.java?rev=1403989&r1=1403988&r2=1403989&view=diff
==============================================================================
--- incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextAnnotator.java (original)
+++ incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextAnnotator.java Wed Oct 31 05:26:43 2012
@@ -1,18 +1,11 @@
 /*
- * Copyright: (c) 2009   Mayo Foundation for Medical Education and 
- * Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the
- * triple-shield Mayo logo are trademarks and service marks of MFMER.
- *
- * Except as contained in the copyright notice above, or as used to identify 
- * MFMER as the author of this software, the trade names, trademarks, service
- * marks, or product names of the copyright holder shall not be used in
- * advertising, promotion or otherwise in connection with this software without
- * prior written authorization of the copyright holder.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  * http://www.apache.org/licenses/LICENSE-2.0 
  * 
  * Unless required by applicable law or agreed to in writing, software
@@ -21,371 +14,371 @@
  * See the License for the specific language governing permissions and 
  * limitations under the License. 
  */
-package edu.mayo.bmi.uima.context;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.log4j.Logger;
-import org.apache.uima.UimaContext;
-import org.apache.uima.analysis_component.JCasAnnotator_ImplBase;
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
-import org.apache.uima.analysis_engine.annotator.AnnotatorConfigurationException;
-import org.apache.uima.cas.FSIterator;
-import org.apache.uima.cas.Type;
-import org.apache.uima.cas.TypeSystem;
-import org.apache.uima.jcas.JCas;
-import org.apache.uima.jcas.tcas.Annotation;
-import org.apache.uima.jcas.tcas.DocumentAnnotation;
-import org.apache.uima.resource.ResourceInitializationException;
-
-import edu.mayo.bmi.uima.core.util.JCasUtil;
-
-/**
- * The context annotator iterates through focus annotations and analyzes the
- * surrounding context of each. The context is defined by a scope, window, and a
- * maximum size (if applicable). The context can be further refined by boundary
- * conditions as specified by the context analyzer used. For each focus
- * annotation, a context is collected as a set of context annotations for each
- * scope that is to be applied. The context annotations are passed to a context
- * analyzer for analysis. If the context analyzer finds something of interest in
- * the context annotations, then it will generate a context hit. Context hits
- * are then passed to a context hit consumer which will perform an action on the
- * hit such as updating an existing annotation or creating a new one.
- */
-public class ContextAnnotator extends JCasAnnotator_ImplBase {
-	// LOG4J logger based on class name
-	private Logger iv_logger = Logger.getLogger(getClass().getName());
-
-	/**
-	 * "MaxLeftScopeSize" is a required, single, integer parameter that
-	 * specifies the maximum size of the left scope.
-	 */
-	public static final String MAX_LEFT_SCOPE_SIZE_PARAM = "MaxLeftScopeSize";
-	/**
-	 * "MaxRightScopeSize" is a required, single, integer parameter that
-	 * specifies the maximum size of the right scope.
-	 */
-	public static final String MAX_RIGHT_SCOPE_SIZE_PARAM = "MaxRightScopeSize";
-	/**
-	 * "ScopeOrder" is a required, multiple, string parameter that specifies the
-	 * order that the scopes should be processed in. Possible values are "LEFT",
-	 * "MIDDLE", "RIGHT", and "ALL".
-	 */
-	public static final String SCOPE_ORDER_PARAM = "ScopeOrder";
-
-	/**
-	 * "WindowAnnotationClass" is a required, single, string parameter that
-	 * specifies the annotation type of the windows that specify the hard
-	 * boundaries of scopes. Note that the entire window may not be used
-	 * depending on the location of the focus annotation, the maximum scope
-	 * size, and the boundary conditions specified by the context analyzer. A
-	 * window encompasses all of the scopes (left, middle, and right). Examples
-	 * of likely window types would be:
-	 * <ul>
-	 * <li>DocumentAnnotation</li>
-	 * <li>SentenceAnnotation</li>
-	 * <li>SegmentAnnotation</li>
-	 * <li>...</li>
-	 * </ul>
-	 * 
-	 * @see DocumentAnnotation
-	 * @see edu.mayo.bmi.common.type.Sentence
-	 * @see edu.mayo.bmi.common.type.Segment
-	 * 
-	 */
-	public static final String WINDOW_ANNOTATION_CLASS_PARAM = "WindowAnnotationClass";
-	/**
-	 * "FocusAnnotationClass" is a required, single, string parameter that
-	 * specifies the annotation type of the focus annotations that are going to
-	 * be examined by this annotator. Examples of likely focus types would be:
-	 * <ul>
-	 * <li>NamedEntityAnnotation</li>
-	 * <li>Token</li>
-	 * <li>...</li>
-	 * </ul>
-	 * 
-	 * @see edu.mayo.bmi.common.type.NamedEntity
-	 * @see edu.mayo.bmi.common.type.BaseToken
-	 */
-
-	public static final String FOCUS_ANNOTATION_CLASS_PARAM = "FocusAnnotationClass";
-	/**
-	 * "ContextAnnotationClass" is a required, single, string parameter that
-	 * specifies the annotation type of the context annotations (often "tokens")
-	 * that make up the context relative to a focus annotation within a scope
-	 * that is being examined. The context annotations are examined for context
-	 * hits by the context analyzer. Examples of likely focus types would be:
-	 * <ul>
-	 * <li>BaseToken</li>
-	 * <li>WordToken</li>
-	 * <li>NamedEntity</li>
-	 * </ul>
-	 * 
-	 * @see edu.mayo.bmi.common.type.BaseToken
-	 * @see edu.mayo.bmi.common.type.WordToken
-	 * @see edu.mayo.bmi.common.type.NamedEntity
-	 * 
-	 */
-
-	public static final String CONTEXT_ANNOTATION_CLASS_PARAM = "ContextAnnotationClass";
-
-	/**
-	 * "ContextAnalyzerClass" is a required, single, string parameter that
-	 * specifies the context analyzer class that determines if a "hit" is found
-	 * within a processed scope.
-	 * 
-	 * @see ContextAnalyzer
-	 */
-	public static final String CONTEXT_ANALYZER_CLASS_PARAM = "ContextAnalyzerClass";
-	/**
-	 * "ContextHitConsumerClass" is a required, single, string parameter that
-	 * specifies the context hit consumer class that will process context hits
-	 * that are found.
-	 * 
-	 * @see ContextHitConsumer
-	 */
-	public static final String CONTEXT_HIT_CONSUMER_CLASS_PARAM = "ContextHitConsumerClass";
-
-	public static final int LEFT_SCOPE = 1;
-	/**
-	 * Provides context annotations that are "inside" the focus annotation. For
-	 * example, if the focus annotation type is a named entity mention and the
-	 * context annotation is a token type, then the middle scope will examine
-	 * the tokens that fall within the named entity mention.
-	 */
-	public static final int MIDDLE_SCOPE = 2;
-	public static final int RIGHT_SCOPE = 3;
-	/**
-	 * The ALL_SCOPE scope provides the context annotation that are found in all three of the other scopes (LEFT, MIDDLE, and RIGHT).  
-	 */
-	public static final int ALL_SCOPE = 4;
-
-	protected int leftScopeSize;
-	protected int rightScopeSize;
-
-	protected List<Integer> scopes = new ArrayList<Integer>();
-
-	protected ContextAnalyzer contextAnalyzer;
-	protected ContextHitConsumer contextConsumer;
-
-	int windowType;
-	int focusType;
-	int contextType;
-
-	public void initialize(UimaContext uimaContext) throws ResourceInitializationException {
-		super.initialize(uimaContext);
-
-		try {
-			leftScopeSize = ((Integer) uimaContext.getConfigParameterValue(MAX_LEFT_SCOPE_SIZE_PARAM)).intValue();
-			rightScopeSize = ((Integer) uimaContext.getConfigParameterValue(MAX_RIGHT_SCOPE_SIZE_PARAM)).intValue();
-
-			String[] scopeOrderArr = (String[]) uimaContext.getConfigParameterValue(SCOPE_ORDER_PARAM);
-
-			parseScopeOrder(scopeOrderArr);
-
-			String contextAnalyzerClassName = (String) uimaContext.getConfigParameterValue(CONTEXT_ANALYZER_CLASS_PARAM);
-			String contextConsumerClassName = (String) uimaContext.getConfigParameterValue(CONTEXT_HIT_CONSUMER_CLASS_PARAM);
-
-			contextAnalyzer = (ContextAnalyzer) Class.forName(contextAnalyzerClassName).newInstance();
-			contextAnalyzer.initialize(uimaContext);
-			contextConsumer = (ContextHitConsumer) Class.forName(contextConsumerClassName).newInstance();
-
-			windowType = JCasUtil.getType((String) uimaContext.getConfigParameterValue(WINDOW_ANNOTATION_CLASS_PARAM));
-			focusType = JCasUtil.getType((String) uimaContext.getConfigParameterValue(FOCUS_ANNOTATION_CLASS_PARAM));
-			contextType = JCasUtil.getType((String) uimaContext.getConfigParameterValue(CONTEXT_ANNOTATION_CLASS_PARAM));
-
-		} catch (Exception e) {
-			throw new ResourceInitializationException(e);
-		}
-	}
-
-	void parseScopeOrder(String[] scopeStrings) throws AnnotatorConfigurationException {
-		scopes.clear();
-		for (int i = 0; i < scopeStrings.length; i++) {
-			if (scopeStrings[i].equals("LEFT")) {
-				scopes.add(new Integer(LEFT_SCOPE));
-			} else if (scopeStrings[i].equals("MIDDLE")) {
-				scopes.add(new Integer(MIDDLE_SCOPE));
-			} else if (scopeStrings[i].equals("RIGHT")) {
-				scopes.add(new Integer(RIGHT_SCOPE));
-			} else if (scopeStrings[i].equals("ALL")) {
-				scopes.add(new Integer(ALL_SCOPE));
-			} else {
-				Exception e = new Exception("Invalid scope value: " + scopeStrings[i]);
-				throw new AnnotatorConfigurationException(e);
-			}
-		}
-		iv_logger.info("SCOPE ORDER: " + scopes);
-	}
-
-	public void process(JCas jCas) throws AnalysisEngineProcessException {
-		try {
-			FSIterator windowIterator = jCas.getAnnotationIndex(windowType).iterator();
-			while (windowIterator.hasNext()) {
-				Annotation window = (Annotation) windowIterator.next();
-				List<Annotation> focusList = constrainToWindow(jCas, focusType, window);
-
-				// why is this list reversed?
-				Collections.reverse(focusList);
-
-				Iterator<Integer> scopeIterator = scopes.iterator();
-				while (scopeIterator.hasNext()) {
-					int scope = scopeIterator.next();
-					Iterator<Annotation> focusIterator = focusList.iterator();
-					while (focusIterator.hasNext()) {
-						Annotation focus = focusIterator.next();
-						List<Annotation> scopeContextAnnotations = getScopeContextAnnotations(jCas, focus, window,
-								scope);
-						ContextHit contextHit = contextAnalyzer.analyzeContext(scopeContextAnnotations, scope);
-						if (contextHit != null) {
-							contextConsumer.consumeHit(jCas, focus, scope, contextHit);
-						}
-					}
-				}
-			}
-		} catch (Exception e) {
-			throw new AnalysisEngineProcessException(e);
-		}
-
-	}
-
-	protected List<Annotation> getScopeContextAnnotations(JCas jCas, Annotation focus, Annotation window, int scope)
-			throws AnalysisEngineProcessException {
-		List<Annotation> scopeContextAnnotations = new ArrayList<Annotation>();
-		switch (scope) {
-		case LEFT_SCOPE:
-			scopeContextAnnotations = getLeftScopeContextAnnotations(jCas, focus, window);
-			break;
-		case MIDDLE_SCOPE:
-			scopeContextAnnotations = getMiddleScopeContextAnnotations(jCas, focus);
-			break;
-		case RIGHT_SCOPE:
-			scopeContextAnnotations = getRightScopeContextAnnotations(jCas, focus, window);
-			break;
-		case ALL_SCOPE:
-			scopeContextAnnotations.addAll(getLeftScopeContextAnnotations(jCas, focus, window));
-			scopeContextAnnotations.addAll(getMiddleScopeContextAnnotations(jCas, focus));
-			scopeContextAnnotations.addAll(getRightScopeContextAnnotations(jCas, focus, window));
-			break;
-		}
-		return scopeContextAnnotations;
-	}
-
-	protected List<Annotation> getLeftScopeContextAnnotations(JCas jCas, Annotation focus, Annotation window)
-			throws AnalysisEngineProcessException {
-
-		List<Annotation> scopeContextAnnotations = new ArrayList<Annotation>();
-
-		// if focus is not completely contained inside the window annotation,
-		// then return empty list.
-		if (focus.getBegin() < window.getBegin() || focus.getEnd() > window.getEnd())
-			return scopeContextAnnotations;
-
-		FSIterator subiterator = jCas.getAnnotationIndex(contextType).subiterator(window);
-		subiterator.moveTo(focus);
-		subiterator.moveToNext();
-		if (!subiterator.isValid())
-			subiterator.moveTo(focus);
-
-		while (scopeContextAnnotations.size() < leftScopeSize) {
-			subiterator.moveToPrevious();
-			if (subiterator.isValid()) {
-				Annotation contextAnnotation = (Annotation) subiterator.get();
-				if (contextAnnotation.getEnd() > focus.getBegin()) {
-					continue;
-				}
-				if (!contextAnalyzer.isBoundary(contextAnnotation, LEFT_SCOPE)) {
-					scopeContextAnnotations.add(contextAnnotation);
-				} else {
-					break;
-				}
-			} else {
-				break;
-			}
-		}
-		Collections.reverse(scopeContextAnnotations);
-		return scopeContextAnnotations;
-	}
-
-	protected List<Annotation> getRightScopeContextAnnotations(JCas jCas, Annotation focus, Annotation window)
-			throws AnalysisEngineProcessException {
-
-		List<Annotation> scopeContextAnnotations = new ArrayList<Annotation>();
-
-		// if focus is not completely contained inside the window annotation,
-		// then return empty list.
-		if (focus.getBegin() < window.getBegin() || focus.getEnd() > window.getEnd())
-			return scopeContextAnnotations;
-
-		FSIterator subiterator = jCas.getAnnotationIndex(contextType).subiterator(window);
-		subiterator.moveTo(focus);
-		subiterator.moveToPrevious();
-		if (!subiterator.isValid())
-			subiterator.moveTo(focus);
-
-		while (scopeContextAnnotations.size() < rightScopeSize) {
-			subiterator.moveToNext();
-			if (subiterator.isValid()) {
-				Annotation contextAnnotation = (Annotation) subiterator.get();
-				if (contextAnnotation.getBegin() < focus.getEnd()) {
-					continue;
-				}
-				if (!contextAnalyzer.isBoundary(contextAnnotation, RIGHT_SCOPE)) {
-					scopeContextAnnotations.add(contextAnnotation);
-				} else {
-					break;
-				}
-			} else {
-				break;
-			}
-		}
-		return scopeContextAnnotations;
-	}
-
-	protected List<Annotation> getMiddleScopeContextAnnotations(JCas jCas, Annotation focus)
-			throws AnalysisEngineProcessException {
-
-		List<Annotation> scopeContextAnnotations = new ArrayList<Annotation>();
-
-		FSIterator subiterator = jCas.getAnnotationIndex(contextType).subiterator(focus);
-		while (subiterator.hasNext()) {
-			scopeContextAnnotations.add((Annotation) subiterator.next());
-		}
-		if (scopeContextAnnotations.size() == 0 && JCasUtil.getType(focus.getClass()) == contextType)
-			scopeContextAnnotations.add(focus);
-		else if (scopeContextAnnotations.size() == 0) {
-			TypeSystem typeSystem = jCas.getTypeSystem();
-			Type superType = jCas.getType(focusType).casType;
-			Type subType = focus.getType();
-			if (typeSystem.subsumes(superType, subType))
-				scopeContextAnnotations.add(focus);
-		}
-		return scopeContextAnnotations;
-	}
-
-	/**
-	 * Gets a list of annotations within the specified window annotation.
-	 * 
-	 * @param annotItr
-	 * @param window
-	 * @param jcas
-	 * @return
-	 * @throws Exception
-	 */
-	private List<Annotation> constrainToWindow(JCas jCas, int type, Annotation window) {
-
-		List<Annotation> list = new ArrayList<Annotation>();
-
-		FSIterator subiterator = jCas.getAnnotationIndex(type).subiterator(window);
-
-		while (subiterator.hasNext()) {
-			Annotation annot = (Annotation) subiterator.next();
-			list.add(annot);
-		}
-		return list;
-	}
-
-}
\ No newline at end of file
+package edu.mayo.bmi.uima.context;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.apache.uima.UimaContext;
+import org.apache.uima.analysis_component.JCasAnnotator_ImplBase;
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.analysis_engine.annotator.AnnotatorConfigurationException;
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.Type;
+import org.apache.uima.cas.TypeSystem;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+import org.apache.uima.jcas.tcas.DocumentAnnotation;
+import org.apache.uima.resource.ResourceInitializationException;
+
+import edu.mayo.bmi.uima.core.util.JCasUtil;
+
+/**
+ * The context annotator iterates through focus annotations and analyzes the
+ * surrounding context of each. The context is defined by a scope, window, and a
+ * maximum size (if applicable). The context can be further refined by boundary
+ * conditions as specified by the context analyzer used. For each focus
+ * annotation, a context is collected as a set of context annotations for each
+ * scope that is to be applied. The context annotations are passed to a context
+ * analyzer for analysis. If the context analyzer finds something of interest in
+ * the context annotations, then it will generate a context hit. Context hits
+ * are then passed to a context hit consumer which will perform an action on the
+ * hit such as updating an existing annotation or creating a new one.
+ */
+public class ContextAnnotator extends JCasAnnotator_ImplBase {
+	// LOG4J logger based on class name
+	private Logger iv_logger = Logger.getLogger(getClass().getName());
+
+	/**
+	 * "MaxLeftScopeSize" is a required, single, integer parameter that
+	 * specifies the maximum size of the left scope.
+	 */
+	public static final String MAX_LEFT_SCOPE_SIZE_PARAM = "MaxLeftScopeSize";
+	/**
+	 * "MaxRightScopeSize" is a required, single, integer parameter that
+	 * specifies the maximum size of the right scope.
+	 */
+	public static final String MAX_RIGHT_SCOPE_SIZE_PARAM = "MaxRightScopeSize";
+	/**
+	 * "ScopeOrder" is a required, multiple, string parameter that specifies the
+	 * order that the scopes should be processed in. Possible values are "LEFT",
+	 * "MIDDLE", "RIGHT", and "ALL".
+	 */
+	public static final String SCOPE_ORDER_PARAM = "ScopeOrder";
+
+	/**
+	 * "WindowAnnotationClass" is a required, single, string parameter that
+	 * specifies the annotation type of the windows that specify the hard
+	 * boundaries of scopes. Note that the entire window may not be used
+	 * depending on the location of the focus annotation, the maximum scope
+	 * size, and the boundary conditions specified by the context analyzer. A
+	 * window encompasses all of the scopes (left, middle, and right). Examples
+	 * of likely window types would be:
+	 * <ul>
+	 * <li>DocumentAnnotation</li>
+	 * <li>SentenceAnnotation</li>
+	 * <li>SegmentAnnotation</li>
+	 * <li>...</li>
+	 * </ul>
+	 * 
+	 * @see DocumentAnnotation
+	 * @see edu.mayo.bmi.common.type.Sentence
+	 * @see edu.mayo.bmi.common.type.Segment
+	 * 
+	 */
+	public static final String WINDOW_ANNOTATION_CLASS_PARAM = "WindowAnnotationClass";
+	/**
+	 * "FocusAnnotationClass" is a required, single, string parameter that
+	 * specifies the annotation type of the focus annotations that are going to
+	 * be examined by this annotator. Examples of likely focus types would be:
+	 * <ul>
+	 * <li>NamedEntityAnnotation</li>
+	 * <li>Token</li>
+	 * <li>...</li>
+	 * </ul>
+	 * 
+	 * @see edu.mayo.bmi.common.type.NamedEntity
+	 * @see edu.mayo.bmi.common.type.BaseToken
+	 */
+
+	public static final String FOCUS_ANNOTATION_CLASS_PARAM = "FocusAnnotationClass";
+	/**
+	 * "ContextAnnotationClass" is a required, single, string parameter that
+	 * specifies the annotation type of the context annotations (often "tokens")
+	 * that make up the context relative to a focus annotation within a scope
+	 * that is being examined. The context annotations are examined for context
+	 * hits by the context analyzer. Examples of likely focus types would be:
+	 * <ul>
+	 * <li>BaseToken</li>
+	 * <li>WordToken</li>
+	 * <li>NamedEntity</li>
+	 * </ul>
+	 * 
+	 * @see edu.mayo.bmi.common.type.BaseToken
+	 * @see edu.mayo.bmi.common.type.WordToken
+	 * @see edu.mayo.bmi.common.type.NamedEntity
+	 * 
+	 */
+
+	public static final String CONTEXT_ANNOTATION_CLASS_PARAM = "ContextAnnotationClass";
+
+	/**
+	 * "ContextAnalyzerClass" is a required, single, string parameter that
+	 * specifies the context analyzer class that determines if a "hit" is found
+	 * within a processed scope.
+	 * 
+	 * @see ContextAnalyzer
+	 */
+	public static final String CONTEXT_ANALYZER_CLASS_PARAM = "ContextAnalyzerClass";
+	/**
+	 * "ContextHitConsumerClass" is a required, single, string parameter that
+	 * specifies the context hit consumer class that will process context hits
+	 * that are found.
+	 * 
+	 * @see ContextHitConsumer
+	 */
+	public static final String CONTEXT_HIT_CONSUMER_CLASS_PARAM = "ContextHitConsumerClass";
+
+	public static final int LEFT_SCOPE = 1;
+	/**
+	 * Provides context annotations that are "inside" the focus annotation. For
+	 * example, if the focus annotation type is a named entity mention and the
+	 * context annotation is a token type, then the middle scope will examine
+	 * the tokens that fall within the named entity mention.
+	 */
+	public static final int MIDDLE_SCOPE = 2;
+	public static final int RIGHT_SCOPE = 3;
+	/**
+	 * The ALL_SCOPE scope provides the context annotation that are found in all three of the other scopes (LEFT, MIDDLE, and RIGHT).  
+	 */
+	public static final int ALL_SCOPE = 4;
+
+	protected int leftScopeSize;
+	protected int rightScopeSize;
+
+	protected List<Integer> scopes = new ArrayList<Integer>();
+
+	protected ContextAnalyzer contextAnalyzer;
+	protected ContextHitConsumer contextConsumer;
+
+	int windowType;
+	int focusType;
+	int contextType;
+
+	public void initialize(UimaContext uimaContext) throws ResourceInitializationException {
+		super.initialize(uimaContext);
+
+		try {
+			leftScopeSize = ((Integer) uimaContext.getConfigParameterValue(MAX_LEFT_SCOPE_SIZE_PARAM)).intValue();
+			rightScopeSize = ((Integer) uimaContext.getConfigParameterValue(MAX_RIGHT_SCOPE_SIZE_PARAM)).intValue();
+
+			String[] scopeOrderArr = (String[]) uimaContext.getConfigParameterValue(SCOPE_ORDER_PARAM);
+
+			parseScopeOrder(scopeOrderArr);
+
+			String contextAnalyzerClassName = (String) uimaContext.getConfigParameterValue(CONTEXT_ANALYZER_CLASS_PARAM);
+			String contextConsumerClassName = (String) uimaContext.getConfigParameterValue(CONTEXT_HIT_CONSUMER_CLASS_PARAM);
+
+			contextAnalyzer = (ContextAnalyzer) Class.forName(contextAnalyzerClassName).newInstance();
+			contextAnalyzer.initialize(uimaContext);
+			contextConsumer = (ContextHitConsumer) Class.forName(contextConsumerClassName).newInstance();
+
+			windowType = JCasUtil.getType((String) uimaContext.getConfigParameterValue(WINDOW_ANNOTATION_CLASS_PARAM));
+			focusType = JCasUtil.getType((String) uimaContext.getConfigParameterValue(FOCUS_ANNOTATION_CLASS_PARAM));
+			contextType = JCasUtil.getType((String) uimaContext.getConfigParameterValue(CONTEXT_ANNOTATION_CLASS_PARAM));
+
+		} catch (Exception e) {
+			throw new ResourceInitializationException(e);
+		}
+	}
+
+	void parseScopeOrder(String[] scopeStrings) throws AnnotatorConfigurationException {
+		scopes.clear();
+		for (int i = 0; i < scopeStrings.length; i++) {
+			if (scopeStrings[i].equals("LEFT")) {
+				scopes.add(new Integer(LEFT_SCOPE));
+			} else if (scopeStrings[i].equals("MIDDLE")) {
+				scopes.add(new Integer(MIDDLE_SCOPE));
+			} else if (scopeStrings[i].equals("RIGHT")) {
+				scopes.add(new Integer(RIGHT_SCOPE));
+			} else if (scopeStrings[i].equals("ALL")) {
+				scopes.add(new Integer(ALL_SCOPE));
+			} else {
+				Exception e = new Exception("Invalid scope value: " + scopeStrings[i]);
+				throw new AnnotatorConfigurationException(e);
+			}
+		}
+		iv_logger.info("SCOPE ORDER: " + scopes);
+	}
+
+	public void process(JCas jCas) throws AnalysisEngineProcessException {
+		try {
+			FSIterator windowIterator = jCas.getAnnotationIndex(windowType).iterator();
+			while (windowIterator.hasNext()) {
+				Annotation window = (Annotation) windowIterator.next();
+				List<Annotation> focusList = constrainToWindow(jCas, focusType, window);
+
+				// why is this list reversed?
+				Collections.reverse(focusList);
+
+				Iterator<Integer> scopeIterator = scopes.iterator();
+				while (scopeIterator.hasNext()) {
+					int scope = scopeIterator.next();
+					Iterator<Annotation> focusIterator = focusList.iterator();
+					while (focusIterator.hasNext()) {
+						Annotation focus = focusIterator.next();
+						List<Annotation> scopeContextAnnotations = getScopeContextAnnotations(jCas, focus, window,
+								scope);
+						ContextHit contextHit = contextAnalyzer.analyzeContext(scopeContextAnnotations, scope);
+						if (contextHit != null) {
+							contextConsumer.consumeHit(jCas, focus, scope, contextHit);
+						}
+					}
+				}
+			}
+		} catch (Exception e) {
+			throw new AnalysisEngineProcessException(e);
+		}
+
+	}
+
+	protected List<Annotation> getScopeContextAnnotations(JCas jCas, Annotation focus, Annotation window, int scope)
+			throws AnalysisEngineProcessException {
+		List<Annotation> scopeContextAnnotations = new ArrayList<Annotation>();
+		switch (scope) {
+		case LEFT_SCOPE:
+			scopeContextAnnotations = getLeftScopeContextAnnotations(jCas, focus, window);
+			break;
+		case MIDDLE_SCOPE:
+			scopeContextAnnotations = getMiddleScopeContextAnnotations(jCas, focus);
+			break;
+		case RIGHT_SCOPE:
+			scopeContextAnnotations = getRightScopeContextAnnotations(jCas, focus, window);
+			break;
+		case ALL_SCOPE:
+			scopeContextAnnotations.addAll(getLeftScopeContextAnnotations(jCas, focus, window));
+			scopeContextAnnotations.addAll(getMiddleScopeContextAnnotations(jCas, focus));
+			scopeContextAnnotations.addAll(getRightScopeContextAnnotations(jCas, focus, window));
+			break;
+		}
+		return scopeContextAnnotations;
+	}
+
+	protected List<Annotation> getLeftScopeContextAnnotations(JCas jCas, Annotation focus, Annotation window)
+			throws AnalysisEngineProcessException {
+
+		List<Annotation> scopeContextAnnotations = new ArrayList<Annotation>();
+
+		// if focus is not completely contained inside the window annotation,
+		// then return empty list.
+		if (focus.getBegin() < window.getBegin() || focus.getEnd() > window.getEnd())
+			return scopeContextAnnotations;
+
+		FSIterator subiterator = jCas.getAnnotationIndex(contextType).subiterator(window);
+		subiterator.moveTo(focus);
+		subiterator.moveToNext();
+		if (!subiterator.isValid())
+			subiterator.moveTo(focus);
+
+		while (scopeContextAnnotations.size() < leftScopeSize) {
+			subiterator.moveToPrevious();
+			if (subiterator.isValid()) {
+				Annotation contextAnnotation = (Annotation) subiterator.get();
+				if (contextAnnotation.getEnd() > focus.getBegin()) {
+					continue;
+				}
+				if (!contextAnalyzer.isBoundary(contextAnnotation, LEFT_SCOPE)) {
+					scopeContextAnnotations.add(contextAnnotation);
+				} else {
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+		Collections.reverse(scopeContextAnnotations);
+		return scopeContextAnnotations;
+	}
+
+	protected List<Annotation> getRightScopeContextAnnotations(JCas jCas, Annotation focus, Annotation window)
+			throws AnalysisEngineProcessException {
+
+		List<Annotation> scopeContextAnnotations = new ArrayList<Annotation>();
+
+		// if focus is not completely contained inside the window annotation,
+		// then return empty list.
+		if (focus.getBegin() < window.getBegin() || focus.getEnd() > window.getEnd())
+			return scopeContextAnnotations;
+
+		FSIterator subiterator = jCas.getAnnotationIndex(contextType).subiterator(window);
+		subiterator.moveTo(focus);
+		subiterator.moveToPrevious();
+		if (!subiterator.isValid())
+			subiterator.moveTo(focus);
+
+		while (scopeContextAnnotations.size() < rightScopeSize) {
+			subiterator.moveToNext();
+			if (subiterator.isValid()) {
+				Annotation contextAnnotation = (Annotation) subiterator.get();
+				if (contextAnnotation.getBegin() < focus.getEnd()) {
+					continue;
+				}
+				if (!contextAnalyzer.isBoundary(contextAnnotation, RIGHT_SCOPE)) {
+					scopeContextAnnotations.add(contextAnnotation);
+				} else {
+					break;
+				}
+			} else {
+				break;
+			}
+		}
+		return scopeContextAnnotations;
+	}
+
+	protected List<Annotation> getMiddleScopeContextAnnotations(JCas jCas, Annotation focus)
+			throws AnalysisEngineProcessException {
+
+		List<Annotation> scopeContextAnnotations = new ArrayList<Annotation>();
+
+		FSIterator subiterator = jCas.getAnnotationIndex(contextType).subiterator(focus);
+		while (subiterator.hasNext()) {
+			scopeContextAnnotations.add((Annotation) subiterator.next());
+		}
+		if (scopeContextAnnotations.size() == 0 && JCasUtil.getType(focus.getClass()) == contextType)
+			scopeContextAnnotations.add(focus);
+		else if (scopeContextAnnotations.size() == 0) {
+			TypeSystem typeSystem = jCas.getTypeSystem();
+			Type superType = jCas.getType(focusType).casType;
+			Type subType = focus.getType();
+			if (typeSystem.subsumes(superType, subType))
+				scopeContextAnnotations.add(focus);
+		}
+		return scopeContextAnnotations;
+	}
+
+	/**
+	 * Gets a list of annotations within the specified window annotation.
+	 * 
+	 * @param annotItr
+	 * @param window
+	 * @param jcas
+	 * @return
+	 * @throws Exception
+	 */
+	private List<Annotation> constrainToWindow(JCas jCas, int type, Annotation window) {
+
+		List<Annotation> list = new ArrayList<Annotation>();
+
+		FSIterator subiterator = jCas.getAnnotationIndex(type).subiterator(window);
+
+		while (subiterator.hasNext()) {
+			Annotation annot = (Annotation) subiterator.next();
+			list.add(annot);
+		}
+		return list;
+	}
+
+}

Modified: incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextHit.java
URL: http://svn.apache.org/viewvc/incubator/ctakes/branches/SHARPn-cTAKES/NE%20contexts/src/edu/mayo/bmi/uima/context/ContextHit.java?rev=1403989&r1=1403988&r2=1403989&view=diff
==============================================================================
--- incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextHit.java (original)
+++ incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextHit.java Wed Oct 31 05:26:43 2012
@@ -1,18 +1,11 @@
 /*
- * Copyright: (c) 2009   Mayo Foundation for Medical Education and 
- * Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the
- * triple-shield Mayo logo are trademarks and service marks of MFMER.
- *
- * Except as contained in the copyright notice above, or as used to identify 
- * MFMER as the author of this software, the trade names, trademarks, service
- * marks, or product names of the copyright holder shall not be used in
- * advertising, promotion or otherwise in connection with this software without
- * prior written authorization of the copyright holder.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  * http://www.apache.org/licenses/LICENSE-2.0 
  * 
  * Unless required by applicable law or agreed to in writing, software
@@ -21,30 +14,30 @@
  * See the License for the specific language governing permissions and 
  * limitations under the License. 
  */
-package edu.mayo.bmi.uima.context;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import edu.mayo.bmi.fsm.output.BaseTokenImpl;
-
-/**
- * Object represents a hit relating to a focus annotation.
- * 
- * @author Mayo Clinic
- */
-public class ContextHit extends BaseTokenImpl {
-	private Map<Object, Object> iv_metaMap = new HashMap<Object, Object>();
-
-	public ContextHit(int startOffset, int endOffset) {
-		super(startOffset, endOffset);
-	}
-
-	public void addMetaData(Object key, Object metaData) {
-		iv_metaMap.put(key, metaData);
-	}
-
-	public Object getMetaData(Object key) {
-		return iv_metaMap.get(key);
-	}
-}
\ No newline at end of file
+package edu.mayo.bmi.uima.context;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import edu.mayo.bmi.fsm.output.BaseTokenImpl;
+
+/**
+ * Object represents a hit relating to a focus annotation.
+ * 
+ * @author Mayo Clinic
+ */
+public class ContextHit extends BaseTokenImpl {
+	private Map<Object, Object> iv_metaMap = new HashMap<Object, Object>();
+
+	public ContextHit(int startOffset, int endOffset) {
+		super(startOffset, endOffset);
+	}
+
+	public void addMetaData(Object key, Object metaData) {
+		iv_metaMap.put(key, metaData);
+	}
+
+	public Object getMetaData(Object key) {
+		return iv_metaMap.get(key);
+	}
+}

Modified: incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextHitConsumer.java
URL: http://svn.apache.org/viewvc/incubator/ctakes/branches/SHARPn-cTAKES/NE%20contexts/src/edu/mayo/bmi/uima/context/ContextHitConsumer.java?rev=1403989&r1=1403988&r2=1403989&view=diff
==============================================================================
--- incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextHitConsumer.java (original)
+++ incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextHitConsumer.java Wed Oct 31 05:26:43 2012
@@ -1,18 +1,11 @@
 /*
- * Copyright: (c) 2009   Mayo Foundation for Medical Education and 
- * Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the
- * triple-shield Mayo logo are trademarks and service marks of MFMER.
- *
- * Except as contained in the copyright notice above, or as used to identify 
- * MFMER as the author of this software, the trade names, trademarks, service
- * marks, or product names of the copyright holder shall not be used in
- * advertising, promotion or otherwise in connection with this software without
- * prior written authorization of the copyright holder.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  * http://www.apache.org/licenses/LICENSE-2.0 
  * 
  * Unless required by applicable law or agreed to in writing, software
@@ -21,32 +14,32 @@
  * See the License for the specific language governing permissions and 
  * limitations under the License. 
  */
-package edu.mayo.bmi.uima.context;
-
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
-import org.apache.uima.analysis_engine.annotator.AnnotatorProcessException;
-import org.apache.uima.jcas.JCas;
-import org.apache.uima.jcas.tcas.Annotation;
-
-/**
- * A context hit consumer is called by the context annotator when a context hit
- * is returned by its context analyzer.
- */
-
-public interface ContextHitConsumer {
-	/**
-	 * Implementation determines how context data is stored to the CAS.
-	 * 
-	 * @param jcas
-	 *            the UIMA view to update.
-	 * @param focusAnnotation
-	 *            The focus annotation.
-	 * @param scope
-	 *            Scope of the context hit.
-	 * @param contextHit
-	 *            The context hit.
-	 * @throws AnnotatorProcessException
-	 */
-	public void consumeHit(JCas jcas, Annotation focusAnnotation, int scope, ContextHit contextHit)
-			throws AnalysisEngineProcessException;
-}
\ No newline at end of file
+package edu.mayo.bmi.uima.context;
+
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.analysis_engine.annotator.AnnotatorProcessException;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+
+/**
+ * A context hit consumer is called by the context annotator when a context hit
+ * is returned by its context analyzer.
+ */
+
+public interface ContextHitConsumer {
+	/**
+	 * Implementation determines how context data is stored to the CAS.
+	 * 
+	 * @param jcas
+	 *            the UIMA view to update.
+	 * @param focusAnnotation
+	 *            The focus annotation.
+	 * @param scope
+	 *            Scope of the context hit.
+	 * @param contextHit
+	 *            The context hit.
+	 * @throws AnnotatorProcessException
+	 */
+	public void consumeHit(JCas jcas, Annotation focusAnnotation, int scope, ContextHit contextHit)
+			throws AnalysisEngineProcessException;
+}

Modified: incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextHitConsumerAdapter.java
URL: http://svn.apache.org/viewvc/incubator/ctakes/branches/SHARPn-cTAKES/NE%20contexts/src/edu/mayo/bmi/uima/context/ContextHitConsumerAdapter.java?rev=1403989&r1=1403988&r2=1403989&view=diff
==============================================================================
--- incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextHitConsumerAdapter.java (original)
+++ incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/ContextHitConsumerAdapter.java Wed Oct 31 05:26:43 2012
@@ -1,18 +1,11 @@
 /*
- * Copyright: (c) 2009   Mayo Foundation for Medical Education and 
- * Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the
- * triple-shield Mayo logo are trademarks and service marks of MFMER.
- *
- * Except as contained in the copyright notice above, or as used to identify 
- * MFMER as the author of this software, the trade names, trademarks, service
- * marks, or product names of the copyright holder shall not be used in
- * advertising, promotion or otherwise in connection with this software without
- * prior written authorization of the copyright holder.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  * http://www.apache.org/licenses/LICENSE-2.0 
  * 
  * Unless required by applicable law or agreed to in writing, software
@@ -21,17 +14,17 @@
  * See the License for the specific language governing permissions and 
  * limitations under the License. 
  */
-package edu.mayo.bmi.uima.context;
-
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
-import org.apache.uima.jcas.JCas;
-import org.apache.uima.jcas.tcas.Annotation;
-
-public class ContextHitConsumerAdapter implements ContextHitConsumer {
-
-	public void consumeHit(JCas jcas, Annotation focusAnnot, int scope, ContextHit ctxHit)
-			throws AnalysisEngineProcessException {
-
-	}
-
-}
+package edu.mayo.bmi.uima.context;
+
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+
+public class ContextHitConsumerAdapter implements ContextHitConsumer {
+
+	public void consumeHit(JCas jcas, Annotation focusAnnot, int scope, ContextHit ctxHit)
+			throws AnalysisEngineProcessException {
+
+	}
+
+}

Modified: incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/NamedEntityContextAnalyzer.java
URL: http://svn.apache.org/viewvc/incubator/ctakes/branches/SHARPn-cTAKES/NE%20contexts/src/edu/mayo/bmi/uima/context/NamedEntityContextAnalyzer.java?rev=1403989&r1=1403988&r2=1403989&view=diff
==============================================================================
--- incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/NamedEntityContextAnalyzer.java (original)
+++ incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/NamedEntityContextAnalyzer.java Wed Oct 31 05:26:43 2012
@@ -1,18 +1,11 @@
 /*
- * Copyright: (c) 2009   Mayo Foundation for Medical Education and 
- * Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the
- * triple-shield Mayo logo are trademarks and service marks of MFMER.
- *
- * Except as contained in the copyright notice above, or as used to identify 
- * MFMER as the author of this software, the trade names, trademarks, service
- * marks, or product names of the copyright holder shall not be used in
- * advertising, promotion or otherwise in connection with this software without
- * prior written authorization of the copyright holder.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  * http://www.apache.org/licenses/LICENSE-2.0 
  * 
  * Unless required by applicable law or agreed to in writing, software
@@ -21,106 +14,106 @@
  * See the License for the specific language governing permissions and 
  * limitations under the License. 
  */
-package edu.mayo.bmi.uima.context;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.log4j.Logger;
-import org.apache.uima.UimaContext;
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
-import org.apache.uima.jcas.tcas.Annotation;
-import org.apache.uima.resource.ResourceInitializationException;
-
-import edu.mayo.bmi.fsm.token.TextToken;
-import edu.mayo.bmi.uima.core.fsm.adapters.TextTokenAdapter;
-
-/**
- * This context analyzer provides code that is shared by the
- * StatusContextAnalyzer and NegationContextAnalyzer which are both analyzers
- * that examine the contexts surrounding named entity annotations.
- */
-public abstract class NamedEntityContextAnalyzer implements ContextAnalyzer {
-
-	private Logger iv_logger = Logger.getLogger(getClass().getName());
-
-	private Set<String> _boundaryWordSet;
-
-	public void initialize(UimaContext annotatorContext) throws ResourceInitializationException {
-		initBoundaryData();
-	}
-
-	private void initBoundaryData() {
-		iv_logger.info("initBoundaryData() called for ContextInitializer");
-		_boundaryWordSet = new HashSet<String>();
-		_boundaryWordSet.add("but");
-		_boundaryWordSet.add("however");
-		_boundaryWordSet.add("nevertheless");
-		_boundaryWordSet.add("notwithstanding");
-		_boundaryWordSet.add("though");
-		_boundaryWordSet.add("although");
-		_boundaryWordSet.add("if");
-		_boundaryWordSet.add("when");
-		_boundaryWordSet.add("how");
-		_boundaryWordSet.add("what");
-		_boundaryWordSet.add("which");
-		_boundaryWordSet.add("while");
-		_boundaryWordSet.add("since");
-		_boundaryWordSet.add("then");
-		_boundaryWordSet.add("i");
-		_boundaryWordSet.add("he");
-		_boundaryWordSet.add("she");
-		_boundaryWordSet.add("they");
-		_boundaryWordSet.add("we");
-
-		_boundaryWordSet.add(";");
-		_boundaryWordSet.add(":");
-		_boundaryWordSet.add(".");
-		_boundaryWordSet.add(")");
-	}
-
-	public boolean isBoundary(Annotation contextAnnotation, int scopeOrientation) throws AnalysisEngineProcessException {
-		String lcText = contextAnnotation.getCoveredText().toLowerCase();
-		return _boundaryWordSet.contains(lcText);
-	}
-
-	/**
-	 * This method converts Token annotations to TextTokens required by the fsm library used by both subclasses of this class.
-	 * @param tokenList a list of token annotations
-	 * @return a conversion of the token annotations as a list of TextTokens
-	 */
-	protected List<TextToken> wrapAsFsmTokens(List<? extends Annotation> tokenList) {
-		List<TextToken> fsmTokenList = new ArrayList<TextToken>();
-
-		Iterator<? extends Annotation> tokenItr = tokenList.iterator();
-		while (tokenItr.hasNext()) {
-			Annotation tokenAnnot = tokenItr.next();
-			fsmTokenList.add(new TextTokenAdapter(tokenAnnot));
-		}
-
-		// Add dummy token to end of the list
-		// This is a workaround for cases where a meaningful token occurs at the
-		// end of the list. Since there are no more tokens, the FSM cannot push
-		// itself into the next state. The dummy token's intent is to provide
-		// that extra token.
-		fsmTokenList.add(new TextToken() {
-
-			public String getText() {
-				return "+DUMMY_TOKEN+";
-			}
-
-			public int getEndOffset() {
-				return 0;
-			}
-
-			public int getStartOffset() {
-				return 0;
-			}
-		});
-
-		return fsmTokenList;
-	}
-}
+package edu.mayo.bmi.uima.context;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.apache.uima.UimaContext;
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.jcas.tcas.Annotation;
+import org.apache.uima.resource.ResourceInitializationException;
+
+import edu.mayo.bmi.fsm.token.TextToken;
+import edu.mayo.bmi.uima.core.fsm.adapters.TextTokenAdapter;
+
+/**
+ * This context analyzer provides code that is shared by the
+ * StatusContextAnalyzer and NegationContextAnalyzer which are both analyzers
+ * that examine the contexts surrounding named entity annotations.
+ */
+public abstract class NamedEntityContextAnalyzer implements ContextAnalyzer {
+
+	private Logger iv_logger = Logger.getLogger(getClass().getName());
+
+	private Set<String> _boundaryWordSet;
+
+	public void initialize(UimaContext annotatorContext) throws ResourceInitializationException {
+		initBoundaryData();
+	}
+
+	private void initBoundaryData() {
+		iv_logger.info("initBoundaryData() called for ContextInitializer");
+		_boundaryWordSet = new HashSet<String>();
+		_boundaryWordSet.add("but");
+		_boundaryWordSet.add("however");
+		_boundaryWordSet.add("nevertheless");
+		_boundaryWordSet.add("notwithstanding");
+		_boundaryWordSet.add("though");
+		_boundaryWordSet.add("although");
+		_boundaryWordSet.add("if");
+		_boundaryWordSet.add("when");
+		_boundaryWordSet.add("how");
+		_boundaryWordSet.add("what");
+		_boundaryWordSet.add("which");
+		_boundaryWordSet.add("while");
+		_boundaryWordSet.add("since");
+		_boundaryWordSet.add("then");
+		_boundaryWordSet.add("i");
+		_boundaryWordSet.add("he");
+		_boundaryWordSet.add("she");
+		_boundaryWordSet.add("they");
+		_boundaryWordSet.add("we");
+
+		_boundaryWordSet.add(";");
+		_boundaryWordSet.add(":");
+		_boundaryWordSet.add(".");
+		_boundaryWordSet.add(")");
+	}
+
+	public boolean isBoundary(Annotation contextAnnotation, int scopeOrientation) throws AnalysisEngineProcessException {
+		String lcText = contextAnnotation.getCoveredText().toLowerCase();
+		return _boundaryWordSet.contains(lcText);
+	}
+
+	/**
+	 * This method converts Token annotations to TextTokens required by the fsm library used by both subclasses of this class.
+	 * @param tokenList a list of token annotations
+	 * @return a conversion of the token annotations as a list of TextTokens
+	 */
+	protected List<TextToken> wrapAsFsmTokens(List<? extends Annotation> tokenList) {
+		List<TextToken> fsmTokenList = new ArrayList<TextToken>();
+
+		Iterator<? extends Annotation> tokenItr = tokenList.iterator();
+		while (tokenItr.hasNext()) {
+			Annotation tokenAnnot = tokenItr.next();
+			fsmTokenList.add(new TextTokenAdapter(tokenAnnot));
+		}
+
+		// Add dummy token to end of the list
+		// This is a workaround for cases where a meaningful token occurs at the
+		// end of the list. Since there are no more tokens, the FSM cannot push
+		// itself into the next state. The dummy token's intent is to provide
+		// that extra token.
+		fsmTokenList.add(new TextToken() {
+
+			public String getText() {
+				return "+DUMMY_TOKEN+";
+			}
+
+			public int getEndOffset() {
+				return 0;
+			}
+
+			public int getStartOffset() {
+				return 0;
+			}
+		});
+
+		return fsmTokenList;
+	}
+}

Modified: incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/NamedEntityContextHitConsumer.java
URL: http://svn.apache.org/viewvc/incubator/ctakes/branches/SHARPn-cTAKES/NE%20contexts/src/edu/mayo/bmi/uima/context/NamedEntityContextHitConsumer.java?rev=1403989&r1=1403988&r2=1403989&view=diff
==============================================================================
--- incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/NamedEntityContextHitConsumer.java (original)
+++ incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/NamedEntityContextHitConsumer.java Wed Oct 31 05:26:43 2012
@@ -1,18 +1,11 @@
 /*
- * Copyright: (c) 2009   Mayo Foundation for Medical Education and 
- * Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the
- * triple-shield Mayo logo are trademarks and service marks of MFMER.
- *
- * Except as contained in the copyright notice above, or as used to identify 
- * MFMER as the author of this software, the trade names, trademarks, service
- * marks, or product names of the copyright holder shall not be used in
- * advertising, promotion or otherwise in connection with this software without
- * prior written authorization of the copyright holder.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  * http://www.apache.org/licenses/LICENSE-2.0 
  * 
  * Unless required by applicable law or agreed to in writing, software
@@ -21,32 +14,32 @@
  * See the License for the specific language governing permissions and 
  * limitations under the License. 
  */
-package edu.mayo.bmi.uima.context;
-
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
-import org.apache.uima.jcas.JCas;
-import org.apache.uima.jcas.tcas.Annotation;
-
-import edu.mayo.bmi.uima.core.type.textsem.ContextAnnotation;
-
-
-public abstract class NamedEntityContextHitConsumer implements ContextHitConsumer {
-	public abstract void consumeHit(JCas jcas, Annotation focusAnnot, int scope, ContextHit ctxHit)
-			throws AnalysisEngineProcessException;
-
-	protected ContextAnnotation createContextAnnot(JCas jcas, Annotation focusAnnot, int scope, ContextHit ctxHit) {
-		ContextAnnotation ctxAnnot = new ContextAnnotation(jcas);
-		ctxAnnot.setBegin(ctxHit.getStartOffset());
-		ctxAnnot.setEnd(ctxHit.getEndOffset());
-		if (scope == ContextAnnotator.LEFT_SCOPE) {
-			ctxAnnot.setScope("LEFT");
-		} else if (scope == ContextAnnotator.MIDDLE_SCOPE) {
-			ctxAnnot.setScope("MIDDLE");
-		} else if (scope == ContextAnnotator.RIGHT_SCOPE) {
-			ctxAnnot.setScope("RIGHT");
-		}
-		ctxAnnot.setFocusText(focusAnnot.getCoveredText());
-		return ctxAnnot;
-	}
-
-}
+package edu.mayo.bmi.uima.context;
+
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+
+import edu.mayo.bmi.uima.core.type.textsem.ContextAnnotation;
+
+
+public abstract class NamedEntityContextHitConsumer implements ContextHitConsumer {
+	public abstract void consumeHit(JCas jcas, Annotation focusAnnot, int scope, ContextHit ctxHit)
+			throws AnalysisEngineProcessException;
+
+	protected ContextAnnotation createContextAnnot(JCas jcas, Annotation focusAnnot, int scope, ContextHit ctxHit) {
+		ContextAnnotation ctxAnnot = new ContextAnnotation(jcas);
+		ctxAnnot.setBegin(ctxHit.getStartOffset());
+		ctxAnnot.setEnd(ctxHit.getEndOffset());
+		if (scope == ContextAnnotator.LEFT_SCOPE) {
+			ctxAnnot.setScope("LEFT");
+		} else if (scope == ContextAnnotator.MIDDLE_SCOPE) {
+			ctxAnnot.setScope("MIDDLE");
+		} else if (scope == ContextAnnotator.RIGHT_SCOPE) {
+			ctxAnnot.setScope("RIGHT");
+		}
+		ctxAnnot.setFocusText(focusAnnot.getCoveredText());
+		return ctxAnnot;
+	}
+
+}

Modified: incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/negation/NegationContextAnalyzer.java
URL: http://svn.apache.org/viewvc/incubator/ctakes/branches/SHARPn-cTAKES/NE%20contexts/src/edu/mayo/bmi/uima/context/negation/NegationContextAnalyzer.java?rev=1403989&r1=1403988&r2=1403989&view=diff
==============================================================================
--- incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/negation/NegationContextAnalyzer.java (original)
+++ incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/negation/NegationContextAnalyzer.java Wed Oct 31 05:26:43 2012
@@ -1,18 +1,11 @@
 /*
- * Copyright: (c) 2009   Mayo Foundation for Medical Education and 
- * Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the
- * triple-shield Mayo logo are trademarks and service marks of MFMER.
- *
- * Except as contained in the copyright notice above, or as used to identify 
- * MFMER as the author of this software, the trade names, trademarks, service
- * marks, or product names of the copyright holder shall not be used in
- * advertising, promotion or otherwise in connection with this software without
- * prior written authorization of the copyright holder.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  * http://www.apache.org/licenses/LICENSE-2.0 
  * 
  * Unless required by applicable law or agreed to in writing, software
@@ -21,44 +14,44 @@
  * See the License for the specific language governing permissions and 
  * limitations under the License. 
  */
-package edu.mayo.bmi.uima.context.negation;
-
-import java.util.List;
-import java.util.Set;
-
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
-import org.apache.uima.jcas.tcas.Annotation;
-
-import edu.mayo.bmi.fsm.machine.NegationFSM;
-import edu.mayo.bmi.fsm.output.NegationIndicator;
-import edu.mayo.bmi.fsm.token.TextToken;
-import edu.mayo.bmi.uima.context.ContextHit;
-import edu.mayo.bmi.uima.context.NamedEntityContextAnalyzer;
-
-public class NegationContextAnalyzer extends NamedEntityContextAnalyzer {
-	private NegationFSM _negIndicatorFSM = new NegationFSM();
-
-	/**
-	 * This method analyzes a list of tokens looking for a negation pattern as
-	 * specified by the class NegationFSM.
-	 * 
-	 * @see NegationFSM
-	 */
-	public ContextHit analyzeContext(List<? extends Annotation> contextTokens, int scopeOrientation)
-			throws AnalysisEngineProcessException {
-		List<TextToken> fsmTokenList = wrapAsFsmTokens(contextTokens);
-
-		try {
-			Set<NegationIndicator> s = _negIndicatorFSM.execute(fsmTokenList);
-
-			if (s.size() > 0) {
-				NegationIndicator neg = s.iterator().next();
-				return new ContextHit(neg.getStartOffset(), neg.getEndOffset());
-			} else {
-				return null;
-			}
-		} catch (Exception e) {
-			throw new AnalysisEngineProcessException(e);
-		}
-	}
-}
\ No newline at end of file
+package edu.mayo.bmi.uima.context.negation;
+
+import java.util.List;
+import java.util.Set;
+
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.jcas.tcas.Annotation;
+
+import edu.mayo.bmi.fsm.machine.NegationFSM;
+import edu.mayo.bmi.fsm.output.NegationIndicator;
+import edu.mayo.bmi.fsm.token.TextToken;
+import edu.mayo.bmi.uima.context.ContextHit;
+import edu.mayo.bmi.uima.context.NamedEntityContextAnalyzer;
+
+public class NegationContextAnalyzer extends NamedEntityContextAnalyzer {
+	private NegationFSM _negIndicatorFSM = new NegationFSM();
+
+	/**
+	 * This method analyzes a list of tokens looking for a negation pattern as
+	 * specified by the class NegationFSM.
+	 * 
+	 * @see NegationFSM
+	 */
+	public ContextHit analyzeContext(List<? extends Annotation> contextTokens, int scopeOrientation)
+			throws AnalysisEngineProcessException {
+		List<TextToken> fsmTokenList = wrapAsFsmTokens(contextTokens);
+
+		try {
+			Set<NegationIndicator> s = _negIndicatorFSM.execute(fsmTokenList);
+
+			if (s.size() > 0) {
+				NegationIndicator neg = s.iterator().next();
+				return new ContextHit(neg.getStartOffset(), neg.getEndOffset());
+			} else {
+				return null;
+			}
+		} catch (Exception e) {
+			throw new AnalysisEngineProcessException(e);
+		}
+	}
+}

Modified: incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/negation/NegationContextHitConsumer.java
URL: http://svn.apache.org/viewvc/incubator/ctakes/branches/SHARPn-cTAKES/NE%20contexts/src/edu/mayo/bmi/uima/context/negation/NegationContextHitConsumer.java?rev=1403989&r1=1403988&r2=1403989&view=diff
==============================================================================
--- incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/negation/NegationContextHitConsumer.java (original)
+++ incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/negation/NegationContextHitConsumer.java Wed Oct 31 05:26:43 2012
@@ -1,18 +1,11 @@
 /*
- * Copyright: (c) 2009   Mayo Foundation for Medical Education and 
- * Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the
- * triple-shield Mayo logo are trademarks and service marks of MFMER.
- *
- * Except as contained in the copyright notice above, or as used to identify 
- * MFMER as the author of this software, the trade names, trademarks, service
- * marks, or product names of the copyright holder shall not be used in
- * advertising, promotion or otherwise in connection with this software without
- * prior written authorization of the copyright holder.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  * http://www.apache.org/licenses/LICENSE-2.0 
  * 
  * Unless required by applicable law or agreed to in writing, software
@@ -21,28 +14,28 @@
  * See the License for the specific language governing permissions and 
  * limitations under the License. 
  */
-package edu.mayo.bmi.uima.context.negation;
-
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
-import org.apache.uima.jcas.JCas;
-import org.apache.uima.jcas.tcas.Annotation;
-
-import edu.mayo.bmi.uima.core.type.textsem.IdentifiedAnnotation;
-import edu.mayo.bmi.uima.context.ContextHitConsumer;
-import edu.mayo.bmi.uima.context.ContextHit;
-import edu.mayo.bmi.uima.context.NamedEntityContextHitConsumer;
-
-/**
- * @author Mayo Clinic
- */
-public class NegationContextHitConsumer extends NamedEntityContextHitConsumer implements ContextHitConsumer {
-	public void consumeHit(JCas jcas, Annotation focusAnnot, int scope, ContextHit ctxHit)
-			throws AnalysisEngineProcessException {
-		if (focusAnnot instanceof IdentifiedAnnotation) {
-			IdentifiedAnnotation neAnnot = (IdentifiedAnnotation) focusAnnot;
-			neAnnot.setPolarity(-1);
-		}
-
-		createContextAnnot(jcas, focusAnnot, scope, ctxHit).addToIndexes();
-	}
-}
+package edu.mayo.bmi.uima.context.negation;
+
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+
+import edu.mayo.bmi.uima.core.type.textsem.IdentifiedAnnotation;
+import edu.mayo.bmi.uima.context.ContextHitConsumer;
+import edu.mayo.bmi.uima.context.ContextHit;
+import edu.mayo.bmi.uima.context.NamedEntityContextHitConsumer;
+
+/**
+ * @author Mayo Clinic
+ */
+public class NegationContextHitConsumer extends NamedEntityContextHitConsumer implements ContextHitConsumer {
+	public void consumeHit(JCas jcas, Annotation focusAnnot, int scope, ContextHit ctxHit)
+			throws AnalysisEngineProcessException {
+		if (focusAnnot instanceof IdentifiedAnnotation) {
+			IdentifiedAnnotation neAnnot = (IdentifiedAnnotation) focusAnnot;
+			neAnnot.setPolarity(-1);
+		}
+
+		createContextAnnot(jcas, focusAnnot, scope, ctxHit).addToIndexes();
+	}
+}

Modified: incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/status/StatusContextAnalyzer.java
URL: http://svn.apache.org/viewvc/incubator/ctakes/branches/SHARPn-cTAKES/NE%20contexts/src/edu/mayo/bmi/uima/context/status/StatusContextAnalyzer.java?rev=1403989&r1=1403988&r2=1403989&view=diff
==============================================================================
--- incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/status/StatusContextAnalyzer.java (original)
+++ incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/status/StatusContextAnalyzer.java Wed Oct 31 05:26:43 2012
@@ -1,18 +1,11 @@
 /*
- * Copyright: (c) 2009   Mayo Foundation for Medical Education and 
- * Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the
- * triple-shield Mayo logo are trademarks and service marks of MFMER.
- *
- * Except as contained in the copyright notice above, or as used to identify 
- * MFMER as the author of this software, the trade names, trademarks, service
- * marks, or product names of the copyright holder shall not be used in
- * advertising, promotion or otherwise in connection with this software without
- * prior written authorization of the copyright holder.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  * http://www.apache.org/licenses/LICENSE-2.0 
  * 
  * Unless required by applicable law or agreed to in writing, software
@@ -21,74 +14,74 @@
  * See the License for the specific language governing permissions and 
  * limitations under the License. 
  */
-package edu.mayo.bmi.uima.context.status;
-
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
-import org.apache.uima.jcas.tcas.Annotation;
-
-import edu.mayo.bmi.fsm.machine.StatusIndicatorFSM;
-import edu.mayo.bmi.fsm.output.StatusIndicator;
-import edu.mayo.bmi.fsm.token.TextToken;
-import edu.mayo.bmi.uima.context.ContextAnnotator;
-import edu.mayo.bmi.uima.context.ContextHit;
-import edu.mayo.bmi.uima.context.ContextAnalyzer;
-import edu.mayo.bmi.uima.context.NamedEntityContextAnalyzer;
-
-public class StatusContextAnalyzer extends NamedEntityContextAnalyzer implements ContextAnalyzer {
-	public static final String CTX_HIT_KEY_STATUS_TYPE = "STATUS_TYPE";
-
-	private StatusIndicatorFSM _statusIndicatorFSM = new StatusIndicatorFSM();
-
-	/**
-	 * Analyze a list of tokens looking for a status pattern as
-	 * specified by the class StatusIndicatorFSM.
-	 * An indication of family history found within the scope takes precedence over 
-	 * an indication of history of, even if evidence of history of is closer.
-	 * Otherwise, the closest indicator of status is used.
-	 * 
-	 * @see StatusIndicatorFSM
-	 */
-
-	public ContextHit analyzeContext(List<? extends Annotation> tokenList, int scope) throws AnalysisEngineProcessException{
-		List<TextToken> fsmTokenList = wrapAsFsmTokens(tokenList);
-
-		try {
-			Set<StatusIndicator> s = _statusIndicatorFSM.execute(fsmTokenList);
-
-			if (s.size() > 0) {
-				StatusIndicator finalSi = null;
-				Iterator<StatusIndicator> siItr = s.iterator();
-				while (siItr.hasNext()) {
-					StatusIndicator si = siItr.next();
-					if (finalSi == null) {
-						finalSi = si;
-					} else if ((si.getStatus() == StatusIndicator.FAMILY_HISTORY_STATUS)
-							&& (finalSi.getStatus() == StatusIndicator.HISTORY_STATUS)) {
-						// family history always overrides history
-						finalSi = si;
-					} else if ((scope == ContextAnnotator.LEFT_SCOPE) && (si.getEndOffset() > finalSi.getEndOffset())) {
-						// pick one with closest proximity to focus
-						finalSi = si;
-					} else if ((scope == ContextAnnotator.RIGHT_SCOPE)
-							&& (si.getStartOffset() < finalSi.getStartOffset())) {
-						// pick one w/ closest proximity to focus
-						finalSi = si;
-					}
-				}
-				ContextHit ctxHit = new ContextHit(finalSi.getStartOffset(), finalSi.getEndOffset());
-
-				ctxHit.addMetaData(CTX_HIT_KEY_STATUS_TYPE, new Integer(finalSi.getStatus()));
-
-				return ctxHit;
-			} else {
-				return null;
-			}
-		} catch (Exception e) {
-			throw new AnalysisEngineProcessException(e);
-		}
-	}
-}
\ No newline at end of file
+package edu.mayo.bmi.uima.context.status;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.jcas.tcas.Annotation;
+
+import edu.mayo.bmi.fsm.machine.StatusIndicatorFSM;
+import edu.mayo.bmi.fsm.output.StatusIndicator;
+import edu.mayo.bmi.fsm.token.TextToken;
+import edu.mayo.bmi.uima.context.ContextAnnotator;
+import edu.mayo.bmi.uima.context.ContextHit;
+import edu.mayo.bmi.uima.context.ContextAnalyzer;
+import edu.mayo.bmi.uima.context.NamedEntityContextAnalyzer;
+
+public class StatusContextAnalyzer extends NamedEntityContextAnalyzer implements ContextAnalyzer {
+	public static final String CTX_HIT_KEY_STATUS_TYPE = "STATUS_TYPE";
+
+	private StatusIndicatorFSM _statusIndicatorFSM = new StatusIndicatorFSM();
+
+	/**
+	 * Analyze a list of tokens looking for a status pattern as
+	 * specified by the class StatusIndicatorFSM.
+	 * An indication of family history found within the scope takes precedence over 
+	 * an indication of history of, even if evidence of history of is closer.
+	 * Otherwise, the closest indicator of status is used.
+	 * 
+	 * @see StatusIndicatorFSM
+	 */
+
+	public ContextHit analyzeContext(List<? extends Annotation> tokenList, int scope) throws AnalysisEngineProcessException{
+		List<TextToken> fsmTokenList = wrapAsFsmTokens(tokenList);
+
+		try {
+			Set<StatusIndicator> s = _statusIndicatorFSM.execute(fsmTokenList);
+
+			if (s.size() > 0) {
+				StatusIndicator finalSi = null;
+				Iterator<StatusIndicator> siItr = s.iterator();
+				while (siItr.hasNext()) {
+					StatusIndicator si = siItr.next();
+					if (finalSi == null) {
+						finalSi = si;
+					} else if ((si.getStatus() == StatusIndicator.FAMILY_HISTORY_STATUS)
+							&& (finalSi.getStatus() == StatusIndicator.HISTORY_STATUS)) {
+						// family history always overrides history
+						finalSi = si;
+					} else if ((scope == ContextAnnotator.LEFT_SCOPE) && (si.getEndOffset() > finalSi.getEndOffset())) {
+						// pick one with closest proximity to focus
+						finalSi = si;
+					} else if ((scope == ContextAnnotator.RIGHT_SCOPE)
+							&& (si.getStartOffset() < finalSi.getStartOffset())) {
+						// pick one w/ closest proximity to focus
+						finalSi = si;
+					}
+				}
+				ContextHit ctxHit = new ContextHit(finalSi.getStartOffset(), finalSi.getEndOffset());
+
+				ctxHit.addMetaData(CTX_HIT_KEY_STATUS_TYPE, new Integer(finalSi.getStatus()));
+
+				return ctxHit;
+			} else {
+				return null;
+			}
+		} catch (Exception e) {
+			throw new AnalysisEngineProcessException(e);
+		}
+	}
+}

Modified: incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/status/StatusContextHitConsumer.java
URL: http://svn.apache.org/viewvc/incubator/ctakes/branches/SHARPn-cTAKES/NE%20contexts/src/edu/mayo/bmi/uima/context/status/StatusContextHitConsumer.java?rev=1403989&r1=1403988&r2=1403989&view=diff
==============================================================================
--- incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/status/StatusContextHitConsumer.java (original)
+++ incubator/ctakes/branches/SHARPn-cTAKES/NE contexts/src/edu/mayo/bmi/uima/context/status/StatusContextHitConsumer.java Wed Oct 31 05:26:43 2012
@@ -1,18 +1,11 @@
 /*
- * Copyright: (c) 2009   Mayo Foundation for Medical Education and 
- * Research (MFMER). All rights reserved. MAYO, MAYO CLINIC, and the
- * triple-shield Mayo logo are trademarks and service marks of MFMER.
- *
- * Except as contained in the copyright notice above, or as used to identify 
- * MFMER as the author of this software, the trade names, trademarks, service
- * marks, or product names of the copyright holder shall not be used in
- * advertising, promotion or otherwise in connection with this software without
- * prior written authorization of the copyright holder.
- * 
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
  * http://www.apache.org/licenses/LICENSE-2.0 
  * 
  * Unless required by applicable law or agreed to in writing, software
@@ -21,31 +14,31 @@
  * See the License for the specific language governing permissions and 
  * limitations under the License. 
  */
-package edu.mayo.bmi.uima.context.status;
-
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
-import org.apache.uima.jcas.JCas;
-import org.apache.uima.jcas.tcas.Annotation;
-
-import edu.mayo.bmi.uima.core.type.textsem.IdentifiedAnnotation;
-import edu.mayo.bmi.uima.context.ContextHitConsumer;
-import edu.mayo.bmi.uima.context.ContextHit;
-import edu.mayo.bmi.uima.context.NamedEntityContextHitConsumer;
-
-/**
- * @author Mayo Clinic
- */
-public class StatusContextHitConsumer extends NamedEntityContextHitConsumer implements ContextHitConsumer {
-	public void consumeHit(JCas jcas, Annotation focusAnnot, int scope, ContextHit ctxHit)
-			throws AnalysisEngineProcessException {
-		
-		Integer status = (Integer) ctxHit.getMetaData(StatusContextAnalyzer.CTX_HIT_KEY_STATUS_TYPE);
-		if (focusAnnot instanceof IdentifiedAnnotation) {
+package edu.mayo.bmi.uima.context.status;
+
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.tcas.Annotation;
+
+import edu.mayo.bmi.uima.core.type.textsem.IdentifiedAnnotation;
+import edu.mayo.bmi.uima.context.ContextHitConsumer;
+import edu.mayo.bmi.uima.context.ContextHit;
+import edu.mayo.bmi.uima.context.NamedEntityContextHitConsumer;
+
+/**
+ * @author Mayo Clinic
+ */
+public class StatusContextHitConsumer extends NamedEntityContextHitConsumer implements ContextHitConsumer {
+	public void consumeHit(JCas jcas, Annotation focusAnnot, int scope, ContextHit ctxHit)
+			throws AnalysisEngineProcessException {
+		
+		Integer status = (Integer) ctxHit.getMetaData(StatusContextAnalyzer.CTX_HIT_KEY_STATUS_TYPE);
+		if (focusAnnot instanceof IdentifiedAnnotation) {
 			IdentifiedAnnotation neAnnot = (IdentifiedAnnotation) focusAnnot;
-			//TODO: currently status is an int in the old system.  Let's update this to a constant string?
-			neAnnot.setUncertainty(status);
-		}
-
-		createContextAnnot(jcas, focusAnnot, scope, ctxHit).addToIndexes();
-	}
-}
\ No newline at end of file
+			//TODO: currently status is an int in the old system.  Let's update this to a constant string?
+			neAnnot.setUncertainty(status);
+		}
+
+		createContextAnnot(jcas, focusAnnot, scope, ctxHit).addToIndexes();
+	}
+}