text:
package org.eclipse.test.internal.performance.results.ui;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseTrackListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.ToolTip;
import org.eclipse.test.internal.performance.results.db.AbstractResults;
import org.eclipse.test.internal.performance.results.model.BuildResultsElement;
import org.eclipse.test.internal.performance.results.model.ComponentResultsElement;
import org.eclipse.test.internal.performance.results.model.ConfigResultsElement;
import org.eclipse.test.internal.performance.results.model.ResultsElement;
import org.eclipse.test.internal.performance.results.model.ScenarioResultsElement;
import org.eclipse.test.internal.performance.results.utils.IPerformancesConstants;
import org.eclipse.test.internal.performance.results.utils.Util;

/**
 * Tab to display all performances results numbers for a configuration (i.e a performance machine).
 */
public class ConfigTab {

	// Colors
	static final Display DEFAULT_DISPLAY = Display.getDefault();
	static final Color BLUE= DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_BLUE);
	static final Color DARK_GREEN= DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_DARK_GREEN);
	static final Color GRAY = DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_GRAY);
	static final Color MAGENTA = DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_MAGENTA);
	static final Color RED = DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_RED);

	// SWT resources
	Shell shell;
	Display display;
	Table table;
	private GC gc;
	private Color lightred;
	private Color lightyellow;
	private Color darkyellow;
	private Color blueref;
	private Font boldFont;
	private Font italicFont;
	private Font boldItalicFont;
	Map toolTips;

	// Information
	String configBox, configName;
	ComponentResultsElement results;
	double[][] allValues;
	double[][] allErrors;

	// Cells management
	Point tableOrigin, tableSize;
	int columnsCount, rowsCount;
	List firstLine;

	// Eclipse preferences
	private IEclipsePreferences preferences;

/*
 * Default constructor.
 */
public ConfigTab(String name, String box) {
    this.configName = name;
    int idx = box.indexOf(" (");
	this.configBox = idx > 0 ? box.substring(0, idx) : box;
	this.preferences = new InstanceScope().getNode(IPerformancesConstants.PLUGIN_ID);
}

/**
 * Creates the tab folder page.
 *
 * @param tabFolder org.eclipse.swt.widgets.TabFolder
 * @param fullSelection Tells whether the table should have a full line selection or not
 * @return the new page for the tab folder
 */
Composite createTabFolderPage (ComponentResultsElement componentResultsElement, CTabFolder tabFolder, boolean fullSelection) {
	// Cache the shell and display.
	this.shell = tabFolder.getShell();
	this.display = this.shell.getDisplay();

	// Remove old table is present
	boolean initResources = this.table == null;
	if (this.table != null) {
		disposeTable();
	}

	// Store results
	this.results = componentResultsElement;

	// Create the "children" table
	int style = SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL;
	if (fullSelection) style |= SWT.FULL_SELECTION;
	this.table = new Table(tabFolder, style);
	this.table.setLinesVisible (true);
	this.table.setHeaderVisible (true);
	GridData gridData = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);
	gridData.heightHint = 150;
	this.table.setLayoutData (gridData);
	this.gc = new GC(this.table);

	// Init resources
	if (initResources) initResources();

	// Add columns to the table
	boolean fingerprints = this.preferences.getBoolean(IPerformancesConstants.PRE_FILTER_ADVANCED_SCENARIOS, IPerformancesConstants.DEFAULT_FILTER_ADVANCED_SCENARIOS);
	String [] columnHeaders = getLayoutDataFieldNames(fingerprints);
	int length = columnHeaders.length;
	for (int i = 0; i < length; i++) {
		TableColumn column = new TableColumn(this.table, SWT.CENTER);
		column.setText (columnHeaders [i]);
	}

	// Add lines to the table
	this.toolTips = new HashMap();
	fillTableLines(fingerprints);

	// Updated columns
	for (int i=0; i<length; i++) {
		TableColumn column = this.table.getColumn(i);
		column.setWidth(i==0?120:100);
		if (i > 0) {
			String text = (String) this.firstLine.get(i);
			column.setToolTipText(text);
		}
	}

	// Store table info
	this.columnsCount = length;

	// Listen to mouse events to select the corresponding build in the components view
	// when a click is done in the table cell.
	final ComponentsView componentsView = (ComponentsView) PerformancesView.getWorkbenchView("org.eclipse.test.internal.performance.results.ui.ComponentsView");
	MouseListener mouseListener = new MouseListener() {
		public void mouseUp(MouseEvent e) {
		}
		public void mouseDown(MouseEvent e) {
			Point cellPosition = currentCellPosition(e.x, e.y);
			Table tabTable = ConfigTab.this.table;
			componentsView.select(ConfigTab.this.results, ConfigTab.this.configName, (String) ConfigTab.this.firstLine.get(cellPosition.x), tabTable.getItem(cellPosition.y).getText());
		}
		public void mouseDoubleClick(MouseEvent e) {
		}
	};
	this.table.addMouseListener(mouseListener);

	// Listen to mouse track events to display the table cell corresponding tooltip.
	MouseTrackListener mouseTrackListener = new MouseTrackListener() {
		ToolTip currentTooltip;
		public void mouseHover(MouseEvent e) {
			if (this.currentTooltip != null) {
				this.currentTooltip.setVisible(false);
				this.currentTooltip = null;
			}
			Point cellPosition = currentCellPosition(e.x, e.y);
			if (cellPosition != null) {
				ToolTip tooltip = (ToolTip) ConfigTab.this.toolTips.get(cellPosition);
				if (tooltip != null) {
					Point location = ConfigTab.this.table.toDisplay(new Point(e.x, e.y));
					tooltip.setLocation(location);
					tooltip.setVisible(true);
					this.currentTooltip = tooltip;
				}
			}
		}
		public void mouseEnter(MouseEvent e) {
		}
		public void mouseExit(MouseEvent e) {
		}
	};
	this.table.addMouseTrackListener(mouseTrackListener);

	// Select the first line by default (as this is the current build)
	this.table.select(0);

	// Return the built composite
	return this.table;
}

/*
 * Create and store a tooltip with the given information and at the given position.
 */
void createToolTip(String toolTipText, String toolTipMessage, int toolTipStyle, Point position) {
	ToolTip toolTip = new ToolTip(this.table.getShell(), toolTipStyle);
	toolTip.setAutoHide(true);
	toolTip.setText(toolTipText);
	toolTip.setMessage(/*"("+col+","+row+") "+*/toolTipMessage);
	this.toolTips.put(position, toolTip);
}

/*
 * Get the current cell position (column, row) from a point position.
 */
Point currentCellPosition(int x, int y) {

	// Compute the origin of the visible area
	if (this.tableOrigin == null) {
		this.tableOrigin = new Point(0, this.table.getHeaderHeight());
	}

	// Increment width until over current y position
	int height= this.tableOrigin.y;
	int row = this.table.getTopIndex();
	while (row<this.rowsCount && height<y) {
		height += this.table.getItemHeight();
		row++;
	}
	if (height < y) {
		// return when position is over the last line
		return null;
	}
	row--;

	// Increment width until being over current x position
	int col = 0;
	TableItem tableItem = this.table.getItem(row);
	Rectangle bounds = tableItem.getBounds(col);
	while (col<this.columnsCount) {
		int max = bounds.x + bounds.width + this.table.getGridLineWidth();
		if (x <= max) break;
		if (col == this.columnsCount) {
			// return when position is over the last column
			return null;
		}
		col++;
		bounds = tableItem.getBounds(col);
	}

	// Return the found table cell position
	return new Point(col, row);
}

/*
 * Dispose all SWT resources.
 */
public void dispose() {
	if (this.boldFont != null) {
		this.boldFont.dispose();
	}
	if (this.italicFont != null) {
		this.italicFont.dispose();
	}
	if (this.boldItalicFont != null) {
		this.boldItalicFont.dispose();
	}
	if (this.darkyellow != null) {
		this.darkyellow.dispose();
	}
	if (this.lightyellow != null) {
		this.lightyellow.dispose();
	}
	if (this.lightred != null) {
		this.lightred.dispose();
	}
	if (this.blueref != null) {
		this.blueref.dispose();
	}
	disposeTable();
}

/*
 * Dispose all SWT controls associated with the table.
 */
private void disposeTable() {
	if (this.toolTips != null) {
		Iterator cells = this.toolTips.keySet().iterator();
		while (cells.hasNext()) {
			ToolTip toolTip = (ToolTip) this.toolTips.get(cells.next());
			toolTip.dispose();
		}
	}
	this.table.dispose();
	this.tableOrigin = null;
	this.firstLine = null;
}

/*
 * Fill the lines of the tables.
 * Get all the information from the model which are returned in a list (lines) of lists (columns).
 */
private void fillTableLines(boolean fingerprints) {

	// Get preferences information
	boolean onlyMilestones = this.preferences.getBoolean(IPerformancesConstants.PRE_FILTER_OLD_BUILDS, IPerformancesConstants.DEFAULT_FILTER_OLD_BUILDS);
	boolean skipNightlyBuilds = this.preferences.getBoolean(IPerformancesConstants.PRE_FILTER_NIGHTLY_BUILDS, IPerformancesConstants.DEFAULT_FILTER_NIGHTLY_BUILDS);

	// Get model information
	if (this.results == null) return;
	List differences = this.results.getConfigNumbers(this.configName, fingerprints);
	if (differences == null) return;

	// Store first information line which are the scenarios full names
	Iterator lines = differences.iterator();
	this.firstLine = (List) lines.next();

	// Read each information line (one line per build results)
	Object[] scenarios = this.results.getChildren(null);
	ConfigResultsElement[] configs = new ConfigResultsElement[scenarios.length];
	int row = 0;
	while (lines.hasNext()) {
		List line = (List) lines.next();
		int size = line.size();

		// The first column is the build name
		String buildName = (String) line.get(0);
		String milestoneName = Util.getMilestoneName(buildName);
		TableItem item = null;

		// Set item if the line is not filtered
		Font italic;
		if (milestoneName != null) {
			item = new TableItem (this.table, SWT.NONE);
			item.setText(milestoneName + " - " + buildName);
			item.setFont(0, this.boldFont);
			if (!onlyMilestones) item.setBackground(this.blueref);
			italic = this.boldItalicFont;
		} else {
			if ((onlyMilestones && Util.getNextMilestone(buildName) != null) ||
				(skipNightlyBuilds && buildName.charAt(0) == 'N')) {
				// skip line
				continue;
			}
			item = new TableItem (this.table, SWT.NONE);
			item.setText(0, buildName);
			italic = this.italicFont;
		}

		// Read each column value
		String baselineName = null;
		for (int col=1; col<size; col++) {

			// Reset tooltip info
			String toolTipText = null;
			String toolTipMessage = null;
			int toolTipStyle = SWT.BALLOON;

			// Otherwise get values for a scenario
			Font italic2 = italic;
			ScenarioResultsElement scenarioResultsElement = (ScenarioResultsElement) scenarios[col-1];
			if (milestoneName != null || (!fingerprints && scenarioResultsElement.hasSummary())) {
				italic2 = this.boldItalicFont;
				item.setFont(col, this.boldFont);
			}
			// Otherwise get values for a scenario
			double[] values = (double[]) line.get(col);
			if (values == AbstractResults.NO_BUILD_RESULTS) {
				item.setText(col, "Missing");
				item.setForeground(col, GRAY);
				item.setFont(col, italic2);
			} else if (values == AbstractResults.INVALID_RESULTS) {
				item.setText(col, "Invalid");
				item.setForeground(col, RED);
				item.setFont(col, italic2);
			} else {
				// Get values array
				double buildValue = values[AbstractResults.BUILD_VALUE_INDEX];
				double baselineValue = values[AbstractResults.BASELINE_VALUE_INDEX];
				double delta = values[AbstractResults.DELTA_VALUE_INDEX];
				double error = values[AbstractResults.DELTA_ERROR_INDEX];

				// Set text with delta value
				item.setText(col, Util.PERCENTAGE_FORMAT.format(delta));

				// Compute the tooltip to display on the cell
				if (error > 0.03) {
					// error is over the 3% threshold
					item.setImage(col, ResultsElement.WARN_IMAGE);
					item.setForeground(col, this.darkyellow);
					toolTipText = "May be not reliable";
					toolTipMessage = "The error on this result is "+Util.PERCENTAGE_FORMAT.format(error)+", hence it may be not reliable";
					toolTipStyle |= SWT.ICON_WARNING;
				}
				if (delta < -0.1) {
					// delta < -10%: failure shown by an red-cross icon + text in red
					item.setImage(col, ResultsElement.ERROR_IMAGE);
					item.setForeground(col, RED);
				} else if (delta < -0.05) {
					// negative delta over 5% shown in red
					item.setForeground(col, RED);
				} else if (delta < 0) {
					// negative delta shown in magenta
					item.setForeground(col, MAGENTA);
				} else if (delta > 0.2) {
					// positive delta over 20% shown in green
					item.setForeground(col, DARK_GREEN);
				} else if (delta > 0.1) {
					// positive delta between 10% and 20% shown in blue
					item.setForeground(col, BLUE);
				}

				// Moderate the status if the build value or the difference is small
				if (delta < 0) {
					double diff = Math.abs(baselineValue - buildValue);
					if (buildValue < 100 || diff < 100) {
						if (toolTipText == null) {
							toolTipText = "";
						} else {
							toolTipText += ", ";
						}
						toolTipText += "Small value";
						if (toolTipMessage == null) {
							toolTipMessage = "";
						} else {
							toolTipMessage += ".\n";
						}
						if (buildValue < 100) {
							toolTipMessage += "This test has a small value ("+buildValue+"ms)";
						} else {
							toolTipMessage += "This test variation has a small value ("+diff+"ms)";
						}
						toolTipMessage +=  ", hence it may not be necessary to spend time on fixing this possible regression";
						// set the text in italic
						item.setFont(col, italic2);
						toolTipStyle |= SWT.ICON_INFORMATION;
					}
				}

				// Add information in tooltip when history shows big variation
				ConfigResultsElement configResultsElement = configs[col-1];
				if (configResultsElement == null) {
					configResultsElement = (ConfigResultsElement) scenarioResultsElement.getResultsElement(this.configName);
					configs[col-1] = configResultsElement;
				}
				double deviation = configResultsElement == null ? 0 : configResultsElement.getStatistics()[3];
				if (deviation > 0.2) {
					// deviation is over 20% over the entire history
					if (toolTipText == null) {
						toolTipText = "";
					} else {
						toolTipText += ", ";
					}
					toolTipText += "History shows erratic values";
					if (toolTipMessage == null) {
						toolTipMessage = "";
					} else {
						toolTipMessage += ".\n";
					}
					toolTipMessage += "The results history shows that the variation of its delta is over 20% ("+Util.PERCENTAGE_FORMAT.format(deviation)+"), hence its result is surely not reliable";
					// set the text in italic
					item.setFont(col, italic2);
					toolTipStyle |= SWT.ICON_INFORMATION;
				} else if (deviation > 0.1) { // moderate the status when the test
					// deviation is between 10% and 20% over the entire history
					if (toolTipText == null) {
						toolTipText = "";
					} else {
						toolTipText += ", ";
					}
					toolTipText += "History shows unstable values";
					if (toolTipMessage == null) {
						toolTipMessage = "";
					} else {
						toolTipMessage += ".\n";
					}
					toolTipMessage += "The results history shows that the variation of its delta is between 10% and 20% ("+Util.PERCENTAGE_FORMAT.format(deviation)+"), hence its result may not be really reliable";
					// set the text in italic
					item.setFont(col, italic2);
					if (toolTipStyle == SWT.BALLOON && delta >= -0.1) {
						toolTipStyle |= SWT.ICON_INFORMATION;
					} else {
						// reduce icon severity from error to warning
						toolTipStyle |= SWT.ICON_WARNING;
					}
				}
			}

			// Set tooltip
			if (toolTipText != null) {
				createToolTip(toolTipText, toolTipMessage, toolTipStyle, new Point(col, row));
			}

			// Baseline name
			ConfigResultsElement configResultsElement = (ConfigResultsElement) scenarioResultsElement.getResultsElement(this.configName);
			if (configResultsElement != null) {
				String configBaselineName = configResultsElement.getBaselineBuildName(buildName);
				if (baselineName == null) {
					baselineName = configBaselineName;
				} else if (baselineName.indexOf(configBaselineName) < 0) {
					baselineName += ", " +configBaselineName;
				}
			}
		}

		// Set the tooltip over the build name
		if (baselineName != null) {
			createToolTip(buildName, "Baseline: "+baselineName, SWT.BALLOON | SWT.ICON_INFORMATION, new Point(0, row));
		}

		// Increment row counter
		row++;
	}
	this.rowsCount = row;
}

/*
 * Get the columns name.
 */
private String[] getLayoutDataFieldNames(boolean fingerprints) {
	if (this.results == null) {
		return new String[0];
	}
	List labels = this.results.getScenariosLabels(fingerprints);
	labels.add(0, "Build");
	String[] names = new String[labels.size()];
	labels.toArray(names);
	return names;
}

/*
 * The tab text is the full machine name.
 */
public String getTabText() {
	return this.configBox;
}

/*
 * Init the SWT resources
 */
private void initResources() {
	// Fonts
	String fontDataName = this.gc.getFont().getFontData()[0].toString();
	FontData fdItalic = new FontData(fontDataName);
	fdItalic.setStyle(SWT.ITALIC);
	this.italicFont = new Font(this.display, fdItalic);
	FontData fdBold = new FontData(fontDataName);
	fdBold.setStyle(SWT.BOLD);
	this.boldFont = new Font(this.display, fdBold);
	FontData fdBoldItalic = new FontData(fontDataName);
	fdBoldItalic.setStyle(SWT.BOLD | SWT.ITALIC);
	this.boldItalicFont = new Font(this.display, fdBoldItalic);

	// Colors
	this.lightred = new Color(DEFAULT_DISPLAY, 220, 50, 50);
	this.lightyellow = new Color(DEFAULT_DISPLAY, 255, 255, 160);
	this.darkyellow = new Color(DEFAULT_DISPLAY, 160, 160, 0);
	this.blueref = new Color(DEFAULT_DISPLAY, 200, 200, 255);
}

/*
 * Select the line corresponding to the given build.
 */
void select(BuildResultsElement buildResultsElement) {
	int count = this.table.getItemCount();
	String buildName = buildResultsElement.getName();
	TableItem[] items = this.table.getItems();
	for (int i=0; i<count; i++) {
		if (items[i].getText().endsWith(buildName)) {
			this.table.deselect(this.table.getSelectionIndex());
			this.table.select(i);
			return;
		}
	}
}
}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
null

#### Original name
Cornularia rhois P. Karst.

### Remarks
null

redpajama_set_name: RedPajamaGithub


text:
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:text="@string/text_days"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/edit_days"
        android:inputType="numberSigned"/>
</LinearLayout>


text:
package org.jetbrains.plugins.groovy.lang.psi.controlFlow;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ArrayUtilRt;
import consulo.util.collection.primitive.ints.IntLists;
import consulo.util.collection.primitive.ints.IntSet;
import consulo.util.collection.primitive.ints.IntSets;
import consulo.util.collection.primitive.objects.ObjectIntMap;
import consulo.util.collection.primitive.objects.ObjectMaps;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
import org.jetbrains.plugins.groovy.lang.psi.api.GroovyResolveResult;
import org.jetbrains.plugins.groovy.lang.psi.api.formatter.GrControlStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrOpenBlock;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.branch.GrBreakStatement;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.clauses.GrCaseSection;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.*;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod;
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement;
import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil;
import org.jetbrains.plugins.groovy.lang.resolve.processors.PropertyResolverProcessor;
import org.jetbrains.plugins.groovy.lang.resolve.processors.ResolverProcessorImpl;

import javax.annotation.Nonnull;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ven
 */
public class ControlFlowBuilderUtil {
  private static final Logger LOG = Logger.getInstance("org.jetbrains.plugins.groovy.lang.psi.controlFlow.ControlFlowBuilderUtil");

  private ControlFlowBuilderUtil() {
  }

  public static int[] postorder(Instruction[] flow) {
    int[] result = new int[flow.length];
    boolean[] visited = new boolean[flow.length];
    for (int i = 0; i < result.length; i++) visited[i] = false;

    int N = flow.length;
    for (int i = 0; i < flow.length; i++) { //graph might not be connected
      if (!visited[i]) N = doVisitForPostorder(flow[i], N, result, visited);
    }

    LOG.assertTrue(N == 0);
    return result;
  }

  private static int doVisitForPostorder(Instruction curr, int currN, int[] postorder, boolean[] visited) {
    visited[curr.num()] = true;
    for (Instruction succ : curr.allSuccessors()) {
      if (!visited[succ.num()]) {
        currN = doVisitForPostorder(succ, currN, postorder, visited);
      }
    }
    postorder[curr.num()] = --currN;
    return currN;
  }

  public static ReadWriteVariableInstruction[] getReadsWithoutPriorWrites(Instruction[] flow, boolean onlyFirstRead) {
    List<ReadWriteVariableInstruction> result = new ArrayList<ReadWriteVariableInstruction>();
    ObjectIntMap<String> namesIndex = buildNamesIndex(flow);

    IntSet[] definitelyAssigned = new IntSet[flow.length];

    int[] postorder = postorder(flow);
    int[] invpostorder = invPostorder(postorder);

    findReadsBeforeWrites(flow, definitelyAssigned, result, namesIndex, postorder, invpostorder, onlyFirstRead);
    if (result.size() == 0) return ReadWriteVariableInstruction.EMPTY_ARRAY;
    return result.toArray(new ReadWriteVariableInstruction[result.size()]);
  }

  private static int[] invPostorder(int[] postorder) {
    int[] result = new int[postorder.length];
    for (int i = 0; i < postorder.length; i++) {
      result[postorder[i]] = i;
    }

    return result;
  }

  private static ObjectIntMap<String> buildNamesIndex(Instruction[] flow) {
    ObjectIntMap<String> namesIndex = ObjectMaps.newObjectIntHashMap();
    int idx = 0;
    for (Instruction instruction : flow) {
      if (instruction instanceof ReadWriteVariableInstruction) {
        String name = ((ReadWriteVariableInstruction)instruction).getVariableName();
        if (!namesIndex.containsKey(name)) {
          namesIndex.putInt(name, idx++);
        }
      }
    }
    return namesIndex;
  }

  private static void findReadsBeforeWrites(Instruction[] flow, IntSet[] definitelyAssigned,
                                            List<ReadWriteVariableInstruction> result,
                                            ObjectIntMap<String> namesIndex,
                                            int[] postorder,
                                            int[] invpostorder,
                                            boolean onlyFirstRead) {
    //skip instructions that are not reachable from the start
    int start = ArrayUtil.find(invpostorder, 0);

    for (int i = start; i < flow.length; i++) {
      int j = invpostorder[i];
      Instruction curr = flow[j];
      if (curr instanceof ReadWriteVariableInstruction) {
        ReadWriteVariableInstruction rw = (ReadWriteVariableInstruction)curr;
        int name = namesIndex.getInt(rw.getVariableName());
        IntSet vars = definitelyAssigned[j];
        if (rw.isWrite()) {
          if (vars == null) {
            vars = IntSets.newHashSet();
            definitelyAssigned[j] = vars;
          }
          vars.add(name);
        }
        else {
          if (vars == null || !vars.contains(name)) {
            result.add(rw);
            if (onlyFirstRead) {
              if (vars == null) {
                vars = IntSets.newHashSet();
                definitelyAssigned[j] = vars;
              }
              vars.add(name);
            }
          }
        }
      }

      for (Instruction succ : curr.allSuccessors()) {
        if (postorder[succ.num()] > postorder[curr.num()]) {
          IntSet currDefinitelyAssigned = definitelyAssigned[curr.num()];
          IntSet succDefinitelyAssigned = definitelyAssigned[succ.num()];
          if (currDefinitelyAssigned != null) {
            int[] currArray = currDefinitelyAssigned.toArray();
            if (succDefinitelyAssigned == null) {
              succDefinitelyAssigned = IntSets.newHashSet();
              succDefinitelyAssigned.addAll(currArray);
              definitelyAssigned[succ.num()] = succDefinitelyAssigned;
            }
            else {
              succDefinitelyAssigned.retainAll(IntLists.newArrayList(currArray));
            }
          }
          else {
            if (succDefinitelyAssigned != null) {
              succDefinitelyAssigned.clear();
            }
            else {
              succDefinitelyAssigned = IntSets.newHashSet();
              definitelyAssigned[succ.num()] = succDefinitelyAssigned;
            }
          }
        }
      }
    }
  }

  public static boolean isInstanceOfBinary(GrBinaryExpression binary) {
    if (binary.getOperationTokenType() == GroovyTokenTypes.kIN) {
      GrExpression left = binary.getLeftOperand();
      GrExpression right = binary.getRightOperand();
      if (left instanceof GrReferenceExpression && ((GrReferenceExpression)left).getQualifier() == null &&
          right instanceof GrReferenceExpression && findClassByText((GrReferenceExpression)right)) {
        return true;
      }
    }
    return false;
  }

  private static boolean findClassByText(GrReferenceExpression ref) {
    final String text = ref.getText();
    final int i = text.indexOf('<');
    String className = i == -1 ? text : text.substring(0, i);

    PsiClass[] names = PsiShortNamesCache.getInstance(ref.getProject()).getClassesByName(className, ref.getResolveScope());
    if (names.length > 0) return true;

    PsiFile file = ref.getContainingFile();
    if (file instanceof GroovyFile) {
      GrImportStatement[] imports = ((GroovyFile)file).getImportStatements();
      for (GrImportStatement anImport : imports) {
        if (className.equals(anImport.getImportedName())) return true;
      }
    }

    return false;
  }

  /**
   * check whether statement is return (the statement which provides return value) statement of method or closure.
   *
   * @param st
   * @return
   */
  public static boolean isCertainlyReturnStatement(GrStatement st) {
    final PsiElement parent = st.getParent();
    if (parent instanceof GrOpenBlock) {
      if (st != ArrayUtil.getLastElement(((GrOpenBlock)parent).getStatements())) return false;

      PsiElement pparent = parent.getParent();
      if (pparent instanceof GrMethod) {
        return true;
      }

      if (pparent instanceof GrBlockStatement || pparent instanceof GrCatchClause || pparent instanceof GrLabeledStatement) {
        pparent = pparent.getParent();
      }
      if (pparent instanceof GrIfStatement || pparent instanceof GrControlStatement || pparent instanceof GrTryCatchStatement) {
        return isCertainlyReturnStatement((GrStatement)pparent);
      }
    }

    else if (parent instanceof GrClosableBlock) {
      return st == ArrayUtil.getLastElement(((GrClosableBlock)parent).getStatements());
    }

    else if (parent instanceof GroovyFileBase) {
      return st == ArrayUtil.getLastElement(((GroovyFileBase)parent).getStatements());
    }

    else if (parent instanceof GrForStatement ||
             parent instanceof GrIfStatement && st != ((GrIfStatement)parent).getCondition() ||
             parent instanceof GrSynchronizedStatement && st != ((GrSynchronizedStatement)parent).getMonitor() ||
             parent instanceof GrWhileStatement && st != ((GrWhileStatement)parent).getCondition() ||
             parent instanceof GrConditionalExpression && st != ((GrConditionalExpression)parent).getCondition() ||
             parent instanceof GrElvisExpression) {
      return isCertainlyReturnStatement((GrStatement)parent);
    }

    else if (parent instanceof GrCaseSection) {
      final GrStatement[] statements = ((GrCaseSection)parent).getStatements();
      final GrStatement last = ArrayUtil.getLastElement(statements);
      final GrSwitchStatement switchStatement = (GrSwitchStatement)parent.getParent();

      if (last instanceof GrBreakStatement && statements.length > 1 && statements[statements.length - 2] == st) {
        return isCertainlyReturnStatement(switchStatement);
      }
      else if (st == last) {
        if (st instanceof GrBreakStatement || isLastStatementInCaseSection((GrCaseSection)parent, switchStatement)) {
          return isCertainlyReturnStatement(switchStatement);
        }
      }
    }
    return false;
  }

  private static boolean isLastStatementInCaseSection(GrCaseSection caseSection, GrSwitchStatement switchStatement) {
    final GrCaseSection[] sections = switchStatement.getCaseSections();
    final int i = ArrayUtilRt.find(sections, caseSection);
    if (i == sections.length - 1) {
      return true;
    }

    for (int j = i + 1; j < sections.length; j++) {
      GrCaseSection section = sections[j];
      for (GrStatement statement : section.getStatements()) {
        if (!(statement instanceof GrBreakStatement)) {
          return false;
        }
      }
    }
    return true;
  }

  @Nonnull
  public static GroovyResolveResult[] resolveNonQualifiedRefWithoutFlow(@Nonnull GrReferenceExpression ref) {
    LOG.assertTrue(!ref.isQualified());

    final String referenceName = ref.getReferenceName();
    final ResolverProcessorImpl processor = new PropertyResolverProcessor(referenceName, ref);

    ResolveUtil.treeWalkUp(ref, processor, false);
    final GroovyResolveResult[] candidates = processor.getCandidates();
    if (candidates.length != 0) {
      return candidates;
    }

    return GroovyResolveResult.EMPTY_ARRAY;
  }
}


text:
"""Create threads to run multiple enqueue ops."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import threading
import weakref

from tensorflow.core.protobuf import queue_runner_pb2
from tensorflow.python.client import session
from tensorflow.python.eager import context
from tensorflow.python.framework import errors
from tensorflow.python.framework import ops
from tensorflow.python.platform import tf_logging as logging
from tensorflow.python.util import deprecation
from tensorflow.python.util.tf_export import tf_export

_DEPRECATION_INSTRUCTION = (
    "To construct input pipelines, use the `tf.data` module.")

@tf_export(v1=["train.queue_runner.QueueRunner", "train.QueueRunner"])
class QueueRunner(object):
  """Holds a list of enqueue operations for a queue, each to be run in a thread.

  Queues are a convenient TensorFlow mechanism to compute tensors
  asynchronously using multiple threads. For example in the canonical 'Input
  Reader' setup one set of threads generates filenames in a queue; a second set
  of threads read records from the files, processes them, and enqueues tensors
  on a second queue; a third set of threads dequeues these input records to
  construct batches and runs them through training operations.

  There are several delicate issues when running multiple threads that way:
  closing the queues in sequence as the input is exhausted, correctly catching
  and reporting exceptions, etc.

  The `QueueRunner`, combined with the `Coordinator`, helps handle these issues.

  @compatibility(TF2)
  QueueRunners are not compatible with eager execution. Instead, please
  use [tf.data](https://www.tensorflow.org/guide/data) to get data into your
  model.
  @end_compatibility
  """

  @deprecation.deprecated(None, _DEPRECATION_INSTRUCTION)
  def __init__(self, queue=None, enqueue_ops=None, close_op=None,
               cancel_op=None, queue_closed_exception_types=None,
               queue_runner_def=None, import_scope=None):
    """Create a QueueRunner.

    On construction the `QueueRunner` adds an op to close the queue.  That op
    will be run if the enqueue ops raise exceptions.

    When you later call the `create_threads()` method, the `QueueRunner` will
    create one thread for each op in `enqueue_ops`.  Each thread will run its
    enqueue op in parallel with the other threads.  The enqueue ops do not have
    to all be the same op, but it is expected that they all enqueue tensors in
    `queue`.

    Args:
      queue: A `Queue`.
      enqueue_ops: List of enqueue ops to run in threads later.
      close_op: Op to close the queue. Pending enqueue ops are preserved.
      cancel_op: Op to close the queue and cancel pending enqueue ops.
      queue_closed_exception_types: Optional tuple of Exception types that
        indicate that the queue has been closed when raised during an enqueue
        operation.  Defaults to `(tf.errors.OutOfRangeError,)`.  Another common
        case includes `(tf.errors.OutOfRangeError, tf.errors.CancelledError)`,
        when some of the enqueue ops may dequeue from other Queues.
      queue_runner_def: Optional `QueueRunnerDef` protocol buffer. If specified,
        recreates the QueueRunner from its contents. `queue_runner_def` and the
        other arguments are mutually exclusive.
      import_scope: Optional `string`. Name scope to add. Only used when
        initializing from protocol buffer.

    Raises:
      ValueError: If both `queue_runner_def` and `queue` are both specified.
      ValueError: If `queue` or `enqueue_ops` are not provided when not
        restoring from `queue_runner_def`.
      RuntimeError: If eager execution is enabled.
    """
    if context.executing_eagerly():
      raise RuntimeError(
          "QueueRunners are not supported when eager execution is enabled. "
          "Instead, please use tf.data to get data into your model.")

    if queue_runner_def:
      if queue or enqueue_ops:
        raise ValueError("queue_runner_def and queue are mutually exclusive.")
      self._init_from_proto(queue_runner_def,
                            import_scope=import_scope)
    else:
      self._init_from_args(
          queue=queue, enqueue_ops=enqueue_ops,
          close_op=close_op, cancel_op=cancel_op,
          queue_closed_exception_types=queue_closed_exception_types)
    # Protect the count of runs to wait for.
    self._lock = threading.Lock()
    # A map from a session object to the number of outstanding queue runner
    # threads for that session.
    self._runs_per_session = weakref.WeakKeyDictionary()
    # List of exceptions raised by the running threads.
    self._exceptions_raised = []

  def _init_from_args(self, queue=None, enqueue_ops=None, close_op=None,
                      cancel_op=None, queue_closed_exception_types=None):
    """Create a QueueRunner from arguments.

    Args:
      queue: A `Queue`.
      enqueue_ops: List of enqueue ops to run in threads later.
      close_op: Op to close the queue. Pending enqueue ops are preserved.
      cancel_op: Op to close the queue and cancel pending enqueue ops.
      queue_closed_exception_types: Tuple of exception types, which indicate
        the queue has been safely closed.

    Raises:
      ValueError: If `queue` or `enqueue_ops` are not provided when not
        restoring from `queue_runner_def`.
      TypeError: If `queue_closed_exception_types` is provided, but is not
        a non-empty tuple of error types (subclasses of `tf.errors.OpError`).
    """
    if not queue or not enqueue_ops:
      raise ValueError("Must provide queue and enqueue_ops.")
    self._queue = queue
    self._enqueue_ops = enqueue_ops
    self._close_op = close_op
    self._cancel_op = cancel_op
    if queue_closed_exception_types is not None:
      if (not isinstance(queue_closed_exception_types, tuple)
          or not queue_closed_exception_types
          or not all(issubclass(t, errors.OpError)
                     for t in queue_closed_exception_types)):
        raise TypeError(
            "queue_closed_exception_types, when provided, "
            "must be a tuple of tf.error types, but saw: %s"
            % queue_closed_exception_types)
    self._queue_closed_exception_types = queue_closed_exception_types
    # Close when no more will be produced, but pending enqueues should be
    # preserved.
    if self._close_op is None:
      self._close_op = self._queue.close()
    # Close and cancel pending enqueues since there was an error and we want
    # to unblock everything so we can cleanly exit.
    if self._cancel_op is None:
      self._cancel_op = self._queue.close(cancel_pending_enqueues=True)
    if not self._queue_closed_exception_types:
      self._queue_closed_exception_types = (errors.OutOfRangeError,)
    else:
      self._queue_closed_exception_types = tuple(
          self._queue_closed_exception_types)

  def _init_from_proto(self, queue_runner_def, import_scope=None):
    """Create a QueueRunner from `QueueRunnerDef`.

    Args:
      queue_runner_def: Optional `QueueRunnerDef` protocol buffer.
      import_scope: Optional `string`. Name scope to add.
    """
    assert isinstance(queue_runner_def, queue_runner_pb2.QueueRunnerDef)
    g = ops.get_default_graph()
    self._queue = g.as_graph_element(
        ops.prepend_name_scope(queue_runner_def.queue_name, import_scope))
    self._enqueue_ops = [g.as_graph_element(
        ops.prepend_name_scope(op, import_scope))
                         for op in queue_runner_def.enqueue_op_name]
    self._close_op = g.as_graph_element(ops.prepend_name_scope(
        queue_runner_def.close_op_name, import_scope))
    self._cancel_op = g.as_graph_element(ops.prepend_name_scope(
        queue_runner_def.cancel_op_name, import_scope))
    self._queue_closed_exception_types = tuple(
        errors.exception_type_from_error_code(code)
        for code in queue_runner_def.queue_closed_exception_types)
    # Legacy support for old QueueRunnerDefs created before this field
    # was added.
    if not self._queue_closed_exception_types:
      self._queue_closed_exception_types = (errors.OutOfRangeError,)

  @property
  def queue(self):
    return self._queue

  @property
  def enqueue_ops(self):
    return self._enqueue_ops

  @property
  def close_op(self):
    return self._close_op

  @property
  def cancel_op(self):
    return self._cancel_op

  @property
  def queue_closed_exception_types(self):
    return self._queue_closed_exception_types

  @property
  def exceptions_raised(self):
    """Exceptions raised but not handled by the `QueueRunner` threads.

    Exceptions raised in queue runner threads are handled in one of two ways
    depending on whether or not a `Coordinator` was passed to
    `create_threads()`:

    * With a `Coordinator`, exceptions are reported to the coordinator and
      forgotten by the `QueueRunner`.
    * Without a `Coordinator`, exceptions are captured by the `QueueRunner` and
      made available in this `exceptions_raised` property.

    Returns:
      A list of Python `Exception` objects.  The list is empty if no exception
      was captured.  (No exceptions are captured when using a Coordinator.)
    """
    return self._exceptions_raised

  @property
  def name(self):
    """The string name of the underlying Queue."""
    return self._queue.name

  # pylint: disable=broad-except
  def _run(self, sess, enqueue_op, coord=None):
    """Execute the enqueue op in a loop, close the queue in case of error.

    Args:
      sess: A Session.
      enqueue_op: The Operation to run.
      coord: Optional Coordinator object for reporting errors and checking
        for stop conditions.
    """
    decremented = False
    try:
      # Make a cached callable from the `enqueue_op` to decrease the
      # Python overhead in the queue-runner loop.
      enqueue_callable = sess.make_callable(enqueue_op)
      while True:
        if coord and coord.should_stop():
          break
        try:
          enqueue_callable()
        except self._queue_closed_exception_types:  # pylint: disable=catching-non-exception
          # This exception indicates that a queue was closed.
          with self._lock:
            self._runs_per_session[sess] -= 1
            decremented = True
            if self._runs_per_session[sess] == 0:
              try:
                sess.run(self._close_op)
              except Exception as e:
                # Intentionally ignore errors from close_op.
                logging.vlog(1, "Ignored exception: %s", str(e))
            return
    except Exception as e:
      # This catches all other exceptions.
      if coord:
        coord.request_stop(e)
      else:
        logging.error("Exception in QueueRunner: %s", str(e))
        with self._lock:
          self._exceptions_raised.append(e)
        raise
    finally:
      # Make sure we account for all terminations: normal or errors.
      if not decremented:
        with self._lock:
          self._runs_per_session[sess] -= 1

  def _close_on_stop(self, sess, cancel_op, coord):
    """Close the queue when the Coordinator requests stop.

    Args:
      sess: A Session.
      cancel_op: The Operation to run.
      coord: Coordinator.
    """
    coord.wait_for_stop()
    try:
      sess.run(cancel_op)
    except Exception as e:
      # Intentionally ignore errors from cancel_op.
      logging.vlog(1, "Ignored exception: %s", str(e))
  # pylint: enable=broad-except

  def create_threads(self, sess, coord=None, daemon=False, start=False):
    """Create threads to run the enqueue ops for the given session.

    This method requires a session in which the graph was launched.  It creates
    a list of threads, optionally starting them.  There is one thread for each
    op passed in `enqueue_ops`.

    The `coord` argument is an optional coordinator that the threads will use
    to terminate together and report exceptions.  If a coordinator is given,
    this method starts an additional thread to close the queue when the
    coordinator requests a stop.

    If previously created threads for the given session are still running, no
    new threads will be created.

    Args:
      sess: A `Session`.
      coord: Optional `Coordinator` object for reporting errors and checking
        stop conditions.
      daemon: Boolean.  If `True` make the threads daemon threads.
      start: Boolean.  If `True` starts the threads.  If `False` the
        caller must call the `start()` method of the returned threads.

    Returns:
      A list of threads.
    """
    with self._lock:
      try:
        if self._runs_per_session[sess] > 0:
          # Already started: no new threads to return.
          return []
      except KeyError:
        # We haven't seen this session yet.
        pass
      self._runs_per_session[sess] = len(self._enqueue_ops)
      self._exceptions_raised = []

    ret_threads = []
    for op in self._enqueue_ops:
      name = "QueueRunnerThread-{}-{}".format(self.name, op.name)
      ret_threads.append(threading.Thread(target=self._run,
                                          args=(sess, op, coord),
                                          name=name))
    if coord:
      name = "QueueRunnerThread-{}-close_on_stop".format(self.name)
      ret_threads.append(threading.Thread(target=self._close_on_stop,
                                          args=(sess, self._cancel_op, coord),
                                          name=name))
    for t in ret_threads:
      if coord:
        coord.register_thread(t)
      if daemon:
        t.daemon = True
      if start:
        t.start()
    return ret_threads

  def to_proto(self, export_scope=None):
    """Converts this `QueueRunner` to a `QueueRunnerDef` protocol buffer.

    Args:
      export_scope: Optional `string`. Name scope to remove.

    Returns:
      A `QueueRunnerDef` protocol buffer, or `None` if the `Variable` is not in
      the specified name scope.
    """
    if (export_scope is None or
        self.queue.name.startswith(export_scope)):
      queue_runner_def = queue_runner_pb2.QueueRunnerDef()
      queue_runner_def.queue_name = ops.strip_name_scope(
          self.queue.name, export_scope)
      for enqueue_op in self.enqueue_ops:
        queue_runner_def.enqueue_op_name.append(
            ops.strip_name_scope(enqueue_op.name, export_scope))
      queue_runner_def.close_op_name = ops.strip_name_scope(
          self.close_op.name, export_scope)
      queue_runner_def.cancel_op_name = ops.strip_name_scope(
          self.cancel_op.name, export_scope)
      queue_runner_def.queue_closed_exception_types.extend([
          errors.error_code_from_exception_type(cls)
          for cls in self._queue_closed_exception_types])
      return queue_runner_def
    else:
      return None

  @staticmethod
  def from_proto(queue_runner_def, import_scope=None):
    """Returns a `QueueRunner` object created from `queue_runner_def`."""
    return QueueRunner(queue_runner_def=queue_runner_def,
                       import_scope=import_scope)

@tf_export(v1=["train.queue_runner.add_queue_runner", "train.add_queue_runner"])
@deprecation.deprecated(None, _DEPRECATION_INSTRUCTION)
def add_queue_runner(qr, collection=ops.GraphKeys.QUEUE_RUNNERS):
  """Adds a `QueueRunner` to a collection in the graph.

  When building a complex model that uses many queues it is often difficult to
  gather all the queue runners that need to be run.  This convenience function
  allows you to add a queue runner to a well known collection in the graph.

  The companion method `start_queue_runners()` can be used to start threads for
  all the collected queue runners.

  @compatibility(TF2)
  QueueRunners are not compatible with eager execution. Instead, please
  use [tf.data](https://www.tensorflow.org/guide/data) to get data into your
  model.
  @end_compatibility

  Args:
    qr: A `QueueRunner`.
    collection: A `GraphKey` specifying the graph collection to add
      the queue runner to.  Defaults to `GraphKeys.QUEUE_RUNNERS`.
  """
  ops.add_to_collection(collection, qr)

@tf_export(v1=["train.queue_runner.start_queue_runners",
               "train.start_queue_runners"])
@deprecation.deprecated(None, _DEPRECATION_INSTRUCTION)
def start_queue_runners(sess=None, coord=None, daemon=True, start=True,
                        collection=ops.GraphKeys.QUEUE_RUNNERS):
  """Starts all queue runners collected in the graph.

  This is a companion method to `add_queue_runner()`.  It just starts
  threads for all queue runners collected in the graph.  It returns
  the list of all threads.

  @compatibility(TF2)
  QueueRunners are not compatible with eager execution. Instead, please
  use [tf.data](https://www.tensorflow.org/guide/data) to get data into your
  model.
  @end_compatibility

  Args:
    sess: `Session` used to run the queue ops.  Defaults to the
      default session.
    coord: Optional `Coordinator` for coordinating the started threads.
    daemon: Whether the threads should be marked as `daemons`, meaning
      they don't block program exit.
    start: Set to `False` to only create the threads, not start them.
    collection: A `GraphKey` specifying the graph collection to
      get the queue runners from.  Defaults to `GraphKeys.QUEUE_RUNNERS`.

  Raises:
    ValueError: if `sess` is None and there isn't any default session.
    TypeError: if `sess` is not a `tf.compat.v1.Session` object.

  Returns:
    A list of threads.

  Raises:
    RuntimeError: If called with eager execution enabled.
    ValueError: If called without a default `tf.compat.v1.Session` registered.
  """
  if context.executing_eagerly():
    raise RuntimeError("Queues are not compatible with eager execution.")
  if sess is None:
    sess = ops.get_default_session()
    if not sess:
      raise ValueError("Cannot start queue runners: No default session is "
                       "registered. Use `with sess.as_default()` or pass an "
                       "explicit session to tf.start_queue_runners(sess=sess)")

  if not isinstance(sess, session.SessionInterface):
    # Following check is due to backward compatibility. (b/62061352)
    if sess.__class__.__name__ in [
        "MonitoredSession", "SingularMonitoredSession"]:
      return []
    raise TypeError("sess must be a `tf.Session` object. "
                    "Given class: {}".format(sess.__class__))

  queue_runners = ops.get_collection(collection)
  if not queue_runners:
    logging.warning(
        "`tf.train.start_queue_runners()` was called when no queue runners "
        "were defined. You can safely remove the call to this deprecated "
        "function.")

  with sess.graph.as_default():
    threads = []
    for qr in ops.get_collection(collection):
      threads.extend(qr.create_threads(sess, coord=coord, daemon=daemon,
                                       start=start))
  return threads

ops.register_proto_function(ops.GraphKeys.QUEUE_RUNNERS,
                            proto_type=queue_runner_pb2.QueueRunnerDef,
                            to_proto=QueueRunner.to_proto,
                            from_proto=QueueRunner.from_proto)


text:
<!DOCTYPE html>

<title>How do I embed an image in a text box?</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta content="CKeditor" name="description">
<meta content="embed image, picture, photo, text box, CKeditor" name="search">
<link href="/library/skin/tool_base.css" media="screen" rel="stylesheet" type="text/css" charset="utf-8">
<link href="/library/skin/neo-default/tool.css" media="screen" rel="stylesheet" type="text/css" charset="utf-8">
<link href="/library/skin/neo-default/help.css" media="screen" rel="stylesheet" type="text/css" charset="utf-8">
<link href="/library/js/jquery/featherlight/0.4.0/featherlight.min.css" media="screen" rel="stylesheet" type="text/css" charset="utf-8">

How do I embed an image in a text box?

Position the cursor.

              Zoom

Position your cursor in the text box at the point you want to embed the image.

Click on the Insert/Edit Image icon.

              Zoom

This displays the image properties dialog box

Click Browse Server.

This displays the entity picker. Your site Resource folders should be displayed

Upload the image file.

Hover your cursor over the folder where you want to store the image file then click on Upload File.

This displays an upload file dialog box.

Click Browse

This displays your computer's file locator.

Locate and select the image file on your computer, then click Open

This will return the display to the upload file dialog box.

Click Upload

This returns the display to the entity picker.

Select the image to be embedded.

Click on the Plus Sign (+) to the left of the folder to expand the folder contents, and then select the image you want to embed in the text box.

Your will be returned to the image properties dialog box with a preview of the embedded image.

Modify image properties.

Adjust the image width and height if needed and add an alternative text for screen readers.

Set the Alignment.

Set the Alignment (left or right) for the image if you want to surround the image with text.

Click OK.

This returns the display to the text box with the embedded image.

Example of additional text displayed next to a left-aligned image.

              Zoom


text:
<!doctype html>

  <meta charset="utf-8">
  <title>K3D headless engine</title>


text:
<?php
namespace CommonBundle\Form;

use CommonBundle\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email', EmailType::class, array('label' => 'Email'))
            ->add('username', TextType::class, array('label' => 'Nom d\'utilisateur'))
            ->add('password', PasswordType::class, array('label' => 'Mot de passe'))
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => User::class,
        ));
    }
}

?>


text:
bool DroneLoggerROSModule::save_front_camera_images  = false;
bool DroneLoggerROSModule::save_bottom_camera_images = false;

DroneLoggerROSModule::DroneLoggerROSModule( ros::NodeHandle n) :
    DroneLoggerROSBasicModule(n),
    // Drone Telemetry
    battery_subscriber(n,        "drone;battery", DRONE_LOGGER_SENSOR_BATTERY, &DroneLoggerROSModule::batteryCallback, init_rostime),
    altitude_subscriber(n,       "drone;altitude", DRONE_LOGGER_SENSOR_ALTITUDE, &DroneLoggerROSModule::droneAltitudeCallback, init_rostime),
    rotation_angles_subscriber(n,"drone;rotation_angles", DRONE_LOGGER_SENSOR_ROTATION_ANGLES, &DroneLoggerROSModule::vector3StampedCallback, init_rostime),
    ground_speed_subscriber(n,   "drone;ground_speed", DRONE_LOGGER_SENSOR_GROUND_SPEED, &DroneLoggerROSModule::vector2StampedCallback, init_rostime),
    status_subscriber(n,         "drone;status", DRONE_LOGGER_SENSOR_STATUS, &DroneLoggerROSModule::droneStatusCallback, init_rostime),
    // Drone driver commands (sent by the interface, the controller or other publishers)
    drone_command_pitch_roll_subscriber(n,"drone;command;PR", DRONE_LOGGER_COMMAND_DRONE_COMMAND_PITCH_ROLL, &DroneLoggerROSModule::dronePitchRollCmdCallback, init_rostime),
    drone_command_daltitude_subscriber(n, "drone;command;Dh", DRONE_LOGGER_COMMAND_DRONE_COMMAND_DALTITUDE, &DroneLoggerROSModule::droneDAltitudeCmdCallback, init_rostime),
    drone_command_dyaw_subscriber(n,      "drone;command;DY", DRONE_LOGGER_COMMAND_DRONE_COMMAND_DYAW, &DroneLoggerROSModule::droneDYawCmdCallback, init_rostime),
    drone_command_high_level_subscriber(n,"drone;command;high_level", DRONE_LOGGER_COMMAND_DRONE_HL_COMMAND, &DroneLoggerROSModule::droneCommandCallback, init_rostime),
    //Cameras
    front_camera_subscriber(n,"camera;front", DRONE_LOGGER_SENSOR_FRONT_CAMERA, &DroneLoggerROSModule::droneFrontCameraCallback, init_rostime),
    bottom_camera_subscriber(n,"camera;bottom", DRONE_LOGGER_SENSOR_BOTTOM_CAMERA, &DroneLoggerROSModule::droneBottomCameraCallback, init_rostime),
    // EKF pose/speed estimates
    state_estimator_pose_LMrT_subscriber(n,  "state_estimator;pose_LMrT", DRONE_LOGGER_POSE_SUBSCRIPTION_LMrT, &DroneLoggerROSModule::dronePoseCallback, init_rostime),
    state_estimator_pose_GMR_subscriber(n,   "state_estimator;pose_GMR", DRONE_LOGGER_POSE_SUBSCRIPTION_GMR, &DroneLoggerROSModule::dronePoseCallback, init_rostime),
    state_estimator_speeds_LMrT_subscriber(n,"state_estimator;speeds_LMrT", DRONE_LOGGER_SPEEDS_SUBSCRIPTION_LMrT, &DroneLoggerROSModule::droneSpeedsCallback, init_rostime),
    state_estimator_speeds_GMR_subscriber(n, "state_estimator;speeds_GMR", DRONE_LOGGER_SPEEDS_SUBSCRIPTION_GMR, &DroneLoggerROSModule::droneSpeedsCallback, init_rostime),
    // droneLocalizer
    localizer_pose_GMR_subscriber(n,   "aruco_localizer;pose_GMR", DRONE_LOGGER_LOCALIZER_POSE_SUBSCRIPTION_GMR, &DroneLoggerROSModule::dronePoseCallback, init_rostime),
    localizer_speeds_GMR_subscriber(n, "aruco_localizer;speeds_GMR", DRONE_LOGGER_LOCALIZER_SPEEDS_SUBSCRIPTION_GMR, &DroneLoggerROSModule::droneSpeedsCallback, init_rostime),
    localizer_landmark_list_subscriber(n, "aruco_localizer;landmark_list", DRONE_LOGGER_LOCALIZER_LANDMARK_LIST, &DroneLoggerROSModule::landmarkVectorCallback, init_rostime),
    // Controller references (rebroadcasts): control mode and position, speed and trajectory references
    trajectory_controller_control_mode_subscriber(n,        "controller;control_mode", MODULE_NAME_TRAJECTORY_CONTROLLER+"/controlMode", &DroneLoggerROSModule::droneTrajectoryControllerControlModeCallback, init_rostime),
    trajectory_controller_position_reference_subscriber(n,  "controller;position_ref", DRONE_LOGGER_POSITION_REF_REBROADCAST_SUBSCRIPTION, &DroneLoggerROSModule::dronePoseCallback, init_rostime),
    trajectory_controller_speeds_reference_subscriber(n,    "controller;speeds_ref", DRONE_LOGGER_SPEED_REF_REBROADCAST_SUBSCRIPTION, &DroneLoggerROSModule::droneSpeedsCallback, init_rostime),
    trajectory_controller_trajectory_reference_subscriber(n,"controller;trajectory_ref", DRONE_LOGGER_TRAJECTORY_REF_REBROADCAST_SUBSCRIPTION, &DroneLoggerROSModule::dronePositionTrajectoryRefCommandCallback, init_rostime),
    //Trajectory planner
    trajectory_planner_drone_trajectory_subscriber(n,"trajectory_planner;droneTrajectory", DRONE_LOGGER_TRAJECTORY_COMMAND, &DroneLoggerROSModule::dronePositionTrajectoryRefCommandCallback, init_rostime),
    //Brain
    brain_society_pose_subscriber(n,"brain;societyPose", DRONE_LOGGER_SOCIETY_POSE_SUBS, &DroneLoggerROSModule::societyPoseCallback, init_rostime),
    brain_mission_hl_cmd_ack_subscriber(n,"brain;drone_hl_cmd_ack", DRONE_BRAIN_MISSION_HL_COMMAND_ACK, &DroneLoggerROSModule::droneHLCommandAckCallback, init_rostime),
    //Obstacles
    obstacles_two_dim(n,"obstacles_processor;obstacles", DRONE_LOGGER_OBSTACLES_SUBS, &DroneLoggerROSModule::obstaclesTwoDimCallback, init_rostime),
    //Aruco Eye
    aruco_eye_observation_list_subscriber(n,"aruco_eye;obs_arucos", DRONE_LOGGER_ARUCO_EYE_OBSERVATIONVEC_LIST, &DroneLoggerROSModule::obsVectorCallback, init_rostime),
    //Drone Mission planner
    drone_mission_point_subscriber(n,"mission_planner;drone_mission_point", DRONE_LOGGER_MISSION_POINT_SUBS, &DroneLoggerROSModule::dronePositionRefCommandCallback, init_rostime),
    drone_mission_point_to_look_subscriber(n,"mission_planner;drone_point_to_look", DRONE_LOGGER_POINT_TO_LOOK_PUB, &DroneLoggerROSModule::dronePositionRefCommandCallback, init_rostime),
    drone_mission_yaw_to_look_subscriber(n,"mission_planner;drone_yaw_to_look", DRONE_LOGGER_YAW_TO_LOOK_PUB, &DroneLoggerROSModule::droneYawRefCommandCallback, init_rostime),
    drone_mission_info_subscriber(n,"mission_planner;drone_mission_info", DRONE_LOGGER_MISSION_INFO_PUB, &DroneLoggerROSModule::droneMissionInfoCallback, init_rostime),
    drone_mission_hl_cmd_subscriber(n,"mission_planner;drone_hl_cmd", DRONE_LOGGER_MISSION_HL_COMMAND, &DroneLoggerROSModule::droneHLCommandCallback, init_rostime),
    //Yaw ref command
    yaw_ref_command_subscriber(n,"yaw_commander;drone_yaw_ref_command", DRONE_LOGGER_YAW_REF_CMD, &DroneLoggerROSModule::droneYawRefCommandCallback, init_rostime)
{

    try {
        XMLFileReader my_xml_reader(stackPath+"configs/drone"+ std::to_string(idDrone)+"/drone_logger_config.xml");
        DroneLoggerROSModule::save_front_camera_images  = (bool) my_xml_reader.readIntValue( {"drone_logger_config","save_front_camera_images"} );
        DroneLoggerROSModule::save_bottom_camera_images = (bool) my_xml_reader.readIntValue( {"drone_logger_config","save_bottom_camera_images"} );
    } catch ( cvg_XMLFileReader_exception &e) {
    throw cvg_XMLFileReader_exception(std::string("[cvg_XMLFileReader_exception! caller_function: ") + BOOST_CURRENT_FUNCTION + e.what() + "]\n");
        DroneLoggerROSModule::save_front_camera_images  = false;
        DroneLoggerROSModule::save_bottom_camera_images = false;
    }

    return;
}

DroneLoggerROSModule::~DroneLoggerROSModule()
{
    return;
}

std::string DroneLoggerROSModule::batteryCallback(const droneMsgsROS::battery::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "batteryPercent:" << msg->batteryPercent;
    return result_ss.str();
}

std::string DroneLoggerROSModule::droneAltitudeCallback(const droneMsgsROS::droneAltitude::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "altitude:" << msg->altitude;
    result_ss << " altitude_speed:" << msg->altitude_speed;
    return result_ss.str();
}

std::string DroneLoggerROSModule::vector3StampedCallback(const geometry_msgs::Vector3Stamped::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "z:" << msg->vector.z; //yaw
    result_ss << " y:" << msg->vector.y; //pitch
    result_ss << " x:" << msg->vector.x; //roll
    return result_ss.str();
}

std::string DroneLoggerROSModule::vector2StampedCallback(const droneMsgsROS::vector2Stamped::ConstPtr &msg) {
    std::stringstream result_ss;
    result_ss <<  "x:" << msg->vector.x;
    result_ss << " y:" << msg->vector.y;
    return result_ss.str();
}

std::string DroneLoggerROSModule::droneStatusCallback(const droneMsgsROS::droneStatus::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "status:";
    switch (msg->status) {
    case droneMsgsROS::droneStatus::INITED:
        result_ss << "INITED";
        break;
    case droneMsgsROS::droneStatus::LANDED:
        result_ss << "LANDED";
        break;
    case droneMsgsROS::droneStatus::FLYING:
        result_ss << "FLYING";
        break;
    case droneMsgsROS::droneStatus::HOVERING:
        result_ss << "HOVERING";
        break;
    case droneMsgsROS::droneStatus::TAKING_OFF:
        result_ss << "TAKING_OFF";
        break;
    case droneMsgsROS::droneStatus::LANDING:
        result_ss << "LANDING";
        break;
    case droneMsgsROS::droneStatus::LOOPING:
        result_ss << "LOOPING";
        break;
    case droneMsgsROS::droneStatus::UNKNOWN:
    default:
        result_ss << "UNKNOWN";
        break;
    }
    return result_ss.str();
}

std::string DroneLoggerROSModule::dronePitchRollCmdCallback(const droneMsgsROS::dronePitchRollCmd::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "pitchCmd:" << msg->pitchCmd;
    result_ss << " rollCmd:" << msg->rollCmd;
    return result_ss.str();
}

std::string DroneLoggerROSModule::droneDAltitudeCmdCallback(const droneMsgsROS::droneDAltitudeCmd::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "dAltitudeCmd:" << msg->dAltitudeCmd;
    return result_ss.str();
}

std::string DroneLoggerROSModule::droneDYawCmdCallback(const droneMsgsROS::droneDYawCmd::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "dYawCmd:" << msg->dYawCmd;
    return result_ss.str();
}

std::string DroneLoggerROSModule::droneCommandCallback(const droneMsgsROS::droneCommand::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "command:";
    switch (msg->command) {
    case droneMsgsROS::droneCommand::TAKE_OFF:
        result_ss << "TAKE_OFF";
        break;
    case droneMsgsROS::droneCommand::HOVER:
        result_ss << "HOVER";
        break;
    case droneMsgsROS::droneCommand::LAND:
        result_ss << "LAND";
        break;
    case droneMsgsROS::droneCommand::MOVE:
        result_ss << "MOVE";
        break;
    case droneMsgsROS::droneCommand::RESET:
        result_ss << "RESET";
        break;
    case droneMsgsROS::droneCommand::UNKNOWN:
    default:
        result_ss << "UNKNOWN";
        break;
    }

    return result_ss.str();
}

std::string DroneLoggerROSModule::dronePoseCallback(const droneMsgsROS::dronePose::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "x:" << msg->x;
    result_ss << " y:" << msg->y;
    result_ss << " z:" << msg->z;
    result_ss << " yaw:" << msg->yaw;
    result_ss << " pitch:" << msg->pitch;
    result_ss << " roll:" << msg->roll;
    return result_ss.str();
}

std::string DroneLoggerROSModule::dronePoseStampedCallback(const droneMsgsROS::dronePoseStamped::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "x:" << msg->pose.x;
    result_ss << " y:" << msg->pose.y;
    result_ss << " z:" << msg->pose.z;
    result_ss << " yaw:" << msg->pose.yaw;
    result_ss << " pitch:" << msg->pose.pitch;
    result_ss << " roll:" << msg->pose.roll;
    return result_ss.str();
}

std::string DroneLoggerROSModule::droneSpeedsCallback(const droneMsgsROS::droneSpeeds::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "dx:" << msg->dx;
    result_ss << " dy:" << msg->dy;
    result_ss << " dz:" << msg->dz;
    result_ss << " dyaw:" << msg->dyaw;
    result_ss << " dpitch:" << msg->dpitch;
    result_ss << " droll:" << msg->droll;
    return result_ss.str();
}

std::string DroneLoggerROSModule::droneSpeedsStampedCallback(const droneMsgsROS::droneSpeedsStamped::ConstPtr &msg)
{
    std::stringstream result_ss;
    result_ss <<  "dx:" << msg->speed.dx;
    result_ss << " dy:" << msg->speed.dy;
    result_ss << " dz:" << msg->speed.dz;
    result_ss << " dyaw:" << msg->speed.dyaw;
    result_ss << " dpitch:" << msg->speed.dpitch;
    result_ss << " droll:" << msg->speed.droll;
    return result_ss.str();
}

std::string DroneLoggerROSModule::droneTrajectoryControllerControlModeCallback(const droneMsgsROS::droneTrajectoryControllerControlMode::ConstPtr &msg)
{
    std::stringstream result_ss;
    switch (msg->command) {
    case droneMsgsROS::droneTrajectoryControllerControlMode::SPEED_CONTROL:
        result_ss << "command:" << "SPEED";
        break;
    case droneMsgsROS::droneTrajectoryControllerControlMode::POSITION_CONTROL:
        result_ss << "command:" << "POSITION";
        break;
    case droneMsgsROS::droneTrajectoryControllerControlMode::TRAJECTORY_CONTROL:
        result_ss << "command:" << "TRAJECTORY";
        break;
    case droneMsgsROS::droneTrajectoryControllerControlMode::UNKNOWN_CONTROL_MODE:
        result_ss << "command:" << "UNKNOWN";
    default:
        break;
    }
    return result_ss.str();
}

std::string DroneLoggerROSModule::dronePositionTrajectoryRefCommandCallback(const droneMsgsROS::dronePositionTrajectoryRefCommand::ConstPtr &msg)
{
    std::ostringstream xmat_trajectoryLogMsgStrm; xmat_trajectoryLogMsgStrm.str(std::string());
    std::ostringstream ymat_trajectoryLogMsgStrm; ymat_trajectoryLogMsgStrm.str(std::string());
    std::ostringstream zmat_trajectoryLogMsgStrm; zmat_trajectoryLogMsgStrm.str(std::string());
    int num_checkpoints = msg->droneTrajectory.size();

    if ( num_checkpoints == 0) {
        xmat_trajectoryLogMsgStrm << "[]";
        ymat_trajectoryLogMsgStrm << "[]";
        zmat_trajectoryLogMsgStrm << "[]";
    } else {
        xmat_trajectoryLogMsgStrm << "[";
        ymat_trajectoryLogMsgStrm << "[";
        zmat_trajectoryLogMsgStrm << "[";

        for (int i=0; i<num_checkpoints; i++ ) {
            xmat_trajectoryLogMsgStrm << msg->droneTrajectory[i].x;
            ymat_trajectoryLogMsgStrm << msg->droneTrajectory[i].y;
            zmat_trajectoryLogMsgStrm << msg->droneTrajectory[i].z;
            if (i < num_checkpoints-1) {
                xmat_trajectoryLogMsgStrm << ";";
                ymat_trajectoryLogMsgStrm << ";";
                zmat_trajectoryLogMsgStrm << ";";
            } else {
                xmat_trajectoryLogMsgStrm << "]";
                ymat_trajectoryLogMsgStrm << "]";
                zmat_trajectoryLogMsgStrm << "]";
            }
        }
    }

    std::stringstream result_ss;
    result_ss <<  "x:" << xmat_trajectoryLogMsgStrm.str()
              << " y:" << ymat_trajectoryLogMsgStrm.str()
              << " z:" << zmat_trajectoryLogMsgStrm.str();
    result_ss << " is_periodic:" << (int)msg->is_periodic
              << " initial_checkpoint:" << msg->initial_checkpoint;
    return result_ss.str();
}

std::string DroneLoggerROSModule::obsVectorCallback(const droneMsgsROS::obsVector::ConstPtr &msg)
{
    std::stringstream result_ss;

    //result_ss<<" YPR_system:"<<msg->YPR_system;
    //result_ss<<" target_frame:"<<msg->target_frame;
    //result_ss<<" reference_frame:"<<msg->reference_frame;

    result_ss<< "obs_id:[";
    for(unsigned int i=0;i<msg->obs.size();i++)
    {
        result_ss<<msg->obs[i].id<<";";
    }
    result_ss<<"]";

    result_ss<<" obs_x:[";
    for(unsigned int i=0;i<msg->obs.size();i++)
    {
        result_ss<<msg->obs[i].x<<";";
    }
    result_ss<<"]";

    result_ss<<" obs_y:[";
    for(unsigned int i=0;i<msg->obs.size();i++)
    {
        result_ss<<msg->obs[i].y<<";";
    }
    result_ss<<"]";

    result_ss<<" obs_z:[";
    for(unsigned int i=0;i<msg->obs.size();i++)
    {
        result_ss<<msg->obs[i].z<<";";
    }
    result_ss<<"]";

    result_ss<<" obs_yaw:[";
    for(unsigned int i=0;i<msg->obs.size();i++)
    {
        result_ss<<msg->obs[i].yaw<<";";
    }
    result_ss<<"]";

    result_ss<<" obs_pitch:[";
    for(unsigned int i=0;i<msg->obs.size();i++)
    {
        result_ss<<msg->obs[i].pitch<<";";
    }
    result_ss<<"]";

    result_ss<<" roll:[";
    for(unsigned int i=0;i<msg->obs.size();i++)
    {
        result_ss<<msg->obs[i].roll<<";";
    }
    result_ss<<"]";

    return result_ss.str();
}

std::string DroneLoggerROSModule::landmarkVectorCallback(const droneMsgsROS::landmarkVector::ConstPtr &msg)
{
    std::stringstream result_ss;

    result_ss<< "id:[";
    for (unsigned int i=0;i<msg->landmark_vector.size();i++)
    {
        result_ss<<msg->landmark_vector[i].id<<";";
    }
    result_ss<<"]";
    result_ss<<" x:[";
    for (unsigned int i=0;i<msg->landmark_vector.size();i++) {
        result_ss<<msg->landmark_vector[i].x<<";";
    }
    result_ss<<"]";
    result_ss<<" y:[";
    for (unsigned int i=0;i<msg->landmark_vector.size();i++) {
        result_ss<<msg->landmark_vector[i].y<<";";
    }
    result_ss<<"]";
    result_ss<<" z:[";
    for (unsigned int i=0;i<msg->landmark_vector.size();i++) {
        result_ss<<msg->landmark_vector[i].z<<";";
    }
    result_ss<<"]";
    result_ss<<" yaw:[";
    for (unsigned int i=0;i<msg->landmark_vector.size();i++) {
        result_ss<<msg->landmark_vector[i].yaw<<";";
    }
    result_ss<<"]";
    result_ss<<" pitch:[";
    for (unsigned int i=0;i<msg->landmark_vector.size();i++) {
        result_ss<<msg->landmark_vector[i].pitch<<";";
    }
    result_ss<<"]";
    result_ss<<" roll:[";
    for (unsigned int i=0;i<msg->landmark_vector.size();i++) {
        result_ss<<msg->landmark_vector[i].roll<<";";
    }
    result_ss<<"]";

    return result_ss.str();
}

std::string DroneLoggerROSModule::obstaclesTwoDimCallback(const droneMsgsROS::obstaclesTwoDim::ConstPtr &msg)
{
    std::stringstream result_ss;

    //msg->walls
    result_ss<< "walls_id:[";
    for (unsigned int i=0; i<msg->walls.size(); i++) {
        result_ss<<msg->walls[i].id<<";";
    }
    result_ss<<"]";
    result_ss<<" walls_center:[";
    for (unsigned int i=0; i<msg->walls.size(); i++) {
        result_ss<<msg->walls[i].centerX<<",";
        result_ss<<msg->walls[i].centerY<<";";
    }
    result_ss<<"]";

    result_ss<<" walls_size:[";
    for (unsigned int i=0; i<msg->walls.size(); i++) {
        result_ss<<msg->walls[i].sizeX<<",";
        result_ss<<msg->walls[i].sizeY<<";";
    }
    result_ss<<"]";

    result_ss<<" walls_yaw:[";
    for (unsigned int i=0; i<msg->walls.size(); i++) {
        result_ss<<msg->walls[i].yawAngle<<";";
    }
    result_ss<<"]";

    // msg->poles
    result_ss<<" poles_id:[";
    for (unsigned int i=0; i<msg->poles.size(); i++) {
        result_ss<<msg->poles[i].id<<";";
    }
    result_ss<<"]";
    result_ss<<" poles_center:[";
    for (unsigned int i=0; i<msg->poles.size(); i++) {
        result_ss<<msg->poles[i].centerX<<",";
        result_ss<<msg->poles[i].centerY<<";";
    }
    result_ss<<"]";
    result_ss<<" poles_size:[";
    for (unsigned int i=0; i<msg->poles.size(); i++) {
        result_ss<<msg->poles[i].radiusX<<",";
        result_ss<<msg->poles[i].radiusY<<";";
    }
    result_ss<<"]";
    result_ss<<" poles_yaw:[";
    for (unsigned int i=0; i<msg->poles.size(); i++) {
        result_ss<<msg->poles[i].yawAngle<<";";
    }
    result_ss<<"]";

    return result_ss.str();
}

std::string DroneLoggerROSModule::societyPoseCallback(const droneMsgsROS::societyPose::ConstPtr &msg)
{
    std::stringstream result_ss;

    result_ss<< "societyDrone_id:[";
    for(unsigned int i=0;i<msg->societyDrone.size();i++)
    {
        result_ss<<msg->societyDrone[i].id<<";";
    }
    result_ss<<"]";

    result_ss<<" societyDrone_pose_x:[";
    for(unsigned int i=0;i<msg->societyDrone.size();i++)
    {
        result_ss<<msg->societyDrone[i].pose.x<<";";
    }
    result_ss<<"]";

    result_ss<<" societyDrone_pose_y:[";
    for(unsigned int i=0;i<msg->societyDrone.size();i++)
    {
        result_ss<<msg->societyDrone[i].pose.y<<";";
    }
    result_ss<<"]";

    result_ss<<" societyDrone_pose_z:[";
    for(unsigned int i=0;i<msg->societyDrone.size();i++)
    {
        result_ss<<msg->societyDrone[i].pose.z<<";";
    }
    result_ss<<"]";

    result_ss<<" societyDrone_pose_yaw:[";
    for(unsigned int i=0;i<msg->societyDrone.size();i++)
    {
        result_ss<<msg->societyDrone[i].pose.yaw<<";";
    }
    result_ss<<"]";

    result_ss<<" societyDrone_pose_pitch:[";
    for(unsigned int i=0;i<msg->societyDrone.size();i++)
    {
        result_ss<<msg->societyDrone[i].pose.pitch<<";";
    }
    result_ss<<"]";

    result_ss<<" societyDrone_pose_roll:[";
    for(unsigned int i=0;i<msg->societyDrone.size();i++)
    {
        result_ss<<msg->societyDrone[i].pose.roll<<";";
    }
    result_ss<<"]";

    return result_ss.str();
}

std::string DroneLoggerROSModule::dronePositionRefCommandCallback(const droneMsgsROS::dronePositionRefCommand::ConstPtr &msg)
{
    std::stringstream result_ss;

    result_ss<< "x:"<<msg->x;
    result_ss<<" y:"<<msg->y;
    result_ss<<" z:"<<msg->z;

    return result_ss.str();
}

std::string DroneLoggerROSModule::dronePositionRefCommandStampedCallback(const droneMsgsROS::dronePositionRefCommandStamped::ConstPtr &msg)
{
    std::stringstream result_ss;

    result_ss<< "position_command_x:"<<msg->position_command.x;
    result_ss<<" position_command_y:"<<msg->position_command.y;
    result_ss<<" position_command_z:"<<msg->position_command.z;

    return result_ss.str();
}

std::string DroneLoggerROSModule::droneYawRefCommandCallback(const droneMsgsROS::droneYawRefCommand::ConstPtr &msg)
{
    std::stringstream result_ss;

    result_ss<< "yaw:"<<msg->yaw;

    return result_ss.str();
}

std::string DroneLoggerROSModule::droneHLCommandCallback(const droneMsgsROS::droneHLCommand::ConstPtr &msg)
{
    std::stringstream result_ss;

    result_ss << "hlCommand:";
    switch (msg->hlCommand)
    {
    case droneMsgsROS::droneHLCommand::TAKE_OFF:
        result_ss << "TAKE_OFF";
        break;
    case droneMsgsROS::droneHLCommand::HOVER:
        result_ss << "HOVER";
        break;
    case droneMsgsROS::droneHLCommand::LAND:
        result_ss << "LAND";
        break;
    case droneMsgsROS::droneHLCommand::MOVE_TRAJECTORY:
        result_ss << "MOVE_TRAJECTORY";
        break;
    case droneMsgsROS::droneHLCommand::SLEEP:
        result_ss << "SLEEP";
        break;
    case droneMsgsROS::droneHLCommand::UNKNOWN:
    default:
        result_ss << "UNKNOWN";
        break;
    }

    return result_ss.str();
}

std::string DroneLoggerROSModule::droneHLCommandAckCallback(const droneMsgsROS::droneHLCommandAck::ConstPtr &msg)
{
    std::stringstream result_ss;

    result_ss<< "ack:"<<static_cast<int>(msg->ack);

    return result_ss.str();
}

std::string DroneLoggerROSModule::droneMissionInfoCallback(const droneMsgsROS::droneMissionInfo::ConstPtr &msg)
{
    std::stringstream result_ss;

    result_ss<< "durationMission:"<<msg->durationMission.toSec();
    result_ss<<" durationSubmission:"<<msg->durationSubmission.toSec();
    result_ss<<" idSubmission:"<<msg->idSubmission;
    result_ss<<" loopSubmision:"<<static_cast<int>(msg->loopSubmission);
    result_ss<<" durationTask:"<<msg->durationTask.toSec();
    result_ss<<" idTask:"<<msg->idTask;
    result_ss<<" taskType:"<<msg->taskType;
    result_ss<<" taskState:";
    switch(msg->taskState)
    {
    case droneMsgsROS::droneMissionInfo::WAITING_BRAIN:
        result_ss<<"WAITING_BRAIN";
        break;
    case droneMsgsROS::droneMissionInfo::TASK_RUNNING:
        result_ss<<"TASK_RUNNING";
        break;
    default:
        result_ss<<"UNKNOWN";
        break;
    }

    return result_ss.str();
}

std::string DroneLoggerROSModule::droneGoTaskCallback(const droneMsgsROS::droneGoTask::ConstPtr &msg)
{
    std::stringstream result_ss;

    result_ss<< "submissionId:"<<msg->submissionId;
    result_ss<<" taskId:"<<msg->taskId;

    return result_ss.str();
}

//////// IMAGES
std::string DroneLoggerROSModule::droneFrontCameraCallback(const sensor_msgs::ImageConstPtr &msg)
{
    std::stringstream result_ss;
    static int numImage=-1;

    numImage++;

    std::string pathToSave=DroneLoggerROSBasicModule::currentlog_path+"/frontImage/";
    result_ss << "image:im_" << std::setfill('0') << std::setw(10) << numImage << ".png";

    if (DroneLoggerROSModule::save_front_camera_images) {
        //Front image
        cv_bridge::CvImagePtr cvFrontImage;
        cv::Mat frontImage;

        try
        {
            cvFrontImage = cv_bridge::toCvCopy(msg,sensor_msgs::image_encodings::BGR8);
        }
        catch (cv_bridge::Exception& e)
        {
            ROS_ERROR("cv_bridge exception: %s", e.what());
            return result_ss.str();
        }

        frontImage=cvFrontImage->image;

        //Store in memory
        cv::imwrite( pathToSave+result_ss.str(), frontImage );
    }

    return result_ss.str();
}

std::string DroneLoggerROSModule::droneBottomCameraCallback(const sensor_msgs::ImageConstPtr &msg)
{
    std::stringstream result_ss;
    static int numImage=-1;
    numImage++;

    std::string pathToSave=DroneLoggerROSBasicModule::currentlog_path+"/bottomImage/";
    result_ss << "image:im_" << std::setfill('0') << std::setw(10) << numImage << ".png";

    if (DroneLoggerROSModule::save_bottom_camera_images) {
        //Bottom image
        cv_bridge::CvImagePtr cvBottomImage;
        cv::Mat BottomImage;

        try
        {
            cvBottomImage = cv_bridge::toCvCopy(msg,sensor_msgs::image_encodings::BGR8);
        }
        catch (cv_bridge::Exception& e)
        {
            ROS_ERROR("cv_bridge exception: %s", e.what());
            return result_ss.str();
        }

        BottomImage=cvBottomImage->image;

        //Store in memory
        cv::imwrite( pathToSave+result_ss.str(), BottomImage );
    }

    return result_ss.str();
}


text:
<Group>
  <Identifier>hkk_101</Identifier>
  <Name>Heemkundevereniging Den Beerschen Aard</Name>
  <Address>
    <Street>Kuikseindseweg 10</Street>
    <Postcode>5091 TD</Postcode>
    <Place>Middelbeers</Place>
    <Thumbnail/>
  </Address>
  <Website/>
</Group>


text:
package io.undertow.protocols.ssl;

import io.undertow.UndertowMessages;

import javax.net.ssl.SSLException;
import java.io.ByteArrayOutputStream;
import java.nio.BufferUnderflowException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * This class is used to both read and write the ALPN protocol names in the ClientHello SSL message.
 *
 * If the out parameter is not null then the read function is being used, while if it present then it is rewriting
 * the hello message to include ALPN.
 *
 * Even though this dual approach is not particularly clean it does remove the need to have two versions of each function,
 * that do almost exactly the same thing.
 *
 */
final class ALPNHackClientHelloExplorer {

    // Private constructor prevents construction outside this class.
    private ALPNHackClientHelloExplorer() {
    }

    /**
     * The header size of TLS/SSL records.
     * <P>
     * The value of this constant is {@value}.
     */
    public static final int RECORD_HEADER_SIZE = 0x05;

    /**
     *
     *
     */
    static List<String> exploreClientHello(ByteBuffer source)
            throws SSLException {

        ByteBuffer input = source.duplicate();

        // Do we have a complete header?
        if (input.remaining() < RECORD_HEADER_SIZE) {
            throw new BufferUnderflowException();
        }
        List<String> alpnProtocols = new ArrayList<>();
        // Is it a handshake message?
        byte firstByte = input.get();
        byte secondByte = input.get();
        byte thirdByte = input.get();

        if ((firstByte & 0x80) != 0 && thirdByte == 0x01) {
            // looks like a V2ClientHello, we ignore it.
            return null;
        } else if (firstByte == 22) {   // 22: handshake record
            if(secondByte == 3 && thirdByte >= 1 && thirdByte <= 3) {
                exploreTLSRecord(input,
                        firstByte, secondByte, thirdByte, alpnProtocols, null);
                return alpnProtocols;
            }
            return null;
        } else {
            throw UndertowMessages.MESSAGES.notHandshakeRecord();
        }
    }

    static byte[] rewriteClientHello(byte[] source, List<String> alpnProtocols) throws SSLException {
        ByteBuffer input = ByteBuffer.wrap(source);
        ByteArrayOutputStream out = new ByteArrayOutputStream();

        // Do we have a complete header?
        if (input.remaining() < RECORD_HEADER_SIZE) {
            throw new BufferUnderflowException();
        }
        try {

            // Is it a handshake message?
            byte firstByte = input.get();
            byte secondByte = input.get();
            byte thirdByte = input.get();
            out.write(firstByte & 0xFF);
            out.write(secondByte & 0xFF);
            out.write(thirdByte & 0xFF);
            if ((firstByte & 0x80) != 0 && thirdByte == 0x01) {
                // looks like a V2ClientHello, we ignore it.
                return null;
            } else if (firstByte == 22) {   // 22: handshake record
                if (secondByte == 3 && thirdByte == 3) {
                    //TLS1.2 is the only one we care about. Previous versions can't use HTTP/2, newer versions won't be backported to JDK8
                    exploreTLSRecord(input,
                            firstByte, secondByte, thirdByte, alpnProtocols, out);
                    //we need to adjust the record length;
                    int clientHelloLength = out.size() - 9;
                    byte[] data = out.toByteArray();
                    int newLength = data.length - 5;
                    data[3] = (byte) ((newLength >> 8) & 0xFF);
                    data[4] = (byte) (newLength & 0xFF);

                    //now we need to adjust the handshake frame length
                    data[6] = (byte) ((clientHelloLength >> 16) & 0xFF);
                    data[7] = (byte) ((clientHelloLength >> 8) & 0xFF);
                    data[8] = (byte) (clientHelloLength & 0xFF);

                    return data;
                }
                return null;
            } else {
                throw UndertowMessages.MESSAGES.notHandshakeRecord();
            }
        } catch (ALPNPresentException e) {
            return null;
        }
    }

    /*
     * struct {
     *     uint8 major;
     *     uint8 minor;
     * } ProtocolVersion;
     *
     * enum {
     *     change_cipher_spec(20), alert(21), handshake(22),
     *     application_data(23), (255)
     * } ContentType;
     *
     * struct {
     *     ContentType type;
     *     ProtocolVersion version;
     *     uint16 length;
     *     opaque fragment[TLSPlaintext.length];
     * } TLSPlaintext;
     */
    private static void exploreTLSRecord(
            ByteBuffer input, byte firstByte, byte secondByte,
            byte thirdByte, List<String> alpnProtocols, ByteArrayOutputStream out) throws SSLException {

        // Is it a handshake message?
        if (firstByte != 22) {        // 22: handshake record
            throw UndertowMessages.MESSAGES.notHandshakeRecord();
        }

        // Is there enough data for a full record?
        int recordLength = getInt16(input);
        if (recordLength > input.remaining()) {
            throw new BufferUnderflowException();
        }
        if(out != null) {
            out.write(0);
            out.write(0);
        }

        // We have already had enough source bytes.
        try {
            exploreHandshake(input,
                secondByte, thirdByte, recordLength, alpnProtocols, out);
        } catch (BufferUnderflowException ignored) {
            throw UndertowMessages.MESSAGES.invalidHandshakeRecord();
        }
    }

    /*
     * enum {
     *     hello_request(0), client_hello(1), server_hello(2),
     *     certificate(11), server_key_exchange (12),
     *     certificate_request(13), server_hello_done(14),
     *     certificate_verify(15), client_key_exchange(16),
     *     finished(20)
     *     (255)
     * } HandshakeType;
     *
     * struct {
     *     HandshakeType msg_type;
     *     uint24 length;
     *     select (HandshakeType) {
     *         case hello_request:       HelloRequest;
     *         case client_hello:        ClientHello;
     *         case server_hello:        ServerHello;
     *         case certificate:         Certificate;
     *         case server_key_exchange: ServerKeyExchange;
     *         case certificate_request: CertificateRequest;
     *         case server_hello_done:   ServerHelloDone;
     *         case certificate_verify:  CertificateVerify;
     *         case client_key_exchange: ClientKeyExchange;
     *         case finished:            Finished;
     *     } body;
     * } Handshake;
     */
    private static void exploreHandshake(
            ByteBuffer input, byte recordMajorVersion,
            byte recordMinorVersion, int recordLength, List<String> alpnProtocols, ByteArrayOutputStream out) throws SSLException {

        // What is the handshake type?
        byte handshakeType = input.get();
        if (handshakeType != 0x01) {   // 0x01: client_hello message
            throw UndertowMessages.MESSAGES.expectedClientHello();
        }
        if(out != null) {
            out.write(handshakeType & 0xFF);
        }

        // What is the handshake body length?
        int handshakeLength = getInt24(input);
        if(out != null) {
            //placeholder
            out.write(0);
            out.write(0);
            out.write(0);
        }

        // Theoretically, a single handshake message might span multiple
        // records, but in practice this does not occur.
        if (handshakeLength > recordLength - 4) { // 4: handshake header size
            throw UndertowMessages.MESSAGES.multiRecordSSLHandshake();
        }

        input = input.duplicate();
        input.limit(handshakeLength + input.position());
        exploreClientHello(input, alpnProtocols, out);
    }

    /*
     * struct {
     *     uint32 gmt_unix_time;
     *     opaque random_bytes[28];
     * } Random;
     *
     * opaque SessionID<0..32>;
     *
     * uint8 CipherSuite[2];
     *
     * enum { null(0), (255) } CompressionMethod;
     *
     * struct {
     *     ProtocolVersion client_version;
     *     Random random;
     *     SessionID session_id;
     *     CipherSuite cipher_suites<2..2^16-2>;
     *     CompressionMethod compression_methods<1..2^8-1>;
     *     select (extensions_present) {
     *         case false:
     *             struct {};
     *         case true:
     *             Extension extensions<0..2^16-1>;
     *     };
     * } ClientHello;
     */
    private static void exploreClientHello(
            ByteBuffer input,
            List<String> alpnProtocols,
            ByteArrayOutputStream out) throws SSLException {

        // client version
        byte helloMajorVersion = input.get();
        byte helloMinorVersion = input.get();
        if(out != null) {
            out.write(helloMajorVersion & 0xFF);
            out.write(helloMinorVersion & 0xFF);
        }
        if(helloMajorVersion != 3 && helloMinorVersion != 3) {
            //we only care about TLS 1.2
            return;
        }

        // ignore random
        for(int i = 0; i < 32; ++i) {// 32: the length of Random
            byte d = input.get();
            if(out != null) {
                out.write(d & 0xFF);
            }
        }

        // session id
        processByteVector8(input, out);

        // cipher_suites
        processByteVector16(input, out);

        // compression methods
        processByteVector8(input, out);
        if (input.remaining() > 0) {
            exploreExtensions(input, alpnProtocols, out);
        } else if(out != null) {
            byte[] data = generateAlpnExtension(alpnProtocols);
            writeInt16(out, data.length);
            out.write(data, 0, data.length);
        }
    }

    private static void writeInt16(ByteArrayOutputStream out, int l) {
        if(out == null) return;
        out.write((l >> 8) & 0xFF);
        out.write(l & 0xFF);
    }

    private static byte[] generateAlpnExtension(List<String> alpnProtocols) {
        ByteArrayOutputStream alpnBits = new ByteArrayOutputStream();
        alpnBits.write(0);
        alpnBits.write(16); //ALPN type
        int length = 2;
        for(String p : alpnProtocols) {
            length++;
            length += p.length();
        }
        writeInt16(alpnBits, length);
        length -= 2;
        writeInt16(alpnBits, length);
        for(String p : alpnProtocols) {
            alpnBits.write(p.length() & 0xFF);
            for (int i = 0; i < p.length(); ++i) {
                alpnBits.write(p.charAt(i) & 0xFF);
            }
        }
        return alpnBits.toByteArray();
    }

    /*
     * struct {
     *     ExtensionType extension_type;
     *     opaque extension_data<0..2^16-1>;
     * } Extension;
     *
     * enum {
     *     server_name(0), max_fragment_length(1),
     *     client_certificate_url(2), trusted_ca_keys(3),
     *     truncated_hmac(4), status_request(5), (65535)
     * } ExtensionType;
     */
    private static void exploreExtensions(ByteBuffer input, List<String> alpnProtocols, ByteArrayOutputStream out)
            throws SSLException {
        ByteArrayOutputStream extensionOut = out == null ? null : new ByteArrayOutputStream();
        int length = getInt16(input);           // length of extensions
        writeInt16(extensionOut, 0); //placeholder
        while (length > 0) {
            int extType = getInt16(input);      // extenson type
            writeInt16(extensionOut, extType);
            int extLen = getInt16(input);       // length of extension data
            writeInt16(extensionOut, extLen);
            if (extType == 16) {      // 0x00: ty
                if(out == null) {
                    exploreALPNExt(input, alpnProtocols);
                } else {
                    throw new ALPNPresentException();
                }
            } else {                    // ignore other extensions
                processByteVector(input, extLen, extensionOut);
            }

            length -= extLen + 4;
        }
        if(out != null) {
            byte[] alpnBits = generateAlpnExtension(alpnProtocols);
            extensionOut.write(alpnBits,0 ,alpnBits.length);
            byte[] extensionsData = extensionOut.toByteArray();
            int newLength = extensionsData.length - 2;
            extensionsData[0] = (byte) ((newLength >> 8) & 0xFF);
            extensionsData[1] = (byte) (newLength & 0xFF);
            out.write(extensionsData, 0, extensionsData.length);
        }

    }

    private static void exploreALPNExt(ByteBuffer input, List<String> alpnProtocols) {
        int length = getInt16(input);
        int end = input.position() + length;
        while (input.position() < end) {
            alpnProtocols.add(readByteVector8(input));
        }
    }

    private static int getInt8(ByteBuffer input) {
        return input.get();
    }

    private static int getInt16(ByteBuffer input) {
        return (input.get() & 0xFF) << 8 | input.get() & 0xFF;
    }

    private static int getInt24(ByteBuffer input) {
        return (input.get() & 0xFF) << 16 | (input.get() & 0xFF) << 8 |
            input.get() & 0xFF;
    }

    private static void processByteVector8(ByteBuffer input, ByteArrayOutputStream out) {
        int int8 = getInt8(input);
        if(out != null) {
            out.write(int8 & 0xFF);
        }
        processByteVector(input, int8, out);
    }

    private static void processByteVector(ByteBuffer input, int length, ByteArrayOutputStream out) {
        for (int i = 0; i < length; ++i) {
            byte b = input.get();
            if(out != null) {
                out.write(b & 0xFF);
            }
        }
    }
    private static String readByteVector8(ByteBuffer input) {
        int length = getInt8(input);
        byte[] data = new byte[length];
        input.get(data);
        return new String(data, StandardCharsets.US_ASCII);
    }

    private static void processByteVector16(ByteBuffer input, ByteArrayOutputStream out) {
        int int16 = getInt16(input);
        writeInt16(out, int16);
        processByteVector(input, int16, out);
    }

    private static final class ALPNPresentException extends RuntimeException {

    }
}


text:
// Copyright 2016 The Bazel Authors. All rights reserved.
//
// 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.

package com.google.devtools.build.lib.buildeventstream;

import com.google.common.collect.ImmutableList;
import java.util.Collection;
import javax.annotation.Nullable;

/**
 * A {@link BuildEvent} reporting about progress.
 *
 * <p>Events of this type are used to report updates on the progress of the build. They are also
 * used to chain in failure events where the canonical parents (e.g., test suites) can only be
 * reported later.
 */
public final class ProgressEvent extends GenericBuildEvent {

  @Nullable private final String out;
  @Nullable private final String err;

  /** The {@link BuildEventId} of the first progress event to be reported. */
  public static final BuildEventId INITIAL_PROGRESS_UPDATE = BuildEventId.progressId(0);

  private ProgressEvent(
      BuildEventId id, Collection<BuildEventId> children, String out, String err) {
    super(id, children);
    this.out = out;
    this.err = err;
  }

  @Override
  public BuildEventStreamProtos.BuildEvent asStreamProto(BuildEventContext converters) {
    BuildEventStreamProtos.Progress.Builder builder = BuildEventStreamProtos.Progress.newBuilder();
    if (out != null) {
      builder.setStdout(out);
    }
    if (err != null) {
      builder.setStderr(err);
    }
    return GenericBuildEvent.protoChaining(this).setProgress(builder.build()).build();
  }

  /** Create a regular progress update with the given running number. */
  public static BuildEvent progressUpdate(int number, String out, String err) {
    BuildEventId id = BuildEventId.progressId(number);
    BuildEventId next = BuildEventId.progressId(number + 1);
    return new ProgressEvent(id, ImmutableList.of(next), out, err);
  }

  public static BuildEvent progressUpdate(int number) {
    return progressUpdate(number, null, null);
  }

  /** Create a progress update event also chaining in a given id. */
  public static BuildEvent progressChainIn(
      int number, BuildEventId chainIn, String out, String err) {
    BuildEventId id = BuildEventId.progressId(number);
    BuildEventId next = BuildEventId.progressId(number + 1);
    return new ProgressEvent(id, ImmutableList.of(next, chainIn), out, err);
  }

  public static BuildEvent progressChainIn(int number, BuildEventId chainIn) {
    return progressChainIn(number, chainIn, null, null);
  }

  /**
   * A progress update event with a given id, that has no children (and hence usually is the last
   * progress event in the stream).
   */
  public static BuildEvent finalProgressUpdate(
      int number, @Nullable String out, @Nullable String err) {
    BuildEventId id = BuildEventId.progressId(number);
    return new ProgressEvent(id, ImmutableList.<BuildEventId>of(), out, err);
  }

  public static BuildEvent finalProgressUpdate(int number) {
    return finalProgressUpdate(number, null, null);
  }
}