text:
![](../../../../image/colab_logo_32px.png)[Run in Google Colab](https://colab.research.google.com/github/intel-analytics/BigDL/blob/main/python/orca/colab-notebook/quickstart/pytorch_distributed_lenet_mnist.ipynb)  ![](../../../../image/GitHub-Mark-32px.png)[View source on GitHub](https://github.com/intel-analytics/BigDL/blob/main/python/orca/colab-notebook/quickstart/pytorch_distributed_lenet_mnist.ipynb)

---

**In this guide we will describe how to scale out _PyTorch_ programs using the `torch.distributed` package in Orca.**

### Step 0: Prepare Environment

[Conda](https://docs.conda.io/projects/conda/en/latest/user-guide/install/) is needed to prepare the Python environment for running this example. Please refer to the [install guide](../../UserGuide/python.md) for more details.

```bash
conda create -n py37 python=3.7  # "py37" is conda environment name, you can use any name you like.
conda activate py37
pip install bigdl-orca[ray]
pip install torch==1.7.1 torchvision==0.8.2
```

### Step 1: Init Orca Context
```python
from bigdl.orca import init_orca_context, stop_orca_context

if cluster_mode == "local":  # For local machine
    init_orca_context(cores=4, memory="10g")
elif cluster_mode == "k8s":  # For K8s cluster
    init_orca_context(cluster_mode="k8s", num_nodes=2, cores=2, memory="10g", driver_memory="10g", driver_cores=1)
elif cluster_mode == "yarn":  # For Hadoop/YARN cluster
    init_orca_context(cluster_mode="yarn", cores=2, num_nodes=2, memory="10g", driver_memory="10g", driver_cores=1)
```

This is the only place where you need to specify local or distributed mode. View [Orca Context](./../Overview/orca-context.md) for more details.

**Note:** You should `export HADOOP_CONF_DIR=/path/to/hadoop/conf/dir` when running on Hadoop YARN cluster. View [Hadoop User Guide](./../../UserGuide/hadoop.md) for more details.

### Step 2: Define the Model

You may define your model, loss and optimizer in the same way as in any standard (single node) PyTorch program.

```python
import torch
import torch.nn as nn
import torch.nn.functional as F

class LeNet(nn.Module):
    def __init__(self):
        super(LeNet, self).__init__()
        self.conv1 = nn.Conv2d(1, 20, 5, 1)
        self.conv2 = nn.Conv2d(20, 50, 5, 1)
        self.fc1 = nn.Linear(4*4*50, 500)
        self.fc2 = nn.Linear(500, 10)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = F.max_pool2d(x, 2, 2)
        x = F.relu(self.conv2(x))
        x = F.max_pool2d(x, 2, 2)
        x = x.view(-1, 4*4*50)
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return F.log_softmax(x, dim=1)

criterion = nn.NLLLoss()
```
After defining your model, you need to define a *Model Creator Function* that returns an instance of your model, and a *Optimizer Creator Function* that returns a PyTorch optimizer.

```python
def model_creator(config):
    model = LeNet()
    return model

def optim_creator(model, config):
    return torch.optim.Adam(model.parameters(), lr=0.001)
```

### Step 3: Define Train Dataset

You can define the dataset using a *Data Creator Function* that returns a PyTorch `DataLoader`. Orca also supports [Orca SparkXShards](../Overview/data-parallel-processing).

```python
import torch
from torchvision import datasets, transforms

torch.manual_seed(0)
batch_size = 320
test_batch_size = 320
dir = './dataset'

def train_loader_creator(config, batch_size):
    train_loader = torch.utils.data.DataLoader(
        datasets.MNIST(dir, train=True, download=True,
                       transform=transforms.Compose([
                           transforms.ToTensor(),
                           transforms.Normalize((0.1307,), (0.3081,))
                       ])),
        batch_size=batch_size, shuffle=True)
    return train_loader

def test_loader_creator(config, batch_size):
    test_loader = torch.utils.data.DataLoader(
        datasets.MNIST(dir, train=False,
                       transform=transforms.Compose([
                           transforms.ToTensor(),
                           transforms.Normalize((0.1307,), (0.3081,))
                       ])),
        batch_size=batch_size, shuffle=False)
    return test_loader
```

### Step 4: Fit with Orca Estimator

First, Create an Estimator

```python
from bigdl.orca.learn.pytorch import Estimator
from bigdl.orca.learn.metrics import Accuracy

est = Estimator.from_torch(model=model_creator, optimizer=optim_creator, loss=criterion, metrics=[Accuracy()],
                           backend="ray")
```

Next, fit and evaluate using the Estimator

```python
est.fit(data=train_loader_creator, epochs=1, batch_size=batch_size)
result = est.evaluate(data=test_loader_creator, batch_size=test_batch_size)
for r in result:
    print(r, ":", result[r])
```

### Step 5: Save and Load the Model

Save the Estimator states (including model and optimizer) to the provided model path.

```python
est.save("mnist_model")
```

Load the Estimator states (model and possibly with optimizer) from provided model path.

```python
est.load("mnist_model")
```

**Note:** You should call `stop_orca_context()` when your application finishes.


text:
//-----------------------------------------------------------------------
// <copyright file="GetAvailableRegionsRequest.cs" company="Sitecore Corporation">
//     Copyright (c) Sitecore Corporation 1999-2015
// </copyright>
// <summary>The get available regions request.</summary>
//-----------------------------------------------------------------------
// Copyright 2015 Sitecore Corporation A/S
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
// except in compliance with the License. You may obtain a copy of the License at
//       http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software distributed under the
// License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
// -------------------------------------------------------------------------------------------

namespace Sitecore.Reference.Storefront.Connect.Pipelines.Arguments
{
    using Sitecore.Diagnostics;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;

    /// <summary>
    /// Defines the GetAvailableRegionsRequest class.
    /// </summary>
    public class GetAvailableRegionsRequest : Sitecore.Commerce.Services.ServiceProviderRequest
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="GetAvailableRegionsRequest"/> class.
        /// </summary>
        /// <param name="countryCode">The country code.</param>
        public GetAvailableRegionsRequest(string countryCode)
        {
            Assert.ArgumentNotNullOrEmpty(countryCode, "countryCode");
            this.CountryCode = countryCode;
        }

        /// <summary>
        /// Gets or sets the country code.
        /// </summary>
        /// <value>
        /// The country code.
        /// </value>
        public string CountryCode { get; set; }
    }
}

redpajama_set_name: RedPajamaGithub


text:
package main

import (
	"bytes"
	"context"
	"crypto/sha256"
	"encoding/hex"
	"errors"
	"flag"
	"fmt"
	"io"
	"net/http"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"strings"
	"time"

	bzl "github.com/bazelbuild/buildtools/build"
	"github.com/google/go-github/v36/github"
	"golang.org/x/mod/semver"
	"golang.org/x/oauth2"
	"golang.org/x/sync/errgroup"
)

var upgradeDepCmd = command{
	name:        "upgrade-dep",
	description: "upgrades a dependency in WORKSPACE or go_repositories.bzl",
	help: `releaser upgrade-dep [-githubtoken=token] [-mirror] [-work] deps...

upgrade-dep upgrades one or more rules_go dependencies in WORKSPACE or
go/private/repositories.bzl. Dependency names (matching the name attributes)
can be specified with positional arguments. "all" may be specified to upgrade
all upgradeable dependencies.

For each dependency, upgrade-dep finds the highest version available in the
upstream repository. If no version is available, upgrade-dep uses the commit
at the tip of the default branch. If a version is part of a release,
upgrade-dep will try to use an archive attached to the release; if none is
available, upgrade-dep uses an archive generated by GitHub.

Once upgrade-dep has found the URL for the latest version, it will:

* Download the archive.
* Upload the archive to mirror.bazel.build.
* Re-generate patches, either by running a command or by re-applying the
  old patches.
* Update dependency attributes in WORKSPACE and repositories.bzl, then format
  and rewrite those files.

Upgradeable dependencies need a comment like '# releaser:upgrade-dep org repo'
where org and repo are the GitHub organization and repository. We could
potentially fetch archives from proxy.golang.org instead, but it's not available
in as many countries.

Patches may have a comment like '# releaser:patch-cmd name args...'. If this
comment is present, upgrade-dep will generate the patch by running the specified
command in a temporary directory containing the extracted archive with the
previous patches applied.
`,
}

func init() {
	// break init cycle
	upgradeDepCmd.run = runUpgradeDep
}

func runUpgradeDep(ctx context.Context, stderr io.Writer, args []string) error {
	// Parse arguments.
	flags := flag.NewFlagSet("releaser upgrade-dep", flag.ContinueOnError)
	var githubToken githubTokenFlag
	var uploadToMirror, leaveWorkDir bool
	flags.Var(&githubToken, "githubtoken", "GitHub personal access token or path to a file containing it")
	flags.BoolVar(&uploadToMirror, "mirror", true, "whether to upload dependency archives to mirror.bazel.build")
	flags.BoolVar(&leaveWorkDir, "work", false, "don't delete temporary work directory (for debugging)")
	if err := flags.Parse(args); err != nil {
		return err
	}
	if flags.NArg() == 0 {
		return usageErrorf(&upgradeDepCmd, "No dependencies specified")
	}
	upgradeAll := false
	for _, arg := range flags.Args() {
		if arg == "all" {
			upgradeAll = true
			break
		}
	}
	if upgradeAll && flags.NArg() != 1 {
		return usageErrorf(&upgradeDepCmd, "When 'all' is specified, it must be the only argument")
	}

	httpClient := http.DefaultClient
	if githubToken != "" {
		ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: string(githubToken)})
		httpClient = oauth2.NewClient(ctx, ts)
	}
	gh := &githubClient{Client: github.NewClient(httpClient)}

	workDir, err := os.MkdirTemp("", "releaser-upgrade-dep-*")
	if leaveWorkDir {
		fmt.Fprintf(stderr, "work dir: %s\n", workDir)
	} else {
		defer func() {
			if rerr := os.RemoveAll(workDir); err == nil && rerr != nil {
				err = rerr
			}
		}()
	}

	// Make sure we have everything we need.
	// upgrade-dep must be run inside rules_go (though we just check for
	// WORKSPACE), and a few tools must be available.
	rootDir, err := repoRoot()
	if err != nil {
		return err
	}
	for _, tool := range []string{"diff", "gazelle", "gsutil", "patch"} {
		if _, err := exec.LookPath(tool); err != nil {
			return fmt.Errorf("%s must be installed in PATH", tool)
		}
	}

	// Parse and index files we might want to update.
	type file struct {
		path     string
		funcName string
		parsed   *bzl.File
		body     []bzl.Expr
	}
	files := []file{
		{path: filepath.Join(rootDir, "WORKSPACE")},
		{path: filepath.Join(rootDir, "go/private/repositories.bzl"), funcName: "go_rules_dependencies"},
	}
	depIndex := make(map[string]*bzl.CallExpr)

	for i := range files {
		f := &files[i]
		data, err := os.ReadFile(f.path)
		if err != nil {
			return err
		}
		f.parsed, err = bzl.Parse(f.path, data)
		if err != nil {
			return err
		}

		if f.funcName == "" {
			f.body = f.parsed.Stmt
		} else {
			for _, expr := range f.parsed.Stmt {
				def, ok := expr.(*bzl.DefStmt)
				if !ok {
					continue
				}
				if def.Name == f.funcName {
					f.body = def.Body
					break
				}
			}
			if f.body == nil {
				return fmt.Errorf("in file %s, could not find function %s", f.path, f.funcName)
			}
		}

		for _, expr := range f.body {
			call, ok := expr.(*bzl.CallExpr)
			if !ok {
				continue
			}
			for _, arg := range call.List {
				kwarg, ok := arg.(*bzl.AssignExpr)
				if !ok {
					continue
				}
				key := kwarg.LHS.(*bzl.Ident) // required by parser
				if key.Name != "name" {
					continue
				}
				value, ok := kwarg.RHS.(*bzl.StringExpr)
				if !ok {
					continue
				}
				depIndex[value.Value] = call
			}
		}
	}

	// Update dependencies in those files.
	eg, egctx := errgroup.WithContext(ctx)
	if upgradeAll {
		for name := range depIndex {
			name := name
			if _, _, err := parseUpgradeDepDirective(depIndex[name]); err != nil {
				continue
			}
			eg.Go(func() error {
				return upgradeDepDecl(egctx, gh, workDir, name, depIndex[name], uploadToMirror)
			})
		}
	} else {
		for _, arg := range flags.Args() {
			if depIndex[arg] == nil {
				return fmt.Errorf("could not find dependency %s", arg)
			}
		}
		for _, arg := range flags.Args() {
			arg := arg
			eg.Go(func() error {
				return upgradeDepDecl(egctx, gh, workDir, arg, depIndex[arg], uploadToMirror)
			})
		}
	}
	if err := eg.Wait(); err != nil {
		return err
	}

	// Format and write files back to disk.
	for _, f := range files {
		if err := os.WriteFile(f.path, bzl.Format(f.parsed), 0666); err != nil {
			return err
		}
	}
	return nil
}

// upgradeDepDecl upgrades a specific dependency.
func upgradeDepDecl(ctx context.Context, gh *githubClient, workDir, name string, call *bzl.CallExpr, uploadToMirror bool) (err error) {
	defer func() {
		if err != nil {
			err = fmt.Errorf("upgrading %s: %w", name, err)
		}
	}()

	// Find a '# releaser:upgrade-dep org repo' comment. We could probably
	// figure this out from URLs but this also serves to mark a dependency as
	// being automatically upgradeable.
	orgName, repoName, err := parseUpgradeDepDirective(call)
	if err != nil {
		return err
	}

	// Find attributes we'll need to read or write. We'll modify these directly
	// in the AST. Nothing else should read or write them while we're working.
	attrs := map[string]*bzl.Expr{
		"patches":      nil,
		"sha256":       nil,
		"strip_prefix": nil,
		"urls":         nil,
	}
	var urlsKwarg *bzl.AssignExpr
	for _, arg := range call.List {
		kwarg, ok := arg.(*bzl.AssignExpr)
		if !ok {
			continue
		}
		key := kwarg.LHS.(*bzl.Ident) // required by parser
		if _, ok := attrs[key.Name]; ok {
			attrs[key.Name] = &kwarg.RHS
		}
		if key.Name == "urls" {
			urlsKwarg = kwarg
		}
	}
	for key := range attrs {
		if key == "patches" {
			// Don't add optional attributes.
			continue
		}
		if attrs[key] == nil {
			kwarg := &bzl.AssignExpr{LHS: &bzl.Ident{Name: key}, Op: "="}
			call.List = append(call.List, kwarg)
			attrs[key] = &kwarg.RHS
		}
	}

	// Find the highest tag in semver order, ignoring whether the version has a
	// leading "v" or not. If there are no tags, find the commit at the tip of the
	// default branch.
	tags, err := gh.listTags(ctx, orgName, repoName)
	if err != nil {
		return err
	}

	vname := func(name string) string {
		if !strings.HasPrefix(name, "v") {
			return "v" + name
		}
		return name
	}

	w := 0
	for r := range tags {
		name := vname(*tags[r].Name)
		if name != semver.Canonical(name) {
			continue
		}
		tags[w] = tags[r]
		w++
	}
	tags = tags[:w]

	var highestTag *github.RepositoryTag
	var highestVname string
	for _, tag := range tags {
		name := vname(*tag.Name)
		if highestTag == nil || semver.Compare(name, highestVname) > 0 {
			highestTag = tag
			highestVname = name
		}
	}

	var ghURL, stripPrefix, urlComment string
	date := time.Now().Format("2006-01-02")
	if highestTag != nil {
		// If the tag is part of a release, check whether there is a release
		// artifact we should use.
		release, _, err := gh.Repositories.GetReleaseByTag(ctx, orgName, repoName, *highestTag.Name)
		if err == nil {
			wantNames := []string{
				fmt.Sprintf("%s-%s.tar.gz", repoName, *highestTag.Name),
				fmt.Sprintf("%s-%s.zip", repoName, *highestTag.Name),
			}
		AssetName:
			for _, asset := range release.Assets {
				for _, wantName := range wantNames {
					if *asset.Name == wantName {
						ghURL = asset.GetBrowserDownloadURL()
						stripPrefix = "" // may not always be correct
						break AssetName
					}
				}
			}
		}
		if ghURL == "" {
			ghURL = fmt.Sprintf("https://github.com/%s/%s/archive/refs/tags/%s.zip", orgName, repoName, *highestTag.Name)
			stripPrefix = repoName + "-" + strings.TrimPrefix(*highestTag.Name, "v")
		}
		urlComment = fmt.Sprintf("%s, latest as of %s", *highestTag.Name, date)
	} else {
		repo, _, err := gh.Repositories.Get(ctx, orgName, repoName)
		if err != nil {
			return err
		}
		defaultBranchName := "main"
		if repo.DefaultBranch != nil {
			defaultBranchName = *repo.DefaultBranch
		}
		branch, _, err := gh.Repositories.GetBranch(ctx, orgName, repoName, defaultBranchName)
		if err != nil {
			return err
		}
		ghURL = fmt.Sprintf("https://github.com/%s/%s/archive/%s.zip", orgName, repoName, *branch.Commit.SHA)
		stripPrefix = repoName + "-" + *branch.Commit.SHA
		urlComment = fmt.Sprintf("%s, as of %s", defaultBranchName, date)
	}
	ghURLWithoutScheme := ghURL[len("https://"):]
	mirrorURL := "https://mirror.bazel.build/" + ghURLWithoutScheme

	// Download the archive and find the SHA.
	archiveFile, err := os.CreateTemp("", "")
	if err != nil {
		return err
	}
	defer func() {
		archiveFile.Close()
		if rerr := os.Remove(archiveFile.Name()); err == nil && rerr != nil {
			err = rerr
		}
	}()
	resp, err := http.Get(ghURL)
	if err != nil {
		return err
	}
	hw := sha256.New()
	mw := io.MultiWriter(hw, archiveFile)
	if _, err := io.Copy(mw, resp.Body); err != nil {
		resp.Body.Close()
		return err
	}
	if err := resp.Body.Close(); err != nil {
		return err
	}
	sha256Sum := hex.EncodeToString(hw.Sum(nil))
	if _, err := archiveFile.Seek(0, io.SeekStart); err != nil {
		return err
	}

	// Upload the archive to mirror.bazel.build.
	if uploadToMirror {
		if err := copyFileToMirror(ctx, ghURLWithoutScheme, archiveFile.Name()); err != nil {
			return err
		}
	}

	// If there are patches, re-apply or re-generate them.
	// Patch labels may have "# releaser:patch-cmd name args..." directives
	// that instruct this program to generate the patch by running a commnad
	// in the directory. If there is no such directive, we apply the old patch
	// using "patch". In either case, we'll generate a new patch with "diff".
	// We'll scrub the timestamps to avoid excessive diffs in the PR that
	// updates dependencies.
	rootDir, err := repoRoot()
	if err != nil {
		return err
	}
	if attrs["patches"] != nil {
		if err != nil {
			return err
		}
		patchDir := filepath.Join(workDir, name, "a")
		if err := extractArchive(archiveFile, path.Base(ghURL), patchDir, stripPrefix); err != nil {
			return err
		}

		patchesList, ok := (*attrs["patches"]).(*bzl.ListExpr)
		if !ok {
			return fmt.Errorf("\"patches\" attribute is not a list")
		}
		for patchIndex, patchLabelExpr := range patchesList.List {
			patchLabelValue, comments, err := parsePatchesItem(patchLabelExpr)
			if err != nil {
				return fmt.Errorf("parsing expr %#v : %w", patchLabelExpr, err)
			}

			if !strings.HasPrefix(patchLabelValue, "//third_party:") {
				return fmt.Errorf("patch does not start with '//third_party:': %q", patchLabelValue)
			}
			patchName := patchLabelValue[len("//third_party:"):]
			patchPath := filepath.Join(rootDir, "third_party", patchName)
			prevDir := filepath.Join(workDir, name, string('a'+patchIndex))
			patchDir := filepath.Join(workDir, name, string('a'+patchIndex+1))
			var patchCmd []string
			for _, c := range comments.Before {
				words := strings.Fields(strings.TrimPrefix(c.Token, "#"))
				if len(words) > 0 && words[0] == "releaser:patch-cmd" {
					patchCmd = words[1:]
					break
				}
			}

			if err := copyDir(patchDir, prevDir); err != nil {
				return err
			}
			if patchCmd == nil {
				if err := runForError(ctx, patchDir, "patch", "-Np1", "-i", patchPath); err != nil {
					return err
				}
			} else {
				if err := runForError(ctx, patchDir, patchCmd[0], patchCmd[1:]...); err != nil {
					return err
				}
			}
			patch, _ := runForOutput(ctx, filepath.Join(workDir, name), "diff", "-urN", string('a'+patchIndex), string('a'+patchIndex+1))
			patch = sanitizePatch(patch)
			if err := os.WriteFile(patchPath, patch, 0666); err != nil {
				return err
			}
		}
	}

	// Update the attributes.
	*attrs["sha256"] = &bzl.StringExpr{Value: sha256Sum}
	*attrs["strip_prefix"] = &bzl.StringExpr{Value: stripPrefix}
	*attrs["urls"] = &bzl.ListExpr{
		List: []bzl.Expr{
			&bzl.StringExpr{Value: mirrorURL},
			&bzl.StringExpr{Value: ghURL},
		},
		ForceMultiLine: true,
	}
	urlsKwarg.Before = []bzl.Comment{{Token: "# " + urlComment}}

	return nil
}

func parsePatchesItem(patchLabelExpr bzl.Expr) (value string, comments *bzl.Comments, err error) {
	switch patchLabel := patchLabelExpr.(type) {
	case *bzl.CallExpr:
		// Verify the identifier, should be Label
		if ident, ok := patchLabel.X.(*bzl.Ident); !ok {
			return "", nil, fmt.Errorf("invalid identifier while parsing patch label")
		} else if ident.Name != "Label" {
			return "", nil, fmt.Errorf("invalid patch function: %q", ident.Name)
		}

		// Expect 1 String argument with the patch
		if len(patchLabel.List) != 1 {
			return "", nil, fmt.Errorf("Label expr should have 1 argument, found %d", len(patchLabel.List))
		}

		// Parse patch as a string
		patchLabelStr, ok := patchLabel.List[0].(*bzl.StringExpr)
		if !ok {
			return "", nil, fmt.Errorf("Label expr does not contain a string literal")
		}
		return patchLabelStr.Value, patchLabel.Comment(), nil
	case *bzl.StringExpr:
		return strings.TrimPrefix(patchLabel.Value, "@io_bazel_rules_go"), patchLabel.Comment(), nil
	default:
		return "", nil, fmt.Errorf("not all patches are string literals or Label()")
	}
}

// parseUpgradeDepDirective parses a '# releaser:upgrade-dep org repo' directive
// and returns the organization and repository name or an error if the directive
// was not found or malformed.
func parseUpgradeDepDirective(call *bzl.CallExpr) (orgName, repoName string, err error) {
	// TODO: support other upgrade strategies. For example, support git_repository
	// and go_repository (possibly wrapped in _maybe).
	for _, c := range call.Comment().Before {
		words := strings.Fields(strings.TrimPrefix(c.Token, "#"))
		if len(words) == 0 || words[0] != "releaser:upgrade-dep" {
			continue
		}
		if len(words) != 3 {
			return "", "", errors.New("invalid upgrade-dep directive; expected org, and name fields")
		}
		return words[1], words[2], nil
	}
	return "", "", errors.New("releaser:upgrade-dep directive not found")
}

// sanitizePatch sets all of the non-zero patch dates to the same value. This
// reduces churn in the PR that updates the patches.
//
// We avoid changing zero-valued patch dates, which are used in added or
// deleted files. Since zero-valued dates can vary a bit by time zone, we assume
// that any year starting with "19" is a zero-valeud date.
func sanitizePatch(patch []byte) []byte {
	lines := bytes.Split(patch, []byte{'\n'})

	for i, line := range lines {
		if !bytes.HasPrefix(line, []byte("+++ ")) && !bytes.HasPrefix(line, []byte("--- ")) {
			continue
		}

		tab := bytes.LastIndexByte(line, '\t')
		if tab < 0 || bytes.HasPrefix(line[tab+1:], []byte("19")) {
			continue
		}

		lines[i] = append(line[:tab+1], []byte("2000-01-01 00:00:00.000000000 -0000")...)
	}
	return bytes.Join(lines, []byte{'\n'})
}


text:
#! /usr/bin/env node

var path    = require('path');
var fs      = require('fs');

var pathutils = require('pathutils');
var dom       = require('xmldom').DOMParser;
var xpath     = require('xpath');

if(module.parent) {
  module.exports = doReplace;
}
else {
  if(process.argv.length == 2) {
    console.log('Usage: replacexml <[xpath=newvalue ...] [dirname ...] [filename ...]>');
    process.exit(0);
  }

  doReplace(process.argv.slice(2));
}

function doReplace(args) {
  var context = determineArguments(args);

  makeFileList(context.locations).forEach(function(file) {
    fs.readFile(file, 'utf-8', function(err, data) {
      if(err) throw err;

      var document = new dom().parseFromString(data);
      var namespaces = determineNamespaces(document);

      context.expressions.forEach(function(expression) {
        var select = xpath.useNamespaces(namespaces);
        select(expression.match, document).forEach(function(node) {
        	console.log('%s: Matched %s: Replacing "%s" with "%s"', file, expression.match, node.firstChild.data, expression.value);
          node.firstChild.data = expression.value;
        });
      });

      fs.writeFile(file, document.toString(), 'utf-8', function(err) {
        if(err) throw err;
      });
    });
  });
}

function determineNamespaces(document) {
	var result = {};

	Object.keys(document.documentElement.attributes).forEach(function(key) {
		var attr = document.documentElement.attributes[key];
		result[attr.localName] = attr.value;
	});

	return result;
}

/**
 * Takes in arguments and determines if they are locations or match parameters
 *
 * @param {Array} argv an array of string arguments
 * @return {Object} result
 */
function determineArguments(argv) {
  var result = {
    expressions: [],
    locations: []
  };

  argv.forEach(function(value, index, array) {
    if(value.indexOf('=') > -1) {
      var parts = value.split('=');
      result.expressions.push({ match: parts[0], value: parts[1] });
    }
    else {
      result.locations.push(value);
    }
  });

  return result;
}

/**
 * Convert the given {@code locations} into a list of files
 *
 * @param {Array} locations
 * @return {Array} result
 */
function makeFileList(locations) {
  var result = [];

  locations.forEach(function(location) {
    pathutils.walkFiles(path.resolve(location), function(err, file) {
      result.push(file);
    });
  });

  return result;
}


text:
using namespace lldb_private;
using namespace lldb_private::line_editor;

// Workaround for what looks like an OS X-specific issue, but other platforms
// may benefit from something similar if issues arise.  The libedit library
// doesn't explicitly initialize the curses termcap library, which it gets away
// with until TERM is set to VT100 where it stumbles over an implementation
// assumption that may not exist on other platforms.  The setupterm() function
// would normally require headers that don't work gracefully in this context,
// so the function declaraction has been hoisted here.
#if defined(__APPLE__)
extern "C" {
int setupterm(char *term, int fildes, int *errret);
}
#define USE_SETUPTERM_WORKAROUND
#endif

// Editline uses careful cursor management to achieve the illusion of editing a
// multi-line block of text with a single line editor.  Preserving this
// illusion requires fairly careful management of cursor state.  Read and
// understand the relationship between DisplayInput(), MoveCursor(),
// SetCurrentLine(), and SaveEditedLine() before making changes.

#define ESCAPE "\x1b"
#define ANSI_FAINT ESCAPE "[2m"
#define ANSI_UNFAINT ESCAPE "[22m"
#define ANSI_CLEAR_BELOW ESCAPE "[J"
#define ANSI_CLEAR_RIGHT ESCAPE "[K"
#define ANSI_SET_COLUMN_N ESCAPE "[%dG"
#define ANSI_UP_N_ROWS ESCAPE "[%dA"
#define ANSI_DOWN_N_ROWS ESCAPE "[%dB"

#if LLDB_EDITLINE_USE_WCHAR

#define EditLineConstString(str) L##str
#define EditLineStringFormatSpec "%ls"

#else

#define EditLineConstString(str) str
#define EditLineStringFormatSpec "%s"

// use #defines so wide version functions and structs will resolve to old
// versions for case of libedit not built with wide char support
#define history_w history
#define history_winit history_init
#define history_wend history_end
#define HistoryW History
#define HistEventW HistEvent
#define LineInfoW LineInfo

#define el_wgets el_gets
#define el_wgetc el_getc
#define el_wpush el_push
#define el_wparse el_parse
#define el_wset el_set
#define el_wget el_get
#define el_wline el_line
#define el_winsertstr el_insertstr
#define el_wdeletestr el_deletestr

#endif // #if LLDB_EDITLINE_USE_WCHAR

bool IsOnlySpaces(const EditLineStringType &content) {
  for (wchar_t ch : content) {
    if (ch != EditLineCharType(' '))
      return false;
  }
  return true;
}

EditLineStringType CombineLines(const std::vector<EditLineStringType> &lines) {
  EditLineStringStreamType combined_stream;
  for (EditLineStringType line : lines) {
    combined_stream << line.c_str() << "\n";
  }
  return combined_stream.str();
}

std::vector<EditLineStringType> SplitLines(const EditLineStringType &input) {
  std::vector<EditLineStringType> result;
  size_t start = 0;
  while (start < input.length()) {
    size_t end = input.find('\n', start);
    if (end == std::string::npos) {
      result.insert(result.end(), input.substr(start));
      break;
    }
    result.insert(result.end(), input.substr(start, end - start));
    start = end + 1;
  }
  return result;
}

EditLineStringType FixIndentation(const EditLineStringType &line,
                                  int indent_correction) {
  if (indent_correction == 0)
    return line;
  if (indent_correction < 0)
    return line.substr(-indent_correction);
  return EditLineStringType(indent_correction, EditLineCharType(' ')) + line;
}

int GetIndentation(const EditLineStringType &line) {
  int space_count = 0;
  for (EditLineCharType ch : line) {
    if (ch != EditLineCharType(' '))
      break;
    ++space_count;
  }
  return space_count;
}

bool IsInputPending(FILE *file) {
  // FIXME: This will be broken on Windows if we ever re-enable Editline.  You
  // can't use select
  // on something that isn't a socket.  This will have to be re-written to not
  // use a FILE*, but instead use some kind of yet-to-be-created abstraction
  // that select-like functionality on non-socket objects.
  const int fd = fileno(file);
  SelectHelper select_helper;
  select_helper.SetTimeout(std::chrono::microseconds(0));
  select_helper.FDSetRead(fd);
  return select_helper.Select().Success();
}

namespace lldb_private {
namespace line_editor {
typedef std::weak_ptr<EditlineHistory> EditlineHistoryWP;

// EditlineHistory objects are sometimes shared between multiple Editline
// instances with the same program name.

class EditlineHistory {
private:
  // Use static GetHistory() function to get a EditlineHistorySP to one of
  // these objects
  EditlineHistory(const std::string &prefix, uint32_t size, bool unique_entries)
      : m_history(NULL), m_event(), m_prefix(prefix), m_path() {
    m_history = history_winit();
    history_w(m_history, &m_event, H_SETSIZE, size);
    if (unique_entries)
      history_w(m_history, &m_event, H_SETUNIQUE, 1);
  }

  const char *GetHistoryFilePath() {
    if (m_path.empty() && m_history && !m_prefix.empty()) {
      FileSpec parent_path{"~/.lldb", true};
      char history_path[PATH_MAX];
      if (!llvm::sys::fs::create_directory(parent_path.GetPath())) {
        snprintf(history_path, sizeof(history_path), "~/.lldb/%s-history",
                 m_prefix.c_str());
      } else {
        snprintf(history_path, sizeof(history_path), "~/%s-widehistory",
                 m_prefix.c_str());
      }
      m_path = FileSpec(history_path, true).GetPath();
    }
    if (m_path.empty())
      return NULL;
    return m_path.c_str();
  }

public:
  ~EditlineHistory() {
    Save();

    if (m_history) {
      history_wend(m_history);
      m_history = NULL;
    }
  }

  static EditlineHistorySP GetHistory(const std::string &prefix) {
    typedef std::map<std::string, EditlineHistoryWP> WeakHistoryMap;
    static std::recursive_mutex g_mutex;
    static WeakHistoryMap g_weak_map;
    std::lock_guard<std::recursive_mutex> guard(g_mutex);
    WeakHistoryMap::const_iterator pos = g_weak_map.find(prefix);
    EditlineHistorySP history_sp;
    if (pos != g_weak_map.end()) {
      history_sp = pos->second.lock();
      if (history_sp)
        return history_sp;
      g_weak_map.erase(pos);
    }
    history_sp.reset(new EditlineHistory(prefix, 800, true));
    g_weak_map[prefix] = history_sp;
    return history_sp;
  }

  bool IsValid() const { return m_history != NULL; }

  HistoryW *GetHistoryPtr() { return m_history; }

  void Enter(const EditLineCharType *line_cstr) {
    if (m_history)
      history_w(m_history, &m_event, H_ENTER, line_cstr);
  }

  bool Load() {
    if (m_history) {
      const char *path = GetHistoryFilePath();
      if (path) {
        history_w(m_history, &m_event, H_LOAD, path);
        return true;
      }
    }
    return false;
  }

  bool Save() {
    if (m_history) {
      const char *path = GetHistoryFilePath();
      if (path) {
        history_w(m_history, &m_event, H_SAVE, path);
        return true;
      }
    }
    return false;
  }

protected:
  HistoryW *m_history; // The history object
  HistEventW m_event;  // The history event needed to contain all history events
  std::string m_prefix; // The prefix name (usually the editline program name)
                        // to use when loading/saving history
  std::string m_path;   // Path to the history file
};
}
}

//------------------------------------------------------------------
// Editline private methods
//------------------------------------------------------------------

void Editline::SetBaseLineNumber(int line_number) {
  std::stringstream line_number_stream;
  line_number_stream << line_number;
  m_base_line_number = line_number;
  m_line_number_digits =
      std::max(3, (int)line_number_stream.str().length() + 1);
}

std::string Editline::PromptForIndex(int line_index) {
  bool use_line_numbers = m_multiline_enabled && m_base_line_number > 0;
  std::string prompt = m_set_prompt;
  if (use_line_numbers && prompt.length() == 0) {
    prompt = ": ";
  }
  std::string continuation_prompt = prompt;
  if (m_set_continuation_prompt.length() > 0) {
    continuation_prompt = m_set_continuation_prompt;

    // Ensure that both prompts are the same length through space padding
    while (continuation_prompt.length() < prompt.length()) {
      continuation_prompt += ' ';
    }
    while (prompt.length() < continuation_prompt.length()) {
      prompt += ' ';
    }
  }

  if (use_line_numbers) {
    StreamString prompt_stream;
    prompt_stream.Printf(
        "%*d%s", m_line_number_digits, m_base_line_number + line_index,
        (line_index == 0) ? prompt.c_str() : continuation_prompt.c_str());
    return std::move(prompt_stream.GetString());
  }
  return (line_index == 0) ? prompt : continuation_prompt;
}

void Editline::SetCurrentLine(int line_index) {
  m_current_line_index = line_index;
  m_current_prompt = PromptForIndex(line_index);
}

int Editline::GetPromptWidth() { return (int)PromptForIndex(0).length(); }

bool Editline::IsEmacs() {
  const char *editor;
  el_get(m_editline, EL_EDITOR, &editor);
  return editor[0] == 'e';
}

bool Editline::IsOnlySpaces() {
  const LineInfoW *info = el_wline(m_editline);
  for (const EditLineCharType *character = info->buffer;
       character < info->lastchar; character++) {
    if (*character != ' ')
      return false;
  }
  return true;
}

int Editline::GetLineIndexForLocation(CursorLocation location, int cursor_row) {
  int line = 0;
  if (location == CursorLocation::EditingPrompt ||
      location == CursorLocation::BlockEnd ||
      location == CursorLocation::EditingCursor) {
    for (unsigned index = 0; index < m_current_line_index; index++) {
      line += CountRowsForLine(m_input_lines[index]);
    }
    if (location == CursorLocation::EditingCursor) {
      line += cursor_row;
    } else if (location == CursorLocation::BlockEnd) {
      for (unsigned index = m_current_line_index; index < m_input_lines.size();
           index++) {
        line += CountRowsForLine(m_input_lines[index]);
      }
      --line;
    }
  }
  return line;
}

void Editline::MoveCursor(CursorLocation from, CursorLocation to) {
  const LineInfoW *info = el_wline(m_editline);
  int editline_cursor_position =
      (int)((info->cursor - info->buffer) + GetPromptWidth());
  int editline_cursor_row = editline_cursor_position / m_terminal_width;

  // Determine relative starting and ending lines
  int fromLine = GetLineIndexForLocation(from, editline_cursor_row);
  int toLine = GetLineIndexForLocation(to, editline_cursor_row);
  if (toLine != fromLine) {
    fprintf(m_output_file,
            (toLine > fromLine) ? ANSI_DOWN_N_ROWS : ANSI_UP_N_ROWS,
            std::abs(toLine - fromLine));
  }

  // Determine target column
  int toColumn = 1;
  if (to == CursorLocation::EditingCursor) {
    toColumn =
        editline_cursor_position - (editline_cursor_row * m_terminal_width) + 1;
  } else if (to == CursorLocation::BlockEnd && !m_input_lines.empty()) {
    toColumn =
        ((m_input_lines[m_input_lines.size() - 1].length() + GetPromptWidth()) %
         80) +
        1;
  }
  fprintf(m_output_file, ANSI_SET_COLUMN_N, toColumn);
}

void Editline::DisplayInput(int firstIndex) {
  fprintf(m_output_file, ANSI_SET_COLUMN_N ANSI_CLEAR_BELOW, 1);
  int line_count = (int)m_input_lines.size();
  const char *faint = m_color_prompts ? ANSI_FAINT : "";
  const char *unfaint = m_color_prompts ? ANSI_UNFAINT : "";

  for (int index = firstIndex; index < line_count; index++) {
    fprintf(m_output_file, "%s"
                           "%s"
                           "%s" EditLineStringFormatSpec " ",
            faint, PromptForIndex(index).c_str(), unfaint,
            m_input_lines[index].c_str());
    if (index < line_count - 1)
      fprintf(m_output_file, "\n");
  }
}

int Editline::CountRowsForLine(const EditLineStringType &content) {
  auto prompt =
      PromptForIndex(0); // Prompt width is constant during an edit session
  int line_length = (int)(content.length() + prompt.length());
  return (line_length / m_terminal_width) + 1;
}

void Editline::SaveEditedLine() {
  const LineInfoW *info = el_wline(m_editline);
  m_input_lines[m_current_line_index] =
      EditLineStringType(info->buffer, info->lastchar - info->buffer);
}

StringList Editline::GetInputAsStringList(int line_count) {
  StringList lines;
  for (EditLineStringType line : m_input_lines) {
    if (line_count == 0)
      break;
#if LLDB_EDITLINE_USE_WCHAR
    lines.AppendString(m_utf8conv.to_bytes(line));
#else
    lines.AppendString(line);
#endif
    --line_count;
  }
  return lines;
}

unsigned char Editline::RecallHistory(bool earlier) {
  if (!m_history_sp || !m_history_sp->IsValid())
    return CC_ERROR;

  HistoryW *pHistory = m_history_sp->GetHistoryPtr();
  HistEventW history_event;
  std::vector<EditLineStringType> new_input_lines;

  // Treat moving from the "live" entry differently
  if (!m_in_history) {
    if (earlier == false)
      return CC_ERROR; // Can't go newer than the "live" entry
    if (history_w(pHistory, &history_event, H_FIRST) == -1)
      return CC_ERROR;

    // Save any edits to the "live" entry in case we return by moving forward
    // in history (it would be more bash-like to save over any current entry,
    // but libedit doesn't offer the ability to add entries anywhere except the
    // end.)
    SaveEditedLine();
    m_live_history_lines = m_input_lines;
    m_in_history = true;
  } else {
    if (history_w(pHistory, &history_event, earlier ? H_NEXT : H_PREV) == -1) {
      // Can't move earlier than the earliest entry
      if (earlier)
        return CC_ERROR;

      // ... but moving to newer than the newest yields the "live" entry
      new_input_lines = m_live_history_lines;
      m_in_history = false;
    }
  }

  // If we're pulling the lines from history, split them apart
  if (m_in_history)
    new_input_lines = SplitLines(history_event.str);

  // Erase the current edit session and replace it with a new one
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
  m_input_lines = new_input_lines;
  DisplayInput();

  // Prepare to edit the last line when moving to previous entry, or the first
  // line when moving to next entry
  SetCurrentLine(m_current_line_index =
                     earlier ? (int)m_input_lines.size() - 1 : 0);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
  return CC_NEWLINE;
}

int Editline::GetCharacter(EditLineGetCharType *c) {
  const LineInfoW *info = el_wline(m_editline);

  // Paint a faint version of the desired prompt over the version libedit draws
  // (will only be requested if colors are supported)
  if (m_needs_prompt_repaint) {
    MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);
    fprintf(m_output_file, "%s"
                           "%s"
                           "%s",
            ANSI_FAINT, Prompt(), ANSI_UNFAINT);
    MoveCursor(CursorLocation::EditingPrompt, CursorLocation::EditingCursor);
    m_needs_prompt_repaint = false;
  }

  if (m_multiline_enabled) {
    // Detect when the number of rows used for this input line changes due to
    // an edit
    int lineLength = (int)((info->lastchar - info->buffer) + GetPromptWidth());
    int new_line_rows = (lineLength / m_terminal_width) + 1;
    if (m_current_line_rows != -1 && new_line_rows != m_current_line_rows) {
      // Respond by repainting the current state from this line on
      MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);
      SaveEditedLine();
      DisplayInput(m_current_line_index);
      MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
    }
    m_current_line_rows = new_line_rows;
  }

  // Read an actual character
  while (true) {
    lldb::ConnectionStatus status = lldb::eConnectionStatusSuccess;
    char ch = 0;

    // This mutex is locked by our caller (GetLine). Unlock it while we read a
    // character (blocking operation), so we do not hold the mutex
    // indefinitely. This gives a chance for someone to interrupt us. After
    // Read returns, immediately lock the mutex again and check if we were
    // interrupted.
    m_output_mutex.unlock();
    int read_count = m_input_connection.Read(&ch, 1, llvm::None, status, NULL);
    m_output_mutex.lock();
    if (m_editor_status == EditorStatus::Interrupted) {
      while (read_count > 0 && status == lldb::eConnectionStatusSuccess)
        read_count = m_input_connection.Read(&ch, 1, llvm::None, status, NULL);
      lldbassert(status == lldb::eConnectionStatusInterrupted);
      return 0;
    }

    if (read_count) {
      if (CompleteCharacter(ch, *c))
        return 1;
    } else {
      switch (status) {
      case lldb::eConnectionStatusSuccess: // Success
        break;

      case lldb::eConnectionStatusInterrupted:
        lldbassert(0 && "Interrupts should have been handled above.");

      case lldb::eConnectionStatusError:        // Check GetError() for details
      case lldb::eConnectionStatusTimedOut:     // Request timed out
      case lldb::eConnectionStatusEndOfFile:    // End-of-file encountered
      case lldb::eConnectionStatusNoConnection: // No connection
      case lldb::eConnectionStatusLostConnection: // Lost connection while
                                                  // connected to a valid
                                                  // connection
        m_editor_status = EditorStatus::EndOfInput;
        return 0;
      }
    }
  }
}

const char *Editline::Prompt() {
  if (m_color_prompts)
    m_needs_prompt_repaint = true;
  return m_current_prompt.c_str();
}

unsigned char Editline::BreakLineCommand(int ch) {
  // Preserve any content beyond the cursor, truncate and save the current line
  const LineInfoW *info = el_wline(m_editline);
  auto current_line =
      EditLineStringType(info->buffer, info->cursor - info->buffer);
  auto new_line_fragment =
      EditLineStringType(info->cursor, info->lastchar - info->cursor);
  m_input_lines[m_current_line_index] = current_line;

  // Ignore whitespace-only extra fragments when breaking a line
  if (::IsOnlySpaces(new_line_fragment))
    new_line_fragment = EditLineConstString("");

  // Establish the new cursor position at the start of a line when inserting a
  // line break
  m_revert_cursor_index = 0;

  // Don't perform automatic formatting when pasting
  if (!IsInputPending(m_input_file)) {
    // Apply smart indentation
    if (m_fix_indentation_callback) {
      StringList lines = GetInputAsStringList(m_current_line_index + 1);
#if LLDB_EDITLINE_USE_WCHAR
      lines.AppendString(m_utf8conv.to_bytes(new_line_fragment));
#else
      lines.AppendString(new_line_fragment);
#endif

      int indent_correction = m_fix_indentation_callback(
          this, lines, 0, m_fix_indentation_callback_baton);
      new_line_fragment = FixIndentation(new_line_fragment, indent_correction);
      m_revert_cursor_index = GetIndentation(new_line_fragment);
    }
  }

  // Insert the new line and repaint everything from the split line on down
  m_input_lines.insert(m_input_lines.begin() + m_current_line_index + 1,
                       new_line_fragment);
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);
  DisplayInput(m_current_line_index);

  // Reposition the cursor to the right line and prepare to edit the new line
  SetCurrentLine(m_current_line_index + 1);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
  return CC_NEWLINE;
}

unsigned char Editline::EndOrAddLineCommand(int ch) {
  // Don't perform end of input detection when pasting, always treat this as a
  // line break
  if (IsInputPending(m_input_file)) {
    return BreakLineCommand(ch);
  }

  // Save any edits to this line
  SaveEditedLine();

  // If this is the end of the last line, consider whether to add a line
  // instead
  const LineInfoW *info = el_wline(m_editline);
  if (m_current_line_index == m_input_lines.size() - 1 &&
      info->cursor == info->lastchar) {
    if (m_is_input_complete_callback) {
      auto lines = GetInputAsStringList();
      if (!m_is_input_complete_callback(this, lines,
                                        m_is_input_complete_callback_baton)) {
        return BreakLineCommand(ch);
      }

      // The completion test is allowed to change the input lines when complete
      m_input_lines.clear();
      for (unsigned index = 0; index < lines.GetSize(); index++) {
#if LLDB_EDITLINE_USE_WCHAR
        m_input_lines.insert(m_input_lines.end(),
                             m_utf8conv.from_bytes(lines[index]));
#else
        m_input_lines.insert(m_input_lines.end(), lines[index]);
#endif
      }
    }
  }
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockEnd);
  fprintf(m_output_file, "\n");
  m_editor_status = EditorStatus::Complete;
  return CC_NEWLINE;
}

unsigned char Editline::DeleteNextCharCommand(int ch) {
  LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline));

  // Just delete the next character normally if possible
  if (info->cursor < info->lastchar) {
    info->cursor++;
    el_deletestr(m_editline, 1);
    return CC_REFRESH;
  }

  // Fail when at the end of the last line, except when ^D is pressed on the
  // line is empty, in which case it is treated as EOF
  if (m_current_line_index == m_input_lines.size() - 1) {
    if (ch == 4 && info->buffer == info->lastchar) {
      fprintf(m_output_file, "^D\n");
      m_editor_status = EditorStatus::EndOfInput;
      return CC_EOF;
    }
    return CC_ERROR;
  }

  // Prepare to combine this line with the one below
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);

  // Insert the next line of text at the cursor and restore the cursor position
  const EditLineCharType *cursor = info->cursor;
  el_winsertstr(m_editline, m_input_lines[m_current_line_index + 1].c_str());
  info->cursor = cursor;
  SaveEditedLine();

  // Delete the extra line
  m_input_lines.erase(m_input_lines.begin() + m_current_line_index + 1);

  // Clear and repaint from this line on down
  DisplayInput(m_current_line_index);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
  return CC_REFRESH;
}

unsigned char Editline::DeletePreviousCharCommand(int ch) {
  LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline));

  // Just delete the previous character normally when not at the start of a
  // line
  if (info->cursor > info->buffer) {
    el_deletestr(m_editline, 1);
    return CC_REFRESH;
  }

  // No prior line and no prior character?  Let the user know
  if (m_current_line_index == 0)
    return CC_ERROR;

  // No prior character, but prior line?  Combine with the line above
  SaveEditedLine();
  SetCurrentLine(m_current_line_index - 1);
  auto priorLine = m_input_lines[m_current_line_index];
  m_input_lines.erase(m_input_lines.begin() + m_current_line_index);
  m_input_lines[m_current_line_index] =
      priorLine + m_input_lines[m_current_line_index];

  // Repaint from the new line down
  fprintf(m_output_file, ANSI_UP_N_ROWS ANSI_SET_COLUMN_N,
          CountRowsForLine(priorLine), 1);
  DisplayInput(m_current_line_index);

  // Put the cursor back where libedit expects it to be before returning to
  // editing by telling libedit about the newly inserted text
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
  el_winsertstr(m_editline, priorLine.c_str());
  return CC_REDISPLAY;
}

unsigned char Editline::PreviousLineCommand(int ch) {
  SaveEditedLine();

  if (m_current_line_index == 0) {
    return RecallHistory(true);
  }

  // Start from a known location
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);

  // Treat moving up from a blank last line as a deletion of that line
  if (m_current_line_index == m_input_lines.size() - 1 && IsOnlySpaces()) {
    m_input_lines.erase(m_input_lines.begin() + m_current_line_index);
    fprintf(m_output_file, ANSI_CLEAR_BELOW);
  }

  SetCurrentLine(m_current_line_index - 1);
  fprintf(m_output_file, ANSI_UP_N_ROWS ANSI_SET_COLUMN_N,
          CountRowsForLine(m_input_lines[m_current_line_index]), 1);
  return CC_NEWLINE;
}

unsigned char Editline::NextLineCommand(int ch) {
  SaveEditedLine();

  // Handle attempts to move down from the last line
  if (m_current_line_index == m_input_lines.size() - 1) {
    // Don't add an extra line if the existing last line is blank, move through
    // history instead
    if (IsOnlySpaces()) {
      return RecallHistory(false);
    }

    // Determine indentation for the new line
    int indentation = 0;
    if (m_fix_indentation_callback) {
      StringList lines = GetInputAsStringList();
      lines.AppendString("");
      indentation = m_fix_indentation_callback(
          this, lines, 0, m_fix_indentation_callback_baton);
    }
    m_input_lines.insert(
        m_input_lines.end(),
        EditLineStringType(indentation, EditLineCharType(' ')));
  }

  // Move down past the current line using newlines to force scrolling if
  // needed
  SetCurrentLine(m_current_line_index + 1);
  const LineInfoW *info = el_wline(m_editline);
  int cursor_position = (int)((info->cursor - info->buffer) + GetPromptWidth());
  int cursor_row = cursor_position / m_terminal_width;
  for (int line_count = 0; line_count < m_current_line_rows - cursor_row;
       line_count++) {
    fprintf(m_output_file, "\n");
  }
  return CC_NEWLINE;
}

unsigned char Editline::PreviousHistoryCommand(int ch) {
  SaveEditedLine();

  return RecallHistory(true);
}

unsigned char Editline::NextHistoryCommand(int ch) {
  SaveEditedLine();

  return RecallHistory(false);
}

unsigned char Editline::FixIndentationCommand(int ch) {
  if (!m_fix_indentation_callback)
    return CC_NORM;

  // Insert the character typed before proceeding
  EditLineCharType inserted[] = {(EditLineCharType)ch, 0};
  el_winsertstr(m_editline, inserted);
  LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline));
  int cursor_position = info->cursor - info->buffer;

  // Save the edits and determine the correct indentation level
  SaveEditedLine();
  StringList lines = GetInputAsStringList(m_current_line_index + 1);
  int indent_correction = m_fix_indentation_callback(
      this, lines, cursor_position, m_fix_indentation_callback_baton);

  // If it is already correct no special work is needed
  if (indent_correction == 0)
    return CC_REFRESH;

  // Change the indentation level of the line
  std::string currentLine = lines.GetStringAtIndex(m_current_line_index);
  if (indent_correction > 0) {
    currentLine = currentLine.insert(0, indent_correction, ' ');
  } else {
    currentLine = currentLine.erase(0, -indent_correction);
  }
#if LLDB_EDITLINE_USE_WCHAR
  m_input_lines[m_current_line_index] = m_utf8conv.from_bytes(currentLine);
#else
  m_input_lines[m_current_line_index] = currentLine;
#endif

  // Update the display to reflect the change
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::EditingPrompt);
  DisplayInput(m_current_line_index);

  // Reposition the cursor back on the original line and prepare to restart
  // editing with a new cursor position
  SetCurrentLine(m_current_line_index);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
  m_revert_cursor_index = cursor_position + indent_correction;
  return CC_NEWLINE;
}

unsigned char Editline::RevertLineCommand(int ch) {
  el_winsertstr(m_editline, m_input_lines[m_current_line_index].c_str());
  if (m_revert_cursor_index >= 0) {
    LineInfoW *info = const_cast<LineInfoW *>(el_wline(m_editline));
    info->cursor = info->buffer + m_revert_cursor_index;
    if (info->cursor > info->lastchar) {
      info->cursor = info->lastchar;
    }
    m_revert_cursor_index = -1;
  }
  return CC_REFRESH;
}

unsigned char Editline::BufferStartCommand(int ch) {
  SaveEditedLine();
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
  SetCurrentLine(0);
  m_revert_cursor_index = 0;
  return CC_NEWLINE;
}

unsigned char Editline::BufferEndCommand(int ch) {
  SaveEditedLine();
  MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockEnd);
  SetCurrentLine((int)m_input_lines.size() - 1);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingPrompt);
  return CC_NEWLINE;
}

unsigned char Editline::TabCommand(int ch) {
  if (m_completion_callback == nullptr)
    return CC_ERROR;

  const LineInfo *line_info = el_line(m_editline);
  StringList completions;
  int page_size = 40;

  const int num_completions = m_completion_callback(
      line_info->buffer, line_info->cursor, line_info->lastchar,
      0,  // Don't skip any matches (start at match zero)
      -1, // Get all the matches
      completions, m_completion_callback_baton);

  if (num_completions == 0)
    return CC_ERROR;
  //    if (num_completions == -1)
  //    {
  //        el_insertstr (m_editline, m_completion_key);
  //        return CC_REDISPLAY;
  //    }
  //    else
  if (num_completions == -2) {
    // Replace the entire line with the first string...
    el_deletestr(m_editline, line_info->cursor - line_info->buffer);
    el_insertstr(m_editline, completions.GetStringAtIndex(0));
    return CC_REDISPLAY;
  }

  // If we get a longer match display that first.
  const char *completion_str = completions.GetStringAtIndex(0);
  if (completion_str != nullptr && *completion_str != '\0') {
    el_insertstr(m_editline, completion_str);
    return CC_REDISPLAY;
  }

  if (num_completions > 1) {
    int num_elements = num_completions + 1;
    fprintf(m_output_file, "\n" ANSI_CLEAR_BELOW "Available completions:");
    if (num_completions < page_size) {
      for (int i = 1; i < num_elements; i++) {
        completion_str = completions.GetStringAtIndex(i);
        fprintf(m_output_file, "\n\t%s", completion_str);
      }
      fprintf(m_output_file, "\n");
    } else {
      int cur_pos = 1;
      char reply;
      int got_char;
      while (cur_pos < num_elements) {
        int endpoint = cur_pos + page_size;
        if (endpoint > num_elements)
          endpoint = num_elements;
        for (; cur_pos < endpoint; cur_pos++) {
          completion_str = completions.GetStringAtIndex(cur_pos);
          fprintf(m_output_file, "\n\t%s", completion_str);
        }

        if (cur_pos >= num_elements) {
          fprintf(m_output_file, "\n");
          break;
        }

        fprintf(m_output_file, "\nMore (Y/n/a): ");
        reply = 'n';
        got_char = el_getc(m_editline, &reply);
        if (got_char == -1 || reply == 'n')
          break;
        if (reply == 'a')
          page_size = num_elements - cur_pos;
      }
    }
    DisplayInput();
    MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
  }
  return CC_REDISPLAY;
}

void Editline::ConfigureEditor(bool multiline) {
  if (m_editline && m_multiline_enabled == multiline)
    return;
  m_multiline_enabled = multiline;

  if (m_editline) {
    // Disable edit mode to stop the terminal from flushing all input during
    // the call to el_end() since we expect to have multiple editline instances
    // in this program.
    el_set(m_editline, EL_EDITMODE, 0);
    el_end(m_editline);
  }

  m_editline =
      el_init(m_editor_name.c_str(), m_input_file, m_output_file, m_error_file);
  TerminalSizeChanged();

  if (m_history_sp && m_history_sp->IsValid()) {
    m_history_sp->Load();
    el_wset(m_editline, EL_HIST, history, m_history_sp->GetHistoryPtr());
  }
  el_set(m_editline, EL_CLIENTDATA, this);
  el_set(m_editline, EL_SIGNAL, 0);
  el_set(m_editline, EL_EDITOR, "emacs");
  el_set(m_editline, EL_PROMPT,
         (EditlinePromptCallbackType)([](EditLine *editline) {
           return Editline::InstanceFor(editline)->Prompt();
         }));

  el_wset(m_editline, EL_GETCFN, (EditlineGetCharCallbackType)([](
                                     EditLine *editline, EditLineGetCharType *c) {
            return Editline::InstanceFor(editline)->GetCharacter(c);
          }));

  // Commands used for multiline support, registered whether or not they're
  // used
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-break-line"),
          EditLineConstString("Insert a line break"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->BreakLineCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-end-or-add-line"),
          EditLineConstString("End editing or continue when incomplete"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->EndOrAddLineCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-delete-next-char"),
          EditLineConstString("Delete next character"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->DeleteNextCharCommand(ch);
          }));
  el_wset(
      m_editline, EL_ADDFN, EditLineConstString("lldb-delete-previous-char"),
      EditLineConstString("Delete previous character"),
      (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
        return Editline::InstanceFor(editline)->DeletePreviousCharCommand(ch);
      }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-previous-line"),
          EditLineConstString("Move to previous line"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->PreviousLineCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-next-line"),
          EditLineConstString("Move to next line"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->NextLineCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-previous-history"),
          EditLineConstString("Move to previous history"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->PreviousHistoryCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-next-history"),
          EditLineConstString("Move to next history"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->NextHistoryCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-buffer-start"),
          EditLineConstString("Move to start of buffer"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->BufferStartCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-buffer-end"),
          EditLineConstString("Move to end of buffer"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->BufferEndCommand(ch);
          }));
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-fix-indentation"),
          EditLineConstString("Fix line indentation"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->FixIndentationCommand(ch);
          }));

  // Register the complete callback under two names for compatibility with
  // older clients using custom .editrc files (largely because libedit has a
  // bad bug where if you have a bind command that tries to bind to a function
  // name that doesn't exist, it can corrupt the heap and crash your process
  // later.)
  EditlineCommandCallbackType complete_callback = [](EditLine *editline,
                                                     int ch) {
    return Editline::InstanceFor(editline)->TabCommand(ch);
  };
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-complete"),
          EditLineConstString("Invoke completion"), complete_callback);
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb_complete"),
          EditLineConstString("Invoke completion"), complete_callback);

  // General bindings we don't mind being overridden
  if (!multiline) {
    el_set(m_editline, EL_BIND, "^r", "em-inc-search-prev",
           NULL); // Cycle through backwards search, entering string
  }
  el_set(m_editline, EL_BIND, "^w", "ed-delete-prev-word",
         NULL); // Delete previous word, behave like bash in emacs mode
  el_set(m_editline, EL_BIND, "\t", "lldb-complete",
         NULL); // Bind TAB to auto complete

  // Allow user-specific customization prior to registering bindings we
  // absolutely require
  el_source(m_editline, NULL);

  // Register an internal binding that external developers shouldn't use
  el_wset(m_editline, EL_ADDFN, EditLineConstString("lldb-revert-line"),
          EditLineConstString("Revert line to saved state"),
          (EditlineCommandCallbackType)([](EditLine *editline, int ch) {
            return Editline::InstanceFor(editline)->RevertLineCommand(ch);
          }));

  // Register keys that perform auto-indent correction
  if (m_fix_indentation_callback && m_fix_indentation_callback_chars) {
    char bind_key[2] = {0, 0};
    const char *indent_chars = m_fix_indentation_callback_chars;
    while (*indent_chars) {
      bind_key[0] = *indent_chars;
      el_set(m_editline, EL_BIND, bind_key, "lldb-fix-indentation", NULL);
      ++indent_chars;
    }
  }

  // Multi-line editor bindings
  if (multiline) {
    el_set(m_editline, EL_BIND, "\n", "lldb-end-or-add-line", NULL);
    el_set(m_editline, EL_BIND, "\r", "lldb-end-or-add-line", NULL);
    el_set(m_editline, EL_BIND, ESCAPE "\n", "lldb-break-line", NULL);
    el_set(m_editline, EL_BIND, ESCAPE "\r", "lldb-break-line", NULL);
    el_set(m_editline, EL_BIND, "^p", "lldb-previous-line", NULL);
    el_set(m_editline, EL_BIND, "^n", "lldb-next-line", NULL);
    el_set(m_editline, EL_BIND, "^?", "lldb-delete-previous-char", NULL);
    el_set(m_editline, EL_BIND, "^d", "lldb-delete-next-char", NULL);
    el_set(m_editline, EL_BIND, ESCAPE "[3~", "lldb-delete-next-char", NULL);
    el_set(m_editline, EL_BIND, ESCAPE "[\\^", "lldb-revert-line", NULL);

    // Editor-specific bindings
    if (IsEmacs()) {
      el_set(m_editline, EL_BIND, ESCAPE "<", "lldb-buffer-start", NULL);
      el_set(m_editline, EL_BIND, ESCAPE ">", "lldb-buffer-end", NULL);
      el_set(m_editline, EL_BIND, ESCAPE "[A", "lldb-previous-line", NULL);
      el_set(m_editline, EL_BIND, ESCAPE "[B", "lldb-next-line", NULL);
      el_set(m_editline, EL_BIND, ESCAPE ESCAPE "[A", "lldb-previous-history",
             NULL);
      el_set(m_editline, EL_BIND, ESCAPE ESCAPE "[B", "lldb-next-history",
             NULL);
      el_set(m_editline, EL_BIND, ESCAPE "[1;3A", "lldb-previous-history",
             NULL);
      el_set(m_editline, EL_BIND, ESCAPE "[1;3B", "lldb-next-history", NULL);
    } else {
      el_set(m_editline, EL_BIND, "^H", "lldb-delete-previous-char", NULL);

      el_set(m_editline, EL_BIND, "-a", ESCAPE "[A", "lldb-previous-line",
             NULL);
      el_set(m_editline, EL_BIND, "-a", ESCAPE "[B", "lldb-next-line", NULL);
      el_set(m_editline, EL_BIND, "-a", "x", "lldb-delete-next-char", NULL);
      el_set(m_editline, EL_BIND, "-a", "^H", "lldb-delete-previous-char",
             NULL);
      el_set(m_editline, EL_BIND, "-a", "^?", "lldb-delete-previous-char",
             NULL);

      // Escape is absorbed exiting edit mode, so re-register important
      // sequences without the prefix
      el_set(m_editline, EL_BIND, "-a", "[A", "lldb-previous-line", NULL);
      el_set(m_editline, EL_BIND, "-a", "[B", "lldb-next-line", NULL);
      el_set(m_editline, EL_BIND, "-a", "[\\^", "lldb-revert-line", NULL);
    }
  }
}

//------------------------------------------------------------------
// Editline public methods
//------------------------------------------------------------------

Editline *Editline::InstanceFor(EditLine *editline) {
  Editline *editor;
  el_get(editline, EL_CLIENTDATA, &editor);
  return editor;
}

Editline::Editline(const char *editline_name, FILE *input_file,
                   FILE *output_file, FILE *error_file, bool color_prompts)
    : m_editor_status(EditorStatus::Complete), m_color_prompts(color_prompts),
      m_input_file(input_file), m_output_file(output_file),
      m_error_file(error_file), m_input_connection(fileno(input_file), false) {
  // Get a shared history instance
  m_editor_name = (editline_name == nullptr) ? "lldb-tmp" : editline_name;
  m_history_sp = EditlineHistory::GetHistory(m_editor_name);

#ifdef USE_SETUPTERM_WORKAROUND
  if (m_output_file) {
    const int term_fd = fileno(m_output_file);
    if (term_fd != -1) {
      static std::mutex *g_init_terminal_fds_mutex_ptr = nullptr;
      static std::set<int> *g_init_terminal_fds_ptr = nullptr;
      static llvm::once_flag g_once_flag;
      llvm::call_once(g_once_flag, [&]() {
        g_init_terminal_fds_mutex_ptr =
            new std::mutex(); // NOTE: Leak to avoid C++ destructor chain issues
        g_init_terminal_fds_ptr = new std::set<int>(); // NOTE: Leak to avoid
                                                       // C++ destructor chain
                                                       // issues
      });

      // We must make sure to initialize the terminal a given file descriptor
      // only once. If we do this multiple times, we start leaking memory.
      std::lock_guard<std::mutex> guard(*g_init_terminal_fds_mutex_ptr);
      if (g_init_terminal_fds_ptr->find(term_fd) ==
          g_init_terminal_fds_ptr->end()) {
        g_init_terminal_fds_ptr->insert(term_fd);
        setupterm((char *)0, term_fd, (int *)0);
      }
    }
  }
#endif
}

Editline::~Editline() {
  if (m_editline) {
    // Disable edit mode to stop the terminal from flushing all input during
    // the call to el_end() since we expect to have multiple editline instances
    // in this program.
    el_set(m_editline, EL_EDITMODE, 0);
    el_end(m_editline);
    m_editline = nullptr;
  }

  // EditlineHistory objects are sometimes shared between multiple Editline
  // instances with the same program name. So just release our shared pointer
  // and if we are the last owner, it will save the history to the history save
  // file automatically.
  m_history_sp.reset();
}

void Editline::SetPrompt(const char *prompt) {
  m_set_prompt = prompt == nullptr ? "" : prompt;
}

void Editline::SetContinuationPrompt(const char *continuation_prompt) {
  m_set_continuation_prompt =
      continuation_prompt == nullptr ? "" : continuation_prompt;
}

void Editline::TerminalSizeChanged() {
  if (m_editline != nullptr) {
    el_resize(m_editline);
    int columns;
    // Despite the man page claiming non-zero indicates success, it's actually
    // zero
    if (el_get(m_editline, EL_GETTC, "co", &columns) == 0) {
      m_terminal_width = columns;
      if (m_current_line_rows != -1) {
        const LineInfoW *info = el_wline(m_editline);
        int lineLength =
            (int)((info->lastchar - info->buffer) + GetPromptWidth());
        m_current_line_rows = (lineLength / columns) + 1;
      }
    } else {
      m_terminal_width = INT_MAX;
      m_current_line_rows = 1;
    }
  }
}

const char *Editline::GetPrompt() { return m_set_prompt.c_str(); }

uint32_t Editline::GetCurrentLine() { return m_current_line_index; }

bool Editline::Interrupt() {
  bool result = true;
  std::lock_guard<std::mutex> guard(m_output_mutex);
  if (m_editor_status == EditorStatus::Editing) {
    fprintf(m_output_file, "^C\n");
    result = m_input_connection.InterruptRead();
  }
  m_editor_status = EditorStatus::Interrupted;
  return result;
}

bool Editline::Cancel() {
  bool result = true;
  std::lock_guard<std::mutex> guard(m_output_mutex);
  if (m_editor_status == EditorStatus::Editing) {
    MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
    fprintf(m_output_file, ANSI_CLEAR_BELOW);
    result = m_input_connection.InterruptRead();
  }
  m_editor_status = EditorStatus::Interrupted;
  return result;
}

void Editline::SetAutoCompleteCallback(CompleteCallbackType callback,
                                       void *baton) {
  m_completion_callback = callback;
  m_completion_callback_baton = baton;
}

void Editline::SetIsInputCompleteCallback(IsInputCompleteCallbackType callback,
                                          void *baton) {
  m_is_input_complete_callback = callback;
  m_is_input_complete_callback_baton = baton;
}

bool Editline::SetFixIndentationCallback(FixIndentationCallbackType callback,
                                         void *baton,
                                         const char *indent_chars) {
  m_fix_indentation_callback = callback;
  m_fix_indentation_callback_baton = baton;
  m_fix_indentation_callback_chars = indent_chars;
  return false;
}

bool Editline::GetLine(std::string &line, bool &interrupted) {
  ConfigureEditor(false);
  m_input_lines = std::vector<EditLineStringType>();
  m_input_lines.insert(m_input_lines.begin(), EditLineConstString(""));

  std::lock_guard<std::mutex> guard(m_output_mutex);

  lldbassert(m_editor_status != EditorStatus::Editing);
  if (m_editor_status == EditorStatus::Interrupted) {
    m_editor_status = EditorStatus::Complete;
    interrupted = true;
    return true;
  }

  SetCurrentLine(0);
  m_in_history = false;
  m_editor_status = EditorStatus::Editing;
  m_revert_cursor_index = -1;

  int count;
  auto input = el_wgets(m_editline, &count);

  interrupted = m_editor_status == EditorStatus::Interrupted;
  if (!interrupted) {
    if (input == nullptr) {
      fprintf(m_output_file, "\n");
      m_editor_status = EditorStatus::EndOfInput;
    } else {
      m_history_sp->Enter(input);
#if LLDB_EDITLINE_USE_WCHAR
      line = m_utf8conv.to_bytes(SplitLines(input)[0]);
#else
      line = SplitLines(input)[0];
#endif
      m_editor_status = EditorStatus::Complete;
    }
  }
  return m_editor_status != EditorStatus::EndOfInput;
}

bool Editline::GetLines(int first_line_number, StringList &lines,
                        bool &interrupted) {
  ConfigureEditor(true);

  // Print the initial input lines, then move the cursor back up to the start
  // of input
  SetBaseLineNumber(first_line_number);
  m_input_lines = std::vector<EditLineStringType>();
  m_input_lines.insert(m_input_lines.begin(), EditLineConstString(""));

  std::lock_guard<std::mutex> guard(m_output_mutex);
  // Begin the line editing loop
  DisplayInput();
  SetCurrentLine(0);
  MoveCursor(CursorLocation::BlockEnd, CursorLocation::BlockStart);
  m_editor_status = EditorStatus::Editing;
  m_in_history = false;

  m_revert_cursor_index = -1;
  while (m_editor_status == EditorStatus::Editing) {
    int count;
    m_current_line_rows = -1;
    el_wpush(m_editline, EditLineConstString(
                             "\x1b[^")); // Revert to the existing line content
    el_wgets(m_editline, &count);
  }

  interrupted = m_editor_status == EditorStatus::Interrupted;
  if (!interrupted) {
    // Save the completed entry in history before returning
    m_history_sp->Enter(CombineLines(m_input_lines).c_str());

    lines = GetInputAsStringList();
  }
  return m_editor_status != EditorStatus::EndOfInput;
}

void Editline::PrintAsync(Stream *stream, const char *s, size_t len) {
  std::lock_guard<std::mutex> guard(m_output_mutex);
  if (m_editor_status == EditorStatus::Editing) {
    MoveCursor(CursorLocation::EditingCursor, CursorLocation::BlockStart);
    fprintf(m_output_file, ANSI_CLEAR_BELOW);
  }
  stream->Write(s, len);
  stream->Flush();
  if (m_editor_status == EditorStatus::Editing) {
    DisplayInput();
    MoveCursor(CursorLocation::BlockEnd, CursorLocation::EditingCursor);
  }
}

bool Editline::CompleteCharacter(char ch, EditLineGetCharType &out) {
#if !LLDB_EDITLINE_USE_WCHAR
  if (ch == (char)EOF)
    return false;

  out = (unsigned char)ch;
  return true;
#else
  std::codecvt_utf8<wchar_t> cvt;
  llvm::SmallString<4> input;
  for (;;) {
    const char *from_next;
    wchar_t *to_next;
    std::mbstate_t state = std::mbstate_t();
    input.push_back(ch);
    switch (cvt.in(state, input.begin(), input.end(), from_next, &out, &out + 1,
                   to_next)) {
    case std::codecvt_base::ok:
      return out != WEOF;

    case std::codecvt_base::error:
    case std::codecvt_base::noconv:
      return false;

    case std::codecvt_base::partial:
      lldb::ConnectionStatus status;
      size_t read_count = m_input_connection.Read(
          &ch, 1, std::chrono::seconds(0), status, nullptr);
      if (read_count == 0)
        return false;
      break;
    }
  }
#endif
}


text:
<?php

namespace Assely\Menu;

use Illuminate\Support\ServiceProvider;

class MenuServiceProvider extends ServiceProvider
{
    /**
     * Register menu services.
     *
     * @return void
     */
    public function register()
    {
        $this->registerMenusCollection();

        $this->registerMenuFactory();
    }

    /**
     * Register collection of menus.
     *
     * @return void
     */
    public function registerMenusCollection()
    {
        $this->app->singleton('menus.collection', function () {
            return new MenusCollection;
        });

        $this->app->alias('menus.collection', MenusCollection::class);
    }

    /**
     * Register factory of menus.
     *
     * @return void
     */
    public function registerMenuFactory()
    {
        $this->app->singleton('menu.factory', function ($app) {
            return new MenuFactory($app['menus.collection'], $app);
        });

        $this->app->alias('menu.factory', MenuFactory::class);
    }
}


text:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace SadConsole.Host
{
    public static class Global
    {
        public static GraphicsDevice GraphicsDevice { get; set; }

        public static GraphicsDeviceManager GraphicsDeviceManager { get; set; }

        public static SpriteBatch SharedSpriteBatch { get; set; }

        public static RenderTarget2D RenderOutput { get; set; }
    }
}


text:
void nspawn_get_paths(const char* env, std::vector<std::string>* paths);

// Gets a file for the specified basename in paths. Returns true on
// success and out_path will be updated. On failure, this function
// returns false and out_path will not be updated.
bool nspawn_find_in_paths(const std::string& basename,
                          const std::vector<std::string>& paths,
                          std::string* out_path);

#endif  // NACL_SPAWN_PATH_UTIL_H_


text:
@interface ActivityPostcard : UIActivity <SYSincerelyControllerDelegate>

@property (nonatomic, retain) UIImage *shareImage;

@end


text:
@class NNReloadOperations;

NS_ASSUME_NONNULL_BEGIN

@interface NNReloadOperationSanitizer : NSObject

+ (void)sanitizeOperations:(NNReloadOperations *)operations customReloadAllowed:(BOOL)customReloadAllowed;

@end

NS_ASSUME_NONNULL_END


text:
/* g-icon */
@import url(core.css);

@import url(common/set_common.css); /* system set */
@import url(common/size_x.css); /* size x */

@import url(other/set_lock.css); /* size x */


text:
- **Title:** Assert that certain keys contain specific values
- **Scope:** ansible-libelektra
- **Level:** User goal
- **Actors:** System administrator
- **Brief:** There should be a functionality in ansible-libelektra to assert certain keys have certain values.
  For example, some app B requires that a certain app A is already set up and running before configuring can be done.
  It may also be used to check that a certain plugin (e.g. `check`) is correctly installed within Elektra.

## Scenarios

- **Precondition:** The user asserts a certain value for a key in the task
- **Main success scenario:** The key on the target machine meets the assertion -> continue the execution
- **Alternative scenario:** The key on the target machine does not meet the assertion -> fail the execution
- **Error scenario:** -
- **Postcondition:** -
- **Non-functional Constraints:** -


text:
Employee Directory

All Employees

              Emp Id
              Name
              Position
              Location
              Office Phone
              Extension
              Cell Phone
              Email Address

              {{ employee.employeeId }}
              {{ employee.firstName }} {{ employee.lastName }}
              {{ employee.designation }}
              {{ employee.location }}
              {{ employee.officePhoneNo }}
              {{ employee.officePhoneExt }}
              {{ employee.cellPhoneNo }}
              {{ employee.email }}

            <button class="btn btn-default" ng-show="loggedInUser.admin" ng-click="addEmployee()">Add</button>
            <button class="btn btn-default" ng-show="loggedInUser.admin" ng-disabled="(selectedRow == -1)" ng-click="editEmployee(selectedRow)">Edit</button>
              <button class="btn btn-default" ng-show="loggedInUser.admin" ng-disabled="(selectedRow == -1)" ng-click="viewEmployeeDetails(selectedRow)">View</button>
            <button class="btn btn-danger" ng-show="loggedInUser.admin" style="margin-left:20px"  ng-disabled="(selectedRow == -1)" ng-click="deleteEmployee(selectedRow)">Delete</button>


text:
<resources>
    <string name="app_name">WKAwesomeMenu</string>
</resources>