func (task *Task) ToLinks() []*Link {
	return task.toLinks
}
ToLinks returns the predecessor links of the task
package definition
import (
	"fmt"
	"github.com/project-flogo/core/data/coerce"
	"github.com/project-flogo/core/activity"
	"github.com/project-flogo/core/data"
	"github.com/project-flogo/core/data/expression"
	"github.com/project-flogo/core/data/mapper"
	"github.com/project-flogo/core/data/metadata"
	"github.com/project-flogo/core/data/schema"
	"github.com/project-flogo/core/support"
	"github.com/project-flogo/core/support/log"
)
type Definition struct {
	name          string
	modelID       string
	explicitReply bool
	attrs map[string]*data.Attribute
	links map[int]*Link
	tasks map[string]*Task
	metadata *metadata.IOMetadata
	errorHandler *ErrorHandler
}
func (d *Definition) Name() string {
	return d.name
}
func (d *Definition) ModelID() string {
	return d.modelID
}
func (d *Definition) Metadata() *metadata.IOMetadata {
	return d.metadata
}
func (d *Definition) GetTask(taskID string) *Task {
	task := d.tasks[taskID]
	return task
}
func (d *Definition) GetLink(linkID int) *Link {
	task := d.links[linkID]
	return task
}
func (d *Definition) ExplicitReply() bool {
	return d.explicitReply
}
func (d *Definition) GetErrorHandler() *ErrorHandler {
	return d.errorHandler
}
func (d *Definition) GetAttr(attrName string) (attr *data.Attribute, exists bool) {
	if d.attrs != nil {
		attr, found := d.attrs[attrName]
		if found {
			return attr, true
		}
	}
	return nil, false
}
func (d *Definition) Cleanup() error {
	for id, task := range d.tasks {
		if !activity.IsSingleton(task.activityCfg.Activity) {
			if needsDisposal, ok := task.activityCfg.Activity.(support.NeedsCleanup); ok {
				err := needsDisposal.Cleanup()
				if err != nil {
					log.RootLogger().Warnf("Error disposing activity '%s' : ", id, err)
				}
			}
		}
	}
	return nil
}
func (d *Definition) Tasks() []*Task {
	tasks := make([]*Task, 0, len(d.tasks))
	for _, task := range d.tasks {
		tasks = append(tasks, task)
	}
	return tasks
}
func (d *Definition) Links() []*Link {
	links := make([]*Link, 0, len(d.links))
	for _, link := range d.links {
		links = append(links, link)
	}
	return links
}
type ActivityConfig struct {
	Activity activity.Activity
	Logger   log.Logger
	settings map[string]interface{}
	inputMapper  mapper.Mapper
	outputMapper mapper.Mapper
	inputSchemas  map[string]schema.Schema
	outputSchemas map[string]schema.Schema
	Details *activity.Details
	outputs  map[string]interface{}
	IsLegacy bool
}
func (ac *ActivityConfig) GetInputSchema(name string) schema.Schema {
	if ac.inputSchemas != nil {
		return ac.inputSchemas[name]
	}
	return nil
}
func (ac *ActivityConfig) GetOutput(name string) interface{} {
	if ac.outputs != nil {
		return ac.outputs[name]
	}
	return nil
}
func (ac *ActivityConfig) GetOutputSchema(name string) schema.Schema {
	if ac.outputSchemas != nil {
		return ac.outputSchemas[name]
	}
	return nil
}
func (ac *ActivityConfig) Ref() string {
	return activity.GetRef(ac.Activity)
}
func (ac *ActivityConfig) GetSetting(setting string) (val interface{}, exists bool) {
	if ac.settings != nil {
		val, found := ac.settings[setting]
		if found {
			return val, true
		}
	}
	return nil, false
}
func (ac *ActivityConfig) InputMapper() mapper.Mapper {
	return ac.inputMapper
}
func (ac *ActivityConfig) OutputMapper() mapper.Mapper {
	return ac.outputMapper
}
type LoopConfig struct {
	condition      expression.Expr
	accumulate     bool
	delay          int
	iterateOn      interface{}
	accApplyOutput bool
}
func (l *LoopConfig) Accumulate() bool {
	return l.accumulate
}
func (l *LoopConfig) ApplyOutputOnAccumulate() bool {
	return l.accApplyOutput
}
func (l *LoopConfig) Condition() expression.Expr {
	return l.condition
}
func (l *LoopConfig) GetIterateOn() interface{} {
	return l.iterateOn
}
func (l *LoopConfig) Delay() int {
	return l.delay
}
type RetryOnError interface {
	Count(scope data.Scope) (int, error)
	Interval(scope data.Scope) (int, error)
}
type retryOnErrConfig struct {
	count    interface{}
	interval interface{}
}
func (r *retryOnErrConfig) Count(scope data.Scope) (int, error) {
	if r.count != nil {
		switch t := r.count.(type) {
		case expression.Expr:
			data, err := t.Eval(scope)
			if err != nil {
				return 0, err
			}
			return coerce.ToInt(data)
		default:
			return coerce.ToInt(t)
		}
	}
	return 0, nil
}
func (r *retryOnErrConfig) Interval(scope data.Scope) (int, error) {
	if r.interval != nil {
		switch t := r.interval.(type) {
		case expression.Expr:
			data, err := t.Eval(scope)
			if err != nil {
				return 0, err
			}
			return coerce.ToInt(data)
		default:
			return coerce.ToInt(t)
		}
	}
	return 0, nil
}
type Task struct {
	definition *Definition
	id         string
	typeID     string
	name       string
	activityCfg *ActivityConfig
	isScope     bool
	settingsMapper mapper.Mapper
	loopCfg          *LoopConfig
	retryOnErrConfig RetryOnError
	toLinks   []*Link
	fromLinks []*Link
}
func (task *Task) ID() string {
	return task.id
}
func (task *Task) Name() string {
	return task.name
}
func (task *Task) TypeID() string {
	return task.typeID
}
func (task *Task) ActivityConfig() *ActivityConfig {
	return task.activityCfg
}
func (task *Task) SettingsMapper() mapper.Mapper {
	return task.settingsMapper
}
func (task *Task) RetryOnErrConfig() RetryOnError {
	return task.retryOnErrConfig
}
func (task *Task) LoopConfig() *LoopConfig {
	return task.loopCfg
}