text:
package db

import (
	"database/sql"
	"encoding/json"
	"errors"
	"fmt"
	"strconv"
	"strings"
	"time"

	"code.cloudfoundry.org/lager"
	sq "github.com/Masterminds/squirrel"
	"github.com/concourse/concourse/atc/creds"
	"github.com/concourse/concourse/vars"
	"github.com/lib/pq"
	"go.opentelemetry.io/otel/propagation"

	"github.com/concourse/concourse/atc"
	"github.com/concourse/concourse/atc/db/encryption"
	"github.com/concourse/concourse/atc/db/lock"
	"github.com/concourse/concourse/atc/event"
	"github.com/concourse/concourse/atc/util"
	"github.com/concourse/concourse/tracing"
)

const schema = "exec.v2"

var ErrAdoptRerunBuildHasNoInputs = errors.New("inputs not ready for build to rerun")
var ErrSetByNewerBuild = errors.New("pipeline set by a newer build")

type BuildInput struct {
	Name       string
	Version    atc.Version
	ResourceID int

	FirstOccurrence bool
	ResolveError    string

	Context SpanContext
}

func (bi BuildInput) SpanContext() propagation.TextMapCarrier {
	return bi.Context
}

type BuildOutput struct {
	Name    string
	Version atc.Version
}

type BuildStatus string

const (
	BuildStatusPending   BuildStatus = "pending"
	BuildStatusStarted   BuildStatus = "started"
	BuildStatusAborted   BuildStatus = "aborted"
	BuildStatusSucceeded BuildStatus = "succeeded"
	BuildStatusFailed    BuildStatus = "failed"
	BuildStatusErrored   BuildStatus = "errored"
)

func (status BuildStatus) String() string {
	return string(status)
}

var buildsQuery = psql.Select(`
		b.id,
		b.name,
		b.job_id,
		b.resource_id,
		b.resource_type_id,
		b.team_id,
		b.status,
		b.manually_triggered,
		b.created_by,
		b.scheduled,
		b.schema,
		b.private_plan,
		b.public_plan,
		b.create_time,
		b.start_time,
		b.end_time,
		b.reap_time,
		j.name,
		r.name,
		b.pipeline_id,
		p.name,
		p.instance_vars,
		t.name,
		b.nonce,
		b.drained,
		b.aborted,
		b.completed,
		b.inputs_ready,
		b.rerun_of,
		rb.name,
		b.rerun_number,
		b.span_context,
		COALESCE(bc.comment, '')
	`).
	From("builds b").
	JoinClause("LEFT OUTER JOIN jobs j ON b.job_id = j.id").
	JoinClause("LEFT OUTER JOIN resources r ON b.resource_id = r.id").
	JoinClause("LEFT OUTER JOIN pipelines p ON b.pipeline_id = p.id").
	JoinClause("LEFT OUTER JOIN teams t ON b.team_id = t.id").
	JoinClause("LEFT OUTER JOIN builds rb ON rb.id = b.rerun_of").
	JoinClause("LEFT OUTER JOIN build_comments bc ON b.id = bc.build_id")

var minMaxIdQuery = psql.Select("COALESCE(MAX(b.id), 0)", "COALESCE(MIN(b.id), 0)").
	From("builds as b")

var latestCompletedBuildQuery = psql.Select("max(id)").
	From("builds").
	Where(sq.Expr(`status NOT IN ('pending', 'started')`))

//counterfeiter:generate . Build
type Build interface {
	PipelineRef

	ID() int
	Name() string

	RunStateID() string

	TeamID() int
	TeamName() string

	Job() (Job, bool, error)

	// AllAssociatedTeamNames is only meaningful for check build. For a global
	// resource's check build, it may associate to resources across multiple
	// teams.
	AllAssociatedTeamNames() []string

	JobID() int
	JobName() string

	ResourceID() int
	ResourceName() string

	ResourceTypeID() int

	Schema() string
	PrivatePlan() atc.Plan
	PublicPlan() *json.RawMessage
	HasPlan() bool
	Comment() string
	Status() BuildStatus
	CreateTime() time.Time
	StartTime() time.Time
	EndTime() time.Time
	ReapTime() time.Time
	IsManuallyTriggered() bool
	IsScheduled() bool
	IsRunning() bool
	IsCompleted() bool
	InputsReady() bool
	RerunOf() int
	RerunOfName() string
	RerunNumber() int
	CreatedBy() *string

	LagerData() lager.Data
	TracingAttrs() tracing.Attrs

	SyslogTag(event.OriginID) string

	Reload() (bool, error)

	ResourcesChecked() (bool, error)

	AcquireTrackingLock(logger lager.Logger, interval time.Duration) (lock.Lock, bool, error)

	Interceptible() (bool, error)
	Preparation() (BuildPreparation, bool, error)

	Start(atc.Plan) (bool, error)
	Finish(BuildStatus) error

	Variables(lager.Logger, creds.Secrets, creds.VarSourcePool) (vars.Variables, error)

	SetComment(string) error
	SetInterceptible(bool) error

	Events(uint) (EventSource, error)
	SaveEvent(event atc.Event) error

	Artifacts() ([]WorkerArtifact, error)
	Artifact(artifactID int) (WorkerArtifact, error)

	SaveOutput(string, ResourceCache, atc.Source, atc.Version, ResourceConfigMetadataFields, string, string) error
	AdoptInputsAndPipes() ([]BuildInput, bool, error)
	AdoptRerunInputsAndPipes() ([]BuildInput, bool, error)

	Resources() ([]BuildInput, []BuildOutput, error)
	SaveImageResourceVersion(ResourceCache) error

	Delete() (bool, error)
	MarkAsAborted() error
	IsAborted() bool
	AbortNotifier() (Notifier, error)

	IsDrained() bool
	SetDrained(bool) error

	SpanContext() propagation.TextMapCarrier

	SavePipeline(
		pipelineRef atc.PipelineRef,
		teamId int,
		config atc.Config,
		from ConfigVersion,
		initiallyPaused bool,
	) (Pipeline, bool, error)

	ResourceCacheUser() ResourceCacheUser
	ContainerOwner(atc.PlanID) ContainerOwner

	OnCheckBuildStart() error
}

type build struct {
	pipelineRef

	id          int
	name        string
	status      BuildStatus
	scheduled   bool
	inputsReady bool

	teamID   int
	teamName string
	comment  string

	jobID   int
	jobName string

	resourceID   int
	resourceName string

	resourceTypeID int

	isManuallyTriggered bool

	createdBy *string

	rerunOf     int
	rerunOfName string
	rerunNumber int

	schema      string
	privatePlan atc.Plan
	publicPlan  *json.RawMessage

	createTime time.Time
	startTime  time.Time
	endTime    time.Time
	reapTime   time.Time

	drained   bool
	aborted   bool
	completed bool

	spanContext SpanContext

	eventIdSeq util.SequenceGenerator
}

func newEmptyBuild(conn Conn, lockFactory lock.LockFactory) *build {
	return &build{pipelineRef: pipelineRef{conn: conn, lockFactory: lockFactory}}
}

var ErrBuildDisappeared = errors.New("build disappeared from db")
var ErrBuildHasNoPipeline = errors.New("build has no pipeline")
var ErrBuildArtifactNotFound = errors.New("build artifact not found")

type ResourceNotFoundInPipeline struct {
	Resource string
	Pipeline string
}

func (r ResourceNotFoundInPipeline) Error() string {
	return fmt.Sprintf("resource %s not found in pipeline %s", r.Resource, r.Pipeline)
}

// SyslogTag returns a string to be set as a tag on syslog events pertaining to
// the build.
func (b *build) SyslogTag(origin event.OriginID) string {
	segments := []string{b.teamName}

	if b.pipelineID != 0 {
		segments = append(segments, b.pipelineName)
	}

	if b.jobID != 0 {
		segments = append(segments, b.jobName, b.name)
	} else if b.resourceID != 0 {
		segments = append(segments, b.resourceName, strconv.Itoa(b.id))
	} else {
		segments = append(segments, strconv.Itoa(b.id))
	}

	segments = append(segments, origin.String())

	return strings.Join(segments, "/")
}

// LagerData returns attributes which are to be emitted in logs pertaining to
// the build.
func (b *build) LagerData() lager.Data {
	data := lager.Data{
		"build_id": b.id,
		"build":    b.name,
		"team":     b.teamName,
	}

	if b.pipelineID != 0 {
		data["pipeline"] = b.pipelineName
	}

	if b.jobID != 0 {
		data["job"] = b.jobName
	}

	if b.resourceID != 0 {
		data["resource"] = b.resourceName
	}

	return data
}

// TracingAttrs returns attributes which are to be emitted in spans and metrics
// pertaining to the build. Metrics emitters may depend on specific attribute
// names being set.
func (b *build) TracingAttrs() tracing.Attrs {
	data := tracing.Attrs{
		"build_id":  strconv.Itoa(b.id),
		"build":     b.name,
		"team_name": b.teamName,
	}

	if b.pipelineID != 0 {
		data["pipeline"] = b.pipelineName
	}

	if b.jobID != 0 {
		data["job"] = b.jobName
	}

	if b.resourceID != 0 {
		data["resource"] = b.resourceName
	}

	return data
}

func (b *build) ID() int                          { return b.id }
func (b *build) Name() string                     { return b.name }
func (b *build) RunStateID() string               { return fmt.Sprintf("build:%v", b.id) }
func (b *build) JobID() int                       { return b.jobID }
func (b *build) JobName() string                  { return b.jobName }
func (b *build) ResourceID() int                  { return b.resourceID }
func (b *build) ResourceName() string             { return b.resourceName }
func (b *build) ResourceTypeID() int              { return b.resourceTypeID }
func (b *build) TeamID() int                      { return b.teamID }
func (b *build) TeamName() string                 { return b.teamName }
func (b *build) AllAssociatedTeamNames() []string { return []string{b.teamName} }
func (b *build) IsManuallyTriggered() bool        { return b.isManuallyTriggered }
func (b *build) Schema() string                   { return b.schema }
func (b *build) PrivatePlan() atc.Plan            { return b.privatePlan }
func (b *build) PublicPlan() *json.RawMessage     { return b.publicPlan }
func (b *build) HasPlan() bool                    { return string(*b.publicPlan) != "{}" }
func (b *build) CreateTime() time.Time            { return b.createTime }
func (b *build) StartTime() time.Time             { return b.startTime }
func (b *build) EndTime() time.Time               { return b.endTime }
func (b *build) ReapTime() time.Time              { return b.reapTime }
func (b *build) Comment() string                  { return b.comment }
func (b *build) Status() BuildStatus              { return b.status }
func (b *build) IsScheduled() bool                { return b.scheduled }
func (b *build) IsDrained() bool                  { return b.drained }
func (b *build) IsRunning() bool                  { return !b.completed }
func (b *build) IsAborted() bool                  { return b.aborted }
func (b *build) IsCompleted() bool                { return b.completed }
func (b *build) InputsReady() bool                { return b.inputsReady }
func (b *build) RerunOf() int                     { return b.rerunOf }
func (b *build) RerunOfName() string              { return b.rerunOfName }
func (b *build) RerunNumber() int                 { return b.rerunNumber }
func (b *build) CreatedBy() *string               { return b.createdBy }

func (b *build) isNewerThanLastCheckOf(input Resource) bool {
	return b.createTime.After(input.LastCheckEndTime())
}

func (b *build) Reload() (bool, error) {
	tx, err := b.conn.Begin()
	if err != nil {
		return false, err
	}
	defer tx.Rollback()

	row := buildsQuery.Where(sq.Eq{"b.id": b.id}).
		RunWith(tx).
		QueryRow()

	err = scanBuild(b, row, b.conn.EncryptionStrategy())
	if err != nil {
		if err == sql.ErrNoRows {
			return false, nil
		}
		return false, err
	}

	err = b.refreshEventIdSeq(tx)
	if err != nil {
		return false, err
	}

	err = tx.Commit()
	if err != nil {
		return false, err
	}

	return true, nil
}

func (b *build) Interceptible() (bool, error) {
	var interceptible bool

	err := psql.Select("interceptible").
		From("builds").
		Where(sq.Eq{
			"id": b.id,
		}).
		RunWith(b.conn).
		QueryRow().Scan(&interceptible)

	if err != nil {
		return true, err
	}

	return interceptible, nil
}

func (b *build) Job() (Job, bool, error) {
	row := jobsQuery.Where(sq.Eq{
		"j.id":     b.JobID(),
		"j.active": true,
	}).RunWith(b.conn).QueryRow()

	job := newEmptyJob(b.conn, b.lockFactory)
	err := scanJob(job, row)

	if err != nil {
		if err == sql.ErrNoRows {
			return nil, false, nil
		}

		return nil, false, err
	}

	return job, true, nil
}

func (b *build) SetComment(comment string) error {
	_, err := psql.Insert("build_comments").
		Columns("build_id", "comment").
		Values(b.id, comment).
		Suffix("ON CONFLICT (build_id) DO UPDATE SET comment = EXCLUDED.comment").
		RunWith(b.conn).
		Exec()

	if err != nil {
		return err
	}

	return nil
}

func (b *build) SetInterceptible(i bool) error {
	rows, err := psql.Update("builds").
		Set("interceptible", i).
		Where(sq.Eq{
			"id": b.id,
		}).
		RunWith(b.conn).
		Exec()
	if err != nil {
		return err
	}

	affected, err := rows.RowsAffected()
	if err != nil {
		return err
	}

	if affected == 0 {
		return ErrBuildDisappeared
	}

	return nil
}

func (b *build) ResourcesChecked() (bool, error) {
	var notChecked bool
	err := b.conn.QueryRow(`
		SELECT EXISTS (
			SELECT 1
			FROM resources r
			JOIN job_inputs ji ON ji.resource_id = r.id
			JOIN resource_config_scopes rs ON r.resource_config_scope_id = rs.id
			WHERE ji.job_id = $1
			AND rs.last_check_end_time < $2
			AND NOT EXISTS (
				SELECT
				FROM resource_pins
				WHERE resource_id = r.id
			)
		)`, b.jobID, b.createTime).Scan(&notChecked)
	if err != nil {
		return false, err
	}

	return !notChecked, nil
}

func (b *build) Start(plan atc.Plan) (bool, error) {
	tx, err := b.conn.Begin()
	if err != nil {
		return false, err
	}

	defer Rollback(tx)

	started, err := b.start(tx, plan)
	if err != nil {
		return false, err
	}

	err = tx.Commit()
	if err != nil {
		return false, err
	}

	if !started {
		return false, nil
	}

	err = b.conn.Bus().Notify(buildEventsChannel(b.id))
	if err != nil {
		return false, err
	}

	err = b.conn.Bus().Notify(atc.ComponentBuildTracker)
	if err != nil {
		return false, err
	}

	return true, nil
}

func (b *build) start(tx Tx, plan atc.Plan) (bool, error) {
	metadata, err := json.Marshal(plan)
	if err != nil {
		return false, err
	}

	encryptedPlan, nonce, err := b.conn.EncryptionStrategy().Encrypt([]byte(metadata))
	if err != nil {
		return false, err
	}

	var startTime time.Time
	err = psql.Update("builds").
		Set("status", BuildStatusStarted).
		Set("start_time", sq.Expr("now()")).
		Set("schema", schema).
		Set("private_plan", encryptedPlan).
		Set("public_plan", plan.Public()).
		Set("nonce", nonce).
		Where(sq.Eq{
			"id":      b.id,
			"status":  "pending",
			"aborted": false,
		}).
		Suffix("RETURNING start_time").
		RunWith(tx).
		QueryRow().
		Scan(&startTime)
	if err != nil {
		if err == sql.ErrNoRows {
			return false, nil
		}
		return false, err
	}

	err = b.saveEvent(tx, event.Status{
		Status: atc.StatusStarted,
		Time:   startTime.Unix(),
	})
	if err != nil {
		return false, err
	}

	return true, nil
}

func (b *build) Finish(status BuildStatus) error {
	tx, err := b.conn.Begin()
	if err != nil {
		return err
	}

	defer Rollback(tx)

	var endTime time.Time

	err = psql.Update("builds").
		Set("status", status).
		Set("end_time", sq.Expr("now()")).
		Set("completed", true).
		Set("private_plan", nil).
		Set("nonce", nil).
		Where(sq.Eq{"id": b.id}).
		Suffix("RETURNING end_time").
		RunWith(tx).
		QueryRow().
		Scan(&endTime)
	if err != nil {
		return err
	}

	err = b.saveEvent(tx, event.Status{
		Status: atc.BuildStatus(status),
		Time:   endTime.Unix(),
	})
	if err != nil {
		return err
	}

	if b.jobID != 0 && status == BuildStatusSucceeded {
		_, err = psql.Delete("build_image_resource_caches").
			Where(sq.And{
				sq.Eq{
					"job_id": b.jobID,
				},
				sq.Lt{
					"build_id": b.id,
				},
			}).
			RunWith(tx).
			Exec()
		if err != nil {
			return err
		}

		rows, err := psql.Select("o.resource_id", "o.version_md5").
			From("build_resource_config_version_outputs o").
			Where(sq.Eq{
				"o.build_id": b.id,
			}).
			RunWith(tx).
			Query()
		if err != nil {
			return err
		}

		defer Close(rows)

		uniqueVersions := map[AlgorithmVersion]bool{}
		outputVersions := map[string][]string{}
		for rows.Next() {
			var resourceID int
			var version string

			err = rows.Scan(&resourceID, &version)
			if err != nil {
				return err
			}

			resourceVersion := AlgorithmVersion{
				ResourceID: resourceID,
				Version:    ResourceVersion(version),
			}

			if !uniqueVersions[resourceVersion] {
				resID := strconv.Itoa(resourceID)
				outputVersions[resID] = append(outputVersions[resID], version)

				uniqueVersions[resourceVersion] = true
			}
		}

		rows, err = psql.Select("i.resource_id", "i.version_md5").
			From("build_resource_config_version_inputs i").
			Where(sq.Eq{
				"i.build_id": b.id,
			}).
			RunWith(tx).
			Query()
		if err != nil {
			return err
		}

		defer Close(rows)

		for rows.Next() {
			var resourceID int
			var version string

			err = rows.Scan(&resourceID, &version)
			if err != nil {
				return err
			}

			resourceVersion := AlgorithmVersion{
				ResourceID: resourceID,
				Version:    ResourceVersion(version),
			}

			if !uniqueVersions[resourceVersion] {
				resID := strconv.Itoa(resourceID)
				outputVersions[resID] = append(outputVersions[resID], version)

				uniqueVersions[resourceVersion] = true
			}
		}

		outputsJSON, err := json.Marshal(outputVersions)
		if err != nil {
			return err
		}

		var rerunOf sql.NullInt64
		if b.rerunOf != 0 {
			rerunOf = sql.NullInt64{Int64: int64(b.rerunOf), Valid: true}
		}

		_, err = psql.Insert("successful_build_outputs").
			Columns("build_id", "job_id", "rerun_of", "outputs").
			Values(b.id, b.jobID, rerunOf, outputsJSON).
			RunWith(tx).
			Exec()
		if err != nil {
			return err
		}

		// recursively archive any child pipelines. This is likely the most common case for
		// automatic archiving so it's worth it to make the feedback more instantenous rather
		// than relying on GC
		pipelineRows, err := pipelinesQuery.
			Prefix(`
WITH RECURSIVE pipelines_to_archive AS (
	SELECT id from pipelines where archived = false AND parent_job_id = $1 AND parent_build_id < $2
	UNION
	SELECT p.id from pipelines p join jobs j on p.parent_job_id = j.id join pipelines_to_archive on j.pipeline_id = pipelines_to_archive.id
)`,
				b.jobID, b.id,
			).
			Where("EXISTS(SELECT 1 FROM pipelines_to_archive pa WHERE pa.id = p.id)").
			RunWith(tx).
			Query()

		if err != nil {
			return err
		}
		defer pipelineRows.Close()

		err = archivePipelines(tx, b.conn, b.lockFactory, pipelineRows)
		if err != nil {
			return err
		}
	}

	if b.jobID != 0 {
		err = requestScheduleOnDownstreamJobs(tx, b.jobID)
		if err != nil {
			return err
		}

		err = updateTransitionBuildForJob(tx, b.jobID, b.id, status, b.rerunOf)
		if err != nil {
			return err
		}

		latestNonRerunID, err := latestCompletedNonRerunBuild(tx, b.jobID)
		if err != nil {
			return err
		}

		err = updateLatestCompletedBuildForJob(tx, b.jobID, latestNonRerunID)
		if err != nil {
			return err
		}

		err = updateNextBuildForJob(tx, b.jobID, latestNonRerunID)
		if err != nil {
			return err
		}
	}

	err = tx.Commit()
	if err != nil {
		return err
	}

	err = b.conn.Bus().Notify(buildEventsChannel(b.id))
	if err != nil {
		return err
	}

	return nil
}

// Variables creates variables for this build. If the build is a one-off build, it
// just uses the global secrets manager. If it belongs to a pipeline, it combines
// the global secrets manager with the pipeline's var_sources.
func (b *build) Variables(logger lager.Logger, globalSecrets creds.Secrets, varSourcePool creds.VarSourcePool) (vars.Variables, error) {
	// "fly execute" generated build will have no pipeline.
	if b.pipelineID == 0 {
		return creds.NewVariables(globalSecrets, b.teamName, b.pipelineName, false), nil
	}
	pipeline, found, err := b.Pipeline()
	if err != nil {
		return nil, fmt.Errorf("failed to find pipeline: %w", err)
	}
	if !found {
		return nil, errors.New("pipeline not found")
	}

	return pipeline.Variables(logger, globalSecrets, varSourcePool)
}

func (b *build) SetDrained(drained bool) error {
	_, err := psql.Update("builds").
		Set("drained", drained).
		Where(sq.Eq{"id": b.id}).
		RunWith(b.conn).
		Exec()

	if err == nil {
		b.drained = drained
	}
	return err
}

func (b *build) Delete() (bool, error) {
	rows, err := psql.Delete("builds").
		Where(sq.Eq{
			"id": b.id,
		}).
		RunWith(b.conn).
		Exec()
	if err != nil {
		return false, err
	}

	affected, err := rows.RowsAffected()
	if err != nil {
		return false, err
	}

	if affected == 0 {
		return false, ErrBuildDisappeared
	}

	return true, nil
}

// MarkAsAborted will send the abort notification to all build abort
// channel listeners. It will set the status to aborted that will make
// AbortNotifier send notification in case if tracking ATC misses the first
// notification on abort channel.
// Setting status as aborted will also make Start() return false in case where
// build was aborted before it was started.
func (b *build) MarkAsAborted() error {
	tx, err := b.conn.Begin()
	if err != nil {
		return err
	}

	defer Rollback(tx)

	_, err = psql.Update("builds").
		Set("aborted", true).
		Where(sq.Eq{"id": b.id}).
		RunWith(tx).
		Exec()
	if err != nil {
		return err
	}

	if b.status == BuildStatusPending {
		err = requestSchedule(tx, b.jobID)
		if err != nil {
			return err
		}
	}

	err = tx.Commit()
	if err != nil {
		return err
	}

	return b.conn.Bus().Notify(buildAbortChannel(b.id))
}

// AbortNotifier returns a Notifier that can be watched for when the build
// is marked as aborted. Once the build is marked as aborted it will send a
// notification to finish the build to ATC that is tracking this build.
func (b *build) AbortNotifier() (Notifier, error) {
	return newConditionNotifier(b.conn.Bus(), buildAbortChannel(b.id), func() (bool, error) {
		var aborted bool
		err := psql.Select("aborted = true").
			From("builds").
			Where(sq.Eq{"id": b.id}).
			RunWith(b.conn).
			QueryRow().
			Scan(&aborted)

		return aborted, err
	})
}

func (b *build) SaveImageResourceVersion(rc ResourceCache) error {
	var jobID sql.NullInt64
	if b.jobID != 0 {
		jobID = newNullInt64(b.jobID)
	}

	_, err := psql.Insert("build_image_resource_caches").
		Columns("resource_cache_id", "build_id", "job_id").
		Values(rc.ID(), b.id, jobID).
		RunWith(b.conn).
		Exec()
	if err != nil {
		if pqErr, ok := err.(*pq.Error); ok && pqErr.Code.Name() == pqUniqueViolationErrCode {
			return nil
		}

		return err
	}

	return nil
}

func (b *build) AcquireTrackingLock(logger lager.Logger, interval time.Duration) (lock.Lock, bool, error) {
	lock, acquired, err := b.lockFactory.Acquire(
		logger.Session("lock", lager.Data{
			"build_id": b.id,
		}),
		lock.NewBuildTrackingLockID(b.id),
	)
	if err != nil {
		return nil, false, err
	}

	if !acquired {
		return nil, false, nil
	}

	return lock, true, nil
}

func (b *build) refreshEventIdSeq(runner sq.Runner) error {
	var currentEventId sql.NullInt64
	err := psql.Select("max(event_id)").
		From(b.eventsTable()).
		Where(sq.Eq{"build_id": b.id}).
		RunWith(runner).
		QueryRow().
		Scan(&currentEventId)
	if err != nil {
		return err
	}

	seqIdInit := 0
	if currentEventId.Valid {
		seqIdInit = int(currentEventId.Int64) + 1
	}
	b.eventIdSeq = util.NewSequenceGenerator(seqIdInit)
	return nil
}

func (b *build) Preparation() (BuildPreparation, bool, error) {
	if b.jobID == 0 || b.status != BuildStatusPending {
		return BuildPreparation{
			BuildID:             b.id,
			PausedPipeline:      BuildPreparationStatusNotBlocking,
			PausedJob:           BuildPreparationStatusNotBlocking,
			MaxRunningBuilds:    BuildPreparationStatusNotBlocking,
			Inputs:              map[string]BuildPreparationStatus{},
			InputsSatisfied:     BuildPreparationStatusNotBlocking,
			MissingInputReasons: MissingInputReasons{},
		}, true, nil
	}

	var (
		pausedPipeline     bool
		pausedJob          bool
		maxInFlightReached bool
		pipelineID         int
		jobName            string
	)
	err := psql.Select("p.paused, j.paused, j.max_in_flight_reached, j.pipeline_id, j.name").
		From("builds b").
		Join("jobs j ON b.job_id = j.id").
		Join("pipelines p ON j.pipeline_id = p.id").
		Where(sq.Eq{"b.id": b.id}).
		RunWith(b.conn).
		QueryRow().
		Scan(&pausedPipeline, &pausedJob, &maxInFlightReached, &pipelineID, &jobName)
	if err != nil {
		if err == sql.ErrNoRows {
			return BuildPreparation{}, false, nil
		}
		return BuildPreparation{}, false, err
	}

	pausedPipelineStatus := BuildPreparationStatusNotBlocking
	if pausedPipeline {
		pausedPipelineStatus = BuildPreparationStatusBlocking
	}

	pausedJobStatus := BuildPreparationStatusNotBlocking
	if pausedJob {
		pausedJobStatus = BuildPreparationStatusBlocking
	}

	maxInFlightReachedStatus := BuildPreparationStatusNotBlocking
	if maxInFlightReached {
		maxInFlightReachedStatus = BuildPreparationStatusBlocking
	}

	tf := NewTeamFactory(b.conn, b.lockFactory)
	t, found, err := tf.FindTeam(b.teamName)
	if err != nil {
		return BuildPreparation{}, false, err
	}

	if !found {
		return BuildPreparation{}, false, nil
	}

	pipeline, found, err := t.Pipeline(b.PipelineRef())
	if err != nil {
		return BuildPreparation{}, false, err
	}

	if !found {
		return BuildPreparation{}, false, nil
	}

	job, found, err := pipeline.Job(jobName)
	if err != nil {
		return BuildPreparation{}, false, err
	}

	if !found {
		return BuildPreparation{}, false, nil
	}

	config, err := job.Config()
	if err != nil {
		return BuildPreparation{}, false, err
	}

	configInputs := config.Inputs()

	buildInputs, err := job.GetNextBuildInputs()
	if err != nil {
		return BuildPreparation{}, false, err
	}

	resolved := true
	for _, input := range buildInputs {
		if input.ResolveError != "" {
			resolved = false
			break
		}
	}

	inputsSatisfiedStatus := BuildPreparationStatusNotBlocking
	inputs := map[string]BuildPreparationStatus{}
	missingInputReasons := MissingInputReasons{}

	for _, configInput := range configInputs {
		buildInput := BuildInput{}
		found := false
		for _, b := range buildInputs {
			if b.Name == configInput.Name {
				found = true
				buildInput = b
				break
			}
		}

		if found {
			if buildInput.ResolveError == "" {
				if b.IsManuallyTriggered() {
					resource, _, err := pipeline.ResourceByID(buildInput.ResourceID)
					if err != nil {
						return BuildPreparation{}, false, err
					}

					// input is blocking if its last check time is before build create time
					if b.isNewerThanLastCheckOf(resource) {
						inputs[buildInput.Name] = BuildPreparationStatusBlocking
						missingInputReasons.RegisterNoResourceCheckFinished(buildInput.Name)
						inputsSatisfiedStatus = BuildPreparationStatusBlocking
					} else {
						inputs[buildInput.Name] = BuildPreparationStatusNotBlocking
					}
				} else {
					inputs[buildInput.Name] = BuildPreparationStatusNotBlocking
				}
			} else {
				inputs[configInput.Name] = BuildPreparationStatusBlocking
				missingInputReasons.RegisterResolveError(configInput.Name, buildInput.ResolveError)
				inputsSatisfiedStatus = BuildPreparationStatusBlocking
			}
		} else {
			if resolved {
				inputs[configInput.Name] = BuildPreparationStatusBlocking
				missingInputReasons.RegisterMissingInput(configInput.Name)
				inputsSatisfiedStatus = BuildPreparationStatusBlocking
			}
		}
	}

	buildPreparation := BuildPreparation{
		BuildID:             b.id,
		PausedPipeline:      pausedPipelineStatus,
		PausedJob:           pausedJobStatus,
		MaxRunningBuilds:    maxInFlightReachedStatus,
		Inputs:              inputs,
		InputsSatisfied:     inputsSatisfiedStatus,
		MissingInputReasons: missingInputReasons,
	}

	return buildPreparation, true, nil
}

func (b *build) Events(from uint) (EventSource, error) {
	notifier, err := newConditionNotifier(b.conn.Bus(), buildEventsChannel(b.id), func() (bool, error) {
		return true, nil
	})
	if err != nil {
		return nil, err
	}

	return newBuildEventSource(
		b.id,
		b.eventsTable(),
		b.conn,
		notifier,
		from,
		func(tx Tx, buildID int) (bool, error) {
			completed := false
			err = psql.Select("completed").
				From("builds").
				Where(sq.Eq{"id": buildID}).
				RunWith(tx).
				QueryRow().
				Scan(&completed)
			if err != nil {
				return false, err
			}
			return completed, nil
		},
	), nil
}

func (b *build) SaveEvent(event atc.Event) error {
	tx, err := b.conn.Begin()
	if err != nil {
		return err
	}

	defer Rollback(tx)

	err = b.saveEvent(tx, event)
	if err != nil {
		return err
	}

	err = tx.Commit()
	if err != nil {
		return err
	}

	return b.conn.Bus().Notify(buildEventsChannel(b.id))
}

func (b *build) Artifact(artifactID int) (WorkerArtifact, error) {

	artifact := artifact{
		conn: b.conn,
	}

	err := psql.Select("id", "name", "created_at").
		From("worker_artifacts").
		Where(sq.Eq{
			"id": artifactID,
		}).
		RunWith(b.conn).
		Scan(&artifact.id, &artifact.name, &artifact.createdAt)

	return &artifact, err
}

func (b *build) Artifacts() ([]WorkerArtifact, error) {
	artifacts := []WorkerArtifact{}

	rows, err := psql.Select("id", "name", "created_at").
		From("worker_artifacts").
		Where(sq.Eq{
			"build_id": b.id,
		}).
		RunWith(b.conn).
		Query()
	if err != nil {
		return nil, err
	}

	defer Close(rows)

	for rows.Next() {
		wa := artifact{
			conn:    b.conn,
			buildID: b.id,
		}

		err = rows.Scan(&wa.id, &wa.name, &wa.createdAt)
		if err != nil {
			return nil, err
		}

		artifacts = append(artifacts, &wa)
	}

	return artifacts, nil
}

func (b *build) SaveOutput(
	resourceType string,
	imageResourceCache ResourceCache,
	source atc.Source,
	version atc.Version,
	metadata ResourceConfigMetadataFields,
	outputName string,
	resourceName string,
) error {
	// We should never save outputs for builds without a Pipeline ID because
	// One-off Builds will never have Put steps. This shouldn't happen, but
	// its best to return an error just in case
	if b.pipelineID == 0 {
		return ErrBuildHasNoPipeline
	}

	pipeline, found, err := b.Pipeline()
	if err != nil {
		return err
	}

	if !found {
		return ErrBuildHasNoPipeline
	}

	theResource, found, err := pipeline.Resource(resourceName)
	if err != nil {
		return err
	}

	if !found {
		return ResourceNotFoundInPipeline{resourceName, b.pipelineName}
	}

	tx, err := b.conn.Begin()
	if err != nil {
		return err
	}

	defer Rollback(tx)

	rc := &resourceConfig{
		lockFactory: b.lockFactory,
		conn:        b.conn,
	}

	err = findOrCreateResourceConfig(tx, rc, resourceType, source, imageResourceCache, false)
	if err != nil {
		return err
	}

	resourceConfigScope, err := findOrCreateResourceConfigScope(tx, b.conn, b.lockFactory, rc, NewIntPtr(theResource.ID()))
	if err != nil {
		return err
	}

	newVersion, err := saveResourceVersion(tx, resourceConfigScope.ID(), version, metadata, nil)
	if err != nil {
		return err
	}

	versionBytes, err := json.Marshal(version)
	if err != nil {
		return err
	}

	versionJSON := string(versionBytes)

	if newVersion {
		err = incrementCheckOrder(tx, resourceConfigScope.ID(), versionJSON)
		if err != nil {
			return err
		}
	}

	err = setResourceConfigScopeForResource(tx, resourceConfigScope, sq.Eq{
		"id": theResource.ID(),
	})
	if err != nil {
		return err
	}

	_, err = psql.Insert("build_resource_config_version_outputs").
		Columns("resource_id", "build_id", "version_md5", "name").
		Values(theResource.ID(), strconv.Itoa(b.id), sq.Expr("md5(?)", versionJSON), outputName).
		Suffix("ON CONFLICT DO NOTHING").
		RunWith(tx).
		Exec()
	if err != nil {
		return err
	}

	if newVersion {
		err = requestScheduleForJobsUsingResourceConfigScope(tx, resourceConfigScope.ID())
		if err != nil {
			return err
		}
	}

	err = tx.Commit()
	if err != nil {
		return err
	}

	return nil
}

func (b *build) AdoptInputsAndPipes() ([]BuildInput, bool, error) {
	tx, err := b.conn.Begin()
	if err != nil {
		return nil, false, err
	}

	defer tx.Rollback()

	var determined bool
	err = psql.Select("inputs_determined").
		From("jobs").
		Where(sq.Eq{
			"id": b.jobID,
		}).
		RunWith(tx).
		QueryRow().
		Scan(&determined)
	if err != nil {
		return nil, false, err
	}

	if !determined {
		return nil, false, nil
	}

	_, err = psql.Delete("build_resource_config_version_inputs").
		Where(sq.Eq{"build_id": b.id}).
		RunWith(tx).
		Exec()
	if err != nil {
		return nil, false, err
	}

	rows, err := psql.Insert("build_resource_config_version_inputs").
		Columns("resource_id", "version_md5", "name", "first_occurrence", "build_id").
		Select(psql.Select("i.resource_id", "i.version_md5", "i.input_name", "i.first_occurrence").
			Column("?", b.id).
			From("next_build_inputs i").
			Where(sq.Eq{"i.job_id": b.jobID})).
		Suffix("ON CONFLICT (build_id, resource_id, version_md5, name) DO UPDATE SET first_occurrence = EXCLUDED.first_occurrence").
		Suffix("RETURNING name, resource_id, version_md5, first_occurrence").
		RunWith(tx).
		Query()
	if err != nil {
		return nil, false, err
	}

	inputs := InputMapping{}
	for rows.Next() {
		var (
			inputName       string
			firstOccurrence bool
			versionMD5      string
			resourceID      int
		)

		err := rows.Scan(&inputName, &resourceID, &versionMD5, &firstOccurrence)
		if err != nil {
			return nil, false, err
		}

		inputs[inputName] = InputResult{
			Input: &AlgorithmInput{
				AlgorithmVersion: AlgorithmVersion{
					ResourceID: resourceID,
					Version:    ResourceVersion(versionMD5),
				},
				FirstOccurrence: firstOccurrence,
			},
		}
	}

	buildInputs := []BuildInput{}

	for inputName, input := range inputs {
		var versionBlob string

		err = psql.Select("v.version").
			From("resource_config_versions v").
			Join("resources r ON r.resource_config_scope_id = v.resource_config_scope_id").
			Where(sq.Eq{
				"v.version_md5": input.Input.Version,
				"r.id":          input.Input.ResourceID,
			}).
			RunWith(tx).
			QueryRow().
			Scan(&versionBlob)
		if err != nil {
			if err == sql.ErrNoRows {
				tx.Rollback()

				_, err = psql.Update("next_build_inputs").
					Set("resolve_error", fmt.Sprintf("chosen version of input %s not available", inputName)).
					Where(sq.Eq{
						"job_id":     b.jobID,
						"input_name": inputName,
					}).
					RunWith(b.conn).
					Exec()
			}

			return nil, false, err
		}

		var version atc.Version
		err = json.Unmarshal([]byte(versionBlob), &version)
		if err != nil {
			return nil, false, err
		}

		buildInputs = append(buildInputs, BuildInput{
			Name:            inputName,
			ResourceID:      input.Input.ResourceID,
			Version:         version,
			FirstOccurrence: input.Input.FirstOccurrence,
		})
	}

	_, err = psql.Delete("build_pipes").
		Where(sq.Eq{"to_build_id": b.id}).
		RunWith(tx).
		Exec()
	if err != nil {
		return nil, false, err
	}

	_, err = psql.Insert("build_pipes").
		Columns("from_build_id", "to_build_id").
		Select(psql.Select("nbp.from_build_id").
			Column("?", b.id).
			From("next_build_pipes nbp").
			Where(sq.Eq{"nbp.to_job_id": b.jobID})).
		Suffix("ON CONFLICT DO NOTHING").
		RunWith(tx).
		Exec()
	if err != nil {
		return nil, false, err
	}

	_, err = psql.Update("builds").
		Set("inputs_ready", true).
		Where(sq.Eq{
			"id": b.id,
		}).
		RunWith(tx).
		Exec()
	if err != nil {
		return nil, false, err
	}

	err = tx.Commit()
	if err != nil {
		return nil, false, err
	}

	return buildInputs, true, nil
}

func (b *build) AdoptRerunInputsAndPipes() ([]BuildInput, bool, error) {
	tx, err := b.conn.Begin()
	if err != nil {
		return nil, false, err
	}

	defer tx.Rollback()

	var ready bool
	err = psql.Select("inputs_ready").
		From("builds").
		Where(sq.Eq{
			"id": b.rerunOf,
		}).
		RunWith(tx).
		QueryRow().
		Scan(&ready)
	if err != nil {
		return nil, false, err
	}

	if !ready {
		return nil, false, nil
	}

	_, err = psql.Delete("build_resource_config_version_inputs").
		Where(sq.Eq{"build_id": b.id}).
		RunWith(tx).
		Exec()
	if err != nil {
		return nil, false, err
	}

	rows, err := psql.Insert("build_resource_config_version_inputs").
		Columns("resource_id", "version_md5", "name", "first_occurrence", "build_id").
		Select(psql.Select("i.resource_id", "i.version_md5", "i.name", "false").
			Column("?", b.id).
			From("build_resource_config_version_inputs i").
			Where(sq.Eq{"i.build_id": b.rerunOf})).
		Suffix("ON CONFLICT (build_id, resource_id, version_md5, name) DO NOTHING").
		Suffix("RETURNING name, resource_id, version_md5, first_occurrence").
		RunWith(tx).
		Query()
	if err != nil {
		return nil, false, err
	}

	inputs := InputMapping{}
	for rows.Next() {
		var (
			inputName       string
			firstOccurrence bool
			versionMD5      string
			resourceID      int
		)

		err := rows.Scan(&inputName, &resourceID, &versionMD5, &firstOccurrence)
		if err != nil {
			return nil, false, err
		}

		inputs[inputName] = InputResult{
			Input: &AlgorithmInput{
				AlgorithmVersion: AlgorithmVersion{
					ResourceID: resourceID,
					Version:    ResourceVersion(versionMD5),
				},
				FirstOccurrence: firstOccurrence,
			},
		}
	}

	buildInputs := []BuildInput{}
	for inputName, input := range inputs {
		var versionBlob string

		err = psql.Select("v.version").
			From("resource_config_versions v").
			Join("resources r ON r.resource_config_scope_id = v.resource_config_scope_id").
			Where(sq.Eq{
				"v.version_md5": input.Input.Version,
				"r.id":          input.Input.ResourceID,
			}).
			RunWith(tx).
			QueryRow().
			Scan(&versionBlob)
		if err != nil {
			if err == sql.ErrNoRows {
				tx.Rollback()

				_, err = psql.Update("next_build_inputs").
					Set("resolve_error", fmt.Sprintf("chosen version of input %s not available", inputName)).
					Where(sq.Eq{
						"job_id":     b.jobID,
						"input_name": inputName,
					}).
					RunWith(b.conn).
					Exec()
				if err != nil {
					return nil, false, err
				}

				err = b.MarkAsAborted()
				if err != nil {
					return nil, false, err
				}
			}

			return nil, false, err
		}

		var version atc.Version
		err = json.Unmarshal([]byte(versionBlob), &version)
		if err != nil {
			return nil, false, err
		}

		buildInputs = append(buildInputs, BuildInput{
			Name:            inputName,
			ResourceID:      input.Input.ResourceID,
			Version:         version,
			FirstOccurrence: input.Input.FirstOccurrence,
		})
	}

	_, err = psql.Delete("build_pipes").
		Where(sq.Eq{"to_build_id": b.id}).
		RunWith(tx).
		Exec()
	if err != nil {
		return nil, false, err
	}

	_, err = psql.Insert("build_pipes").
		Columns("from_build_id", "to_build_id").
		Select(psql.Select("bp.from_build_id").
			Column("?", b.id).
			From("build_pipes bp").
			Where(sq.Eq{"bp.to_build_id": b.rerunOf})).
		Suffix("ON CONFLICT DO NOTHING").
		RunWith(tx).
		Exec()
	if err != nil {
		return nil, false, err
	}

	_, err = psql.Update("builds").
		Set("inputs_ready", true).
		Where(sq.Eq{
			"id": b.id,
		}).
		RunWith(tx).
		Exec()
	if err != nil {
		return nil, false, err
	}

	err = tx.Commit()
	if err != nil {
		return nil, false, err
	}

	return buildInputs, true, nil
}

func (b *build) Resources() ([]BuildInput, []BuildOutput, error) {
	inputs := []BuildInput{}
	outputs := []BuildOutput{}

	tx, err := b.conn.Begin()
	if err != nil {
		return nil, nil, err
	}

	defer Rollback(tx)

	rows, err := psql.Select("inputs.name", "resources.id", "versions.version", `COALESCE(inputs.first_occurrence, NOT EXISTS (
			SELECT 1
			FROM build_resource_config_version_inputs i, builds b
			WHERE versions.version_md5 = i.version_md5
			AND resources.resource_config_scope_id = versions.resource_config_scope_id
			AND resources.id = i.resource_id
			AND b.job_id = builds.job_id
			AND i.build_id = b.id
			AND i.build_id < builds.id
		))`).
		From("resource_config_versions versions, build_resource_config_version_inputs inputs, builds, resources").
		Where(sq.Eq{"builds.id": b.id}).
		Where(sq.Expr("inputs.build_id = builds.id")).
		Where(sq.Expr("inputs.version_md5 = versions.version_md5")).
		Where(sq.Expr("resources.resource_config_scope_id = versions.resource_config_scope_id")).
		Where(sq.Expr("resources.id = inputs.resource_id")).
		Where(sq.Expr(`NOT EXISTS (
			SELECT 1
			FROM build_resource_config_version_outputs outputs
			WHERE outputs.version_md5 = versions.version_md5
			AND versions.resource_config_scope_id = resources.resource_config_scope_id
			AND outputs.resource_id = resources.id
			AND outputs.build_id = inputs.build_id
		)`)).
		RunWith(tx).
		Query()
	if err != nil {
		return nil, nil, err
	}

	defer Close(rows)

	for rows.Next() {
		var (
			inputName   string
			firstOcc    bool
			versionBlob string
			version     atc.Version
			resourceID  int
		)

		err = rows.Scan(&inputName, &resourceID, &versionBlob, &firstOcc)
		if err != nil {
			return nil, nil, err
		}

		err = json.Unmarshal([]byte(versionBlob), &version)
		if err != nil {
			return nil, nil, err
		}

		inputs = append(inputs, BuildInput{
			Name:            inputName,
			Version:         version,
			ResourceID:      resourceID,
			FirstOccurrence: firstOcc,
		})
	}

	rows, err = psql.Select("outputs.name", "versions.version").
		From("resource_config_versions versions, build_resource_config_version_outputs outputs, builds, resources").
		Where(sq.Eq{"builds.id": b.id}).
		Where(sq.Expr("outputs.build_id = builds.id")).
		Where(sq.Expr("outputs.version_md5 = versions.version_md5")).
		Where(sq.Expr("outputs.resource_id = resources.id")).
		Where(sq.Expr("resources.resource_config_scope_id = versions.resource_config_scope_id")).
		RunWith(tx).
		Query()

	if err != nil {
		return nil, nil, err
	}

	defer Close(rows)

	for rows.Next() {
		var (
			outputName  string
			versionBlob string
			version     atc.Version
		)

		err := rows.Scan(&outputName, &versionBlob)
		if err != nil {
			return nil, nil, err
		}

		err = json.Unmarshal([]byte(versionBlob), &version)
		if err != nil {
			return nil, nil, err
		}

		outputs = append(outputs, BuildOutput{
			Name:    outputName,
			Version: version,
		})
	}

	err = tx.Commit()
	if err != nil {
		return nil, nil, err
	}

	return inputs, outputs, nil
}

func (b *build) SpanContext() propagation.TextMapCarrier {
	return b.spanContext
}

func (b *build) SavePipeline(
	pipelineRef atc.PipelineRef,
	teamID int,
	config atc.Config,
	from ConfigVersion,
	initiallyPaused bool,
) (Pipeline, bool, error) {
	tx, err := b.conn.Begin()
	if err != nil {
		return nil, false, err
	}

	defer Rollback(tx)

	jobID := newNullInt64(b.jobID)
	buildID := newNullInt64(b.id)
	pipelineID, isNewPipeline, err := savePipeline(tx, pipelineRef, config, from, initiallyPaused, teamID, jobID, buildID)
	if err != nil {
		return nil, false, err
	}

	pipeline := newPipeline(b.conn, b.lockFactory)
	err = scanPipeline(
		pipeline,
		pipelinesQuery.
			Where(sq.Eq{"p.id": pipelineID}).
			RunWith(tx).
			QueryRow(),
	)
	if err != nil {
		return nil, false, err
	}

	err = tx.Commit()
	if err != nil {
		return nil, false, err
	}

	return pipeline, isNewPipeline, nil
}

func (b *build) ResourceCacheUser() ResourceCacheUser {
	return ForBuild(b.ID())
}

func (b *build) ContainerOwner(planId atc.PlanID) ContainerOwner {
	return NewBuildStepContainerOwner(b.ID(), planId, b.TeamID())
}

// OnCheckBuildStart is a hook point called after a worker is selected. For DB
// build, there is nothing to in at this point.
func (b *build) OnCheckBuildStart() error {
	return nil
}

func newNullInt64(i int) sql.NullInt64 {
	return sql.NullInt64{
		Valid: true,
		Int64: int64(i),
	}
}

func scanBuild(b *build, row scannable, encryptionStrategy encryption.Strategy) error {
	var (
		jobID, resourceID, resourceTypeID, pipelineID, rerunOf, rerunNumber               sql.NullInt64
		schema, privatePlan, jobName, resourceName, pipelineName, publicPlan, rerunOfName sql.NullString
		createTime, startTime, endTime, reapTime                                          pq.NullTime
		nonce, spanContext, createdBy                                                     sql.NullString
		drained, aborted, completed                                                       bool
		status                                                                            string
		pipelineInstanceVars, comment                                                     sql.NullString
	)

	err := row.Scan(
		&b.id,
		&b.name,
		&jobID,
		&resourceID,
		&resourceTypeID,
		&b.teamID,
		&status,
		&b.isManuallyTriggered,
		&createdBy,
		&b.scheduled,
		&schema,
		&privatePlan,
		&publicPlan,
		&createTime,
		&startTime,
		&endTime,
		&reapTime,
		&jobName,
		&resourceName,
		&pipelineID,
		&pipelineName,
		&pipelineInstanceVars,
		&b.teamName,
		&nonce,
		&drained,
		&aborted,
		&completed,
		&b.inputsReady,
		&rerunOf,
		&rerunOfName,
		&rerunNumber,
		&spanContext,
		&comment,
	)
	if err != nil {
		return err
	}

	b.status = BuildStatus(status)
	b.jobID = int(jobID.Int64)
	b.jobName = jobName.String
	b.resourceID = int(resourceID.Int64)
	b.resourceName = resourceName.String
	b.resourceTypeID = int(resourceTypeID.Int64)
	b.pipelineID = int(pipelineID.Int64)
	b.pipelineName = pipelineName.String
	b.schema = schema.String
	b.createTime = createTime.Time
	b.startTime = startTime.Time
	b.endTime = endTime.Time
	b.reapTime = reapTime.Time
	b.drained = drained
	b.aborted = aborted
	b.completed = completed
	b.rerunOf = int(rerunOf.Int64)
	b.rerunOfName = rerunOfName.String
	b.rerunNumber = int(rerunNumber.Int64)
	b.comment = comment.String

	var (
		noncense      *string
		decryptedPlan []byte
	)

	if nonce.Valid {
		noncense = &nonce.String
		decryptedPlan, err = encryptionStrategy.Decrypt(string(privatePlan.String), noncense)
		if err != nil {
			return err
		}
	} else {
		decryptedPlan = []byte(privatePlan.String)
	}

	if len(decryptedPlan) > 0 {
		err = json.Unmarshal(decryptedPlan, &b.privatePlan)
		if err != nil {
			return err
		}
	}

	if publicPlan.Valid {
		err = json.Unmarshal([]byte(publicPlan.String), &b.publicPlan)
		if err != nil {
			return err
		}
	}

	if spanContext.Valid {
		err = json.Unmarshal([]byte(spanContext.String), &b.spanContext)
		if err != nil {
			return err
		}
	}

	if pipelineInstanceVars.Valid {
		err = json.Unmarshal([]byte(pipelineInstanceVars.String), &b.pipelineInstanceVars)
		if err != nil {
			return err
		}
	}

	if createdBy.Valid {
		b.createdBy = &createdBy.String
	}

	return nil
}

func (b *build) saveEvent(tx Tx, event atc.Event) error {
	payload, err := json.Marshal(event)
	if err != nil {
		return err
	}

	if b.eventIdSeq == nil {
		err = b.refreshEventIdSeq(tx)
		if err != nil {
			return err
		}
	}

	_, err = psql.Insert(b.eventsTable()).
		Columns("event_id", "build_id", "type", "version", "payload").
		Values(b.eventIdSeq.Next(), b.id, string(event.EventType()), string(event.Version()), payload).
		RunWith(tx).
		Exec()
	return err
}

func (b *build) isForCheck() bool {
	return b.resourceTypeID != 0 || b.resourceID != 0
}

func (b *build) eventsTable() string {
	if b.isForCheck() {
		return "check_build_events"
	}
	if b.pipelineID != 0 {
		return fmt.Sprintf("pipeline_build_events_%d", b.pipelineID)
	}
	return fmt.Sprintf("team_build_events_%d", b.teamID)
}

func createBuild(tx Tx, build *build, vals map[string]interface{}) error {
	var buildID int

	err := psql.Insert("builds").
		SetMap(vals).
		Suffix("RETURNING id").
		RunWith(tx).
		QueryRow().
		Scan(&buildID)
	if err != nil {
		return err
	}

	err = scanBuild(build, buildsQuery.
		Where(sq.Eq{"b.id": buildID}).
		RunWith(tx).
		QueryRow(),
		build.conn.EncryptionStrategy(),
	)
	if err != nil {
		return err
	}

	return nil
}

type startedBuildArgs struct {
	Name              string
	PipelineID        int
	TeamID            int
	Plan              atc.Plan
	ManuallyTriggered bool
	SpanContext       SpanContext
	ExtraValues       map[string]interface{}
}

func createStartedBuild(tx Tx, build *build, args startedBuildArgs) error {
	spanContext, err := json.Marshal(args.SpanContext)
	if err != nil {
		return err
	}

	plan, err := json.Marshal(args.Plan)
	if err != nil {
		return err
	}

	encryptedPlan, nonce, err := build.conn.EncryptionStrategy().Encrypt(plan)
	if err != nil {
		return err
	}

	buildVals := make(map[string]interface{})
	buildVals["name"] = args.Name
	buildVals["pipeline_id"] = args.PipelineID
	buildVals["team_id"] = args.TeamID
	buildVals["manually_triggered"] = args.ManuallyTriggered
	buildVals["private_plan"] = encryptedPlan
	buildVals["public_plan"] = args.Plan.Public()
	buildVals["nonce"] = nonce
	buildVals["span_context"] = string(spanContext)

	buildVals["status"] = BuildStatusStarted
	buildVals["start_time"] = sq.Expr("now()")
	buildVals["schema"] = schema
	buildVals["needs_v6_migration"] = false

	for name, value := range args.ExtraValues {
		buildVals[name] = value
	}

	err = createBuild(tx, build, buildVals)
	if err != nil {
		return err
	}

	err = build.saveEvent(tx, event.Status{
		Status: atc.StatusStarted,
		Time:   build.StartTime().Unix(),
	})
	if err != nil {
		return err
	}

	return nil
}

func buildStartedChannel() string {
	return atc.ComponentBuildTracker
}

func buildEventsChannel(buildID int) string {
	return fmt.Sprintf("build_events_%d", buildID)
}

func buildAbortChannel(buildID int) string {
	return fmt.Sprintf("build_abort_%d", buildID)
}

func latestCompletedNonRerunBuild(tx Tx, jobID int) (int, error) {
	var latestNonRerunId int
	err := latestCompletedBuildQuery.
		Where(sq.Eq{"job_id": jobID}).
		Where(sq.Eq{"rerun_of": nil}).
		RunWith(tx).
		QueryRow().
		Scan(&latestNonRerunId)
	if err != nil && err == sql.ErrNoRows {
		return 0, nil
	}

	return latestNonRerunId, nil
}

func updateNextBuildForJob(tx Tx, jobID int, latestNonRerunId int) error {
	_, err := tx.Exec(`
		UPDATE jobs AS j
		SET next_build_id = (
			SELECT min(b.id)
			FROM builds b
			INNER JOIN jobs j ON j.id = b.job_id
			WHERE b.job_id = $1
			AND b.status IN ('pending', 'started')
			AND (b.rerun_of IS NULL OR b.rerun_of = $2)
		)
		WHERE j.id = $1
	`, jobID, latestNonRerunId)
	if err != nil {
		return err
	}
	return nil
}

func updateLatestCompletedBuildForJob(tx Tx, jobID int, latestNonRerunId int) error {
	var latestRerunId sql.NullString
	err := latestCompletedBuildQuery.
		Where(sq.Eq{"job_id": jobID}).
		Where(sq.Eq{"rerun_of": latestNonRerunId}).
		RunWith(tx).
		QueryRow().
		Scan(&latestRerunId)
	if err != nil {
		return err
	}

	var id int
	if latestRerunId.Valid {
		id, err = strconv.Atoi(latestRerunId.String)
		if err != nil {
			return err
		}
	} else {
		id = latestNonRerunId
	}

	_, err = tx.Exec(`
		UPDATE jobs AS j
		SET latest_completed_build_id = $1
		WHERE j.id = $2
	`, id, jobID)
	if err != nil {
		return err
	}

	return nil
}

func updateTransitionBuildForJob(tx Tx, jobID int, buildID int, buildStatus BuildStatus, rerunID int) error {
	var shouldUpdateTransition bool

	var latestID int
	var latestStatus BuildStatus
	err := psql.Select("b.id", "b.status").
		From("builds b").
		JoinClause("INNER JOIN jobs j ON j.latest_completed_build_id = b.id").
		Where(sq.Eq{"j.id": jobID}).
		RunWith(tx).
		QueryRow().
		Scan(&latestID, &latestStatus)
	if err != nil {
		if err == sql.ErrNoRows {
			// this is the first completed build; initiate transition
			shouldUpdateTransition = true
		} else {
			return err
		}
	}

	if buildID < latestID {
		// latest completed build is actually after this one, so this build
		// has no influence on the job's overall state
		//
		// this can happen when multiple builds are running at a time and the
		// later-queued ones finish earlier
		return nil
	}

	if latestStatus != buildStatus && (isNotRerunBuild(rerunID) || rerunID == latestID) {
		// status has changed; transitioned!
		shouldUpdateTransition = true
	}

	if shouldUpdateTransition {
		_, err := psql.Update("jobs").
			Set("transition_build_id", buildID).
			Where(sq.Eq{"id": jobID}).
			RunWith(tx).
			Exec()
		if err != nil {
			return err
		}
	}

	return nil
}

func isNotRerunBuild(rerunID int) bool {
	return rerunID == 0
}


text:
package com.baronzhang.android.weather;

/**
 * @author baronzhang (baron[dot]zhanglei[at]gmail[dot]com ==>> baronzhang.com)
 *         16/3/13
 */
public class AppConstants {

    public static final String DB_NAME_CITY = "city.db";
}

redpajama_set_name: RedPajamaGithub


text:
/*jslint browser: true, devel: true, onevar: true, undef: true, regexp: true, bitwise: true, newcap: true*/
/*globals doodle*/
/**
 * @name doodle.LineCap
 * @class
 * @static
 */
Object.defineProperty(doodle, 'LineCap', {
  enumerable: true,
  writable: false,
  configurable: false,
  value: Object.create(null, {
    /**
     * @name BUTT
     * @return {string} [read-only] Default
     * @property
     * @constant
     * @static
     */
    'BUTT': {
      enumerable: true,
      writable: false,
      configurable: false,
      value: 'butt'
    },

    /**
     * @name ROUND
     * @return {string} [read-only]
     * @property
     * @constant
     * @static
     */
    'ROUND': {
      enumerable: true,
      writable: false,
      configurable: false,
      value: 'round'
    },

    /**
     * @name SQUARE
     * @return {string} [read-only]
     * @property
     * @constant
     * @static
     */
    'SQUARE': {
      enumerable: true,
      writable: false,
      configurable: false,
      value: 'square'
    }
  })
});


text:
wysihtml5.commands.strike = {
  exec: function(composer, command) {
    return wysihtml5.commands.formatInline.exec(composer, command, "s");
  },

  state: function(composer, command) {
    return wysihtml5.commands.formatInline.state(composer, command, "s");
  }
};


text:
// ***********************************************************************
// Copyright (c) 2016 Charlie Poole
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
// ***********************************************************************

using NUnit.Framework;
using NSubstitute;

namespace TestCentric.Gui.Presenters.Main
{
    using Model;
    using Views;

    public class MainPresenterTestBase
    {
        protected IMainView View;
        protected ITestModel Model;
        protected MainPresenter Presenter;

        [SetUp]
        public void CreatePresenter()
        {
            View = Substitute.For<IMainView>();
            Model = Substitute.For<ITestModel>();

            Presenter = new MainPresenter(View, Model, null);
        }

        [TearDown]
        public void RemovePresenter()
        {
            if (Presenter != null)
                Presenter.Dispose();

            Presenter = null;
        }
    }
}


text:
package com.yaoa.hibatis.lock;

/**
 *
 *
 * @author kingsy.lin
 * @version 1.0 , 2016年10月30日
 */
public class LockException extends RuntimeException{

	private static final long serialVersionUID = 2363778344355818691L;

	public LockException(String message){
		super(message);
	}
}


text:
class CreateFreeTextTexts < ActiveRecord::Migration
  def change
    create_table :free_text_texts do |t|
      t.string :key
      t.string :locale
      t.text :content

      t.timestamps
    end
  end
end


text:
from __future__ import unicode_literals

from django.db import migrations

class Migration(migrations.Migration):

    dependencies = [
        ('topic', '0005_auto_20170507_1012'),
    ]

    operations = [
        migrations.AlterModelOptions(
            name='topic',
            options={'ordering': ['-is_top', '-created_at'], 'verbose_name': 'topic', 'verbose_name_plural': 'topics'},
        ),
    ]


text:
function Power() {
  this.mode = true;
}

Power.prototype.switch_off = function() {
  this.mode = false;
};

Power.prototype.switch_on = function() {
  this.mode = true;
};


text:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="net.studymongolian.fontmetrics.MainActivity">

    <net.studymongolian.fontmetrics.FontMetricsView
        android:id="@+id/viewWindow"
        android:layout_width="match_parent"
        android:layout_height="150dp"
        android:background="@android:color/white"
        android:padding="20dp"/>

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/viewWindow">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <LinearLayout
                android:id="@+id/contentLayout"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <EditText
                    android:id="@+id/etTextString"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginBottom="20dp"
                    android:layout_weight="0.5"
                    android:hint="My text line"/>

                <Button
                    android:id="@+id/updateButton"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="0.25"
                    android:text="Update text"/>

                <EditText
                    android:id="@+id/etFontSize"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_weight="0.25"
                    android:hint="17"
                    android:inputType="number"/>
            </LinearLayout>

            <CheckBox
                android:id="@+id/cbTop"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/contentLayout"
                android:checked="true"
                android:text="Top"
                android:textAppearance="?android:attr/textAppearanceMedium"/>

            <TextView
                android:id="@+id/tvTop"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBaseline="@id/cbTop"
                android:layout_marginLeft="110dp"
                android:layout_toRightOf="@id/cbTop"
                android:text="10"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@android:color/darker_gray"/>

            <CheckBox
                android:id="@+id/cbAscent"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/cbTop"
                android:checked="true"
                android:text="Ascent"
                android:textAppearance="?android:attr/textAppearanceMedium"

                android:theme="@style/Theme.AppCompat.CheckBoxAscent"/>

            <TextView
                android:id="@+id/tvAscent"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBaseline="@id/cbAscent"
                android:layout_marginLeft="110dp"
                android:layout_toRightOf="@id/cbTop"
                android:text="10"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@android:color/darker_gray"/>

            <CheckBox
                android:id="@+id/cbBaseline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/cbAscent"
                android:checked="true"
                android:text="Baseline"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:theme="@style/Theme.AppCompat.CheckboxBaseline"/>

            <TextView
                android:id="@+id/tvBaseline"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBaseline="@id/cbBaseline"
                android:layout_marginLeft="110dp"
                android:layout_toRightOf="@id/cbTop"
                android:text="10"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@android:color/darker_gray"/>

            <CheckBox
                android:id="@+id/cbDescent"

                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/cbBaseline"
                android:checked="true"
                android:text="Descent"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:theme="@style/Theme.AppCompat.CheckboxDescent"/>

            <TextView
                android:id="@+id/tvDescent"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBaseline="@id/cbDescent"
                android:layout_marginLeft="110dp"
                android:layout_toRightOf="@id/cbTop"
                android:text="10"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@android:color/darker_gray"/>

            <CheckBox
                android:id="@+id/cbBottom"
                android:theme="@style/Theme.AppCompat.CheckboxBottom"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/cbDescent"
                android:checked="true"
                android:text="Bottom"
                android:textAppearance="?android:attr/textAppearanceMedium"/>

            <TextView
                android:id="@+id/tvBottom"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBaseline="@id/cbBottom"
                android:layout_marginLeft="110dp"
                android:layout_toRightOf="@id/cbTop"
                android:text="10"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@android:color/darker_gray"/>

            <CheckBox
                android:id="@+id/cbWidth"
                android:theme="@style/Theme.AppCompat.MeasuerdWidth"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/cbBottom"
                android:checked="true"
                android:text="Measured width"
                android:textAppearance="?android:attr/textAppearanceMedium"/>

            <TextView
                android:id="@+id/tvWidth"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBaseline="@id/cbWidth"
                android:layout_marginLeft="110dp"
                android:layout_toRightOf="@id/cbTop"
                android:text="10"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@android:color/darker_gray"/>

            <CheckBox
                android:id="@+id/cbTextBounds"
                android:theme="@style/Theme.AppCompat.TextBounds"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/cbWidth"
                android:checked="true"
                android:text="Text bounds"
                android:textAppearance="?android:attr/textAppearanceMedium"/>

            <TextView
                android:id="@+id/tvTextBounds"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBaseline="@id/cbTextBounds"
                android:layout_marginLeft="110dp"
                android:layout_toRightOf="@id/cbTop"
                android:text="10"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@android:color/darker_gray"/>

            <TextView
                android:id="@+id/tvLeadingLabel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/cbTextBounds"
                android:layout_marginLeft="33dp"
                android:layout_marginTop="10dp"
                android:text="Leading"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@android:color/white"/>

            <TextView
                android:id="@+id/tvLeadingValue"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignBaseline="@id/tvLeadingLabel"
                android:layout_marginLeft="110dp"
                android:layout_toRightOf="@id/cbTop"
                android:text="10"
                android:textAppearance="?android:attr/textAppearanceMedium"
                android:textColor="@android:color/darker_gray"/>
        </RelativeLayout>

    </ScrollView>

</RelativeLayout>


text:
<?php

    require_once(__DIR__."/../../Backend/SessionManager.php");
    require_once(__DIR__."/../../Backend/ProofManager.php");
    require_once(__DIR__."/../../Backend/PersonManager.php");
    require_once(__DIR__."/../../Backend/RectorManager.php");
    require_once(__DIR__."/../../Backend/LanguageSupport.php");

    SessionManager::validateUserInPage('proofLook.php');

    //Get File contest from template
    $string = file_get_contents("template/ProofInsertion.html");

    if (!isset($_GET) || $_GET["id"] === NULL)
    {
        echo "";
    }

    //Remplace the nav
    $string = str_replace("|title|",  'Look Proof', $string);
    $string = str_replace("|NavBar|", SessionManager::getNavBar(), $string);

    //Get The Data of the Proof
    $idProof       = $_GET["id"];
    $proof         = ProofManager::getSingleProofTalks('id', $idProof);

    $ownerId         = $proof->getIdOwner();
    $owner           = PersonManager::getSinglePerson('id', $ownerId);
    $owner->getIdFather() !== NULL ? $fatherId = $owner->getIdFather() : $fatherId = 0;
    $owner->getIdMother() !== NULL ? $motherId = $owner->getIdMother() : $motherId = 0;
    $address         = $owner->getAddress();
    $phonenum        = $owner->getPhoneNumber();
    $gender          = $owner->getGender();

    $churchId        = $proof->getIdChurch();

    $idGodFather     = $proof->getIdGodFather();
    $idGodMother     = $proof->getIdGodMother();
    $godMother       = PersonManager::getSinglePerson('id', $idGodMother);
    $godFather       = PersonManager::getSinglePerson('id', $idGodFather);

    if ($godFather === NULL)
    {
        $godFather = new Person();
    }

    if ($godMother === NULL)
    {
        $godMother = new Person();
    }

    //Create a String of options of Last Church
    $churchString = "";
    $churchs = ChurchManager::getAllChurchs('name');

    foreach ($churchs as $singleChurch)
    {
        if ($singleChurch->getId() === $churchId)
        {
            $churchString = $churchString . "<option selected> " . $singleChurch->getName() . "</option>\n";
        }
        else
        {
            $churchString = $churchString . "<option> " . $singleChurch->getName() . "</option>\n";
        }
    }

    $string = str_replace("|ChurchOption|", $churchString, $string);

    //Create a String of options of Cities
    $citiesString = "";
    $cities = CityManager::getAllCities();

    $idCity = "7";

    if ($owner->getIdCityAddress() !== NULL)
    {
        $idCity = $owner->getIdCityAddress();
    }

    foreach ($cities as $singleCity)
    {
        if ($idCity === $singleCity->getId())
        {
            $citiesString = $citiesString . "<option selected> " . $singleCity->getName() . "</option>\n";
        }
        else
        {
            $citiesString = $citiesString . "<option> " . $singleCity->getName() . "</option>\n";
        }
    }

    $string = str_replace("|CityOptions|", $citiesString, $string);

    //Insert the Type Proof
    $stringProof = "";

    if ($proof->getType() === 'C')
    {
        $stringProof = $stringProof . "<option>^Baptism^</option>";
        $stringProof = $stringProof . "<option>^Communion^</option>";
        $stringProof = $stringProof . "<option selected>^Confirmation^</option>";
        $stringProof = $stringProof . "<option>^XV^</option>";
    }
    else if ($proof->getType() === 'X')
    {
        $stringProof = $stringProof . "<option>^Baptism^</option>";
        $stringProof = $stringProof . "<option>^Communion^</option>";
        $stringProof = $stringProof . "<option>^Confirmation^</option>";
        $stringProof = $stringProof . "<option selected>^XV^</option>";
    }
    else if ($proof->getType() === 'C')
    {
        $stringProof = $stringProof . "<option>^Baptism^</option>";
        $stringProof = $stringProof . "<option selected>^Communion^</option>";
        $stringProof = $stringProof . "<option>^Confirmation^</option>";
        $stringProof = $stringProof . "<option>^XV^</option>";
    }
    else
    {
        $stringProof = $stringProof . "<option>^Baptism^</option>";
        $stringProof = $stringProof . "<option>^Communion^</option>";
        $stringProof = $stringProof . "<option>^Confirmation^</option>";
        $stringProof = $stringProof . "<option>^XV^</option>";
    }

    $string = str_replace("|TypeOptions|", $stringProof, $string);

    //Create the button
    $saveButton   = '';

    $cancelButton = '';

    $returnButton = '<button type="button" class="btn btn-success" onclick=\'href("proofMenu.php")\'>

                        ^Return^
                    </button>';

    //Create a action for button cancel
    $string = str_replace("|SaveButton|"  , $saveButton  , $string);
    $string = str_replace("|CancelButton|", $cancelButton, $string);
    $string = str_replace("|ReturnButton|", $returnButton, $string);

    $script = "";

    $string = LanguageSupport::HTMLEvalLanguage($string);

    echo $string;
    echo $script;

 ?>


text:
package com.hlin.sensitive;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * 敏感词匹配结果
 *
 * @author hailin0@yeah.net
 * @createDate 2016年5月22日
 *
 */
public class SensitiveWordResult implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 6908376892848907410L;

    /**
     * 敏感词
     */
    private String word;

    /**
     * 敏感词匹配位置集合
     */
    private List<PositionNode> positions = new ArrayList<PositionNode>();

    /**
     * 构造器
     *
     * @param startPosition
     * @param word
     */
    public SensitiveWordResult(int startPosition, String word) {
        this.word = word;
        addPosition(startPosition, word);
    }

    /**
     * @return the word
     */
    public String getWord() {
        return word;
    }

    /**
     * @param word the word to set
     */
    public void setWord(String word) {
        this.word = word;
    }

    /**
     * @return the positions
     */
    public List<PositionNode> getPositions() {
        return positions;
    }

    /**
     * @param positions the positions to set
     */
    public void setPositions(List<PositionNode> positions) {
        this.positions = positions;
    }

    /**
     * 记录敏感词位置
     *
     * @param startPosition
     * @param word
     */
    public void addPosition(int startPosition, String word) {
        positions.add(new PositionNode(startPosition, startPosition + word.length()));
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((word == null) ? 0 : word.hashCode());
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        SensitiveWordResult other = (SensitiveWordResult) obj;
        if (word == null) {
            if (other.word != null)
                return false;
        } else if (!word.equals(other.word))
            return false;
        return true;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "SensitiveWordResult [word=" + word + ", positions=" + positions + "]";
    }

    /**
     * 位置节点
     *
     * @author hailin0@yeah.net
     * @createDate 2016年5月22日
     *
     */
    public class PositionNode {
        /**
         * 开始位置
         */
        private int startPosition;

        /**
         * 结束位置
         */
        private int endPosition;

        /**
         * @param startPosition
         * @param endPosition
         */
        public PositionNode(int startPosition, int endPosition) {
            super();
            this.startPosition = startPosition;
            this.endPosition = endPosition;
        }

        /**
         * @return the startPosition
         */
        public int getStartPosition() {
            return startPosition;
        }

        /**
         * @param startPosition the startPosition to set
         */
        public void setStartPosition(int startPosition) {
            this.startPosition = startPosition;
        }

        /**
         * @return the endPosition
         */
        public int getEndPosition() {
            return endPosition;
        }

        /**
         * @param endPosition the endPosition to set
         */
        public void setEndPosition(int endPosition) {
            this.endPosition = endPosition;
        }

        /*
         * (non-Javadoc)
         *
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            return "PositionNode [startPosition=" + startPosition + ", endPosition=" + endPosition
                    + "]";
        }

    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/menu_expandable_limit"
        android:checkable="true"
        android:title="limit"/>

</menu>


text:
class Incident < ActiveRecord::Base
  belongs_to :bike
  validates_presence_of :last_seen, :last_location, :bike

  geocoded_by :last_location
  after_validation :geocode, unless: lambda { |u| u.last_location_changed? || u.geocoded? }
end


text:
// File system implementation.  Five layers:
//   + Blocks: allocator for raw disk blocks.
//   + Log: crash recovery for multi-step updates.
//   + Files: inode allocator, reading, writing, metadata.
//   + Directories: inode with special contents (list of other inodes!)
//   + Names: paths like /usr/rtm/xv6/fs.c for convenient naming.
//
// This file contains the low-level file system manipulation
// routines.  The (higher-level) system call implementations
// are in sysfile.c.

#include "types.h"
#include "defs.h"
#include "param.h"
#include "stat.h"
#include "mmu.h"
#include "proc.h"
#include "spinlock.h"
#include "buf.h"
#include "fs.h"
#include "file.h"

#define LOOP_NUM  16
#define min(a, b) ((a) < (b) ? (a) : (b))
static void itrunc(struct inode*);

// Read the super block.
void
readsb(int dev, struct superblock *sb)
{
  struct buf *bp;

  bp = bread(dev, 1);
  memmove(sb, bp->data, sizeof(*sb));
  brelse(bp);
}

// Zero a block.
static void
bzero(int dev, int bno)
{
  struct buf *bp;

  bp = bread(dev, bno);
  memset(bp->data, 0, BSIZE);
  log_write(bp);
  brelse(bp);
}

// Blocks.

// Allocate a zeroed disk block.
static uint
balloc(uint dev)
{
  int b, bi, m;
  struct buf *bp;
  struct superblock sb;

  bp = 0;
  readsb(dev, &sb);
  for(b = 0; b < sb.size; b += BPB){
    bp = bread(dev, BBLOCK(b, sb.ninodes));
    for(bi = 0; bi < BPB && b + bi < sb.size; bi++){
      m = 1 << (bi % 8);
      if((bp->data[bi/8] & m) == 0){  // Is block free?
        bp->data[bi/8] |= m;  // Mark block in use.
        log_write(bp);
        brelse(bp);
        bzero(dev, b + bi);
        return b + bi;
      }
    }
    brelse(bp);
  }
  panic("balloc: out of blocks");
}

// Free a disk block.
static void
bfree(int dev, uint b)
{
  struct buf *bp;
  struct superblock sb;
  int bi, m;

  readsb(dev, &sb);
  bp = bread(dev, BBLOCK(b, sb.ninodes));
  bi = b % BPB;
  m = 1 << (bi % 8);
  if((bp->data[bi/8] & m) == 0)
    panic("freeing free block");
  bp->data[bi/8] &= ~m;
  log_write(bp);
  brelse(bp);
}

// Inodes.
//
// An inode describes a single unnamed file.
// The inode disk structure holds metadata: the file's type,
// its size, the number of links referring to it, and the
// list of blocks holding the file's content.
//
// The inodes are laid out sequentially on disk immediately after
// the superblock. Each inode has a number, indicating its
// position on the disk.
//
// The kernel keeps a cache of in-use inodes in memory
// to provide a place for synchronizing access
// to inodes used by multiple processes. The cached
// inodes include book-keeping information that is
// not stored on disk: ip->ref and ip->flags.
//
// An inode and its in-memory represtative go through a
// sequence of states before they can be used by the
// rest of the file system code.
//
// * Allocation: an inode is allocated if its type (on disk)
//   is non-zero. ialloc() allocates, iput() frees if
//   the link count has fallen to zero.
//
// * Referencing in cache: an entry in the inode cache
//   is free if ip->ref is zero. Otherwise ip->ref tracks
//   the number of in-memory pointers to the entry (open
//   files and current directories). iget() to find or
//   create a cache entry and increment its ref, iput()
//   to decrement ref.
//
// * Valid: the information (type, size, &c) in an inode
//   cache entry is only correct when the I_VALID bit
//   is set in ip->flags. ilock() reads the inode from
//   the disk and sets I_VALID, while iput() clears
//   I_VALID if ip->ref has fallen to zero.
//
// * Locked: file system code may only examine and modify
//   the information in an inode and its content if it
//   has first locked the inode. The I_BUSY flag indicates
//   that the inode is locked. ilock() sets I_BUSY,
//   while iunlock clears it.
//
// Thus a typical sequence is:
//   ip = iget(dev, inum)
//   ilock(ip)
//   ... examine and modify ip->xxx ...
//   iunlock(ip)
//   iput(ip)
//
// ilock() is separate from iget() so that system calls can
// get a long-term reference to an inode (as for an open file)
// and only lock it for short periods (e.g., in read()).
// The separation also helps avoid deadlock and races during
// pathname lookup. iget() increments ip->ref so that the inode
// stays cached and pointers to it remain valid.
//
// Many internal file system functions expect the caller to
// have locked the inodes involved; this lets callers create
// multi-step atomic operations.

struct {
  struct spinlock lock;
  struct inode inode[NINODE];
} icache;

void
iinit(void)
{
  initlock(&icache.lock, "icache");
}

static struct inode* iget(uint dev, uint inum);

//PAGEBREAK!
// Allocate a new inode with the given type on device dev.
// A free inode has a type of zero.
struct inode*
ialloc(uint dev, short type)
{
  int inum;
  struct buf *bp;
  struct dinode *dip;
  struct superblock sb;

  readsb(dev, &sb);

  for(inum = 1; inum < sb.ninodes; inum++){
    bp = bread(dev, IBLOCK(inum));
    dip = (struct dinode*)bp->data + inum%IPB;
    if(dip->type == 0){  // a free inode
      memset(dip, 0, sizeof(*dip));
      dip->type = type;
      log_write(bp);   // mark it allocated on the disk
      brelse(bp);
      return iget(dev, inum);
    }
    brelse(bp);
  }
  panic("ialloc: no inodes");
}

// Copy a modified in-memory inode to disk.
void
iupdate(struct inode *ip)
{
  struct buf *bp;
  struct dinode *dip;

  bp = bread(ip->dev, IBLOCK(ip->inum));
  dip = (struct dinode*)bp->data + ip->inum%IPB;
  dip->type = ip->type;
  dip->major = ip->major;
  dip->minor = ip->minor;
  dip->nlink = ip->nlink;
  dip->size = ip->size;
  memmove(dip->addrs, ip->addrs, sizeof(ip->addrs));
  memmove(dip->password, ip->password, sizeof(ip->password)); // task 2
  log_write(bp);
  brelse(bp);
}

// Find the inode with number inum on device dev
// and return the in-memory copy. Does not lock
// the inode and does not read it from disk.
static struct inode*
iget(uint dev, uint inum)
{
  struct inode *ip, *empty;

  acquire(&icache.lock);

  // Is the inode already cached?
  empty = 0;
  for(ip = &icache.inode[0]; ip < &icache.inode[NINODE]; ip++){
    if(ip->ref > 0 && ip->dev == dev && ip->inum == inum){
      ip->ref++;
      release(&icache.lock);
      return ip;
    }
    if(empty == 0 && ip->ref == 0)    // Remember empty slot.
      empty = ip;
  }

  // Recycle an inode cache entry.
  if(empty == 0)
    panic("iget: no inodes");

  ip = empty;
  ip->dev = dev;
  ip->inum = inum;
  ip->ref = 1;
  ip->flags = 0;
  release(&icache.lock);

  return ip;
}

// Increment reference count for ip.
// Returns ip to enable ip = idup(ip1) idiom.
struct inode*
idup(struct inode *ip)
{
  acquire(&icache.lock);
  ip->ref++;
  release(&icache.lock);
  return ip;
}

// Lock the given inode.
// Reads the inode from disk if necessary.
void
ilock(struct inode *ip)
{
  struct buf *bp;
  struct dinode *dip;

  if(ip == 0 || ip->ref < 1)
    panic("ilock");

  acquire(&icache.lock);
  while(ip->flags & I_BUSY){
    // cprintf("sleeping\n");
    sleep(ip, &icache.lock);
  }
  // cprintf("done\n");
  ip->flags |= I_BUSY;
  release(&icache.lock);

  if(!(ip->flags & I_VALID)){
    bp = bread(ip->dev, IBLOCK(ip->inum));
    dip = (struct dinode*)bp->data + ip->inum%IPB;
    ip->type = dip->type;
    ip->major = dip->major;
    ip->minor = dip->minor;
    ip->nlink = dip->nlink;
    ip->size = dip->size;
    memmove(ip->addrs, dip->addrs, sizeof(ip->addrs));
    memmove(ip->password, dip->password, sizeof(dip->password));
    brelse(bp);
    ip->flags |= I_VALID;
    if(ip->type == 0)
      panic("ilock: no type");
  }
}

// Unlock the given inode.
void
iunlock(struct inode *ip)
{
  if(ip == 0 || !(ip->flags & I_BUSY) || ip->ref < 1)
    panic("iunlock");

  acquire(&icache.lock);
  ip->flags &= ~I_BUSY;
  wakeup(ip);
  release(&icache.lock);
}

// Drop a reference to an in-memory inode.
// If that was the last reference, the inode cache entry can
// be recycled.
// If that was the last reference and the inode has no links
// to it, free the inode (and its content) on disk.
void
iput(struct inode *ip)
{
  acquire(&icache.lock);
  if(ip->ref == 1 && (ip->flags & I_VALID) && ip->nlink == 0){
    // inode has no links: truncate and free inode.
    if(ip->flags & I_BUSY)
      panic("iput busy");
    ip->flags |= I_BUSY;
    release(&icache.lock);
    itrunc(ip);
    ip->type = 0;
    iupdate(ip);
    acquire(&icache.lock);
    ip->flags = 0;
    wakeup(ip);
  }
  ip->ref--;
  release(&icache.lock);
}

// Common idiom: unlock, then put.
void
iunlockput(struct inode *ip)
{
  iunlock(ip);
  iput(ip);
}

//PAGEBREAK!
// Inode content
//
// The content (data) associated with each inode is stored
// in blocks on the disk. The first NDIRECT block numbers
// are listed in ip->addrs[].  The next NINDIRECT blocks are
// listed in block ip->addrs[NDIRECT].

// Return the disk block address of the nth block in inode ip.
// If there is no such block, bmap allocates one.

// modified as part of task1a

static uint
bmap(struct inode *ip, uint bn)
{
  uint addr, *a, *a2;
  struct buf *bp, *bp2;

  if(bn < NDIRECT){
    if((addr = ip->addrs[bn]) == 0)
      ip->addrs[bn] = addr = balloc(ip->dev);
    return addr;
  }
  bn -= NDIRECT;

  // this condition is for one level indirection

  if(bn < NINDIRECT){
    // Load indirect block, allocating if necessary.
    if((addr = ip->addrs[NDIRECT]) == 0){  // addr now holds the address of the block
      ip->addrs[NDIRECT] = addr = balloc(ip->dev);  // allocates root if null
    }
    bp = bread(ip->dev, addr); // returns a buffer
    a = (uint*)bp->data;       // takes its data
    if((addr = a[bn]) == 0){   // check if in the place it is null
      a[bn] = addr = balloc(ip->dev); // allocates a leaf
      log_write(bp);
    }
    brelse(bp);
    return addr;
  }

  // task1 addition
  bn -= NINDIRECT;
  if (bn < NNIINDIRECT){
    uint lower_bits = bn & 0x7F;  // lower 7 bits of bn
    uint upper_bits = (bn >> 7) & 0x7F; // upper 7 bits of bn
    if((addr = ip->addrs[NDIRECT+1]) == 0){
      ip->addrs[NDIRECT+1] = addr = balloc(ip->dev); // allocates root if null
    }
    bp = bread(ip->dev, addr); // reads the block
    a = (uint*)bp->data;
    if((addr = a[upper_bits]) == 0){
      a[upper_bits] = addr = balloc(ip->dev); // allocates first level if null
      log_write(bp);
    }
    /* until here acts like the conditional above
     * in the way that it searched and allocated layer 1.
     * now entering the second level of indirection*/

    // a is our block now

    bp2 = bread(ip->dev,addr);
    a2 = (uint*)bp2->data;
    if((addr = a2[lower_bits]) == 0){
      a2[lower_bits] = addr = balloc(ip->dev);  // allocates leaf
      log_write(bp2);
    }

    brelse(bp2);
    brelse(bp);

    return addr;

  }
  panic("bmap: out of range");
}

// Truncate inode (discard contents).
// Only called when the inode has no links
// to it (no directory entries referring to it)
// and has no in-memory reference to it (is
// not an open file or current directory).
static void
itrunc(struct inode *ip)
{
  int i, j;
  struct buf *bp, *bp2;
  uint *a, *a2;

  for(i = 0; i < NDIRECT; i++){
    if(ip->addrs[i]){
      bfree(ip->dev, ip->addrs[i]);
      ip->addrs[i] = 0;
    }
  }

  if(ip->addrs[NDIRECT]){
    bp = bread(ip->dev, ip->addrs[NDIRECT]);
    a = (uint*)bp->data;
    for(j = 0; j < NINDIRECT; j++){
      if(a[j])
        bfree(ip->dev, a[j]);
    }
    brelse(bp);
    bfree(ip->dev, ip->addrs[NDIRECT]);
    ip->addrs[NDIRECT] = 0;
  }

  /* task1 addition
   * iteration on the 2 level indirection tree*/

  if(ip->addrs[NDIRECT+1]){
    bp = bread(ip->dev, ip->addrs[NDIRECT+1]);
    a = (uint*)bp->data;
    for(j = 0; j < NINDIRECT; j++){
      if(a[j]){
        bp2 = bread(ip->dev,a[j]);
        a2 = (uint*)bp2->data;

        for(i = 0 ; i < NINDIRECT ; i++){
          if(a2[i]){
            bfree(ip->dev, a2[i]);
          }
        }

        brelse(bp2);
        bfree(ip->dev, a[j]);
      }

    }
    brelse(bp);
    bfree(ip->dev, ip->addrs[NDIRECT+1]);
    ip->addrs[NDIRECT+1] = 0;
  }

  ip->size = 0;
  iupdate(ip);
}

// Copy stat information from inode.
void
stati(struct inode *ip, struct stat *st)
{
  st->dev = ip->dev;
  st->ino = ip->inum;
  st->type = ip->type;
  st->nlink = ip->nlink;
  st->size = ip->size;
}

//PAGEBREAK!
// Read data from inode.
int
readi(struct inode *ip, char *dst, uint off, uint n)
{
  uint tot, m;
  struct buf *bp;

  if(ip->type == T_DEV){
    if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].read)
      return -1;
    return devsw[ip->major].read(ip, dst, n);
  }

  if(off > ip->size || off + n < off)
    return -1;
  if(off + n > ip->size)
    n = ip->size - off;

  for(tot=0; tot<n; tot+=m, off+=m, dst+=m){
    bp = bread(ip->dev, bmap(ip, off/BSIZE));
    m = min(n - tot, BSIZE - off%BSIZE);
    memmove(dst, bp->data + off%BSIZE, m);
    brelse(bp);
  }
  return n;
}

// PAGEBREAK!
// Write data to inode.
int
writei(struct inode *ip, char *src, uint off, uint n)
{
  uint tot, m;
  struct buf *bp;

  if(ip->type == T_DEV){
    if(ip->major < 0 || ip->major >= NDEV || !devsw[ip->major].write)
      return -1;
    return devsw[ip->major].write(ip, src, n);
  }

  if(off > ip->size || off + n < off)
    return -1;
  if(off + n > MAXFILE*BSIZE)
    return -1;

  for(tot=0; tot<n; tot+=m, off+=m, src+=m){
    bp = bread(ip->dev, bmap(ip, off/BSIZE));
    m = min(n - tot, BSIZE - off%BSIZE);
    memmove(bp->data + off%BSIZE, src, m);
    log_write(bp);
    brelse(bp);
  }

  if(n > 0 && off > ip->size){
    ip->size = off;
    iupdate(ip);
  }
  return n;
}

//PAGEBREAK!
// Directories

int
namecmp(const char *s, const char *t)
{
  return strncmp(s, t, DIRSIZ);
}

// Look for a directory entry in a directory.
// If found, set *poff to byte offset of entry.
struct inode*
dirlookup(struct inode *dp, char *name, uint *poff)
{
  uint off, inum;
  struct dirent de;

  if(dp->type != T_DIR)
    panic("dirlookup not DIR");

  for(off = 0; off < dp->size; off += sizeof(de)){
    if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
      panic("dirlink read");
    if(de.inum == 0)
      continue;
    if(namecmp(name, de.name) == 0){
      // entry matches path element
      if(poff)
        *poff = off;
      inum = de.inum;
      return iget(dp->dev, inum);
    }
  }

  return 0;
}

// Write a new directory entry (name, inum) into the directory dp.
int
dirlink(struct inode *dp, char *name, uint inum)
{
  int off;
  struct dirent de;
  struct inode *ip;

  // Check that name is not present.
  if((ip = dirlookup(dp, name, 0)) != 0){
    iput(ip);
    return -1;
  }

  // Look for an empty dirent.
  for(off = 0; off < dp->size; off += sizeof(de)){
    if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
      panic("dirlink read");
    if(de.inum == 0)
      break;
  }

  strncpy(de.name, name, DIRSIZ);
  de.inum = inum;
  if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
    panic("dirlink");

  return 0;
}

//PAGEBREAK!
// Paths

// Copy the next path element from path into name.
// Return a pointer to the element following the copied one.
// The returned path has no leading slashes,
// so the caller can check *path=='\0' to see if the name is the last one.
// If no name to remove, return 0.
//
// Examples:
//   skipelem("a/bb/c", name) = "bb/c", setting name = "a"
//   skipelem("///a//bb", name) = "bb", setting name = "a"
//   skipelem("a", name) = "", setting name = "a"
//   skipelem("", name) = skipelem("////", name) = 0
//
static char*
skipelem(char *path, char *name)
{
  char *s;
  int len;

  while(*path == '/')
    path++;
  if(*path == 0)
    return 0;
  s = path;
  while(*path != '/' && *path != 0)
    path++;
  len = path - s;
  if(len >= DIRSIZ)
    memmove(name, s, DIRSIZ);
  else {
    memmove(name, s, len);
    name[len] = 0;
  }
  while(*path == '/')
    path++;
  return path;
}

// Look up and return the inode for a path name.
// If parent != 0, return the inode for the parent and copy the final
// path element into name, which must have room for DIRSIZ bytes.
static struct inode*
namex(struct inode *root,char *path, int nameiparent, char *name, int deref, uint loops)
{
  struct inode *ip, *next;
  char buf[128], name2[DIRSIZ]; // changes for task1b
  uint deref_flag = 0;
  if(*path == '/')
    ip = iget(ROOTDEV, ROOTINO);
  else if(root)
    ip = idup(root);
  else
    ip = idup(proc->cwd);

  // cprintf("path: <%s>\n",path);
  while((path = skipelem(path, name)) != 0){
    ilock(ip);
    if(ip->type != T_DIR){
      iunlockput(ip);
      return 0;
    }
    if(nameiparent && *path == '\0'){
      // Stop one level early.
      iunlock(ip);
      return ip;
    }
    if((next = dirlookup(ip, name, 0)) == 0){
      iunlockput(ip);
      return 0;
    }
    // cprintf("path: <%s>\n",path);
    // task1 changes starts here
    deref_flag = deref | (*path != '\0');
    // cprintf("deref: %d, pred: %d, flag: %d\n",deref,(*path == '\0'),deref_flag);
    // iunlockput(ip);
    iunlock(ip);
    ilock(next);
    // cprintf("inside namex!!!!!!!!!!!! %d\n",next->type);

    if(next->type == T_SYMLINK && deref_flag){ // if next file is of symlink type
      // open file and reads its contents
      if(readi(next,buf,0,next->size) != next->size){
        // if read fails
        // cprintf("buf: %d %d%s",test,sizeof(buf),buf);
        iunlockput(next);
        iput(ip);
        return 0;
      }

      buf[next->size] = 0; // null terminates string
      iunlockput(next);

      /* recursive use in the function to find
       * the file which is written on the inode
       */

      if(loops == 0){ // avoid infinite
          cprintf("Error: infinite loop\n"); //TODO: maybe replace with panic
          iput(ip);
          return 0;// break;
      }
      next = namex(ip,buf,0,name2, deref, loops-1);
      // if((next = namex(buf,0,name2, deref, loops-1)) == 0){
        // cprintf("debug next null");
        // iput(ip);
        // return 0;
      // }
      deref_flag = deref | (*path != '\0');
      // cprintf("2deref: %d, pred: %d, flag: %d\n",deref,(*path == '\0'),deref_flag);
      // cprintf("read: %s\n",buf);
    }else{
      iunlock(next);
    }
    iput(ip);
    ip = next;
  }

  if(nameiparent){
    iput(ip);
    return 0;
  }

  return ip;
}

struct inode*
namei(char *path)
{
  char name[DIRSIZ];
  return namex(0, path, 0, name, 1, LOOP_NUM);
}

struct inode*
namei_sym(char *path, int deref)
{
  char name[DIRSIZ];
  // cprintf("been here in namei_sym %d\n", deref);
  return namex(0, path, 0, name, deref, LOOP_NUM);
}

struct inode*
nameiparent(char *path, char *name)
{
  return namex(0 ,path, 1, name, 0, LOOP_NUM);
}


text:
/**
 * An enumeration of channels to be used when responding to
 * {@code ipcRenderer.send}.
 * @enum {string}
 */
const ResponseChannel = {
  /**
   * Provides the percentage completed for the current request.
   * Arguments: number
   */
  PROGRESS_UPDATE: 'PROGRESS_UPDATE',

  /**
   * Provides application settings.
   * Arguments: ApplicationSettingsSpecification
   */
  LOAD_APPLICATION_SETTINGS: 'LOAD_APPLICATION_SETTINGS_RESPONSE',

  /**
   * Indicates application settings were saved.
   * Arguments: boolean
   */
  SAVE_APPLICATION_SETTINGS: 'SAVE_APPLICATION_SETTINGS_RESPONSE',

  /**
   * Provides a user-selected *.plexporter file from the file system.
   * Arguments:
   */
  SELECT_PLEXPORTER_FILE: 'SELECT_PLEXPORTER_FILE_RESPONSE',

  /**
   * Provides a user-selected existing folder/directory.
   * Arguments: string
   */
  SELECT_EXISTING_DIRECTORY: 'SELECT_EXISTING_DIRECTORY_RESPONSE',

  /**
   * Provides an error if a COPY_TRACKS operation failed, or null otherwise.
   * Arguments: ?Error
   */
  COPY_TRACKS: 'COPY_TRACKS',

  /**
   * Provides an error if a COPY_ALBUMS operation failed, or null otherwise.
   * Arguments: ?Error
   */
  COPY_ALBUMS: 'COPY_ALBUMS',
};

module.exports = ResponseChannel;


text:
/////////////////////////////////////////////////////////////////////////////
// Name:        src/palmos/dir.cpp
// Purpose:     wxDir implementation for PalmOS
// Author:      William Osborne - minimal working wxPalmOS port
// Modified by:
// Created:     10.13.04
// RCS-ID:      $Id: dir.cpp,v 1.1 2005/04/25 09:54:06 MW Exp $
// Copyright:   (c) William Osborne
// Licence:     wxWindows licence
/////////////////////////////////////////////////////////////////////////////

// ============================================================================
// declarations
// ============================================================================

// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------

#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
    #pragma implementation "dir.h"
#endif

// For compilers that support precompilation, includes "wx.h".
#include "wx/wxprec.h"

#ifdef __BORLANDC__
    #pragma hdrstop
#endif

#ifndef WX_PRECOMP
    #include "wx/intl.h"
    #include "wx/log.h"
#endif // PCH

#include "wx/dir.h"
#include "wx/filefn.h"          // for wxDirExists()

// ----------------------------------------------------------------------------
// define the types and functions used for file searching
// ----------------------------------------------------------------------------

// ----------------------------------------------------------------------------
// constants
// ----------------------------------------------------------------------------

#ifndef MAX_PATH
    #define MAX_PATH 260        // from VC++ headers
#endif

// ----------------------------------------------------------------------------
// macros
// ----------------------------------------------------------------------------

#define M_DIR       ((wxDirData *)m_data)

// ----------------------------------------------------------------------------
// private classes
// ----------------------------------------------------------------------------

// ============================================================================
// implementation
// ============================================================================

// ----------------------------------------------------------------------------
// wxDir helpers
// ----------------------------------------------------------------------------

/* static */
bool wxDir::Exists(const wxString& dir)
{
    return false;
}

// ----------------------------------------------------------------------------
// wxDir construction/destruction
// ----------------------------------------------------------------------------

wxDir::wxDir(const wxString& dirname)
{
}

bool wxDir::Open(const wxString& dirname)
{
    return false;
}

bool wxDir::IsOpened() const
{
    return false;
}

wxString wxDir::GetName() const
{
    wxString name;

    return name;
}

wxDir::~wxDir()
{
}

// ----------------------------------------------------------------------------
// wxDir enumerating
// ----------------------------------------------------------------------------

bool wxDir::GetFirst(wxString *filename,
                     const wxString& filespec,
                     int flags) const
{
    return false;
}

bool wxDir::GetNext(wxString *filename) const
{
    return false;
}