func (factory *AppExaminerCommandFactory) listApps(context *cli.Context) {
	appList, err := factory.appExaminer.ListApps()
	if err == nil {
		w := &tabwriter.Writer{}
		w.Init(factory.ui, 10+colors.ColorCodeLength, 8, 1, '\t', 0)
		appTableHeader := strings.Repeat("-", 30) + "= Apps =" + strings.Repeat("-", 31)
		fmt.Fprintln(w, appTableHeader)
		if len(appList) != 0 {
			header := fmt.Sprintf("%s\t%s\t%s\t%s\t%s", colors.Bold("App Name"), colors.Bold("Instances"), colors.Bold("DiskMB"), colors.Bold("MemoryMB"), colors.Bold("Route"))
			fmt.Fprintln(w, header)

			for _, appInfo := range appList {
				displayedRoutes := factory.getRoutes(appInfo)
				fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n", colors.Bold(appInfo.ProcessGuid), colorInstances(appInfo), colors.NoColor(strconv.Itoa(appInfo.DiskMB)), colors.NoColor(strconv.Itoa(appInfo.MemoryMB)), colors.Cyan(displayedRoutes))
			}

		} else {
			fmt.Fprintf(w, "No apps to display."+"\n")
		}
		w.Flush()
	} else {
		factory.ui.SayLine("Error listing apps: " + err.Error())
		factory.exitHandler.Exit(exit_codes.CommandFailed)
	}
	taskList, err := factory.taskExaminer.ListTasks()
	if err == nil {
		wTask := &tabwriter.Writer{}
		wTask.Init(factory.ui, 10+colors.ColorCodeLength, 8, 1, '\t', 0)
		factory.ui.SayNewLine()
		taskTableHeader := strings.Repeat("-", 30) + "= Tasks =" + strings.Repeat("-", 30)
		fmt.Fprintln(wTask, taskTableHeader)
		if len(taskList) != 0 {
			taskHeader := fmt.Sprintf("%s\t%s\t%s\t%s\t%s\t", colors.Bold("Task Name"), colors.Bold("Cell ID"), colors.Bold("Status"), colors.Bold("Result"), colors.Bold("Failure Reason"))
			fmt.Fprintln(wTask, taskHeader)

			for _, taskInfo := range taskList {
				if taskInfo.CellID == "" {
					taskInfo.CellID = "N/A"
				}
				if taskInfo.Result == "" {
					taskInfo.Result = "N/A"
				}
				if taskInfo.FailureReason == "" {
					taskInfo.FailureReason = "N/A"
				}
				coloumnInfo := fmt.Sprintf("%s\t%s\t%s\t%s\t%s\t", colors.Bold(taskInfo.TaskGuid), colors.NoColor(taskInfo.CellID), colors.NoColor(taskInfo.State), colors.NoColor(taskInfo.Result), colors.NoColor(taskInfo.FailureReason))
				fmt.Fprintln(wTask, coloumnInfo)
			}

		} else {
			fmt.Fprintf(wTask, "No tasks to display.\n")
		}
		wTask.Flush()
	} else {
		factory.ui.SayLine("Error listing tasks: " + err.Error())
		factory.exitHandler.Exit(exit_codes.CommandFailed)
	}
}
func (factory *AppExaminerCommandFactory) printAppInfo(writer io.Writer, appInfo app_examiner.AppInfo) {
	factory.ui.Say(cursor.ClearToEndOfDisplay())

	w := tabwriter.NewWriter(writer, minColumnWidth, 8, 1, '\t', 0)

	titleBar := func(title string) {
		printHorizontalRule(w, "=")
		fmt.Fprintf(w, "%s%s\n", indentHeading, title)
		printHorizontalRule(w, "-")
	}

	titleBar(colors.Bold(appInfo.ProcessGuid))

	fmt.Fprintf(w, "%s\t%s\n", "Instances", colorInstances(appInfo))
	fmt.Fprintf(w, "%s\t%d\n", "Start Timeout", appInfo.StartTimeout)
	fmt.Fprintf(w, "%s\t%d\n", "DiskMB", appInfo.DiskMB)
	fmt.Fprintf(w, "%s\t%d\n", "MemoryMB", appInfo.MemoryMB)
	fmt.Fprintf(w, "%s\t%d\n", "CPUWeight", appInfo.CPUWeight)

	portStrings := make([]string, 0)
	for _, port := range appInfo.Ports {
		portStrings = append(portStrings, fmt.Sprint(port))
	}

	fmt.Fprintf(w, "%s\t%s\n", "Ports", strings.Join(portStrings, ","))

	factory.printAppRoutes(w, appInfo)

	if appInfo.Annotation != "" {
		fmt.Fprintf(w, "%s\t%s\n", "Annotation", appInfo.Annotation)
	}

	printHorizontalRule(w, "-")
	var envVars string
	for _, envVar := range appInfo.EnvironmentVariables {
		envVars += envVar.Name + `="` + envVar.Value + `" ` + "\n"
	}
	fmt.Fprintf(w, "%s\n\n%s", "Environment", envVars)

	fmt.Fprintln(w, "")

	w.Flush()
}
func (factory *AppExaminerCommandFactory) visualizeCells(context *cli.Context) {
	rate := context.Duration("rate")
	graphicalFlag := context.Bool("graphical")

	if graphicalFlag {
		err := factory.graphicalVisualizer.PrintDistributionChart(rate)
		if err != nil {
			factory.ui.SayLine("Error Visualization: " + err.Error())
			factory.exitHandler.Exit(exit_codes.CommandFailed)
		}
		return
	}

	factory.ui.SayLine(colors.Bold("Distribution"))
	linesWritten := factory.printDistribution()

	if rate == 0 {
		return
	}

	closeChan := make(chan struct{})
	factory.ui.Say(cursor.Hide())

	factory.exitHandler.OnExit(func() {
		closeChan <- struct{}{}
		factory.ui.Say(cursor.Show())

	})

	for {
		select {
		case <-closeChan:
			return
		case <-factory.clock.NewTimer(rate).C():
			factory.ui.Say(cursor.Up(linesWritten))
			linesWritten = factory.printDistribution()
		}
	}
}
					State:         "COMPLETED",
				},
				task_examiner.TaskInfo{
					TaskGuid:      "task-guid-3",
					CellID:        "",
					Failed:        true,
					FailureReason: "",
					Result:        "",
					State:         "COMPLETED",
				},
			}
			fakeTaskExaminer.ListTasksReturns(listTasks, nil)

			test_helpers.ExecuteCommandWithArgs(listAppsCommand, []string{})

			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("App Name")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("Instances")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("DiskMB")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("MemoryMB")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("Route")))

			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("process1")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Red("0/21")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("100")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("50")))
			Expect(outputBuffer).To(test_helpers.Say("alldaylong.com => 54321"))

			Expect(outputBuffer).To(test_helpers.Say(colors.Bold("process2")))
			Expect(outputBuffer).To(test_helpers.Say(colors.Yellow("9/8")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("400")))
			Expect(outputBuffer).To(test_helpers.Say(colors.NoColor("30")))
func (factory *AppExaminerCommandFactory) printAppInfo(writer io.Writer, appInfo app_examiner.AppInfo) {
	factory.ui.Say(cursor.ClearToEndOfDisplay())

	w := tabwriter.NewWriter(writer, minColumnWidth, 8, 1, '\t', 0)

	titleBar := func(title string) {
		printHorizontalRule(w, "=")
		fmt.Fprintf(w, "%s%s\n", indentHeading, title)
		printHorizontalRule(w, "-")
	}

	titleBar(colors.Bold(appInfo.ProcessGuid))

	fmt.Fprintf(w, "%s\t%s\n", "Instances", colorInstances(appInfo))
	fmt.Fprintf(w, "%s\t%d\n", "Start Timeout", appInfo.StartTimeout)
	fmt.Fprintf(w, "%s\t%d\n", "DiskMB", appInfo.DiskMB)
	fmt.Fprintf(w, "%s\t%d\n", "MemoryMB", appInfo.MemoryMB)
	fmt.Fprintf(w, "%s\t%d\n", "CPUWeight", appInfo.CPUWeight)

	portStrings := make([]string, 0)
	for _, port := range appInfo.Ports {
		portStrings = append(portStrings, fmt.Sprint(port))
	}

	fmt.Fprintf(w, "%s\t%s\n", "Ports", strings.Join(portStrings, ","))

	factory.printAppRoutes(w, appInfo)
	factory.printMonitor(w, appInfo)

	if appInfo.RootFS != "" {
		if strings.HasPrefix(appInfo.RootFS, "docker://") {
			image := strings.Replace(appInfo.RootFS, "docker://", "", 1)

			if strings.HasPrefix(image, "/") {
				image = strings.Replace(image, "/", "", 1)
			}

			if strings.HasPrefix(image, "library/") {
				image = strings.Replace(image, "library/", "", 1)
			}

			if hashIndex := strings.LastIndex(image, "#"); hashIndex != -1 {
				image = image[:hashIndex] + ":" + image[hashIndex+1:]
			}

			fmt.Fprintf(w, "%s\t%s\n", "Docker Image", image)
		} else if strings.HasPrefix(appInfo.RootFS, "preloaded:") {
			fmt.Fprintf(w, "%s\t%s\n", "Stack", strings.Replace(appInfo.RootFS, "preloaded:", "", 1))
		} else {
			fmt.Fprintf(w, "%s\t%s\n", "RootFS", appInfo.RootFS)
		}
	}

	if appInfo.Annotation != "" {
		fmt.Fprintf(w, "%s\t%s\n", "Annotation", appInfo.Annotation)
	}

	printHorizontalRule(w, "-")
	var envVars string
	for _, envVar := range appInfo.EnvironmentVariables {
		envVars += envVar.Name + `="` + envVar.Value + `" ` + "\n"
	}
	fmt.Fprintf(w, "%s\n\n%s", "Environment", envVars)

	fmt.Fprintln(w, "")

	w.Flush()
}
		})

		itShouldNotColorizeWhitespace(colors.Yellow)
	})

	Describe("Gray", func() {
		It("adds the gray color code", func() {
			Expect(colors.Gray("INFO")).To(Equal("\x1b[90mINFO\x1b[0m"))
		})

		itShouldNotColorizeWhitespace(colors.Gray)
	})

	Describe("Bold", func() {
		It("adds the bold color code", func() {
			Expect(colors.Bold("Bold")).To(Equal("\x1b[1mBold\x1b[0m"))
		})

		itShouldNotColorizeWhitespace(colors.Bold)
	})

	Describe("PurpleUnderline", func() {
		It("adds the purple underlined color code", func() {
			Expect(colors.PurpleUnderline("PURPLE UNDERLINE")).To(Equal("\x1b[35;4mPURPLE UNDERLINE\x1b[0m"))
		})

		itShouldNotColorizeWhitespace(colors.PurpleUnderline)
	})

	Describe("NoColor", func() {
		It("adds no color code", func() {