code: func Iterate(p *dt.Plugin, label string, opts OptsIterate) []dt.State {
  	if len(label) == 0 {
  		label = "__iterableStart"
  	}
  	return []dt.State{
  		{
  			Label: label,
  			OnEntry: func(in *dt.Msg) string {
  				var ss []string
  				mem := p.GetMemory(in, opts.IterableMemKey)
  				if len(mem.Val) == 0 {
  					mem.Val = []byte(`[]`)
  				}
  				err := json.Unmarshal(mem.Val, &ss)
  				if err != nil {
  					p.Log.Info("failed to get iterable memory.", err)
  					return ""
  				}
  				if len(ss) == 0 {
  					return "I'm afraid I couldn't find any results like that."
  				}
  				var idx int64
  				if p.HasMemory(in, keySelection) {
  					idx = p.GetMemory(in, keySelection).Int64() + 1
  				}
  				if idx >= int64(len(ss)) {
  					return "I'm afraid that's all I have."
  				}
  				p.SetMemory(in, keySelection, idx)
  				return fmt.Sprintf("How about %s?", ss[idx])
  			},
  			OnInput: func(in *dt.Msg) {
  				yes, err := language.ExtractYesNo(in.Sentence)
  				if err != nil {
  					// Yes/No answer not found
  					return
  				}
  				if yes {
  					idx := p.GetMemory(in, keySelection).Int64()
  					p.SetMemory(in, opts.ResultMemKeyIdx, idx)
  					return
  				}
  				// TODO handle "next", "something else", etc.
  			},
  			Complete: func(in *dt.Msg) (bool, string) {
  				if p.HasMemory(in, opts.ResultMemKeyIdx) {
  					return true, ""
  				}
  				return false, p.SM.ReplayState(in)
  			},
  		},
  	}
  }
docs: // Iterate through a set of options allowing the user to select one before
  // continuing.