code: func extractContext(a *lingo.Annotation) (retVal [featuresPerContext]string) {
  	if a == nil {
  		return retVal
  	}
  
  	word := a.Lowered
  
  	// we normalize all the unicode btes first
  	asRunes := []rune(a.Value)
  	loweredRunes := []rune(word)
  
  	retVal[0] = word
  	retVal[1] = a.Lemma
  	retVal[2] = strconv.Itoa(int(a.Cluster))
  	retVal[3] = string(a.Shape)
  
  	// prefix and suffix
  	// we want the characters, not the bytes
  	// for the prefix, we'll use the un-normalized version because having that extra fidelity would be useful
  	if len(asRunes) > 0 {
  		retVal[4] = string(asRunes[0])
  	} else {
  		retVal[4] = ""
  	}
  	if len(loweredRunes) >= 3 {
  		retVal[5] = string(loweredRunes[len(loweredRunes)-3 : len(loweredRunes)])
  	} else {
  		retVal[5] = ""
  	}
  	retVal[6] = a.POSTag.String()
  	retVal[7] = a.WordFlag.String()
  
  	return retVal
  }
docs: // type featureContext struct {
  // 	word    string
  // 	lemma   string
  // 	cluster lingo.Cluster
  // 	shape   string
  // 	prefix  string
  // 	suffix  string
  // 	POSTag  lingo.POSTag
  // 	flag    lingo.WordFlag
  // }
  // extractContext extracts the feature contexts from a given annotation